aboutsummaryrefslogtreecommitdiff
path: root/core/math
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2021-08-31 22:21:13 +0100
committergingerBill <bill@gingerbill.org>2021-08-31 22:21:13 +0100
commit251da264ed6e0f039931683c7b0d4b97e88c8d99 (patch)
treec7a9a088477d2452c2cf850458c62d994a211df6 /core/math
parentb176af27427a6c39448a71a8023e4a9877f0a51c (diff)
Remove unneeded semicolons from the core library
Diffstat (limited to 'core/math')
-rw-r--r--core/math/big/api.odin32
-rw-r--r--core/math/big/common.odin90
-rw-r--r--core/math/big/example.odin180
-rw-r--r--core/math/big/helpers.odin502
-rw-r--r--core/math/big/internal.odin1438
-rw-r--r--core/math/big/logical.odin90
-rw-r--r--core/math/big/prime.odin146
-rw-r--r--core/math/big/private.odin1294
-rw-r--r--core/math/big/public.odin350
-rw-r--r--core/math/big/radix.odin280
-rw-r--r--core/math/big/test.odin274
-rw-r--r--core/math/big/tune.odin38
-rw-r--r--core/math/bits/bits.odin384
-rw-r--r--core/math/fixed/fixed.odin120
-rw-r--r--core/math/linalg/extended.odin328
-rw-r--r--core/math/linalg/general.odin244
-rw-r--r--core/math/linalg/specific.odin2986
-rw-r--r--core/math/linalg/specific_euler_angles.odin200
-rw-r--r--core/math/linalg/specific_euler_angles_f16.odin2080
-rw-r--r--core/math/linalg/specific_euler_angles_f32.odin2080
-rw-r--r--core/math/linalg/specific_euler_angles_f64.odin2080
-rw-r--r--core/math/linalg/swizzle.odin74
-rw-r--r--core/math/math.odin932
-rw-r--r--core/math/rand/normal.odin32
-rw-r--r--core/math/rand/rand.odin128
25 files changed, 8191 insertions, 8191 deletions
diff --git a/core/math/big/api.odin b/core/math/big/api.odin
index 1f2eab8d7..1c7833730 100644
--- a/core/math/big/api.odin
+++ b/core/math/big/api.odin
@@ -31,7 +31,7 @@ add :: proc {
int_add_digit :: proc(dest, a: ^Int, digit: DIGIT, allocator := context.allocator) -> (err: Error)
*/
int_add_digit,
-};
+}
/*
err = sub(dest, a, b);
@@ -45,7 +45,7 @@ sub :: proc {
int_sub_digit :: proc(dest, a: ^Int, digit: DIGIT) -> (err: Error)
*/
int_sub_digit,
-};
+}
/*
=== === === === === === === === === === === === === === === === === === === === === === === ===
@@ -59,44 +59,44 @@ is_initialized :: proc {
int_is_initialized :: proc(a: ^Int) -> bool
*/
int_is_initialized,
-};
+}
is_zero :: proc {
/*
int_is_zero :: proc(a: ^Int) -> bool
*/
int_is_zero,
-};
+}
is_positive :: proc {
/*
int_is_positive :: proc(a: ^Int) -> bool
*/
int_is_positive,
-};
-is_pos :: is_positive;
+}
+is_pos :: is_positive
is_negative :: proc {
/*
int_is_negative :: proc(a: ^Int) -> bool
*/
int_is_negative,
-};
-is_neg :: is_negative;
+}
+is_neg :: is_negative
is_even :: proc {
/*
int_is_even :: proc(a: ^Int) -> bool
*/
int_is_even,
-};
+}
is_odd :: proc {
/*
int_is_odd :: proc(a: ^Int) -> bool
*/
int_is_odd,
-};
+}
is_power_of_two :: proc {
/*
@@ -107,7 +107,7 @@ is_power_of_two :: proc {
int_is_power_of_two :: proc(a: ^Int) -> (res: bool)
*/
int_is_power_of_two,
-};
+}
compare :: proc {
/*
@@ -122,16 +122,16 @@ compare :: proc {
int_compare_digit :: proc(a: ^Int, u: DIGIT) -> Comparison_Flag
*/
int_compare_digit,
-};
-cmp :: compare;
+}
+cmp :: compare
compare_magnitude :: proc {
/*
Compare the magnitude of two `Int`s, unsigned.
*/
int_compare_magnitude,
-};
-cmp_mag :: compare_magnitude;
+}
+cmp_mag :: compare_magnitude
/*
=== === === === === === === === === === === === === === === === === === === === === === === ===
@@ -147,6 +147,6 @@ destroy :: proc {
int_destroy :: proc(integers: ..^Int)
*/
int_destroy,
-};
+}
diff --git a/core/math/big/common.odin b/core/math/big/common.odin
index ce1f7d77f..f23754e89 100644
--- a/core/math/big/common.odin
+++ b/core/math/big/common.odin
@@ -33,15 +33,15 @@ import "core:intrinsics"
To allow tests to run we add `-define:MATH_BIG_EXE=false` to hardcode the cutoffs for now.
*/
when #config(MATH_BIG_EXE, true) {
- MUL_KARATSUBA_CUTOFF := initialize_constants();
- SQR_KARATSUBA_CUTOFF := _DEFAULT_SQR_KARATSUBA_CUTOFF;
- MUL_TOOM_CUTOFF := _DEFAULT_MUL_TOOM_CUTOFF;
- SQR_TOOM_CUTOFF := _DEFAULT_SQR_TOOM_CUTOFF;
+ MUL_KARATSUBA_CUTOFF := initialize_constants()
+ SQR_KARATSUBA_CUTOFF := _DEFAULT_SQR_KARATSUBA_CUTOFF
+ MUL_TOOM_CUTOFF := _DEFAULT_MUL_TOOM_CUTOFF
+ SQR_TOOM_CUTOFF := _DEFAULT_SQR_TOOM_CUTOFF
} else {
- MUL_KARATSUBA_CUTOFF := _DEFAULT_MUL_KARATSUBA_CUTOFF;
- SQR_KARATSUBA_CUTOFF := _DEFAULT_SQR_KARATSUBA_CUTOFF;
- MUL_TOOM_CUTOFF := _DEFAULT_MUL_TOOM_CUTOFF;
- SQR_TOOM_CUTOFF := _DEFAULT_SQR_TOOM_CUTOFF;
+ MUL_KARATSUBA_CUTOFF := _DEFAULT_MUL_KARATSUBA_CUTOFF
+ SQR_KARATSUBA_CUTOFF := _DEFAULT_SQR_KARATSUBA_CUTOFF
+ MUL_TOOM_CUTOFF := _DEFAULT_MUL_TOOM_CUTOFF
+ SQR_TOOM_CUTOFF := _DEFAULT_SQR_TOOM_CUTOFF
}
/*
@@ -57,24 +57,24 @@ when #config(MATH_BIG_EXE, true) {
debugged where necessary.
*/
-_DEFAULT_MUL_KARATSUBA_CUTOFF :: #config(MUL_KARATSUBA_CUTOFF, 80);
-_DEFAULT_SQR_KARATSUBA_CUTOFF :: #config(SQR_KARATSUBA_CUTOFF, 120);
-_DEFAULT_MUL_TOOM_CUTOFF :: #config(MUL_TOOM_CUTOFF, 350);
-_DEFAULT_SQR_TOOM_CUTOFF :: #config(SQR_TOOM_CUTOFF, 400);
+_DEFAULT_MUL_KARATSUBA_CUTOFF :: #config(MUL_KARATSUBA_CUTOFF, 80)
+_DEFAULT_SQR_KARATSUBA_CUTOFF :: #config(SQR_KARATSUBA_CUTOFF, 120)
+_DEFAULT_MUL_TOOM_CUTOFF :: #config(MUL_TOOM_CUTOFF, 350)
+_DEFAULT_SQR_TOOM_CUTOFF :: #config(SQR_TOOM_CUTOFF, 400)
-MAX_ITERATIONS_ROOT_N := 500;
+MAX_ITERATIONS_ROOT_N := 500
/*
Largest `N` for which we'll compute `N!`
*/
-FACTORIAL_MAX_N := 1_000_000;
+FACTORIAL_MAX_N := 1_000_000
/*
Cutoff to switch to int_factorial_binary_split, and its max recursion level.
*/
-FACTORIAL_BINARY_SPLIT_CUTOFF := 6100;
-FACTORIAL_BINARY_SPLIT_MAX_RECURSIONS := 100;
+FACTORIAL_BINARY_SPLIT_CUTOFF := 6100
+FACTORIAL_BINARY_SPLIT_MAX_RECURSIONS := 100
/*
@@ -85,15 +85,15 @@ FACTORIAL_BINARY_SPLIT_MAX_RECURSIONS := 100;
2) Optimizations thanks to precomputed masks wouldn't work.
*/
-MATH_BIG_FORCE_64_BIT :: #config(MATH_BIG_FORCE_64_BIT, false);
-MATH_BIG_FORCE_32_BIT :: #config(MATH_BIG_FORCE_32_BIT, false);
+MATH_BIG_FORCE_64_BIT :: #config(MATH_BIG_FORCE_64_BIT, false)
+MATH_BIG_FORCE_32_BIT :: #config(MATH_BIG_FORCE_32_BIT, false)
when (MATH_BIG_FORCE_32_BIT && MATH_BIG_FORCE_64_BIT) { #panic("Cannot force 32-bit and 64-bit big backend simultaneously."); };
-_LOW_MEMORY :: #config(BIGINT_SMALL_MEMORY, false);
+_LOW_MEMORY :: #config(BIGINT_SMALL_MEMORY, false)
when _LOW_MEMORY {
- _DEFAULT_DIGIT_COUNT :: 8;
+ _DEFAULT_DIGIT_COUNT :: 8
} else {
- _DEFAULT_DIGIT_COUNT :: 32;
+ _DEFAULT_DIGIT_COUNT :: 32
}
/*
@@ -103,22 +103,22 @@ when _LOW_MEMORY {
Sign :: enum u8 {
Zero_or_Positive = 0,
Negative = 1,
-};
+}
Int :: struct {
used: int,
digit: [dynamic]DIGIT,
sign: Sign,
flags: Flags,
-};
+}
Flag :: enum u8 {
NaN,
Inf,
Immutable,
-};
+}
-Flags :: bit_set[Flag; u8];
+Flags :: bit_set[Flag; u8]
/*
Errors are a strict superset of runtime.Allocation_Error.
@@ -138,7 +138,7 @@ Error :: enum int {
Math_Domain_Error = 9,
Unimplemented = 127,
-};
+}
Error_String :: #partial [Error]string{
.Out_Of_Memory = "Out of memory",
@@ -154,14 +154,14 @@ Error_String :: #partial [Error]string{
.Math_Domain_Error = "Math domain error",
.Unimplemented = "Unimplemented",
-};
+}
Primality_Flag :: enum u8 {
Blum_Blum_Shub = 0, /* BBS style prime */
Safe = 1, /* Safe prime (p-1)/2 == prime */
Second_MSB_On = 3, /* force 2nd MSB to 1 */
-};
-Primality_Flags :: bit_set[Primality_Flag; u8];
+}
+Primality_Flags :: bit_set[Primality_Flag; u8]
/*
How do we store the Ints?
@@ -171,7 +171,7 @@ Primality_Flags :: bit_set[Primality_Flag; u8];
- Must be large enough such that `init_integer` can store `u128` in the `Int` without growing.
*/
-_MIN_DIGIT_COUNT :: max(3, ((size_of(u128) + _DIGIT_BITS) - 1) / _DIGIT_BITS);
+_MIN_DIGIT_COUNT :: max(3, ((size_of(u128) + _DIGIT_BITS) - 1) / _DIGIT_BITS)
#assert(_DEFAULT_DIGIT_COUNT >= _MIN_DIGIT_COUNT);
/*
@@ -180,36 +180,36 @@ _MIN_DIGIT_COUNT :: max(3, ((size_of(u128) + _DIGIT_BITS) - 1) / _DIGIT_BITS);
- Must be small enough such that `_radix_size` for base 2 does not overflow.
`_radix_size` needs two additional bytes for zero termination and sign.
*/
-_MAX_BIT_COUNT :: (max(int) - 2);
-_MAX_DIGIT_COUNT :: _MAX_BIT_COUNT / _DIGIT_BITS;
+_MAX_BIT_COUNT :: (max(int) - 2)
+_MAX_DIGIT_COUNT :: _MAX_BIT_COUNT / _DIGIT_BITS
when MATH_BIG_FORCE_64_BIT || (!MATH_BIG_FORCE_32_BIT && size_of(rawptr) == 8) {
/*
We can use u128 as an intermediary.
*/
- DIGIT :: distinct u64;
- _WORD :: distinct u128;
+ DIGIT :: distinct u64
+ _WORD :: distinct u128
} else {
- DIGIT :: distinct u32;
- _WORD :: distinct u64;
+ DIGIT :: distinct u32
+ _WORD :: distinct u64
}
#assert(size_of(_WORD) == 2 * size_of(DIGIT));
-_DIGIT_TYPE_BITS :: 8 * size_of(DIGIT);
-_WORD_TYPE_BITS :: 8 * size_of(_WORD);
+_DIGIT_TYPE_BITS :: 8 * size_of(DIGIT)
+_WORD_TYPE_BITS :: 8 * size_of(_WORD)
-_DIGIT_BITS :: _DIGIT_TYPE_BITS - 4;
-_WORD_BITS :: 2 * _DIGIT_BITS;
+_DIGIT_BITS :: _DIGIT_TYPE_BITS - 4
+_WORD_BITS :: 2 * _DIGIT_BITS
-_MASK :: (DIGIT(1) << DIGIT(_DIGIT_BITS)) - DIGIT(1);
-_DIGIT_MAX :: _MASK;
-_MAX_COMBA :: 1 << (_WORD_TYPE_BITS - (2 * _DIGIT_BITS)) ;
-_WARRAY :: 1 << ((_WORD_TYPE_BITS - (2 * _DIGIT_BITS)) + 1);
+_MASK :: (DIGIT(1) << DIGIT(_DIGIT_BITS)) - DIGIT(1)
+_DIGIT_MAX :: _MASK
+_MAX_COMBA :: 1 << (_WORD_TYPE_BITS - (2 * _DIGIT_BITS))
+_WARRAY :: 1 << ((_WORD_TYPE_BITS - (2 * _DIGIT_BITS)) + 1)
Order :: enum i8 {
LSB_First = -1,
MSB_First = 1,
-};
+}
Endianness :: enum i8 {
Little = -1,
diff --git a/core/math/big/example.odin b/core/math/big/example.odin
index 4542e9e15..d764ad940 100644
--- a/core/math/big/example.odin
+++ b/core/math/big/example.odin
@@ -47,186 +47,186 @@ MAX_ITERATIONS_ROOT_N,
FACTORIAL_MAX_N,
FACTORIAL_BINARY_SPLIT_CUTOFF,
FACTORIAL_BINARY_SPLIT_MAX_RECURSIONS,
-);
+)
}
print :: proc(name: string, a: ^Int, base := i8(10), print_name := true, newline := true, print_extra_info := false) {
- assert_if_nil(a);
+ assert_if_nil(a)
- as, err := itoa(a, base);
- defer delete(as);
+ as, err := itoa(a, base)
+ defer delete(as)
- cb := internal_count_bits(a);
+ cb := internal_count_bits(a)
if print_name {
- fmt.printf("%v", name);
+ fmt.printf("%v", name)
}
if err != nil {
- fmt.printf("%v (error: %v | %v)", name, err, a);
+ fmt.printf("%v (error: %v | %v)", name, err, a)
}
- fmt.printf("%v", as);
+ fmt.printf("%v", as)
if print_extra_info {
- fmt.printf(" (base: %v, bits: %v (digits: %v), flags: %v)", base, cb, a.used, a.flags);
+ fmt.printf(" (base: %v, bits: %v (digits: %v), flags: %v)", base, cb, a.used, a.flags)
}
if newline {
- fmt.println();
+ fmt.println()
}
}
int_to_byte :: proc(v: ^Int) {
- err: Error;
- size: int;
- print("v: ", v);
- fmt.println();
+ err: Error
+ size: int
+ print("v: ", v)
+ fmt.println()
- t := &Int{};
- defer destroy(t);
+ t := &Int{}
+ defer destroy(t)
if size, err = int_to_bytes_size(v); err != nil {
- fmt.printf("int_to_bytes_size returned: %v\n", err);
- return;
+ fmt.printf("int_to_bytes_size returned: %v\n", err)
+ return
}
- b1 := make([]u8, size, context.temp_allocator);
- err = int_to_bytes_big(v, b1);
- int_from_bytes_big(t, b1);
- fmt.printf("big: %v | err: %v\n", b1, err);
+ b1 := make([]u8, size, context.temp_allocator)
+ err = int_to_bytes_big(v, b1)
+ int_from_bytes_big(t, b1)
+ fmt.printf("big: %v | err: %v\n", b1, err)
- int_from_bytes_big(t, b1);
+ int_from_bytes_big(t, b1)
if internal_cmp_mag(t, v) != 0 {
- print("\tError parsing t: ", t);
+ print("\tError parsing t: ", t)
}
if size, err = int_to_bytes_size(v); err != nil {
- fmt.printf("int_to_bytes_size returned: %v\n", err);
- return;
+ fmt.printf("int_to_bytes_size returned: %v\n", err)
+ return
}
- b2 := make([]u8, size, context.temp_allocator);
- err = int_to_bytes_big_python(v, b2);
- fmt.printf("big python: %v | err: %v\n", b2, err);
+ b2 := make([]u8, size, context.temp_allocator)
+ err = int_to_bytes_big_python(v, b2)
+ fmt.printf("big python: %v | err: %v\n", b2, err)
if err == nil {
- int_from_bytes_big_python(t, b2);
+ int_from_bytes_big_python(t, b2)
if internal_cmp_mag(t, v) != 0 {
- print("\tError parsing t: ", t);
+ print("\tError parsing t: ", t)
}
}
if size, err = int_to_bytes_size(v, true); err != nil {
- fmt.printf("int_to_bytes_size returned: %v\n", err);
- return;
+ fmt.printf("int_to_bytes_size returned: %v\n", err)
+ return
}
- b3 := make([]u8, size, context.temp_allocator);
- err = int_to_bytes_big(v, b3, true);
- fmt.printf("big signed: %v | err: %v\n", b3, err);
+ b3 := make([]u8, size, context.temp_allocator)
+ err = int_to_bytes_big(v, b3, true)
+ fmt.printf("big signed: %v | err: %v\n", b3, err)
- int_from_bytes_big(t, b3, true);
+ int_from_bytes_big(t, b3, true)
if internal_cmp(t, v) != 0 {
- print("\tError parsing t: ", t);
+ print("\tError parsing t: ", t)
}
if size, err = int_to_bytes_size(v, true); err != nil {
- fmt.printf("int_to_bytes_size returned: %v\n", err);
- return;
+ fmt.printf("int_to_bytes_size returned: %v\n", err)
+ return
}
- b4 := make([]u8, size, context.temp_allocator);
- err = int_to_bytes_big_python(v, b4, true);
- fmt.printf("big signed python: %v | err: %v\n", b4, err);
+ b4 := make([]u8, size, context.temp_allocator)
+ err = int_to_bytes_big_python(v, b4, true)
+ fmt.printf("big signed python: %v | err: %v\n", b4, err)
- int_from_bytes_big_python(t, b4, true);
+ int_from_bytes_big_python(t, b4, true)
if internal_cmp(t, v) != 0 {
- print("\tError parsing t: ", t);
+ print("\tError parsing t: ", t)
}
}
int_to_byte_little :: proc(v: ^Int) {
- err: Error;
- size: int;
- print("v: ", v);
- fmt.println();
+ err: Error
+ size: int
+ print("v: ", v)
+ fmt.println()
- t := &Int{};
- defer destroy(t);
+ t := &Int{}
+ defer destroy(t)
if size, err = int_to_bytes_size(v); err != nil {
- fmt.printf("int_to_bytes_size returned: %v\n", err);
- return;
+ fmt.printf("int_to_bytes_size returned: %v\n", err)
+ return
}
- b1 := make([]u8, size, context.temp_allocator);
- err = int_to_bytes_little(v, b1);
- fmt.printf("little: %v | err: %v\n", b1, err);
+ b1 := make([]u8, size, context.temp_allocator)
+ err = int_to_bytes_little(v, b1)
+ fmt.printf("little: %v | err: %v\n", b1, err)
- int_from_bytes_little(t, b1);
+ int_from_bytes_little(t, b1)
if internal_cmp_mag(t, v) != 0 {
- print("\tError parsing t: ", t);
+ print("\tError parsing t: ", t)
}
if size, err = int_to_bytes_size(v); err != nil {
- fmt.printf("int_to_bytes_size returned: %v\n", err);
- return;
+ fmt.printf("int_to_bytes_size returned: %v\n", err)
+ return
}
- b2 := make([]u8, size, context.temp_allocator);
- err = int_to_bytes_little_python(v, b2);
- fmt.printf("little python: %v | err: %v\n", b2, err);
+ b2 := make([]u8, size, context.temp_allocator)
+ err = int_to_bytes_little_python(v, b2)
+ fmt.printf("little python: %v | err: %v\n", b2, err)
if err == nil {
- int_from_bytes_little_python(t, b2);
+ int_from_bytes_little_python(t, b2)
if internal_cmp_mag(t, v) != 0 {
- print("\tError parsing t: ", t);
+ print("\tError parsing t: ", t)
}
}
if size, err = int_to_bytes_size(v, true); err != nil {
- fmt.printf("int_to_bytes_size returned: %v\n", err);
- return;
+ fmt.printf("int_to_bytes_size returned: %v\n", err)
+ return
}
- b3 := make([]u8, size, context.temp_allocator);
- err = int_to_bytes_little(v, b3, true);
- fmt.printf("little signed: %v | err: %v\n", b3, err);
+ b3 := make([]u8, size, context.temp_allocator)
+ err = int_to_bytes_little(v, b3, true)
+ fmt.printf("little signed: %v | err: %v\n", b3, err)
- int_from_bytes_little(t, b3, true);
+ int_from_bytes_little(t, b3, true)
if internal_cmp(t, v) != 0 {
- print("\tError parsing t: ", t);
+ print("\tError parsing t: ", t)
}
if size, err = int_to_bytes_size(v, true); err != nil {
- fmt.printf("int_to_bytes_size returned: %v\n", err);
- return;
+ fmt.printf("int_to_bytes_size returned: %v\n", err)
+ return
}
- b4 := make([]u8, size, context.temp_allocator);
- err = int_to_bytes_little_python(v, b4, true);
- fmt.printf("little signed python: %v | err: %v\n", b4, err);
+ b4 := make([]u8, size, context.temp_allocator)
+ err = int_to_bytes_little_python(v, b4, true)
+ fmt.printf("little signed python: %v | err: %v\n", b4, err)
- int_from_bytes_little_python(t, b4, true);
+ int_from_bytes_little_python(t, b4, true)
if internal_cmp(t, v) != 0 {
- print("\tError parsing t: ", t);
+ print("\tError parsing t: ", t)
}
}
demo :: proc() {
- a, b, c, d, e, f := &Int{}, &Int{}, &Int{}, &Int{}, &Int{}, &Int{};
- defer destroy(a, b, c, d, e, f);
+ a, b, c, d, e, f := &Int{}, &Int{}, &Int{}, &Int{}, &Int{}, &Int{}
+ defer destroy(a, b, c, d, e, f)
}
main :: proc() {
- ta := mem.Tracking_Allocator{};
- mem.tracking_allocator_init(&ta, context.allocator);
- context.allocator = mem.tracking_allocator(&ta);
+ ta := mem.Tracking_Allocator{}
+ mem.tracking_allocator_init(&ta, context.allocator)
+ context.allocator = mem.tracking_allocator(&ta)
- demo();
+ demo()
- print_configation();
+ print_configation()
- print_timings();
+ print_timings()
if len(ta.allocation_map) > 0 {
for _, v in ta.allocation_map {
- fmt.printf("Leaked %v bytes @ %v\n", v.size, v.location);
+ fmt.printf("Leaked %v bytes @ %v\n", v.size, v.location)
}
}
if len(ta.bad_free_array) > 0 {
- fmt.println("Bad frees:");
+ fmt.println("Bad frees:")
for v in ta.bad_free_array {
- fmt.println(v);
+ fmt.println(v)
}
}
} \ No newline at end of file
diff --git a/core/math/big/helpers.odin b/core/math/big/helpers.odin
index 8ce1b2811..5138dd77d 100644
--- a/core/math/big/helpers.odin
+++ b/core/math/big/helpers.odin
@@ -22,10 +22,10 @@ import rnd "core:math/rand"
Deallocates the backing memory of one or more `Int`s.
*/
int_destroy :: proc(integers: ..^Int) {
- integers := integers;
+ integers := integers
for a in &integers {
- assert_if_nil(a);
+ assert_if_nil(a)
}
#force_inline internal_int_destroy(..integers);
}
@@ -35,19 +35,19 @@ int_destroy :: proc(integers: ..^Int) {
*/
int_set_from_integer :: proc(dest: ^Int, src: $T, minimize := false, allocator := context.allocator) -> (err: Error)
where intrinsics.type_is_integer(T) {
- context.allocator = allocator;
- src := src;
+ context.allocator = allocator
+ src := src
/*
Check that `src` is usable and `dest` isn't immutable.
*/
- assert_if_nil(dest);
+ assert_if_nil(dest)
#force_inline internal_error_if_immutable(dest) or_return;
- return #force_inline internal_int_set_from_integer(dest, src, minimize);
+ return #force_inline internal_int_set_from_integer(dest, src, minimize)
}
-set :: proc { int_set_from_integer, int_copy, int_atoi, };
+set :: proc { int_set_from_integer, int_copy, int_atoi, }
/*
Copy one `Int` to another.
@@ -61,15 +61,15 @@ int_copy :: proc(dest, src: ^Int, minimize := false, allocator := context.alloca
/*
Check that `src` is usable and `dest` isn't immutable.
*/
- assert_if_nil(dest, src);
- context.allocator = allocator;
+ assert_if_nil(dest, src)
+ context.allocator = allocator
#force_inline internal_clear_if_uninitialized(src) or_return;
#force_inline internal_error_if_immutable(dest) or_return;
- return #force_inline internal_int_copy(dest, src, minimize);
+ return #force_inline internal_int_copy(dest, src, minimize)
}
-copy :: proc { int_copy, };
+copy :: proc { int_copy, }
/*
In normal code, you can also write `a, b = b, a`.
@@ -77,10 +77,10 @@ copy :: proc { int_copy, };
This helper swaps completely.
*/
int_swap :: proc(a, b: ^Int) {
- assert_if_nil(a, b);
+ assert_if_nil(a, b)
#force_inline internal_swap(a, b);
}
-swap :: proc { int_swap, };
+swap :: proc { int_swap, }
/*
Set `dest` to |`src`|.
@@ -89,19 +89,19 @@ int_abs :: proc(dest, src: ^Int, allocator := context.allocator) -> (err: Error)
/*
Check that `src` is usable and `dest` isn't immutable.
*/
- assert_if_nil(dest, src);
- context.allocator = allocator;
+ assert_if_nil(dest, src)
+ context.allocator = allocator
#force_inline internal_clear_if_uninitialized(src) or_return;
#force_inline internal_error_if_immutable(dest) or_return;
- return #force_inline internal_int_abs(dest, src);
+ return #force_inline internal_int_abs(dest, src)
}
platform_abs :: proc(n: $T) -> T where intrinsics.type_is_integer(T) {
- return n if n >= 0 else -n;
+ return n if n >= 0 else -n
}
-abs :: proc{ int_abs, platform_abs, };
+abs :: proc{ int_abs, platform_abs, }
/*
Set `dest` to `-src`.
@@ -110,32 +110,32 @@ int_neg :: proc(dest, src: ^Int, allocator := context.allocator) -> (err: Error)
/*
Check that `src` is usable and `dest` isn't immutable.
*/
- assert_if_nil(dest, src);
- context.allocator = allocator;
+ assert_if_nil(dest, src)
+ context.allocator = allocator
#force_inline internal_clear_if_uninitialized(src) or_return;
#force_inline internal_error_if_immutable(dest) or_return;
- return #force_inline internal_int_neg(dest, src);
+ return #force_inline internal_int_neg(dest, src)
}
-neg :: proc { int_neg, };
+neg :: proc { int_neg, }
/*
Helpers to extract values from the `Int`.
*/
int_bitfield_extract_single :: proc(a: ^Int, offset: int, allocator := context.allocator) -> (bit: _WORD, err: Error) {
- return #force_inline int_bitfield_extract(a, offset, 1, allocator);
+ return #force_inline int_bitfield_extract(a, offset, 1, allocator)
}
int_bitfield_extract :: proc(a: ^Int, offset, count: int, allocator := context.allocator) -> (res: _WORD, err: Error) {
/*
Check that `a` is usable.
*/
- assert_if_nil(a);
- context.allocator = allocator;
+ assert_if_nil(a)
+ context.allocator = allocator
#force_inline internal_clear_if_uninitialized(a) or_return;
- return #force_inline internal_int_bitfield_extract(a, offset, count);
+ return #force_inline internal_int_bitfield_extract(a, offset, count)
}
/*
@@ -145,21 +145,21 @@ shrink :: proc(a: ^Int, allocator := context.allocator) -> (err: Error) {
/*
Check that `a` is usable.
*/
- assert_if_nil(a);
- context.allocator = allocator;
+ assert_if_nil(a)
+ context.allocator = allocator
#force_inline internal_clear_if_uninitialized(a) or_return;
- return #force_inline internal_shrink(a);
+ return #force_inline internal_shrink(a)
}
int_grow :: proc(a: ^Int, digits: int, allow_shrink := false, allocator := context.allocator) -> (err: Error) {
/*
Check that `a` is usable.
*/
- assert_if_nil(a);
- return #force_inline internal_int_grow(a, digits, allow_shrink, allocator);
+ assert_if_nil(a)
+ return #force_inline internal_int_grow(a, digits, allow_shrink, allocator)
}
-grow :: proc { int_grow, };
+grow :: proc { int_grow, }
/*
Clear `Int` and resize it to the default size.
@@ -168,11 +168,11 @@ int_clear :: proc(a: ^Int, minimize := false, allocator := context.allocator) ->
/*
Check that `a` is usable.
*/
- assert_if_nil(a);
- return #force_inline internal_int_clear(a, minimize, allocator);
+ assert_if_nil(a)
+ return #force_inline internal_int_clear(a, minimize, allocator)
}
-clear :: proc { int_clear, };
-zero :: clear;
+clear :: proc { int_clear, }
+zero :: clear
/*
Set the `Int` to 1 and optionally shrink it to the minimum backing size.
@@ -181,10 +181,10 @@ int_one :: proc(a: ^Int, minimize := false, allocator := context.allocator) -> (
/*
Check that `a` is usable.
*/
- assert_if_nil(a);
- return #force_inline internal_one(a, minimize, allocator);
+ assert_if_nil(a)
+ return #force_inline internal_one(a, minimize, allocator)
}
-one :: proc { int_one, };
+one :: proc { int_one, }
/*
Set the `Int` to -1 and optionally shrink it to the minimum backing size.
@@ -193,10 +193,10 @@ int_minus_one :: proc(a: ^Int, minimize := false, allocator := context.allocator
/*
Check that `a` is usable.
*/
- assert_if_nil(a);
- return #force_inline internal_minus_one(a, minimize, allocator);
+ assert_if_nil(a)
+ return #force_inline internal_minus_one(a, minimize, allocator)
}
-minus_one :: proc { int_minus_one, };
+minus_one :: proc { int_minus_one, }
/*
Set the `Int` to Inf and optionally shrink it to the minimum backing size.
@@ -205,10 +205,10 @@ int_inf :: proc(a: ^Int, minimize := false, allocator := context.allocator) -> (
/*
Check that `a` is usable.
*/
- assert_if_nil(a);
- return #force_inline internal_inf(a, minimize, allocator);
+ assert_if_nil(a)
+ return #force_inline internal_inf(a, minimize, allocator)
}
-inf :: proc { int_inf, };
+inf :: proc { int_inf, }
/*
Set the `Int` to -Inf and optionally shrink it to the minimum backing size.
@@ -217,10 +217,10 @@ int_minus_inf :: proc(a: ^Int, minimize := false, allocator := context.allocator
/*
Check that `a` is usable.
*/
- assert_if_nil(a);
- return #force_inline internal_minus_inf(a, minimize, allocator);
+ assert_if_nil(a)
+ return #force_inline internal_minus_inf(a, minimize, allocator)
}
-minus_inf :: proc { int_inf, };
+minus_inf :: proc { int_inf, }
/*
Set the `Int` to NaN and optionally shrink it to the minimum backing size.
@@ -229,72 +229,72 @@ int_nan :: proc(a: ^Int, minimize := false, allocator := context.allocator) -> (
/*
Check that `a` is usable.
*/
- assert_if_nil(a);
- return #force_inline internal_nan(a, minimize, allocator);
+ assert_if_nil(a)
+ return #force_inline internal_nan(a, minimize, allocator)
}
-nan :: proc { int_nan, };
+nan :: proc { int_nan, }
power_of_two :: proc(a: ^Int, power: int, allocator := context.allocator) -> (err: Error) {
/*
Check that `a` is usable.
*/
- assert_if_nil(a);
- return #force_inline internal_int_power_of_two(a, power, allocator);
+ assert_if_nil(a)
+ return #force_inline internal_int_power_of_two(a, power, allocator)
}
int_get_u128 :: proc(a: ^Int, allocator := context.allocator) -> (res: u128, err: Error) {
/*
Check that `a` is usable.
*/
- assert_if_nil(a);
- return int_get(a, u128, allocator);
+ assert_if_nil(a)
+ return int_get(a, u128, allocator)
}
-get_u128 :: proc { int_get_u128, };
+get_u128 :: proc { int_get_u128, }
int_get_i128 :: proc(a: ^Int, allocator := context.allocator) -> (res: i128, err: Error) {
/*
Check that `a` is usable.
*/
- assert_if_nil(a);
- return int_get(a, i128, allocator);
+ assert_if_nil(a)
+ return int_get(a, i128, allocator)
}
-get_i128 :: proc { int_get_i128, };
+get_i128 :: proc { int_get_i128, }
int_get_u64 :: proc(a: ^Int, allocator := context.allocator) -> (res: u64, err: Error) {
/*
Check that `a` is usable.
*/
- assert_if_nil(a);
- return int_get(a, u64, allocator);
+ assert_if_nil(a)
+ return int_get(a, u64, allocator)
}
-get_u64 :: proc { int_get_u64, };
+get_u64 :: proc { int_get_u64, }
int_get_i64 :: proc(a: ^Int, allocator := context.allocator) -> (res: i64, err: Error) {
/*
Check that `a` is usable.
*/
- assert_if_nil(a);
- return int_get(a, i64, allocator);
+ assert_if_nil(a)
+ return int_get(a, i64, allocator)
}
-get_i64 :: proc { int_get_i64, };
+get_i64 :: proc { int_get_i64, }
int_get_u32 :: proc(a: ^Int, allocator := context.allocator) -> (res: u32, err: Error) {
/*
Check that `a` is usable.
*/
- assert_if_nil(a);
- return int_get(a, u32, allocator);
+ assert_if_nil(a)
+ return int_get(a, u32, allocator)
}
-get_u32 :: proc { int_get_u32, };
+get_u32 :: proc { int_get_u32, }
int_get_i32 :: proc(a: ^Int, allocator := context.allocator) -> (res: i32, err: Error) {
/*
Check that `a` is usable.
*/
- assert_if_nil(a);
- return int_get(a, i32, allocator);
+ assert_if_nil(a)
+ return int_get(a, i32, allocator)
}
-get_i32 :: proc { int_get_i32, };
+get_i32 :: proc { int_get_i32, }
/*
TODO: Think about using `count_bits` to check if the value could be returned completely,
@@ -304,19 +304,19 @@ int_get :: proc(a: ^Int, $T: typeid, allocator := context.allocator) -> (res: T,
/*
Check that `a` is usable.
*/
- assert_if_nil(a);
+ assert_if_nil(a)
#force_inline internal_clear_if_uninitialized(a, allocator) or_return;
- return #force_inline internal_int_get(a, T);
+ return #force_inline internal_int_get(a, T)
}
-get :: proc { int_get, };
+get :: proc { int_get, }
int_get_float :: proc(a: ^Int, allocator := context.allocator) -> (res: f64, err: Error) {
/*
Check that `a` is usable.
*/
- assert_if_nil(a);
+ assert_if_nil(a)
#force_inline internal_clear_if_uninitialized(a, allocator) or_return;
- return #force_inline internal_int_get_float(a);
+ return #force_inline internal_int_get_float(a)
}
/*
@@ -326,9 +326,9 @@ count_bits :: proc(a: ^Int, allocator := context.allocator) -> (count: int, err:
/*
Check that `a` is usable.
*/
- assert_if_nil(a);
+ assert_if_nil(a)
#force_inline internal_clear_if_uninitialized(a, allocator) or_return;
- return #force_inline internal_count_bits(a), nil;
+ return #force_inline internal_count_bits(a), nil
}
/*
@@ -339,109 +339,109 @@ int_count_lsb :: proc(a: ^Int, allocator := context.allocator) -> (count: int, e
/*
Check that `a` is usable.
*/
- assert_if_nil(a);
+ assert_if_nil(a)
#force_inline internal_clear_if_uninitialized(a, allocator) or_return;
- return #force_inline internal_int_count_lsb(a);
+ return #force_inline internal_int_count_lsb(a)
}
platform_count_lsb :: #force_inline proc(a: $T) -> (count: int)
where intrinsics.type_is_integer(T) && intrinsics.type_is_unsigned(T) {
- return int(intrinsics.count_trailing_zeros(a)) if a > 0 else 0;
+ return int(intrinsics.count_trailing_zeros(a)) if a > 0 else 0
}
-count_lsb :: proc { int_count_lsb, platform_count_lsb, };
+count_lsb :: proc { int_count_lsb, platform_count_lsb, }
int_random_digit :: proc(r: ^rnd.Rand = nil) -> (res: DIGIT) {
when _DIGIT_BITS == 60 { // DIGIT = u64
- return DIGIT(rnd.uint64(r)) & _MASK;
+ return DIGIT(rnd.uint64(r)) & _MASK
} else when _DIGIT_BITS == 28 { // DIGIT = u32
- return DIGIT(rnd.uint32(r)) & _MASK;
+ return DIGIT(rnd.uint32(r)) & _MASK
} else {
- panic("Unsupported DIGIT size.");
+ panic("Unsupported DIGIT size.")
}
- return 0; // We shouldn't get here.
+ return 0 // We shouldn't get here.
}
int_rand :: proc(dest: ^Int, bits: int, r: ^rnd.Rand = nil, allocator := context.allocator) -> (err: Error) {
/*
Check that `a` is usable.
*/
- assert_if_nil(dest);
- return #force_inline internal_int_rand(dest, bits, r, allocator);
+ assert_if_nil(dest)
+ return #force_inline internal_int_rand(dest, bits, r, allocator)
}
-rand :: proc { int_rand, };
+rand :: proc { int_rand, }
/*
Internal helpers.
*/
assert_initialized :: proc(a: ^Int, loc := #caller_location) {
- assert_if_nil(a);
- assert(is_initialized(a), "`Int` was not properly initialized.", loc);
+ assert_if_nil(a)
+ assert(is_initialized(a), "`Int` was not properly initialized.", loc)
}
zero_unused :: proc(dest: ^Int, old_used := -1) {
- assert_if_nil(dest);
+ assert_if_nil(dest)
if ! #force_inline is_initialized(dest) { return; }
#force_inline internal_zero_unused(dest, old_used);
}
clear_if_uninitialized_single :: proc(arg: ^Int, allocator := context.allocator) -> (err: Error) {
- assert_if_nil(arg);
- return #force_inline internal_clear_if_uninitialized_single(arg, allocator);
+ assert_if_nil(arg)
+ return #force_inline internal_clear_if_uninitialized_single(arg, allocator)
}
clear_if_uninitialized_multi :: proc(args: ..^Int, allocator := context.allocator) -> (err: Error) {
- args := args;
- assert_if_nil(..args);
+ args := args
+ assert_if_nil(..args)
for i in &args {
#force_inline internal_clear_if_uninitialized_single(i, allocator) or_return;
}
- return err;
+ return err
}
-clear_if_uninitialized :: proc {clear_if_uninitialized_single, clear_if_uninitialized_multi, };
+clear_if_uninitialized :: proc {clear_if_uninitialized_single, clear_if_uninitialized_multi, }
error_if_immutable_single :: proc(arg: ^Int) -> (err: Error) {
if arg != nil && .Immutable in arg.flags { return .Assignment_To_Immutable; }
- return nil;
+ return nil
}
error_if_immutable_multi :: proc(args: ..^Int) -> (err: Error) {
for i in args {
if i != nil && .Immutable in i.flags { return .Assignment_To_Immutable; }
}
- return nil;
+ return nil
}
-error_if_immutable :: proc {error_if_immutable_single, error_if_immutable_multi, };
+error_if_immutable :: proc {error_if_immutable_single, error_if_immutable_multi, }
/*
Allocates several `Int`s at once.
*/
int_init_multi :: proc(integers: ..^Int, allocator := context.allocator) -> (err: Error) {
- assert_if_nil(..integers);
+ assert_if_nil(..integers)
- integers := integers;
+ integers := integers
for a in &integers {
#force_inline internal_clear(a, true, allocator) or_return;
}
- return nil;
+ return nil
}
-init_multi :: proc { int_init_multi, };
+init_multi :: proc { int_init_multi, }
copy_digits :: proc(dest, src: ^Int, digits: int, offset := int(0), allocator := context.allocator) -> (err: Error) {
- context.allocator = allocator;
+ context.allocator = allocator
/*
Check that `src` is usable and `dest` isn't immutable.
*/
- assert_if_nil(dest, src);
+ assert_if_nil(dest, src)
#force_inline internal_clear_if_uninitialized(src) or_return;
- return #force_inline internal_copy_digits(dest, src, digits, offset);
+ return #force_inline internal_copy_digits(dest, src, digits, offset)
}
/*
@@ -451,17 +451,17 @@ copy_digits :: proc(dest, src: ^Int, digits: int, offset := int(0), allocator :=
Typically very fast. Also fixes the sign if there are no more leading digits.
*/
clamp :: proc(a: ^Int, allocator := context.allocator) -> (err: Error) {
- assert_if_nil(a);
+ assert_if_nil(a)
#force_inline internal_clear_if_uninitialized(a, allocator) or_return;
for a.used > 0 && a.digit[a.used - 1] == 0 {
- a.used -= 1;
+ a.used -= 1
}
if z, _ := is_zero(a); z {
- a.sign = .Zero_or_Positive;
+ a.sign = .Zero_or_Positive
}
- return nil;
+ return nil
}
@@ -469,15 +469,15 @@ clamp :: proc(a: ^Int, allocator := context.allocator) -> (err: Error) {
Size binary representation
*/
int_to_bytes_size :: proc(a: ^Int, signed := false, allocator := context.allocator) -> (size_in_bytes: int, err: Error) {
- assert_if_nil(a);
+ assert_if_nil(a)
#force_inline internal_clear_if_uninitialized(a, allocator) or_return;
- size_in_bits := internal_count_bits(a);
+ size_in_bits := internal_count_bits(a)
- size_in_bytes = (size_in_bits / 8);
- size_in_bytes += 0 if size_in_bits % 8 == 0 else 1;
- size_in_bytes += 1 if signed else 0;
- return;
+ size_in_bytes = (size_in_bits / 8)
+ size_in_bytes += 0 if size_in_bits % 8 == 0 else 1
+ size_in_bytes += 1 if signed else 0
+ return
}
/*
@@ -485,22 +485,22 @@ int_to_bytes_size :: proc(a: ^Int, signed := false, allocator := context.allocat
If `a` is negative and we ask for the default unsigned representation, we return abs(a).
*/
int_to_bytes_little :: proc(a: ^Int, buf: []u8, signed := false, allocator := context.allocator) -> (err: Error) {
- assert_if_nil(a);
+ assert_if_nil(a)
- size_in_bytes := int_to_bytes_size(a, signed, allocator) or_return;
- l := len(buf);
+ size_in_bytes := int_to_bytes_size(a, signed, allocator) or_return
+ l := len(buf)
if size_in_bytes > l { return .Buffer_Overflow; }
- size_in_bits := internal_count_bits(a);
- i := 0;
+ size_in_bits := internal_count_bits(a)
+ i := 0
if signed {
- buf[l - 1] = 1 if a.sign == .Negative else 0;
+ buf[l - 1] = 1 if a.sign == .Negative else 0
}
for offset := 0; offset < size_in_bits; offset += 8 {
- bits, _ := internal_int_bitfield_extract(a, offset, 8);
- buf[i] = u8(bits & 255); i += 1;
+ bits, _ := internal_int_bitfield_extract(a, offset, 8)
+ buf[i] = u8(bits & 255); i += 1
}
- return;
+ return
}
/*
@@ -508,23 +508,23 @@ int_to_bytes_little :: proc(a: ^Int, buf: []u8, signed := false, allocator := co
If `a` is negative and we ask for the default unsigned representation, we return abs(a).
*/
int_to_bytes_big :: proc(a: ^Int, buf: []u8, signed := false, allocator := context.allocator) -> (err: Error) {
- assert_if_nil(a);
+ assert_if_nil(a)
- size_in_bytes := int_to_bytes_size(a, signed, allocator) or_return;
- l := len(buf);
+ size_in_bytes := int_to_bytes_size(a, signed, allocator) or_return
+ l := len(buf)
if size_in_bytes > l { return .Buffer_Overflow; }
- size_in_bits := internal_count_bits(a);
- i := l - 1;
+ size_in_bits := internal_count_bits(a)
+ i := l - 1
if signed {
- buf[0] = 1 if a.sign == .Negative else 0;
+ buf[0] = 1 if a.sign == .Negative else 0
}
for offset := 0; offset < size_in_bits; offset += 8 {
- bits, _ := internal_int_bitfield_extract(a, offset, 8);
- buf[i] = u8(bits & 255); i -= 1;
+ bits, _ := internal_int_bitfield_extract(a, offset, 8)
+ buf[i] = u8(bits & 255); i -= 1
}
- return;
+ return
}
/*
@@ -532,35 +532,35 @@ int_to_bytes_big :: proc(a: ^Int, buf: []u8, signed := false, allocator := conte
If `a` is negative when asking for an unsigned number, we return an error like Python does.
*/
int_to_bytes_little_python :: proc(a: ^Int, buf: []u8, signed := false, allocator := context.allocator) -> (err: Error) {
- assert_if_nil(a);
+ assert_if_nil(a)
if !signed && a.sign == .Negative { return .Invalid_Argument; }
- l := len(buf);
- size_in_bytes := int_to_bytes_size(a, signed, allocator) or_return;
+ l := len(buf)
+ size_in_bytes := int_to_bytes_size(a, signed, allocator) or_return
if size_in_bytes > l { return .Buffer_Overflow; }
if a.sign == .Negative {
- t := &Int{};
- defer destroy(t);
- internal_complement(t, a, allocator) or_return;
+ t := &Int{}
+ defer destroy(t)
+ internal_complement(t, a, allocator) or_return
- size_in_bits := internal_count_bits(t);
- i := 0;
+ size_in_bits := internal_count_bits(t)
+ i := 0
for offset := 0; offset < size_in_bits; offset += 8 {
- bits, _ := internal_int_bitfield_extract(t, offset, 8);
- buf[i] = 255 - u8(bits & 255); i += 1;
+ bits, _ := internal_int_bitfield_extract(t, offset, 8)
+ buf[i] = 255 - u8(bits & 255); i += 1
}
- buf[l-1] = 255;
+ buf[l-1] = 255
} else {
- size_in_bits := internal_count_bits(a);
- i := 0;
+ size_in_bits := internal_count_bits(a)
+ i := 0
for offset := 0; offset < size_in_bits; offset += 8 {
- bits, _ := internal_int_bitfield_extract(a, offset, 8);
- buf[i] = u8(bits & 255); i += 1;
+ bits, _ := internal_int_bitfield_extract(a, offset, 8)
+ buf[i] = u8(bits & 255); i += 1
}
}
- return;
+ return
}
/*
@@ -568,29 +568,29 @@ int_to_bytes_little_python :: proc(a: ^Int, buf: []u8, signed := false, allocato
If `a` is negative when asking for an unsigned number, we return an error like Python does.
*/
int_to_bytes_big_python :: proc(a: ^Int, buf: []u8, signed := false, allocator := context.allocator) -> (err: Error) {
- assert_if_nil(a);
+ assert_if_nil(a)
if !signed && a.sign == .Negative { return .Invalid_Argument; }
if a.sign == .Zero_or_Positive { return int_to_bytes_big(a, buf, signed, allocator); }
- l := len(buf);
- size_in_bytes := int_to_bytes_size(a, signed, allocator) or_return;
+ l := len(buf)
+ size_in_bytes := int_to_bytes_size(a, signed, allocator) or_return
if size_in_bytes > l { return .Buffer_Overflow; }
- t := &Int{};
- defer destroy(t);
+ t := &Int{}
+ defer destroy(t)
- internal_complement(t, a, allocator) or_return;
+ internal_complement(t, a, allocator) or_return
- size_in_bits := internal_count_bits(t);
- i := l - 1;
+ size_in_bits := internal_count_bits(t)
+ i := l - 1
for offset := 0; offset < size_in_bits; offset += 8 {
- bits, _ := internal_int_bitfield_extract(t, offset, 8);
- buf[i] = 255 - u8(bits & 255); i -= 1;
+ bits, _ := internal_int_bitfield_extract(t, offset, 8)
+ buf[i] = 255 - u8(bits & 255); i -= 1
}
- buf[0] = 255;
+ buf[0] = 255
- return;
+ return
}
/*
@@ -598,36 +598,36 @@ int_to_bytes_big_python :: proc(a: ^Int, buf: []u8, signed := false, allocator :
Sign is detected from the first byte if `signed` is true.
*/
int_from_bytes_big :: proc(a: ^Int, buf: []u8, signed := false, allocator := context.allocator) -> (err: Error) {
- assert_if_nil(a);
- buf := buf;
- l := len(buf);
+ assert_if_nil(a)
+ buf := buf
+ l := len(buf)
if l == 0 { return .Invalid_Argument; }
- sign: Sign;
- size_in_bits := l * 8;
+ sign: Sign
+ size_in_bits := l * 8
if signed {
/*
First byte denotes the sign.
*/
- size_in_bits -= 8;
+ size_in_bits -= 8
}
- size_in_digits := (size_in_bits + _DIGIT_BITS - 1) / _DIGIT_BITS;
- size_in_digits += 0 if size_in_bits % 8 == 0 else 1;
- internal_zero(a, false, allocator) or_return;
- internal_grow(a, size_in_digits, false, allocator) or_return;
+ size_in_digits := (size_in_bits + _DIGIT_BITS - 1) / _DIGIT_BITS
+ size_in_digits += 0 if size_in_bits % 8 == 0 else 1
+ internal_zero(a, false, allocator) or_return
+ internal_grow(a, size_in_digits, false, allocator) or_return
if signed {
- sign = .Zero_or_Positive if buf[0] == 0 else .Negative;
- buf = buf[1:];
+ sign = .Zero_or_Positive if buf[0] == 0 else .Negative
+ buf = buf[1:]
}
for v in buf {
- internal_shl(a, a, 8) or_return;
- a.digit[0] |= DIGIT(v);
+ internal_shl(a, a, 8) or_return
+ a.digit[0] |= DIGIT(v)
}
- a.sign = sign;
- a.used = size_in_digits;
- return internal_clamp(a);
+ a.sign = sign
+ a.used = size_in_digits
+ return internal_clamp(a)
}
/*
@@ -635,45 +635,45 @@ int_from_bytes_big :: proc(a: ^Int, buf: []u8, signed := false, allocator := con
Sign is detected from the first byte if `signed` is true.
*/
int_from_bytes_big_python :: proc(a: ^Int, buf: []u8, signed := false, allocator := context.allocator) -> (err: Error) {
- assert_if_nil(a);
- buf := buf;
- l := len(buf);
+ assert_if_nil(a)
+ buf := buf
+ l := len(buf)
if l == 0 { return .Invalid_Argument; }
- sign: Sign;
- size_in_bits := l * 8;
+ sign: Sign
+ size_in_bits := l * 8
if signed {
/*
First byte denotes the sign.
*/
- size_in_bits -= 8;
+ size_in_bits -= 8
}
- size_in_digits := (size_in_bits + _DIGIT_BITS - 1) / _DIGIT_BITS;
- size_in_digits += 0 if size_in_bits % 8 == 0 else 1;
- internal_zero(a, false, allocator) or_return;
- internal_grow(a, size_in_digits, false, allocator) or_return;
+ size_in_digits := (size_in_bits + _DIGIT_BITS - 1) / _DIGIT_BITS
+ size_in_digits += 0 if size_in_bits % 8 == 0 else 1
+ internal_zero(a, false, allocator) or_return
+ internal_grow(a, size_in_digits, false, allocator) or_return
if signed {
- sign = .Zero_or_Positive if buf[0] == 0 else .Negative;
- buf = buf[1:];
+ sign = .Zero_or_Positive if buf[0] == 0 else .Negative
+ buf = buf[1:]
}
for v in buf {
- internal_shl(a, a, 8) or_return;
+ internal_shl(a, a, 8) or_return
if signed && sign == .Negative {
- a.digit[0] |= DIGIT(255 - v);
+ a.digit[0] |= DIGIT(255 - v)
} else {
- a.digit[0] |= DIGIT(v);
+ a.digit[0] |= DIGIT(v)
}
}
- a.sign = sign;
- a.used = size_in_digits;
- internal_clamp(a) or_return;
+ a.sign = sign
+ a.used = size_in_digits
+ internal_clamp(a) or_return
if signed && sign == .Negative {
- return internal_sub(a, a, 1);
+ return internal_sub(a, a, 1)
}
- return nil;
+ return nil
}
/*
@@ -681,37 +681,37 @@ int_from_bytes_big_python :: proc(a: ^Int, buf: []u8, signed := false, allocator
Sign is detected from the last byte if `signed` is true.
*/
int_from_bytes_little :: proc(a: ^Int, buf: []u8, signed := false, allocator := context.allocator) -> (err: Error) {
- assert_if_nil(a);
- buf := buf;
- l := len(buf);
+ assert_if_nil(a)
+ buf := buf
+ l := len(buf)
if l == 0 { return .Invalid_Argument; }
- sign: Sign;
- size_in_bits := l * 8;
+ sign: Sign
+ size_in_bits := l * 8
if signed {
/*
First byte denotes the sign.
*/
- size_in_bits -= 8;
+ size_in_bits -= 8
}
- size_in_digits := (size_in_bits + _DIGIT_BITS - 1) / _DIGIT_BITS;
- size_in_digits += 0 if size_in_bits % 8 == 0 else 1;
- internal_zero(a, false, allocator) or_return;
- internal_grow(a, size_in_digits, false, allocator) or_return;
+ size_in_digits := (size_in_bits + _DIGIT_BITS - 1) / _DIGIT_BITS
+ size_in_digits += 0 if size_in_bits % 8 == 0 else 1
+ internal_zero(a, false, allocator) or_return
+ internal_grow(a, size_in_digits, false, allocator) or_return
if signed {
- sign = .Zero_or_Positive if buf[l-1] == 0 else .Negative;
- buf = buf[:l-1];
- l -= 1;
+ sign = .Zero_or_Positive if buf[l-1] == 0 else .Negative
+ buf = buf[:l-1]
+ l -= 1
}
for _, i in buf {
- internal_shl(a, a, 8) or_return;
- a.digit[0] |= DIGIT(buf[l-i-1]);
+ internal_shl(a, a, 8) or_return
+ a.digit[0] |= DIGIT(buf[l-i-1])
}
- a.sign = sign;
- a.used = size_in_digits;
- return internal_clamp(a);
+ a.sign = sign
+ a.used = size_in_digits
+ return internal_clamp(a)
}
/*
@@ -719,67 +719,67 @@ int_from_bytes_little :: proc(a: ^Int, buf: []u8, signed := false, allocator :=
Sign is detected from the first byte if `signed` is true.
*/
int_from_bytes_little_python :: proc(a: ^Int, buf: []u8, signed := false, allocator := context.allocator) -> (err: Error) {
- assert_if_nil(a);
- buf := buf;
- l := len(buf);
+ assert_if_nil(a)
+ buf := buf
+ l := len(buf)
if l == 0 { return .Invalid_Argument; }
- sign: Sign;
- size_in_bits := l * 8;
+ sign: Sign
+ size_in_bits := l * 8
if signed {
/*
First byte denotes the sign.
*/
- size_in_bits -= 8;
+ size_in_bits -= 8
}
- size_in_digits := (size_in_bits + _DIGIT_BITS - 1) / _DIGIT_BITS;
- size_in_digits += 0 if size_in_bits % 8 == 0 else 1;
- internal_zero(a, false, allocator) or_return;
- internal_grow(a, size_in_digits, false, allocator) or_return;
+ size_in_digits := (size_in_bits + _DIGIT_BITS - 1) / _DIGIT_BITS
+ size_in_digits += 0 if size_in_bits % 8 == 0 else 1
+ internal_zero(a, false, allocator) or_return
+ internal_grow(a, size_in_digits, false, allocator) or_return
if signed {
- sign = .Zero_or_Positive if buf[l-1] == 0 else .Negative;
- buf = buf[:l-1];
- l -= 1;
+ sign = .Zero_or_Positive if buf[l-1] == 0 else .Negative
+ buf = buf[:l-1]
+ l -= 1
}
for _, i in buf {
- internal_shl(a, a, 8) or_return;
+ internal_shl(a, a, 8) or_return
if signed && sign == .Negative {
- a.digit[0] |= DIGIT(255 - buf[l-i-1]);
+ a.digit[0] |= DIGIT(255 - buf[l-i-1])
} else {
- a.digit[0] |= DIGIT(buf[l-i-1]);
+ a.digit[0] |= DIGIT(buf[l-i-1])
}
}
- a.sign = sign;
- a.used = size_in_digits;
- internal_clamp(a) or_return;
+ a.sign = sign
+ a.used = size_in_digits
+ internal_clamp(a) or_return
if signed && sign == .Negative {
- return internal_sub(a, a, 1);
+ return internal_sub(a, a, 1)
}
- return nil;
+ return nil
}
/*
Initialize constants.
*/
-INT_ONE, INT_ZERO, INT_MINUS_ONE, INT_INF, INT_MINUS_INF, INT_NAN := &Int{}, &Int{}, &Int{}, &Int{}, &Int{}, &Int{};
+INT_ONE, INT_ZERO, INT_MINUS_ONE, INT_INF, INT_MINUS_INF, INT_NAN := &Int{}, &Int{}, &Int{}, &Int{}, &Int{}, &Int{}
initialize_constants :: proc() -> (res: int) {
- internal_set( INT_ZERO, 0); INT_ZERO.flags = {.Immutable};
- internal_set( INT_ONE, 1); INT_ONE.flags = {.Immutable};
- internal_set(INT_MINUS_ONE, -1); INT_MINUS_ONE.flags = {.Immutable};
+ internal_set( INT_ZERO, 0); INT_ZERO.flags = {.Immutable}
+ internal_set( INT_ONE, 1); INT_ONE.flags = {.Immutable}
+ internal_set(INT_MINUS_ONE, -1); INT_MINUS_ONE.flags = {.Immutable}
/*
We set these special values to -1 or 1 so they don't get mistake for zero accidentally.
This allows for shortcut tests of is_zero as .used == 0.
*/
- internal_set( INT_NAN, 1); INT_NAN.flags = {.Immutable, .NaN};
- internal_set( INT_INF, 1); INT_INF.flags = {.Immutable, .Inf};
- internal_set( INT_INF, -1); INT_MINUS_INF.flags = {.Immutable, .Inf};
+ internal_set( INT_NAN, 1); INT_NAN.flags = {.Immutable, .NaN}
+ internal_set( INT_INF, 1); INT_INF.flags = {.Immutable, .Inf}
+ internal_set( INT_INF, -1); INT_MINUS_INF.flags = {.Immutable, .Inf}
- return _DEFAULT_MUL_KARATSUBA_CUTOFF;
+ return _DEFAULT_MUL_KARATSUBA_CUTOFF
}
/*
@@ -787,14 +787,14 @@ initialize_constants :: proc() -> (res: int) {
Optional for an EXE, as this would be called at the very end of a process.
*/
destroy_constants :: proc() {
- internal_destroy(INT_ONE, INT_ZERO, INT_MINUS_ONE, INT_INF, INT_MINUS_INF, INT_NAN);
+ internal_destroy(INT_ONE, INT_ZERO, INT_MINUS_ONE, INT_INF, INT_MINUS_INF, INT_NAN)
}
assert_if_nil :: #force_inline proc(integers: ..^Int, loc := #caller_location) {
- integers := integers;
+ integers := integers
for i in &integers {
- assert(i != nil, "(nil)", loc);
+ assert(i != nil, "(nil)", loc)
}
}
diff --git a/core/math/big/internal.odin b/core/math/big/internal.odin
index 9422067ae..033bc11a2 100644
--- a/core/math/big/internal.odin
+++ b/core/math/big/internal.odin
@@ -43,43 +43,43 @@ import rnd "core:math/rand"
`dest`, `a` and `b` != `nil` and have been initalized.
*/
internal_int_add_unsigned :: proc(dest, a, b: ^Int, allocator := context.allocator) -> (err: Error) {
- dest := dest; x := a; y := b;
- context.allocator = allocator;
+ dest := dest; x := a; y := b
+ context.allocator = allocator
- old_used, min_used, max_used, i: int;
+ old_used, min_used, max_used, i: int
if x.used < y.used {
- x, y = y, x;
+ x, y = y, x
}
- min_used = y.used;
- max_used = x.used;
- old_used = dest.used;
+ min_used = y.used
+ max_used = x.used
+ old_used = dest.used
- internal_grow(dest, max(max_used + 1, _DEFAULT_DIGIT_COUNT)) or_return;
- dest.used = max_used + 1;
+ internal_grow(dest, max(max_used + 1, _DEFAULT_DIGIT_COUNT)) or_return
+ dest.used = max_used + 1
/*
All parameters have been initialized.
*/
/* Zero the carry */
- carry := DIGIT(0);
+ carry := DIGIT(0)
#no_bounds_check for i = 0; i < min_used; i += 1 {
/*
Compute the sum one _DIGIT at a time.
dest[i] = a[i] + b[i] + carry;
*/
- dest.digit[i] = x.digit[i] + y.digit[i] + carry;
+ dest.digit[i] = x.digit[i] + y.digit[i] + carry
/*
Compute carry
*/
- carry = dest.digit[i] >> _DIGIT_BITS;
+ carry = dest.digit[i] >> _DIGIT_BITS
/*
Mask away carry from result digit.
*/
- dest.digit[i] &= _MASK;
+ dest.digit[i] &= _MASK
}
if min_used != max_used {
@@ -88,32 +88,32 @@ internal_int_add_unsigned :: proc(dest, a, b: ^Int, allocator := context.allocat
If A or B has more digits, add those in.
*/
#no_bounds_check for ; i < max_used; i += 1 {
- dest.digit[i] = x.digit[i] + carry;
+ dest.digit[i] = x.digit[i] + carry
/*
Compute carry
*/
- carry = dest.digit[i] >> _DIGIT_BITS;
+ carry = dest.digit[i] >> _DIGIT_BITS
/*
Mask away carry from result digit.
*/
- dest.digit[i] &= _MASK;
+ dest.digit[i] &= _MASK
}
}
/*
Add remaining carry.
*/
- dest.digit[i] = carry;
+ dest.digit[i] = carry
/*
Zero remainder.
*/
- internal_zero_unused(dest, old_used);
+ internal_zero_unused(dest, old_used)
/*
Adjust dest.used based on leading zeroes.
*/
- return internal_clamp(dest);
+ return internal_clamp(dest)
}
-internal_add_unsigned :: proc { internal_int_add_unsigned, };
+internal_add_unsigned :: proc { internal_int_add_unsigned, }
/*
Low-level addition, signed. Handbook of Applied Cryptography, algorithm 14.7.
@@ -122,14 +122,14 @@ internal_add_unsigned :: proc { internal_int_add_unsigned, };
`dest`, `a` and `b` != `nil` and have been initalized.
*/
internal_int_add_signed :: proc(dest, a, b: ^Int, allocator := context.allocator) -> (err: Error) {
- x := a; y := b;
- context.allocator = allocator;
+ x := a; y := b
+ context.allocator = allocator
/*
Handle both negative or both positive.
*/
if x.sign == y.sign {
- dest.sign = x.sign;
- return #force_inline internal_int_add_unsigned(dest, x, y);
+ dest.sign = x.sign
+ return #force_inline internal_int_add_unsigned(dest, x, y)
}
/*
@@ -138,13 +138,13 @@ internal_int_add_signed :: proc(dest, a, b: ^Int, allocator := context.allocator
The result gets the sign of the one with the greater magnitude.
*/
if #force_inline internal_cmp_mag(a, b) == -1 {
- x, y = y, x;
+ x, y = y, x
}
- dest.sign = x.sign;
- return #force_inline internal_int_sub_unsigned(dest, x, y);
+ dest.sign = x.sign
+ return #force_inline internal_int_sub_unsigned(dest, x, y)
}
-internal_add_signed :: proc { internal_int_add_signed, };
+internal_add_signed :: proc { internal_int_add_signed, }
/*
Low-level addition Int+DIGIT, signed. Handbook of Applied Cryptography, algorithm 14.7.
@@ -154,9 +154,9 @@ internal_add_signed :: proc { internal_int_add_signed, };
`dest` is large enough (a.used + 1) to fit result.
*/
internal_int_add_digit :: proc(dest, a: ^Int, digit: DIGIT, allocator := context.allocator) -> (err: Error) {
- context.allocator = allocator;
+ context.allocator = allocator
- internal_grow(dest, a.used + 1) or_return;
+ internal_grow(dest, a.used + 1) or_return
/*
Fast paths for destination and input Int being the same.
*/
@@ -165,17 +165,17 @@ internal_int_add_digit :: proc(dest, a: ^Int, digit: DIGIT, allocator := context
Fast path for dest.digit[0] + digit fits in dest.digit[0] without overflow.
*/
if dest.sign == .Zero_or_Positive && (dest.digit[0] + digit < _DIGIT_MAX) {
- dest.digit[0] += digit;
- dest.used += 1;
- return internal_clamp(dest);
+ dest.digit[0] += digit
+ dest.used += 1
+ return internal_clamp(dest)
}
/*
Can be subtracted from dest.digit[0] without underflow.
*/
if a.sign == .Negative && (dest.digit[0] > digit) {
- dest.digit[0] -= digit;
- dest.used += 1;
- return internal_clamp(dest);
+ dest.digit[0] -= digit
+ dest.used += 1
+ return internal_clamp(dest)
}
}
@@ -186,7 +186,7 @@ internal_int_add_digit :: proc(dest, a: ^Int, digit: DIGIT, allocator := context
/*
Temporarily fix `a`'s sign.
*/
- a.sign = .Zero_or_Positive;
+ a.sign = .Zero_or_Positive
/*
dest = |a| - digit
*/
@@ -194,22 +194,22 @@ internal_int_add_digit :: proc(dest, a: ^Int, digit: DIGIT, allocator := context
/*
Restore a's sign.
*/
- a.sign = .Negative;
- return err;
+ a.sign = .Negative
+ return err
}
/*
Restore sign and set `dest` sign.
*/
- a.sign = .Negative;
- dest.sign = .Negative;
+ a.sign = .Negative
+ dest.sign = .Negative
- return internal_clamp(dest);
+ return internal_clamp(dest)
}
/*
Remember the currently used number of digits in `dest`.
*/
- old_used := dest.used;
+ old_used := dest.used
/*
If `a` is positive
@@ -218,53 +218,53 @@ internal_int_add_digit :: proc(dest, a: ^Int, digit: DIGIT, allocator := context
/*
Add digits, use `carry`.
*/
- i: int;
- carry := digit;
+ i: int
+ carry := digit
#no_bounds_check for i = 0; i < a.used; i += 1 {
- dest.digit[i] = a.digit[i] + carry;
- carry = dest.digit[i] >> _DIGIT_BITS;
- dest.digit[i] &= _MASK;
+ dest.digit[i] = a.digit[i] + carry
+ carry = dest.digit[i] >> _DIGIT_BITS
+ dest.digit[i] &= _MASK
}
/*
Set final carry.
*/
- dest.digit[i] = carry;
+ dest.digit[i] = carry
/*
Set `dest` size.
*/
- dest.used = a.used + 1;
+ dest.used = a.used + 1
} else {
/*
`a` was negative and |a| < digit.
*/
- dest.used = 1;
+ dest.used = 1
/*
The result is a single DIGIT.
*/
- dest.digit[0] = digit - a.digit[0] if a.used == 1 else digit;
+ dest.digit[0] = digit - a.digit[0] if a.used == 1 else digit
}
/*
Sign is always positive.
*/
- dest.sign = .Zero_or_Positive;
+ dest.sign = .Zero_or_Positive
/*
Zero remainder.
*/
- internal_zero_unused(dest, old_used);
+ internal_zero_unused(dest, old_used)
/*
Adjust dest.used based on leading zeroes.
*/
- return internal_clamp(dest);
+ return internal_clamp(dest)
}
-internal_add :: proc { internal_int_add_signed, internal_int_add_digit, };
+internal_add :: proc { internal_int_add_signed, internal_int_add_digit, }
internal_int_incr :: proc(dest: ^Int, allocator := context.allocator) -> (err: Error) {
- return #force_inline internal_add(dest, dest, 1);
+ return #force_inline internal_add(dest, dest, 1)
}
-internal_incr :: proc { internal_int_incr, };
+internal_incr :: proc { internal_int_incr, }
/*
Low-level subtraction, dest = number - decrease. Assumes |number| > |decrease|.
@@ -274,66 +274,66 @@ internal_incr :: proc { internal_int_incr, };
`dest`, `number` and `decrease` != `nil` and have been initalized.
*/
internal_int_sub_unsigned :: proc(dest, number, decrease: ^Int, allocator := context.allocator) -> (err: Error) {
- context.allocator = allocator;
+ context.allocator = allocator
- dest := dest; x := number; y := decrease;
- old_used := dest.used;
- min_used := y.used;
- max_used := x.used;
- i: int;
+ dest := dest; x := number; y := decrease
+ old_used := dest.used
+ min_used := y.used
+ max_used := x.used
+ i: int
- grow(dest, max(max_used, _DEFAULT_DIGIT_COUNT)) or_return;
- dest.used = max_used;
+ grow(dest, max(max_used, _DEFAULT_DIGIT_COUNT)) or_return
+ dest.used = max_used
/*
All parameters have been initialized.
*/
- borrow := DIGIT(0);
+ borrow := DIGIT(0)
#no_bounds_check for i = 0; i < min_used; i += 1 {
- dest.digit[i] = (x.digit[i] - y.digit[i] - borrow);
+ dest.digit[i] = (x.digit[i] - y.digit[i] - borrow)
/*
borrow = carry bit of dest[i]
Note this saves performing an AND operation since if a carry does occur,
it will propagate all the way to the MSB.
As a result a single shift is enough to get the carry.
*/
- borrow = dest.digit[i] >> ((size_of(DIGIT) * 8) - 1);
+ borrow = dest.digit[i] >> ((size_of(DIGIT) * 8) - 1)
/*
Clear borrow from dest[i].
*/
- dest.digit[i] &= _MASK;
+ dest.digit[i] &= _MASK
}
/*
Now copy higher words if any, e.g. if A has more digits than B
*/
#no_bounds_check for ; i < max_used; i += 1 {
- dest.digit[i] = x.digit[i] - borrow;
+ dest.digit[i] = x.digit[i] - borrow
/*
borrow = carry bit of dest[i]
Note this saves performing an AND operation since if a carry does occur,
it will propagate all the way to the MSB.
As a result a single shift is enough to get the carry.
*/
- borrow = dest.digit[i] >> ((size_of(DIGIT) * 8) - 1);
+ borrow = dest.digit[i] >> ((size_of(DIGIT) * 8) - 1)
/*
Clear borrow from dest[i].
*/
- dest.digit[i] &= _MASK;
+ dest.digit[i] &= _MASK
}
/*
Zero remainder.
*/
- internal_zero_unused(dest, old_used);
+ internal_zero_unused(dest, old_used)
/*
Adjust dest.used based on leading zeroes.
*/
- return internal_clamp(dest);
+ return internal_clamp(dest)
}
-internal_sub_unsigned :: proc { internal_int_sub_unsigned, };
+internal_sub_unsigned :: proc { internal_int_sub_unsigned, }
/*
Low-level subtraction, signed. Handbook of Applied Cryptography, algorithm 14.9.
@@ -343,16 +343,16 @@ internal_sub_unsigned :: proc { internal_int_sub_unsigned, };
`dest`, `number` and `decrease` != `nil` and have been initalized.
*/
internal_int_sub_signed :: proc(dest, number, decrease: ^Int, allocator := context.allocator) -> (err: Error) {
- context.allocator = allocator;
+ context.allocator = allocator
- number := number; decrease := decrease;
+ number := number; decrease := decrease
if number.sign != decrease.sign {
/*
Subtract a negative from a positive, OR subtract a positive from a negative.
In either case, ADD their magnitudes and use the sign of the first number.
*/
- dest.sign = number.sign;
- return #force_inline internal_int_add_unsigned(dest, number, decrease);
+ dest.sign = number.sign
+ return #force_inline internal_int_add_unsigned(dest, number, decrease)
}
/*
@@ -364,16 +364,16 @@ internal_int_sub_signed :: proc(dest, number, decrease: ^Int, allocator := conte
The second has a larger magnitude.
The result has the *opposite* sign from the first number.
*/
- dest.sign = .Negative if number.sign == .Zero_or_Positive else .Zero_or_Positive;
- number, decrease = decrease, number;
+ dest.sign = .Negative if number.sign == .Zero_or_Positive else .Zero_or_Positive
+ number, decrease = decrease, number
} else {
/*
The first has a larger or equal magnitude.
Copy the sign from the first.
*/
- dest.sign = number.sign;
+ dest.sign = number.sign
}
- return #force_inline internal_int_sub_unsigned(dest, number, decrease);
+ return #force_inline internal_int_sub_unsigned(dest, number, decrease)
}
/*
@@ -385,11 +385,11 @@ internal_int_sub_signed :: proc(dest, number, decrease: ^Int, allocator := conte
`dest` is large enough (number.used + 1) to fit result.
*/
internal_int_sub_digit :: proc(dest, number: ^Int, digit: DIGIT, allocator := context.allocator) -> (err: Error) {
- context.allocator = allocator;
+ context.allocator = allocator
- internal_grow(dest, number.used + 1) or_return;
+ internal_grow(dest, number.used + 1) or_return
- dest := dest; digit := digit;
+ dest := dest; digit := digit
/*
All parameters have been initialized.
@@ -400,15 +400,15 @@ internal_int_sub_digit :: proc(dest, number: ^Int, digit: DIGIT, allocator := co
Fast path for `dest` is negative and unsigned addition doesn't overflow the lowest digit.
*/
if dest.sign == .Negative && (dest.digit[0] + digit < _DIGIT_MAX) {
- dest.digit[0] += digit;
- return nil;
+ dest.digit[0] += digit
+ return nil
}
/*
Can be subtracted from dest.digit[0] without underflow.
*/
if number.sign == .Zero_or_Positive && (dest.digit[0] > digit) {
- dest.digit[0] -= digit;
- return nil;
+ dest.digit[0] -= digit
+ return nil
}
}
@@ -416,58 +416,58 @@ internal_int_sub_digit :: proc(dest, number: ^Int, digit: DIGIT, allocator := co
If `a` is negative, just do an unsigned addition (with fudged signs).
*/
if number.sign == .Negative {
- t := number;
- t.sign = .Zero_or_Positive;
+ t := number
+ t.sign = .Zero_or_Positive
- err = #force_inline internal_int_add_digit(dest, t, digit);
- dest.sign = .Negative;
+ err = #force_inline internal_int_add_digit(dest, t, digit)
+ dest.sign = .Negative
- internal_clamp(dest);
- return err;
+ internal_clamp(dest)
+ return err
}
- old_used := dest.used;
+ old_used := dest.used
/*
if `a`<= digit, simply fix the single digit.
*/
if number.used == 1 && (number.digit[0] <= digit) || number.used == 0 {
- dest.digit[0] = digit - number.digit[0] if number.used == 1 else digit;
- dest.sign = .Negative;
- dest.used = 1;
+ dest.digit[0] = digit - number.digit[0] if number.used == 1 else digit
+ dest.sign = .Negative
+ dest.used = 1
} else {
- dest.sign = .Zero_or_Positive;
- dest.used = number.used;
+ dest.sign = .Zero_or_Positive
+ dest.used = number.used
/*
Subtract with carry.
*/
- carry := digit;
+ carry := digit
#no_bounds_check for i := 0; i < number.used; i += 1 {
- dest.digit[i] = number.digit[i] - carry;
- carry = dest.digit[i] >> (_DIGIT_TYPE_BITS - 1);
- dest.digit[i] &= _MASK;
+ dest.digit[i] = number.digit[i] - carry
+ carry = dest.digit[i] >> (_DIGIT_TYPE_BITS - 1)
+ dest.digit[i] &= _MASK
}
}
/*
Zero remainder.
*/
- internal_zero_unused(dest, old_used);
+ internal_zero_unused(dest, old_used)
/*
Adjust dest.used based on leading zeroes.
*/
- return internal_clamp(dest);
+ return internal_clamp(dest)
}
-internal_sub :: proc { internal_int_sub_signed, internal_int_sub_digit, };
+internal_sub :: proc { internal_int_sub_signed, internal_int_sub_digit, }
internal_int_decr :: proc(dest: ^Int, allocator := context.allocator) -> (err: Error) {
- return #force_inline internal_sub(dest, dest, 1);
+ return #force_inline internal_sub(dest, dest, 1)
}
-internal_decr :: proc { internal_int_decr, };
+internal_decr :: proc { internal_int_decr, }
/*
dest = src / 2
@@ -477,38 +477,38 @@ internal_decr :: proc { internal_int_decr, };
We make no allocations here.
*/
internal_int_shr1 :: proc(dest, src: ^Int) -> (err: Error) {
- old_used := dest.used; dest.used = src.used;
+ old_used := dest.used; dest.used = src.used
/*
Carry
*/
- fwd_carry := DIGIT(0);
+ fwd_carry := DIGIT(0)
#no_bounds_check for x := dest.used - 1; x >= 0; x -= 1 {
/*
Get the carry for the next iteration.
*/
- src_digit := src.digit[x];
- carry := src_digit & 1;
+ src_digit := src.digit[x]
+ carry := src_digit & 1
/*
Shift the current digit, add in carry and store.
*/
- dest.digit[x] = (src_digit >> 1) | (fwd_carry << (_DIGIT_BITS - 1));
+ dest.digit[x] = (src_digit >> 1) | (fwd_carry << (_DIGIT_BITS - 1))
/*
Forward carry to next iteration.
*/
- fwd_carry = carry;
+ fwd_carry = carry
}
/*
Zero remainder.
*/
- internal_zero_unused(dest, old_used);
+ internal_zero_unused(dest, old_used)
/*
Adjust dest.used based on leading zeroes.
*/
- dest.sign = src.sign;
- return internal_clamp(dest);
+ dest.sign = src.sign
+ return internal_clamp(dest)
}
/*
@@ -516,121 +516,121 @@ internal_int_shr1 :: proc(dest, src: ^Int) -> (err: Error) {
dest = src << 1
*/
internal_int_shl1 :: proc(dest, src: ^Int, allocator := context.allocator) -> (err: Error) {
- context.allocator = allocator;
+ context.allocator = allocator
- internal_copy(dest, src) or_return;
+ internal_copy(dest, src) or_return
/*
Grow `dest` to accommodate the additional bits.
*/
- digits_needed := dest.used + 1;
- internal_grow(dest, digits_needed) or_return;
- dest.used = digits_needed;
+ digits_needed := dest.used + 1
+ internal_grow(dest, digits_needed) or_return
+ dest.used = digits_needed
- mask := (DIGIT(1) << uint(1)) - DIGIT(1);
- shift := DIGIT(_DIGIT_BITS - 1);
- carry := DIGIT(0);
+ mask := (DIGIT(1) << uint(1)) - DIGIT(1)
+ shift := DIGIT(_DIGIT_BITS - 1)
+ carry := DIGIT(0)
#no_bounds_check for x:= 0; x < dest.used; x+= 1 {
- fwd_carry := (dest.digit[x] >> shift) & mask;
- dest.digit[x] = (dest.digit[x] << uint(1) | carry) & _MASK;
- carry = fwd_carry;
+ fwd_carry := (dest.digit[x] >> shift) & mask
+ dest.digit[x] = (dest.digit[x] << uint(1) | carry) & _MASK
+ carry = fwd_carry
}
/*
Use final carry.
*/
if carry != 0 {
- dest.digit[dest.used] = carry;
- dest.used += 1;
+ dest.digit[dest.used] = carry
+ dest.used += 1
}
- return internal_clamp(dest);
+ return internal_clamp(dest)
}
/*
Multiply by a DIGIT.
*/
internal_int_mul_digit :: proc(dest, src: ^Int, multiplier: DIGIT, allocator := context.allocator) -> (err: Error) {
- context.allocator = allocator;
- assert_if_nil(dest, src);
+ context.allocator = allocator
+ assert_if_nil(dest, src)
if multiplier == 0 {
- return internal_zero(dest);
+ return internal_zero(dest)
}
if multiplier == 1 {
- return internal_copy(dest, src);
+ return internal_copy(dest, src)
}
/*
Power of two?
*/
if multiplier == 2 {
- return #force_inline internal_int_shl1(dest, src);
+ return #force_inline internal_int_shl1(dest, src)
}
if #force_inline platform_int_is_power_of_two(int(multiplier)) {
- ix := internal_log(multiplier, 2) or_return;
- return internal_shl(dest, src, ix);
+ ix := internal_log(multiplier, 2) or_return
+ return internal_shl(dest, src, ix)
}
/*
Ensure `dest` is big enough to hold `src` * `multiplier`.
*/
- grow(dest, max(src.used + 1, _DEFAULT_DIGIT_COUNT)) or_return;
+ grow(dest, max(src.used + 1, _DEFAULT_DIGIT_COUNT)) or_return
/*
Save the original used count.
*/
- old_used := dest.used;
+ old_used := dest.used
/*
Set the sign.
*/
- dest.sign = src.sign;
+ dest.sign = src.sign
/*
Set up carry.
*/
- carry := _WORD(0);
+ carry := _WORD(0)
/*
Compute columns.
*/
- ix := 0;
+ ix := 0
#no_bounds_check for ; ix < src.used; ix += 1 {
/*
Compute product and carry sum for this term
*/
- product := carry + _WORD(src.digit[ix]) * _WORD(multiplier);
+ product := carry + _WORD(src.digit[ix]) * _WORD(multiplier)
/*
Mask off higher bits to get a single DIGIT.
*/
- dest.digit[ix] = DIGIT(product & _WORD(_MASK));
+ dest.digit[ix] = DIGIT(product & _WORD(_MASK))
/*
Send carry into next iteration
*/
- carry = product >> _DIGIT_BITS;
+ carry = product >> _DIGIT_BITS
}
/*
Store final carry [if any] and increment used.
*/
- dest.digit[ix] = DIGIT(carry);
- dest.used = src.used + 1;
+ dest.digit[ix] = DIGIT(carry)
+ dest.used = src.used + 1
/*
Zero remainder.
*/
- internal_zero_unused(dest, old_used);
+ internal_zero_unused(dest, old_used)
- return internal_clamp(dest);
+ return internal_clamp(dest)
}
/*
High level multiplication (handles sign).
*/
internal_int_mul :: proc(dest, src, multiplier: ^Int, allocator := context.allocator) -> (err: Error) {
- context.allocator = allocator;
+ context.allocator = allocator
/*
Early out for `multiplier` is zero; Set `dest` to zero.
*/
if multiplier.used == 0 || src.used == 0 { return internal_zero(dest); }
- neg := src.sign != multiplier.sign;
+ neg := src.sign != multiplier.sign
if src == multiplier {
/*
@@ -640,19 +640,19 @@ internal_int_mul :: proc(dest, src, multiplier: ^Int, allocator := context.alloc
/*
Use Toom-Cook?
*/
- err = #force_inline _private_int_sqr_toom(dest, src);
+ err = #force_inline _private_int_sqr_toom(dest, src)
} else if src.used >= SQR_KARATSUBA_CUTOFF {
/*
Karatsuba?
*/
- err = #force_inline _private_int_sqr_karatsuba(dest, src);
+ err = #force_inline _private_int_sqr_karatsuba(dest, src)
} else if ((src.used * 2) + 1) < _WARRAY && src.used < (_MAX_COMBA / 2) {
/*
Fast comba?
*/
- err = #force_inline _private_int_sqr_comba(dest, src);
+ err = #force_inline _private_int_sqr_comba(dest, src)
} else {
- err = #force_inline _private_int_sqr(dest, src);
+ err = #force_inline _private_int_sqr(dest, src)
}
} else {
/*
@@ -664,23 +664,23 @@ internal_int_mul :: proc(dest, src, multiplier: ^Int, allocator := context.alloc
* was actually slower on the author's machine, but YMMV.
*/
- min_used := min(src.used, multiplier.used);
- max_used := max(src.used, multiplier.used);
- digits := src.used + multiplier.used + 1;
+ min_used := min(src.used, multiplier.used)
+ max_used := max(src.used, multiplier.used)
+ digits := src.used + multiplier.used + 1
if min_used >= MUL_KARATSUBA_CUTOFF && (max_used / 2) >= MUL_KARATSUBA_CUTOFF && max_used >= (2 * min_used) {
/*
Not much effect was observed below a ratio of 1:2, but again: YMMV.
*/
- err = _private_int_mul_balance(dest, src, multiplier);
+ err = _private_int_mul_balance(dest, src, multiplier)
} else if min_used >= MUL_TOOM_CUTOFF {
/*
Toom path commented out until it no longer fails Factorial 10k or 100k,
as reveaved in the long test.
*/
- err = #force_inline _private_int_mul_toom(dest, src, multiplier);
+ err = #force_inline _private_int_mul_toom(dest, src, multiplier)
} else if min_used >= MUL_KARATSUBA_CUTOFF {
- err = #force_inline _private_int_mul_karatsuba(dest, src, multiplier);
+ err = #force_inline _private_int_mul_karatsuba(dest, src, multiplier)
} else if digits < _WARRAY && min_used <= _MAX_COMBA {
/*
Can we use the fast multiplier?
@@ -688,24 +688,24 @@ internal_int_mul :: proc(dest, src, multiplier: ^Int, allocator := context.alloc
* have less than MP_WARRAY digits and the number of
* digits won't affect carry propagation
*/
- err = #force_inline _private_int_mul_comba(dest, src, multiplier, digits);
+ err = #force_inline _private_int_mul_comba(dest, src, multiplier, digits)
} else {
- err = #force_inline _private_int_mul(dest, src, multiplier, digits);
+ err = #force_inline _private_int_mul(dest, src, multiplier, digits)
}
}
- dest.sign = .Negative if dest.used > 0 && neg else .Zero_or_Positive;
- return err;
+ dest.sign = .Negative if dest.used > 0 && neg else .Zero_or_Positive
+ return err
}
-internal_mul :: proc { internal_int_mul, internal_int_mul_digit, };
+internal_mul :: proc { internal_int_mul, internal_int_mul_digit, }
internal_sqr :: proc (dest, src: ^Int, allocator := context.allocator) -> (res: Error) {
/*
We call `internal_mul` and not e.g. `_private_int_sqr` because the former
will dispatch to the optimal implementation depending on the source.
*/
- return #force_inline internal_mul(dest, src, src, allocator);
+ return #force_inline internal_mul(dest, src, src, allocator)
}
/*
@@ -714,37 +714,37 @@ internal_sqr :: proc (dest, src: ^Int, allocator := context.allocator) -> (res:
`numerator` and `denominator` are expected not to be `nil` and have been initialized.
*/
internal_int_divmod :: proc(quotient, remainder, numerator, denominator: ^Int, allocator := context.allocator) -> (err: Error) {
- context.allocator = allocator;
+ context.allocator = allocator
if denominator.used == 0 { return .Division_by_Zero; }
/*
If numerator < denominator then quotient = 0, remainder = numerator.
*/
if #force_inline internal_cmp_mag(numerator, denominator) == -1 {
if remainder != nil {
- internal_copy(remainder, numerator) or_return;
+ internal_copy(remainder, numerator) or_return
}
if quotient != nil {
- internal_zero(quotient);
+ internal_zero(quotient)
}
- return nil;
+ return nil
}
if (denominator.used > 2 * MUL_KARATSUBA_CUTOFF) && (denominator.used <= (numerator.used / 3) * 2) {
- assert(denominator.used >= 160 && numerator.used >= 240, "MUL_KARATSUBA_CUTOFF global not properly set.");
- err = _private_int_div_recursive(quotient, remainder, numerator, denominator);
+ assert(denominator.used >= 160 && numerator.used >= 240, "MUL_KARATSUBA_CUTOFF global not properly set.")
+ err = _private_int_div_recursive(quotient, remainder, numerator, denominator)
// err = #force_inline _private_int_div_school(quotient, remainder, numerator, denominator);
} else {
when true {
- err = #force_inline _private_int_div_school(quotient, remainder, numerator, denominator);
+ err = #force_inline _private_int_div_school(quotient, remainder, numerator, denominator)
} else {
/*
NOTE(Jeroen): We no longer need or use `_private_int_div_small`.
We'll keep it around for a bit until we're reasonably certain div_school is bug free.
*/
- err = _private_int_div_small(quotient, remainder, numerator, denominator);
+ err = _private_int_div_small(quotient, remainder, numerator, denominator)
}
}
- return;
+ return
}
/*
@@ -752,7 +752,7 @@ internal_int_divmod :: proc(quotient, remainder, numerator, denominator: ^Int, a
The quotient is optional and may be passed a nil.
*/
internal_int_divmod_digit :: proc(quotient, numerator: ^Int, denominator: DIGIT, allocator := context.allocator) -> (remainder: DIGIT, err: Error) {
- context.allocator = allocator;
+ context.allocator = allocator
/*
Cannot divide by zero.
@@ -764,9 +764,9 @@ internal_int_divmod_digit :: proc(quotient, numerator: ^Int, denominator: DIGIT,
*/
if denominator == 1 || numerator.used == 0 {
if quotient != nil {
- return 0, internal_copy(quotient, numerator);
+ return 0, internal_copy(quotient, numerator)
}
- return 0, err;
+ return 0, err
}
/*
Power of two?
@@ -774,75 +774,75 @@ internal_int_divmod_digit :: proc(quotient, numerator: ^Int, denominator: DIGIT,
if denominator == 2 {
if numerator.used > 0 && numerator.digit[0] & 1 != 0 {
// Remainder is 1 if numerator is odd.
- remainder = 1;
+ remainder = 1
}
if quotient == nil {
- return remainder, nil;
+ return remainder, nil
}
- return remainder, internal_shr(quotient, numerator, 1);
+ return remainder, internal_shr(quotient, numerator, 1)
}
- ix: int;
+ ix: int
if platform_int_is_power_of_two(int(denominator)) {
- ix = 1;
+ ix = 1
for ix < _DIGIT_BITS && denominator != (1 << uint(ix)) {
- ix += 1;
+ ix += 1
}
- remainder = numerator.digit[0] & ((1 << uint(ix)) - 1);
+ remainder = numerator.digit[0] & ((1 << uint(ix)) - 1)
if quotient == nil {
- return remainder, nil;
+ return remainder, nil
}
- return remainder, internal_shr(quotient, numerator, int(ix));
+ return remainder, internal_shr(quotient, numerator, int(ix))
}
/*
Three?
*/
if denominator == 3 {
- return _private_int_div_3(quotient, numerator);
+ return _private_int_div_3(quotient, numerator)
}
/*
No easy answer [c'est la vie]. Just division.
*/
- q := &Int{};
+ q := &Int{}
- internal_grow(q, numerator.used) or_return;
+ internal_grow(q, numerator.used) or_return
- q.used = numerator.used;
- q.sign = numerator.sign;
+ q.used = numerator.used
+ q.sign = numerator.sign
- w := _WORD(0);
+ w := _WORD(0)
for ix = numerator.used - 1; ix >= 0; ix -= 1 {
- t := DIGIT(0);
- w = (w << _WORD(_DIGIT_BITS) | _WORD(numerator.digit[ix]));
+ t := DIGIT(0)
+ w = (w << _WORD(_DIGIT_BITS) | _WORD(numerator.digit[ix]))
if w >= _WORD(denominator) {
- t = DIGIT(w / _WORD(denominator));
- w -= _WORD(t) * _WORD(denominator);
+ t = DIGIT(w / _WORD(denominator))
+ w -= _WORD(t) * _WORD(denominator)
}
- q.digit[ix] = t;
+ q.digit[ix] = t
}
- remainder = DIGIT(w);
+ remainder = DIGIT(w)
if quotient != nil {
- internal_clamp(q);
- internal_swap(q, quotient);
+ internal_clamp(q)
+ internal_swap(q, quotient)
}
- internal_destroy(q);
- return remainder, nil;
+ internal_destroy(q)
+ return remainder, nil
}
-internal_divmod :: proc { internal_int_divmod, internal_int_divmod_digit, };
+internal_divmod :: proc { internal_int_divmod, internal_int_divmod_digit, }
/*
Asssumes quotient, numerator and denominator to have been initialized and not to be nil.
*/
internal_int_div :: proc(quotient, numerator, denominator: ^Int, allocator := context.allocator) -> (err: Error) {
- return #force_inline internal_int_divmod(quotient, nil, numerator, denominator, allocator);
+ return #force_inline internal_int_divmod(quotient, nil, numerator, denominator, allocator)
}
-internal_div :: proc { internal_int_div, };
+internal_div :: proc { internal_int_div, }
/*
remainder = numerator % denominator.
@@ -856,50 +856,50 @@ internal_int_mod :: proc(remainder, numerator, denominator: ^Int, allocator := c
if remainder.used == 0 || denominator.sign == remainder.sign { return nil; }
- return #force_inline internal_add(remainder, remainder, numerator, allocator);
+ return #force_inline internal_add(remainder, remainder, numerator, allocator)
}
internal_int_mod_digit :: proc(numerator: ^Int, denominator: DIGIT, allocator := context.allocator) -> (remainder: DIGIT, err: Error) {
- return internal_int_divmod_digit(nil, numerator, denominator, allocator);
+ return internal_int_divmod_digit(nil, numerator, denominator, allocator)
}
-internal_mod :: proc{ internal_int_mod, internal_int_mod_digit};
+internal_mod :: proc{ internal_int_mod, internal_int_mod_digit}
/*
remainder = (number + addend) % modulus.
*/
internal_int_addmod :: proc(remainder, number, addend, modulus: ^Int, allocator := context.allocator) -> (err: Error) {
#force_inline internal_add(remainder, number, addend, allocator) or_return;
- return #force_inline internal_mod(remainder, remainder, modulus, allocator);
+ return #force_inline internal_mod(remainder, remainder, modulus, allocator)
}
-internal_addmod :: proc { internal_int_addmod, };
+internal_addmod :: proc { internal_int_addmod, }
/*
remainder = (number - decrease) % modulus.
*/
internal_int_submod :: proc(remainder, number, decrease, modulus: ^Int, allocator := context.allocator) -> (err: Error) {
#force_inline internal_sub(remainder, number, decrease, allocator) or_return;
- return #force_inline internal_mod(remainder, remainder, modulus, allocator);
+ return #force_inline internal_mod(remainder, remainder, modulus, allocator)
}
-internal_submod :: proc { internal_int_submod, };
+internal_submod :: proc { internal_int_submod, }
/*
remainder = (number * multiplicand) % modulus.
*/
internal_int_mulmod :: proc(remainder, number, multiplicand, modulus: ^Int, allocator := context.allocator) -> (err: Error) {
#force_inline internal_mul(remainder, number, multiplicand, allocator) or_return;
- return #force_inline internal_mod(remainder, remainder, modulus, allocator);
+ return #force_inline internal_mod(remainder, remainder, modulus, allocator)
}
-internal_mulmod :: proc { internal_int_mulmod, };
+internal_mulmod :: proc { internal_int_mulmod, }
/*
remainder = (number * number) % modulus.
*/
internal_int_sqrmod :: proc(remainder, number, modulus: ^Int, allocator := context.allocator) -> (err: Error) {
#force_inline internal_sqr(remainder, number, allocator) or_return;
- return #force_inline internal_mod(remainder, remainder, modulus, allocator);
+ return #force_inline internal_mod(remainder, remainder, modulus, allocator)
}
-internal_sqrmod :: proc { internal_int_sqrmod, };
+internal_sqrmod :: proc { internal_int_sqrmod, }
@@ -908,26 +908,26 @@ internal_sqrmod :: proc { internal_int_sqrmod, };
This way we'll have to reallocate less, possibly not at all.
*/
internal_int_factorial :: proc(res: ^Int, n: int, allocator := context.allocator) -> (err: Error) {
- context.allocator = allocator;
+ context.allocator = allocator
if n >= FACTORIAL_BINARY_SPLIT_CUTOFF {
- return _private_int_factorial_binary_split(res, n);
+ return _private_int_factorial_binary_split(res, n)
}
- i := len(_factorial_table);
+ i := len(_factorial_table)
if n < i {
- return #force_inline internal_set(res, _factorial_table[n]);
+ return #force_inline internal_set(res, _factorial_table[n])
}
#force_inline internal_set(res, _factorial_table[i - 1]) or_return;
for {
if err = #force_inline internal_mul(res, res, DIGIT(i)); err != nil || i == n {
- return err;
+ return err
}
- i += 1;
+ i += 1
}
- return nil;
+ return nil
}
/*
@@ -939,7 +939,7 @@ internal_int_factorial :: proc(res: ^Int, n: int, allocator := context.allocator
internal_int_gcd_lcm :: proc(res_gcd, res_lcm, a, b: ^Int, allocator := context.allocator) -> (err: Error) {
if res_gcd == nil && res_lcm == nil { return nil; }
- return #force_inline _private_int_gcd_lcm(res_gcd, res_lcm, a, b, allocator);
+ return #force_inline _private_int_gcd_lcm(res_gcd, res_lcm, a, b, allocator)
}
/*
@@ -956,29 +956,29 @@ internal_int_mod_bits :: proc(remainder, numerator: ^Int, bits: int, allocator :
/*
If the modulus is larger than the value, return the value.
*/
- internal_copy(remainder, numerator) or_return;
+ internal_copy(remainder, numerator) or_return
if bits >= (numerator.used * _DIGIT_BITS) {
- return;
+ return
}
/*
Zero digits above the last digit of the modulus.
*/
- zero_count := (bits / _DIGIT_BITS);
- zero_count += 0 if (bits % _DIGIT_BITS == 0) else 1;
+ zero_count := (bits / _DIGIT_BITS)
+ zero_count += 0 if (bits % _DIGIT_BITS == 0) else 1
/*
Zero remainder. Special case, can't use `internal_zero_unused`.
*/
if zero_count > 0 {
- mem.zero_slice(remainder.digit[zero_count:]);
+ mem.zero_slice(remainder.digit[zero_count:])
}
/*
Clear the digit that is not completely outside/inside the modulus.
*/
- remainder.digit[bits / _DIGIT_BITS] &= DIGIT(1 << DIGIT(bits % _DIGIT_BITS)) - DIGIT(1);
- return internal_clamp(remainder);
+ remainder.digit[bits / _DIGIT_BITS] &= DIGIT(1 << DIGIT(bits % _DIGIT_BITS)) - DIGIT(1)
+ return internal_clamp(remainder)
}
/*
@@ -997,37 +997,37 @@ internal_int_mod_bits :: proc(remainder, numerator: ^Int, bits: int, allocator :
Assumes `a` not to be `nil`.
*/
internal_int_is_initialized :: #force_inline proc(a: ^Int) -> (initialized: bool) {
- raw := transmute(mem.Raw_Dynamic_Array)a.digit;
- return raw.cap >= _MIN_DIGIT_COUNT;
+ raw := transmute(mem.Raw_Dynamic_Array)a.digit
+ return raw.cap >= _MIN_DIGIT_COUNT
}
-internal_is_initialized :: proc { internal_int_is_initialized, };
+internal_is_initialized :: proc { internal_int_is_initialized, }
/*
This procedure will return `true` if the `Int` is zero, `false` if not.
Assumes `a` not to be `nil`.
*/
internal_int_is_zero :: #force_inline proc(a: ^Int) -> (zero: bool) {
- return a.used == 0;
+ return a.used == 0
}
-internal_is_zero :: proc { internal_int_is_zero, };
+internal_is_zero :: proc { internal_int_is_zero, }
/*
This procedure will return `true` if the `Int` is positive, `false` if not.
Assumes `a` not to be `nil`.
*/
internal_int_is_positive :: #force_inline proc(a: ^Int) -> (positive: bool) {
- return a.sign == .Zero_or_Positive;
+ return a.sign == .Zero_or_Positive
}
-internal_is_positive :: proc { internal_int_is_positive, };
+internal_is_positive :: proc { internal_int_is_positive, }
/*
This procedure will return `true` if the `Int` is negative, `false` if not.
Assumes `a` not to be `nil`.
*/
internal_int_is_negative :: #force_inline proc(a: ^Int) -> (negative: bool) {
- return a.sign == .Negative;
+ return a.sign == .Negative
}
-internal_is_negative :: proc { internal_int_is_negative, };
+internal_is_negative :: proc { internal_int_is_negative, }
/*
This procedure will return `true` if the `Int` is even, `false` if not.
@@ -1040,18 +1040,18 @@ internal_int_is_even :: #force_inline proc(a: ^Int) -> (even: bool) {
`a.used` > 0 here, because the above handled `is_zero`.
We don't need to explicitly test it.
*/
- return a.digit[0] & 1 == 0;
+ return a.digit[0] & 1 == 0
}
-internal_is_even :: proc { internal_int_is_even, };
+internal_is_even :: proc { internal_int_is_even, }
/*
This procedure will return `true` if the `Int` is even, `false` if not.
Assumes `a` not to be `nil`.
*/
internal_int_is_odd :: #force_inline proc(a: ^Int) -> (odd: bool) {
- return !internal_int_is_even(a);
+ return !internal_int_is_even(a)
}
-internal_is_odd :: proc { internal_int_is_odd, };
+internal_is_odd :: proc { internal_int_is_odd, }
/*
@@ -1080,9 +1080,9 @@ internal_int_is_power_of_two :: #force_inline proc(a: ^Int) -> (power_of_two: bo
*/
for i := 1; i < a.used && a.digit[i - 1] != 0; i += 1 { return false; }
- return true;
+ return true
}
-internal_is_power_of_two :: proc { internal_int_is_power_of_two, };
+internal_is_power_of_two :: proc { internal_int_is_power_of_two, }
/*
Compare two `Int`s, signed.
@@ -1091,7 +1091,7 @@ internal_is_power_of_two :: proc { internal_int_is_power_of_two, };
Expects `a` and `b` both to be valid `Int`s, i.e. initialized and not `nil`.
*/
internal_int_compare :: #force_inline proc(a, b: ^Int) -> (comparison: int) {
- a_is_negative := #force_inline internal_is_negative(a);
+ a_is_negative := #force_inline internal_is_negative(a)
/*
Compare based on sign.
@@ -1102,10 +1102,10 @@ internal_int_compare :: #force_inline proc(a, b: ^Int) -> (comparison: int) {
If `a` is negative, compare in the opposite direction */
if a_is_negative { return #force_inline internal_compare_magnitude(b, a); }
- return #force_inline internal_compare_magnitude(a, b);
+ return #force_inline internal_compare_magnitude(a, b)
}
-internal_compare :: proc { internal_int_compare, internal_int_compare_digit, };
-internal_cmp :: internal_compare;
+internal_compare :: proc { internal_int_compare, internal_int_compare_digit, }
+internal_cmp :: internal_compare
/*
Compare an `Int` to an unsigned number upto `DIGIT & _MASK`.
@@ -1114,32 +1114,32 @@ internal_cmp :: internal_compare;
Expects: `a` and `b` both to be valid `Int`s, i.e. initialized and not `nil`.
*/
internal_int_compare_digit :: #force_inline proc(a: ^Int, b: DIGIT) -> (comparison: int) {
- a_is_negative := #force_inline internal_is_negative(a);
+ a_is_negative := #force_inline internal_is_negative(a)
switch {
/*
Compare based on sign first.
*/
- case a_is_negative: return -1;
+ case a_is_negative: return -1
/*
Then compare on magnitude.
*/
- case a.used > 1: return +1;
+ case a.used > 1: return +1
/*
We have only one digit. Compare it against `b`.
*/
- case a.digit[0] < b: return -1;
- case a.digit[0] == b: return 0;
- case a.digit[0] > b: return +1;
+ case a.digit[0] < b: return -1
+ case a.digit[0] == b: return 0
+ case a.digit[0] > b: return +1
/*
Unreachable.
Just here because Odin complains about a missing return value at the bottom of the proc otherwise.
*/
- case: return;
+ case: return
}
}
-internal_compare_digit :: proc { internal_int_compare_digit, };
-internal_cmp_digit :: internal_compare_digit;
+internal_compare_digit :: proc { internal_int_compare_digit, }
+internal_cmp_digit :: internal_compare_digit
/*
Compare the magnitude of two `Int`s, unsigned.
@@ -1150,9 +1150,9 @@ internal_int_compare_magnitude :: #force_inline proc(a, b: ^Int) -> (comparison:
*/
if a.used != b.used {
if a.used > b.used {
- return +1;
+ return +1
}
- return -1;
+ return -1
}
/*
@@ -1161,16 +1161,16 @@ internal_int_compare_magnitude :: #force_inline proc(a, b: ^Int) -> (comparison:
#no_bounds_check for n := a.used - 1; n >= 0; n -= 1 {
if a.digit[n] != b.digit[n] {
if a.digit[n] > b.digit[n] {
- return +1;
+ return +1
}
- return -1;
+ return -1
}
}
- return 0;
+ return 0
}
-internal_compare_magnitude :: proc { internal_int_compare_magnitude, };
-internal_cmp_mag :: internal_compare_magnitude;
+internal_compare_magnitude :: proc { internal_int_compare_magnitude, }
+internal_cmp_mag :: internal_compare_magnitude
/*
Check if remainders are possible squares - fast exclude non-squares.
@@ -1179,12 +1179,12 @@ internal_cmp_mag :: internal_compare_magnitude;
Assumes `a` not to be `nil` and to have been initialized.
*/
internal_int_is_square :: proc(a: ^Int, allocator := context.allocator) -> (square: bool, err: Error) {
- context.allocator = allocator;
+ context.allocator = allocator
/*
Default to Non-square :)
*/
- square = false;
+ square = false
if internal_is_negative(a) { return; }
if internal_is_zero(a) { return; }
@@ -1197,18 +1197,18 @@ internal_int_is_square :: proc(a: ^Int, allocator := context.allocator) -> (squa
/*
Next check mod 105 (3*5*7).
*/
- c: DIGIT;
- c, err = internal_mod(a, 105);
+ c: DIGIT
+ c, err = internal_mod(a, 105)
if _private_int_rem_105[c] == 1 { return; }
- t := &Int{};
- defer destroy(t);
+ t := &Int{}
+ defer destroy(t)
- set(t, 11 * 13 * 17 * 19 * 23 * 29 * 31) or_return;
- internal_mod(t, a, t) or_return;
+ set(t, 11 * 13 * 17 * 19 * 23 * 29 * 31) or_return
+ internal_mod(t, a, t) or_return
- r: u64;
- r, err = internal_int_get(t, u64);
+ r: u64
+ r, err = internal_int_get(t, u64)
/*
Check for other prime modules, note it's not an ERROR but we must
@@ -1226,12 +1226,12 @@ internal_int_is_square :: proc(a: ^Int, allocator := context.allocator) -> (squa
/*
Final check - is sqr(sqrt(arg)) == arg?
*/
- sqrt(t, a) or_return;
- sqr(t, t) or_return;
+ sqrt(t, a) or_return
+ sqr(t, t) or_return
- square = internal_cmp_mag(t, a) == 0;
+ square = internal_cmp_mag(t, a) == 0
- return;
+ return
}
/*
@@ -1258,7 +1258,7 @@ internal_int_log :: proc(a: ^Int, base: DIGIT) -> (res: int, err: Error) {
*/
if a.used == 1 { return internal_log(a.digit[0], DIGIT(base)); }
- return _private_int_log(a, base);
+ return _private_int_log(a, base)
}
@@ -1277,52 +1277,52 @@ internal_digit_log :: proc(a: DIGIT, base: DIGIT) -> (log: int, err: Error) {
*/
if a == base { return 1, nil; }
- N := _WORD(a);
- bracket_low := _WORD(1);
- bracket_high := _WORD(base);
- high := 1;
- low := 0;
+ N := _WORD(a)
+ bracket_low := _WORD(1)
+ bracket_high := _WORD(base)
+ high := 1
+ low := 0
for bracket_high < N {
- low = high;
- bracket_low = bracket_high;
- high <<= 1;
- bracket_high *= bracket_high;
+ low = high
+ bracket_low = bracket_high
+ high <<= 1
+ bracket_high *= bracket_high
}
for high - low > 1 {
- mid := (low + high) >> 1;
- bracket_mid := bracket_low * #force_inline internal_small_pow(_WORD(base), _WORD(mid - low));
+ mid := (low + high) >> 1
+ bracket_mid := bracket_low * #force_inline internal_small_pow(_WORD(base), _WORD(mid - low))
if N < bracket_mid {
- high = mid;
- bracket_high = bracket_mid;
+ high = mid
+ bracket_high = bracket_mid
}
if N > bracket_mid {
- low = mid;
- bracket_low = bracket_mid;
+ low = mid
+ bracket_low = bracket_mid
}
if N == bracket_mid {
- return mid, nil;
+ return mid, nil
}
}
if bracket_high == N {
- return high, nil;
+ return high, nil
} else {
- return low, nil;
+ return low, nil
}
}
-internal_log :: proc { internal_int_log, internal_digit_log, };
+internal_log :: proc { internal_int_log, internal_digit_log, }
/*
Calculate dest = base^power using a square-multiply algorithm.
Assumes `dest` and `base` not to be `nil` and to have been initialized.
*/
internal_int_pow :: proc(dest, base: ^Int, power: int, allocator := context.allocator) -> (err: Error) {
- context.allocator = allocator;
+ context.allocator = allocator
- power := power;
+ power := power
/*
Early outs.
*/
@@ -1331,8 +1331,8 @@ internal_int_pow :: proc(dest, base: ^Int, power: int, allocator := context.allo
A zero base is a special case.
*/
if power < 0 {
- internal_zero(dest) or_return;
- return .Math_Domain_Error;
+ internal_zero(dest) or_return
+ return .Math_Domain_Error
}
if power == 0 { return internal_one(dest); }
if power > 0 { return internal_zero(dest); }
@@ -1342,52 +1342,52 @@ internal_int_pow :: proc(dest, base: ^Int, power: int, allocator := context.allo
/*
Fraction, so we'll return zero.
*/
- return internal_zero(dest);
+ return internal_zero(dest)
}
switch(power) {
case 0:
/*
Any base to the power zero is one.
*/
- return #force_inline internal_one(dest);
+ return #force_inline internal_one(dest)
case 1:
/*
Any base to the power one is itself.
*/
- return copy(dest, base);
+ return copy(dest, base)
case 2:
- return #force_inline internal_sqr(dest, base);
+ return #force_inline internal_sqr(dest, base)
}
- g := &Int{};
- internal_copy(g, base) or_return;
+ g := &Int{}
+ internal_copy(g, base) or_return
/*
Set initial result.
*/
- internal_one(dest) or_return;
+ internal_one(dest) or_return
- defer internal_destroy(g);
+ defer internal_destroy(g)
for power > 0 {
/*
If the bit is set, multiply.
*/
if power & 1 != 0 {
- internal_mul(dest, g, dest) or_return;
+ internal_mul(dest, g, dest) or_return
}
/*
Square.
*/
if power > 1 {
- internal_sqr(g, g) or_return;
+ internal_sqr(g, g) or_return
}
/* shift to next bit */
- power >>= 1;
+ power >>= 1
}
- return;
+ return
}
/*
@@ -1395,34 +1395,34 @@ internal_int_pow :: proc(dest, base: ^Int, power: int, allocator := context.allo
Assumes `dest` not to be `nil` and to have been initialized.
*/
internal_int_pow_int :: proc(dest: ^Int, base, power: int, allocator := context.allocator) -> (err: Error) {
- context.allocator = allocator;
+ context.allocator = allocator
- base_t := &Int{};
- defer internal_destroy(base_t);
+ base_t := &Int{}
+ defer internal_destroy(base_t)
- internal_set(base_t, base) or_return;
+ internal_set(base_t, base) or_return
- return #force_inline internal_int_pow(dest, base_t, power);
+ return #force_inline internal_int_pow(dest, base_t, power)
}
-internal_pow :: proc { internal_int_pow, internal_int_pow_int, };
-internal_exp :: pow;
+internal_pow :: proc { internal_int_pow, internal_int_pow_int, }
+internal_exp :: pow
/*
*/
internal_small_pow :: proc(base: _WORD, exponent: _WORD) -> (result: _WORD) {
- exponent := exponent; base := base;
- result = _WORD(1);
+ exponent := exponent; base := base
+ result = _WORD(1)
for exponent != 0 {
if exponent & 1 == 1 {
- result *= base;
+ result *= base
}
- exponent >>= 1;
- base *= base;
+ exponent >>= 1
+ base *= base
}
- return result;
+ return result
}
/*
@@ -1430,7 +1430,7 @@ internal_small_pow :: proc(base: _WORD, exponent: _WORD) -> (result: _WORD) {
Assumes `dest` and `src` not to be `nil` and to have been initialized.
*/
internal_int_sqrt :: proc(dest, src: ^Int, allocator := context.allocator) -> (err: Error) {
- context.allocator = allocator;
+ context.allocator = allocator
/*
Must be positive.
@@ -1445,33 +1445,33 @@ internal_int_sqrt :: proc(dest, src: ^Int, allocator := context.allocator) -> (e
/*
Set up temporaries.
*/
- x, y, t1, t2 := &Int{}, &Int{}, &Int{}, &Int{};
- defer internal_destroy(x, y, t1, t2);
+ x, y, t1, t2 := &Int{}, &Int{}, &Int{}, &Int{}
+ defer internal_destroy(x, y, t1, t2)
- count := #force_inline internal_count_bits(src);
+ count := #force_inline internal_count_bits(src)
- a, b := count >> 1, count & 1;
- internal_int_power_of_two(x, a+b, allocator) or_return;
+ a, b := count >> 1, count & 1
+ internal_int_power_of_two(x, a+b, allocator) or_return
for {
/*
y = (x + n // x) // 2
*/
- internal_div(t1, src, x) or_return;
- internal_add(t2, t1, x) or_return;
- internal_shr(y, t2, 1) or_return;
+ internal_div(t1, src, x) or_return
+ internal_add(t2, t1, x) or_return
+ internal_shr(y, t2, 1) or_return
if c := internal_cmp(y, x); c == 0 || c == 1 {
- internal_swap(dest, x);
- return nil;
+ internal_swap(dest, x)
+ return nil
}
- internal_swap(x, y);
+ internal_swap(x, y)
}
- internal_swap(dest, x);
- return err;
+ internal_swap(dest, x)
+ return err
}
-internal_sqrt :: proc { internal_int_sqrt, };
+internal_sqrt :: proc { internal_int_sqrt, }
/*
@@ -1484,7 +1484,7 @@ internal_sqrt :: proc { internal_int_sqrt, };
Assumes `dest` and `src` not to be `nil` and have been initialized.
*/
internal_int_root_n :: proc(dest, src: ^Int, n: int, allocator := context.allocator) -> (err: Error) {
- context.allocator = allocator;
+ context.allocator = allocator
/*
Fast path for n == 2
@@ -1498,15 +1498,15 @@ internal_int_root_n :: proc(dest, src: ^Int, n: int, allocator := context.alloca
/*
Set up temporaries.
*/
- t1, t2, t3, a := &Int{}, &Int{}, &Int{}, &Int{};
- defer internal_destroy(t1, t2, t3);
+ t1, t2, t3, a := &Int{}, &Int{}, &Int{}, &Int{}
+ defer internal_destroy(t1, t2, t3)
/*
If `src` is negative fudge the sign but keep track.
*/
- a.sign = .Zero_or_Positive;
- a.used = src.used;
- a.digit = src.digit;
+ a.sign = .Zero_or_Positive
+ a.used = src.used
+ a.digit = src.digit
/*
If "n" is larger than INT_MAX it is also larger than
@@ -1514,63 +1514,63 @@ internal_int_root_n :: proc(dest, src: ^Int, n: int, allocator := context.alloca
with an int and hence the root is always < 2 (two).
*/
if n > max(int) / 2 {
- err = set(dest, 1);
- dest.sign = a.sign;
- return err;
+ err = set(dest, 1)
+ dest.sign = a.sign
+ return err
}
/*
Compute seed: 2^(log_2(src)/n + 2)
*/
- ilog2 := internal_count_bits(src);
+ ilog2 := internal_count_bits(src)
/*
"src" is smaller than max(int), we can cast safely.
*/
if ilog2 < n {
- err = internal_one(dest);
- dest.sign = a.sign;
- return err;
+ err = internal_one(dest)
+ dest.sign = a.sign
+ return err
}
- ilog2 /= n;
+ ilog2 /= n
if ilog2 == 0 {
- err = internal_one(dest);
- dest.sign = a.sign;
- return err;
+ err = internal_one(dest)
+ dest.sign = a.sign
+ return err
}
/*
Start value must be larger than root.
*/
- ilog2 += 2;
- internal_int_power_of_two(t2, ilog2) or_return;
+ ilog2 += 2
+ internal_int_power_of_two(t2, ilog2) or_return
- c: int;
- iterations := 0;
+ c: int
+ iterations := 0
for {
/* t1 = t2 */
- internal_copy(t1, t2) or_return;
+ internal_copy(t1, t2) or_return
/* t2 = t1 - ((t1**b - a) / (b * t1**(b-1))) */
/* t3 = t1**(b-1) */
- internal_pow(t3, t1, n-1) or_return;
+ internal_pow(t3, t1, n-1) or_return
/* numerator */
/* t2 = t1**b */
- internal_mul(t2, t1, t3) or_return;
+ internal_mul(t2, t1, t3) or_return
/* t2 = t1**b - a */
- internal_sub(t2, t2, a) or_return;
+ internal_sub(t2, t2, a) or_return
/* denominator */
/* t3 = t1**(b-1) * b */
- internal_mul(t3, t3, DIGIT(n)) or_return;
+ internal_mul(t3, t3, DIGIT(n)) or_return
/* t3 = (t1**b - a)/(b * t1**(b-1)) */
- internal_div(t3, t2, t3) or_return;
- internal_sub(t2, t1, t3) or_return;
+ internal_div(t3, t2, t3) or_return
+ internal_sub(t2, t1, t3) or_return
/*
Number of rounds is at most log_2(root). If it is more it
@@ -1579,65 +1579,65 @@ internal_int_root_n :: proc(dest, src: ^Int, n: int, allocator := context.alloca
if ilog2 -= 1; ilog2 == 0 { break; }
if internal_cmp(t1, t2) == 0 { break; }
- iterations += 1;
+ iterations += 1
if iterations == MAX_ITERATIONS_ROOT_N {
- return .Max_Iterations_Reached;
+ return .Max_Iterations_Reached
}
}
/* Result can be off by a few so check. */
/* Loop beneath can overshoot by one if found root is smaller than actual root. */
- iterations = 0;
+ iterations = 0
for {
- internal_pow(t2, t1, n) or_return;
+ internal_pow(t2, t1, n) or_return
- c = internal_cmp(t2, a);
+ c = internal_cmp(t2, a)
if c == 0 {
- swap(dest, t1);
- return nil;
+ swap(dest, t1)
+ return nil
} else if c == -1 {
- internal_add(t1, t1, DIGIT(1)) or_return;
+ internal_add(t1, t1, DIGIT(1)) or_return
} else {
- break;
+ break
}
- iterations += 1;
+ iterations += 1
if iterations == MAX_ITERATIONS_ROOT_N {
- return .Max_Iterations_Reached;
+ return .Max_Iterations_Reached
}
}
- iterations = 0;
+ iterations = 0
/*
Correct overshoot from above or from recurrence.
*/
for {
- internal_pow(t2, t1, n) or_return;
+ internal_pow(t2, t1, n) or_return
if internal_cmp(t2, a) != 1 { break; }
- internal_sub(t1, t1, DIGIT(1)) or_return;
+ internal_sub(t1, t1, DIGIT(1)) or_return
- iterations += 1;
+ iterations += 1
if iterations == MAX_ITERATIONS_ROOT_N {
- return .Max_Iterations_Reached;
+ return .Max_Iterations_Reached
}
}
/*
Set the result.
*/
- internal_swap(dest, t1);
+ internal_swap(dest, t1)
/*
Set the sign of the result.
*/
- dest.sign = src.sign;
+ dest.sign = src.sign
- return err;
+ return err
}
-internal_root_n :: proc { internal_int_root_n, };
+internal_root_n :: proc { internal_int_root_n, }
/*
Other internal helpers
@@ -1648,51 +1648,51 @@ internal_root_n :: proc { internal_int_root_n, };
Asssumes none of the `integers` to be a `nil`.
*/
internal_int_destroy :: proc(integers: ..^Int) {
- integers := integers;
+ integers := integers
for a in &integers {
- raw := transmute(mem.Raw_Dynamic_Array)a.digit;
+ raw := transmute(mem.Raw_Dynamic_Array)a.digit
if raw.cap > 0 {
- mem.zero_slice(a.digit[:]);
- free(&a.digit[0]);
+ mem.zero_slice(a.digit[:])
+ free(&a.digit[0])
}
- a = &Int{};
+ a = &Int{}
}
}
-internal_destroy :: proc{ internal_int_destroy, };
+internal_destroy :: proc{ internal_int_destroy, }
/*
Helpers to set an `Int` to a specific value.
*/
internal_int_set_from_integer :: proc(dest: ^Int, src: $T, minimize := false, allocator := context.allocator) -> (err: Error)
where intrinsics.type_is_integer(T) {
- context.allocator = allocator;
+ context.allocator = allocator
- src := src;
+ src := src
- internal_error_if_immutable(dest) or_return;
+ internal_error_if_immutable(dest) or_return
/*
Most internal procs asssume an Int to have already been initialize,
but as this is one of the procs that initializes, we have to check the following.
*/
- internal_clear_if_uninitialized_single(dest) or_return;
+ internal_clear_if_uninitialized_single(dest) or_return
- dest.flags = {}; // We're not -Inf, Inf, NaN or Immutable.
+ dest.flags = {} // We're not -Inf, Inf, NaN or Immutable.
- dest.used = 0;
- dest.sign = .Zero_or_Positive if src >= 0 else .Negative;
- src = internal_abs(src);
+ dest.used = 0
+ dest.sign = .Zero_or_Positive if src >= 0 else .Negative
+ src = internal_abs(src)
#no_bounds_check for src != 0 {
- dest.digit[dest.used] = DIGIT(src) & _MASK;
- dest.used += 1;
- src >>= _DIGIT_BITS;
+ dest.digit[dest.used] = DIGIT(src) & _MASK
+ dest.used += 1
+ src >>= _DIGIT_BITS
}
- internal_zero_unused(dest);
- return nil;
+ internal_zero_unused(dest)
+ return nil
}
-internal_set :: proc { internal_int_set_from_integer, internal_int_copy };
+internal_set :: proc { internal_int_set_from_integer, internal_int_copy }
internal_copy_digits :: #force_inline proc(dest, src: ^Int, digits: int, offset := int(0)) -> (err: Error) {
#force_inline internal_error_if_immutable(dest) or_return;
@@ -1700,43 +1700,43 @@ internal_copy_digits :: #force_inline proc(dest, src: ^Int, digits: int, offset
/*
If dest == src, do nothing
*/
- return #force_inline _private_copy_digits(dest, src, digits, offset);
+ return #force_inline _private_copy_digits(dest, src, digits, offset)
}
/*
Copy one `Int` to another.
*/
internal_int_copy :: proc(dest, src: ^Int, minimize := false, allocator := context.allocator) -> (err: Error) {
- context.allocator = allocator;
+ context.allocator = allocator
/*
If dest == src, do nothing
*/
if (dest == src) { return nil; }
- internal_error_if_immutable(dest) or_return;
+ internal_error_if_immutable(dest) or_return
/*
Grow `dest` to fit `src`.
If `dest` is not yet initialized, it will be using `allocator`.
*/
- needed := src.used if minimize else max(src.used, _DEFAULT_DIGIT_COUNT);
+ needed := src.used if minimize else max(src.used, _DEFAULT_DIGIT_COUNT)
- internal_grow(dest, needed, minimize) or_return;
+ internal_grow(dest, needed, minimize) or_return
/*
Copy everything over and zero high digits.
*/
- internal_copy_digits(dest, src, src.used);
+ internal_copy_digits(dest, src, src.used)
- dest.used = src.used;
- dest.sign = src.sign;
- dest.flags = src.flags &~ {.Immutable};
+ dest.used = src.used
+ dest.sign = src.sign
+ dest.flags = src.flags &~ {.Immutable}
- internal_zero_unused(dest);
- return nil;
+ internal_zero_unused(dest)
+ return nil
}
-internal_copy :: proc { internal_int_copy, };
+internal_copy :: proc { internal_int_copy, }
/*
In normal code, you can also write `a, b = b, a`.
@@ -1744,80 +1744,80 @@ internal_copy :: proc { internal_int_copy, };
This helper swaps completely.
*/
internal_int_swap :: #force_inline proc(a, b: ^Int) {
- a := a; b := b;
+ a := a; b := b
- a.used, b.used = b.used, a.used;
- a.sign, b.sign = b.sign, a.sign;
- a.digit, b.digit = b.digit, a.digit;
+ a.used, b.used = b.used, a.used
+ a.sign, b.sign = b.sign, a.sign
+ a.digit, b.digit = b.digit, a.digit
}
-internal_swap :: proc { internal_int_swap, };
+internal_swap :: proc { internal_int_swap, }
/*
Set `dest` to |`src`|.
*/
internal_int_abs :: proc(dest, src: ^Int, allocator := context.allocator) -> (err: Error) {
- context.allocator = allocator;
+ context.allocator = allocator
/*
If `dest == src`, just fix `dest`'s sign.
*/
if (dest == src) {
- dest.sign = .Zero_or_Positive;
- return nil;
+ dest.sign = .Zero_or_Positive
+ return nil
}
/*
Copy `src` to `dest`
*/
- internal_copy(dest, src) or_return;
+ internal_copy(dest, src) or_return
/*
Fix sign.
*/
- dest.sign = .Zero_or_Positive;
- return nil;
+ dest.sign = .Zero_or_Positive
+ return nil
}
internal_platform_abs :: proc(n: $T) -> T where intrinsics.type_is_integer(T) {
- return n if n >= 0 else -n;
+ return n if n >= 0 else -n
}
-internal_abs :: proc{ internal_int_abs, internal_platform_abs, };
+internal_abs :: proc{ internal_int_abs, internal_platform_abs, }
/*
Set `dest` to `-src`.
*/
internal_int_neg :: proc(dest, src: ^Int, allocator := context.allocator) -> (err: Error) {
- context.allocator = allocator;
+ context.allocator = allocator
/*
If `dest == src`, just fix `dest`'s sign.
*/
- sign := Sign.Negative;
+ sign := Sign.Negative
if #force_inline internal_is_zero(src) || #force_inline internal_is_negative(src) {
- sign = .Zero_or_Positive;
+ sign = .Zero_or_Positive
}
if dest == src {
- dest.sign = sign;
- return nil;
+ dest.sign = sign
+ return nil
}
/*
Copy `src` to `dest`
*/
- internal_copy(dest, src) or_return;
+ internal_copy(dest, src) or_return
/*
Fix sign.
*/
- dest.sign = sign;
- return nil;
+ dest.sign = sign
+ return nil
}
-internal_neg :: proc { internal_int_neg, };
+internal_neg :: proc { internal_int_neg, }
/*
hac 14.61, pp608.
*/
internal_int_inverse_modulo :: proc(dest, a, b: ^Int, allocator := context.allocator) -> (err: Error) {
- context.allocator = allocator;
+ context.allocator = allocator
/*
For all n in N and n > 0, n = 0 mod 1.
*/
@@ -1833,15 +1833,15 @@ internal_int_inverse_modulo :: proc(dest, a, b: ^Int, allocator := context.alloc
*/
if internal_is_odd(b) { return _private_inverse_modulo_odd(dest, a, b); }
- return _private_inverse_modulo(dest, a, b);
+ return _private_inverse_modulo(dest, a, b)
}
-internal_invmod :: proc{ internal_int_inverse_modulo, };
+internal_invmod :: proc{ internal_int_inverse_modulo, }
/*
Helpers to extract values from the `Int`.
*/
internal_int_bitfield_extract_single :: proc(a: ^Int, offset: int) -> (bit: _WORD, err: Error) {
- return #force_inline int_bitfield_extract(a, offset, 1);
+ return #force_inline int_bitfield_extract(a, offset, 1)
}
internal_int_bitfield_extract :: proc(a: ^Int, offset, count: int) -> (res: _WORD, err: Error) #no_bounds_check {
@@ -1849,10 +1849,10 @@ internal_int_bitfield_extract :: proc(a: ^Int, offset, count: int) -> (res: _WOR
Early out for single bit.
*/
if count == 1 {
- limb := offset / _DIGIT_BITS;
+ limb := offset / _DIGIT_BITS
if limb < 0 || limb >= a.used { return 0, .Invalid_Argument; }
- i := _WORD(1 << _WORD((offset % _DIGIT_BITS)));
- return 1 if ((_WORD(a.digit[limb]) & i) != 0) else 0, nil;
+ i := _WORD(1 << _WORD((offset % _DIGIT_BITS)))
+ return 1 if ((_WORD(a.digit[limb]) & i) != 0) else 0, nil
}
if count > _WORD_BITS || count < 1 { return 0, .Invalid_Argument; }
@@ -1869,34 +1869,34 @@ internal_int_bitfield_extract :: proc(a: ^Int, offset, count: int) -> (res: _WOR
e.g. offset: 40, count: 120 = bits 40..59, 0..59, 0..39
*/
- limb := offset / _DIGIT_BITS;
- bits_left := count;
- bits_offset := offset % _DIGIT_BITS;
+ limb := offset / _DIGIT_BITS
+ bits_left := count
+ bits_offset := offset % _DIGIT_BITS
- num_bits := min(bits_left, _DIGIT_BITS - bits_offset);
+ num_bits := min(bits_left, _DIGIT_BITS - bits_offset)
- shift := offset % _DIGIT_BITS;
- mask := (_WORD(1) << uint(num_bits)) - 1;
- res = (_WORD(a.digit[limb]) >> uint(shift)) & mask;
+ shift := offset % _DIGIT_BITS
+ mask := (_WORD(1) << uint(num_bits)) - 1
+ res = (_WORD(a.digit[limb]) >> uint(shift)) & mask
- bits_left -= num_bits;
+ bits_left -= num_bits
if bits_left == 0 { return res, nil; }
- res_shift := num_bits;
- num_bits = min(bits_left, _DIGIT_BITS);
- mask = (1 << uint(num_bits)) - 1;
+ res_shift := num_bits
+ num_bits = min(bits_left, _DIGIT_BITS)
+ mask = (1 << uint(num_bits)) - 1
- res |= (_WORD(a.digit[limb + 1]) & mask) << uint(res_shift);
+ res |= (_WORD(a.digit[limb + 1]) & mask) << uint(res_shift)
- bits_left -= num_bits;
+ bits_left -= num_bits
if bits_left == 0 { return res, nil; }
- mask = (1 << uint(bits_left)) - 1;
- res_shift += _DIGIT_BITS;
+ mask = (1 << uint(bits_left)) - 1
+ res_shift += _DIGIT_BITS
- res |= (_WORD(a.digit[limb + 2]) & mask) << uint(res_shift);
+ res |= (_WORD(a.digit[limb + 2]) & mask) << uint(res_shift)
- return res, nil;
+ return res, nil
}
/*
@@ -1906,169 +1906,169 @@ internal_int_bitfield_extract :: proc(a: ^Int, offset, count: int) -> (res: _WOR
Assumes `a` not to be `nil`, and to have already been initialized.
*/
internal_int_shrink :: proc(a: ^Int) -> (err: Error) {
- needed := max(_MIN_DIGIT_COUNT, a.used);
+ needed := max(_MIN_DIGIT_COUNT, a.used)
if a.used != needed { return internal_grow(a, needed, true); }
- return nil;
+ return nil
}
-internal_shrink :: proc { internal_int_shrink, };
+internal_shrink :: proc { internal_int_shrink, }
internal_int_grow :: proc(a: ^Int, digits: int, allow_shrink := false, allocator := context.allocator) -> (err: Error) {
- raw := transmute(mem.Raw_Dynamic_Array)a.digit;
+ raw := transmute(mem.Raw_Dynamic_Array)a.digit
/*
We need at least _MIN_DIGIT_COUNT or a.used digits, whichever is bigger.
The caller is asking for `digits`. Let's be accomodating.
*/
- needed := max(_MIN_DIGIT_COUNT, a.used, digits);
+ needed := max(_MIN_DIGIT_COUNT, a.used, digits)
if !allow_shrink {
- needed = max(needed, raw.cap);
+ needed = max(needed, raw.cap)
}
/*
If not yet iniialized, initialize the `digit` backing with the allocator we were passed.
*/
if raw.cap == 0 {
- a.digit = make([dynamic]DIGIT, needed, allocator);
+ a.digit = make([dynamic]DIGIT, needed, allocator)
} else if raw.cap != needed {
/*
`[dynamic]DIGIT` already knows what allocator was used for it, so resize will do the right thing.
*/
- resize(&a.digit, needed);
+ resize(&a.digit, needed)
}
/*
Let's see if the allocation/resize worked as expected.
*/
if len(a.digit) != needed {
- return .Out_Of_Memory;
+ return .Out_Of_Memory
}
- return nil;
+ return nil
}
-internal_grow :: proc { internal_int_grow, };
+internal_grow :: proc { internal_int_grow, }
/*
Clear `Int` and resize it to the default size.
Assumes `a` not to be `nil`.
*/
internal_int_clear :: proc(a: ^Int, minimize := false, allocator := context.allocator) -> (err: Error) {
- raw := transmute(mem.Raw_Dynamic_Array)a.digit;
+ raw := transmute(mem.Raw_Dynamic_Array)a.digit
if raw.cap != 0 {
- mem.zero_slice(a.digit[:a.used]);
+ mem.zero_slice(a.digit[:a.used])
}
- a.sign = .Zero_or_Positive;
- a.used = 0;
+ a.sign = .Zero_or_Positive
+ a.used = 0
- return #force_inline internal_grow(a, a.used, minimize, allocator);
+ return #force_inline internal_grow(a, a.used, minimize, allocator)
}
-internal_clear :: proc { internal_int_clear, };
-internal_zero :: internal_clear;
+internal_clear :: proc { internal_int_clear, }
+internal_zero :: internal_clear
/*
Set the `Int` to 1 and optionally shrink it to the minimum backing size.
*/
internal_int_one :: proc(a: ^Int, minimize := false, allocator := context.allocator) -> (err: Error) {
- return internal_copy(a, INT_ONE, minimize, allocator);
+ return internal_copy(a, INT_ONE, minimize, allocator)
}
-internal_one :: proc { internal_int_one, };
+internal_one :: proc { internal_int_one, }
/*
Set the `Int` to -1 and optionally shrink it to the minimum backing size.
*/
internal_int_minus_one :: proc(a: ^Int, minimize := false, allocator := context.allocator) -> (err: Error) {
- return internal_copy(a, INT_MINUS_ONE, minimize, allocator);
+ return internal_copy(a, INT_MINUS_ONE, minimize, allocator)
}
-internal_minus_one :: proc { internal_int_minus_one, };
+internal_minus_one :: proc { internal_int_minus_one, }
/*
Set the `Int` to Inf and optionally shrink it to the minimum backing size.
*/
internal_int_inf :: proc(a: ^Int, minimize := false, allocator := context.allocator) -> (err: Error) {
- return internal_copy(a, INT_INF, minimize, allocator);
+ return internal_copy(a, INT_INF, minimize, allocator)
}
-internal_inf :: proc { internal_int_inf, };
+internal_inf :: proc { internal_int_inf, }
/*
Set the `Int` to -Inf and optionally shrink it to the minimum backing size.
*/
internal_int_minus_inf :: proc(a: ^Int, minimize := false, allocator := context.allocator) -> (err: Error) {
- return internal_copy(a, INT_MINUS_INF, minimize, allocator);
+ return internal_copy(a, INT_MINUS_INF, minimize, allocator)
}
-internal_minus_inf :: proc { internal_int_inf, };
+internal_minus_inf :: proc { internal_int_inf, }
/*
Set the `Int` to NaN and optionally shrink it to the minimum backing size.
*/
internal_int_nan :: proc(a: ^Int, minimize := false, allocator := context.allocator) -> (err: Error) {
- return internal_copy(a, INT_NAN, minimize, allocator);
+ return internal_copy(a, INT_NAN, minimize, allocator)
}
-internal_nan :: proc { internal_int_nan, };
+internal_nan :: proc { internal_int_nan, }
internal_int_power_of_two :: proc(a: ^Int, power: int, allocator := context.allocator) -> (err: Error) {
- context.allocator = allocator;
+ context.allocator = allocator
if power < 0 || power > _MAX_BIT_COUNT { return .Invalid_Argument; }
/*
Grow to accomodate the single bit.
*/
- a.used = (power / _DIGIT_BITS) + 1;
- internal_grow(a, a.used) or_return;
+ a.used = (power / _DIGIT_BITS) + 1
+ internal_grow(a, a.used) or_return
/*
Zero the entirety.
*/
- mem.zero_slice(a.digit[:]);
+ mem.zero_slice(a.digit[:])
/*
Set the bit.
*/
- a.digit[power / _DIGIT_BITS] = 1 << uint((power % _DIGIT_BITS));
- return nil;
+ a.digit[power / _DIGIT_BITS] = 1 << uint((power % _DIGIT_BITS))
+ return nil
}
internal_int_get_u128 :: proc(a: ^Int) -> (res: u128, err: Error) {
- return internal_int_get(a, u128);
+ return internal_int_get(a, u128)
}
-internal_get_u128 :: proc { internal_int_get_u128, };
+internal_get_u128 :: proc { internal_int_get_u128, }
internal_int_get_i128 :: proc(a: ^Int) -> (res: i128, err: Error) {
- return internal_int_get(a, i128);
+ return internal_int_get(a, i128)
}
-internal_get_i128 :: proc { internal_int_get_i128, };
+internal_get_i128 :: proc { internal_int_get_i128, }
internal_int_get_u64 :: proc(a: ^Int) -> (res: u64, err: Error) {
- return internal_int_get(a, u64);
+ return internal_int_get(a, u64)
}
-internal_get_u64 :: proc { internal_int_get_u64, };
+internal_get_u64 :: proc { internal_int_get_u64, }
internal_int_get_i64 :: proc(a: ^Int) -> (res: i64, err: Error) {
- return internal_int_get(a, i64);
+ return internal_int_get(a, i64)
}
-internal_get_i64 :: proc { internal_int_get_i64, };
+internal_get_i64 :: proc { internal_int_get_i64, }
internal_int_get_u32 :: proc(a: ^Int) -> (res: u32, err: Error) {
- return internal_int_get(a, u32);
+ return internal_int_get(a, u32)
}
-internal_get_u32 :: proc { internal_int_get_u32, };
+internal_get_u32 :: proc { internal_int_get_u32, }
internal_int_get_i32 :: proc(a: ^Int) -> (res: i32, err: Error) {
- return internal_int_get(a, i32);
+ return internal_int_get(a, i32)
}
-internal_get_i32 :: proc { internal_int_get_i32, };
+internal_get_i32 :: proc { internal_int_get_i32, }
/*
TODO: Think about using `count_bits` to check if the value could be returned completely,
and maybe return max(T), .Integer_Overflow if not?
*/
internal_int_get :: proc(a: ^Int, $T: typeid) -> (res: T, err: Error) where intrinsics.type_is_integer(T) {
- size_in_bits := int(size_of(T) * 8);
- i := int((size_in_bits + _DIGIT_BITS - 1) / _DIGIT_BITS);
- i = min(int(a.used), i);
+ size_in_bits := int(size_of(T) * 8)
+ i := int((size_in_bits + _DIGIT_BITS - 1) / _DIGIT_BITS)
+ i = min(int(a.used), i)
#no_bounds_check for ; i >= 0; i -= 1 {
- res <<= uint(0) if size_in_bits <= _DIGIT_BITS else _DIGIT_BITS;
- res |= T(a.digit[i]);
+ res <<= uint(0) if size_in_bits <= _DIGIT_BITS else _DIGIT_BITS
+ res |= T(a.digit[i])
if size_in_bits <= _DIGIT_BITS {
- break;
+ break
};
}
@@ -2076,31 +2076,31 @@ internal_int_get :: proc(a: ^Int, $T: typeid) -> (res: T, err: Error) where intr
/*
Mask off sign bit.
*/
- res ~= 1 << uint(size_in_bits - 1);
+ res ~= 1 << uint(size_in_bits - 1)
/*
Set the sign.
*/
if a.sign == .Negative { res = -res; }
}
- return;
+ return
}
-internal_get :: proc { internal_int_get, };
+internal_get :: proc { internal_int_get, }
internal_int_get_float :: proc(a: ^Int) -> (res: f64, err: Error) {
/*
log2(max(f64)) is approximately 1020, or 17 legs with the 64-bit storage.
*/
- legs :: 1020 / _DIGIT_BITS;
- l := min(a.used, legs);
- fac := f64(1 << _DIGIT_BITS);
- d := 0.0;
+ legs :: 1020 / _DIGIT_BITS
+ l := min(a.used, legs)
+ fac := f64(1 << _DIGIT_BITS)
+ d := 0.0
#no_bounds_check for i := l; i >= 0; i -= 1 {
- d = (d * fac) + f64(a.digit[i]);
+ d = (d * fac) + f64(a.digit[i])
}
- res = -d if a.sign == .Negative else d;
- return;
+ res = -d if a.sign == .Negative else d
+ return
}
/*
@@ -2114,278 +2114,278 @@ internal_int_get_float :: proc(a: ^Int) -> (res: f64, err: Error) {
2's complement `and`, returns `dest = a & b;`
*/
internal_int_and :: proc(dest, a, b: ^Int, allocator := context.allocator) -> (err: Error) {
- context.allocator = allocator;
+ context.allocator = allocator
- used := max(a.used, b.used) + 1;
+ used := max(a.used, b.used) + 1
/*
Grow the destination to accomodate the result.
*/
- internal_grow(dest, used) or_return;
+ internal_grow(dest, used) or_return
- neg_a := #force_inline internal_is_negative(a);
- neg_b := #force_inline internal_is_negative(b);
- neg := neg_a && neg_b;
+ neg_a := #force_inline internal_is_negative(a)
+ neg_b := #force_inline internal_is_negative(b)
+ neg := neg_a && neg_b
- ac, bc, cc := DIGIT(1), DIGIT(1), DIGIT(1);
+ ac, bc, cc := DIGIT(1), DIGIT(1), DIGIT(1)
#no_bounds_check for i := 0; i < used; i += 1 {
- x, y: DIGIT;
+ x, y: DIGIT
/*
Convert to 2's complement if negative.
*/
if neg_a {
- ac += _MASK if i >= a.used else (~a.digit[i] & _MASK);
- x = ac & _MASK;
- ac >>= _DIGIT_BITS;
+ ac += _MASK if i >= a.used else (~a.digit[i] & _MASK)
+ x = ac & _MASK
+ ac >>= _DIGIT_BITS
} else {
- x = 0 if i >= a.used else a.digit[i];
+ x = 0 if i >= a.used else a.digit[i]
}
/*
Convert to 2's complement if negative.
*/
if neg_b {
- bc += _MASK if i >= b.used else (~b.digit[i] & _MASK);
- y = bc & _MASK;
- bc >>= _DIGIT_BITS;
+ bc += _MASK if i >= b.used else (~b.digit[i] & _MASK)
+ y = bc & _MASK
+ bc >>= _DIGIT_BITS
} else {
- y = 0 if i >= b.used else b.digit[i];
+ y = 0 if i >= b.used else b.digit[i]
}
- dest.digit[i] = x & y;
+ dest.digit[i] = x & y
/*
Convert to to sign-magnitude if negative.
*/
if neg {
- cc += ~dest.digit[i] & _MASK;
- dest.digit[i] = cc & _MASK;
- cc >>= _DIGIT_BITS;
+ cc += ~dest.digit[i] & _MASK
+ dest.digit[i] = cc & _MASK
+ cc >>= _DIGIT_BITS
}
}
- dest.used = used;
- dest.sign = .Negative if neg else .Zero_or_Positive;
- return internal_clamp(dest);
+ dest.used = used
+ dest.sign = .Negative if neg else .Zero_or_Positive
+ return internal_clamp(dest)
}
-internal_and :: proc { internal_int_and, };
+internal_and :: proc { internal_int_and, }
/*
2's complement `or`, returns `dest = a | b;`
*/
internal_int_or :: proc(dest, a, b: ^Int, allocator := context.allocator) -> (err: Error) {
- context.allocator = allocator;
+ context.allocator = allocator
- used := max(a.used, b.used) + 1;
+ used := max(a.used, b.used) + 1
/*
Grow the destination to accomodate the result.
*/
- internal_grow(dest, used) or_return;
+ internal_grow(dest, used) or_return
- neg_a := #force_inline internal_is_negative(a);
- neg_b := #force_inline internal_is_negative(b);
- neg := neg_a || neg_b;
+ neg_a := #force_inline internal_is_negative(a)
+ neg_b := #force_inline internal_is_negative(b)
+ neg := neg_a || neg_b
- ac, bc, cc := DIGIT(1), DIGIT(1), DIGIT(1);
+ ac, bc, cc := DIGIT(1), DIGIT(1), DIGIT(1)
#no_bounds_check for i := 0; i < used; i += 1 {
- x, y: DIGIT;
+ x, y: DIGIT
/*
Convert to 2's complement if negative.
*/
if neg_a {
- ac += _MASK if i >= a.used else (~a.digit[i] & _MASK);
- x = ac & _MASK;
- ac >>= _DIGIT_BITS;
+ ac += _MASK if i >= a.used else (~a.digit[i] & _MASK)
+ x = ac & _MASK
+ ac >>= _DIGIT_BITS
} else {
- x = 0 if i >= a.used else a.digit[i];
+ x = 0 if i >= a.used else a.digit[i]
}
/*
Convert to 2's complement if negative.
*/
if neg_b {
- bc += _MASK if i >= b.used else (~b.digit[i] & _MASK);
- y = bc & _MASK;
- bc >>= _DIGIT_BITS;
+ bc += _MASK if i >= b.used else (~b.digit[i] & _MASK)
+ y = bc & _MASK
+ bc >>= _DIGIT_BITS
} else {
- y = 0 if i >= b.used else b.digit[i];
+ y = 0 if i >= b.used else b.digit[i]
}
- dest.digit[i] = x | y;
+ dest.digit[i] = x | y
/*
Convert to to sign-magnitude if negative.
*/
if neg {
- cc += ~dest.digit[i] & _MASK;
- dest.digit[i] = cc & _MASK;
- cc >>= _DIGIT_BITS;
+ cc += ~dest.digit[i] & _MASK
+ dest.digit[i] = cc & _MASK
+ cc >>= _DIGIT_BITS
}
}
- dest.used = used;
- dest.sign = .Negative if neg else .Zero_or_Positive;
- return internal_clamp(dest);
+ dest.used = used
+ dest.sign = .Negative if neg else .Zero_or_Positive
+ return internal_clamp(dest)
}
-internal_or :: proc { internal_int_or, };
+internal_or :: proc { internal_int_or, }
/*
2's complement `xor`, returns `dest = a ~ b;`
*/
internal_int_xor :: proc(dest, a, b: ^Int, allocator := context.allocator) -> (err: Error) {
- context.allocator = allocator;
+ context.allocator = allocator
- used := max(a.used, b.used) + 1;
+ used := max(a.used, b.used) + 1
/*
Grow the destination to accomodate the result.
*/
- internal_grow(dest, used) or_return;
+ internal_grow(dest, used) or_return
- neg_a := #force_inline internal_is_negative(a);
- neg_b := #force_inline internal_is_negative(b);
- neg := neg_a != neg_b;
+ neg_a := #force_inline internal_is_negative(a)
+ neg_b := #force_inline internal_is_negative(b)
+ neg := neg_a != neg_b
- ac, bc, cc := DIGIT(1), DIGIT(1), DIGIT(1);
+ ac, bc, cc := DIGIT(1), DIGIT(1), DIGIT(1)
#no_bounds_check for i := 0; i < used; i += 1 {
- x, y: DIGIT;
+ x, y: DIGIT
/*
Convert to 2's complement if negative.
*/
if neg_a {
- ac += _MASK if i >= a.used else (~a.digit[i] & _MASK);
- x = ac & _MASK;
- ac >>= _DIGIT_BITS;
+ ac += _MASK if i >= a.used else (~a.digit[i] & _MASK)
+ x = ac & _MASK
+ ac >>= _DIGIT_BITS
} else {
- x = 0 if i >= a.used else a.digit[i];
+ x = 0 if i >= a.used else a.digit[i]
}
/*
Convert to 2's complement if negative.
*/
if neg_b {
- bc += _MASK if i >= b.used else (~b.digit[i] & _MASK);
- y = bc & _MASK;
- bc >>= _DIGIT_BITS;
+ bc += _MASK if i >= b.used else (~b.digit[i] & _MASK)
+ y = bc & _MASK
+ bc >>= _DIGIT_BITS
} else {
- y = 0 if i >= b.used else b.digit[i];
+ y = 0 if i >= b.used else b.digit[i]
}
- dest.digit[i] = x ~ y;
+ dest.digit[i] = x ~ y
/*
Convert to to sign-magnitude if negative.
*/
if neg {
- cc += ~dest.digit[i] & _MASK;
- dest.digit[i] = cc & _MASK;
- cc >>= _DIGIT_BITS;
+ cc += ~dest.digit[i] & _MASK
+ dest.digit[i] = cc & _MASK
+ cc >>= _DIGIT_BITS
}
}
- dest.used = used;
- dest.sign = .Negative if neg else .Zero_or_Positive;
- return internal_clamp(dest);
+ dest.used = used
+ dest.sign = .Negative if neg else .Zero_or_Positive
+ return internal_clamp(dest)
}
-internal_xor :: proc { internal_int_xor, };
+internal_xor :: proc { internal_int_xor, }
/*
dest = ~src
*/
internal_int_complement :: proc(dest, src: ^Int, allocator := context.allocator) -> (err: Error) {
- context.allocator = allocator;
+ context.allocator = allocator
/*
Temporarily fix sign.
*/
- old_sign := src.sign;
+ old_sign := src.sign
- neg := #force_inline internal_is_zero(src) || #force_inline internal_is_positive(src);
+ neg := #force_inline internal_is_zero(src) || #force_inline internal_is_positive(src)
- src.sign = .Negative if neg else .Zero_or_Positive;
+ src.sign = .Negative if neg else .Zero_or_Positive
- err = #force_inline internal_sub(dest, src, 1);
+ err = #force_inline internal_sub(dest, src, 1)
/*
Restore sign.
*/
- src.sign = old_sign;
+ src.sign = old_sign
- return err;
+ return err
}
-internal_complement :: proc { internal_int_complement, };
+internal_complement :: proc { internal_int_complement, }
/*
quotient, remainder := numerator >> bits;
`remainder` is allowed to be passed a `nil`, in which case `mod` won't be computed.
*/
internal_int_shrmod :: proc(quotient, remainder, numerator: ^Int, bits: int, allocator := context.allocator) -> (err: Error) {
- context.allocator = allocator;
+ context.allocator = allocator
- bits := bits;
+ bits := bits
if bits < 0 { return .Invalid_Argument; }
- internal_copy(quotient, numerator) or_return;
+ internal_copy(quotient, numerator) or_return
/*
Shift right by a certain bit count (store quotient and optional remainder.)
`numerator` should not be used after this.
*/
if remainder != nil {
- internal_int_mod_bits(remainder, numerator, bits) or_return;
+ internal_int_mod_bits(remainder, numerator, bits) or_return
}
/*
Shift by as many digits in the bit count.
*/
if bits >= _DIGIT_BITS {
- internal_shr_digit(quotient, bits / _DIGIT_BITS) or_return;
+ internal_shr_digit(quotient, bits / _DIGIT_BITS) or_return
}
/*
Shift any bit count < _DIGIT_BITS.
*/
- bits %= _DIGIT_BITS;
+ bits %= _DIGIT_BITS
if bits != 0 {
- mask := DIGIT(1 << uint(bits)) - 1;
- shift := DIGIT(_DIGIT_BITS - bits);
- carry := DIGIT(0);
+ mask := DIGIT(1 << uint(bits)) - 1
+ shift := DIGIT(_DIGIT_BITS - bits)
+ carry := DIGIT(0)
#no_bounds_check for x := quotient.used - 1; x >= 0; x -= 1 {
/*
Get the lower bits of this word in a temp.
*/
- fwd_carry := quotient.digit[x] & mask;
+ fwd_carry := quotient.digit[x] & mask
/*
Shift the current word and mix in the carry bits from the previous word.
*/
- quotient.digit[x] = (quotient.digit[x] >> uint(bits)) | (carry << shift);
+ quotient.digit[x] = (quotient.digit[x] >> uint(bits)) | (carry << shift)
/*
Update carry from forward carry.
*/
- carry = fwd_carry;
+ carry = fwd_carry
}
}
- return internal_clamp(numerator);
+ return internal_clamp(numerator)
}
-internal_shrmod :: proc { internal_int_shrmod, };
+internal_shrmod :: proc { internal_int_shrmod, }
internal_int_shr :: proc(dest, source: ^Int, bits: int, allocator := context.allocator) -> (err: Error) {
- return #force_inline internal_shrmod(dest, nil, source, bits, allocator);
+ return #force_inline internal_shrmod(dest, nil, source, bits, allocator)
}
-internal_shr :: proc { internal_int_shr, };
+internal_shr :: proc { internal_int_shr, }
/*
Shift right by `digits` * _DIGIT_BITS bits.
*/
internal_int_shr_digit :: proc(quotient: ^Int, digits: int, allocator := context.allocator) -> (err: Error) {
- context.allocator = allocator;
+ context.allocator = allocator
if digits <= 0 { return nil; }
@@ -2404,88 +2404,88 @@ internal_int_shr_digit :: proc(quotient: ^Int, digits: int, allocator := context
*/
#no_bounds_check for x := 0; x < (quotient.used - digits); x += 1 {
- quotient.digit[x] = quotient.digit[x + digits];
+ quotient.digit[x] = quotient.digit[x + digits]
}
- quotient.used -= digits;
- internal_zero_unused(quotient);
- return internal_clamp(quotient);
+ quotient.used -= digits
+ internal_zero_unused(quotient)
+ return internal_clamp(quotient)
}
-internal_shr_digit :: proc { internal_int_shr_digit, };
+internal_shr_digit :: proc { internal_int_shr_digit, }
/*
Shift right by a certain bit count with sign extension.
*/
internal_int_shr_signed :: proc(dest, src: ^Int, bits: int, allocator := context.allocator) -> (err: Error) {
- context.allocator = allocator;
+ context.allocator = allocator
if src.sign == .Zero_or_Positive {
- return internal_shr(dest, src, bits);
+ return internal_shr(dest, src, bits)
}
- internal_int_add_digit(dest, src, DIGIT(1)) or_return;
- internal_shr(dest, dest, bits) or_return;
- return internal_sub(dest, src, DIGIT(1));
+ internal_int_add_digit(dest, src, DIGIT(1)) or_return
+ internal_shr(dest, dest, bits) or_return
+ return internal_sub(dest, src, DIGIT(1))
}
-internal_shr_signed :: proc { internal_int_shr_signed, };
+internal_shr_signed :: proc { internal_int_shr_signed, }
/*
Shift left by a certain bit count.
*/
internal_int_shl :: proc(dest, src: ^Int, bits: int, allocator := context.allocator) -> (err: Error) {
- context.allocator = allocator;
+ context.allocator = allocator
- bits := bits;
+ bits := bits
if bits < 0 { return .Invalid_Argument; }
- internal_copy(dest, src) or_return;
+ internal_copy(dest, src) or_return
/*
Grow `dest` to accommodate the additional bits.
*/
- digits_needed := dest.used + (bits / _DIGIT_BITS) + 1;
- internal_grow(dest, digits_needed) or_return;
- dest.used = digits_needed;
+ digits_needed := dest.used + (bits / _DIGIT_BITS) + 1
+ internal_grow(dest, digits_needed) or_return
+ dest.used = digits_needed
/*
Shift by as many digits in the bit count as we have.
*/
if bits >= _DIGIT_BITS {
- internal_shl_digit(dest, bits / _DIGIT_BITS) or_return;
+ internal_shl_digit(dest, bits / _DIGIT_BITS) or_return
}
/*
Shift any remaining bit count < _DIGIT_BITS
*/
- bits %= _DIGIT_BITS;
+ bits %= _DIGIT_BITS
if bits != 0 {
- mask := (DIGIT(1) << uint(bits)) - DIGIT(1);
- shift := DIGIT(_DIGIT_BITS - bits);
- carry := DIGIT(0);
+ mask := (DIGIT(1) << uint(bits)) - DIGIT(1)
+ shift := DIGIT(_DIGIT_BITS - bits)
+ carry := DIGIT(0)
#no_bounds_check for x:= 0; x < dest.used; x+= 1 {
- fwd_carry := (dest.digit[x] >> shift) & mask;
- dest.digit[x] = (dest.digit[x] << uint(bits) | carry) & _MASK;
- carry = fwd_carry;
+ fwd_carry := (dest.digit[x] >> shift) & mask
+ dest.digit[x] = (dest.digit[x] << uint(bits) | carry) & _MASK
+ carry = fwd_carry
}
/*
Use final carry.
*/
if carry != 0 {
- dest.digit[dest.used] = carry;
- dest.used += 1;
+ dest.digit[dest.used] = carry
+ dest.used += 1
}
}
- return internal_clamp(dest);
+ return internal_clamp(dest)
}
-internal_shl :: proc { internal_int_shl, };
+internal_shl :: proc { internal_int_shl, }
/*
Shift left by `digits` * _DIGIT_BITS bits.
*/
internal_int_shl_digit :: proc(quotient: ^Int, digits: int, allocator := context.allocator) -> (err: Error) {
- context.allocator = allocator;
+ context.allocator = allocator
if digits <= 0 { return nil; }
@@ -2493,7 +2493,7 @@ internal_int_shl_digit :: proc(quotient: ^Int, digits: int, allocator := context
No need to shift a zero.
*/
if #force_inline internal_is_zero(quotient) {
- return nil;
+ return nil
}
/*
@@ -2510,14 +2510,14 @@ internal_int_shl_digit :: proc(quotient: ^Int, digits: int, allocator := context
except the window goes the other way around.
*/
#no_bounds_check for x := quotient.used; x > 0; x -= 1 {
- quotient.digit[x+digits-1] = quotient.digit[x-1];
+ quotient.digit[x+digits-1] = quotient.digit[x-1]
}
- quotient.used += digits;
- mem.zero_slice(quotient.digit[:digits]);
- return nil;
+ quotient.used += digits
+ mem.zero_slice(quotient.digit[:digits])
+ return nil
}
-internal_shl_digit :: proc { internal_int_shl_digit, };
+internal_shl_digit :: proc { internal_int_shl_digit, }
/*
Count bits in an `Int`.
@@ -2531,13 +2531,13 @@ internal_count_bits :: proc(a: ^Int) -> (count: int) {
/*
Get the number of DIGITs and use it.
*/
- count = (a.used - 1) * _DIGIT_BITS;
+ count = (a.used - 1) * _DIGIT_BITS
/*
Take the last DIGIT and count the bits in it.
*/
- clz := int(intrinsics.count_leading_zeros(a.digit[a.used - 1]));
- count += (_DIGIT_TYPE_BITS - clz);
- return;
+ clz := int(intrinsics.count_leading_zeros(a.digit[a.used - 1]))
+ count += (_DIGIT_TYPE_BITS - clz)
+ return
}
/*
@@ -2555,117 +2555,117 @@ internal_int_count_lsb :: proc(a: ^Int) -> (count: int, err: Error) {
/*
Scan lower digits until non-zero.
*/
- x: int;
+ x: int
#no_bounds_check for x = 0; x < a.used && a.digit[x] == 0; x += 1 {}
- q := a.digit[x];
- x *= _DIGIT_BITS;
- x += internal_count_lsb(q);
- return x, nil;
+ q := a.digit[x]
+ x *= _DIGIT_BITS
+ x += internal_count_lsb(q)
+ return x, nil
}
internal_platform_count_lsb :: #force_inline proc(a: $T) -> (count: int)
where intrinsics.type_is_integer(T) && intrinsics.type_is_unsigned(T) {
- return int(intrinsics.count_trailing_zeros(a)) if a > 0 else 0;
+ return int(intrinsics.count_trailing_zeros(a)) if a > 0 else 0
}
-internal_count_lsb :: proc { internal_int_count_lsb, internal_platform_count_lsb, };
+internal_count_lsb :: proc { internal_int_count_lsb, internal_platform_count_lsb, }
internal_int_random_digit :: proc(r: ^rnd.Rand = nil) -> (res: DIGIT) {
when _DIGIT_BITS == 60 { // DIGIT = u64
- return DIGIT(rnd.uint64(r)) & _MASK;
+ return DIGIT(rnd.uint64(r)) & _MASK
} else when _DIGIT_BITS == 28 { // DIGIT = u32
- return DIGIT(rnd.uint32(r)) & _MASK;
+ return DIGIT(rnd.uint32(r)) & _MASK
} else {
- panic("Unsupported DIGIT size.");
+ panic("Unsupported DIGIT size.")
}
- return 0; // We shouldn't get here.
+ return 0 // We shouldn't get here.
}
internal_int_rand :: proc(dest: ^Int, bits: int, r: ^rnd.Rand = nil, allocator := context.allocator) -> (err: Error) {
- context.allocator = allocator;
+ context.allocator = allocator
- bits := bits;
+ bits := bits
if bits <= 0 { return .Invalid_Argument; }
- digits := bits / _DIGIT_BITS;
- bits %= _DIGIT_BITS;
+ digits := bits / _DIGIT_BITS
+ bits %= _DIGIT_BITS
if bits > 0 {
- digits += 1;
+ digits += 1
}
#force_inline internal_grow(dest, digits) or_return;
for i := 0; i < digits; i += 1 {
- dest.digit[i] = int_random_digit(r) & _MASK;
+ dest.digit[i] = int_random_digit(r) & _MASK
}
if bits > 0 {
- dest.digit[digits - 1] &= ((1 << uint(bits)) - 1);
+ dest.digit[digits - 1] &= ((1 << uint(bits)) - 1)
}
- dest.used = digits;
- return nil;
+ dest.used = digits
+ return nil
}
-internal_rand :: proc { internal_int_rand, };
+internal_rand :: proc { internal_int_rand, }
/*
Internal helpers.
*/
internal_assert_initialized :: proc(a: ^Int, loc := #caller_location) {
- assert(internal_is_initialized(a), "`Int` was not properly initialized.", loc);
+ assert(internal_is_initialized(a), "`Int` was not properly initialized.", loc)
}
internal_clear_if_uninitialized_single :: proc(arg: ^Int, allocator := context.allocator) -> (err: Error) {
- context.allocator = allocator;
+ context.allocator = allocator
if ! #force_inline internal_is_initialized(arg) {
- return #force_inline internal_grow(arg, _DEFAULT_DIGIT_COUNT);
+ return #force_inline internal_grow(arg, _DEFAULT_DIGIT_COUNT)
}
- return err;
+ return err
}
internal_clear_if_uninitialized_multi :: proc(args: ..^Int, allocator := context.allocator) -> (err: Error) {
- context.allocator = allocator;
+ context.allocator = allocator
for i in args {
if ! #force_inline internal_is_initialized(i) {
- e := #force_inline internal_grow(i, _DEFAULT_DIGIT_COUNT);
+ e := #force_inline internal_grow(i, _DEFAULT_DIGIT_COUNT)
if e != nil { err = e; }
}
}
- return err;
+ return err
}
-internal_clear_if_uninitialized :: proc {internal_clear_if_uninitialized_single, internal_clear_if_uninitialized_multi, };
+internal_clear_if_uninitialized :: proc {internal_clear_if_uninitialized_single, internal_clear_if_uninitialized_multi, }
internal_error_if_immutable_single :: proc(arg: ^Int) -> (err: Error) {
if arg != nil && .Immutable in arg.flags { return .Assignment_To_Immutable; }
- return nil;
+ return nil
}
internal_error_if_immutable_multi :: proc(args: ..^Int) -> (err: Error) {
for i in args {
if i != nil && .Immutable in i.flags { return .Assignment_To_Immutable; }
}
- return nil;
+ return nil
}
-internal_error_if_immutable :: proc {internal_error_if_immutable_single, internal_error_if_immutable_multi, };
+internal_error_if_immutable :: proc {internal_error_if_immutable_single, internal_error_if_immutable_multi, }
/*
Allocates several `Int`s at once.
*/
internal_int_init_multi :: proc(integers: ..^Int, allocator := context.allocator) -> (err: Error) {
- context.allocator = allocator;
+ context.allocator = allocator
- integers := integers;
+ integers := integers
for a in &integers {
- internal_clear(a) or_return;
+ internal_clear(a) or_return
}
- return nil;
+ return nil
}
-internal_init_multi :: proc { internal_int_init_multi, };
+internal_init_multi :: proc { internal_int_init_multi, }
/*
Trim unused digits.
@@ -2678,7 +2678,7 @@ internal_clamp :: proc(a: ^Int) -> (err: Error) {
if #force_inline internal_is_zero(a) { a.sign = .Zero_or_Positive; }
- return nil;
+ return nil
}
@@ -2686,21 +2686,21 @@ internal_int_zero_unused :: #force_inline proc(dest: ^Int, old_used := -1) {
/*
If we don't pass the number of previously used DIGITs, we zero all remaining ones.
*/
- zero_count: int;
+ zero_count: int
if old_used == -1 {
- zero_count = len(dest.digit) - dest.used;
+ zero_count = len(dest.digit) - dest.used
} else {
- zero_count = old_used - dest.used;
+ zero_count = old_used - dest.used
}
/*
Zero remainder.
*/
if zero_count > 0 && dest.used < len(dest.digit) {
- mem.zero_slice(dest.digit[dest.used:][:zero_count]);
+ mem.zero_slice(dest.digit[dest.used:][:zero_count])
}
}
-internal_zero_unused :: proc { internal_int_zero_unused, };
+internal_zero_unused :: proc { internal_int_zero_unused, }
/*
========================== End of low-level routines ==========================
diff --git a/core/math/big/logical.odin b/core/math/big/logical.odin
index 64f3b0898..d455d480d 100644
--- a/core/math/big/logical.odin
+++ b/core/math/big/logical.odin
@@ -22,37 +22,37 @@ package math_big
2's complement `and`, returns `dest = a & b;`
*/
int_and :: proc(dest, a, b: ^Int, allocator := context.allocator) -> (err: Error) {
- assert_if_nil(dest, a, b);
- context.allocator = allocator;
+ assert_if_nil(dest, a, b)
+ context.allocator = allocator
- internal_clear_if_uninitialized(a, b) or_return;
- return #force_inline internal_int_and(dest, a, b);
+ internal_clear_if_uninitialized(a, b) or_return
+ return #force_inline internal_int_and(dest, a, b)
}
-and :: proc { int_and, };
+and :: proc { int_and, }
/*
2's complement `or`, returns `dest = a | b;`
*/
int_or :: proc(dest, a, b: ^Int, allocator := context.allocator) -> (err: Error) {
- assert_if_nil(dest, a, b);
- context.allocator = allocator;
+ assert_if_nil(dest, a, b)
+ context.allocator = allocator
- internal_clear_if_uninitialized(a, b) or_return;
- return #force_inline internal_int_or(dest, a, b);
+ internal_clear_if_uninitialized(a, b) or_return
+ return #force_inline internal_int_or(dest, a, b)
}
-or :: proc { int_or, };
+or :: proc { int_or, }
/*
2's complement `xor`, returns `dest = a ^ b;`
*/
int_xor :: proc(dest, a, b: ^Int, allocator := context.allocator) -> (err: Error) {
- assert_if_nil(dest, a, b);
- context.allocator = allocator;
+ assert_if_nil(dest, a, b)
+ context.allocator = allocator
- internal_clear_if_uninitialized(a, b) or_return;
- return #force_inline internal_int_xor(dest, a, b);
+ internal_clear_if_uninitialized(a, b) or_return
+ return #force_inline internal_int_xor(dest, a, b)
}
-xor :: proc { int_xor, };
+xor :: proc { int_xor, }
/*
dest = ~src
@@ -61,31 +61,31 @@ int_complement :: proc(dest, src: ^Int, allocator := context.allocator) -> (err:
/*
Check that `src` and `dest` are usable.
*/
- assert_if_nil(dest, src);
- context.allocator = allocator;
+ assert_if_nil(dest, src)
+ context.allocator = allocator
- internal_clear_if_uninitialized(dest, src) or_return;
- return #force_inline internal_int_complement(dest, src);
+ internal_clear_if_uninitialized(dest, src) or_return
+ return #force_inline internal_int_complement(dest, src)
}
-complement :: proc { int_complement, };
+complement :: proc { int_complement, }
/*
quotient, remainder := numerator >> bits;
`remainder` is allowed to be passed a `nil`, in which case `mod` won't be computed.
*/
int_shrmod :: proc(quotient, remainder, numerator: ^Int, bits: int, allocator := context.allocator) -> (err: Error) {
- assert_if_nil(quotient, numerator);
- context.allocator = allocator;
+ assert_if_nil(quotient, numerator)
+ context.allocator = allocator
if err = internal_clear_if_uninitialized(quotient, numerator); err != nil { return err; }
- return #force_inline internal_int_shrmod(quotient, remainder, numerator, bits);
+ return #force_inline internal_int_shrmod(quotient, remainder, numerator, bits)
}
-shrmod :: proc { int_shrmod, };
+shrmod :: proc { int_shrmod, }
int_shr :: proc(dest, source: ^Int, bits: int, allocator := context.allocator) -> (err: Error) {
- return #force_inline shrmod(dest, nil, source, bits, allocator);
+ return #force_inline shrmod(dest, nil, source, bits, allocator)
}
-shr :: proc { int_shr, };
+shr :: proc { int_shr, }
/*
Shift right by `digits` * _DIGIT_BITS bits.
@@ -94,38 +94,38 @@ int_shr_digit :: proc(quotient: ^Int, digits: int, allocator := context.allocato
/*
Check that `quotient` is usable.
*/
- assert_if_nil(quotient);
- context.allocator = allocator;
+ assert_if_nil(quotient)
+ context.allocator = allocator
- internal_clear_if_uninitialized(quotient) or_return;
- return #force_inline internal_int_shr_digit(quotient, digits);
+ internal_clear_if_uninitialized(quotient) or_return
+ return #force_inline internal_int_shr_digit(quotient, digits)
}
-shr_digit :: proc { int_shr_digit, };
+shr_digit :: proc { int_shr_digit, }
/*
Shift right by a certain bit count with sign extension.
*/
int_shr_signed :: proc(dest, src: ^Int, bits: int, allocator := context.allocator) -> (err: Error) {
- assert_if_nil(dest, src);
- context.allocator = allocator;
+ assert_if_nil(dest, src)
+ context.allocator = allocator
- internal_clear_if_uninitialized(dest, src) or_return;
- return #force_inline internal_int_shr_signed(dest, src, bits);
+ internal_clear_if_uninitialized(dest, src) or_return
+ return #force_inline internal_int_shr_signed(dest, src, bits)
}
-shr_signed :: proc { int_shr_signed, };
+shr_signed :: proc { int_shr_signed, }
/*
Shift left by a certain bit count.
*/
int_shl :: proc(dest, src: ^Int, bits: int, allocator := context.allocator) -> (err: Error) {
- assert_if_nil(dest, src);
- context.allocator = allocator;
+ assert_if_nil(dest, src)
+ context.allocator = allocator
- internal_clear_if_uninitialized(dest, src) or_return;
- return #force_inline internal_int_shl(dest, src, bits);
+ internal_clear_if_uninitialized(dest, src) or_return
+ return #force_inline internal_int_shl(dest, src, bits)
}
-shl :: proc { int_shl, };
+shl :: proc { int_shl, }
/*
@@ -135,10 +135,10 @@ int_shl_digit :: proc(quotient: ^Int, digits: int, allocator := context.allocato
/*
Check that `quotient` is usable.
*/
- assert_if_nil(quotient);
- context.allocator = allocator;
+ assert_if_nil(quotient)
+ context.allocator = allocator
- internal_clear_if_uninitialized(quotient) or_return;
- return #force_inline internal_int_shl_digit(quotient, digits);
+ internal_clear_if_uninitialized(quotient) or_return
+ return #force_inline internal_int_shl_digit(quotient, digits)
}
shl_digit :: proc { int_shl_digit, }; \ No newline at end of file
diff --git a/core/math/big/prime.odin b/core/math/big/prime.odin
index f35e02807..b943da83b 100644
--- a/core/math/big/prime.odin
+++ b/core/math/big/prime.odin
@@ -16,43 +16,43 @@ package math_big
Returns true if it is, false if not.
*/
int_prime_is_divisible :: proc(a: ^Int, allocator := context.allocator) -> (res: bool, err: Error) {
- assert_if_nil(a);
- context.allocator = allocator;
+ assert_if_nil(a)
+ context.allocator = allocator
- internal_clear_if_uninitialized(a) or_return;
+ internal_clear_if_uninitialized(a) or_return
for prime in _private_prime_table {
- rem := #force_inline int_mod_digit(a, prime) or_return;
+ rem := #force_inline int_mod_digit(a, prime) or_return
if rem == 0 {
- return true, nil;
+ return true, nil
}
}
/*
Default to not divisible.
*/
- return false, nil;
+ return false, nil
}
/*
Computes xR**-1 == x (mod N) via Montgomery Reduction.
*/
internal_int_montgomery_reduce :: proc(x, n: ^Int, rho: DIGIT, allocator := context.allocator) -> (err: Error) {
- context.allocator = allocator;
+ context.allocator = allocator
/*
Can the fast reduction [comba] method be used?
Note that unlike in mul, you're safely allowed *less* than the available columns [255 per default],
since carries are fixed up in the inner loop.
*/
- digs := (n.used * 2) + 1;
+ digs := (n.used * 2) + 1
if digs < _WARRAY && x.used <= _WARRAY && n.used < _MAX_COMBA {
- return _private_montgomery_reduce_comba(x, n, rho);
+ return _private_montgomery_reduce_comba(x, n, rho)
}
/*
Grow the input as required
*/
- internal_grow(x, digs) or_return;
- x.used = digs;
+ internal_grow(x, digs) or_return
+ x.used = digs
for ix := 0; ix < n.used; ix += 1 {
/*
@@ -62,29 +62,29 @@ internal_int_montgomery_reduce :: proc(x, n: ^Int, rho: DIGIT, allocator := cont
to reduce the input one digit at a time.
*/
- mu := DIGIT((_WORD(x.digit[ix]) * _WORD(rho)) & _WORD(_MASK));
+ mu := DIGIT((_WORD(x.digit[ix]) * _WORD(rho)) & _WORD(_MASK))
/*
a = a + mu * m * b**i
Multiply and add in place.
*/
- u := DIGIT(0);
- iy := int(0);
+ u := DIGIT(0)
+ iy := int(0)
for ; iy < n.used; iy += 1 {
/*
Compute product and sum.
*/
- r := (_WORD(mu) * _WORD(n.digit[iy]) + _WORD(u) + _WORD(x.digit[ix + iy]));
+ r := (_WORD(mu) * _WORD(n.digit[iy]) + _WORD(u) + _WORD(x.digit[ix + iy]))
/*
Get carry.
*/
- u = DIGIT(r >> _DIGIT_BITS);
+ u = DIGIT(r >> _DIGIT_BITS)
/*
Fix digit.
*/
- x.digit[ix + iy] = DIGIT(r & _WORD(_MASK));
+ x.digit[ix + iy] = DIGIT(r & _WORD(_MASK))
}
/*
@@ -92,10 +92,10 @@ internal_int_montgomery_reduce :: proc(x, n: ^Int, rho: DIGIT, allocator := cont
Propagate carries upwards as required.
*/
for u != 0 {
- x.digit[ix + iy] += u;
- u = x.digit[ix + iy] >> _DIGIT_BITS;
- x.digit[ix + iy] &= _MASK;
- iy += 1;
+ x.digit[ix + iy] += u
+ u = x.digit[ix + iy] >> _DIGIT_BITS
+ x.digit[ix + iy] &= _MASK
+ iy += 1
}
}
@@ -106,26 +106,26 @@ internal_int_montgomery_reduce :: proc(x, n: ^Int, rho: DIGIT, allocator := cont
x = x/b**n.used.
*/
- internal_clamp(x);
- internal_shr_digit(x, n.used);
+ internal_clamp(x)
+ internal_shr_digit(x, n.used)
/*
if x >= n then x = x - n
*/
if internal_cmp_mag(x, n) != -1 {
- return internal_sub(x, x, n);
+ return internal_sub(x, x, n)
}
- return nil;
+ return nil
}
int_montgomery_reduce :: proc(x, n: ^Int, rho: DIGIT, allocator := context.allocator) -> (err: Error) {
- assert_if_nil(x, n);
- context.allocator = allocator;
+ assert_if_nil(x, n)
+ context.allocator = allocator
- internal_clear_if_uninitialized(x, n) or_return;
+ internal_clear_if_uninitialized(x, n) or_return
- return #force_inline internal_int_montgomery_reduce(x, n, rho);
+ return #force_inline internal_int_montgomery_reduce(x, n, rho)
}
/*
@@ -135,39 +135,39 @@ int_montgomery_reduce :: proc(x, n: ^Int, rho: DIGIT, allocator := context.alloc
the leading bit of b. This saves alot of multiple precision shifting.
*/
internal_int_montgomery_calc_normalization :: proc(a, b: ^Int, allocator := context.allocator) -> (err: Error) {
- context.allocator = allocator;
+ context.allocator = allocator
/*
How many bits of last digit does b use.
*/
- bits := internal_count_bits(b) % _DIGIT_BITS;
+ bits := internal_count_bits(b) % _DIGIT_BITS
if b.used > 1 {
- power := ((b.used - 1) * _DIGIT_BITS) + bits - 1;
- internal_int_power_of_two(a, power) or_return;
+ power := ((b.used - 1) * _DIGIT_BITS) + bits - 1
+ internal_int_power_of_two(a, power) or_return
} else {
- internal_one(a);
- bits = 1;
+ internal_one(a)
+ bits = 1
}
/*
Now compute C = A * B mod b.
*/
for x := bits - 1; x < _DIGIT_BITS; x += 1 {
- internal_int_shl1(a, a) or_return;
+ internal_int_shl1(a, a) or_return
if internal_cmp_mag(a, b) != -1 {
- internal_sub(a, a, b) or_return;
+ internal_sub(a, a, b) or_return
}
}
- return nil;
+ return nil
}
int_montgomery_calc_normalization :: proc(a, b: ^Int, allocator := context.allocator) -> (err: Error) {
- assert_if_nil(a, b);
- context.allocator = allocator;
+ assert_if_nil(a, b)
+ context.allocator = allocator
- internal_clear_if_uninitialized(a, b) or_return;
+ internal_clear_if_uninitialized(a, b) or_return
- return #force_inline internal_int_montgomery_calc_normalization(a, b);
+ return #force_inline internal_int_montgomery_calc_normalization(a, b)
}
/*
@@ -182,29 +182,29 @@ internal_int_montgomery_setup :: proc(n: ^Int) -> (rho: DIGIT, err: Error) {
=> 2*X*A - X*X*A*A = 1
=> 2*(1) - (1) = 1
*/
- b := n.digit[0];
+ b := n.digit[0]
if b & 1 == 0 { return 0, .Invalid_Argument; }
- x := (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */
- x *= 2 - (b * x); /* here x*a==1 mod 2**8 */
- x *= 2 - (b * x); /* here x*a==1 mod 2**16 */
+ x := (((b + 2) & 4) << 1) + b /* here x*a==1 mod 2**4 */
+ x *= 2 - (b * x) /* here x*a==1 mod 2**8 */
+ x *= 2 - (b * x) /* here x*a==1 mod 2**16 */
when _WORD_TYPE_BITS == 64 {
- x *= 2 - (b * x); /* here x*a==1 mod 2**32 */
- x *= 2 - (b * x); /* here x*a==1 mod 2**64 */
+ x *= 2 - (b * x) /* here x*a==1 mod 2**32 */
+ x *= 2 - (b * x) /* here x*a==1 mod 2**64 */
}
/*
rho = -1/m mod b
*/
- rho = DIGIT(((_WORD(1) << _WORD(_DIGIT_BITS)) - _WORD(x)) & _WORD(_MASK));
- return rho, nil;
+ rho = DIGIT(((_WORD(1) << _WORD(_DIGIT_BITS)) - _WORD(x)) & _WORD(_MASK))
+ return rho, nil
}
int_montgomery_setup :: proc(n: ^Int, allocator := context.allocator) -> (rho: DIGIT, err: Error) {
- assert_if_nil(n);
- internal_clear_if_uninitialized(n, allocator) or_return;
+ assert_if_nil(n)
+ internal_clear_if_uninitialized(n, allocator) or_return
- return #force_inline internal_int_montgomery_setup(n);
+ return #force_inline internal_int_montgomery_setup(n)
}
/*
@@ -213,44 +213,44 @@ int_montgomery_setup :: proc(n: ^Int, allocator := context.allocator) -> (rho: D
number_of_rabin_miller_trials :: proc(bit_size: int) -> (number_of_trials: int) {
switch {
case bit_size <= 80:
- return - 1; /* Use deterministic algorithm for size <= 80 bits */
+ return - 1 /* Use deterministic algorithm for size <= 80 bits */
case bit_size >= 81 && bit_size < 96:
- return 37; /* max. error = 2^(-96) */
+ return 37 /* max. error = 2^(-96) */
case bit_size >= 96 && bit_size < 128:
- return 32; /* max. error = 2^(-96) */
+ return 32 /* max. error = 2^(-96) */
case bit_size >= 128 && bit_size < 160:
- return 40; /* max. error = 2^(-112) */
+ return 40 /* max. error = 2^(-112) */
case bit_size >= 160 && bit_size < 256:
- return 35; /* max. error = 2^(-112) */
+ return 35 /* max. error = 2^(-112) */
case bit_size >= 256 && bit_size < 384:
- return 27; /* max. error = 2^(-128) */
+ return 27 /* max. error = 2^(-128) */
case bit_size >= 384 && bit_size < 512:
- return 16; /* max. error = 2^(-128) */
+ return 16 /* max. error = 2^(-128) */
case bit_size >= 512 && bit_size < 768:
- return 18; /* max. error = 2^(-160) */
+ return 18 /* max. error = 2^(-160) */
case bit_size >= 768 && bit_size < 896:
- return 11; /* max. error = 2^(-160) */
+ return 11 /* max. error = 2^(-160) */
case bit_size >= 896 && bit_size < 1_024:
- return 10; /* max. error = 2^(-160) */
+ return 10 /* max. error = 2^(-160) */
case bit_size >= 1_024 && bit_size < 1_536:
- return 12; /* max. error = 2^(-192) */
+ return 12 /* max. error = 2^(-192) */
case bit_size >= 1_536 && bit_size < 2_048:
- return 8; /* max. error = 2^(-192) */
+ return 8 /* max. error = 2^(-192) */
case bit_size >= 2_048 && bit_size < 3_072:
- return 6; /* max. error = 2^(-192) */
+ return 6 /* max. error = 2^(-192) */
case bit_size >= 3_072 && bit_size < 4_096:
- return 4; /* max. error = 2^(-192) */
+ return 4 /* max. error = 2^(-192) */
case bit_size >= 4_096 && bit_size < 5_120:
- return 5; /* max. error = 2^(-256) */
+ return 5 /* max. error = 2^(-256) */
case bit_size >= 5_120 && bit_size < 6_144:
- return 4; /* max. error = 2^(-256) */
+ return 4 /* max. error = 2^(-256) */
case bit_size >= 6_144 && bit_size < 8_192:
- return 4; /* max. error = 2^(-256) */
+ return 4 /* max. error = 2^(-256) */
case bit_size >= 8_192 && bit_size < 9_216:
- return 3; /* max. error = 2^(-256) */
+ return 3 /* max. error = 2^(-256) */
case bit_size >= 9_216 && bit_size < 10_240:
- return 3; /* max. error = 2^(-256) */
+ return 3 /* max. error = 2^(-256) */
case:
- return 2; /* For keysizes bigger than 10_240 use always at least 2 Rounds */
+ return 2 /* For keysizes bigger than 10_240 use always at least 2 Rounds */
}
} \ No newline at end of file
diff --git a/core/math/big/private.odin b/core/math/big/private.odin
index d71946ce2..81bae57f0 100644
--- a/core/math/big/private.odin
+++ b/core/math/big/private.odin
@@ -27,35 +27,35 @@ import "core:mem"
many digits of output are created.
*/
_private_int_mul :: proc(dest, a, b: ^Int, digits: int, allocator := context.allocator) -> (err: Error) {
- context.allocator = allocator;
+ context.allocator = allocator
/*
Can we use the fast multiplier?
*/
if digits < _WARRAY && min(a.used, b.used) < _MAX_COMBA {
- return #force_inline _private_int_mul_comba(dest, a, b, digits);
+ return #force_inline _private_int_mul_comba(dest, a, b, digits)
}
/*
Set up temporary output `Int`, which we'll swap for `dest` when done.
*/
- t := &Int{};
+ t := &Int{}
- internal_grow(t, max(digits, _DEFAULT_DIGIT_COUNT)) or_return;
- t.used = digits;
+ internal_grow(t, max(digits, _DEFAULT_DIGIT_COUNT)) or_return
+ t.used = digits
/*
Compute the digits of the product directly.
*/
- pa := a.used;
+ pa := a.used
for ix := 0; ix < pa; ix += 1 {
/*
Limit ourselves to `digits` DIGITs of output.
*/
- pb := min(b.used, digits - ix);
- carry := _WORD(0);
- iy := 0;
+ pb := min(b.used, digits - ix)
+ carry := _WORD(0)
+ iy := 0
/*
Compute the column of the output and propagate the carry.
@@ -64,29 +64,29 @@ _private_int_mul :: proc(dest, a, b: ^Int, digits: int, allocator := context.all
/*
Compute the column as a _WORD.
*/
- column := _WORD(t.digit[ix + iy]) + _WORD(a.digit[ix]) * _WORD(b.digit[iy]) + carry;
+ column := _WORD(t.digit[ix + iy]) + _WORD(a.digit[ix]) * _WORD(b.digit[iy]) + carry
/*
The new column is the lower part of the result.
*/
- t.digit[ix + iy] = DIGIT(column & _WORD(_MASK));
+ t.digit[ix + iy] = DIGIT(column & _WORD(_MASK))
/*
Get the carry word from the result.
*/
- carry = column >> _DIGIT_BITS;
+ carry = column >> _DIGIT_BITS
}
/*
Set carry if it is placed below digits
*/
if ix + iy < digits {
- t.digit[ix + pb] = DIGIT(carry);
+ t.digit[ix + pb] = DIGIT(carry)
}
}
- internal_swap(dest, t);
- internal_destroy(t);
- return internal_clamp(dest);
+ internal_swap(dest, t)
+ internal_destroy(t)
+ return internal_clamp(dest)
}
@@ -110,121 +110,121 @@ _private_int_mul :: proc(dest, a, b: ^Int, digits: int, allocator := context.all
Centro Vito Volterra Universita di Roma Tor Vergata (2006)
*/
_private_int_mul_toom :: proc(dest, a, b: ^Int, allocator := context.allocator) -> (err: Error) {
- context.allocator = allocator;
+ context.allocator = allocator
- S1, S2, T1, a0, a1, a2, b0, b1, b2 := &Int{}, &Int{}, &Int{}, &Int{}, &Int{}, &Int{}, &Int{}, &Int{}, &Int{};
- defer internal_destroy(S1, S2, T1, a0, a1, a2, b0, b1, b2);
+ S1, S2, T1, a0, a1, a2, b0, b1, b2 := &Int{}, &Int{}, &Int{}, &Int{}, &Int{}, &Int{}, &Int{}, &Int{}, &Int{}
+ defer internal_destroy(S1, S2, T1, a0, a1, a2, b0, b1, b2)
/*
Init temps.
*/
- internal_init_multi(S1, S2, T1) or_return;
+ internal_init_multi(S1, S2, T1) or_return
/*
B
*/
- B := min(a.used, b.used) / 3;
+ B := min(a.used, b.used) / 3
/*
a = a2 * x^2 + a1 * x + a0;
*/
- internal_grow(a0, B) or_return;
- internal_grow(a1, B) or_return;
- internal_grow(a2, a.used - 2 * B) or_return;
+ internal_grow(a0, B) or_return
+ internal_grow(a1, B) or_return
+ internal_grow(a2, a.used - 2 * B) or_return
- a0.used, a1.used = B, B;
- a2.used = a.used - 2 * B;
+ a0.used, a1.used = B, B
+ a2.used = a.used - 2 * B
- internal_copy_digits(a0, a, a0.used) or_return;
- internal_copy_digits(a1, a, a1.used, B) or_return;
- internal_copy_digits(a2, a, a2.used, 2 * B) or_return;
+ internal_copy_digits(a0, a, a0.used) or_return
+ internal_copy_digits(a1, a, a1.used, B) or_return
+ internal_copy_digits(a2, a, a2.used, 2 * B) or_return
- internal_clamp(a0);
- internal_clamp(a1);
- internal_clamp(a2);
+ internal_clamp(a0)
+ internal_clamp(a1)
+ internal_clamp(a2)
/*
b = b2 * x^2 + b1 * x + b0;
*/
- internal_grow(b0, B) or_return;
- internal_grow(b1, B) or_return;
- internal_grow(b2, b.used - 2 * B) or_return;
+ internal_grow(b0, B) or_return
+ internal_grow(b1, B) or_return
+ internal_grow(b2, b.used - 2 * B) or_return
- b0.used, b1.used = B, B;
- b2.used = b.used - 2 * B;
+ b0.used, b1.used = B, B
+ b2.used = b.used - 2 * B
- internal_copy_digits(b0, b, b0.used) or_return;
- internal_copy_digits(b1, b, b1.used, B) or_return;
- internal_copy_digits(b2, b, b2.used, 2 * B) or_return;
+ internal_copy_digits(b0, b, b0.used) or_return
+ internal_copy_digits(b1, b, b1.used, B) or_return
+ internal_copy_digits(b2, b, b2.used, 2 * B) or_return
- internal_clamp(b0);
- internal_clamp(b1);
- internal_clamp(b2);
+ internal_clamp(b0)
+ internal_clamp(b1)
+ internal_clamp(b2)
/*
\\ S1 = (a2+a1+a0) * (b2+b1+b0);
*/
- internal_add(T1, a2, a1) or_return; /* T1 = a2 + a1; */
- internal_add(S2, T1, a0) or_return; /* S2 = T1 + a0; */
- internal_add(dest, b2, b1) or_return; /* dest = b2 + b1; */
- internal_add(S1, dest, b0) or_return; /* S1 = c + b0; */
- internal_mul(S1, S1, S2) or_return; /* S1 = S1 * S2; */
+ internal_add(T1, a2, a1) or_return /* T1 = a2 + a1; */
+ internal_add(S2, T1, a0) or_return /* S2 = T1 + a0; */
+ internal_add(dest, b2, b1) or_return /* dest = b2 + b1; */
+ internal_add(S1, dest, b0) or_return /* S1 = c + b0; */
+ internal_mul(S1, S1, S2) or_return /* S1 = S1 * S2; */
/*
\\S2 = (4*a2+2*a1+a0) * (4*b2+2*b1+b0);
*/
- internal_add(T1, T1, a2) or_return; /* T1 = T1 + a2; */
- internal_int_shl1(T1, T1) or_return; /* T1 = T1 << 1; */
- internal_add(T1, T1, a0) or_return; /* T1 = T1 + a0; */
- internal_add(dest, dest, b2) or_return; /* c = c + b2; */
- internal_int_shl1(dest, dest) or_return; /* c = c << 1; */
- internal_add(dest, dest, b0) or_return; /* c = c + b0; */
- internal_mul(S2, T1, dest) or_return; /* S2 = T1 * c; */
+ internal_add(T1, T1, a2) or_return /* T1 = T1 + a2; */
+ internal_int_shl1(T1, T1) or_return /* T1 = T1 << 1; */
+ internal_add(T1, T1, a0) or_return /* T1 = T1 + a0; */
+ internal_add(dest, dest, b2) or_return /* c = c + b2; */
+ internal_int_shl1(dest, dest) or_return /* c = c << 1; */
+ internal_add(dest, dest, b0) or_return /* c = c + b0; */
+ internal_mul(S2, T1, dest) or_return /* S2 = T1 * c; */
/*
\\S3 = (a2-a1+a0) * (b2-b1+b0);
*/
- internal_sub(a1, a2, a1) or_return; /* a1 = a2 - a1; */
- internal_add(a1, a1, a0) or_return; /* a1 = a1 + a0; */
- internal_sub(b1, b2, b1) or_return; /* b1 = b2 - b1; */
- internal_add(b1, b1, b0) or_return; /* b1 = b1 + b0; */
- internal_mul(a1, a1, b1) or_return; /* a1 = a1 * b1; */
- internal_mul(b1, a2, b2) or_return; /* b1 = a2 * b2; */
+ internal_sub(a1, a2, a1) or_return /* a1 = a2 - a1; */
+ internal_add(a1, a1, a0) or_return /* a1 = a1 + a0; */
+ internal_sub(b1, b2, b1) or_return /* b1 = b2 - b1; */
+ internal_add(b1, b1, b0) or_return /* b1 = b1 + b0; */
+ internal_mul(a1, a1, b1) or_return /* a1 = a1 * b1; */
+ internal_mul(b1, a2, b2) or_return /* b1 = a2 * b2; */
/*
\\S2 = (S2 - S3) / 3;
*/
- internal_sub(S2, S2, a1) or_return; /* S2 = S2 - a1; */
- _private_int_div_3(S2, S2) or_return; /* S2 = S2 / 3; \\ this is an exact division */
- internal_sub(a1, S1, a1) or_return; /* a1 = S1 - a1; */
- internal_int_shr1(a1, a1) or_return; /* a1 = a1 >> 1; */
- internal_mul(a0, a0, b0) or_return; /* a0 = a0 * b0; */
- internal_sub(S1, S1, a0) or_return; /* S1 = S1 - a0; */
- internal_sub(S2, S2, S1) or_return; /* S2 = S2 - S1; */
- internal_int_shr1(S2, S2) or_return; /* S2 = S2 >> 1; */
- internal_sub(S1, S1, a1) or_return; /* S1 = S1 - a1; */
- internal_sub(S1, S1, b1) or_return; /* S1 = S1 - b1; */
- internal_int_shl1(T1, b1) or_return; /* T1 = b1 << 1; */
- internal_sub(S2, S2, T1) or_return; /* S2 = S2 - T1; */
- internal_sub(a1, a1, S2) or_return; /* a1 = a1 - S2; */
+ internal_sub(S2, S2, a1) or_return /* S2 = S2 - a1; */
+ _private_int_div_3(S2, S2) or_return /* S2 = S2 / 3; \\ this is an exact division */
+ internal_sub(a1, S1, a1) or_return /* a1 = S1 - a1; */
+ internal_int_shr1(a1, a1) or_return /* a1 = a1 >> 1; */
+ internal_mul(a0, a0, b0) or_return /* a0 = a0 * b0; */
+ internal_sub(S1, S1, a0) or_return /* S1 = S1 - a0; */
+ internal_sub(S2, S2, S1) or_return /* S2 = S2 - S1; */
+ internal_int_shr1(S2, S2) or_return /* S2 = S2 >> 1; */
+ internal_sub(S1, S1, a1) or_return /* S1 = S1 - a1; */
+ internal_sub(S1, S1, b1) or_return /* S1 = S1 - b1; */
+ internal_int_shl1(T1, b1) or_return /* T1 = b1 << 1; */
+ internal_sub(S2, S2, T1) or_return /* S2 = S2 - T1; */
+ internal_sub(a1, a1, S2) or_return /* a1 = a1 - S2; */
/*
P = b1*x^4+ S2*x^3+ S1*x^2+ a1*x + a0;
*/
- internal_shl_digit(b1, 4 * B) or_return;
- internal_shl_digit(S2, 3 * B) or_return;
- internal_add(b1, b1, S2) or_return;
- internal_shl_digit(S1, 2 * B) or_return;
- internal_add(b1, b1, S1) or_return;
- internal_shl_digit(a1, 1 * B) or_return;
- internal_add(b1, b1, a1) or_return;
- internal_add(dest, b1, a0) or_return;
+ internal_shl_digit(b1, 4 * B) or_return
+ internal_shl_digit(S2, 3 * B) or_return
+ internal_add(b1, b1, S2) or_return
+ internal_shl_digit(S1, 2 * B) or_return
+ internal_add(b1, b1, S1) or_return
+ internal_shl_digit(a1, 1 * B) or_return
+ internal_add(b1, b1, a1) or_return
+ internal_add(dest, b1, a0) or_return
/*
a * b - P
*/
- return nil;
+ return nil
}
/*
@@ -255,76 +255,76 @@ _private_int_mul_toom :: proc(dest, a, b: ^Int, allocator := context.allocator)
until a certain size is reached, of around 80 used DIGITs.
*/
_private_int_mul_karatsuba :: proc(dest, a, b: ^Int, allocator := context.allocator) -> (err: Error) {
- context.allocator = allocator;
+ context.allocator = allocator
- x0, x1, y0, y1, t1, x0y0, x1y1 := &Int{}, &Int{}, &Int{}, &Int{}, &Int{}, &Int{}, &Int{};
- defer internal_destroy(x0, x1, y0, y1, t1, x0y0, x1y1);
+ x0, x1, y0, y1, t1, x0y0, x1y1 := &Int{}, &Int{}, &Int{}, &Int{}, &Int{}, &Int{}, &Int{}
+ defer internal_destroy(x0, x1, y0, y1, t1, x0y0, x1y1)
/*
min # of digits, divided by two.
*/
- B := min(a.used, b.used) >> 1;
+ B := min(a.used, b.used) >> 1
/*
Init all the temps.
*/
- internal_grow(x0, B) or_return;
- internal_grow(x1, a.used - B) or_return;
- internal_grow(y0, B) or_return;
- internal_grow(y1, b.used - B) or_return;
- internal_grow(t1, B * 2) or_return;
- internal_grow(x0y0, B * 2) or_return;
- internal_grow(x1y1, B * 2) or_return;
+ internal_grow(x0, B) or_return
+ internal_grow(x1, a.used - B) or_return
+ internal_grow(y0, B) or_return
+ internal_grow(y1, b.used - B) or_return
+ internal_grow(t1, B * 2) or_return
+ internal_grow(x0y0, B * 2) or_return
+ internal_grow(x1y1, B * 2) or_return
/*
Now shift the digits.
*/
- x0.used, y0.used = B, B;
- x1.used = a.used - B;
- y1.used = b.used - B;
+ x0.used, y0.used = B, B
+ x1.used = a.used - B
+ y1.used = b.used - B
/*
We copy the digits directly instead of using higher level functions
since we also need to shift the digits.
*/
- internal_copy_digits(x0, a, x0.used);
- internal_copy_digits(y0, b, y0.used);
- internal_copy_digits(x1, a, x1.used, B);
- internal_copy_digits(y1, b, y1.used, B);
+ internal_copy_digits(x0, a, x0.used)
+ internal_copy_digits(y0, b, y0.used)
+ internal_copy_digits(x1, a, x1.used, B)
+ internal_copy_digits(y1, b, y1.used, B)
/*
Only need to clamp the lower words since by definition the
upper words x1/y1 must have a known number of digits.
*/
- clamp(x0);
- clamp(y0);
+ clamp(x0)
+ clamp(y0)
/*
Now calc the products x0y0 and x1y1,
after this x0 is no longer required, free temp [x0==t2]!
*/
- internal_mul(x0y0, x0, y0) or_return; /* x0y0 = x0*y0 */
- internal_mul(x1y1, x1, y1) or_return; /* x1y1 = x1*y1 */
- internal_add(t1, x1, x0) or_return; /* now calc x1+x0 and */
- internal_add(x0, y1, y0) or_return; /* t2 = y1 + y0 */
- internal_mul(t1, t1, x0) or_return; /* t1 = (x1 + x0) * (y1 + y0) */
+ internal_mul(x0y0, x0, y0) or_return /* x0y0 = x0*y0 */
+ internal_mul(x1y1, x1, y1) or_return /* x1y1 = x1*y1 */
+ internal_add(t1, x1, x0) or_return /* now calc x1+x0 and */
+ internal_add(x0, y1, y0) or_return /* t2 = y1 + y0 */
+ internal_mul(t1, t1, x0) or_return /* t1 = (x1 + x0) * (y1 + y0) */
/*
Add x0y0.
*/
- internal_add(x0, x0y0, x1y1) or_return; /* t2 = x0y0 + x1y1 */
- internal_sub(t1, t1, x0) or_return; /* t1 = (x1+x0)*(y1+y0) - (x1y1 + x0y0) */
+ internal_add(x0, x0y0, x1y1) or_return /* t2 = x0y0 + x1y1 */
+ internal_sub(t1, t1, x0) or_return /* t1 = (x1+x0)*(y1+y0) - (x1y1 + x0y0) */
/*
shift by B.
*/
- internal_shl_digit(t1, B) or_return; /* t1 = (x0y0 + x1y1 - (x1-x0)*(y1-y0))<<B */
- internal_shl_digit(x1y1, B * 2) or_return; /* x1y1 = x1y1 << 2*B */
+ internal_shl_digit(t1, B) or_return /* t1 = (x0y0 + x1y1 - (x1-x0)*(y1-y0))<<B */
+ internal_shl_digit(x1y1, B * 2) or_return /* x1y1 = x1y1 << 2*B */
- internal_add(t1, x0y0, t1) or_return; /* t1 = x0y0 + t1 */
- internal_add(dest, t1, x1y1) or_return; /* t1 = x0y0 + t1 + x1y1 */
+ internal_add(t1, x0y0, t1) or_return /* t1 = x0y0 + t1 */
+ internal_add(dest, t1, x1y1) or_return /* t1 = x0y0 + t1 + x1y1 */
- return nil;
+ return nil
}
@@ -346,84 +346,84 @@ _private_int_mul_karatsuba :: proc(dest, a, b: ^Int, allocator := context.alloca
Based on Algorithm 14.12 on pp.595 of HAC.
*/
_private_int_mul_comba :: proc(dest, a, b: ^Int, digits: int, allocator := context.allocator) -> (err: Error) {
- context.allocator = allocator;
+ context.allocator = allocator
/*
Set up array.
*/
- W: [_WARRAY]DIGIT = ---;
+ W: [_WARRAY]DIGIT = ---
/*
Grow the destination as required.
*/
- internal_grow(dest, digits) or_return;
+ internal_grow(dest, digits) or_return
/*
Number of output digits to produce.
*/
- pa := min(digits, a.used + b.used);
+ pa := min(digits, a.used + b.used)
/*
Clear the carry
*/
- _W := _WORD(0);
+ _W := _WORD(0)
- ix: int;
+ ix: int
for ix = 0; ix < pa; ix += 1 {
- tx, ty, iy, iz: int;
+ tx, ty, iy, iz: int
/*
Get offsets into the two bignums.
*/
- ty = min(b.used - 1, ix);
- tx = ix - ty;
+ ty = min(b.used - 1, ix)
+ tx = ix - ty
/*
This is the number of times the loop will iterate, essentially.
while (tx++ < a->used && ty-- >= 0) { ... }
*/
- iy = min(a.used - tx, ty + 1);
+ iy = min(a.used - tx, ty + 1)
/*
Execute loop.
*/
#no_bounds_check for iz = 0; iz < iy; iz += 1 {
- _W += _WORD(a.digit[tx + iz]) * _WORD(b.digit[ty - iz]);
+ _W += _WORD(a.digit[tx + iz]) * _WORD(b.digit[ty - iz])
}
/*
Store term.
*/
- W[ix] = DIGIT(_W) & _MASK;
+ W[ix] = DIGIT(_W) & _MASK
/*
Make next carry.
*/
- _W = _W >> _WORD(_DIGIT_BITS);
+ _W = _W >> _WORD(_DIGIT_BITS)
}
/*
Setup dest.
*/
- old_used := dest.used;
- dest.used = pa;
+ old_used := dest.used
+ dest.used = pa
/*
Now extract the previous digit [below the carry].
*/
- copy_slice(dest.digit[0:], W[:pa]);
+ copy_slice(dest.digit[0:], W[:pa])
/*
Clear unused digits [that existed in the old copy of dest].
*/
- internal_zero_unused(dest, old_used);
+ internal_zero_unused(dest, old_used)
/*
Adjust dest.used based on leading zeroes.
*/
- return internal_clamp(dest);
+ return internal_clamp(dest)
}
/*
@@ -431,42 +431,42 @@ _private_int_mul_comba :: proc(dest, a, b: ^Int, digits: int, allocator := conte
[meant to get the higher part of the product]
*/
_private_int_mul_high :: proc(dest, a, b: ^Int, digits: int, allocator := context.allocator) -> (err: Error) {
- context.allocator = allocator;
+ context.allocator = allocator
/*
Can we use the fast multiplier?
*/
if a.used + b.used + 1 < _WARRAY && min(a.used, b.used) < _MAX_COMBA {
- return _private_int_mul_high_comba(dest, a, b, digits);
+ return _private_int_mul_high_comba(dest, a, b, digits)
}
- internal_grow(dest, a.used + b.used + 1) or_return;
- dest.used = a.used + b.used + 1;
+ internal_grow(dest, a.used + b.used + 1) or_return
+ dest.used = a.used + b.used + 1
- pa := a.used;
- pb := b.used;
+ pa := a.used
+ pb := b.used
for ix := 0; ix < pa; ix += 1 {
- carry := DIGIT(0);
+ carry := DIGIT(0)
for iy := digits - ix; iy < pb; iy += 1 {
/*
Calculate the double precision result.
*/
- r := _WORD(dest.digit[ix + iy]) + _WORD(a.digit[ix]) * _WORD(b.digit[iy]) + _WORD(carry);
+ r := _WORD(dest.digit[ix + iy]) + _WORD(a.digit[ix]) * _WORD(b.digit[iy]) + _WORD(carry)
/*
Get the lower part.
*/
- dest.digit[ix + iy] = DIGIT(r & _WORD(_MASK));
+ dest.digit[ix + iy] = DIGIT(r & _WORD(_MASK))
/*
Carry the carry.
*/
- carry = DIGIT(r >> _WORD(_DIGIT_BITS));
+ carry = DIGIT(r >> _WORD(_DIGIT_BITS))
}
- dest.digit[ix + pb] = carry;
+ dest.digit[ix + pb] = carry
}
- return internal_clamp(dest);
+ return internal_clamp(dest)
}
/*
@@ -479,140 +479,140 @@ _private_int_mul_high :: proc(dest, a, b: ^Int, digits: int, allocator := contex
Based on Algorithm 14.12 on pp.595 of HAC.
*/
_private_int_mul_high_comba :: proc(dest, a, b: ^Int, digits: int, allocator := context.allocator) -> (err: Error) {
- context.allocator = allocator;
+ context.allocator = allocator
- W: [_WARRAY]DIGIT = ---;
- _W: _WORD = 0;
+ W: [_WARRAY]DIGIT = ---
+ _W: _WORD = 0
/*
Number of output digits to produce. Grow the destination as required.
*/
- pa := a.used + b.used;
- internal_grow(dest, pa) or_return;
+ pa := a.used + b.used
+ internal_grow(dest, pa) or_return
- ix: int;
+ ix: int
for ix = digits; ix < pa; ix += 1 {
/*
Get offsets into the two bignums.
*/
- ty := min(b.used - 1, ix);
- tx := ix - ty;
+ ty := min(b.used - 1, ix)
+ tx := ix - ty
/*
This is the number of times the loop will iterrate, essentially it's
while (tx++ < a->used && ty-- >= 0) { ... }
*/
- iy := min(a.used - tx, ty + 1);
+ iy := min(a.used - tx, ty + 1)
/*
Execute loop.
*/
for iz := 0; iz < iy; iz += 1 {
- _W += _WORD(a.digit[tx + iz]) * _WORD(b.digit[ty - iz]);
+ _W += _WORD(a.digit[tx + iz]) * _WORD(b.digit[ty - iz])
}
/*
Store term.
*/
- W[ix] = DIGIT(_W) & DIGIT(_MASK);
+ W[ix] = DIGIT(_W) & DIGIT(_MASK)
/*
Make next carry.
*/
- _W = _W >> _WORD(_DIGIT_BITS);
+ _W = _W >> _WORD(_DIGIT_BITS)
}
/*
Setup dest
*/
- old_used := dest.used;
- dest.used = pa;
+ old_used := dest.used
+ dest.used = pa
for ix = digits; ix < pa; ix += 1 {
/*
Now extract the previous digit [below the carry].
*/
- dest.digit[ix] = W[ix];
+ dest.digit[ix] = W[ix]
}
/*
Zero remainder.
*/
- internal_zero_unused(dest, old_used);
+ internal_zero_unused(dest, old_used)
/*
Adjust dest.used based on leading zeroes.
*/
- return internal_clamp(dest);
+ return internal_clamp(dest)
}
/*
Single-digit multiplication with the smaller number as the single-digit.
*/
_private_int_mul_balance :: proc(dest, a, b: ^Int, allocator := context.allocator) -> (err: Error) {
- context.allocator = allocator;
- a, b := a, b;
+ context.allocator = allocator
+ a, b := a, b
- a0, tmp, r := &Int{}, &Int{}, &Int{};
- defer internal_destroy(a0, tmp, r);
+ a0, tmp, r := &Int{}, &Int{}, &Int{}
+ defer internal_destroy(a0, tmp, r)
- b_size := min(a.used, b.used);
- n_blocks := max(a.used, b.used) / b_size;
+ b_size := min(a.used, b.used)
+ n_blocks := max(a.used, b.used) / b_size
- internal_grow(a0, b_size + 2) or_return;
- internal_init_multi(tmp, r) or_return;
+ internal_grow(a0, b_size + 2) or_return
+ internal_init_multi(tmp, r) or_return
/*
Make sure that `a` is the larger one.
*/
if a.used < b.used {
- a, b = b, a;
+ a, b = b, a
}
- assert(a.used >= b.used);
+ assert(a.used >= b.used)
- i, j := 0, 0;
+ i, j := 0, 0
for ; i < n_blocks; i += 1 {
/*
Cut a slice off of `a`.
*/
- a0.used = b_size;
- internal_copy_digits(a0, a, a0.used, j);
- j += a0.used;
- internal_clamp(a0);
+ a0.used = b_size
+ internal_copy_digits(a0, a, a0.used, j)
+ j += a0.used
+ internal_clamp(a0)
/*
Multiply with `b`.
*/
- internal_mul(tmp, a0, b) or_return;
+ internal_mul(tmp, a0, b) or_return
/*
Shift `tmp` to the correct position.
*/
- internal_shl_digit(tmp, b_size * i) or_return;
+ internal_shl_digit(tmp, b_size * i) or_return
/*
Add to output. No carry needed.
*/
- internal_add(r, r, tmp) or_return;
+ internal_add(r, r, tmp) or_return
}
/*
The left-overs; there are always left-overs.
*/
if j < a.used {
- a0.used = a.used - j;
- internal_copy_digits(a0, a, a0.used, j);
- j += a0.used;
- internal_clamp(a0);
-
- internal_mul(tmp, a0, b) or_return;
- internal_shl_digit(tmp, b_size * i) or_return;
- internal_add(r, r, tmp) or_return;
+ a0.used = a.used - j
+ internal_copy_digits(a0, a, a0.used, j)
+ j += a0.used
+ internal_clamp(a0)
+
+ internal_mul(tmp, a0, b) or_return
+ internal_shl_digit(tmp, b_size * i) or_return
+ internal_add(r, r, tmp) or_return
}
- internal_swap(dest, r);
- return;
+ internal_swap(dest, r)
+ return
}
/*
@@ -620,68 +620,68 @@ _private_int_mul_balance :: proc(dest, a, b: ^Int, allocator := context.allocato
Assumes `dest` and `src` to not be `nil`, and `src` to have been initialized.
*/
_private_int_sqr :: proc(dest, src: ^Int, allocator := context.allocator) -> (err: Error) {
- context.allocator = allocator;
- pa := src.used;
+ context.allocator = allocator
+ pa := src.used
- t := &Int{}; ix, iy: int;
+ t := &Int{}; ix, iy: int
/*
Grow `t` to maximum needed size, or `_DEFAULT_DIGIT_COUNT`, whichever is bigger.
*/
- internal_grow(t, max((2 * pa) + 1, _DEFAULT_DIGIT_COUNT)) or_return;
- t.used = (2 * pa) + 1;
+ internal_grow(t, max((2 * pa) + 1, _DEFAULT_DIGIT_COUNT)) or_return
+ t.used = (2 * pa) + 1
#no_bounds_check for ix = 0; ix < pa; ix += 1 {
- carry := DIGIT(0);
+ carry := DIGIT(0)
/*
First calculate the digit at 2*ix; calculate double precision result.
*/
- r := _WORD(t.digit[ix+ix]) + (_WORD(src.digit[ix]) * _WORD(src.digit[ix]));
+ r := _WORD(t.digit[ix+ix]) + (_WORD(src.digit[ix]) * _WORD(src.digit[ix]))
/*
Store lower part in result.
*/
- t.digit[ix+ix] = DIGIT(r & _WORD(_MASK));
+ t.digit[ix+ix] = DIGIT(r & _WORD(_MASK))
/*
Get the carry.
*/
- carry = DIGIT(r >> _DIGIT_BITS);
+ carry = DIGIT(r >> _DIGIT_BITS)
#no_bounds_check for iy = ix + 1; iy < pa; iy += 1 {
/*
First calculate the product.
*/
- r = _WORD(src.digit[ix]) * _WORD(src.digit[iy]);
+ r = _WORD(src.digit[ix]) * _WORD(src.digit[iy])
/* Now calculate the double precision result. Nóte we use
* addition instead of *2 since it's easier to optimize
*/
- r = _WORD(t.digit[ix+iy]) + r + r + _WORD(carry);
+ r = _WORD(t.digit[ix+iy]) + r + r + _WORD(carry)
/*
Store lower part.
*/
- t.digit[ix+iy] = DIGIT(r & _WORD(_MASK));
+ t.digit[ix+iy] = DIGIT(r & _WORD(_MASK))
/*
Get carry.
*/
- carry = DIGIT(r >> _DIGIT_BITS);
+ carry = DIGIT(r >> _DIGIT_BITS)
}
/*
Propagate upwards.
*/
#no_bounds_check for carry != 0 {
- r = _WORD(t.digit[ix+iy]) + _WORD(carry);
- t.digit[ix+iy] = DIGIT(r & _WORD(_MASK));
- carry = DIGIT(r >> _WORD(_DIGIT_BITS));
- iy += 1;
+ r = _WORD(t.digit[ix+iy]) + _WORD(carry)
+ t.digit[ix+iy] = DIGIT(r & _WORD(_MASK))
+ carry = DIGIT(r >> _WORD(_DIGIT_BITS))
+ iy += 1
}
}
- err = internal_clamp(t);
- internal_swap(dest, t);
- internal_destroy(t);
- return err;
+ err = internal_clamp(t)
+ internal_swap(dest, t)
+ internal_destroy(t)
+ return err
}
/*
@@ -693,94 +693,94 @@ _private_int_sqr :: proc(dest, src: ^Int, allocator := context.allocator) -> (er
Assumes `dest` and `src` not to be `nil` and `src` to have been initialized.
*/
_private_int_sqr_comba :: proc(dest, src: ^Int, allocator := context.allocator) -> (err: Error) {
- context.allocator = allocator;
+ context.allocator = allocator
- W: [_WARRAY]DIGIT = ---;
+ W: [_WARRAY]DIGIT = ---
/*
Grow the destination as required.
*/
- pa := uint(src.used) + uint(src.used);
- internal_grow(dest, int(pa)) or_return;
+ pa := uint(src.used) + uint(src.used)
+ internal_grow(dest, int(pa)) or_return
/*
Number of output digits to produce.
*/
- W1 := _WORD(0);
- _W : _WORD = ---;
- ix := uint(0);
+ W1 := _WORD(0)
+ _W : _WORD = ---
+ ix := uint(0)
#no_bounds_check for ; ix < pa; ix += 1 {
/*
Clear counter.
*/
- _W = {};
+ _W = {}
/*
Get offsets into the two bignums.
*/
- ty := min(uint(src.used) - 1, ix);
- tx := ix - ty;
+ ty := min(uint(src.used) - 1, ix)
+ tx := ix - ty
/*
This is the number of times the loop will iterate,
essentially while (tx++ < a->used && ty-- >= 0) { ... }
*/
- iy := min(uint(src.used) - tx, ty + 1);
+ iy := min(uint(src.used) - tx, ty + 1)
/*
Now for squaring, tx can never equal ty.
We halve the distance since they approach at a rate of 2x,
and we have to round because odd cases need to be executed.
*/
- iy = min(iy, ((ty - tx) + 1) >> 1 );
+ iy = min(iy, ((ty - tx) + 1) >> 1 )
/*
Execute loop.
*/
#no_bounds_check for iz := uint(0); iz < iy; iz += 1 {
- _W += _WORD(src.digit[tx + iz]) * _WORD(src.digit[ty - iz]);
+ _W += _WORD(src.digit[tx + iz]) * _WORD(src.digit[ty - iz])
}
/*
Double the inner product and add carry.
*/
- _W = _W + _W + W1;
+ _W = _W + _W + W1
/*
Even columns have the square term in them.
*/
if ix & 1 == 0 {
- _W += _WORD(src.digit[ix >> 1]) * _WORD(src.digit[ix >> 1]);
+ _W += _WORD(src.digit[ix >> 1]) * _WORD(src.digit[ix >> 1])
}
/*
Store it.
*/
- W[ix] = DIGIT(_W & _WORD(_MASK));
+ W[ix] = DIGIT(_W & _WORD(_MASK))
/*
Make next carry.
*/
- W1 = _W >> _DIGIT_BITS;
+ W1 = _W >> _DIGIT_BITS
}
/*
Setup dest.
*/
- old_used := dest.used;
- dest.used = src.used + src.used;
+ old_used := dest.used
+ dest.used = src.used + src.used
#no_bounds_check for ix = 0; ix < pa; ix += 1 {
- dest.digit[ix] = W[ix] & _MASK;
+ dest.digit[ix] = W[ix] & _MASK
}
/*
Clear unused digits [that existed in the old copy of dest].
*/
- internal_zero_unused(dest, old_used);
+ internal_zero_unused(dest, old_used)
- return internal_clamp(dest);
+ return internal_clamp(dest)
}
/*
@@ -790,31 +790,31 @@ _private_int_sqr_comba :: proc(dest, src: ^Int, allocator := context.allocator)
It is essentially the same algorithm but merely tuned to perform recursive squarings.
*/
_private_int_sqr_karatsuba :: proc(dest, src: ^Int, allocator := context.allocator) -> (err: Error) {
- context.allocator = allocator;
+ context.allocator = allocator
- x0, x1, t1, t2, x0x0, x1x1 := &Int{}, &Int{}, &Int{}, &Int{}, &Int{}, &Int{};
- defer internal_destroy(x0, x1, t1, t2, x0x0, x1x1);
+ x0, x1, t1, t2, x0x0, x1x1 := &Int{}, &Int{}, &Int{}, &Int{}, &Int{}, &Int{}
+ defer internal_destroy(x0, x1, t1, t2, x0x0, x1x1)
/*
Min # of digits, divided by two.
*/
- B := src.used >> 1;
+ B := src.used >> 1
/*
Init temps.
*/
- internal_grow(x0, B) or_return;
- internal_grow(x1, src.used - B) or_return;
- internal_grow(t1, src.used * 2) or_return;
- internal_grow(t2, src.used * 2) or_return;
- internal_grow(x0x0, B * 2 ) or_return;
- internal_grow(x1x1, (src.used - B) * 2) or_return;
+ internal_grow(x0, B) or_return
+ internal_grow(x1, src.used - B) or_return
+ internal_grow(t1, src.used * 2) or_return
+ internal_grow(t2, src.used * 2) or_return
+ internal_grow(x0x0, B * 2 ) or_return
+ internal_grow(x1x1, (src.used - B) * 2) or_return
/*
Now shift the digits.
*/
- x0.used = B;
- x1.used = src.used - B;
+ x0.used = B
+ x1.used = src.used - B
#force_inline internal_copy_digits(x0, src, x0.used);
#force_inline mem.copy_non_overlapping(&x1.digit[0], &src.digit[B], size_of(DIGIT) * x1.used);
@@ -823,30 +823,30 @@ _private_int_sqr_karatsuba :: proc(dest, src: ^Int, allocator := context.allocat
/*
Now calc the products x0*x0 and x1*x1.
*/
- internal_sqr(x0x0, x0) or_return;
- internal_sqr(x1x1, x1) or_return;
+ internal_sqr(x0x0, x0) or_return
+ internal_sqr(x1x1, x1) or_return
/*
Now calc (x1+x0)^2
*/
- internal_add(t1, x0, x1) or_return;
- internal_sqr(t1, t1) or_return;
+ internal_add(t1, x0, x1) or_return
+ internal_sqr(t1, t1) or_return
/*
Add x0y0
*/
- internal_add(t2, x0x0, x1x1) or_return;
- internal_sub(t1, t1, t2) or_return;
+ internal_add(t2, x0x0, x1x1) or_return
+ internal_sub(t1, t1, t2) or_return
/*
Shift by B.
*/
- internal_shl_digit(t1, B) or_return;
- internal_shl_digit(x1x1, B * 2) or_return;
- internal_add(t1, t1, x0x0) or_return;
- internal_add(dest, t1, x1x1) or_return;
+ internal_shl_digit(t1, B) or_return
+ internal_shl_digit(x1x1, B * 2) or_return
+ internal_add(t1, t1, x0x0) or_return
+ internal_add(dest, t1, x1x1) or_return
- return #force_inline internal_clamp(dest);
+ return #force_inline internal_clamp(dest)
}
/*
@@ -856,160 +856,160 @@ _private_int_sqr_karatsuba :: proc(dest, src: ^Int, allocator := context.allocat
18th IEEE Symposium on Computer Arithmetic (ARITH'07). IEEE, 2007.
*/
_private_int_sqr_toom :: proc(dest, src: ^Int, allocator := context.allocator) -> (err: Error) {
- context.allocator = allocator;
+ context.allocator = allocator
- S0, a0, a1, a2 := &Int{}, &Int{}, &Int{}, &Int{};
- defer internal_destroy(S0, a0, a1, a2);
+ S0, a0, a1, a2 := &Int{}, &Int{}, &Int{}, &Int{}
+ defer internal_destroy(S0, a0, a1, a2)
/*
Init temps.
*/
- internal_zero(S0) or_return;
+ internal_zero(S0) or_return
/*
B
*/
- B := src.used / 3;
+ B := src.used / 3
/*
a = a2 * x^2 + a1 * x + a0;
*/
- internal_grow(a0, B) or_return;
- internal_grow(a1, B) or_return;
- internal_grow(a2, src.used - (2 * B)) or_return;
+ internal_grow(a0, B) or_return
+ internal_grow(a1, B) or_return
+ internal_grow(a2, src.used - (2 * B)) or_return
- a0.used = B;
- a1.used = B;
- a2.used = src.used - 2 * B;
+ a0.used = B
+ a1.used = B
+ a2.used = src.used - 2 * B
#force_inline mem.copy_non_overlapping(&a0.digit[0], &src.digit[ 0], size_of(DIGIT) * a0.used);
#force_inline mem.copy_non_overlapping(&a1.digit[0], &src.digit[ B], size_of(DIGIT) * a1.used);
#force_inline mem.copy_non_overlapping(&a2.digit[0], &src.digit[2 * B], size_of(DIGIT) * a2.used);
- internal_clamp(a0);
- internal_clamp(a1);
- internal_clamp(a2);
+ internal_clamp(a0)
+ internal_clamp(a1)
+ internal_clamp(a2)
/** S0 = a0^2; */
- internal_sqr(S0, a0) or_return;
+ internal_sqr(S0, a0) or_return
/** \\S1 = (a2 + a1 + a0)^2 */
/** \\S2 = (a2 - a1 + a0)^2 */
/** \\S1 = a0 + a2; */
/** a0 = a0 + a2; */
- internal_add(a0, a0, a2) or_return;
+ internal_add(a0, a0, a2) or_return
/** \\S2 = S1 - a1; */
/** b = a0 - a1; */
- internal_sub(dest, a0, a1) or_return;
+ internal_sub(dest, a0, a1) or_return
/** \\S1 = S1 + a1; */
/** a0 = a0 + a1; */
- internal_add(a0, a0, a1) or_return;
+ internal_add(a0, a0, a1) or_return
/** \\S1 = S1^2; */
/** a0 = a0^2; */
- internal_sqr(a0, a0) or_return;
+ internal_sqr(a0, a0) or_return
/** \\S2 = S2^2; */
/** b = b^2; */
- internal_sqr(dest, dest) or_return;
+ internal_sqr(dest, dest) or_return
/** \\ S3 = 2 * a1 * a2 */
/** \\S3 = a1 * a2; */
/** a1 = a1 * a2; */
- internal_mul(a1, a1, a2) or_return;
+ internal_mul(a1, a1, a2) or_return
/** \\S3 = S3 << 1; */
/** a1 = a1 << 1; */
- internal_shl(a1, a1, 1) or_return;
+ internal_shl(a1, a1, 1) or_return
/** \\S4 = a2^2; */
/** a2 = a2^2; */
- internal_sqr(a2, a2) or_return;
+ internal_sqr(a2, a2) or_return
/** \\ tmp = (S1 + S2)/2 */
/** \\tmp = S1 + S2; */
/** b = a0 + b; */
- internal_add(dest, a0, dest) or_return;
+ internal_add(dest, a0, dest) or_return
/** \\tmp = tmp >> 1; */
/** b = b >> 1; */
- internal_shr(dest, dest, 1) or_return;
+ internal_shr(dest, dest, 1) or_return
/** \\ S1 = S1 - tmp - S3 */
/** \\S1 = S1 - tmp; */
/** a0 = a0 - b; */
- internal_sub(a0, a0, dest) or_return;
+ internal_sub(a0, a0, dest) or_return
/** \\S1 = S1 - S3; */
/** a0 = a0 - a1; */
- internal_sub(a0, a0, a1) or_return;
+ internal_sub(a0, a0, a1) or_return
/** \\S2 = tmp - S4 -S0 */
/** \\S2 = tmp - S4; */
/** b = b - a2; */
- internal_sub(dest, dest, a2) or_return;
+ internal_sub(dest, dest, a2) or_return
/** \\S2 = S2 - S0; */
/** b = b - S0; */
- internal_sub(dest, dest, S0) or_return;
+ internal_sub(dest, dest, S0) or_return
/** \\P = S4*x^4 + S3*x^3 + S2*x^2 + S1*x + S0; */
/** P = a2*x^4 + a1*x^3 + b*x^2 + a0*x + S0; */
- internal_shl_digit( a2, 4 * B) or_return;
- internal_shl_digit( a1, 3 * B) or_return;
- internal_shl_digit(dest, 2 * B) or_return;
- internal_shl_digit( a0, 1 * B) or_return;
-
- internal_add(a2, a2, a1) or_return;
- internal_add(dest, dest, a2) or_return;
- internal_add(dest, dest, a0) or_return;
- internal_add(dest, dest, S0) or_return;
+ internal_shl_digit( a2, 4 * B) or_return
+ internal_shl_digit( a1, 3 * B) or_return
+ internal_shl_digit(dest, 2 * B) or_return
+ internal_shl_digit( a0, 1 * B) or_return
+
+ internal_add(a2, a2, a1) or_return
+ internal_add(dest, dest, a2) or_return
+ internal_add(dest, dest, a0) or_return
+ internal_add(dest, dest, S0) or_return
/** a^2 - P */
- return #force_inline internal_clamp(dest);
+ return #force_inline internal_clamp(dest)
}
/*
Divide by three (based on routine from MPI and the GMP manual).
*/
_private_int_div_3 :: proc(quotient, numerator: ^Int, allocator := context.allocator) -> (remainder: DIGIT, err: Error) {
- context.allocator = allocator;
+ context.allocator = allocator
/*
b = 2^_DIGIT_BITS / 3
*/
- b := _WORD(1) << _WORD(_DIGIT_BITS) / _WORD(3);
+ b := _WORD(1) << _WORD(_DIGIT_BITS) / _WORD(3)
- q := &Int{};
- internal_grow(q, numerator.used) or_return;
- q.used = numerator.used;
- q.sign = numerator.sign;
+ q := &Int{}
+ internal_grow(q, numerator.used) or_return
+ q.used = numerator.used
+ q.sign = numerator.sign
- w, t: _WORD;
+ w, t: _WORD
#no_bounds_check for ix := numerator.used; ix >= 0; ix -= 1 {
- w = (w << _WORD(_DIGIT_BITS)) | _WORD(numerator.digit[ix]);
+ w = (w << _WORD(_DIGIT_BITS)) | _WORD(numerator.digit[ix])
if w >= 3 {
/*
Multiply w by [1/3].
*/
- t = (w * b) >> _WORD(_DIGIT_BITS);
+ t = (w * b) >> _WORD(_DIGIT_BITS)
/*
Now subtract 3 * [w/3] from w, to get the remainder.
*/
- w -= t+t+t;
+ w -= t+t+t
/*
Fixup the remainder as required since the optimization is not exact.
*/
for w >= 3 {
- t += 1;
- w -= 3;
+ t += 1
+ w -= 3
}
} else {
- t = 0;
+ t = 0
}
- q.digit[ix] = DIGIT(t);
+ q.digit[ix] = DIGIT(t)
}
- remainder = DIGIT(w);
+ remainder = DIGIT(w)
/*
[optional] store the quotient.
*/
if quotient != nil {
- err = clamp(q);
- internal_swap(q, quotient);
+ err = clamp(q)
+ internal_swap(q, quotient)
}
- internal_destroy(q);
- return remainder, nil;
+ internal_destroy(q)
+ return remainder, nil
}
/*
@@ -1025,64 +1025,64 @@ _private_int_div_3 :: proc(quotient, numerator: ^Int, allocator := context.alloc
The overall algorithm is as described as 14.20 from HAC but fixed to treat these cases.
*/
_private_int_div_school :: proc(quotient, remainder, numerator, denominator: ^Int, allocator := context.allocator) -> (err: Error) {
- context.allocator = allocator;
+ context.allocator = allocator
- error_if_immutable(quotient, remainder) or_return;
+ error_if_immutable(quotient, remainder) or_return
- q, x, y, t1, t2 := &Int{}, &Int{}, &Int{}, &Int{}, &Int{};
- defer internal_destroy(q, x, y, t1, t2);
+ q, x, y, t1, t2 := &Int{}, &Int{}, &Int{}, &Int{}, &Int{}
+ defer internal_destroy(q, x, y, t1, t2)
- internal_grow(q, numerator.used + 2) or_return;
- q.used = numerator.used + 2;
+ internal_grow(q, numerator.used + 2) or_return
+ q.used = numerator.used + 2
- internal_init_multi(t1, t2) or_return;
- internal_copy(x, numerator) or_return;
- internal_copy(y, denominator) or_return;
+ internal_init_multi(t1, t2) or_return
+ internal_copy(x, numerator) or_return
+ internal_copy(y, denominator) or_return
/*
Fix the sign.
*/
- neg := numerator.sign != denominator.sign;
- x.sign = .Zero_or_Positive;
- y.sign = .Zero_or_Positive;
+ neg := numerator.sign != denominator.sign
+ x.sign = .Zero_or_Positive
+ y.sign = .Zero_or_Positive
/*
Normalize both x and y, ensure that y >= b/2, [b == 2**MP_DIGIT_BIT]
*/
- norm := internal_count_bits(y) % _DIGIT_BITS;
+ norm := internal_count_bits(y) % _DIGIT_BITS
if norm < _DIGIT_BITS - 1 {
- norm = (_DIGIT_BITS - 1) - norm;
- internal_shl(x, x, norm) or_return;
- internal_shl(y, y, norm) or_return;
+ norm = (_DIGIT_BITS - 1) - norm
+ internal_shl(x, x, norm) or_return
+ internal_shl(y, y, norm) or_return
} else {
- norm = 0;
+ norm = 0
}
/*
Note: HAC does 0 based, so if used==5 then it's 0,1,2,3,4, i.e. use 4
*/
- n := x.used - 1;
- t := y.used - 1;
+ n := x.used - 1
+ t := y.used - 1
/*
while (x >= y*b**n-t) do { q[n-t] += 1; x -= y*b**{n-t} }
y = y*b**{n-t}
*/
- internal_shl_digit(y, n - t) or_return;
+ internal_shl_digit(y, n - t) or_return
- c := internal_cmp(x, y);
+ c := internal_cmp(x, y)
for c != -1 {
- q.digit[n - t] += 1;
- internal_sub(x, x, y) or_return;
- c = internal_cmp(x, y);
+ q.digit[n - t] += 1
+ internal_sub(x, x, y) or_return
+ c = internal_cmp(x, y)
}
/*
Reset y by shifting it back down.
*/
- internal_shr_digit(y, n - t);
+ internal_shr_digit(y, n - t)
/*
Step 3. for i from n down to (t + 1).
@@ -1094,16 +1094,16 @@ _private_int_div_school :: proc(quotient, remainder, numerator, denominator: ^In
step 3.1 if xi == yt then set q{i-t-1} to b-1, otherwise set q{i-t-1} to (xi*b + x{i-1})/yt
*/
if x.digit[i] == y.digit[t] {
- q.digit[(i - t) - 1] = 1 << (_DIGIT_BITS - 1);
+ q.digit[(i - t) - 1] = 1 << (_DIGIT_BITS - 1)
} else {
- tmp := _WORD(x.digit[i]) << _DIGIT_BITS;
- tmp |= _WORD(x.digit[i - 1]);
- tmp /= _WORD(y.digit[t]);
+ tmp := _WORD(x.digit[i]) << _DIGIT_BITS
+ tmp |= _WORD(x.digit[i - 1])
+ tmp /= _WORD(y.digit[t])
if tmp > _WORD(_MASK) {
- tmp = _WORD(_MASK);
+ tmp = _WORD(_MASK)
}
- q.digit[(i - t) - 1] = DIGIT(tmp & _WORD(_MASK));
+ q.digit[(i - t) - 1] = DIGIT(tmp & _WORD(_MASK))
}
/* while (q{i-t-1} * (yt * b + y{t-1})) >
@@ -1112,53 +1112,53 @@ _private_int_div_school :: proc(quotient, remainder, numerator, denominator: ^In
do q{i-t-1} -= 1;
*/
- iter := 0;
+ iter := 0
- q.digit[(i - t) - 1] = (q.digit[(i - t) - 1] + 1) & _MASK;
+ q.digit[(i - t) - 1] = (q.digit[(i - t) - 1] + 1) & _MASK
#no_bounds_check for {
- q.digit[(i - t) - 1] = (q.digit[(i - t) - 1] - 1) & _MASK;
+ q.digit[(i - t) - 1] = (q.digit[(i - t) - 1] - 1) & _MASK
/*
Find left hand.
*/
- internal_zero(t1);
- t1.digit[0] = ((t - 1) < 0) ? 0 : y.digit[t - 1];
- t1.digit[1] = y.digit[t];
- t1.used = 2;
- internal_mul(t1, t1, q.digit[(i - t) - 1]) or_return;
+ internal_zero(t1)
+ t1.digit[0] = ((t - 1) < 0) ? 0 : y.digit[t - 1]
+ t1.digit[1] = y.digit[t]
+ t1.used = 2
+ internal_mul(t1, t1, q.digit[(i - t) - 1]) or_return
/*
Find right hand.
*/
- t2.digit[0] = ((i - 2) < 0) ? 0 : x.digit[i - 2];
- t2.digit[1] = x.digit[i - 1]; /* i >= 1 always holds */
- t2.digit[2] = x.digit[i];
- t2.used = 3;
+ t2.digit[0] = ((i - 2) < 0) ? 0 : x.digit[i - 2]
+ t2.digit[1] = x.digit[i - 1] /* i >= 1 always holds */
+ t2.digit[2] = x.digit[i]
+ t2.used = 3
if t1_t2 := internal_cmp_mag(t1, t2); t1_t2 != 1 {
- break;
+ break
}
iter += 1; if iter > 100 {
- return .Max_Iterations_Reached;
+ return .Max_Iterations_Reached
}
}
/*
Step 3.3 x = x - q{i-t-1} * y * b**{i-t-1}
*/
- int_mul_digit(t1, y, q.digit[(i - t) - 1]) or_return;
- internal_shl_digit(t1, (i - t) - 1) or_return;
- internal_sub(x, x, t1) or_return;
+ int_mul_digit(t1, y, q.digit[(i - t) - 1]) or_return
+ internal_shl_digit(t1, (i - t) - 1) or_return
+ internal_sub(x, x, t1) or_return
/*
if x < 0 then { x = x + y*b**{i-t-1}; q{i-t-1} -= 1; }
*/
if x.sign == .Negative {
- internal_copy(t1, y) or_return;
- internal_shl_digit(t1, (i - t) - 1) or_return;
- internal_add(x, x, t1) or_return;
+ internal_copy(t1, y) or_return
+ internal_shl_digit(t1, (i - t) - 1) or_return
+ internal_add(x, x, t1) or_return
- q.digit[(i - t) - 1] = (q.digit[(i - t) - 1] - 1) & _MASK;
+ q.digit[(i - t) - 1] = (q.digit[(i - t) - 1] - 1) & _MASK
}
}
@@ -1166,21 +1166,21 @@ _private_int_div_school :: proc(quotient, remainder, numerator, denominator: ^In
Now q is the quotient and x is the remainder, [which we have to normalize]
Get sign before writing to c.
*/
- z, _ := is_zero(x);
- x.sign = .Zero_or_Positive if z else numerator.sign;
+ z, _ := is_zero(x)
+ x.sign = .Zero_or_Positive if z else numerator.sign
if quotient != nil {
- internal_clamp(q);
- internal_swap(q, quotient);
- quotient.sign = .Negative if neg else .Zero_or_Positive;
+ internal_clamp(q)
+ internal_swap(q, quotient)
+ quotient.sign = .Negative if neg else .Zero_or_Positive
}
if remainder != nil {
- internal_shr(x, x, norm) or_return;
- internal_swap(x, remainder);
+ internal_shr(x, x, norm) or_return
+ internal_swap(x, remainder)
}
- return nil;
+ return nil
}
/*
@@ -1193,49 +1193,49 @@ _private_int_div_school :: proc(quotient, remainder, numerator, denominator: ^In
pages 19ff. in the above online document.
*/
_private_div_recursion :: proc(quotient, remainder, a, b: ^Int, allocator := context.allocator) -> (err: Error) {
- context.allocator = allocator;
+ context.allocator = allocator
- A1, A2, B1, B0, Q1, Q0, R1, R0, t := &Int{}, &Int{}, &Int{}, &Int{}, &Int{}, &Int{}, &Int{}, &Int{}, &Int{};
- defer internal_destroy(A1, A2, B1, B0, Q1, Q0, R1, R0, t);
+ A1, A2, B1, B0, Q1, Q0, R1, R0, t := &Int{}, &Int{}, &Int{}, &Int{}, &Int{}, &Int{}, &Int{}, &Int{}, &Int{}
+ defer internal_destroy(A1, A2, B1, B0, Q1, Q0, R1, R0, t)
- m := a.used - b.used;
- k := m / 2;
+ m := a.used - b.used
+ k := m / 2
if m < MUL_KARATSUBA_CUTOFF {
- return _private_int_div_school(quotient, remainder, a, b);
+ return _private_int_div_school(quotient, remainder, a, b)
}
- internal_init_multi(A1, A2, B1, B0, Q1, Q0, R1, R0, t) or_return;
+ internal_init_multi(A1, A2, B1, B0, Q1, Q0, R1, R0, t) or_return
/*
`B1` = `b` / `beta`^`k`, `B0` = `b` % `beta`^`k`
*/
- internal_shrmod(B1, B0, b, k * _DIGIT_BITS) or_return;
+ internal_shrmod(B1, B0, b, k * _DIGIT_BITS) or_return
/*
(Q1, R1) = RecursiveDivRem(A / beta^(2k), B1)
*/
- internal_shrmod(A1, t, a, 2 * k * _DIGIT_BITS) or_return;
- _private_div_recursion(Q1, R1, A1, B1) or_return;
+ internal_shrmod(A1, t, a, 2 * k * _DIGIT_BITS) or_return
+ _private_div_recursion(Q1, R1, A1, B1) or_return
/*
A1 = (R1 * beta^(2k)) + (A % beta^(2k)) - (Q1 * B0 * beta^k)
*/
- internal_shl_digit(R1, 2 * k) or_return;
- internal_add(A1, R1, t) or_return;
- internal_mul(t, Q1, B0) or_return;
+ internal_shl_digit(R1, 2 * k) or_return
+ internal_add(A1, R1, t) or_return
+ internal_mul(t, Q1, B0) or_return
/*
While A1 < 0 do Q1 = Q1 - 1, A1 = A1 + (beta^k * B)
*/
if internal_cmp(A1, 0) == -1 {
- internal_shl(t, b, k * _DIGIT_BITS) or_return;
+ internal_shl(t, b, k * _DIGIT_BITS) or_return
for {
- internal_decr(Q1) or_return;
- internal_add(A1, A1, t) or_return;
+ internal_decr(Q1) or_return
+ internal_add(A1, A1, t) or_return
if internal_cmp(A1, 0) != -1 {
- break;
+ break
}
}
}
@@ -1243,72 +1243,72 @@ _private_div_recursion :: proc(quotient, remainder, a, b: ^Int, allocator := con
/*
(Q0, R0) = RecursiveDivRem(A1 / beta^(k), B1)
*/
- internal_shrmod(A1, t, A1, k * _DIGIT_BITS) or_return;
- _private_div_recursion(Q0, R0, A1, B1) or_return;
+ internal_shrmod(A1, t, A1, k * _DIGIT_BITS) or_return
+ _private_div_recursion(Q0, R0, A1, B1) or_return
/*
A2 = (R0*beta^k) + (A1 % beta^k) - (Q0*B0)
*/
- internal_shl_digit(R0, k) or_return;
- internal_add(A2, R0, t) or_return;
- internal_mul(t, Q0, B0) or_return;
- internal_sub(A2, A2, t) or_return;
+ internal_shl_digit(R0, k) or_return
+ internal_add(A2, R0, t) or_return
+ internal_mul(t, Q0, B0) or_return
+ internal_sub(A2, A2, t) or_return
/*
While A2 < 0 do Q0 = Q0 - 1, A2 = A2 + B.
*/
for internal_cmp(A2, 0) == -1 {
- internal_decr(Q0) or_return;
- internal_add(A2, A2, b) or_return;
+ internal_decr(Q0) or_return
+ internal_add(A2, A2, b) or_return
}
/*
Return q = (Q1*beta^k) + Q0, r = A2.
*/
- internal_shl_digit(Q1, k) or_return;
- internal_add(quotient, Q1, Q0) or_return;
+ internal_shl_digit(Q1, k) or_return
+ internal_add(quotient, Q1, Q0) or_return
- return internal_copy(remainder, A2);
+ return internal_copy(remainder, A2)
}
_private_int_div_recursive :: proc(quotient, remainder, a, b: ^Int, allocator := context.allocator) -> (err: Error) {
- context.allocator = allocator;
+ context.allocator = allocator
- A, B, Q, Q1, R, A_div, A_mod := &Int{}, &Int{}, &Int{}, &Int{}, &Int{}, &Int{}, &Int{};
- defer internal_destroy(A, B, Q, Q1, R, A_div, A_mod);
+ A, B, Q, Q1, R, A_div, A_mod := &Int{}, &Int{}, &Int{}, &Int{}, &Int{}, &Int{}, &Int{}
+ defer internal_destroy(A, B, Q, Q1, R, A_div, A_mod)
- internal_init_multi(A, B, Q, Q1, R, A_div, A_mod) or_return;
+ internal_init_multi(A, B, Q, Q1, R, A_div, A_mod) or_return
/*
Most significant bit of a limb.
Assumes _DIGIT_MAX < (sizeof(DIGIT) * sizeof(u8)).
*/
- msb := (_DIGIT_MAX + DIGIT(1)) >> 1;
- sigma := 0;
- msb_b := b.digit[b.used - 1];
+ msb := (_DIGIT_MAX + DIGIT(1)) >> 1
+ sigma := 0
+ msb_b := b.digit[b.used - 1]
for msb_b < msb {
- sigma += 1;
- msb_b <<= 1;
+ sigma += 1
+ msb_b <<= 1
}
/*
Use that sigma to normalize B.
*/
- internal_shl(B, b, sigma) or_return;
- internal_shl(A, a, sigma) or_return;
+ internal_shl(B, b, sigma) or_return
+ internal_shl(A, a, sigma) or_return
/*
Fix the sign.
*/
- neg := a.sign != b.sign;
- A.sign = .Zero_or_Positive; B.sign = .Zero_or_Positive;
+ neg := a.sign != b.sign
+ A.sign = .Zero_or_Positive; B.sign = .Zero_or_Positive
/*
If the magnitude of "A" is not more more than twice that of "B" we can work
on them directly, otherwise we need to work at "A" in chunks.
*/
- n := B.used;
- m := A.used - B.used;
+ n := B.used
+ m := A.used - B.used
/*
Q = 0. We already ensured that when we called `internal_init_multi`.
@@ -1317,56 +1317,56 @@ _private_int_div_recursive :: proc(quotient, remainder, a, b: ^Int, allocator :=
/*
(q, r) = RecursiveDivRem(A / (beta^(m-n)), B)
*/
- j := (m - n) * _DIGIT_BITS;
- internal_shrmod(A_div, A_mod, A, j) or_return;
- _private_div_recursion(Q1, R, A_div, B) or_return;
+ j := (m - n) * _DIGIT_BITS
+ internal_shrmod(A_div, A_mod, A, j) or_return
+ _private_div_recursion(Q1, R, A_div, B) or_return
/*
Q = (Q*beta!(n)) + q
*/
- internal_shl(Q, Q, n * _DIGIT_BITS) or_return;
- internal_add(Q, Q, Q1) or_return;
+ internal_shl(Q, Q, n * _DIGIT_BITS) or_return
+ internal_add(Q, Q, Q1) or_return
/*
A = (r * beta^(m-n)) + (A % beta^(m-n))
*/
- internal_shl(R, R, (m - n) * _DIGIT_BITS) or_return;
- internal_add(A, R, A_mod) or_return;
+ internal_shl(R, R, (m - n) * _DIGIT_BITS) or_return
+ internal_add(A, R, A_mod) or_return
/*
m = m - n
*/
- m -= n;
+ m -= n
}
/*
(q, r) = RecursiveDivRem(A, B)
*/
- _private_div_recursion(Q1, R, A, B) or_return;
+ _private_div_recursion(Q1, R, A, B) or_return
/*
Q = (Q * beta^m) + q, R = r
*/
- internal_shl(Q, Q, m * _DIGIT_BITS) or_return;
- internal_add(Q, Q, Q1) or_return;
+ internal_shl(Q, Q, m * _DIGIT_BITS) or_return
+ internal_add(Q, Q, Q1) or_return
/*
Get sign before writing to dest.
*/
- R.sign = .Zero_or_Positive if internal_is_zero(Q) else a.sign;
+ R.sign = .Zero_or_Positive if internal_is_zero(Q) else a.sign
if quotient != nil {
- swap(quotient, Q);
- quotient.sign = .Negative if neg else .Zero_or_Positive;
+ swap(quotient, Q)
+ quotient.sign = .Negative if neg else .Zero_or_Positive
}
if remainder != nil {
/*
De-normalize the remainder.
*/
- internal_shrmod(R, nil, R, sigma) or_return;
- swap(remainder, R);
+ internal_shrmod(R, nil, R, sigma) or_return
+ swap(remainder, R)
}
- return nil;
+ return nil
}
/*
@@ -1375,53 +1375,53 @@ _private_int_div_recursive :: proc(quotient, remainder, a, b: ^Int, allocator :=
@(deprecated="Use `_int_div_school`, it's 3.5x faster.")
_private_int_div_small :: proc(quotient, remainder, numerator, denominator: ^Int) -> (err: Error) {
- ta, tb, tq, q := &Int{}, &Int{}, &Int{}, &Int{};
- c: int;
- defer internal_destroy(ta, tb, tq, q);
+ ta, tb, tq, q := &Int{}, &Int{}, &Int{}, &Int{}
+ c: int
+ defer internal_destroy(ta, tb, tq, q)
for {
- internal_one(tq) or_return;
+ internal_one(tq) or_return
- num_bits, _ := count_bits(numerator);
- den_bits, _ := count_bits(denominator);
- n := num_bits - den_bits;
+ num_bits, _ := count_bits(numerator)
+ den_bits, _ := count_bits(denominator)
+ n := num_bits - den_bits
- abs(ta, numerator) or_return;
- abs(tb, denominator) or_return;
- shl(tb, tb, n) or_return;
- shl(tq, tq, n) or_return;
+ abs(ta, numerator) or_return
+ abs(tb, denominator) or_return
+ shl(tb, tb, n) or_return
+ shl(tq, tq, n) or_return
for n >= 0 {
if c, _ = cmp_mag(ta, tb); c == 0 || c == 1 {
// ta -= tb
- sub(ta, ta, tb) or_return;
+ sub(ta, ta, tb) or_return
// q += tq
- add( q, q, tq) or_return;
+ add( q, q, tq) or_return
}
- shr1(tb, tb) or_return;
- shr1(tq, tq) or_return;
+ shr1(tb, tb) or_return
+ shr1(tq, tq) or_return
- n -= 1;
+ n -= 1
}
/*
Now q == quotient and ta == remainder.
*/
- neg := numerator.sign != denominator.sign;
+ neg := numerator.sign != denominator.sign
if quotient != nil {
- swap(quotient, q);
- z, _ := is_zero(quotient);
- quotient.sign = .Negative if neg && !z else .Zero_or_Positive;
+ swap(quotient, q)
+ z, _ := is_zero(quotient)
+ quotient.sign = .Negative if neg && !z else .Zero_or_Positive
}
if remainder != nil {
- swap(remainder, ta);
- z, _ := is_zero(numerator);
- remainder.sign = .Zero_or_Positive if z else numerator.sign;
+ swap(remainder, ta)
+ z, _ := is_zero(numerator)
+ remainder.sign = .Zero_or_Positive if z else numerator.sign
}
- break;
+ break
}
- return err;
+ return err
}
@@ -1430,65 +1430,65 @@ _private_int_div_small :: proc(quotient, remainder, numerator, denominator: ^Int
Binary split factorial algo due to: http://www.luschny.de/math/factorial/binarysplitfact.html
*/
_private_int_factorial_binary_split :: proc(res: ^Int, n: int, allocator := context.allocator) -> (err: Error) {
- context.allocator = allocator;
+ context.allocator = allocator
- inner, outer, start, stop, temp := &Int{}, &Int{}, &Int{}, &Int{}, &Int{};
- defer internal_destroy(inner, outer, start, stop, temp);
+ inner, outer, start, stop, temp := &Int{}, &Int{}, &Int{}, &Int{}, &Int{}
+ defer internal_destroy(inner, outer, start, stop, temp)
- internal_one(inner, false) or_return;
- internal_one(outer, false) or_return;
+ internal_one(inner, false) or_return
+ internal_one(outer, false) or_return
- bits_used := int(_DIGIT_TYPE_BITS - intrinsics.count_leading_zeros(n));
+ bits_used := int(_DIGIT_TYPE_BITS - intrinsics.count_leading_zeros(n))
for i := bits_used; i >= 0; i -= 1 {
- start := (n >> (uint(i) + 1)) + 1 | 1;
- stop := (n >> uint(i)) + 1 | 1;
- _private_int_recursive_product(temp, start, stop, 0) or_return;
- internal_mul(inner, inner, temp) or_return;
- internal_mul(outer, outer, inner) or_return;
+ start := (n >> (uint(i) + 1)) + 1 | 1
+ stop := (n >> uint(i)) + 1 | 1
+ _private_int_recursive_product(temp, start, stop, 0) or_return
+ internal_mul(inner, inner, temp) or_return
+ internal_mul(outer, outer, inner) or_return
}
- shift := n - intrinsics.count_ones(n);
+ shift := n - intrinsics.count_ones(n)
- return internal_shl(res, outer, int(shift));
+ return internal_shl(res, outer, int(shift))
}
/*
Recursive product used by binary split factorial algorithm.
*/
_private_int_recursive_product :: proc(res: ^Int, start, stop: int, level := int(0), allocator := context.allocator) -> (err: Error) {
- context.allocator = allocator;
+ context.allocator = allocator
- t1, t2 := &Int{}, &Int{};
- defer internal_destroy(t1, t2);
+ t1, t2 := &Int{}, &Int{}
+ defer internal_destroy(t1, t2)
if level > FACTORIAL_BINARY_SPLIT_MAX_RECURSIONS {
- return .Max_Iterations_Reached;
+ return .Max_Iterations_Reached
}
- num_factors := (stop - start) >> 1;
+ num_factors := (stop - start) >> 1
if num_factors == 2 {
- internal_set(t1, start, false) or_return;
+ internal_set(t1, start, false) or_return
when true {
- internal_grow(t2, t1.used + 1, false) or_return;
- internal_add(t2, t1, 2) or_return;
+ internal_grow(t2, t1.used + 1, false) or_return
+ internal_add(t2, t1, 2) or_return
} else {
- internal_add(t2, t1, 2) or_return;
+ internal_add(t2, t1, 2) or_return
}
- return internal_mul(res, t1, t2);
+ return internal_mul(res, t1, t2)
}
if num_factors > 1 {
- mid := (start + num_factors) | 1;
- _private_int_recursive_product(t1, start, mid, level + 1) or_return;
- _private_int_recursive_product(t2, mid, stop, level + 1) or_return;
- return internal_mul(res, t1, t2);
+ mid := (start + num_factors) | 1
+ _private_int_recursive_product(t1, start, mid, level + 1) or_return
+ _private_int_recursive_product(t2, mid, stop, level + 1) or_return
+ return internal_mul(res, t1, t2)
}
if num_factors == 1 {
- return #force_inline internal_set(res, start, true);
+ return #force_inline internal_set(res, start, true)
}
- return #force_inline internal_one(res, true);
+ return #force_inline internal_one(res, true)
}
/*
@@ -1507,10 +1507,10 @@ _private_int_recursive_product :: proc(res: ^Int, start, stop: int, level := int
If neither result is wanted, we have nothing to do.
*/
_private_int_gcd_lcm :: proc(res_gcd, res_lcm, a, b: ^Int, allocator := context.allocator) -> (err: Error) {
- context.allocator = allocator;
+ context.allocator = allocator
if res_gcd == nil && res_lcm == nil {
- return nil;
+ return nil
}
/*
@@ -1521,76 +1521,76 @@ _private_int_gcd_lcm :: proc(res_gcd, res_lcm, a, b: ^Int, allocator := context.
GCD(0, 0) and LCM(0, 0) are both 0.
*/
if res_gcd != nil {
- internal_zero(res_gcd) or_return;
+ internal_zero(res_gcd) or_return
}
if res_lcm != nil {
- internal_zero(res_lcm) or_return;
+ internal_zero(res_lcm) or_return
}
- return nil;
+ return nil
} else if a.used == 0 {
/*
We can early out with GCD = B and LCM = 0
*/
if res_gcd != nil {
- internal_abs(res_gcd, b) or_return;
+ internal_abs(res_gcd, b) or_return
}
if res_lcm != nil {
- internal_zero(res_lcm) or_return;
+ internal_zero(res_lcm) or_return
}
- return nil;
+ return nil
} else if b.used == 0 {
/*
We can early out with GCD = A and LCM = 0
*/
if res_gcd != nil {
- internal_abs(res_gcd, a) or_return;
+ internal_abs(res_gcd, a) or_return
}
if res_lcm != nil {
- internal_zero(res_lcm) or_return;
+ internal_zero(res_lcm) or_return
}
- return nil;
+ return nil
}
- temp_gcd_res := &Int{};
- defer internal_destroy(temp_gcd_res);
+ temp_gcd_res := &Int{}
+ defer internal_destroy(temp_gcd_res)
/*
If neither `a` or `b` was zero, we need to compute `gcd`.
Get copies of `a` and `b` we can modify.
*/
- u, v := &Int{}, &Int{};
- defer internal_destroy(u, v);
- internal_copy(u, a) or_return;
- internal_copy(v, b) or_return;
+ u, v := &Int{}, &Int{}
+ defer internal_destroy(u, v)
+ internal_copy(u, a) or_return
+ internal_copy(v, b) or_return
/*
Must be positive for the remainder of the algorithm.
*/
- u.sign = .Zero_or_Positive; v.sign = .Zero_or_Positive;
+ u.sign = .Zero_or_Positive; v.sign = .Zero_or_Positive
/*
B1. Find the common power of two for `u` and `v`.
*/
- u_lsb, _ := internal_count_lsb(u);
- v_lsb, _ := internal_count_lsb(v);
- k := min(u_lsb, v_lsb);
+ u_lsb, _ := internal_count_lsb(u)
+ v_lsb, _ := internal_count_lsb(v)
+ k := min(u_lsb, v_lsb)
if k > 0 {
/*
Divide the power of two out.
*/
- internal_shr(u, u, k) or_return;
- internal_shr(v, v, k) or_return;
+ internal_shr(u, u, k) or_return
+ internal_shr(v, v, k) or_return
}
/*
Divide any remaining factors of two out.
*/
if u_lsb != k {
- internal_shr(u, u, u_lsb - k) or_return;
+ internal_shr(u, u, u_lsb - k) or_return
}
if v_lsb != k {
- internal_shr(v, v, v_lsb - k) or_return;
+ internal_shr(v, v, v_lsb - k) or_return
}
for v.used != 0 {
@@ -1601,34 +1601,34 @@ _private_int_gcd_lcm :: proc(res_gcd, res_lcm, a, b: ^Int, allocator := context.
/*
Swap `u` and `v` to make sure `v` is >= `u`.
*/
- internal_swap(u, v);
+ internal_swap(u, v)
}
/*
Subtract smallest from largest.
*/
- internal_sub(v, v, u) or_return;
+ internal_sub(v, v, u) or_return
/*
Divide out all factors of two.
*/
- b, _ := internal_count_lsb(v);
- internal_shr(v, v, b) or_return;
+ b, _ := internal_count_lsb(v)
+ internal_shr(v, v, b) or_return
}
/*
Multiply by 2**k which we divided out at the beginning.
*/
- internal_shl(temp_gcd_res, u, k) or_return;
- temp_gcd_res.sign = .Zero_or_Positive;
+ internal_shl(temp_gcd_res, u, k) or_return
+ temp_gcd_res.sign = .Zero_or_Positive
/*
We've computed `gcd`, either the long way, or because one of the inputs was zero.
If we don't want `lcm`, we're done.
*/
if res_lcm == nil {
- internal_swap(temp_gcd_res, res_gcd);
- return nil;
+ internal_swap(temp_gcd_res, res_gcd)
+ return nil
}
/*
@@ -1639,25 +1639,25 @@ _private_int_gcd_lcm :: proc(res_gcd, res_lcm, a, b: ^Int, allocator := context.
/*
Store quotient in `t2` such that `t2 * b` is the LCM.
*/
- internal_div(res_lcm, a, temp_gcd_res) or_return;
- err = internal_mul(res_lcm, res_lcm, b);
+ internal_div(res_lcm, a, temp_gcd_res) or_return
+ err = internal_mul(res_lcm, res_lcm, b)
} else {
/*
Store quotient in `t2` such that `t2 * a` is the LCM.
*/
- internal_div(res_lcm, a, temp_gcd_res) or_return;
- err = internal_mul(res_lcm, res_lcm, b);
+ internal_div(res_lcm, a, temp_gcd_res) or_return
+ err = internal_mul(res_lcm, res_lcm, b)
}
if res_gcd != nil {
- internal_swap(temp_gcd_res, res_gcd);
+ internal_swap(temp_gcd_res, res_gcd)
}
/*
Fix the sign to positive and return.
*/
- res_lcm.sign = .Zero_or_Positive;
- return err;
+ res_lcm.sign = .Zero_or_Positive
+ return err
}
/*
@@ -1665,24 +1665,24 @@ _private_int_gcd_lcm :: proc(res_gcd, res_lcm, a, b: ^Int, allocator := context.
Assumes `a` not to be `nil` and to have been initialized.
*/
_private_int_log :: proc(a: ^Int, base: DIGIT, allocator := context.allocator) -> (res: int, err: Error) {
- bracket_low, bracket_high, bracket_mid, t, bi_base := &Int{}, &Int{}, &Int{}, &Int{}, &Int{};
- defer internal_destroy(bracket_low, bracket_high, bracket_mid, t, bi_base);
+ bracket_low, bracket_high, bracket_mid, t, bi_base := &Int{}, &Int{}, &Int{}, &Int{}, &Int{}
+ defer internal_destroy(bracket_low, bracket_high, bracket_mid, t, bi_base)
- ic := #force_inline internal_cmp(a, base);
+ ic := #force_inline internal_cmp(a, base)
if ic == -1 || ic == 0 {
- return 1 if ic == 0 else 0, nil;
+ return 1 if ic == 0 else 0, nil
}
defer if err != nil {
- res = -1;
+ res = -1
}
- internal_set(bi_base, base, true, allocator) or_return;
- internal_clear(bracket_mid, false, allocator) or_return;
- internal_clear(t, false, allocator) or_return;
- internal_one(bracket_low, false, allocator) or_return;
- internal_set(bracket_high, base, false, allocator) or_return;
+ internal_set(bi_base, base, true, allocator) or_return
+ internal_clear(bracket_mid, false, allocator) or_return
+ internal_clear(t, false, allocator) or_return
+ internal_one(bracket_low, false, allocator) or_return
+ internal_set(bracket_high, base, false, allocator) or_return
- low := 0; high := 1;
+ low := 0; high := 1
/*
A kind of Giant-step/baby-step algorithm.
@@ -1696,39 +1696,39 @@ _private_int_log :: proc(a: ^Int, base: DIGIT, allocator := context.allocator) -
Iterate until `a` is bracketed between low + high.
*/
if #force_inline internal_cmp(bracket_high, a) != -1 {
- break;
+ break
}
- low = high;
+ low = high
#force_inline internal_copy(bracket_low, bracket_high) or_return;
- high <<= 1;
+ high <<= 1
#force_inline internal_sqr(bracket_high, bracket_high) or_return;
}
for (high - low) > 1 {
- mid := (high + low) >> 1;
+ mid := (high + low) >> 1
#force_inline internal_pow(t, bi_base, mid - low) or_return;
#force_inline internal_mul(bracket_mid, bracket_low, t) or_return;
- mc := #force_inline internal_cmp(a, bracket_mid);
+ mc := #force_inline internal_cmp(a, bracket_mid)
switch mc {
case -1:
- high = mid;
- internal_swap(bracket_mid, bracket_high);
+ high = mid
+ internal_swap(bracket_mid, bracket_high)
case 0:
- return mid, nil;
+ return mid, nil
case 1:
- low = mid;
- internal_swap(bracket_mid, bracket_low);
+ low = mid
+ internal_swap(bracket_mid, bracket_low)
}
}
- fc := #force_inline internal_cmp(bracket_high, a);
- res = high if fc == 0 else low;
+ fc := #force_inline internal_cmp(bracket_high, a)
+ res = high if fc == 0 else low
- return;
+ return
}
@@ -1741,37 +1741,37 @@ _private_int_log :: proc(a: ^Int, base: DIGIT, allocator := context.allocator) -
Based on Algorithm 14.32 on pp.601 of HAC.
*/
_private_montgomery_reduce_comba :: proc(x, n: ^Int, rho: DIGIT, allocator := context.allocator) -> (err: Error) {
- context.allocator = allocator;
- W: [_WARRAY]_WORD = ---;
+ context.allocator = allocator
+ W: [_WARRAY]_WORD = ---
if x.used > _WARRAY { return .Invalid_Argument; }
/*
Get old used count.
*/
- old_used := x.used;
+ old_used := x.used
/*
Grow `x` as required.
*/
- internal_grow(x, n.used + 1) or_return;
+ internal_grow(x, n.used + 1) or_return
/*
First we have to get the digits of the input into an array of double precision words W[...]
Copy the digits of `x` into W[0..`x.used` - 1]
*/
- ix: int;
+ ix: int
for ix = 0; ix < x.used; ix += 1 {
- W[ix] = _WORD(x.digit[ix]);
+ W[ix] = _WORD(x.digit[ix])
}
/*
Zero the high words of W[a->used..m->used*2].
*/
- zero_upper := (n.used * 2) + 1;
+ zero_upper := (n.used * 2) + 1
if ix < zero_upper {
for ix = x.used; ix < zero_upper; ix += 1 {
- W[ix] = {};
+ W[ix] = {}
}
}
@@ -1786,7 +1786,7 @@ _private_montgomery_reduce_comba :: proc(x, n: ^Int, rho: DIGIT, allocator := co
by casting the value down to a DIGIT. Note this requires
that W[ix-1] have the carry cleared (see after the inner loop)
*/
- mu := ((W[ix] & _WORD(_MASK)) * _WORD(rho)) & _WORD(_MASK);
+ mu := ((W[ix] & _WORD(_MASK)) * _WORD(rho)) & _WORD(_MASK)
/*
`a = a + mu * m * b**i`
@@ -1805,13 +1805,13 @@ _private_montgomery_reduce_comba :: proc(x, n: ^Int, rho: DIGIT, allocator := co
first m->used words of W[] have the carries fixed.
*/
for iy := 0; iy < n.used; iy += 1 {
- W[ix + iy] += mu * _WORD(n.digit[iy]);
+ W[ix + iy] += mu * _WORD(n.digit[iy])
}
/*
Now fix carry for next digit, W[ix+1].
*/
- W[ix + 1] += (W[ix] >> _DIGIT_BITS);
+ W[ix + 1] += (W[ix] >> _DIGIT_BITS)
}
/*
@@ -1820,7 +1820,7 @@ _private_montgomery_reduce_comba :: proc(x, n: ^Int, rho: DIGIT, allocator := co
*/
for ; ix < n.used * 2; ix += 1 {
- W[ix + 1] += (W[ix] >> _DIGIT_BITS);
+ W[ix + 1] += (W[ix] >> _DIGIT_BITS)
}
/* copy out, A = A/b**n
@@ -1831,69 +1831,69 @@ _private_montgomery_reduce_comba :: proc(x, n: ^Int, rho: DIGIT, allocator := co
*/
for ix = 0; ix < (n.used + 1); ix += 1 {
- x.digit[ix] = DIGIT(W[n.used + ix] & _WORD(_MASK));
+ x.digit[ix] = DIGIT(W[n.used + ix] & _WORD(_MASK))
}
/*
Set the max used.
*/
- x.used = n.used + 1;
+ x.used = n.used + 1
/*
Zero old_used digits, if the input a was larger than m->used+1 we'll have to clear the digits.
*/
- internal_zero_unused(x, old_used);
- internal_clamp(x);
+ internal_zero_unused(x, old_used)
+ internal_clamp(x)
/*
if A >= m then A = A - m
*/
if internal_cmp_mag(x, n) != -1 {
- return internal_sub(x, x, n);
+ return internal_sub(x, x, n)
}
- return nil;
+ return nil
}
/*
hac 14.61, pp608
*/
_private_inverse_modulo :: proc(dest, a, b: ^Int, allocator := context.allocator) -> (err: Error) {
- context.allocator = allocator;
- x, y, u, v, A, B, C, D := &Int{}, &Int{}, &Int{}, &Int{}, &Int{}, &Int{}, &Int{}, &Int{};
- defer internal_destroy(x, y, u, v, A, B, C, D);
+ context.allocator = allocator
+ x, y, u, v, A, B, C, D := &Int{}, &Int{}, &Int{}, &Int{}, &Int{}, &Int{}, &Int{}, &Int{}
+ defer internal_destroy(x, y, u, v, A, B, C, D)
/*
`b` cannot be negative.
*/
if b.sign == .Negative || internal_is_zero(b) {
- return .Invalid_Argument;
+ return .Invalid_Argument
}
/*
init temps.
*/
- internal_init_multi(x, y, u, v, A, B, C, D) or_return;
+ internal_init_multi(x, y, u, v, A, B, C, D) or_return
/*
`x` = `a` % `b`, `y` = `b`
*/
- internal_mod(x, a, b) or_return;
- internal_copy(y, b) or_return;
+ internal_mod(x, a, b) or_return
+ internal_copy(y, b) or_return
/*
2. [modified] if x,y are both even then return an error!
*/
if internal_is_even(x) && internal_is_even(y) {
- return .Invalid_Argument;
+ return .Invalid_Argument
}
/*
3. u=x, v=y, A=1, B=0, C=0, D=1
*/
- internal_copy(u, x) or_return;
- internal_copy(v, y) or_return;
- internal_one(A) or_return;
- internal_one(D) or_return;
+ internal_copy(u, x) or_return
+ internal_copy(v, y) or_return
+ internal_one(A) or_return
+ internal_one(D) or_return
for {
/*
@@ -1903,7 +1903,7 @@ _private_inverse_modulo :: proc(dest, a, b: ^Int, allocator := context.allocator
/*
4.1 `u` = `u` / 2
*/
- internal_int_shr1(u, u) or_return;
+ internal_int_shr1(u, u) or_return
/*
4.2 if `A` or `B` is odd then:
@@ -1912,14 +1912,14 @@ _private_inverse_modulo :: proc(dest, a, b: ^Int, allocator := context.allocator
/*
`A` = (`A`+`y`) / 2, `B` = (`B`-`x`) / 2
*/
- internal_add(A, A, y) or_return;
- internal_add(B, B, x) or_return;
+ internal_add(A, A, y) or_return
+ internal_add(B, B, x) or_return
}
/*
`A` = `A` / 2, `B` = `B` / 2
*/
- internal_int_shr1(A, A) or_return;
- internal_int_shr1(B, B) or_return;
+ internal_int_shr1(A, A) or_return
+ internal_int_shr1(B, B) or_return
}
/*
@@ -1929,7 +1929,7 @@ _private_inverse_modulo :: proc(dest, a, b: ^Int, allocator := context.allocator
/*
5.1 `v` = `v` / 2
*/
- internal_int_shr1(v, v) or_return;
+ internal_int_shr1(v, v) or_return
/*
5.2 if `C` or `D` is odd then:
@@ -1938,14 +1938,14 @@ _private_inverse_modulo :: proc(dest, a, b: ^Int, allocator := context.allocator
/*
`C` = (`C`+`y`) / 2, `D` = (`D`-`x`) / 2
*/
- internal_add(C, C, y) or_return;
- internal_add(D, D, x) or_return;
+ internal_add(C, C, y) or_return
+ internal_add(D, D, x) or_return
}
/*
`C` = `C` / 2, `D` = `D` / 2
*/
- internal_int_shr1(C, C) or_return;
- internal_int_shr1(D, D) or_return;
+ internal_int_shr1(C, C) or_return
+ internal_int_shr1(D, D) or_return
}
/*
@@ -1955,21 +1955,21 @@ _private_inverse_modulo :: proc(dest, a, b: ^Int, allocator := context.allocator
/*
`u` = `u` - `v`, `A` = `A` - `C`, `B` = `B` - `D`
*/
- internal_sub(u, u, v) or_return;
- internal_sub(A, A, C) or_return;
- internal_sub(B, B, D) or_return;
+ internal_sub(u, u, v) or_return
+ internal_sub(A, A, C) or_return
+ internal_sub(B, B, D) or_return
} else {
/* v - v - u, C = C - A, D = D - B */
- internal_sub(v, v, u) or_return;
- internal_sub(C, C, A) or_return;
- internal_sub(D, D, B) or_return;
+ internal_sub(v, v, u) or_return
+ internal_sub(C, C, A) or_return
+ internal_sub(D, D, B) or_return
}
/*
If not zero goto step 4
*/
if internal_is_zero(u) {
- break;
+ break
}
}
@@ -1981,29 +1981,29 @@ _private_inverse_modulo :: proc(dest, a, b: ^Int, allocator := context.allocator
If `v` != `1` then there is no inverse.
*/
if internal_cmp(v, 1) != 0 {
- return .Invalid_Argument;
+ return .Invalid_Argument
}
/*
If its too low.
*/
if internal_cmp(C, 0) == -1 {
- internal_add(C, C, b) or_return;
+ internal_add(C, C, b) or_return
}
/*
Too big.
*/
if internal_cmp(C, 0) != -1 {
- internal_sub(C, C, b) or_return;
+ internal_sub(C, C, b) or_return
}
/*
`C` is now the inverse.
*/
- swap(dest, C);
+ swap(dest, C)
- return;
+ return
}
/*
@@ -2013,11 +2013,11 @@ _private_inverse_modulo :: proc(dest, a, b: ^Int, allocator := context.allocator
as per HAC Note 14.64 on pp. 610.
*/
_private_inverse_modulo_odd :: proc(dest, a, b: ^Int, allocator := context.allocator) -> (err: Error) {
- context.allocator = allocator;
- x, y, u, v, B, D := &Int{}, &Int{}, &Int{}, &Int{}, &Int{}, &Int{};
- defer internal_destroy(x, y, u, v, B, D);
+ context.allocator = allocator
+ x, y, u, v, B, D := &Int{}, &Int{}, &Int{}, &Int{}, &Int{}, &Int{}
+ defer internal_destroy(x, y, u, v, B, D)
- sign: Sign;
+ sign: Sign
/*
2. [modified] `b` must be odd.
@@ -2027,17 +2027,17 @@ _private_inverse_modulo_odd :: proc(dest, a, b: ^Int, allocator := context.alloc
/*
Init all our temps.
*/
- internal_init_multi(x, y, u, v, B, D) or_return;
+ internal_init_multi(x, y, u, v, B, D) or_return
/*
`x` == modulus, `y` == value to invert.
*/
- internal_copy(x, b) or_return;
+ internal_copy(x, b) or_return
/*
We need `y` = `|a|`.
*/
- internal_mod(y, a, b) or_return;
+ internal_mod(y, a, b) or_return
/*
If one of `x`, `y` is zero return an error!
@@ -2047,10 +2047,10 @@ _private_inverse_modulo_odd :: proc(dest, a, b: ^Int, allocator := context.alloc
/*
3. `u` = `x`, `v` = `y`, `A` = 1, `B` = 0, `C` = 0, `D` = 1
*/
- internal_copy(u, x) or_return;
- internal_copy(v, y) or_return;
+ internal_copy(u, x) or_return
+ internal_copy(v, y) or_return
- internal_one(D) or_return;
+ internal_one(D) or_return
for {
/*
@@ -2060,7 +2060,7 @@ _private_inverse_modulo_odd :: proc(dest, a, b: ^Int, allocator := context.alloc
/*
4.1 `u` = `u` / 2
*/
- internal_int_shr1(u, u) or_return;
+ internal_int_shr1(u, u) or_return
/*
4.2 if `B` is odd then:
@@ -2069,13 +2069,13 @@ _private_inverse_modulo_odd :: proc(dest, a, b: ^Int, allocator := context.alloc
/*
`B` = (`B` - `x`) / 2
*/
- internal_sub(B, B, x) or_return;
+ internal_sub(B, B, x) or_return
}
/*
`B` = `B` / 2
*/
- internal_int_shr1(B, B) or_return;
+ internal_int_shr1(B, B) or_return
}
/*
@@ -2085,7 +2085,7 @@ _private_inverse_modulo_odd :: proc(dest, a, b: ^Int, allocator := context.alloc
/*
5.1 `v` = `v` / 2
*/
- internal_int_shr1(v, v) or_return;
+ internal_int_shr1(v, v) or_return
/*
5.2 if `D` is odd then:
@@ -2094,12 +2094,12 @@ _private_inverse_modulo_odd :: proc(dest, a, b: ^Int, allocator := context.alloc
/*
`D` = (`D` - `x`) / 2
*/
- internal_sub(D, D, x) or_return;
+ internal_sub(D, D, x) or_return
}
/*
`D` = `D` / 2
*/
- internal_int_shr1(D, D) or_return;
+ internal_int_shr1(D, D) or_return
}
/*
@@ -2109,14 +2109,14 @@ _private_inverse_modulo_odd :: proc(dest, a, b: ^Int, allocator := context.alloc
/*
`u` = `u` - `v`, `B` = `B` - `D`
*/
- internal_sub(u, u, v) or_return;
- internal_sub(B, B, D) or_return;
+ internal_sub(u, u, v) or_return
+ internal_sub(B, B, D) or_return
} else {
/*
`v` - `v` - `u`, `D` = `D` - `B`
*/
- internal_sub(v, v, u) or_return;
- internal_sub(D, D, B) or_return;
+ internal_sub(v, v, u) or_return
+ internal_sub(D, D, B) or_return
}
/*
@@ -2133,27 +2133,27 @@ _private_inverse_modulo_odd :: proc(dest, a, b: ^Int, allocator := context.alloc
if `v` != 1 then there is no inverse
*/
if internal_cmp(v, 1) != 0 {
- return .Invalid_Argument;
+ return .Invalid_Argument
}
/*
`b` is now the inverse.
*/
- sign = a.sign;
+ sign = a.sign
for internal_int_is_negative(D) {
- internal_add(D, D, b) or_return;
+ internal_add(D, D, b) or_return
}
/*
Too big.
*/
for internal_cmp_mag(D, b) != -1 {
- internal_sub(D, D, b) or_return;
+ internal_sub(D, D, b) or_return
}
- swap(dest, D);
- dest.sign = sign;
- return nil;
+ swap(dest, D)
+ dest.sign = sign
+ return nil
}
@@ -2163,14 +2163,14 @@ _private_inverse_modulo_odd :: proc(dest, a, b: ^Int, allocator := context.alloc
Also assumes `base` is a power of two.
*/
_private_log_power_of_two :: proc(a: ^Int, base: DIGIT) -> (log: int, err: Error) {
- base := base;
- y: int;
+ base := base
+ y: int
for y = 0; base & 1 == 0; {
- y += 1;
- base >>= 1;
+ y += 1
+ base >>= 1
}
- log = internal_count_bits(a);
- return (log - 1) / y, err;
+ log = internal_count_bits(a)
+ return (log - 1) / y, err
}
/*
@@ -2178,17 +2178,17 @@ _private_log_power_of_two :: proc(a: ^Int, base: DIGIT) -> (log: int, err: Error
Assumes `src` and `dest` to not be `nil` and have been initialized.
*/
_private_copy_digits :: proc(dest, src: ^Int, digits: int, offset := int(0)) -> (err: Error) {
- digits := digits;
+ digits := digits
/*
If dest == src, do nothing
*/
if dest == src {
- return nil;
+ return nil
}
- digits = min(digits, len(src.digit), len(dest.digit));
- mem.copy_non_overlapping(&dest.digit[0], &src.digit[offset], size_of(DIGIT) * digits);
- return nil;
+ digits = min(digits, len(src.digit), len(dest.digit))
+ mem.copy_non_overlapping(&dest.digit[0], &src.digit[offset], size_of(DIGIT) * digits)
+ return nil
}
/*
@@ -2208,7 +2208,7 @@ _private_int_rem_128 := [?]DIGIT{
1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
-};
+}
#assert(128 * size_of(DIGIT) == size_of(_private_int_rem_128));
_private_int_rem_105 := [?]DIGIT{
@@ -2219,7 +2219,7 @@ _private_int_rem_105 := [?]DIGIT{
0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1,
1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1,
1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1,
-};
+}
#assert(105 * size_of(DIGIT) == size_of(_private_int_rem_105));
_private_prime_table := [?]DIGIT{
@@ -2258,7 +2258,7 @@ _private_prime_table := [?]DIGIT{
0x05BF, 0x05C9, 0x05CB, 0x05CF, 0x05D1, 0x05D5, 0x05DB, 0x05E7,
0x05F3, 0x05FB, 0x0607, 0x060D, 0x0611, 0x0617, 0x061F, 0x0623,
0x062B, 0x062F, 0x063D, 0x0641, 0x0647, 0x0649, 0x064D, 0x0653,
-};
+}
#assert(256 * size_of(DIGIT) == size_of(_private_prime_table));
when MATH_BIG_FORCE_64_BIT || (!MATH_BIG_FORCE_32_BIT && size_of(rawptr) == 8) {
@@ -2298,7 +2298,7 @@ when MATH_BIG_FORCE_64_BIT || (!MATH_BIG_FORCE_32_BIT && size_of(rawptr) == 8) {
/* f(32): */ 263_130_836_933_693_530_167_218_012_160_000_000,
/* f(33): */ 8_683_317_618_811_886_495_518_194_401_280_000_000,
/* f(34): */ 295_232_799_039_604_140_847_618_609_643_520_000_000,
- };
+ }
} else {
_factorial_table := [21]_WORD{
/* f(00): */ 1,
@@ -2322,7 +2322,7 @@ when MATH_BIG_FORCE_64_BIT || (!MATH_BIG_FORCE_32_BIT && size_of(rawptr) == 8) {
/* f(18): */ 6_402_373_705_728_000,
/* f(19): */ 121_645_100_408_832_000,
/* f(20): */ 2_432_902_008_176_640_000,
- };
+ }
};
/*
diff --git a/core/math/big/public.odin b/core/math/big/public.odin
index 542725289..f3dd096b6 100644
--- a/core/math/big/public.odin
+++ b/core/math/big/public.odin
@@ -21,14 +21,14 @@ package math_big
High-level addition. Handles sign.
*/
int_add :: proc(dest, a, b: ^Int, allocator := context.allocator) -> (err: Error) {
- assert_if_nil(dest, a, b);
- context.allocator = allocator;
+ assert_if_nil(dest, a, b)
+ context.allocator = allocator
- internal_clear_if_uninitialized(dest, a, b) or_return;
+ internal_clear_if_uninitialized(dest, a, b) or_return
/*
All parameters have been initialized.
*/
- return #force_inline internal_int_add_signed(dest, a, b);
+ return #force_inline internal_int_add_signed(dest, a, b)
}
/*
@@ -38,33 +38,33 @@ int_add :: proc(dest, a, b: ^Int, allocator := context.allocator) -> (err: Error
dest = a + digit;
*/
int_add_digit :: proc(dest, a: ^Int, digit: DIGIT, allocator := context.allocator) -> (err: Error) {
- assert_if_nil(dest, a);
- context.allocator = allocator;
+ assert_if_nil(dest, a)
+ context.allocator = allocator
- internal_clear_if_uninitialized(a) or_return;
+ internal_clear_if_uninitialized(a) or_return
/*
Grow destination as required.
*/
- grow(dest, a.used + 1) or_return;
+ grow(dest, a.used + 1) or_return
/*
All parameters have been initialized.
*/
- return #force_inline internal_int_add_digit(dest, a, digit);
+ return #force_inline internal_int_add_digit(dest, a, digit)
}
/*
High-level subtraction, dest = number - decrease. Handles signs.
*/
int_sub :: proc(dest, number, decrease: ^Int, allocator := context.allocator) -> (err: Error) {
- assert_if_nil(dest, number, decrease);
- context.allocator = allocator;
+ assert_if_nil(dest, number, decrease)
+ context.allocator = allocator
- internal_clear_if_uninitialized(dest, number, decrease) or_return;
+ internal_clear_if_uninitialized(dest, number, decrease) or_return
/*
All parameters have been initialized.
*/
- return #force_inline internal_int_sub_signed(dest, number, decrease);
+ return #force_inline internal_int_sub_signed(dest, number, decrease)
}
/*
@@ -74,19 +74,19 @@ int_sub :: proc(dest, number, decrease: ^Int, allocator := context.allocator) ->
dest = a - digit;
*/
int_sub_digit :: proc(dest, a: ^Int, digit: DIGIT, allocator := context.allocator) -> (err: Error) {
- assert_if_nil(dest, a);
- context.allocator = allocator;
+ assert_if_nil(dest, a)
+ context.allocator = allocator
- internal_clear_if_uninitialized(a) or_return;
+ internal_clear_if_uninitialized(a) or_return
/*
Grow destination as required.
*/
- grow(dest, a.used + 1) or_return;
+ grow(dest, a.used + 1) or_return
/*
All parameters have been initialized.
*/
- return #force_inline internal_int_sub_digit(dest, a, digit);
+ return #force_inline internal_int_sub_digit(dest, a, digit)
}
/*
@@ -94,64 +94,64 @@ int_sub_digit :: proc(dest, a: ^Int, digit: DIGIT, allocator := context.allocato
dest = src >> 1
*/
int_halve :: proc(dest, src: ^Int, allocator := context.allocator) -> (err: Error) {
- assert_if_nil(dest, src);
- context.allocator = allocator;
+ assert_if_nil(dest, src)
+ context.allocator = allocator
- internal_clear_if_uninitialized(dest, src) or_return;
+ internal_clear_if_uninitialized(dest, src) or_return
/*
Grow destination as required.
*/
if dest != src { grow(dest, src.used + 1) or_return }
- return #force_inline internal_int_shr1(dest, src);
+ return #force_inline internal_int_shr1(dest, src)
}
-halve :: proc { int_halve, };
-shr1 :: halve;
+halve :: proc { int_halve, }
+shr1 :: halve
/*
dest = src * 2
dest = src << 1
*/
int_double :: proc(dest, src: ^Int, allocator := context.allocator) -> (err: Error) {
- assert_if_nil(dest, src);
- context.allocator = allocator;
+ assert_if_nil(dest, src)
+ context.allocator = allocator
- internal_clear_if_uninitialized(dest, src) or_return;
+ internal_clear_if_uninitialized(dest, src) or_return
/*
Grow destination as required.
*/
if dest != src { grow(dest, src.used + 1) or_return; }
- return #force_inline internal_int_shl1(dest, src);
+ return #force_inline internal_int_shl1(dest, src)
}
-double :: proc { int_double, };
-shl1 :: double;
+double :: proc { int_double, }
+shl1 :: double
/*
Multiply by a DIGIT.
*/
int_mul_digit :: proc(dest, src: ^Int, multiplier: DIGIT, allocator := context.allocator) -> (err: Error) {
- assert_if_nil(dest, src);
- context.allocator = allocator;
+ assert_if_nil(dest, src)
+ context.allocator = allocator
- internal_clear_if_uninitialized(src, dest) or_return;
+ internal_clear_if_uninitialized(src, dest) or_return
- return #force_inline internal_int_mul_digit(dest, src, multiplier);
+ return #force_inline internal_int_mul_digit(dest, src, multiplier)
}
/*
High level multiplication (handles sign).
*/
int_mul :: proc(dest, src, multiplier: ^Int, allocator := context.allocator) -> (err: Error) {
- assert_if_nil(dest, src, multiplier);
- context.allocator = allocator;
+ assert_if_nil(dest, src, multiplier)
+ context.allocator = allocator
- internal_clear_if_uninitialized(dest, src, multiplier) or_return;
+ internal_clear_if_uninitialized(dest, src, multiplier) or_return
- return #force_inline internal_int_mul(dest, src, multiplier);
+ return #force_inline internal_int_mul(dest, src, multiplier)
}
-mul :: proc { int_mul, int_mul_digit, };
+mul :: proc { int_mul, int_mul_digit, }
sqr :: proc(dest, src: ^Int) -> (err: Error) { return mul(dest, src, src); }
@@ -160,46 +160,46 @@ sqr :: proc(dest, src: ^Int) -> (err: Error) { return mul(dest, src, src); }
Both the quotient and remainder are optional and may be passed a nil.
*/
int_divmod :: proc(quotient, remainder, numerator, denominator: ^Int, allocator := context.allocator) -> (err: Error) {
- context.allocator = allocator;
+ context.allocator = allocator
/*
Early out if neither of the results is wanted.
*/
if quotient == nil && remainder == nil { return nil; }
- internal_clear_if_uninitialized(numerator, denominator) or_return;
+ internal_clear_if_uninitialized(numerator, denominator) or_return
- return #force_inline internal_divmod(quotient, remainder, numerator, denominator);
+ return #force_inline internal_divmod(quotient, remainder, numerator, denominator)
}
int_divmod_digit :: proc(quotient, numerator: ^Int, denominator: DIGIT, allocator := context.allocator) -> (remainder: DIGIT, err: Error) {
- assert_if_nil(quotient, numerator);
- context.allocator = allocator;
+ assert_if_nil(quotient, numerator)
+ context.allocator = allocator
- internal_clear_if_uninitialized(numerator) or_return;
+ internal_clear_if_uninitialized(numerator) or_return
- return #force_inline internal_divmod(quotient, numerator, denominator);
+ return #force_inline internal_divmod(quotient, numerator, denominator)
}
-divmod :: proc{ int_divmod, int_divmod_digit, };
+divmod :: proc{ int_divmod, int_divmod_digit, }
int_div :: proc(quotient, numerator, denominator: ^Int, allocator := context.allocator) -> (err: Error) {
- assert_if_nil(quotient, numerator, denominator);
- context.allocator = allocator;
+ assert_if_nil(quotient, numerator, denominator)
+ context.allocator = allocator
- internal_clear_if_uninitialized(numerator, denominator) or_return;
+ internal_clear_if_uninitialized(numerator, denominator) or_return
- return #force_inline internal_divmod(quotient, nil, numerator, denominator);
+ return #force_inline internal_divmod(quotient, nil, numerator, denominator)
}
int_div_digit :: proc(quotient, numerator: ^Int, denominator: DIGIT, allocator := context.allocator) -> (err: Error) {
- assert_if_nil(quotient, numerator);
- context.allocator = allocator;
+ assert_if_nil(quotient, numerator)
+ context.allocator = allocator
- internal_clear_if_uninitialized(numerator) or_return;
+ internal_clear_if_uninitialized(numerator) or_return
- _ = #force_inline internal_divmod(quotient, numerator, denominator) or_return;
- return;
+ _ = #force_inline internal_divmod(quotient, numerator, denominator) or_return
+ return
}
-div :: proc { int_div, int_div_digit, };
+div :: proc { int_div, int_div_digit, }
/*
remainder = numerator % denominator.
@@ -207,80 +207,80 @@ div :: proc { int_div, int_div_digit, };
denominator < remainder <= 0 if denominator < 0
*/
int_mod :: proc(remainder, numerator, denominator: ^Int, allocator := context.allocator) -> (err: Error) {
- assert_if_nil(remainder, numerator, denominator);
- context.allocator = allocator;
+ assert_if_nil(remainder, numerator, denominator)
+ context.allocator = allocator
- internal_clear_if_uninitialized(numerator, denominator) or_return;
+ internal_clear_if_uninitialized(numerator, denominator) or_return
- return #force_inline internal_int_mod(remainder, numerator, denominator);
+ return #force_inline internal_int_mod(remainder, numerator, denominator)
}
int_mod_digit :: proc(numerator: ^Int, denominator: DIGIT, allocator := context.allocator) -> (remainder: DIGIT, err: Error) {
- return #force_inline internal_divmod(nil, numerator, denominator, allocator);
+ return #force_inline internal_divmod(nil, numerator, denominator, allocator)
}
-mod :: proc { int_mod, int_mod_digit, };
+mod :: proc { int_mod, int_mod_digit, }
/*
remainder = (number + addend) % modulus.
*/
int_addmod :: proc(remainder, number, addend, modulus: ^Int, allocator := context.allocator) -> (err: Error) {
- assert_if_nil(remainder, number, addend);
- context.allocator = allocator;
+ assert_if_nil(remainder, number, addend)
+ context.allocator = allocator
- internal_clear_if_uninitialized(number, addend, modulus) or_return;
+ internal_clear_if_uninitialized(number, addend, modulus) or_return
- return #force_inline internal_addmod(remainder, number, addend, modulus);
+ return #force_inline internal_addmod(remainder, number, addend, modulus)
}
-addmod :: proc { int_addmod, };
+addmod :: proc { int_addmod, }
/*
remainder = (number - decrease) % modulus.
*/
int_submod :: proc(remainder, number, decrease, modulus: ^Int, allocator := context.allocator) -> (err: Error) {
- assert_if_nil(remainder, number, decrease);
- context.allocator = allocator;
+ assert_if_nil(remainder, number, decrease)
+ context.allocator = allocator
- internal_clear_if_uninitialized(number, decrease, modulus) or_return;
+ internal_clear_if_uninitialized(number, decrease, modulus) or_return
- return #force_inline internal_submod(remainder, number, decrease, modulus);
+ return #force_inline internal_submod(remainder, number, decrease, modulus)
}
-submod :: proc { int_submod, };
+submod :: proc { int_submod, }
/*
remainder = (number * multiplicand) % modulus.
*/
int_mulmod :: proc(remainder, number, multiplicand, modulus: ^Int, allocator := context.allocator) -> (err: Error) {
- assert_if_nil(remainder, number, multiplicand);
- context.allocator = allocator;
+ assert_if_nil(remainder, number, multiplicand)
+ context.allocator = allocator
- internal_clear_if_uninitialized(number, multiplicand, modulus) or_return;
+ internal_clear_if_uninitialized(number, multiplicand, modulus) or_return
- return #force_inline internal_mulmod(remainder, number, multiplicand, modulus);
+ return #force_inline internal_mulmod(remainder, number, multiplicand, modulus)
}
-mulmod :: proc { int_mulmod, };
+mulmod :: proc { int_mulmod, }
/*
remainder = (number * number) % modulus.
*/
int_sqrmod :: proc(remainder, number, modulus: ^Int, allocator := context.allocator) -> (err: Error) {
- assert_if_nil(remainder, number, modulus);
- context.allocator = allocator;
+ assert_if_nil(remainder, number, modulus)
+ context.allocator = allocator
- internal_clear_if_uninitialized(number, modulus) or_return;
+ internal_clear_if_uninitialized(number, modulus) or_return
- return #force_inline internal_sqrmod(remainder, number, modulus);
+ return #force_inline internal_sqrmod(remainder, number, modulus)
}
-sqrmod :: proc { int_sqrmod, };
+sqrmod :: proc { int_sqrmod, }
int_factorial :: proc(res: ^Int, n: int, allocator := context.allocator) -> (err: Error) {
if n < 0 || n > FACTORIAL_MAX_N { return .Invalid_Argument; }
- assert_if_nil(res);
+ assert_if_nil(res)
- return #force_inline internal_int_factorial(res, n, allocator);
+ return #force_inline internal_int_factorial(res, n, allocator)
}
-factorial :: proc { int_factorial, };
+factorial :: proc { int_factorial, }
/*
@@ -299,8 +299,8 @@ factorial :: proc { int_factorial, };
*/
int_choose_digit :: proc(res: ^Int, n, k: int, allocator := context.allocator) -> (err: Error) {
- assert_if_nil(res);
- context.allocator = allocator;
+ assert_if_nil(res)
+ context.allocator = allocator
if n < 0 || n > FACTORIAL_MAX_N { return .Invalid_Argument; }
if k > n { return internal_zero(res); }
@@ -308,8 +308,8 @@ int_choose_digit :: proc(res: ^Int, n, k: int, allocator := context.allocator) -
/*
res = n! / (k! * (n - k)!)
*/
- n_fac, k_fac, n_minus_k_fac := &Int{}, &Int{}, &Int{};
- defer internal_destroy(n_fac, k_fac, n_minus_k_fac);
+ n_fac, k_fac, n_minus_k_fac := &Int{}, &Int{}, &Int{}
+ defer internal_destroy(n_fac, k_fac, n_minus_k_fac)
#force_inline internal_int_factorial(n_minus_k_fac, n - k) or_return;
#force_inline internal_int_factorial(k_fac, k) or_return;
@@ -318,112 +318,112 @@ int_choose_digit :: proc(res: ^Int, n, k: int, allocator := context.allocator) -
#force_inline internal_int_factorial(n_fac, n) or_return;
#force_inline internal_div(res, n_fac, k_fac) or_return;
- return;
+ return
}
-choose :: proc { int_choose_digit, };
+choose :: proc { int_choose_digit, }
/*
Function computing both GCD and (if target isn't `nil`) also LCM.
*/
int_gcd_lcm :: proc(res_gcd, res_lcm, a, b: ^Int, allocator := context.allocator) -> (err: Error) {
if res_gcd == nil && res_lcm == nil { return nil; }
- assert_if_nil(a, b);
- context.allocator = allocator;
+ assert_if_nil(a, b)
+ context.allocator = allocator
- internal_clear_if_uninitialized(a, b) or_return;
- return #force_inline internal_int_gcd_lcm(res_gcd, res_lcm, a, b);
+ internal_clear_if_uninitialized(a, b) or_return
+ return #force_inline internal_int_gcd_lcm(res_gcd, res_lcm, a, b)
}
-gcd_lcm :: proc { int_gcd_lcm, };
+gcd_lcm :: proc { int_gcd_lcm, }
/*
Greatest Common Divisor.
*/
int_gcd :: proc(res, a, b: ^Int, allocator := context.allocator) -> (err: Error) {
- return #force_inline int_gcd_lcm(res, nil, a, b, allocator);
+ return #force_inline int_gcd_lcm(res, nil, a, b, allocator)
}
-gcd :: proc { int_gcd, };
+gcd :: proc { int_gcd, }
/*
Least Common Multiple.
*/
int_lcm :: proc(res, a, b: ^Int, allocator := context.allocator) -> (err: Error) {
- return #force_inline int_gcd_lcm(nil, res, a, b, allocator);
+ return #force_inline int_gcd_lcm(nil, res, a, b, allocator)
}
-lcm :: proc { int_lcm, };
+lcm :: proc { int_lcm, }
/*
remainder = numerator % (1 << bits)
*/
int_mod_bits :: proc(remainder, numerator: ^Int, bits: int, allocator := context.allocator) -> (err: Error) {
- assert_if_nil(remainder, numerator);
- context.allocator = allocator;
+ assert_if_nil(remainder, numerator)
+ context.allocator = allocator
- internal_clear_if_uninitialized(remainder, numerator) or_return;
+ internal_clear_if_uninitialized(remainder, numerator) or_return
if bits < 0 { return .Invalid_Argument; }
- return #force_inline internal_int_mod_bits(remainder, numerator, bits);
+ return #force_inline internal_int_mod_bits(remainder, numerator, bits)
}
-mod_bits :: proc { int_mod_bits, };
+mod_bits :: proc { int_mod_bits, }
/*
Logs and roots and such.
*/
int_log :: proc(a: ^Int, base: DIGIT, allocator := context.allocator) -> (res: int, err: Error) {
- assert_if_nil(a);
- context.allocator = allocator;
+ assert_if_nil(a)
+ context.allocator = allocator
- internal_clear_if_uninitialized(a) or_return;
+ internal_clear_if_uninitialized(a) or_return
- return #force_inline internal_int_log(a, base);
+ return #force_inline internal_int_log(a, base)
}
digit_log :: proc(a: DIGIT, base: DIGIT) -> (log: int, err: Error) {
- return #force_inline internal_digit_log(a, base);
+ return #force_inline internal_digit_log(a, base)
}
-log :: proc { int_log, digit_log, };
+log :: proc { int_log, digit_log, }
/*
Calculate `dest = base^power` using a square-multiply algorithm.
*/
int_pow :: proc(dest, base: ^Int, power: int, allocator := context.allocator) -> (err: Error) {
- assert_if_nil(dest, base);
- context.allocator = allocator;
+ assert_if_nil(dest, base)
+ context.allocator = allocator
- internal_clear_if_uninitialized(dest, base) or_return;
+ internal_clear_if_uninitialized(dest, base) or_return
- return #force_inline internal_int_pow(dest, base, power);
+ return #force_inline internal_int_pow(dest, base, power)
}
/*
Calculate `dest = base^power` using a square-multiply algorithm.
*/
int_pow_int :: proc(dest: ^Int, base, power: int, allocator := context.allocator) -> (err: Error) {
- assert_if_nil(dest);
+ assert_if_nil(dest)
- return #force_inline internal_pow(dest, base, power, allocator);
+ return #force_inline internal_pow(dest, base, power, allocator)
}
-pow :: proc { int_pow, int_pow_int, small_pow, };
-exp :: pow;
+pow :: proc { int_pow, int_pow_int, small_pow, }
+exp :: pow
small_pow :: proc(base: _WORD, exponent: _WORD) -> (result: _WORD) {
- return #force_inline internal_small_pow(base, exponent);
+ return #force_inline internal_small_pow(base, exponent)
}
/*
This function is less generic than `root_n`, simpler and faster.
*/
int_sqrt :: proc(dest, src: ^Int, allocator := context.allocator) -> (err: Error) {
- assert_if_nil(dest, src);
- context.allocator = allocator;
+ assert_if_nil(dest, src)
+ context.allocator = allocator
- internal_clear_if_uninitialized(dest, src) or_return;
+ internal_clear_if_uninitialized(dest, src) or_return
- return #force_inline internal_int_sqrt(dest, src);
+ return #force_inline internal_int_sqrt(dest, src)
}
-sqrt :: proc { int_sqrt, };
+sqrt :: proc { int_sqrt, }
/*
@@ -434,22 +434,22 @@ sqrt :: proc { int_sqrt, };
which will find the root in `log(n)` time where each step involves a fair bit.
*/
int_root_n :: proc(dest, src: ^Int, n: int, allocator := context.allocator) -> (err: Error) {
- context.allocator = allocator;
+ context.allocator = allocator
/*
Fast path for n == 2.
*/
if n == 2 { return sqrt(dest, src); }
- assert_if_nil(dest, src);
+ assert_if_nil(dest, src)
/*
Initialize dest + src if needed.
*/
- internal_clear_if_uninitialized(dest, src) or_return;
+ internal_clear_if_uninitialized(dest, src) or_return
- return #force_inline internal_int_root_n(dest, src, n);
+ return #force_inline internal_int_root_n(dest, src, n)
}
-root_n :: proc { int_root_n, };
+root_n :: proc { int_root_n, }
/*
Comparison routines.
@@ -458,103 +458,103 @@ root_n :: proc { int_root_n, };
int_is_initialized :: proc(a: ^Int) -> bool {
if a == nil { return false; }
- return #force_inline internal_int_is_initialized(a);
+ return #force_inline internal_int_is_initialized(a)
}
int_is_zero :: proc(a: ^Int, allocator := context.allocator) -> (zero: bool, err: Error) {
- assert_if_nil(a);
- context.allocator = allocator;
+ assert_if_nil(a)
+ context.allocator = allocator
- internal_clear_if_uninitialized(a) or_return;
+ internal_clear_if_uninitialized(a) or_return
- return #force_inline internal_is_zero(a), nil;
+ return #force_inline internal_is_zero(a), nil
}
int_is_positive :: proc(a: ^Int, allocator := context.allocator) -> (positive: bool, err: Error) {
- assert_if_nil(a);
- context.allocator = allocator;
+ assert_if_nil(a)
+ context.allocator = allocator
- internal_clear_if_uninitialized(a) or_return;
+ internal_clear_if_uninitialized(a) or_return
- return #force_inline internal_is_positive(a), nil;
+ return #force_inline internal_is_positive(a), nil
}
int_is_negative :: proc(a: ^Int, allocator := context.allocator) -> (negative: bool, err: Error) {
- assert_if_nil(a);
- context.allocator = allocator;
+ assert_if_nil(a)
+ context.allocator = allocator
- internal_clear_if_uninitialized(a) or_return;
+ internal_clear_if_uninitialized(a) or_return
- return #force_inline internal_is_negative(a), nil;
+ return #force_inline internal_is_negative(a), nil
}
int_is_even :: proc(a: ^Int, allocator := context.allocator) -> (even: bool, err: Error) {
- assert_if_nil(a);
- context.allocator = allocator;
+ assert_if_nil(a)
+ context.allocator = allocator
- internal_clear_if_uninitialized(a) or_return;
+ internal_clear_if_uninitialized(a) or_return
- return #force_inline internal_is_even(a), nil;
+ return #force_inline internal_is_even(a), nil
}
int_is_odd :: proc(a: ^Int, allocator := context.allocator) -> (odd: bool, err: Error) {
- assert_if_nil(a);
- context.allocator = allocator;
+ assert_if_nil(a)
+ context.allocator = allocator
- internal_clear_if_uninitialized(a) or_return;
+ internal_clear_if_uninitialized(a) or_return
- return #force_inline internal_is_odd(a), nil;
+ return #force_inline internal_is_odd(a), nil
}
platform_int_is_power_of_two :: #force_inline proc(a: int) -> bool {
- return ((a) != 0) && (((a) & ((a) - 1)) == 0);
+ return ((a) != 0) && (((a) & ((a) - 1)) == 0)
}
int_is_power_of_two :: proc(a: ^Int, allocator := context.allocator) -> (res: bool, err: Error) {
- assert_if_nil(a);
- context.allocator = allocator;
+ assert_if_nil(a)
+ context.allocator = allocator
- internal_clear_if_uninitialized(a) or_return;
+ internal_clear_if_uninitialized(a) or_return
- return #force_inline internal_is_power_of_two(a), nil;
+ return #force_inline internal_is_power_of_two(a), nil
}
/*
Compare two `Int`s, signed.
*/
int_compare :: proc(a, b: ^Int, allocator := context.allocator) -> (comparison: int, err: Error) {
- assert_if_nil(a, b);
- context.allocator = allocator;
+ assert_if_nil(a, b)
+ context.allocator = allocator
- internal_clear_if_uninitialized(a, b) or_return;
+ internal_clear_if_uninitialized(a, b) or_return
- return #force_inline internal_cmp(a, b), nil;
+ return #force_inline internal_cmp(a, b), nil
}
-int_cmp :: int_compare;
+int_cmp :: int_compare
/*
Compare an `Int` to an unsigned number upto the size of the backing type.
*/
int_compare_digit :: proc(a: ^Int, b: DIGIT, allocator := context.allocator) -> (comparison: int, err: Error) {
- assert_if_nil(a);
- context.allocator = allocator;
+ assert_if_nil(a)
+ context.allocator = allocator
- internal_clear_if_uninitialized(a) or_return;
+ internal_clear_if_uninitialized(a) or_return
- return #force_inline internal_cmp_digit(a, b), nil;
+ return #force_inline internal_cmp_digit(a, b), nil
}
-int_cmp_digit :: int_compare_digit;
+int_cmp_digit :: int_compare_digit
/*
Compare the magnitude of two `Int`s, unsigned.
*/
int_compare_magnitude :: proc(a, b: ^Int, allocator := context.allocator) -> (res: int, err: Error) {
- assert_if_nil(a, b);
- context.allocator = allocator;
+ assert_if_nil(a, b)
+ context.allocator = allocator
- internal_clear_if_uninitialized(a, b) or_return;
+ internal_clear_if_uninitialized(a, b) or_return
- return #force_inline internal_cmp_mag(a, b), nil;
+ return #force_inline internal_cmp_mag(a, b), nil
}
/*
@@ -564,10 +564,10 @@ int_compare_magnitude :: proc(a, b: ^Int, allocator := context.allocator) -> (re
Assumes `a` not to be `nil` and to have been initialized.
*/
int_is_square :: proc(a: ^Int, allocator := context.allocator) -> (square: bool, err: Error) {
- assert_if_nil(a);
- context.allocator = allocator;
+ assert_if_nil(a)
+ context.allocator = allocator
- internal_clear_if_uninitialized(a) or_return;
+ internal_clear_if_uninitialized(a) or_return
- return #force_inline internal_int_is_square(a);
+ return #force_inline internal_int_is_square(a)
} \ No newline at end of file
diff --git a/core/math/big/radix.odin b/core/math/big/radix.odin
index acf0bacbd..8908f7775 100644
--- a/core/math/big/radix.odin
+++ b/core/math/big/radix.odin
@@ -22,15 +22,15 @@ import "core:mem"
This version of `itoa` allocates one behalf of the caller. The caller must free the string.
*/
int_itoa_string :: proc(a: ^Int, radix := i8(-1), zero_terminate := false, allocator := context.allocator) -> (res: string, err: Error) {
- assert_if_nil(a);
- context.allocator = allocator;
+ assert_if_nil(a)
+ context.allocator = allocator
- a := a; radix := radix;
- clear_if_uninitialized(a) or_return;
+ a := a; radix := radix
+ clear_if_uninitialized(a) or_return
/*
Radix defaults to 10.
*/
- radix = radix if radix > 0 else 10;
+ radix = radix if radix > 0 else 10
/*
TODO: If we want to write a prefix for some of the radixes, we can oversize the buffer.
@@ -41,39 +41,39 @@ int_itoa_string :: proc(a: ^Int, radix := i8(-1), zero_terminate := false, alloc
Calculate the size of the buffer we need, and
Exit if calculating the size returned an error.
*/
- size := radix_size(a, radix, zero_terminate) or_return;
+ size := radix_size(a, radix, zero_terminate) or_return
/*
Allocate the buffer we need.
*/
- buffer := make([]u8, size);
+ buffer := make([]u8, size)
/*
Write the digits out into the buffer.
*/
- written: int;
- written, err = int_itoa_raw(a, radix, buffer, size, zero_terminate);
+ written: int
+ written, err = int_itoa_raw(a, radix, buffer, size, zero_terminate)
- return string(buffer[:written]), err;
+ return string(buffer[:written]), err
}
/*
This version of `itoa` allocates one behalf of the caller. The caller must free the string.
*/
int_itoa_cstring :: proc(a: ^Int, radix := i8(-1), allocator := context.allocator) -> (res: cstring, err: Error) {
- assert_if_nil(a);
- context.allocator = allocator;
+ assert_if_nil(a)
+ context.allocator = allocator
- a := a; radix := radix;
- clear_if_uninitialized(a) or_return;
+ a := a; radix := radix
+ clear_if_uninitialized(a) or_return
/*
Radix defaults to 10.
*/
- radix = radix if radix > 0 else 10;
+ radix = radix if radix > 0 else 10
- s: string;
- s, err = int_itoa_string(a, radix, true);
- return cstring(raw_data(s)), err;
+ s: string
+ s, err = int_itoa_string(a, radix, true)
+ return cstring(raw_data(s)), err
}
/*
@@ -97,57 +97,57 @@ int_itoa_cstring :: proc(a: ^Int, radix := i8(-1), allocator := context.allocato
and having to perform a buffer overflow check each character.
*/
int_itoa_raw :: proc(a: ^Int, radix: i8, buffer: []u8, size := int(-1), zero_terminate := false) -> (written: int, err: Error) {
- assert_if_nil(a);
- a := a; radix := radix; size := size;
- clear_if_uninitialized(a) or_return;
+ assert_if_nil(a)
+ a := a; radix := radix; size := size
+ clear_if_uninitialized(a) or_return
/*
Radix defaults to 10.
*/
- radix = radix if radix > 0 else 10;
+ radix = radix if radix > 0 else 10
if radix < 2 || radix > 64 {
- return 0, .Invalid_Argument;
+ return 0, .Invalid_Argument
}
/*
We weren't given a size. Let's compute it.
*/
if size == -1 {
- size = radix_size(a, radix, zero_terminate) or_return;
+ size = radix_size(a, radix, zero_terminate) or_return
}
/*
Early exit if the buffer we were given is too small.
*/
- available := len(buffer);
+ available := len(buffer)
if available < size {
- return 0, .Buffer_Overflow;
+ return 0, .Buffer_Overflow
}
/*
Fast path for when `Int` == 0 or the entire `Int` fits in a single radix digit.
*/
- z, _ := is_zero(a);
+ z, _ := is_zero(a)
if z || (a.used == 1 && a.digit[0] < DIGIT(radix)) {
if zero_terminate {
- available -= 1;
- buffer[available] = 0;
+ available -= 1
+ buffer[available] = 0
}
- available -= 1;
- buffer[available] = RADIX_TABLE[a.digit[0]];
+ available -= 1
+ buffer[available] = RADIX_TABLE[a.digit[0]]
if n, _ := is_neg(a); n {
- available -= 1;
- buffer[available] = '-';
+ available -= 1
+ buffer[available] = '-'
}
/*
If we overestimated the size, we need to move the buffer left.
*/
- written = len(buffer) - available;
+ written = len(buffer) - available
if written < size {
- diff := size - written;
- mem.copy(&buffer[0], &buffer[diff], written);
+ diff := size - written
+ mem.copy(&buffer[0], &buffer[diff], written)
}
- return written, nil;
+ return written, nil
}
/*
@@ -155,32 +155,32 @@ int_itoa_raw :: proc(a: ^Int, radix: i8, buffer: []u8, size := int(-1), zero_ter
*/
if a.used == 1 || a.used == 2 {
if zero_terminate {
- available -= 1;
- buffer[available] = 0;
+ available -= 1
+ buffer[available] = 0
}
- val := _WORD(a.digit[1]) << _DIGIT_BITS + _WORD(a.digit[0]);
+ val := _WORD(a.digit[1]) << _DIGIT_BITS + _WORD(a.digit[0])
for val > 0 {
- q := val / _WORD(radix);
- available -= 1;
- buffer[available] = RADIX_TABLE[val - (q * _WORD(radix))];
+ q := val / _WORD(radix)
+ available -= 1
+ buffer[available] = RADIX_TABLE[val - (q * _WORD(radix))]
- val = q;
+ val = q
}
if n, _ := is_neg(a); n {
- available -= 1;
- buffer[available] = '-';
+ available -= 1
+ buffer[available] = '-'
}
/*
If we overestimated the size, we need to move the buffer left.
*/
- written = len(buffer) - available;
+ written = len(buffer) - available
if written < size {
- diff := size - written;
- mem.copy(&buffer[0], &buffer[diff], written);
+ diff := size - written
+ mem.copy(&buffer[0], &buffer[diff], written)
}
- return written, nil;
+ return written, nil
}
/*
@@ -188,57 +188,57 @@ int_itoa_raw :: proc(a: ^Int, radix: i8, buffer: []u8, size := int(-1), zero_ter
*/
if is_power_of_two(int(radix)) {
if zero_terminate {
- available -= 1;
- buffer[available] = 0;
+ available -= 1
+ buffer[available] = 0
}
- shift, count: int;
+ shift, count: int
// mask := _WORD(radix - 1);
- shift, err = log(DIGIT(radix), 2);
- count, err = count_bits(a);
- digit: _WORD;
+ shift, err = log(DIGIT(radix), 2)
+ count, err = count_bits(a)
+ digit: _WORD
for offset := 0; offset < count; offset += shift {
- bits_to_get := int(min(count - offset, shift));
+ bits_to_get := int(min(count - offset, shift))
- digit, err = int_bitfield_extract(a, offset, bits_to_get);
+ digit, err = int_bitfield_extract(a, offset, bits_to_get)
if err != nil {
- return len(buffer) - available, .Invalid_Argument;
+ return len(buffer) - available, .Invalid_Argument
}
- available -= 1;
- buffer[available] = RADIX_TABLE[digit];
+ available -= 1
+ buffer[available] = RADIX_TABLE[digit]
}
if n, _ := is_neg(a); n {
- available -= 1;
- buffer[available] = '-';
+ available -= 1
+ buffer[available] = '-'
}
/*
If we overestimated the size, we need to move the buffer left.
*/
- written = len(buffer) - available;
+ written = len(buffer) - available
if written < size {
- diff := size - written;
- mem.copy(&buffer[0], &buffer[diff], written);
+ diff := size - written
+ mem.copy(&buffer[0], &buffer[diff], written)
}
- return written, nil;
+ return written, nil
}
- return _itoa_raw_full(a, radix, buffer, zero_terminate);
+ return _itoa_raw_full(a, radix, buffer, zero_terminate)
}
-itoa :: proc{int_itoa_string, int_itoa_raw};
-int_to_string :: int_itoa_string;
-int_to_cstring :: int_itoa_cstring;
+itoa :: proc{int_itoa_string, int_itoa_raw}
+int_to_string :: int_itoa_string
+int_to_cstring :: int_itoa_cstring
/*
Read a string [ASCII] in a given radix.
*/
int_atoi :: proc(res: ^Int, input: string, radix := i8(10), allocator := context.allocator) -> (err: Error) {
- assert_if_nil(res);
- input := input;
- context.allocator = allocator;
+ assert_if_nil(res)
+ input := input
+ context.allocator = allocator
/*
Make sure the radix is ok.
@@ -249,92 +249,92 @@ int_atoi :: proc(res: ^Int, input: string, radix := i8(10), allocator := context
/*
Set the integer to the default of zero.
*/
- internal_zero(res) or_return;
+ internal_zero(res) or_return
/*
We'll interpret an empty string as zero.
*/
if len(input) == 0 {
- return nil;
+ return nil
}
/*
If the leading digit is a minus set the sign to negative.
Given the above early out, the length should be at least 1.
*/
- sign := Sign.Zero_or_Positive;
+ sign := Sign.Zero_or_Positive
if input[0] == '-' {
- input = input[1:];
- sign = .Negative;
+ input = input[1:]
+ sign = .Negative
}
/*
Process each digit of the string.
*/
- ch: rune;
+ ch: rune
for len(input) > 0 {
/* if the radix <= 36 the conversion is case insensitive
* this allows numbers like 1AB and 1ab to represent the same value
* [e.g. in hex]
*/
- ch = rune(input[0]);
+ ch = rune(input[0])
if radix <= 36 && ch >= 'a' && ch <= 'z' {
- ch -= 32; // 'a' - 'A'
+ ch -= 32 // 'a' - 'A'
}
- pos := ch - '+';
+ pos := ch - '+'
if RADIX_TABLE_REVERSE_SIZE <= pos {
- break;
+ break
}
- y := RADIX_TABLE_REVERSE[pos];
+ y := RADIX_TABLE_REVERSE[pos]
/* if the char was found in the map
* and is less than the given radix add it
* to the number, otherwise exit the loop.
*/
if y >= u8(radix) {
- break;
+ break
}
- internal_mul(res, res, DIGIT(radix)) or_return;
- internal_add(res, res, DIGIT(y)) or_return;
+ internal_mul(res, res, DIGIT(radix)) or_return
+ internal_add(res, res, DIGIT(y)) or_return
- input = input[1:];
+ input = input[1:]
}
/*
If an illegal character was found, fail.
*/
if len(input) > 0 && ch != 0 && ch != '\r' && ch != '\n' {
- return .Invalid_Argument;
+ return .Invalid_Argument
}
/*
Set the sign only if res != 0.
*/
if res.used > 0 {
- res.sign = sign;
+ res.sign = sign
}
- return nil;
+ return nil
}
-atoi :: proc { int_atoi, };
+atoi :: proc { int_atoi, }
/*
We size for `string` by default.
*/
radix_size :: proc(a: ^Int, radix: i8, zero_terminate := false, allocator := context.allocator) -> (size: int, err: Error) {
- a := a;
- assert_if_nil(a);
+ a := a
+ assert_if_nil(a)
if radix < 2 || radix > 64 { return -1, .Invalid_Argument; }
- clear_if_uninitialized(a) or_return;
+ clear_if_uninitialized(a) or_return
if internal_is_zero(a) {
if zero_terminate {
- return 2, nil;
+ return 2, nil
}
- return 1, nil;
+ return 1, nil
}
if internal_is_power_of_two(a) {
@@ -345,37 +345,37 @@ radix_size :: proc(a: ^Int, radix: i8, zero_terminate := false, allocator := con
used = a.used,
sign = .Zero_or_Positive,
digit = a.digit,
- };
+ }
- size = internal_log(t, DIGIT(radix)) or_return;
+ size = internal_log(t, DIGIT(radix)) or_return
} else {
- la, k := &Int{}, &Int{};
- defer internal_destroy(la, k);
+ la, k := &Int{}, &Int{}
+ defer internal_destroy(la, k)
/* la = floor(log_2(a)) + 1 */
- bit_count := internal_count_bits(a);
- internal_set(la, bit_count) or_return;
+ bit_count := internal_count_bits(a)
+ internal_set(la, bit_count) or_return
/* k = floor(2^29/log_2(radix)) + 1 */
- lb := _log_bases;
- internal_set(k, lb[radix]) or_return;
+ lb := _log_bases
+ internal_set(k, lb[radix]) or_return
/* n = floor((la * k) / 2^29) + 1 */
- internal_mul(k, la, k) or_return;
- internal_shr(k, k, _RADIX_SIZE_SCALE) or_return;
+ internal_mul(k, la, k) or_return
+ internal_shr(k, k, _RADIX_SIZE_SCALE) or_return
/* The "+1" here is the "+1" in "floor((la * k) / 2^29) + 1" */
/* n = n + 1 + EOS + sign */
- size_, _ := internal_get(k, u128);
- size = int(size_);
+ size_, _ := internal_get(k, u128)
+ size = int(size_)
}
/*
log truncates to zero, so we need to add one more, and one for `-` if negative.
*/
- size += 2 if a.sign == .Negative else 1;
- size += 1 if zero_terminate else 0;
- return size, nil;
+ size += 2 if a.sign == .Negative else 1
+ size += 1 if zero_terminate else 0
+ return size, nil
}
/*
@@ -392,7 +392,7 @@ radix_size :: proc(a: ^Int, radix: i8, zero_terminate := false, allocator := con
for 64 bit "int".
*/
-_RADIX_SIZE_SCALE :: 29;
+_RADIX_SIZE_SCALE :: 29
_log_bases :: [65]u32{
0, 0, 0x20000001, 0x14309399, 0x10000001,
0xdc81a35, 0xc611924, 0xb660c9e, 0xaaaaaab, 0xa1849cd,
@@ -407,12 +407,12 @@ _log_bases :: [65]u32{
0x5ab7d68, 0x5a42df0, 0x59d1506, 0x5962ffe, 0x58f7c57,
0x588f7bc, 0x582a000, 0x57c7319, 0x5766f1d, 0x5709243,
0x56adad9, 0x565474d, 0x55fd61f, 0x55a85e8, 0x5555556,
-};
+}
/*
Characters used in radix conversions.
*/
-RADIX_TABLE := "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/";
+RADIX_TABLE := "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/"
RADIX_TABLE_REVERSE := [RADIX_TABLE_REVERSE_SIZE]u8{
0x3e, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x01, 0x02, 0x03, 0x04, /* +,-./01234 */
0x05, 0x06, 0x07, 0x08, 0x09, 0xff, 0xff, 0xff, 0xff, 0xff, /* 56789:;<=> */
@@ -422,59 +422,59 @@ RADIX_TABLE_REVERSE := [RADIX_TABLE_REVERSE_SIZE]u8{
0xff, 0xff, 0xff, 0xff, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, /* ]^_`abcdef */
0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, /* ghijklmnop */
0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, /* qrstuvwxyz */
-};
-RADIX_TABLE_REVERSE_SIZE :: 80;
+}
+RADIX_TABLE_REVERSE_SIZE :: 80
/*
Stores a bignum as a ASCII string in a given radix (2..64)
The buffer must be appropriately sized. This routine doesn't check.
*/
_itoa_raw_full :: proc(a: ^Int, radix: i8, buffer: []u8, zero_terminate := false, allocator := context.allocator) -> (written: int, err: Error) {
- assert_if_nil(a);
- context.allocator = allocator;
+ assert_if_nil(a)
+ context.allocator = allocator
- temp, denominator := &Int{}, &Int{};
+ temp, denominator := &Int{}, &Int{}
- internal_copy(temp, a) or_return;
- internal_set(denominator, radix) or_return;
+ internal_copy(temp, a) or_return
+ internal_set(denominator, radix) or_return
- available := len(buffer);
+ available := len(buffer)
if zero_terminate {
- available -= 1;
- buffer[available] = 0;
+ available -= 1
+ buffer[available] = 0
}
if a.sign == .Negative {
- temp.sign = .Zero_or_Positive;
+ temp.sign = .Zero_or_Positive
}
- remainder: DIGIT;
+ remainder: DIGIT
for {
if remainder, err = #force_inline internal_divmod(temp, temp, DIGIT(radix)); err != nil {
- internal_destroy(temp, denominator);
- return len(buffer) - available, err;
+ internal_destroy(temp, denominator)
+ return len(buffer) - available, err
}
- available -= 1;
- buffer[available] = RADIX_TABLE[remainder];
+ available -= 1
+ buffer[available] = RADIX_TABLE[remainder]
if temp.used == 0 {
- break;
+ break
}
}
if a.sign == .Negative {
- available -= 1;
- buffer[available] = '-';
+ available -= 1
+ buffer[available] = '-'
}
- internal_destroy(temp, denominator);
+ internal_destroy(temp, denominator)
/*
If we overestimated the size, we need to move the buffer left.
*/
- written = len(buffer) - available;
+ written = len(buffer) - available
if written < len(buffer) {
- diff := len(buffer) - written;
- mem.copy(&buffer[0], &buffer[diff], written);
+ diff := len(buffer) - written
+ mem.copy(&buffer[0], &buffer[diff], written)
}
- return written, nil;
+ return written, nil
} \ No newline at end of file
diff --git a/core/math/big/test.odin b/core/math/big/test.odin
index ea3c6be49..609b8ce10 100644
--- a/core/math/big/test.odin
+++ b/core/math/big/test.odin
@@ -25,24 +25,24 @@ PyRes :: struct {
}
@export test_initialize_constants :: proc "c" () -> (res: u64) {
- context = runtime.default_context();
- res = u64(initialize_constants());
+ context = runtime.default_context()
+ res = u64(initialize_constants())
//assert(MUL_KARATSUBA_CUTOFF >= 40);
- return res;
+ return res
}
@export test_error_string :: proc "c" (err: Error) -> (res: cstring) {
- context = runtime.default_context();
- es := Error_String;
- return strings.clone_to_cstring(es[err], context.temp_allocator);
+ context = runtime.default_context()
+ es := Error_String
+ return strings.clone_to_cstring(es[err], context.temp_allocator)
}
@export test_add :: proc "c" (a, b: cstring) -> (res: PyRes) {
- context = runtime.default_context();
- err: Error;
+ context = runtime.default_context()
+ err: Error
- aa, bb, sum := &Int{}, &Int{}, &Int{};
- defer internal_destroy(aa, bb, sum);
+ aa, bb, sum := &Int{}, &Int{}, &Int{}
+ defer internal_destroy(aa, bb, sum)
if err = atoi(aa, string(a), 16); err != nil { return PyRes{res=":add:atoi(a):", err=err}; }
if err = atoi(bb, string(b), 16); err != nil { return PyRes{res=":add:atoi(b):", err=err}; }
@@ -52,18 +52,18 @@ PyRes :: struct {
if err = #force_inline internal_add(sum, aa, bb); err != nil { return PyRes{res=":add:add(sum,a,b):", err=err}; }
}
- r: cstring;
- r, err = int_itoa_cstring(sum, 16, context.temp_allocator);
+ r: cstring
+ r, err = int_itoa_cstring(sum, 16, context.temp_allocator)
if err != nil { return PyRes{res=":add:itoa(sum):", err=err}; }
- return PyRes{res = r, err = nil};
+ return PyRes{res = r, err = nil}
}
@export test_sub :: proc "c" (a, b: cstring) -> (res: PyRes) {
- context = runtime.default_context();
- err: Error;
+ context = runtime.default_context()
+ err: Error
- aa, bb, sum := &Int{}, &Int{}, &Int{};
- defer internal_destroy(aa, bb, sum);
+ aa, bb, sum := &Int{}, &Int{}, &Int{}
+ defer internal_destroy(aa, bb, sum)
if err = atoi(aa, string(a), 16); err != nil { return PyRes{res=":sub:atoi(a):", err=err}; }
if err = atoi(bb, string(b), 16); err != nil { return PyRes{res=":sub:atoi(b):", err=err}; }
@@ -73,63 +73,63 @@ PyRes :: struct {
if err = #force_inline internal_sub(sum, aa, bb); err != nil { return PyRes{res=":sub:sub(sum,a,b):", err=err}; }
}
- r: cstring;
- r, err = int_itoa_cstring(sum, 16, context.temp_allocator);
+ r: cstring
+ r, err = int_itoa_cstring(sum, 16, context.temp_allocator)
if err != nil { return PyRes{res=":sub:itoa(sum):", err=err}; }
- return PyRes{res = r, err = nil};
+ return PyRes{res = r, err = nil}
}
@export test_mul :: proc "c" (a, b: cstring) -> (res: PyRes) {
- context = runtime.default_context();
- err: Error;
+ context = runtime.default_context()
+ err: Error
- aa, bb, product := &Int{}, &Int{}, &Int{};
- defer internal_destroy(aa, bb, product);
+ aa, bb, product := &Int{}, &Int{}, &Int{}
+ defer internal_destroy(aa, bb, product)
if err = atoi(aa, string(a), 16); err != nil { return PyRes{res=":mul:atoi(a):", err=err}; }
if err = atoi(bb, string(b), 16); err != nil { return PyRes{res=":mul:atoi(b):", err=err}; }
if err = #force_inline internal_mul(product, aa, bb); err != nil { return PyRes{res=":mul:mul(product,a,b):", err=err}; }
- r: cstring;
- r, err = int_itoa_cstring(product, 16, context.temp_allocator);
+ r: cstring
+ r, err = int_itoa_cstring(product, 16, context.temp_allocator)
if err != nil { return PyRes{res=":mul:itoa(product):", err=err}; }
- return PyRes{res = r, err = nil};
+ return PyRes{res = r, err = nil}
}
@export test_sqr :: proc "c" (a: cstring) -> (res: PyRes) {
- context = runtime.default_context();
- err: Error;
+ context = runtime.default_context()
+ err: Error
- aa, square := &Int{}, &Int{};
- defer internal_destroy(aa, square);
+ aa, square := &Int{}, &Int{}
+ defer internal_destroy(aa, square)
if err = atoi(aa, string(a), 16); err != nil { return PyRes{res=":sqr:atoi(a):", err=err}; }
if err = #force_inline internal_sqr(square, aa); err != nil { return PyRes{res=":sqr:sqr(square,a):", err=err}; }
- r: cstring;
- r, err = int_itoa_cstring(square, 16, context.temp_allocator);
+ r: cstring
+ r, err = int_itoa_cstring(square, 16, context.temp_allocator)
if err != nil { return PyRes{res=":sqr:itoa(square):", err=err}; }
- return PyRes{res = r, err = nil};
+ return PyRes{res = r, err = nil}
}
/*
NOTE(Jeroen): For simplicity, we don't return the quotient and the remainder, just the quotient.
*/
@export test_div :: proc "c" (a, b: cstring) -> (res: PyRes) {
- context = runtime.default_context();
- err: Error;
+ context = runtime.default_context()
+ err: Error
- aa, bb, quotient := &Int{}, &Int{}, &Int{};
- defer internal_destroy(aa, bb, quotient);
+ aa, bb, quotient := &Int{}, &Int{}, &Int{}
+ defer internal_destroy(aa, bb, quotient)
if err = atoi(aa, string(a), 16); err != nil { return PyRes{res=":div:atoi(a):", err=err}; }
if err = atoi(bb, string(b), 16); err != nil { return PyRes{res=":div:atoi(b):", err=err}; }
if err = #force_inline internal_div(quotient, aa, bb); err != nil { return PyRes{res=":div:div(quotient,a,b):", err=err}; }
- r: cstring;
- r, err = int_itoa_cstring(quotient, 16, context.temp_allocator);
+ r: cstring
+ r, err = int_itoa_cstring(quotient, 16, context.temp_allocator)
if err != nil { return PyRes{res=":div:itoa(quotient):", err=err}; }
- return PyRes{res = r, err = nil};
+ return PyRes{res = r, err = nil}
}
@@ -137,254 +137,254 @@ PyRes :: struct {
res = log(a, base)
*/
@export test_log :: proc "c" (a: cstring, base := DIGIT(2)) -> (res: PyRes) {
- context = runtime.default_context();
- err: Error;
- l: int;
+ context = runtime.default_context()
+ err: Error
+ l: int
- aa := &Int{};
- defer internal_destroy(aa);
+ aa := &Int{}
+ defer internal_destroy(aa)
if err = atoi(aa, string(a), 16); err != nil { return PyRes{res=":log:atoi(a):", err=err}; }
if l, err = #force_inline internal_log(aa, base); err != nil { return PyRes{res=":log:log(a, base):", err=err}; }
#force_inline internal_zero(aa);
- aa.digit[0] = DIGIT(l) & _MASK;
- aa.digit[1] = DIGIT(l) >> _DIGIT_BITS;
- aa.used = 2;
- clamp(aa);
+ aa.digit[0] = DIGIT(l) & _MASK
+ aa.digit[1] = DIGIT(l) >> _DIGIT_BITS
+ aa.used = 2
+ clamp(aa)
- r: cstring;
- r, err = int_itoa_cstring(aa, 16, context.temp_allocator);
+ r: cstring
+ r, err = int_itoa_cstring(aa, 16, context.temp_allocator)
if err != nil { return PyRes{res=":log:itoa(res):", err=err}; }
- return PyRes{res = r, err = nil};
+ return PyRes{res = r, err = nil}
}
/*
dest = base^power
*/
@export test_pow :: proc "c" (base: cstring, power := int(2)) -> (res: PyRes) {
- context = runtime.default_context();
- err: Error;
+ context = runtime.default_context()
+ err: Error
- dest, bb := &Int{}, &Int{};
- defer internal_destroy(dest, bb);
+ dest, bb := &Int{}, &Int{}
+ defer internal_destroy(dest, bb)
if err = atoi(bb, string(base), 16); err != nil { return PyRes{res=":pow:atoi(base):", err=err}; }
if err = #force_inline internal_pow(dest, bb, power); err != nil { return PyRes{res=":pow:pow(dest, base, power):", err=err}; }
- r: cstring;
- r, err = int_itoa_cstring(dest, 16, context.temp_allocator);
+ r: cstring
+ r, err = int_itoa_cstring(dest, 16, context.temp_allocator)
if err != nil { return PyRes{res=":log:itoa(res):", err=err}; }
- return PyRes{res = r, err = nil};
+ return PyRes{res = r, err = nil}
}
/*
dest = sqrt(src)
*/
@export test_sqrt :: proc "c" (source: cstring) -> (res: PyRes) {
- context = runtime.default_context();
- err: Error;
+ context = runtime.default_context()
+ err: Error
- src := &Int{};
- defer internal_destroy(src);
+ src := &Int{}
+ defer internal_destroy(src)
if err = atoi(src, string(source), 16); err != nil { return PyRes{res=":sqrt:atoi(src):", err=err}; }
if err = #force_inline internal_sqrt(src, src); err != nil { return PyRes{res=":sqrt:sqrt(src):", err=err}; }
- r: cstring;
- r, err = int_itoa_cstring(src, 16, context.temp_allocator);
+ r: cstring
+ r, err = int_itoa_cstring(src, 16, context.temp_allocator)
if err != nil { return PyRes{res=":log:itoa(res):", err=err}; }
- return PyRes{res = r, err = nil};
+ return PyRes{res = r, err = nil}
}
/*
dest = root_n(src, power)
*/
@export test_root_n :: proc "c" (source: cstring, power: int) -> (res: PyRes) {
- context = runtime.default_context();
- err: Error;
+ context = runtime.default_context()
+ err: Error
- src := &Int{};
- defer internal_destroy(src);
+ src := &Int{}
+ defer internal_destroy(src)
if err = atoi(src, string(source), 16); err != nil { return PyRes{res=":root_n:atoi(src):", err=err}; }
if err = #force_inline internal_root_n(src, src, power); err != nil { return PyRes{res=":root_n:root_n(src):", err=err}; }
- r: cstring;
- r, err = int_itoa_cstring(src, 16, context.temp_allocator);
+ r: cstring
+ r, err = int_itoa_cstring(src, 16, context.temp_allocator)
if err != nil { return PyRes{res=":root_n:itoa(res):", err=err}; }
- return PyRes{res = r, err = nil};
+ return PyRes{res = r, err = nil}
}
/*
dest = shr_digit(src, digits)
*/
@export test_shr_digit :: proc "c" (source: cstring, digits: int) -> (res: PyRes) {
- context = runtime.default_context();
- err: Error;
+ context = runtime.default_context()
+ err: Error
- src := &Int{};
- defer internal_destroy(src);
+ src := &Int{}
+ defer internal_destroy(src)
if err = atoi(src, string(source), 16); err != nil { return PyRes{res=":shr_digit:atoi(src):", err=err}; }
if err = #force_inline internal_shr_digit(src, digits); err != nil { return PyRes{res=":shr_digit:shr_digit(src):", err=err}; }
- r: cstring;
- r, err = int_itoa_cstring(src, 16, context.temp_allocator);
+ r: cstring
+ r, err = int_itoa_cstring(src, 16, context.temp_allocator)
if err != nil { return PyRes{res=":shr_digit:itoa(res):", err=err}; }
- return PyRes{res = r, err = nil};
+ return PyRes{res = r, err = nil}
}
/*
dest = shl_digit(src, digits)
*/
@export test_shl_digit :: proc "c" (source: cstring, digits: int) -> (res: PyRes) {
- context = runtime.default_context();
- err: Error;
+ context = runtime.default_context()
+ err: Error
- src := &Int{};
- defer internal_destroy(src);
+ src := &Int{}
+ defer internal_destroy(src)
if err = atoi(src, string(source), 16); err != nil { return PyRes{res=":shl_digit:atoi(src):", err=err}; }
if err = #force_inline internal_shl_digit(src, digits); err != nil { return PyRes{res=":shl_digit:shr_digit(src):", err=err}; }
- r: cstring;
- r, err = int_itoa_cstring(src, 16, context.temp_allocator);
+ r: cstring
+ r, err = int_itoa_cstring(src, 16, context.temp_allocator)
if err != nil { return PyRes{res=":shl_digit:itoa(res):", err=err}; }
- return PyRes{res = r, err = nil};
+ return PyRes{res = r, err = nil}
}
/*
dest = shr(src, bits)
*/
@export test_shr :: proc "c" (source: cstring, bits: int) -> (res: PyRes) {
- context = runtime.default_context();
- err: Error;
+ context = runtime.default_context()
+ err: Error
- src := &Int{};
- defer internal_destroy(src);
+ src := &Int{}
+ defer internal_destroy(src)
if err = atoi(src, string(source), 16); err != nil { return PyRes{res=":shr:atoi(src):", err=err}; }
if err = #force_inline internal_shr(src, src, bits); err != nil { return PyRes{res=":shr:shr(src, bits):", err=err}; }
- r: cstring;
- r, err = int_itoa_cstring(src, 16, context.temp_allocator);
+ r: cstring
+ r, err = int_itoa_cstring(src, 16, context.temp_allocator)
if err != nil { return PyRes{res=":shr:itoa(res):", err=err}; }
- return PyRes{res = r, err = nil};
+ return PyRes{res = r, err = nil}
}
/*
dest = shr_signed(src, bits)
*/
@export test_shr_signed :: proc "c" (source: cstring, bits: int) -> (res: PyRes) {
- context = runtime.default_context();
- err: Error;
+ context = runtime.default_context()
+ err: Error
- src := &Int{};
- defer internal_destroy(src);
+ src := &Int{}
+ defer internal_destroy(src)
if err = atoi(src, string(source), 16); err != nil { return PyRes{res=":shr_signed:atoi(src):", err=err}; }
if err = #force_inline internal_shr_signed(src, src, bits); err != nil { return PyRes{res=":shr_signed:shr_signed(src, bits):", err=err}; }
- r: cstring;
- r, err = int_itoa_cstring(src, 16, context.temp_allocator);
+ r: cstring
+ r, err = int_itoa_cstring(src, 16, context.temp_allocator)
if err != nil { return PyRes{res=":shr_signed:itoa(res):", err=err}; }
- return PyRes{res = r, err = nil};
+ return PyRes{res = r, err = nil}
}
/*
dest = shl(src, bits)
*/
@export test_shl :: proc "c" (source: cstring, bits: int) -> (res: PyRes) {
- context = runtime.default_context();
- err: Error;
+ context = runtime.default_context()
+ err: Error
- src := &Int{};
- defer internal_destroy(src);
+ src := &Int{}
+ defer internal_destroy(src)
if err = atoi(src, string(source), 16); err != nil { return PyRes{res=":shl:atoi(src):", err=err}; }
if err = #force_inline internal_shl(src, src, bits); err != nil { return PyRes{res=":shl:shl(src, bits):", err=err}; }
- r: cstring;
- r, err = int_itoa_cstring(src, 16, context.temp_allocator);
+ r: cstring
+ r, err = int_itoa_cstring(src, 16, context.temp_allocator)
if err != nil { return PyRes{res=":shl:itoa(res):", err=err}; }
- return PyRes{res = r, err = nil};
+ return PyRes{res = r, err = nil}
}
/*
dest = factorial(n)
*/
@export test_factorial :: proc "c" (n: int) -> (res: PyRes) {
- context = runtime.default_context();
- err: Error;
+ context = runtime.default_context()
+ err: Error
- dest := &Int{};
- defer internal_destroy(dest);
+ dest := &Int{}
+ defer internal_destroy(dest)
if err = #force_inline internal_int_factorial(dest, n); err != nil { return PyRes{res=":factorial:factorial(n):", err=err}; }
- r: cstring;
- r, err = int_itoa_cstring(dest, 16, context.temp_allocator);
+ r: cstring
+ r, err = int_itoa_cstring(dest, 16, context.temp_allocator)
if err != nil { return PyRes{res=":factorial:itoa(res):", err=err}; }
- return PyRes{res = r, err = nil};
+ return PyRes{res = r, err = nil}
}
/*
dest = gcd(a, b)
*/
@export test_gcd :: proc "c" (a, b: cstring) -> (res: PyRes) {
- context = runtime.default_context();
- err: Error;
+ context = runtime.default_context()
+ err: Error
- ai, bi, dest := &Int{}, &Int{}, &Int{};
- defer internal_destroy(ai, bi, dest);
+ ai, bi, dest := &Int{}, &Int{}, &Int{}
+ defer internal_destroy(ai, bi, dest)
if err = atoi(ai, string(a), 16); err != nil { return PyRes{res=":gcd:atoi(a):", err=err}; }
if err = atoi(bi, string(b), 16); err != nil { return PyRes{res=":gcd:atoi(b):", err=err}; }
if err = #force_inline internal_int_gcd_lcm(dest, nil, ai, bi); err != nil { return PyRes{res=":gcd:gcd(a, b):", err=err}; }
- r: cstring;
- r, err = int_itoa_cstring(dest, 16, context.temp_allocator);
+ r: cstring
+ r, err = int_itoa_cstring(dest, 16, context.temp_allocator)
if err != nil { return PyRes{res=":gcd:itoa(res):", err=err}; }
- return PyRes{res = r, err = nil};
+ return PyRes{res = r, err = nil}
}
/*
dest = lcm(a, b)
*/
@export test_lcm :: proc "c" (a, b: cstring) -> (res: PyRes) {
- context = runtime.default_context();
- err: Error;
+ context = runtime.default_context()
+ err: Error
- ai, bi, dest := &Int{}, &Int{}, &Int{};
- defer internal_destroy(ai, bi, dest);
+ ai, bi, dest := &Int{}, &Int{}, &Int{}
+ defer internal_destroy(ai, bi, dest)
if err = atoi(ai, string(a), 16); err != nil { return PyRes{res=":lcm:atoi(a):", err=err}; }
if err = atoi(bi, string(b), 16); err != nil { return PyRes{res=":lcm:atoi(b):", err=err}; }
if err = #force_inline internal_int_gcd_lcm(nil, dest, ai, bi); err != nil { return PyRes{res=":lcm:lcm(a, b):", err=err}; }
- r: cstring;
- r, err = int_itoa_cstring(dest, 16, context.temp_allocator);
+ r: cstring
+ r, err = int_itoa_cstring(dest, 16, context.temp_allocator)
if err != nil { return PyRes{res=":lcm:itoa(res):", err=err}; }
- return PyRes{res = r, err = nil};
+ return PyRes{res = r, err = nil}
}
/*
dest = lcm(a, b)
*/
@export test_is_square :: proc "c" (a: cstring) -> (res: PyRes) {
- context = runtime.default_context();
- err: Error;
- square: bool;
+ context = runtime.default_context()
+ err: Error
+ square: bool
- ai := &Int{};
- defer internal_destroy(ai);
+ ai := &Int{}
+ defer internal_destroy(ai)
if err = atoi(ai, string(a), 16); err != nil { return PyRes{res=":is_square:atoi(a):", err=err}; }
if square, err = #force_inline internal_int_is_square(ai); err != nil { return PyRes{res=":is_square:is_square(a):", err=err}; }
if square {
- return PyRes{"True", nil};
+ return PyRes{"True", nil}
}
- return PyRes{"False", nil};
+ return PyRes{"False", nil}
} \ No newline at end of file
diff --git a/core/math/big/tune.odin b/core/math/big/tune.odin
index 700a5e74a..c34f73b37 100644
--- a/core/math/big/tune.odin
+++ b/core/math/big/tune.odin
@@ -24,58 +24,58 @@ Category :: enum {
sqr,
bitfield_extract,
rm_trials,
-};
+}
Event :: struct {
ticks: time.Duration,
count: int,
cycles: u64,
}
-Timings := [Category]Event{};
+Timings := [Category]Event{}
print_timings :: proc() {
duration :: proc(d: time.Duration) -> (res: string) {
switch {
case d < time.Microsecond:
- return fmt.tprintf("%v ns", time.duration_nanoseconds(d));
+ return fmt.tprintf("%v ns", time.duration_nanoseconds(d))
case d < time.Millisecond:
- return fmt.tprintf("%v µs", time.duration_microseconds(d));
+ return fmt.tprintf("%v µs", time.duration_microseconds(d))
case:
- return fmt.tprintf("%v ms", time.duration_milliseconds(d));
+ return fmt.tprintf("%v ms", time.duration_milliseconds(d))
}
}
for v in Timings {
if v.count > 0 {
- fmt.println("\nTimings:");
- break;
+ fmt.println("\nTimings:")
+ break
}
}
for v, i in Timings {
if v.count > 0 {
- avg_ticks := time.Duration(f64(v.ticks) / f64(v.count));
- avg_cycles := f64(v.cycles) / f64(v.count);
+ avg_ticks := time.Duration(f64(v.ticks) / f64(v.count))
+ avg_cycles := f64(v.cycles) / f64(v.count)
- fmt.printf("\t%v: %s / %v cycles (avg), %s / %v cycles (total, %v calls)\n", i, duration(avg_ticks), avg_cycles, duration(v.ticks), v.cycles, v.count);
+ fmt.printf("\t%v: %s / %v cycles (avg), %s / %v cycles (total, %v calls)\n", i, duration(avg_ticks), avg_cycles, duration(v.ticks), v.cycles, v.count)
}
}
}
@(deferred_in_out=_SCOPE_END)
SCOPED_TIMING :: #force_inline proc(c: Category) -> (ticks: time.Tick, cycles: u64) {
- cycles = time.read_cycle_counter();
- ticks = time.tick_now();
- return;
+ cycles = time.read_cycle_counter()
+ ticks = time.tick_now()
+ return
}
_SCOPE_END :: #force_inline proc(c: Category, ticks: time.Tick, cycles: u64) {
- cycles_now := time.read_cycle_counter();
- ticks_now := time.tick_now();
+ cycles_now := time.read_cycle_counter()
+ ticks_now := time.tick_now()
- Timings[c].ticks = time.tick_diff(ticks, ticks_now);
- Timings[c].cycles = cycles_now - cycles;
- Timings[c].count += 1;
+ Timings[c].ticks = time.tick_diff(ticks, ticks_now)
+ Timings[c].cycles = cycles_now - cycles
+ Timings[c].count += 1
}
SCOPED_COUNT_ADD :: #force_inline proc(c: Category, count: int) {
- Timings[c].count += count;
+ Timings[c].count += count
}
diff --git a/core/math/bits/bits.odin b/core/math/bits/bits.odin
index 91b773504..c65c2fa2b 100644
--- a/core/math/bits/bits.odin
+++ b/core/math/bits/bits.odin
@@ -2,66 +2,66 @@ package math_bits
import "core:intrinsics"
-U8_MIN :: 0;
-U16_MIN :: 0;
-U32_MIN :: 0;
-U64_MIN :: 0;
+U8_MIN :: 0
+U16_MIN :: 0
+U32_MIN :: 0
+U64_MIN :: 0
-U8_MAX :: 1 << 8 - 1;
-U16_MAX :: 1 << 16 - 1;
-U32_MAX :: 1 << 32 - 1;
-U64_MAX :: 1 << 64 - 1;
+U8_MAX :: 1 << 8 - 1
+U16_MAX :: 1 << 16 - 1
+U32_MAX :: 1 << 32 - 1
+U64_MAX :: 1 << 64 - 1
-I8_MIN :: - 1 << 7;
-I16_MIN :: - 1 << 15;
-I32_MIN :: - 1 << 31;
-I64_MIN :: - 1 << 63;
+I8_MIN :: - 1 << 7
+I16_MIN :: - 1 << 15
+I32_MIN :: - 1 << 31
+I64_MIN :: - 1 << 63
-I8_MAX :: 1 << 7 - 1;
-I16_MAX :: 1 << 15 - 1;
-I32_MAX :: 1 << 31 - 1;
-I64_MAX :: 1 << 63 - 1;
+I8_MAX :: 1 << 7 - 1
+I16_MAX :: 1 << 15 - 1
+I32_MAX :: 1 << 31 - 1
+I64_MAX :: 1 << 63 - 1
-count_ones :: intrinsics.count_ones;
-count_zeros :: intrinsics.count_zeros;
-trailing_zeros :: intrinsics.count_trailing_zeros;
-leading_zeros :: intrinsics.count_leading_zeros;
-count_trailing_zeros :: intrinsics.count_trailing_zeros;
-count_leading_zeros :: intrinsics.count_leading_zeros;
-reverse_bits :: intrinsics.reverse_bits;
-byte_swap :: intrinsics.byte_swap;
+count_ones :: intrinsics.count_ones
+count_zeros :: intrinsics.count_zeros
+trailing_zeros :: intrinsics.count_trailing_zeros
+leading_zeros :: intrinsics.count_leading_zeros
+count_trailing_zeros :: intrinsics.count_trailing_zeros
+count_leading_zeros :: intrinsics.count_leading_zeros
+reverse_bits :: intrinsics.reverse_bits
+byte_swap :: intrinsics.byte_swap
-overflowing_add :: intrinsics.overflow_add;
-overflowing_sub :: intrinsics.overflow_sub;
-overflowing_mul :: intrinsics.overflow_mul;
+overflowing_add :: intrinsics.overflow_add
+overflowing_sub :: intrinsics.overflow_sub
+overflowing_mul :: intrinsics.overflow_mul
rotate_left8 :: proc(x: u8, k: int) -> u8 {
- n :: 8;
- s := uint(k) & (n-1);
- return x <<s | x>>(n-s);
+ n :: 8
+ s := uint(k) & (n-1)
+ return x <<s | x>>(n-s)
}
rotate_left16 :: proc(x: u16, k: int) -> u16 {
- n :: 16;
- s := uint(k) & (n-1);
- return x <<s | x>>(n-s);
+ n :: 16
+ s := uint(k) & (n-1)
+ return x <<s | x>>(n-s)
}
rotate_left32 :: proc(x: u32, k: int) -> u32 {
- n :: 32;
- s := uint(k) & (n-1);
- return x <<s | x>>(n-s);
+ n :: 32
+ s := uint(k) & (n-1)
+ return x <<s | x>>(n-s)
}
rotate_left64 :: proc(x: u64, k: int) -> u64 {
- n :: 64;
- s := uint(k) & (n-1);
- return x <<s | x>>(n-s);
+ n :: 64
+ s := uint(k) & (n-1)
+ return x <<s | x>>(n-s)
}
rotate_left :: proc(x: uint, k: int) -> uint {
- n :: 8*size_of(uint);
- s := uint(k) & (n-1);
- return x <<s | x>>(n-s);
+ n :: 8*size_of(uint)
+ s := uint(k) & (n-1)
+ return x <<s | x>>(n-s)
}
from_be_u8 :: proc(i: u8) -> u8 { return i; }
@@ -92,205 +92,205 @@ to_le_uint :: proc(i: uint) -> uint { when ODIN_ENDIAN == "little" { return i; }
len_u8 :: proc(x: u8) -> int {
- return int(len_u8_table[x]);
+ return int(len_u8_table[x])
}
len_u16 :: proc(x: u16) -> (n: int) {
- x := x;
+ x := x
if x >= 1<<8 {
- x >>= 8;
- n = 8;
+ x >>= 8
+ n = 8
}
- return n + int(len_u8_table[x]);
+ return n + int(len_u8_table[x])
}
len_u32 :: proc(x: u32) -> (n: int) {
- x := x;
+ x := x
if x >= 1<<16 {
- x >>= 16;
- n = 16;
+ x >>= 16
+ n = 16
}
if x >= 1<<8 {
- x >>= 8;
- n += 8;
+ x >>= 8
+ n += 8
}
- return n + int(len_u8_table[x]);
+ return n + int(len_u8_table[x])
}
len_u64 :: proc(x: u64) -> (n: int) {
- x := x;
+ x := x
if x >= 1<<32 {
- x >>= 32;
- n = 32;
+ x >>= 32
+ n = 32
}
if x >= 1<<16 {
- x >>= 16;
- n += 16;
+ x >>= 16
+ n += 16
}
if x >= 1<<8 {
- x >>= 8;
- n += 8;
+ x >>= 8
+ n += 8
}
- return n + int(len_u8_table[x]);
+ return n + int(len_u8_table[x])
}
len_uint :: proc(x: uint) -> (n: int) {
when size_of(uint) == size_of(u64) {
- return len_u64(u64(x));
+ return len_u64(u64(x))
} else {
- return len_u32(u32(x));
+ return len_u32(u32(x))
}
}
// returns the minimum number of bits required to represent x
-len :: proc{len_u8, len_u16, len_u32, len_u64, len_uint};
+len :: proc{len_u8, len_u16, len_u32, len_u64, len_uint}
add_u32 :: proc(x, y, carry: u32) -> (sum, carry_out: u32) {
- yc := y + carry;
- sum = x + yc;
+ yc := y + carry
+ sum = x + yc
if sum < x || yc < y {
- carry_out = 1;
+ carry_out = 1
}
- return;
+ return
}
add_u64 :: proc(x, y, carry: u64) -> (sum, carry_out: u64) {
- yc := y + carry;
- sum = x + yc;
+ yc := y + carry
+ sum = x + yc
if sum < x || yc < y {
- carry_out = 1;
+ carry_out = 1
}
- return;
+ return
}
add_uint :: proc(x, y, carry: uint) -> (sum, carry_out: uint) {
- yc := y + carry;
- sum = x + yc;
+ yc := y + carry
+ sum = x + yc
if sum < x || yc < y {
- carry_out = 1;
+ carry_out = 1
}
- return;
+ return
}
-add :: proc{add_u32, add_u64, add_uint};
+add :: proc{add_u32, add_u64, add_uint}
sub_u32 :: proc(x, y, borrow: u32) -> (diff, borrow_out: u32) {
- yb := y + borrow;
- diff = x - yb;
+ yb := y + borrow
+ diff = x - yb
if diff > x || yb < y {
- borrow_out = 1;
+ borrow_out = 1
}
- return;
+ return
}
sub_u64 :: proc(x, y, borrow: u64) -> (diff, borrow_out: u64) {
- yb := y + borrow;
- diff = x - yb;
+ yb := y + borrow
+ diff = x - yb
if diff > x || yb < y {
- borrow_out = 1;
+ borrow_out = 1
}
- return;
+ return
}
sub_uint :: proc(x, y, borrow: uint) -> (diff, borrow_out: uint) {
- yb := y + borrow;
- diff = x - yb;
+ yb := y + borrow
+ diff = x - yb
if diff > x || yb < y {
- borrow_out = 1;
+ borrow_out = 1
}
- return;
+ return
}
-sub :: proc{sub_u32, sub_u64, sub_uint};
+sub :: proc{sub_u32, sub_u64, sub_uint}
mul_u32 :: proc(x, y: u32) -> (hi, lo: u32) {
- z := u64(x) * u64(y);
- hi, lo = u32(z>>32), u32(z);
- return;
+ z := u64(x) * u64(y)
+ hi, lo = u32(z>>32), u32(z)
+ return
}
mul_u64 :: proc(x, y: u64) -> (hi, lo: u64) {
- mask :: 1<<32 - 1;
+ mask :: 1<<32 - 1
- x0, x1 := x & mask, x >> 32;
- y0, y1 := y & mask, y >> 32;
+ x0, x1 := x & mask, x >> 32
+ y0, y1 := y & mask, y >> 32
- w0 := x0 * y0;
- t := x1*y0 + w0>>32;
+ w0 := x0 * y0
+ t := x1*y0 + w0>>32
- w1, w2 := t & mask, t >> 32;
- w1 += x0 * y1;
- hi = x1*y1 + w2 + w1>>32;
- lo = x * y;
- return;
+ w1, w2 := t & mask, t >> 32
+ w1 += x0 * y1
+ hi = x1*y1 + w2 + w1>>32
+ lo = x * y
+ return
}
mul_uint :: proc(x, y: uint) -> (hi, lo: uint) {
when size_of(uint) == size_of(u32) {
- a, b := mul_u32(u32(x), u32(y));
+ a, b := mul_u32(u32(x), u32(y))
} else {
#assert(size_of(uint) == size_of(u64));
- a, b := mul_u64(u64(x), u64(y));
+ a, b := mul_u64(u64(x), u64(y))
}
- return uint(a), uint(b);
+ return uint(a), uint(b)
}
-mul :: proc{mul_u32, mul_u64, mul_uint};
+mul :: proc{mul_u32, mul_u64, mul_uint}
div_u32 :: proc(hi, lo, y: u32) -> (quo, rem: u32) {
- assert(y != 0 && y <= hi);
- z := u64(hi)<<32 | u64(lo);
- quo, rem = u32(z/u64(y)), u32(z%u64(y));
- return;
+ assert(y != 0 && y <= hi)
+ z := u64(hi)<<32 | u64(lo)
+ quo, rem = u32(z/u64(y)), u32(z%u64(y))
+ return
}
div_u64 :: proc(hi, lo, y: u64) -> (quo, rem: u64) {
- y := y;
- two32 :: 1 << 32;
- mask32 :: two32 - 1;
+ y := y
+ two32 :: 1 << 32
+ mask32 :: two32 - 1
if y == 0 {
- panic("divide error");
+ panic("divide error")
}
if y <= hi {
- panic("overflow error");
+ panic("overflow error")
}
- s := uint(count_leading_zeros(y));
- y <<= s;
+ s := uint(count_leading_zeros(y))
+ y <<= s
- yn1 := y >> 32;
- yn0 := y & mask32;
- un32 := hi<<s | lo>>(64-s);
- un10 := lo << s;
- un1 := un10 >> 32;
- un0 := un10 & mask32;
- q1 := un32 / yn1;
- rhat := un32 - q1*yn1;
+ yn1 := y >> 32
+ yn0 := y & mask32
+ un32 := hi<<s | lo>>(64-s)
+ un10 := lo << s
+ un1 := un10 >> 32
+ un0 := un10 & mask32
+ q1 := un32 / yn1
+ rhat := un32 - q1*yn1
for q1 >= two32 || q1*yn0 > two32*rhat+un1 {
- q1 -= 1;
- rhat += yn1;
+ q1 -= 1
+ rhat += yn1
if rhat >= two32 {
- break;
+ break
}
}
- un21 := un32*two32 + un1 - q1*y;
- q0 := un21 / yn1;
- rhat = un21 - q0*yn1;
+ un21 := un32*two32 + un1 - q1*y
+ q0 := un21 / yn1
+ rhat = un21 - q0*yn1
for q0 >= two32 || q0*yn0 > two32*rhat+un0 {
- q0 -= 1;
- rhat += yn1;
+ q0 -= 1
+ rhat += yn1
if rhat >= two32 {
- break;
+ break
}
}
- return q1*two32 + q0, (un21*two32 + un0 - q0*y) >> s;
+ return q1*two32 + q0, (un21*two32 + un0 - q0*y) >> s
}
div_uint :: proc(hi, lo, y: uint) -> (quo, rem: uint) {
when size_of(uint) == size_of(u32) {
- a, b := div_u32(u32(hi), u32(lo), u32(y));
+ a, b := div_u32(u32(hi), u32(lo), u32(y))
} else {
#assert(size_of(uint) == size_of(u64));
- a, b := div_u64(u64(hi), u64(lo), u64(y));
+ a, b := div_u64(u64(hi), u64(lo), u64(y))
}
- return uint(a), uint(b);
+ return uint(a), uint(b)
}
-div :: proc{div_u32, div_u64, div_uint};
+div :: proc{div_u32, div_u64, div_uint}
@@ -311,7 +311,7 @@ is_power_of_two :: proc{
is_power_of_two_u32, is_power_of_two_i32,
is_power_of_two_u64, is_power_of_two_i64,
is_power_of_two_uint, is_power_of_two_int,
-};
+}
@private
@@ -325,7 +325,7 @@ len_u8_table := [256]u8{
32..<64 = 6,
64..<128 = 7,
128..<256 = 8,
-};
+}
bitfield_extract_u8 :: proc(value: u8, offset, bits: uint) -> u8 { return (value >> offset) & u8(1<<bits - 1); }
@@ -336,40 +336,40 @@ bitfield_extract_u128 :: proc(value: u128, offset, bits: uint) -> u128 { return
bitfield_extract_uint :: proc(value: uint, offset, bits: uint) -> uint { return (value >> offset) & uint(1<<bits - 1); }
bitfield_extract_i8 :: proc(value: i8, offset, bits: uint) -> i8 {
- v := (u8(value) >> offset) & u8(1<<bits - 1);
- m := u8(1<<(bits-1));
- r := (v~m) - m;
- return i8(r);
+ v := (u8(value) >> offset) & u8(1<<bits - 1)
+ m := u8(1<<(bits-1))
+ r := (v~m) - m
+ return i8(r)
}
bitfield_extract_i16 :: proc(value: i16, offset, bits: uint) -> i16 {
- v := (u16(value) >> offset) & u16(1<<bits - 1);
- m := u16(1<<(bits-1));
- r := (v~m) - m;
- return i16(r);
+ v := (u16(value) >> offset) & u16(1<<bits - 1)
+ m := u16(1<<(bits-1))
+ r := (v~m) - m
+ return i16(r)
}
bitfield_extract_i32 :: proc(value: i32, offset, bits: uint) -> i32 {
- v := (u32(value) >> offset) & u32(1<<bits - 1);
- m := u32(1<<(bits-1));
- r := (v~m) - m;
- return i32(r);
+ v := (u32(value) >> offset) & u32(1<<bits - 1)
+ m := u32(1<<(bits-1))
+ r := (v~m) - m
+ return i32(r)
}
bitfield_extract_i64 :: proc(value: i64, offset, bits: uint) -> i64 {
- v := (u64(value) >> offset) & u64(1<<bits - 1);
- m := u64(1<<(bits-1));
- r := (v~m) - m;
- return i64(r);
+ v := (u64(value) >> offset) & u64(1<<bits - 1)
+ m := u64(1<<(bits-1))
+ r := (v~m) - m
+ return i64(r)
}
bitfield_extract_i128 :: proc(value: i128, offset, bits: uint) -> i128 {
- v := (u128(value) >> offset) & u128(1<<bits - 1);
- m := u128(1<<(bits-1));
- r := (v~m) - m;
- return i128(r);
+ v := (u128(value) >> offset) & u128(1<<bits - 1)
+ m := u128(1<<(bits-1))
+ r := (v~m) - m
+ return i128(r)
}
bitfield_extract_int :: proc(value: int, offset, bits: uint) -> int {
- v := (uint(value) >> offset) & uint(1<<bits - 1);
- m := uint(1<<(bits-1));
- r := (v~m) - m;
- return int(r);
+ v := (uint(value) >> offset) & uint(1<<bits - 1)
+ m := uint(1<<(bits-1))
+ r := (v~m) - m
+ return int(r)
}
@@ -386,57 +386,57 @@ bitfield_extract :: proc{
bitfield_extract_i64,
bitfield_extract_i128,
bitfield_extract_int,
-};
+}
bitfield_insert_u8 :: proc(base, insert: u8, offset, bits: uint) -> u8 {
- mask := u8(1<<bits - 1);
- return (base &~ (mask<<offset)) | ((insert&mask) << offset);
+ mask := u8(1<<bits - 1)
+ return (base &~ (mask<<offset)) | ((insert&mask) << offset)
}
bitfield_insert_u16 :: proc(base, insert: u16, offset, bits: uint) -> u16 {
- mask := u16(1<<bits - 1);
- return (base &~ (mask<<offset)) | ((insert&mask) << offset);
+ mask := u16(1<<bits - 1)
+ return (base &~ (mask<<offset)) | ((insert&mask) << offset)
}
bitfield_insert_u32 :: proc(base, insert: u32, offset, bits: uint) -> u32 {
- mask := u32(1<<bits - 1);
- return (base &~ (mask<<offset)) | ((insert&mask) << offset);
+ mask := u32(1<<bits - 1)
+ return (base &~ (mask<<offset)) | ((insert&mask) << offset)
}
bitfield_insert_u64 :: proc(base, insert: u64, offset, bits: uint) -> u64 {
- mask := u64(1<<bits - 1);
- return (base &~ (mask<<offset)) | ((insert&mask) << offset);
+ mask := u64(1<<bits - 1)
+ return (base &~ (mask<<offset)) | ((insert&mask) << offset)
}
bitfield_insert_u128 :: proc(base, insert: u128, offset, bits: uint) -> u128 {
- mask := u128(1<<bits - 1);
- return (base &~ (mask<<offset)) | ((insert&mask) << offset);
+ mask := u128(1<<bits - 1)
+ return (base &~ (mask<<offset)) | ((insert&mask) << offset)
}
bitfield_insert_uint :: proc(base, insert: uint, offset, bits: uint) -> uint {
- mask := uint(1<<bits - 1);
- return (base &~ (mask<<offset)) | ((insert&mask) << offset);
+ mask := uint(1<<bits - 1)
+ return (base &~ (mask<<offset)) | ((insert&mask) << offset)
}
bitfield_insert_i8 :: proc(base, insert: i8, offset, bits: uint) -> i8 {
- mask := i8(1<<bits - 1);
- return (base &~ (mask<<offset)) | ((insert&mask) << offset);
+ mask := i8(1<<bits - 1)
+ return (base &~ (mask<<offset)) | ((insert&mask) << offset)
}
bitfield_insert_i16 :: proc(base, insert: i16, offset, bits: uint) -> i16 {
- mask := i16(1<<bits - 1);
- return (base &~ (mask<<offset)) | ((insert&mask) << offset);
+ mask := i16(1<<bits - 1)
+ return (base &~ (mask<<offset)) | ((insert&mask) << offset)
}
bitfield_insert_i32 :: proc(base, insert: i32, offset, bits: uint) -> i32 {
- mask := i32(1<<bits - 1);
- return (base &~ (mask<<offset)) | ((insert&mask) << offset);
+ mask := i32(1<<bits - 1)
+ return (base &~ (mask<<offset)) | ((insert&mask) << offset)
}
bitfield_insert_i64 :: proc(base, insert: i64, offset, bits: uint) -> i64 {
- mask := i64(1<<bits - 1);
- return (base &~ (mask<<offset)) | ((insert&mask) << offset);
+ mask := i64(1<<bits - 1)
+ return (base &~ (mask<<offset)) | ((insert&mask) << offset)
}
bitfield_insert_i128 :: proc(base, insert: i128, offset, bits: uint) -> i128 {
- mask := i128(1<<bits - 1);
- return (base &~ (mask<<offset)) | ((insert&mask) << offset);
+ mask := i128(1<<bits - 1)
+ return (base &~ (mask<<offset)) | ((insert&mask) << offset)
}
bitfield_insert_int :: proc(base, insert: int, offset, bits: uint) -> int {
- mask := int(1<<bits - 1);
- return (base &~ (mask<<offset)) | ((insert&mask) << offset);
+ mask := int(1<<bits - 1)
+ return (base &~ (mask<<offset)) | ((insert&mask) << offset)
}
bitfield_insert :: proc{
@@ -452,4 +452,4 @@ bitfield_insert :: proc{
bitfield_insert_i64,
bitfield_insert_i128,
bitfield_insert_int,
-};
+}
diff --git a/core/math/fixed/fixed.odin b/core/math/fixed/fixed.odin
index 6e4709af7..ef97b66d3 100644
--- a/core/math/fixed/fixed.odin
+++ b/core/math/fixed/fixed.odin
@@ -4,7 +4,7 @@ import "core:math"
import "core:strconv"
import "core:intrinsics"
-_ :: intrinsics;
+_ :: intrinsics
Fixed :: struct($Backing: typeid, $Fraction_Width: uint)
where
@@ -14,120 +14,120 @@ Fixed :: struct($Backing: typeid, $Fraction_Width: uint)
i: Backing,
}
-Fixed4_4 :: distinct Fixed(i8, 4);
-Fixed5_3 :: distinct Fixed(i8, 3);
-Fixed6_2 :: distinct Fixed(i8, 2);
-Fixed7_1 :: distinct Fixed(i8, 1);
+Fixed4_4 :: distinct Fixed(i8, 4)
+Fixed5_3 :: distinct Fixed(i8, 3)
+Fixed6_2 :: distinct Fixed(i8, 2)
+Fixed7_1 :: distinct Fixed(i8, 1)
-Fixed8_8 :: distinct Fixed(i16, 8);
-Fixed13_3 :: distinct Fixed(i16, 3);
+Fixed8_8 :: distinct Fixed(i16, 8)
+Fixed13_3 :: distinct Fixed(i16, 3)
-Fixed16_16 :: distinct Fixed(i32, 16);
-Fixed26_6 :: distinct Fixed(i32, 6);
+Fixed16_16 :: distinct Fixed(i32, 16)
+Fixed26_6 :: distinct Fixed(i32, 6)
-Fixed32_32 :: distinct Fixed(i64, 32);
-Fixed52_12 :: distinct Fixed(i64, 12);
+Fixed32_32 :: distinct Fixed(i64, 32)
+Fixed52_12 :: distinct Fixed(i64, 12)
init_from_f64 :: proc(x: ^$T/Fixed($Backing, $Fraction_Width), val: f64) {
- i, f := math.modf(val);
- x.i = Backing(f * (1<<Fraction_Width));
- x.i &= 1<<Fraction_Width - 1;
- x.i |= Backing(i) << Fraction_Width;
+ i, f := math.modf(val)
+ x.i = Backing(f * (1<<Fraction_Width))
+ x.i &= 1<<Fraction_Width - 1
+ x.i |= Backing(i) << Fraction_Width
}
init_from_parts :: proc(x: ^$T/Fixed($Backing, $Fraction_Width), integer, fraction: Backing) {
- i, f := math.modf(val);
- x.i = fraction;
- x.i &= 1<<Fraction_Width - 1;
- x.i |= integer;
+ i, f := math.modf(val)
+ x.i = fraction
+ x.i &= 1<<Fraction_Width - 1
+ x.i |= integer
}
to_f64 :: proc(x: $T/Fixed($Backing, $Fraction_Width)) -> f64 {
- res := f64(x.i >> Fraction_Width);
- res += f64(x.i & (1<<Fraction_Width-1)) / f64(1<<Fraction_Width);
- return res;
+ res := f64(x.i >> Fraction_Width)
+ res += f64(x.i & (1<<Fraction_Width-1)) / f64(1<<Fraction_Width)
+ return res
}
add :: proc(x, y: $T/Fixed) -> T {
- return {x.i + y.i};
+ return {x.i + y.i}
}
sub :: proc(x, y: $T/Fixed) -> T {
- return {x.i - y.i};
+ return {x.i - y.i}
}
mul :: proc(x, y: $T/Fixed($Backing, $Fraction_Width)) -> (z: T) {
- z.i = intrinsics.fixed_point_mul(x.i, y.i, Fraction_Width);
- return;
+ z.i = intrinsics.fixed_point_mul(x.i, y.i, Fraction_Width)
+ return
}
mul_sat :: proc(x, y: $T/Fixed($Backing, $Fraction_Width)) -> (z: T) {
- z.i = intrinsics.fixed_point_mul_sat(x.i, y.i, Fraction_Width);
- return;
+ z.i = intrinsics.fixed_point_mul_sat(x.i, y.i, Fraction_Width)
+ return
}
div :: proc(x, y: $T/Fixed($Backing, $Fraction_Width)) -> (z: T) {
- z.i = intrinsics.fixed_point_div(x.i, y.i, Fraction_Width);
- return;
+ z.i = intrinsics.fixed_point_div(x.i, y.i, Fraction_Width)
+ return
}
div_sat :: proc(x, y: $T/Fixed($Backing, $Fraction_Width)) -> (z: T) {
- z.i = intrinsics.fixed_point_div_sat(x.i, y.i, Fraction_Width);
- return;
+ z.i = intrinsics.fixed_point_div_sat(x.i, y.i, Fraction_Width)
+ return
}
floor :: proc(x: $T/Fixed($Backing, $Fraction_Width)) -> Backing {
- return x.i >> Fraction_Width;
+ return x.i >> Fraction_Width
}
ceil :: proc(x: $T/Fixed($Backing, $Fraction_Width)) -> Backing {
- Integer :: 8*size_of(Backing) - Fraction_Width;
- return (x.i + (1 << Integer-1)) >> Fraction_Width;
+ Integer :: 8*size_of(Backing) - Fraction_Width
+ return (x.i + (1 << Integer-1)) >> Fraction_Width
}
round :: proc(x: $T/Fixed($Backing, $Fraction_Width)) -> Backing {
- Integer :: 8*size_of(Backing) - Fraction_Width;
- return (x.i + (1 << (Integer - 1))) >> Fraction_Width;
+ Integer :: 8*size_of(Backing) - Fraction_Width
+ return (x.i + (1 << (Integer - 1))) >> Fraction_Width
}
append :: proc(dst: []byte, x: $T/Fixed($Backing, $Fraction_Width)) -> string {
- x := x;
- buf: [48]byte;
- i := 0;
+ x := x
+ buf: [48]byte
+ i := 0
if x.i < 0 {
- buf[i] = '-';
- i += 1;
- x.i = -x.i;
+ buf[i] = '-'
+ i += 1
+ x.i = -x.i
}
- integer := x.i >> Fraction_Width;
- fraction := x.i & (1<<Fraction_Width - 1);
+ integer := x.i >> Fraction_Width
+ fraction := x.i & (1<<Fraction_Width - 1)
- s := strconv.append_uint(buf[i:], u64(integer), 10);
- i += len(s);
+ s := strconv.append_uint(buf[i:], u64(integer), 10)
+ i += len(s)
if fraction != 0 {
- buf[i] = '.';
- i += 1;
+ buf[i] = '.'
+ i += 1
for fraction > 0 {
- fraction *= 10;
- buf[i] = byte('0' + (fraction>>Fraction_Width));
- i += 1;
- fraction &= 1<<Fraction_Width - 1;
+ fraction *= 10
+ buf[i] = byte('0' + (fraction>>Fraction_Width))
+ i += 1
+ fraction &= 1<<Fraction_Width - 1
}
}
- n := copy(dst, buf[:i]);
- return string(dst[:i]);
+ n := copy(dst, buf[:i])
+ return string(dst[:i])
}
to_string :: proc(x: $T/Fixed($Backing, $Fraction_Width), allocator := context.allocator) -> string {
- buf: [48]byte;
- s := append(buf[:], x);
- str := make([]byte, len(s), allocator);
- copy(str, s);
- return string(str);
+ buf: [48]byte
+ s := append(buf[:], x)
+ str := make([]byte, len(s), allocator)
+ copy(str, s)
+ return string(str)
}
diff --git a/core/math/linalg/extended.odin b/core/math/linalg/extended.odin
index 373a4e4ce..8f7b2dd1e 100644
--- a/core/math/linalg/extended.odin
+++ b/core/math/linalg/extended.odin
@@ -6,476 +6,476 @@ import "core:math"
radians :: proc(degrees: $T) -> (out: T) where IS_NUMERIC(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
for i in 0..<len(T) {
- out[i] = degrees * RAD_PER_DEG;
+ out[i] = degrees * RAD_PER_DEG
}
} else {
- out = degrees * RAD_PER_DEG;
+ out = degrees * RAD_PER_DEG
}
- return;
+ return
}
degrees :: proc(radians: $T) -> (out: T) where IS_NUMERIC(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
for i in 0..<len(T) {
- out[i] = radians * DEG_PER_RAD;
+ out[i] = radians * DEG_PER_RAD
}
} else {
- out = radians * DEG_PER_RAD;
+ out = radians * DEG_PER_RAD
}
- return;
+ return
}
min_double :: proc(a, b: $T) -> (out: T) where IS_NUMERIC(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
for i in 0..<len(T) {
- out[i] = builtin.min(a[i], b[i]);
+ out[i] = builtin.min(a[i], b[i])
}
} else {
- out = builtin.min(a, b);
+ out = builtin.min(a, b)
}
- return;
+ return
}
min_single :: proc(a: $T) -> (out: ELEM_TYPE(T)) where IS_NUMERIC(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
- N :: len(T);
+ N :: len(T)
when N == 1 {
- out = a[0];
+ out = a[0]
} else when N == 2 {
- out = builtin.min(a[0], a[1]);
+ out = builtin.min(a[0], a[1])
} else {
- out = builtin.min(a[0], a[1]);
+ out = builtin.min(a[0], a[1])
for i in 2..<N {
- out = builtin.min(out, a[i]);
+ out = builtin.min(out, a[i])
}
}
} else {
- out = a;
+ out = a
}
- return;
+ return
}
min_triple :: proc(a, b, c: $T) -> T where IS_NUMERIC(ELEM_TYPE(T)) {
- return min_double(a, min_double(b, c));
+ return min_double(a, min_double(b, c))
}
-min :: proc{min_single, min_double, min_triple};
+min :: proc{min_single, min_double, min_triple}
max_double :: proc(a, b: $T) -> (out: T) where IS_NUMERIC(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
for i in 0..<len(T) {
- out[i] = builtin.max(a[i], b[i]);
+ out[i] = builtin.max(a[i], b[i])
}
} else {
- out = builtin.max(a, b);
+ out = builtin.max(a, b)
}
- return;
+ return
}
max_single :: proc(a: $T) -> (out: ELEM_TYPE(T)) where IS_NUMERIC(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
- N :: len(T);
+ N :: len(T)
when N == 1 {
- out = a[0];
+ out = a[0]
} else when N == 2 {
- out = builtin.max(a[0], a[1]);
+ out = builtin.max(a[0], a[1])
} else when N == 3 {
- out = builtin.max(a[0], a[1], a[3]);
+ out = builtin.max(a[0], a[1], a[3])
}else {
- out = builtin.max(a[0], a[1]);
+ out = builtin.max(a[0], a[1])
for i in 2..<N {
- out = builtin.max(out, a[i]);
+ out = builtin.max(out, a[i])
}
}
} else {
- out = a;
+ out = a
}
- return;
+ return
}
max_triple :: proc(a, b, c: $T) -> T where IS_NUMERIC(ELEM_TYPE(T)) {
- return max_double(a, max_double(b, c));
+ return max_double(a, max_double(b, c))
}
-max :: proc{max_single, max_double, max_triple};
+max :: proc{max_single, max_double, max_triple}
abs :: proc(a: $T) -> (out: T) where IS_NUMERIC(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
for i in 0..<len(T) {
- out[i] = builtin.abs(a[i]);
+ out[i] = builtin.abs(a[i])
}
} else {
- out = builtin.abs(a);
+ out = builtin.abs(a)
}
- return;
+ return
}
sign :: proc(a: $T) -> (out: T) where IS_NUMERIC(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
for i in 0..<len(T) {
- out[i] = #force_inline math.sign(a[i]);
+ out[i] = #force_inline math.sign(a[i])
}
} else {
- out = #force_inline math.sign(a);
+ out = #force_inline math.sign(a)
}
- return;
+ return
}
clamp :: proc(x, a, b: $T) -> (out: T) where IS_NUMERIC(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
for i in 0..<len(T) {
- out[i] = builtin.clamp(x[i], a[i], b[i]);
+ out[i] = builtin.clamp(x[i], a[i], b[i])
}
} else {
- out = builtin.clamp(x, a, b);
+ out = builtin.clamp(x, a, b)
}
- return;
+ return
}
saturate :: proc(x: $T) -> T where IS_FLOAT(ELEM_TYPE(T)) {
- return clamp(x, 0.0, 1.0);
+ return clamp(x, 0.0, 1.0)
}
lerp :: proc(a, b, t: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
for i in 0..<len(T) {
- out[i] = a[i]*(1-t[i]) + b[i]*t[i];
+ out[i] = a[i]*(1-t[i]) + b[i]*t[i]
}
} else {
- out = a * (1.0 - t) + b * t;
+ out = a * (1.0 - t) + b * t
}
- return;
+ return
}
mix :: proc(a, b, t: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
for i in 0..<len(T) {
- out[i] = a[i]*(1-t[i]) + b[i]*t[i];
+ out[i] = a[i]*(1-t[i]) + b[i]*t[i]
}
} else {
- out = a * (1.0 - t) + b * t;
+ out = a * (1.0 - t) + b * t
}
- return;
+ return
}
unlerp :: proc(a, b, x: $T) -> T where IS_FLOAT(ELEM_TYPE(T)) {
- return (x - a) / (b - a);
+ return (x - a) / (b - a)
}
step :: proc(e, x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
for i in 0..<len(T) {
- out[i] = x[i] < e[i] ? 0.0 : 1.0;
+ out[i] = x[i] < e[i] ? 0.0 : 1.0
}
} else {
- out = x < e ? 0.0 : 1.0;
+ out = x < e ? 0.0 : 1.0
}
- return;
+ return
}
smoothstep :: proc(e0, e1, x: $T) -> T where IS_FLOAT(ELEM_TYPE(T)) {
- t := saturate(unlerp(e0, e1, x));
- return t * t * (3.0 - 2.0 * t);
+ t := saturate(unlerp(e0, e1, x))
+ return t * t * (3.0 - 2.0 * t)
}
smootherstep :: proc(e0, e1, x: $T) -> T where IS_FLOAT(ELEM_TYPE(T)) {
- t := saturate(unlerp(e0, e1, x));
- return t * t * t * (t * (6*t - 15) + 10);
+ t := saturate(unlerp(e0, e1, x))
+ return t * t * t * (t * (6*t - 15) + 10)
}
sqrt :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
for i in 0..<len(T) {
- out[i] = math.sqrt(x[i]);
+ out[i] = math.sqrt(x[i])
}
} else {
- out = math.sqrt(x);
+ out = math.sqrt(x)
}
- return;
+ return
}
inverse_sqrt :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
for i in 0..<len(T) {
- out[i] = 1.0/math.sqrt(x[i]);
+ out[i] = 1.0/math.sqrt(x[i])
}
} else {
- out = 1.0/math.sqrt(x);
+ out = 1.0/math.sqrt(x)
}
- return;
+ return
}
cos :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
for i in 0..<len(T) {
- out[i] = math.cos(x[i]);
+ out[i] = math.cos(x[i])
}
} else {
- out = math.cos(x);
+ out = math.cos(x)
}
- return;
+ return
}
sin :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
for i in 0..<len(T) {
- out[i] = math.sin(x[i]);
+ out[i] = math.sin(x[i])
}
} else {
- out = math.sin(x);
+ out = math.sin(x)
}
- return;
+ return
}
tan :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
for i in 0..<len(T) {
- out[i] = math.tan(x[i]);
+ out[i] = math.tan(x[i])
}
} else {
- out = math.tan(x);
+ out = math.tan(x)
}
- return;
+ return
}
acos :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
for i in 0..<len(T) {
- out[i] = math.acos(x[i]);
+ out[i] = math.acos(x[i])
}
} else {
- out = math.acos(x);
+ out = math.acos(x)
}
- return;
+ return
}
asin :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
for i in 0..<len(T) {
- out[i] = math.asin(x[i]);
+ out[i] = math.asin(x[i])
}
} else {
- out = math.asin(x);
+ out = math.asin(x)
}
- return;
+ return
}
atan :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
for i in 0..<len(T) {
- out[i] = math.atan(x[i]);
+ out[i] = math.atan(x[i])
}
} else {
- out = math.atan(x);
+ out = math.atan(x)
}
- return;
+ return
}
atan2 :: proc(y, x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
for i in 0..<len(T) {
- out[i] = math.atan2(y[i], x[i]);
+ out[i] = math.atan2(y[i], x[i])
}
} else {
- out = math.atan2(y, x);
+ out = math.atan2(y, x)
}
- return;
+ return
}
ln :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
for i in 0..<len(T) {
- out[i] = math.ln(x[i]);
+ out[i] = math.ln(x[i])
}
} else {
- out = math.ln(x);
+ out = math.ln(x)
}
- return;
+ return
}
log2 :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
for i in 0..<len(T) {
- out[i] = INVLN2 * math.ln(x[i]);
+ out[i] = INVLN2 * math.ln(x[i])
}
} else {
- out = INVLN2 * math.ln(x);
+ out = INVLN2 * math.ln(x)
}
- return;
+ return
}
log10 :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
for i in 0..<len(T) {
- out[i] = INVLN10 * math.ln(x[i]);
+ out[i] = INVLN10 * math.ln(x[i])
}
} else {
- out = INVLN10 * math.ln(x);
+ out = INVLN10 * math.ln(x)
}
- return;
+ return
}
log :: proc(x, b: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
for i in 0..<len(T) {
- out[i] = math.ln(x[i]) / math.ln(cast(ELEM_TYPE(T))b[i]);
+ out[i] = math.ln(x[i]) / math.ln(cast(ELEM_TYPE(T))b[i])
}
} else {
- out = INVLN10 * math.ln(x) / math.ln(cast(ELEM_TYPE(T))b);
+ out = INVLN10 * math.ln(x) / math.ln(cast(ELEM_TYPE(T))b)
}
- return;
+ return
}
exp :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
for i in 0..<len(T) {
- out[i] = math.exp(x[i]);
+ out[i] = math.exp(x[i])
}
} else {
- out = math.exp(x);
+ out = math.exp(x)
}
- return;
+ return
}
exp2 :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
for i in 0..<len(T) {
- out[i] = math.exp(LN2 * x[i]);
+ out[i] = math.exp(LN2 * x[i])
}
} else {
- out = math.exp(LN2 * x);
+ out = math.exp(LN2 * x)
}
- return;
+ return
}
exp10 :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
for i in 0..<len(T) {
- out[i] = math.exp(LN10 * x[i]);
+ out[i] = math.exp(LN10 * x[i])
}
} else {
- out = math.exp(LN10 * x);
+ out = math.exp(LN10 * x)
}
- return;
+ return
}
pow :: proc(x, e: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
for i in 0..<len(T) {
- out[i] = math.pow(x[i], e[i]);
+ out[i] = math.pow(x[i], e[i])
}
} else {
- out = math.pow(x, e);
+ out = math.pow(x, e)
}
- return;
+ return
}
ceil :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
for i in 0..<len(T) {
- out[i] = #force_inline math.ceil(x[i]);
+ out[i] = #force_inline math.ceil(x[i])
}
} else {
- out = #force_inline math.ceil(x);
+ out = #force_inline math.ceil(x)
}
- return;
+ return
}
floor :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
for i in 0..<len(T) {
- out[i] = #force_inline math.floor(x[i]);
+ out[i] = #force_inline math.floor(x[i])
}
} else {
- out = #force_inline math.floor(x);
+ out = #force_inline math.floor(x)
}
- return;
+ return
}
round :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
for i in 0..<len(T) {
- out[i] = #force_inline math.round(x[i]);
+ out[i] = #force_inline math.round(x[i])
}
} else {
- out = #force_inline math.round(x);
+ out = #force_inline math.round(x)
}
- return;
+ return
}
fract :: proc(x: $T) -> T where IS_FLOAT(ELEM_TYPE(T)) {
- f := #force_inline floor(x);
- return x - f;
+ f := #force_inline floor(x)
+ return x - f
}
mod :: proc(x, m: $T) -> T where IS_FLOAT(ELEM_TYPE(T)) {
- f := #force_inline floor(x / m);
- return x - f * m;
+ f := #force_inline floor(x / m)
+ return x - f * m
}
face_forward :: proc(N, I, N_ref: $T) -> (out: T) where IS_ARRAY(T), IS_FLOAT(ELEM_TYPE(T)) {
- return dot(N_ref, I) < 0 ? N : -N;
+ return dot(N_ref, I) < 0 ? N : -N
}
distance :: proc(p0, p1: $V/[$N]$E) -> E where IS_NUMERIC(E) {
- return length(p1 - p0);
+ return length(p1 - p0)
}
reflect :: proc(I, N: $T) -> (out: T) where IS_ARRAY(T), IS_FLOAT(ELEM_TYPE(T)) {
- b := n * (2 * dot(n, i));
- return i - b;
+ b := n * (2 * dot(n, i))
+ return i - b
}
refract :: proc(I, N: $T) -> (out: T) where IS_ARRAY(T), IS_FLOAT(ELEM_TYPE(T)) {
- dv := dot(n, i);
- k := 1 - eta*eta - (1 - dv*dv);
- a := i * eta;
- b := n * eta*dv*math.sqrt(k);
- return (a - b) * E(int(k >= 0));
+ dv := dot(n, i)
+ k := 1 - eta*eta - (1 - dv*dv)
+ a := i * eta
+ b := n * eta*dv*math.sqrt(k)
+ return (a - b) * E(int(k >= 0))
}
is_nan_single :: proc(x: $T) -> bool where IS_FLOAT(T) {
- return #force_inline math.is_nan(x);
+ return #force_inline math.is_nan(x)
}
is_nan_array :: proc(x: $A/[$N]$T) -> (out: [N]bool) where IS_FLOAT(T) {
for i in 0..<N {
- out[i] = #force_inline is_nan(x[i]);
+ out[i] = #force_inline is_nan(x[i])
}
- return;
+ return
}
is_inf_single :: proc(x: $T) -> bool where IS_FLOAT(T) {
- return #force_inline math.is_inf(x);
+ return #force_inline math.is_inf(x)
}
is_inf_array :: proc(x: $A/[$N]$T) -> (out: [N]bool) where IS_FLOAT(T) {
for i in 0..<N {
- out[i] = #force_inline is_inf(x[i]);
+ out[i] = #force_inline is_inf(x[i])
}
- return;
+ return
}
classify_single :: proc(x: $T) -> math.Float_Class where IS_FLOAT(T) {
- return #force_inline math.classify(x);
+ return #force_inline math.classify(x)
}
classify_array :: proc(x: $A/[$N]$T) -> (out: [N]math.Float_Class) where IS_FLOAT(T) {
for i in 0..<N {
- out[i] = #force_inline classify_single(x[i]);
+ out[i] = #force_inline classify_single(x[i])
}
- return;
+ return
}
-is_nan :: proc{is_nan_single, is_nan_array};
-is_inf :: proc{is_inf_single, is_inf_array};
-classify :: proc{classify_single, classify_array};
+is_nan :: proc{is_nan_single, is_nan_array}
+is_inf :: proc{is_inf_single, is_inf_array}
+classify :: proc{classify_single, classify_array}
less_than_single :: proc(x, y: $T) -> (out: bool) where !IS_ARRAY(T), IS_FLOAT(T) { return x < y; }
@@ -487,67 +487,67 @@ not_equal_single :: proc(x, y: $T) -> (out: bool) where !IS_ARRAY(T), I
less_than_array :: proc(x, y: $A/[$N]$T) -> (out: [N]bool) where IS_ARRAY(A), IS_FLOAT(ELEM_TYPE(A)) {
for i in 0..<N {
- out[i] = x[i] < y[i];
+ out[i] = x[i] < y[i]
}
- return;
+ return
}
less_than_equal_array :: proc(x, y: $A/[$N]$T) -> (out: [N]bool) where IS_ARRAY(A), IS_FLOAT(ELEM_TYPE(A)) {
for i in 0..<N {
- out[i] = x[i] <= y[i];
+ out[i] = x[i] <= y[i]
}
- return;
+ return
}
greater_than_array :: proc(x, y: $A/[$N]$T) -> (out: [N]bool) where IS_ARRAY(A), IS_FLOAT(ELEM_TYPE(A)) {
for i in 0..<N {
- out[i] = x[i] > y[i];
+ out[i] = x[i] > y[i]
}
- return;
+ return
}
greater_than_equal_array :: proc(x, y: $A/[$N]$T) -> (out: [N]bool) where IS_ARRAY(A), IS_FLOAT(ELEM_TYPE(A)) {
for i in 0..<N {
- out[i] = x[i] >= y[i];
+ out[i] = x[i] >= y[i]
}
- return;
+ return
}
equal_array :: proc(x, y: $A/[$N]$T) -> (out: [N]bool) where IS_ARRAY(A), IS_FLOAT(ELEM_TYPE(A)) {
for i in 0..<N {
- out[i] = x[i] == y[i];
+ out[i] = x[i] == y[i]
}
- return;
+ return
}
not_equal_array :: proc(x, y: $A/[$N]$T) -> (out: [N]bool) where IS_ARRAY(A), IS_FLOAT(ELEM_TYPE(A)) {
for i in 0..<N {
- out[i] = x[i] != y[i];
+ out[i] = x[i] != y[i]
}
- return;
+ return
}
-less_than :: proc{less_than_single, less_than_array};
-less_than_equal :: proc{less_than_equal_single, less_than_equal_array};
-greater_than :: proc{greater_than_single, greater_than_array};
-greater_than_equal :: proc{greater_than_equal_single, greater_than_equal_array};
-equal :: proc{equal_single, equal_array};
-not_equal :: proc{not_equal_single, not_equal_array};
+less_than :: proc{less_than_single, less_than_array}
+less_than_equal :: proc{less_than_equal_single, less_than_equal_array}
+greater_than :: proc{greater_than_single, greater_than_array}
+greater_than_equal :: proc{greater_than_equal_single, greater_than_equal_array}
+equal :: proc{equal_single, equal_array}
+not_equal :: proc{not_equal_single, not_equal_array}
any :: proc(x: $A/[$N]bool) -> (out: bool) {
for e in x {
if x {
- return true;
+ return true
}
}
- return false;
+ return false
}
all :: proc(x: $A/[$N]bool) -> (out: bool) {
for e in x {
if !e {
- return false;
+ return false
}
}
- return true;
+ return true
}
not :: proc(x: $A/[$N]bool) -> (out: A) {
for e, i in x {
- out[i] = !e;
+ out[i] = !e
}
- return;
+ return
}
diff --git a/core/math/linalg/general.odin b/core/math/linalg/general.odin
index a053b75fd..241a50f28 100644
--- a/core/math/linalg/general.odin
+++ b/core/math/linalg/general.odin
@@ -5,178 +5,178 @@ import "core:intrinsics"
// Generic
-TAU :: 6.28318530717958647692528676655900576;
-PI :: 3.14159265358979323846264338327950288;
+TAU :: 6.28318530717958647692528676655900576
+PI :: 3.14159265358979323846264338327950288
-E :: 2.71828182845904523536;
+E :: 2.71828182845904523536
-Ï„ :: TAU;
-Ï€ :: PI;
-e :: E;
+Ï„ :: TAU
+Ï€ :: PI
+e :: E
-SQRT_TWO :: 1.41421356237309504880168872420969808;
-SQRT_THREE :: 1.73205080756887729352744634150587236;
-SQRT_FIVE :: 2.23606797749978969640917366873127623;
+SQRT_TWO :: 1.41421356237309504880168872420969808
+SQRT_THREE :: 1.73205080756887729352744634150587236
+SQRT_FIVE :: 2.23606797749978969640917366873127623
-LN2 :: 0.693147180559945309417232121458176568;
-LN10 :: 2.30258509299404568401799145468436421;
+LN2 :: 0.693147180559945309417232121458176568
+LN10 :: 2.30258509299404568401799145468436421
-MAX_F64_PRECISION :: 16; // Maximum number of meaningful digits after the decimal point for 'f64'
-MAX_F32_PRECISION :: 8; // Maximum number of meaningful digits after the decimal point for 'f32'
+MAX_F64_PRECISION :: 16 // Maximum number of meaningful digits after the decimal point for 'f64'
+MAX_F32_PRECISION :: 8 // Maximum number of meaningful digits after the decimal point for 'f32'
-RAD_PER_DEG :: TAU/360.0;
-DEG_PER_RAD :: 360.0/TAU;
+RAD_PER_DEG :: TAU/360.0
+DEG_PER_RAD :: 360.0/TAU
-@private IS_NUMERIC :: intrinsics.type_is_numeric;
-@private IS_QUATERNION :: intrinsics.type_is_quaternion;
-@private IS_ARRAY :: intrinsics.type_is_array;
-@private IS_FLOAT :: intrinsics.type_is_float;
-@private BASE_TYPE :: intrinsics.type_base_type;
-@private ELEM_TYPE :: intrinsics.type_elem_type;
+@private IS_NUMERIC :: intrinsics.type_is_numeric
+@private IS_QUATERNION :: intrinsics.type_is_quaternion
+@private IS_ARRAY :: intrinsics.type_is_array
+@private IS_FLOAT :: intrinsics.type_is_float
+@private BASE_TYPE :: intrinsics.type_base_type
+@private ELEM_TYPE :: intrinsics.type_elem_type
scalar_dot :: proc(a, b: $T) -> T where IS_FLOAT(T), !IS_ARRAY(T) {
- return a * b;
+ return a * b
}
vector_dot :: proc(a, b: $T/[$N]$E) -> (c: E) where IS_NUMERIC(E) #no_bounds_check {
for i in 0..<N {
- c += a[i] * b[i];
+ c += a[i] * b[i]
}
- return;
+ return
}
quaternion64_dot :: proc(a, b: $T/quaternion64) -> (c: f16) {
- return a.w*a.w + a.x*b.x + a.y*b.y + a.z*b.z;
+ return a.w*a.w + a.x*b.x + a.y*b.y + a.z*b.z
}
quaternion128_dot :: proc(a, b: $T/quaternion128) -> (c: f32) {
- return a.w*a.w + a.x*b.x + a.y*b.y + a.z*b.z;
+ return a.w*a.w + a.x*b.x + a.y*b.y + a.z*b.z
}
quaternion256_dot :: proc(a, b: $T/quaternion256) -> (c: f64) {
- return a.w*a.w + a.x*b.x + a.y*b.y + a.z*b.z;
+ return a.w*a.w + a.x*b.x + a.y*b.y + a.z*b.z
}
-dot :: proc{scalar_dot, vector_dot, quaternion64_dot, quaternion128_dot, quaternion256_dot};
+dot :: proc{scalar_dot, vector_dot, quaternion64_dot, quaternion128_dot, quaternion256_dot}
-inner_product :: dot;
+inner_product :: dot
outer_product :: proc(a: $A/[$M]$E, b: $B/[$N]E) -> (out: [M][N]E) where IS_NUMERIC(E) #no_bounds_check {
for i in 0..<M {
for j in 0..<N {
- out[i][j] = a[i]*b[j];
+ out[i][j] = a[i]*b[j]
}
}
- return;
+ return
}
quaternion_inverse :: proc(q: $Q) -> Q where IS_QUATERNION(Q) {
- return conj(q) * quaternion(1.0/dot(q, q), 0, 0, 0);
+ return conj(q) * quaternion(1.0/dot(q, q), 0, 0, 0)
}
scalar_cross :: proc(a, b: $T) -> T where IS_FLOAT(T), !IS_ARRAY(T) {
- return a * b;
+ return a * b
}
vector_cross2 :: proc(a, b: $T/[2]$E) -> E where IS_NUMERIC(E) {
- return a[0]*b[1] - b[0]*a[1];
+ return a[0]*b[1] - b[0]*a[1]
}
vector_cross3 :: proc(a, b: $T/[3]$E) -> (c: T) where IS_NUMERIC(E) {
- c[0] = a[1]*b[2] - b[1]*a[2];
- c[1] = a[2]*b[0] - b[2]*a[0];
- c[2] = a[0]*b[1] - b[0]*a[1];
- return;
+ c[0] = a[1]*b[2] - b[1]*a[2]
+ c[1] = a[2]*b[0] - b[2]*a[0]
+ c[2] = a[0]*b[1] - b[0]*a[1]
+ return
}
quaternion_cross :: proc(q1, q2: $Q) -> (q3: Q) where IS_QUATERNION(Q) {
- q3.x = q1.w * q2.x + q1.x * q2.w + q1.y * q2.z - q1.z * q2.y;
- q3.y = q1.w * q2.y + q1.y * q2.w + q1.z * q2.x - q1.x * q2.z;
- q3.z = q1.w * q2.z + q1.z * q2.w + q1.x * q2.y - q1.y * q2.x;
- q3.w = q1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z;
- return;
+ q3.x = q1.w * q2.x + q1.x * q2.w + q1.y * q2.z - q1.z * q2.y
+ q3.y = q1.w * q2.y + q1.y * q2.w + q1.z * q2.x - q1.x * q2.z
+ q3.z = q1.w * q2.z + q1.z * q2.w + q1.x * q2.y - q1.y * q2.x
+ q3.w = q1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z
+ return
}
-vector_cross :: proc{scalar_cross, vector_cross2, vector_cross3};
-cross :: proc{scalar_cross, vector_cross2, vector_cross3, quaternion_cross};
+vector_cross :: proc{scalar_cross, vector_cross2, vector_cross3}
+cross :: proc{scalar_cross, vector_cross2, vector_cross3, quaternion_cross}
vector_normalize :: proc(v: $T/[$N]$E) -> T where IS_NUMERIC(E) {
- return v / length(v);
+ return v / length(v)
}
quaternion_normalize :: proc(q: $Q) -> Q where IS_QUATERNION(Q) {
- return q/abs(q);
+ return q/abs(q)
}
-normalize :: proc{vector_normalize, quaternion_normalize};
+normalize :: proc{vector_normalize, quaternion_normalize}
vector_normalize0 :: proc(v: $T/[$N]$E) -> T where IS_NUMERIC(E) {
- m := length(v);
- return 0 if m == 0 else v/m;
+ m := length(v)
+ return 0 if m == 0 else v/m
}
quaternion_normalize0 :: proc(q: $Q) -> Q where IS_QUATERNION(Q) {
- m := abs(q);
- return 0 if m == 0 else q/m;
+ m := abs(q)
+ return 0 if m == 0 else q/m
}
-normalize0 :: proc{vector_normalize0, quaternion_normalize0};
+normalize0 :: proc{vector_normalize0, quaternion_normalize0}
vector_length :: proc(v: $T/[$N]$E) -> E where IS_NUMERIC(E) {
- return math.sqrt(dot(v, v));
+ return math.sqrt(dot(v, v))
}
vector_length2 :: proc(v: $T/[$N]$E) -> E where IS_NUMERIC(E) {
- return dot(v, v);
+ return dot(v, v)
}
quaternion_length :: proc(q: $Q) -> Q where IS_QUATERNION(Q) {
- return abs(q);
+ return abs(q)
}
quaternion_length2 :: proc(q: $Q) -> Q where IS_QUATERNION(Q) {
- return dot(q, q);
+ return dot(q, q)
}
scalar_triple_product :: proc(a, b, c: $T/[$N]$E) -> E where IS_NUMERIC(E) {
// a . (b x c)
// b . (c x a)
// c . (a x b)
- return dot(a, cross(b, c));
+ return dot(a, cross(b, c))
}
vector_triple_product :: proc(a, b, c: $T/[$N]$E) -> T where IS_NUMERIC(E) {
// a x (b x c)
// (a . c)b - (a . b)c
- return cross(a, cross(b, c));
+ return cross(a, cross(b, c))
}
-length :: proc{vector_length, quaternion_length};
-length2 :: proc{vector_length2, quaternion_length2};
+length :: proc{vector_length, quaternion_length}
+length2 :: proc{vector_length2, quaternion_length2}
projection :: proc(x, normal: $T/[$N]$E) -> T where IS_NUMERIC(E) {
- return dot(x, normal) / dot(normal, normal) * normal;
+ return dot(x, normal) / dot(normal, normal) * normal
}
identity :: proc($T: typeid/[$N][N]$E) -> (m: T) #no_bounds_check {
for i in 0..<N {
- m[i][i] = E(1);
+ m[i][i] = E(1)
}
- return m;
+ return m
}
trace :: proc(m: $T/[$N][N]$E) -> (tr: E) {
for i in 0..<N {
- tr += m[i][i];
+ tr += m[i][i]
}
- return;
+ return
}
transpose :: proc(a: $T/[$N][$M]$E) -> (m: (T when N == M else [M][N]E)) #no_bounds_check {
for j in 0..<M {
for i in 0..<N {
- m[j][i] = a[i][j];
+ m[j][i] = a[i][j]
}
}
- return;
+ return
}
matrix_mul :: proc(a, b: $M/[$N][N]$E) -> (c: M)
@@ -184,21 +184,21 @@ matrix_mul :: proc(a, b: $M/[$N][N]$E) -> (c: M)
for i in 0..<N {
for k in 0..<N {
for j in 0..<N {
- c[k][i] += a[j][i] * b[k][j];
+ c[k][i] += a[j][i] * b[k][j]
}
}
}
- return;
+ return
}
matrix_comp_mul :: proc(a, b: $M/[$J][$I]$E) -> (c: M)
where !IS_ARRAY(E), IS_NUMERIC(E) #no_bounds_check {
for j in 0..<J {
for i in 0..<I {
- c[j][i] = a[j][i] * b[j][i];
+ c[j][i] = a[j][i] * b[j][i]
}
}
- return;
+ return
}
matrix_mul_differ :: proc(a: $A/[$J][$I]$E, b: $B/[$K][J]E) -> (c: [K][I]E)
@@ -206,11 +206,11 @@ matrix_mul_differ :: proc(a: $A/[$J][$I]$E, b: $B/[$K][J]E) -> (c: [K][I]E)
for k in 0..<K {
for j in 0..<J {
for i in 0..<I {
- c[k][i] += a[j][i] * b[k][j];
+ c[k][i] += a[j][i] * b[k][j]
}
}
}
- return;
+ return
}
@@ -218,44 +218,44 @@ matrix_mul_vector :: proc(a: $A/[$I][$J]$E, b: $B/[I]E) -> (c: B)
where !IS_ARRAY(E), IS_NUMERIC(E) #no_bounds_check {
for i in 0..<I {
for j in 0..<J {
- c[j] += a[i][j] * b[i];
+ c[j] += a[i][j] * b[i]
}
}
- return;
+ return
}
quaternion_mul_quaternion :: proc(q1, q2: $Q) -> Q where IS_QUATERNION(Q) {
- return q1 * q2;
+ return q1 * q2
}
quaternion64_mul_vector3 :: proc(q: $Q/quaternion64, v: $V/[3]$F/f16) -> V {
- Raw_Quaternion :: struct {xyz: [3]f16, r: f16};
+ Raw_Quaternion :: struct {xyz: [3]f16, r: f16}
- q := transmute(Raw_Quaternion)q;
- v := transmute([3]f16)v;
+ q := transmute(Raw_Quaternion)q
+ v := transmute([3]f16)v
- t := cross(2*q.xyz, v);
- return V(v + q.r*t + cross(q.xyz, t));
+ t := cross(2*q.xyz, v)
+ return V(v + q.r*t + cross(q.xyz, t))
}
quaternion128_mul_vector3 :: proc(q: $Q/quaternion128, v: $V/[3]$F/f32) -> V {
- Raw_Quaternion :: struct {xyz: [3]f32, r: f32};
+ Raw_Quaternion :: struct {xyz: [3]f32, r: f32}
- q := transmute(Raw_Quaternion)q;
- v := transmute([3]f32)v;
+ q := transmute(Raw_Quaternion)q
+ v := transmute([3]f32)v
- t := cross(2*q.xyz, v);
- return V(v + q.r*t + cross(q.xyz, t));
+ t := cross(2*q.xyz, v)
+ return V(v + q.r*t + cross(q.xyz, t))
}
quaternion256_mul_vector3 :: proc(q: $Q/quaternion256, v: $V/[3]$F/f64) -> V {
- Raw_Quaternion :: struct {xyz: [3]f64, r: f64};
+ Raw_Quaternion :: struct {xyz: [3]f64, r: f64}
- q := transmute(Raw_Quaternion)q;
- v := transmute([3]f64)v;
+ q := transmute(Raw_Quaternion)q
+ v := transmute([3]f64)v
- t := cross(2*q.xyz, v);
- return V(v + q.r*t + cross(q.xyz, t));
+ t := cross(2*q.xyz, v)
+ return V(v + q.r*t + cross(q.xyz, t))
}
-quaternion_mul_vector3 :: proc{quaternion64_mul_vector3, quaternion128_mul_vector3, quaternion256_mul_vector3};
+quaternion_mul_vector3 :: proc{quaternion64_mul_vector3, quaternion128_mul_vector3, quaternion256_mul_vector3}
mul :: proc{
matrix_mul,
@@ -265,16 +265,16 @@ mul :: proc{
quaternion128_mul_vector3,
quaternion256_mul_vector3,
quaternion_mul_quaternion,
-};
+}
vector_to_ptr :: proc(v: ^$V/[$N]$E) -> ^E where IS_NUMERIC(E), N > 0 #no_bounds_check {
- return &v[0];
+ return &v[0]
}
matrix_to_ptr :: proc(m: ^$A/[$I][$J]$E) -> ^E where IS_NUMERIC(E), I > 0, J > 0 #no_bounds_check {
- return &m[0][0];
+ return &m[0][0]
}
-to_ptr :: proc{vector_to_ptr, matrix_to_ptr};
+to_ptr :: proc{vector_to_ptr, matrix_to_ptr}
@@ -283,60 +283,60 @@ to_ptr :: proc{vector_to_ptr, matrix_to_ptr};
// Splines
vector_slerp :: proc(x, y: $T/[$N]$E, a: E) -> T {
- cos_alpha := dot(x, y);
- alpha := math.acos(cos_alpha);
- sin_alpha := math.sin(alpha);
+ cos_alpha := dot(x, y)
+ alpha := math.acos(cos_alpha)
+ sin_alpha := math.sin(alpha)
- t1 := math.sin((1 - a) * alpha) / sin_alpha;
- t2 := math.sin(a * alpha) / sin_alpha;
+ t1 := math.sin((1 - a) * alpha) / sin_alpha
+ t2 := math.sin(a * alpha) / sin_alpha
- return x * t1 + y * t2;
+ return x * t1 + y * t2
}
catmull_rom :: proc(v1, v2, v3, v4: $T/[$N]$E, s: E) -> T {
- s2 := s*s;
- s3 := s2*s;
+ s2 := s*s
+ s3 := s2*s
- f1 := -s3 + 2 * s2 - s;
- f2 := 3 * s3 - 5 * s2 + 2;
- f3 := -3 * s3 + 4 * s2 + s;
- f4 := s3 - s2;
+ f1 := -s3 + 2 * s2 - s
+ f2 := 3 * s3 - 5 * s2 + 2
+ f3 := -3 * s3 + 4 * s2 + s
+ f4 := s3 - s2
- return (f1 * v1 + f2 * v2 + f3 * v3 + f4 * v4) * 0.5;
+ return (f1 * v1 + f2 * v2 + f3 * v3 + f4 * v4) * 0.5
}
hermite :: proc(v1, t1, v2, t2: $T/[$N]$E, s: E) -> T {
- s2 := s*s;
- s3 := s2*s;
+ s2 := s*s
+ s3 := s2*s
- f1 := 2 * s3 - 3 * s2 + 1;
- f2 := -2 * s3 + 3 * s2;
- f3 := s3 - 2 * s2 + s;
- f4 := s3 - s2;
+ f1 := 2 * s3 - 3 * s2 + 1
+ f2 := -2 * s3 + 3 * s2
+ f3 := s3 - 2 * s2 + s
+ f4 := s3 - s2
- return f1 * v1 + f2 * v2 + f3 * t1 + f4 * t2;
+ return f1 * v1 + f2 * v2 + f3 * t1 + f4 * t2
}
cubic :: proc(v1, v2, v3, v4: $T/[$N]$E, s: E) -> T {
- return ((v1 * s + v2) * s + v3) * s + v4;
+ return ((v1 * s + v2) * s + v3) * s + v4
}
array_cast :: proc(v: $A/[$N]$T, $Elem_Type: typeid) -> (w: [N]Elem_Type) #no_bounds_check {
for i in 0..<N {
- w[i] = Elem_Type(v[i]);
+ w[i] = Elem_Type(v[i])
}
- return;
+ return
}
matrix_cast :: proc(v: $A/[$M][$N]$T, $Elem_Type: typeid) -> (w: [M][N]Elem_Type) #no_bounds_check {
for i in 0..<M {
for j in 0..<N {
- w[i][j] = Elem_Type(v[i][j]);
+ w[i][j] = Elem_Type(v[i][j])
}
}
- return;
+ return
}
to_f32 :: #force_inline proc(v: $A/[$N]$T) -> [N]f32 { return array_cast(v, f32); }
diff --git a/core/math/linalg/specific.odin b/core/math/linalg/specific.odin
index 7d0d9dc7e..333d17e44 100644
--- a/core/math/linalg/specific.odin
+++ b/core/math/linalg/specific.odin
@@ -2,2452 +2,2452 @@ package linalg
import "core:math"
-F16_EPSILON :: 1e-3;
-F32_EPSILON :: 1e-7;
-F64_EPSILON :: 1e-15;
-
-Vector2f16 :: distinct [2]f16;
-Vector3f16 :: distinct [3]f16;
-Vector4f16 :: distinct [4]f16;
-
-Matrix1x1f16 :: distinct [1][1]f16;
-Matrix1x2f16 :: distinct [1][2]f16;
-Matrix1x3f16 :: distinct [1][3]f16;
-Matrix1x4f16 :: distinct [1][4]f16;
-
-Matrix2x1f16 :: distinct [2][1]f16;
-Matrix2x2f16 :: distinct [2][2]f16;
-Matrix2x3f16 :: distinct [2][3]f16;
-Matrix2x4f16 :: distinct [2][4]f16;
-
-Matrix3x1f16 :: distinct [3][1]f16;
-Matrix3x2f16 :: distinct [3][2]f16;
-Matrix3x3f16 :: distinct [3][3]f16;
-Matrix3x4f16 :: distinct [3][4]f16;
-
-Matrix4x1f16 :: distinct [4][1]f16;
-Matrix4x2f16 :: distinct [4][2]f16;
-Matrix4x3f16 :: distinct [4][3]f16;
-Matrix4x4f16 :: distinct [4][4]f16;
-
-Matrix1f16 :: Matrix1x1f16;
-Matrix2f16 :: Matrix2x2f16;
-Matrix3f16 :: Matrix3x3f16;
-Matrix4f16 :: Matrix4x4f16;
-
-Vector2f32 :: distinct [2]f32;
-Vector3f32 :: distinct [3]f32;
-Vector4f32 :: distinct [4]f32;
-
-Matrix1x1f32 :: distinct [1][1]f32;
-Matrix1x2f32 :: distinct [1][2]f32;
-Matrix1x3f32 :: distinct [1][3]f32;
-Matrix1x4f32 :: distinct [1][4]f32;
-
-Matrix2x1f32 :: distinct [2][1]f32;
-Matrix2x2f32 :: distinct [2][2]f32;
-Matrix2x3f32 :: distinct [2][3]f32;
-Matrix2x4f32 :: distinct [2][4]f32;
-
-Matrix3x1f32 :: distinct [3][1]f32;
-Matrix3x2f32 :: distinct [3][2]f32;
-Matrix3x3f32 :: distinct [3][3]f32;
-Matrix3x4f32 :: distinct [3][4]f32;
-
-Matrix4x1f32 :: distinct [4][1]f32;
-Matrix4x2f32 :: distinct [4][2]f32;
-Matrix4x3f32 :: distinct [4][3]f32;
-Matrix4x4f32 :: distinct [4][4]f32;
-
-Matrix1f32 :: Matrix1x1f32;
-Matrix2f32 :: Matrix2x2f32;
-Matrix3f32 :: Matrix3x3f32;
-Matrix4f32 :: Matrix4x4f32;
-
-Vector2f64 :: distinct [2]f64;
-Vector3f64 :: distinct [3]f64;
-Vector4f64 :: distinct [4]f64;
-
-Matrix1x1f64 :: distinct [1][1]f64;
-Matrix1x2f64 :: distinct [1][2]f64;
-Matrix1x3f64 :: distinct [1][3]f64;
-Matrix1x4f64 :: distinct [1][4]f64;
-
-Matrix2x1f64 :: distinct [2][1]f64;
-Matrix2x2f64 :: distinct [2][2]f64;
-Matrix2x3f64 :: distinct [2][3]f64;
-Matrix2x4f64 :: distinct [2][4]f64;
-
-Matrix3x1f64 :: distinct [3][1]f64;
-Matrix3x2f64 :: distinct [3][2]f64;
-Matrix3x3f64 :: distinct [3][3]f64;
-Matrix3x4f64 :: distinct [3][4]f64;
-
-Matrix4x1f64 :: distinct [4][1]f64;
-Matrix4x2f64 :: distinct [4][2]f64;
-Matrix4x3f64 :: distinct [4][3]f64;
-Matrix4x4f64 :: distinct [4][4]f64;
-
-Matrix1f64 :: Matrix1x1f64;
-Matrix2f64 :: Matrix2x2f64;
-Matrix3f64 :: Matrix3x3f64;
-Matrix4f64 :: Matrix4x4f64;
-
-Quaternionf16 :: distinct quaternion64;
-Quaternionf32 :: distinct quaternion128;
-Quaternionf64 :: distinct quaternion256;
-
-MATRIX1F16_IDENTITY :: Matrix1f16{{1}};
-MATRIX2F16_IDENTITY :: Matrix2f16{{1, 0}, {0, 1}};
-MATRIX3F16_IDENTITY :: Matrix3f16{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
-MATRIX4F16_IDENTITY :: Matrix4f16{{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}};
-
-MATRIX1F32_IDENTITY :: Matrix1f32{{1}};
-MATRIX2F32_IDENTITY :: Matrix2f32{{1, 0}, {0, 1}};
-MATRIX3F32_IDENTITY :: Matrix3f32{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
-MATRIX4F32_IDENTITY :: Matrix4f32{{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}};
-
-MATRIX1F64_IDENTITY :: Matrix1f64{{1}};
-MATRIX2F64_IDENTITY :: Matrix2f64{{1, 0}, {0, 1}};
-MATRIX3F64_IDENTITY :: Matrix3f64{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
-MATRIX4F64_IDENTITY :: Matrix4f64{{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}};
-
-QUATERNIONF16_IDENTITY :: Quaternionf16(1);
-QUATERNIONF32_IDENTITY :: Quaternionf32(1);
-QUATERNIONF64_IDENTITY :: Quaternionf64(1);
-
-VECTOR3F16_X_AXIS :: Vector3f16{1, 0, 0};
-VECTOR3F16_Y_AXIS :: Vector3f16{0, 1, 0};
-VECTOR3F16_Z_AXIS :: Vector3f16{0, 0, 1};
-
-VECTOR3F32_X_AXIS :: Vector3f32{1, 0, 0};
-VECTOR3F32_Y_AXIS :: Vector3f32{0, 1, 0};
-VECTOR3F32_Z_AXIS :: Vector3f32{0, 0, 1};
-
-VECTOR3F64_X_AXIS :: Vector3f64{1, 0, 0};
-VECTOR3F64_Y_AXIS :: Vector3f64{0, 1, 0};
-VECTOR3F64_Z_AXIS :: Vector3f64{0, 0, 1};
+F16_EPSILON :: 1e-3
+F32_EPSILON :: 1e-7
+F64_EPSILON :: 1e-15
+
+Vector2f16 :: distinct [2]f16
+Vector3f16 :: distinct [3]f16
+Vector4f16 :: distinct [4]f16
+
+Matrix1x1f16 :: distinct [1][1]f16
+Matrix1x2f16 :: distinct [1][2]f16
+Matrix1x3f16 :: distinct [1][3]f16
+Matrix1x4f16 :: distinct [1][4]f16
+
+Matrix2x1f16 :: distinct [2][1]f16
+Matrix2x2f16 :: distinct [2][2]f16
+Matrix2x3f16 :: distinct [2][3]f16
+Matrix2x4f16 :: distinct [2][4]f16
+
+Matrix3x1f16 :: distinct [3][1]f16
+Matrix3x2f16 :: distinct [3][2]f16
+Matrix3x3f16 :: distinct [3][3]f16
+Matrix3x4f16 :: distinct [3][4]f16
+
+Matrix4x1f16 :: distinct [4][1]f16
+Matrix4x2f16 :: distinct [4][2]f16
+Matrix4x3f16 :: distinct [4][3]f16
+Matrix4x4f16 :: distinct [4][4]f16
+
+Matrix1f16 :: Matrix1x1f16
+Matrix2f16 :: Matrix2x2f16
+Matrix3f16 :: Matrix3x3f16
+Matrix4f16 :: Matrix4x4f16
+
+Vector2f32 :: distinct [2]f32
+Vector3f32 :: distinct [3]f32
+Vector4f32 :: distinct [4]f32
+
+Matrix1x1f32 :: distinct [1][1]f32
+Matrix1x2f32 :: distinct [1][2]f32
+Matrix1x3f32 :: distinct [1][3]f32
+Matrix1x4f32 :: distinct [1][4]f32
+
+Matrix2x1f32 :: distinct [2][1]f32
+Matrix2x2f32 :: distinct [2][2]f32
+Matrix2x3f32 :: distinct [2][3]f32
+Matrix2x4f32 :: distinct [2][4]f32
+
+Matrix3x1f32 :: distinct [3][1]f32
+Matrix3x2f32 :: distinct [3][2]f32
+Matrix3x3f32 :: distinct [3][3]f32
+Matrix3x4f32 :: distinct [3][4]f32
+
+Matrix4x1f32 :: distinct [4][1]f32
+Matrix4x2f32 :: distinct [4][2]f32
+Matrix4x3f32 :: distinct [4][3]f32
+Matrix4x4f32 :: distinct [4][4]f32
+
+Matrix1f32 :: Matrix1x1f32
+Matrix2f32 :: Matrix2x2f32
+Matrix3f32 :: Matrix3x3f32
+Matrix4f32 :: Matrix4x4f32
+
+Vector2f64 :: distinct [2]f64
+Vector3f64 :: distinct [3]f64
+Vector4f64 :: distinct [4]f64
+
+Matrix1x1f64 :: distinct [1][1]f64
+Matrix1x2f64 :: distinct [1][2]f64
+Matrix1x3f64 :: distinct [1][3]f64
+Matrix1x4f64 :: distinct [1][4]f64
+
+Matrix2x1f64 :: distinct [2][1]f64
+Matrix2x2f64 :: distinct [2][2]f64
+Matrix2x3f64 :: distinct [2][3]f64
+Matrix2x4f64 :: distinct [2][4]f64
+
+Matrix3x1f64 :: distinct [3][1]f64
+Matrix3x2f64 :: distinct [3][2]f64
+Matrix3x3f64 :: distinct [3][3]f64
+Matrix3x4f64 :: distinct [3][4]f64
+
+Matrix4x1f64 :: distinct [4][1]f64
+Matrix4x2f64 :: distinct [4][2]f64
+Matrix4x3f64 :: distinct [4][3]f64
+Matrix4x4f64 :: distinct [4][4]f64
+
+Matrix1f64 :: Matrix1x1f64
+Matrix2f64 :: Matrix2x2f64
+Matrix3f64 :: Matrix3x3f64
+Matrix4f64 :: Matrix4x4f64
+
+Quaternionf16 :: distinct quaternion64
+Quaternionf32 :: distinct quaternion128
+Quaternionf64 :: distinct quaternion256
+
+MATRIX1F16_IDENTITY :: Matrix1f16{{1}}
+MATRIX2F16_IDENTITY :: Matrix2f16{{1, 0}, {0, 1}}
+MATRIX3F16_IDENTITY :: Matrix3f16{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}
+MATRIX4F16_IDENTITY :: Matrix4f16{{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}}
+
+MATRIX1F32_IDENTITY :: Matrix1f32{{1}}
+MATRIX2F32_IDENTITY :: Matrix2f32{{1, 0}, {0, 1}}
+MATRIX3F32_IDENTITY :: Matrix3f32{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}
+MATRIX4F32_IDENTITY :: Matrix4f32{{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}}
+
+MATRIX1F64_IDENTITY :: Matrix1f64{{1}}
+MATRIX2F64_IDENTITY :: Matrix2f64{{1, 0}, {0, 1}}
+MATRIX3F64_IDENTITY :: Matrix3f64{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}
+MATRIX4F64_IDENTITY :: Matrix4f64{{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}}
+
+QUATERNIONF16_IDENTITY :: Quaternionf16(1)
+QUATERNIONF32_IDENTITY :: Quaternionf32(1)
+QUATERNIONF64_IDENTITY :: Quaternionf64(1)
+
+VECTOR3F16_X_AXIS :: Vector3f16{1, 0, 0}
+VECTOR3F16_Y_AXIS :: Vector3f16{0, 1, 0}
+VECTOR3F16_Z_AXIS :: Vector3f16{0, 0, 1}
+
+VECTOR3F32_X_AXIS :: Vector3f32{1, 0, 0}
+VECTOR3F32_Y_AXIS :: Vector3f32{0, 1, 0}
+VECTOR3F32_Z_AXIS :: Vector3f32{0, 0, 1}
+
+VECTOR3F64_X_AXIS :: Vector3f64{1, 0, 0}
+VECTOR3F64_Y_AXIS :: Vector3f64{0, 1, 0}
+VECTOR3F64_Z_AXIS :: Vector3f64{0, 0, 1}
vector2_orthogonal :: proc(v: $V/[2]$E) -> V where !IS_ARRAY(E), IS_FLOAT(E) {
- return {-v.y, v.x};
+ return {-v.y, v.x}
}
vector3_orthogonal :: proc(v: $V/[3]$E) -> V where !IS_ARRAY(E), IS_FLOAT(E) {
- x := abs(v.x);
- y := abs(v.y);
- z := abs(v.z);
+ x := abs(v.x)
+ y := abs(v.y)
+ z := abs(v.z)
- other: V;
+ other: V
if x < y {
if x < z {
- other = {1, 0, 0};
+ other = {1, 0, 0}
} else {
- other = {0, 0, 1};
+ other = {0, 0, 1}
}
} else {
if y < z {
- other = {0, 1, 0};
+ other = {0, 1, 0}
} else {
- other = {0, 0, 1};
+ other = {0, 0, 1}
}
}
- return normalize(cross(v, other));
+ return normalize(cross(v, other))
}
-orthogonal :: proc{vector2_orthogonal, vector3_orthogonal};
+orthogonal :: proc{vector2_orthogonal, vector3_orthogonal}
vector4_srgb_to_linear_f16 :: proc(col: Vector4f16) -> Vector4f16 {
- r := math.pow(col.x, 2.2);
- g := math.pow(col.y, 2.2);
- b := math.pow(col.z, 2.2);
- a := col.w;
- return {r, g, b, a};
+ r := math.pow(col.x, 2.2)
+ g := math.pow(col.y, 2.2)
+ b := math.pow(col.z, 2.2)
+ a := col.w
+ return {r, g, b, a}
}
vector4_srgb_to_linear_f32 :: proc(col: Vector4f32) -> Vector4f32 {
- r := math.pow(col.x, 2.2);
- g := math.pow(col.y, 2.2);
- b := math.pow(col.z, 2.2);
- a := col.w;
- return {r, g, b, a};
+ r := math.pow(col.x, 2.2)
+ g := math.pow(col.y, 2.2)
+ b := math.pow(col.z, 2.2)
+ a := col.w
+ return {r, g, b, a}
}
vector4_srgb_to_linear_f64 :: proc(col: Vector4f64) -> Vector4f64 {
- r := math.pow(col.x, 2.2);
- g := math.pow(col.y, 2.2);
- b := math.pow(col.z, 2.2);
- a := col.w;
- return {r, g, b, a};
+ r := math.pow(col.x, 2.2)
+ g := math.pow(col.y, 2.2)
+ b := math.pow(col.z, 2.2)
+ a := col.w
+ return {r, g, b, a}
}
vector4_srgb_to_linear :: proc{
vector4_srgb_to_linear_f16,
vector4_srgb_to_linear_f32,
vector4_srgb_to_linear_f64,
-};
+}
vector4_linear_to_srgb_f16 :: proc(col: Vector4f16) -> Vector4f16 {
- a :: 2.51;
- b :: 0.03;
- c :: 2.43;
- d :: 0.59;
- e :: 0.14;
+ a :: 2.51
+ b :: 0.03
+ c :: 2.43
+ d :: 0.59
+ e :: 0.14
- x := col.x;
- y := col.y;
- z := col.z;
+ x := col.x
+ y := col.y
+ z := col.z
- x = (x * (a * x + b)) / (x * (c * x + d) + e);
- y = (y * (a * y + b)) / (y * (c * y + d) + e);
- z = (z * (a * z + b)) / (z * (c * z + d) + e);
+ x = (x * (a * x + b)) / (x * (c * x + d) + e)
+ y = (y * (a * y + b)) / (y * (c * y + d) + e)
+ z = (z * (a * z + b)) / (z * (c * z + d) + e)
- x = math.pow(clamp(x, 0, 1), 1.0 / 2.2);
- y = math.pow(clamp(y, 0, 1), 1.0 / 2.2);
- z = math.pow(clamp(z, 0, 1), 1.0 / 2.2);
+ x = math.pow(clamp(x, 0, 1), 1.0 / 2.2)
+ y = math.pow(clamp(y, 0, 1), 1.0 / 2.2)
+ z = math.pow(clamp(z, 0, 1), 1.0 / 2.2)
- return {x, y, z, col.w};
+ return {x, y, z, col.w}
}
vector4_linear_to_srgb_f32 :: proc(col: Vector4f32) -> Vector4f32 {
- a :: 2.51;
- b :: 0.03;
- c :: 2.43;
- d :: 0.59;
- e :: 0.14;
+ a :: 2.51
+ b :: 0.03
+ c :: 2.43
+ d :: 0.59
+ e :: 0.14
- x := col.x;
- y := col.y;
- z := col.z;
+ x := col.x
+ y := col.y
+ z := col.z
- x = (x * (a * x + b)) / (x * (c * x + d) + e);
- y = (y * (a * y + b)) / (y * (c * y + d) + e);
- z = (z * (a * z + b)) / (z * (c * z + d) + e);
+ x = (x * (a * x + b)) / (x * (c * x + d) + e)
+ y = (y * (a * y + b)) / (y * (c * y + d) + e)
+ z = (z * (a * z + b)) / (z * (c * z + d) + e)
- x = math.pow(clamp(x, 0, 1), 1.0 / 2.2);
- y = math.pow(clamp(y, 0, 1), 1.0 / 2.2);
- z = math.pow(clamp(z, 0, 1), 1.0 / 2.2);
+ x = math.pow(clamp(x, 0, 1), 1.0 / 2.2)
+ y = math.pow(clamp(y, 0, 1), 1.0 / 2.2)
+ z = math.pow(clamp(z, 0, 1), 1.0 / 2.2)
- return {x, y, z, col.w};
+ return {x, y, z, col.w}
}
vector4_linear_to_srgb_f64 :: proc(col: Vector4f64) -> Vector4f64 {
- a :: 2.51;
- b :: 0.03;
- c :: 2.43;
- d :: 0.59;
- e :: 0.14;
+ a :: 2.51
+ b :: 0.03
+ c :: 2.43
+ d :: 0.59
+ e :: 0.14
- x := col.x;
- y := col.y;
- z := col.z;
+ x := col.x
+ y := col.y
+ z := col.z
- x = (x * (a * x + b)) / (x * (c * x + d) + e);
- y = (y * (a * y + b)) / (y * (c * y + d) + e);
- z = (z * (a * z + b)) / (z * (c * z + d) + e);
+ x = (x * (a * x + b)) / (x * (c * x + d) + e)
+ y = (y * (a * y + b)) / (y * (c * y + d) + e)
+ z = (z * (a * z + b)) / (z * (c * z + d) + e)
- x = math.pow(clamp(x, 0, 1), 1.0 / 2.2);
- y = math.pow(clamp(y, 0, 1), 1.0 / 2.2);
- z = math.pow(clamp(z, 0, 1), 1.0 / 2.2);
+ x = math.pow(clamp(x, 0, 1), 1.0 / 2.2)
+ y = math.pow(clamp(y, 0, 1), 1.0 / 2.2)
+ z = math.pow(clamp(z, 0, 1), 1.0 / 2.2)
- return {x, y, z, col.w};
+ return {x, y, z, col.w}
}
vector4_linear_to_srgb :: proc{
vector4_linear_to_srgb_f16,
vector4_linear_to_srgb_f32,
vector4_linear_to_srgb_f64,
-};
+}
vector4_hsl_to_rgb_f16 :: proc(h, s, l: f16, a: f16 = 1) -> Vector4f16 {
hue_to_rgb :: proc(p, q, t: f16) -> f16 {
- t := t;
+ t := t
if t < 0 { t += 1; }
if t > 1 { t -= 1; }
switch {
- case t < 1.0/6.0: return p + (q - p) * 6.0 * t;
- case t < 1.0/2.0: return q;
- case t < 2.0/3.0: return p + (q - p) * 6.0 * (2.0/3.0 - t);
+ case t < 1.0/6.0: return p + (q - p) * 6.0 * t
+ case t < 1.0/2.0: return q
+ case t < 2.0/3.0: return p + (q - p) * 6.0 * (2.0/3.0 - t)
}
- return p;
+ return p
}
- r, g, b: f16;
+ r, g, b: f16
if s == 0 {
- r = l;
- g = l;
- b = l;
+ r = l
+ g = l
+ b = l
} else {
- q := l * (1+s) if l < 0.5 else l+s - l*s;
- p := 2*l - q;
- r = hue_to_rgb(p, q, h + 1.0/3.0);
- g = hue_to_rgb(p, q, h);
- b = hue_to_rgb(p, q, h - 1.0/3.0);
+ q := l * (1+s) if l < 0.5 else l+s - l*s
+ p := 2*l - q
+ r = hue_to_rgb(p, q, h + 1.0/3.0)
+ g = hue_to_rgb(p, q, h)
+ b = hue_to_rgb(p, q, h - 1.0/3.0)
}
- return {r, g, b, a};
+ return {r, g, b, a}
}
vector4_hsl_to_rgb_f32 :: proc(h, s, l: f32, a: f32 = 1) -> Vector4f32 {
hue_to_rgb :: proc(p, q, t: f32) -> f32 {
- t := t;
+ t := t
if t < 0 { t += 1; }
if t > 1 { t -= 1; }
switch {
- case t < 1.0/6.0: return p + (q - p) * 6.0 * t;
- case t < 1.0/2.0: return q;
- case t < 2.0/3.0: return p + (q - p) * 6.0 * (2.0/3.0 - t);
+ case t < 1.0/6.0: return p + (q - p) * 6.0 * t
+ case t < 1.0/2.0: return q
+ case t < 2.0/3.0: return p + (q - p) * 6.0 * (2.0/3.0 - t)
}
- return p;
+ return p
}
- r, g, b: f32;
+ r, g, b: f32
if s == 0 {
- r = l;
- g = l;
- b = l;
+ r = l
+ g = l
+ b = l
} else {
- q := l * (1+s) if l < 0.5 else l+s - l*s;
- p := 2*l - q;
- r = hue_to_rgb(p, q, h + 1.0/3.0);
- g = hue_to_rgb(p, q, h);
- b = hue_to_rgb(p, q, h - 1.0/3.0);
+ q := l * (1+s) if l < 0.5 else l+s - l*s
+ p := 2*l - q
+ r = hue_to_rgb(p, q, h + 1.0/3.0)
+ g = hue_to_rgb(p, q, h)
+ b = hue_to_rgb(p, q, h - 1.0/3.0)
}
- return {r, g, b, a};
+ return {r, g, b, a}
}
vector4_hsl_to_rgb_f64 :: proc(h, s, l: f64, a: f64 = 1) -> Vector4f64 {
hue_to_rgb :: proc(p, q, t: f64) -> f64 {
- t := t;
+ t := t
if t < 0 { t += 1; }
if t > 1 { t -= 1; }
switch {
- case t < 1.0/6.0: return p + (q - p) * 6.0 * t;
- case t < 1.0/2.0: return q;
- case t < 2.0/3.0: return p + (q - p) * 6.0 * (2.0/3.0 - t);
+ case t < 1.0/6.0: return p + (q - p) * 6.0 * t
+ case t < 1.0/2.0: return q
+ case t < 2.0/3.0: return p + (q - p) * 6.0 * (2.0/3.0 - t)
}
- return p;
+ return p
}
- r, g, b: f64;
+ r, g, b: f64
if s == 0 {
- r = l;
- g = l;
- b = l;
+ r = l
+ g = l
+ b = l
} else {
- q := l * (1+s) if l < 0.5 else l+s - l*s;
- p := 2*l - q;
- r = hue_to_rgb(p, q, h + 1.0/3.0);
- g = hue_to_rgb(p, q, h);
- b = hue_to_rgb(p, q, h - 1.0/3.0);
+ q := l * (1+s) if l < 0.5 else l+s - l*s
+ p := 2*l - q
+ r = hue_to_rgb(p, q, h + 1.0/3.0)
+ g = hue_to_rgb(p, q, h)
+ b = hue_to_rgb(p, q, h - 1.0/3.0)
}
- return {r, g, b, a};
+ return {r, g, b, a}
}
vector4_hsl_to_rgb :: proc{
vector4_hsl_to_rgb_f16,
vector4_hsl_to_rgb_f32,
vector4_hsl_to_rgb_f64,
-};
+}
vector4_rgb_to_hsl_f16 :: proc(col: Vector4f16) -> Vector4f16 {
- r := col.x;
- g := col.y;
- b := col.z;
- a := col.w;
- v_min := min(r, g, b);
- v_max := max(r, g, b);
- h, s, l: f16;
- h = 0.0;
- s = 0.0;
- l = (v_min + v_max) * 0.5;
+ r := col.x
+ g := col.y
+ b := col.z
+ a := col.w
+ v_min := min(r, g, b)
+ v_max := max(r, g, b)
+ h, s, l: f16
+ h = 0.0
+ s = 0.0
+ l = (v_min + v_max) * 0.5
if v_max != v_min {
- d: = v_max - v_min;
- s = d / (2.0 - v_max - v_min) if l > 0.5 else d / (v_max + v_min);
+ d: = v_max - v_min
+ s = d / (2.0 - v_max - v_min) if l > 0.5 else d / (v_max + v_min)
switch {
case v_max == r:
- h = (g - b) / d + (6.0 if g < b else 0.0);
+ h = (g - b) / d + (6.0 if g < b else 0.0)
case v_max == g:
- h = (b - r) / d + 2.0;
+ h = (b - r) / d + 2.0
case v_max == b:
- h = (r - g) / d + 4.0;
+ h = (r - g) / d + 4.0
}
- h *= 1.0/6.0;
+ h *= 1.0/6.0
}
- return {h, s, l, a};
+ return {h, s, l, a}
}
vector4_rgb_to_hsl_f32 :: proc(col: Vector4f32) -> Vector4f32 {
- r := col.x;
- g := col.y;
- b := col.z;
- a := col.w;
- v_min := min(r, g, b);
- v_max := max(r, g, b);
- h, s, l: f32;
- h = 0.0;
- s = 0.0;
- l = (v_min + v_max) * 0.5;
+ r := col.x
+ g := col.y
+ b := col.z
+ a := col.w
+ v_min := min(r, g, b)
+ v_max := max(r, g, b)
+ h, s, l: f32
+ h = 0.0
+ s = 0.0
+ l = (v_min + v_max) * 0.5
if v_max != v_min {
- d: = v_max - v_min;
- s = d / (2.0 - v_max - v_min) if l > 0.5 else d / (v_max + v_min);
+ d: = v_max - v_min
+ s = d / (2.0 - v_max - v_min) if l > 0.5 else d / (v_max + v_min)
switch {
case v_max == r:
- h = (g - b) / d + (6.0 if g < b else 0.0);
+ h = (g - b) / d + (6.0 if g < b else 0.0)
case v_max == g:
- h = (b - r) / d + 2.0;
+ h = (b - r) / d + 2.0
case v_max == b:
- h = (r - g) / d + 4.0;
+ h = (r - g) / d + 4.0
}
- h *= 1.0/6.0;
+ h *= 1.0/6.0
}
- return {h, s, l, a};
+ return {h, s, l, a}
}
vector4_rgb_to_hsl_f64 :: proc(col: Vector4f64) -> Vector4f64 {
- r := col.x;
- g := col.y;
- b := col.z;
- a := col.w;
- v_min := min(r, g, b);
- v_max := max(r, g, b);
- h, s, l: f64;
- h = 0.0;
- s = 0.0;
- l = (v_min + v_max) * 0.5;
+ r := col.x
+ g := col.y
+ b := col.z
+ a := col.w
+ v_min := min(r, g, b)
+ v_max := max(r, g, b)
+ h, s, l: f64
+ h = 0.0
+ s = 0.0
+ l = (v_min + v_max) * 0.5
if v_max != v_min {
- d: = v_max - v_min;
- s = d / (2.0 - v_max - v_min) if l > 0.5 else d / (v_max + v_min);
+ d: = v_max - v_min
+ s = d / (2.0 - v_max - v_min) if l > 0.5 else d / (v_max + v_min)
switch {
case v_max == r:
- h = (g - b) / d + (6.0 if g < b else 0.0);
+ h = (g - b) / d + (6.0 if g < b else 0.0)
case v_max == g:
- h = (b - r) / d + 2.0;
+ h = (b - r) / d + 2.0
case v_max == b:
- h = (r - g) / d + 4.0;
+ h = (r - g) / d + 4.0
}
- h *= 1.0/6.0;
+ h *= 1.0/6.0
}
- return {h, s, l, a};
+ return {h, s, l, a}
}
vector4_rgb_to_hsl :: proc{
vector4_rgb_to_hsl_f16,
vector4_rgb_to_hsl_f32,
vector4_rgb_to_hsl_f64,
-};
+}
quaternion_angle_axis_f16 :: proc(angle_radians: f16, axis: Vector3f16) -> (q: Quaternionf16) {
- t := angle_radians*0.5;
- v := normalize(axis) * math.sin(t);
- q.x = v.x;
- q.y = v.y;
- q.z = v.z;
- q.w = math.cos(t);
- return;
+ t := angle_radians*0.5
+ v := normalize(axis) * math.sin(t)
+ q.x = v.x
+ q.y = v.y
+ q.z = v.z
+ q.w = math.cos(t)
+ return
}
quaternion_angle_axis_f32 :: proc(angle_radians: f32, axis: Vector3f32) -> (q: Quaternionf32) {
- t := angle_radians*0.5;
- v := normalize(axis) * math.sin(t);
- q.x = v.x;
- q.y = v.y;
- q.z = v.z;
- q.w = math.cos(t);
- return;
+ t := angle_radians*0.5
+ v := normalize(axis) * math.sin(t)
+ q.x = v.x
+ q.y = v.y
+ q.z = v.z
+ q.w = math.cos(t)
+ return
}
quaternion_angle_axis_f64 :: proc(angle_radians: f64, axis: Vector3f64) -> (q: Quaternionf64) {
- t := angle_radians*0.5;
- v := normalize(axis) * math.sin(t);
- q.x = v.x;
- q.y = v.y;
- q.z = v.z;
- q.w = math.cos(t);
- return;
+ t := angle_radians*0.5
+ v := normalize(axis) * math.sin(t)
+ q.x = v.x
+ q.y = v.y
+ q.z = v.z
+ q.w = math.cos(t)
+ return
}
quaternion_angle_axis :: proc{
quaternion_angle_axis_f16,
quaternion_angle_axis_f32,
quaternion_angle_axis_f64,
-};
+}
angle_from_quaternion_f16 :: proc(q: Quaternionf16) -> f16 {
if abs(q.w) > math.SQRT_THREE*0.5 {
- return math.asin(q.x*q.x + q.y*q.y + q.z*q.z) * 2;
+ return math.asin(q.x*q.x + q.y*q.y + q.z*q.z) * 2
}
- return math.cos(q.x) * 2;
+ return math.cos(q.x) * 2
}
angle_from_quaternion_f32 :: proc(q: Quaternionf32) -> f32 {
if abs(q.w) > math.SQRT_THREE*0.5 {
- return math.asin(q.x*q.x + q.y*q.y + q.z*q.z) * 2;
+ return math.asin(q.x*q.x + q.y*q.y + q.z*q.z) * 2
}
- return math.cos(q.x) * 2;
+ return math.cos(q.x) * 2
}
angle_from_quaternion_f64 :: proc(q: Quaternionf64) -> f64 {
if abs(q.w) > math.SQRT_THREE*0.5 {
- return math.asin(q.x*q.x + q.y*q.y + q.z*q.z) * 2;
+ return math.asin(q.x*q.x + q.y*q.y + q.z*q.z) * 2
}
- return math.cos(q.x) * 2;
+ return math.cos(q.x) * 2
}
angle_from_quaternion :: proc{
angle_from_quaternion_f16,
angle_from_quaternion_f32,
angle_from_quaternion_f64,
-};
+}
axis_from_quaternion_f16 :: proc(q: Quaternionf16) -> Vector3f16 {
- t1 := 1 - q.w*q.w;
+ t1 := 1 - q.w*q.w
if t1 < 0 {
- return {0, 0, 1};
+ return {0, 0, 1}
}
- t2 := 1.0 / math.sqrt(t1);
- return {q.x*t2, q.y*t2, q.z*t2};
+ t2 := 1.0 / math.sqrt(t1)
+ return {q.x*t2, q.y*t2, q.z*t2}
}
axis_from_quaternion_f32 :: proc(q: Quaternionf32) -> Vector3f32 {
- t1 := 1 - q.w*q.w;
+ t1 := 1 - q.w*q.w
if t1 < 0 {
- return {0, 0, 1};
+ return {0, 0, 1}
}
- t2 := 1.0 / math.sqrt(t1);
- return {q.x*t2, q.y*t2, q.z*t2};
+ t2 := 1.0 / math.sqrt(t1)
+ return {q.x*t2, q.y*t2, q.z*t2}
}
axis_from_quaternion_f64 :: proc(q: Quaternionf64) -> Vector3f64 {
- t1 := 1 - q.w*q.w;
+ t1 := 1 - q.w*q.w
if t1 < 0 {
- return {0, 0, 1};
+ return {0, 0, 1}
}
- t2 := 1.0 / math.sqrt(t1);
- return {q.x*t2, q.y*t2, q.z*t2};
+ t2 := 1.0 / math.sqrt(t1)
+ return {q.x*t2, q.y*t2, q.z*t2}
}
axis_from_quaternion :: proc{
axis_from_quaternion_f16,
axis_from_quaternion_f32,
axis_from_quaternion_f64,
-};
+}
angle_axis_from_quaternion_f16 :: proc(q: Quaternionf16) -> (angle: f16, axis: Vector3f16) {
- angle = angle_from_quaternion(q);
- axis = axis_from_quaternion(q);
- return;
+ angle = angle_from_quaternion(q)
+ axis = axis_from_quaternion(q)
+ return
}
angle_axis_from_quaternion_f32 :: proc(q: Quaternionf32) -> (angle: f32, axis: Vector3f32) {
- angle = angle_from_quaternion(q);
- axis = axis_from_quaternion(q);
- return;
+ angle = angle_from_quaternion(q)
+ axis = axis_from_quaternion(q)
+ return
}
angle_axis_from_quaternion_f64 :: proc(q: Quaternionf64) -> (angle: f64, axis: Vector3f64) {
- angle = angle_from_quaternion(q);
- axis = axis_from_quaternion(q);
- return;
+ angle = angle_from_quaternion(q)
+ axis = axis_from_quaternion(q)
+ return
}
angle_axis_from_quaternion :: proc {
angle_axis_from_quaternion_f16,
angle_axis_from_quaternion_f32,
angle_axis_from_quaternion_f64,
-};
+}
quaternion_from_forward_and_up_f16 :: proc(forward, up: Vector3f16) -> Quaternionf16 {
- f := normalize(forward);
- s := normalize(cross(f, up));
- u := cross(s, f);
+ f := normalize(forward)
+ s := normalize(cross(f, up))
+ u := cross(s, f)
m := Matrix3f16{
{+s.x, +u.x, -f.x},
{+s.y, +u.y, -f.y},
{+s.z, +u.z, -f.z},
- };
+ }
- tr := trace(m);
+ tr := trace(m)
- q: Quaternionf16;
+ q: Quaternionf16
switch {
case tr > 0:
- S := 2 * math.sqrt(1 + tr);
- q.w = 0.25 * S;
- q.x = (m[2][1] - m[1][2]) / S;
- q.y = (m[0][2] - m[2][0]) / S;
- q.z = (m[1][0] - m[0][1]) / S;
+ S := 2 * math.sqrt(1 + tr)
+ q.w = 0.25 * S
+ q.x = (m[2][1] - m[1][2]) / S
+ q.y = (m[0][2] - m[2][0]) / S
+ q.z = (m[1][0] - m[0][1]) / S
case (m[0][0] > m[1][1]) && (m[0][0] > m[2][2]):
- S := 2 * math.sqrt(1 + m[0][0] - m[1][1] - m[2][2]);
- q.w = (m[2][1] - m[1][2]) / S;
- q.x = 0.25 * S;
- q.y = (m[0][1] + m[1][0]) / S;
- q.z = (m[0][2] + m[2][0]) / S;
+ S := 2 * math.sqrt(1 + m[0][0] - m[1][1] - m[2][2])
+ q.w = (m[2][1] - m[1][2]) / S
+ q.x = 0.25 * S
+ q.y = (m[0][1] + m[1][0]) / S
+ q.z = (m[0][2] + m[2][0]) / S
case m[1][1] > m[2][2]:
- S := 2 * math.sqrt(1 + m[1][1] - m[0][0] - m[2][2]);
- q.w = (m[0][2] - m[2][0]) / S;
- q.x = (m[0][1] + m[1][0]) / S;
- q.y = 0.25 * S;
- q.z = (m[1][2] + m[2][1]) / S;
+ S := 2 * math.sqrt(1 + m[1][1] - m[0][0] - m[2][2])
+ q.w = (m[0][2] - m[2][0]) / S
+ q.x = (m[0][1] + m[1][0]) / S
+ q.y = 0.25 * S
+ q.z = (m[1][2] + m[2][1]) / S
case:
- S := 2 * math.sqrt(1 + m[2][2] - m[0][0] - m[1][1]);
- q.w = (m[1][0] - m[0][1]) / S;
- q.x = (m[0][2] - m[2][0]) / S;
- q.y = (m[1][2] + m[2][1]) / S;
- q.z = 0.25 * S;
+ S := 2 * math.sqrt(1 + m[2][2] - m[0][0] - m[1][1])
+ q.w = (m[1][0] - m[0][1]) / S
+ q.x = (m[0][2] - m[2][0]) / S
+ q.y = (m[1][2] + m[2][1]) / S
+ q.z = 0.25 * S
}
- return normalize(q);
+ return normalize(q)
}
quaternion_from_forward_and_up_f32 :: proc(forward, up: Vector3f32) -> Quaternionf32 {
- f := normalize(forward);
- s := normalize(cross(f, up));
- u := cross(s, f);
+ f := normalize(forward)
+ s := normalize(cross(f, up))
+ u := cross(s, f)
m := Matrix3f32{
{+s.x, +u.x, -f.x},
{+s.y, +u.y, -f.y},
{+s.z, +u.z, -f.z},
- };
+ }
- tr := trace(m);
+ tr := trace(m)
- q: Quaternionf32;
+ q: Quaternionf32
switch {
case tr > 0:
- S := 2 * math.sqrt(1 + tr);
- q.w = 0.25 * S;
- q.x = (m[2][1] - m[1][2]) / S;
- q.y = (m[0][2] - m[2][0]) / S;
- q.z = (m[1][0] - m[0][1]) / S;
+ S := 2 * math.sqrt(1 + tr)
+ q.w = 0.25 * S
+ q.x = (m[2][1] - m[1][2]) / S
+ q.y = (m[0][2] - m[2][0]) / S
+ q.z = (m[1][0] - m[0][1]) / S
case (m[0][0] > m[1][1]) && (m[0][0] > m[2][2]):
- S := 2 * math.sqrt(1 + m[0][0] - m[1][1] - m[2][2]);
- q.w = (m[2][1] - m[1][2]) / S;
- q.x = 0.25 * S;
- q.y = (m[0][1] + m[1][0]) / S;
- q.z = (m[0][2] + m[2][0]) / S;
+ S := 2 * math.sqrt(1 + m[0][0] - m[1][1] - m[2][2])
+ q.w = (m[2][1] - m[1][2]) / S
+ q.x = 0.25 * S
+ q.y = (m[0][1] + m[1][0]) / S
+ q.z = (m[0][2] + m[2][0]) / S
case m[1][1] > m[2][2]:
- S := 2 * math.sqrt(1 + m[1][1] - m[0][0] - m[2][2]);
- q.w = (m[0][2] - m[2][0]) / S;
- q.x = (m[0][1] + m[1][0]) / S;
- q.y = 0.25 * S;
- q.z = (m[1][2] + m[2][1]) / S;
+ S := 2 * math.sqrt(1 + m[1][1] - m[0][0] - m[2][2])
+ q.w = (m[0][2] - m[2][0]) / S
+ q.x = (m[0][1] + m[1][0]) / S
+ q.y = 0.25 * S
+ q.z = (m[1][2] + m[2][1]) / S
case:
- S := 2 * math.sqrt(1 + m[2][2] - m[0][0] - m[1][1]);
- q.w = (m[1][0] - m[0][1]) / S;
- q.x = (m[0][2] - m[2][0]) / S;
- q.y = (m[1][2] + m[2][1]) / S;
- q.z = 0.25 * S;
+ S := 2 * math.sqrt(1 + m[2][2] - m[0][0] - m[1][1])
+ q.w = (m[1][0] - m[0][1]) / S
+ q.x = (m[0][2] - m[2][0]) / S
+ q.y = (m[1][2] + m[2][1]) / S
+ q.z = 0.25 * S
}
- return normalize(q);
+ return normalize(q)
}
quaternion_from_forward_and_up_f64 :: proc(forward, up: Vector3f64) -> Quaternionf64 {
- f := normalize(forward);
- s := normalize(cross(f, up));
- u := cross(s, f);
+ f := normalize(forward)
+ s := normalize(cross(f, up))
+ u := cross(s, f)
m := Matrix3f64{
{+s.x, +u.x, -f.x},
{+s.y, +u.y, -f.y},
{+s.z, +u.z, -f.z},
- };
+ }
- tr := trace(m);
+ tr := trace(m)
- q: Quaternionf64;
+ q: Quaternionf64
switch {
case tr > 0:
- S := 2 * math.sqrt(1 + tr);
- q.w = 0.25 * S;
- q.x = (m[2][1] - m[1][2]) / S;
- q.y = (m[0][2] - m[2][0]) / S;
- q.z = (m[1][0] - m[0][1]) / S;
+ S := 2 * math.sqrt(1 + tr)
+ q.w = 0.25 * S
+ q.x = (m[2][1] - m[1][2]) / S
+ q.y = (m[0][2] - m[2][0]) / S
+ q.z = (m[1][0] - m[0][1]) / S
case (m[0][0] > m[1][1]) && (m[0][0] > m[2][2]):
- S := 2 * math.sqrt(1 + m[0][0] - m[1][1] - m[2][2]);
- q.w = (m[2][1] - m[1][2]) / S;
- q.x = 0.25 * S;
- q.y = (m[0][1] + m[1][0]) / S;
- q.z = (m[0][2] + m[2][0]) / S;
+ S := 2 * math.sqrt(1 + m[0][0] - m[1][1] - m[2][2])
+ q.w = (m[2][1] - m[1][2]) / S
+ q.x = 0.25 * S
+ q.y = (m[0][1] + m[1][0]) / S
+ q.z = (m[0][2] + m[2][0]) / S
case m[1][1] > m[2][2]:
- S := 2 * math.sqrt(1 + m[1][1] - m[0][0] - m[2][2]);
- q.w = (m[0][2] - m[2][0]) / S;
- q.x = (m[0][1] + m[1][0]) / S;
- q.y = 0.25 * S;
- q.z = (m[1][2] + m[2][1]) / S;
+ S := 2 * math.sqrt(1 + m[1][1] - m[0][0] - m[2][2])
+ q.w = (m[0][2] - m[2][0]) / S
+ q.x = (m[0][1] + m[1][0]) / S
+ q.y = 0.25 * S
+ q.z = (m[1][2] + m[2][1]) / S
case:
- S := 2 * math.sqrt(1 + m[2][2] - m[0][0] - m[1][1]);
- q.w = (m[1][0] - m[0][1]) / S;
- q.x = (m[0][2] - m[2][0]) / S;
- q.y = (m[1][2] + m[2][1]) / S;
- q.z = 0.25 * S;
+ S := 2 * math.sqrt(1 + m[2][2] - m[0][0] - m[1][1])
+ q.w = (m[1][0] - m[0][1]) / S
+ q.x = (m[0][2] - m[2][0]) / S
+ q.y = (m[1][2] + m[2][1]) / S
+ q.z = 0.25 * S
}
- return normalize(q);
+ return normalize(q)
}
quaternion_from_forward_and_up :: proc{
quaternion_from_forward_and_up_f16,
quaternion_from_forward_and_up_f32,
quaternion_from_forward_and_up_f64,
-};
+}
quaternion_look_at_f16 :: proc(eye, centre: Vector3f16, up: Vector3f16) -> Quaternionf16 {
- return quaternion_from_matrix3(matrix3_look_at(eye, centre, up));
+ return quaternion_from_matrix3(matrix3_look_at(eye, centre, up))
}
quaternion_look_at_f32 :: proc(eye, centre: Vector3f32, up: Vector3f32) -> Quaternionf32 {
- return quaternion_from_matrix3(matrix3_look_at(eye, centre, up));
+ return quaternion_from_matrix3(matrix3_look_at(eye, centre, up))
}
quaternion_look_at_f64 :: proc(eye, centre: Vector3f64, up: Vector3f64) -> Quaternionf64 {
- return quaternion_from_matrix3(matrix3_look_at(eye, centre, up));
+ return quaternion_from_matrix3(matrix3_look_at(eye, centre, up))
}
quaternion_look_at :: proc{
quaternion_look_at_f16,
quaternion_look_at_f32,
quaternion_look_at_f64,
-};
+}
quaternion_nlerp_f16 :: proc(a, b: Quaternionf16, t: f16) -> (c: Quaternionf16) {
- c.x = a.x + (b.x-a.x)*t;
- c.y = a.y + (b.y-a.y)*t;
- c.z = a.z + (b.z-a.z)*t;
- c.w = a.w + (b.w-a.w)*t;
- return normalize(c);
+ c.x = a.x + (b.x-a.x)*t
+ c.y = a.y + (b.y-a.y)*t
+ c.z = a.z + (b.z-a.z)*t
+ c.w = a.w + (b.w-a.w)*t
+ return normalize(c)
}
quaternion_nlerp_f32 :: proc(a, b: Quaternionf32, t: f32) -> (c: Quaternionf32) {
- c.x = a.x + (b.x-a.x)*t;
- c.y = a.y + (b.y-a.y)*t;
- c.z = a.z + (b.z-a.z)*t;
- c.w = a.w + (b.w-a.w)*t;
- return normalize(c);
+ c.x = a.x + (b.x-a.x)*t
+ c.y = a.y + (b.y-a.y)*t
+ c.z = a.z + (b.z-a.z)*t
+ c.w = a.w + (b.w-a.w)*t
+ return normalize(c)
}
quaternion_nlerp_f64 :: proc(a, b: Quaternionf64, t: f64) -> (c: Quaternionf64) {
- c.x = a.x + (b.x-a.x)*t;
- c.y = a.y + (b.y-a.y)*t;
- c.z = a.z + (b.z-a.z)*t;
- c.w = a.w + (b.w-a.w)*t;
- return normalize(c);
+ c.x = a.x + (b.x-a.x)*t
+ c.y = a.y + (b.y-a.y)*t
+ c.z = a.z + (b.z-a.z)*t
+ c.w = a.w + (b.w-a.w)*t
+ return normalize(c)
}
quaternion_nlerp :: proc{
quaternion_nlerp_f16,
quaternion_nlerp_f32,
quaternion_nlerp_f64,
-};
+}
quaternion_slerp_f16 :: proc(x, y: Quaternionf16, t: f16) -> (q: Quaternionf16) {
- a, b := x, y;
- cos_angle := dot(a, b);
+ a, b := x, y
+ cos_angle := dot(a, b)
if cos_angle < 0 {
- b = -b;
- cos_angle = -cos_angle;
+ b = -b
+ cos_angle = -cos_angle
}
if cos_angle > 1 - F32_EPSILON {
- q.x = a.x + (b.x-a.x)*t;
- q.y = a.y + (b.y-a.y)*t;
- q.z = a.z + (b.z-a.z)*t;
- q.w = a.w + (b.w-a.w)*t;
- return;
+ q.x = a.x + (b.x-a.x)*t
+ q.y = a.y + (b.y-a.y)*t
+ q.z = a.z + (b.z-a.z)*t
+ q.w = a.w + (b.w-a.w)*t
+ return
}
- angle := math.acos(cos_angle);
- sin_angle := math.sin(angle);
- factor_a := math.sin((1-t) * angle) / sin_angle;
- factor_b := math.sin(t * angle) / sin_angle;
+ angle := math.acos(cos_angle)
+ sin_angle := math.sin(angle)
+ factor_a := math.sin((1-t) * angle) / sin_angle
+ factor_b := math.sin(t * angle) / sin_angle
- q.x = factor_a * a.x + factor_b * b.x;
- q.y = factor_a * a.y + factor_b * b.y;
- q.z = factor_a * a.z + factor_b * b.z;
- q.w = factor_a * a.w + factor_b * b.w;
- return;
+ q.x = factor_a * a.x + factor_b * b.x
+ q.y = factor_a * a.y + factor_b * b.y
+ q.z = factor_a * a.z + factor_b * b.z
+ q.w = factor_a * a.w + factor_b * b.w
+ return
}
quaternion_slerp_f32 :: proc(x, y: Quaternionf32, t: f32) -> (q: Quaternionf32) {
- a, b := x, y;
- cos_angle := dot(a, b);
+ a, b := x, y
+ cos_angle := dot(a, b)
if cos_angle < 0 {
- b = -b;
- cos_angle = -cos_angle;
+ b = -b
+ cos_angle = -cos_angle
}
if cos_angle > 1 - F32_EPSILON {
- q.x = a.x + (b.x-a.x)*t;
- q.y = a.y + (b.y-a.y)*t;
- q.z = a.z + (b.z-a.z)*t;
- q.w = a.w + (b.w-a.w)*t;
- return;
+ q.x = a.x + (b.x-a.x)*t
+ q.y = a.y + (b.y-a.y)*t
+ q.z = a.z + (b.z-a.z)*t
+ q.w = a.w + (b.w-a.w)*t
+ return
}
- angle := math.acos(cos_angle);
- sin_angle := math.sin(angle);
- factor_a := math.sin((1-t) * angle) / sin_angle;
- factor_b := math.sin(t * angle) / sin_angle;
+ angle := math.acos(cos_angle)
+ sin_angle := math.sin(angle)
+ factor_a := math.sin((1-t) * angle) / sin_angle
+ factor_b := math.sin(t * angle) / sin_angle
- q.x = factor_a * a.x + factor_b * b.x;
- q.y = factor_a * a.y + factor_b * b.y;
- q.z = factor_a * a.z + factor_b * b.z;
- q.w = factor_a * a.w + factor_b * b.w;
- return;
+ q.x = factor_a * a.x + factor_b * b.x
+ q.y = factor_a * a.y + factor_b * b.y
+ q.z = factor_a * a.z + factor_b * b.z
+ q.w = factor_a * a.w + factor_b * b.w
+ return
}
quaternion_slerp_f64 :: proc(x, y: Quaternionf64, t: f64) -> (q: Quaternionf64) {
- a, b := x, y;
- cos_angle := dot(a, b);
+ a, b := x, y
+ cos_angle := dot(a, b)
if cos_angle < 0 {
- b = -b;
- cos_angle = -cos_angle;
+ b = -b
+ cos_angle = -cos_angle
}
if cos_angle > 1 - F64_EPSILON {
- q.x = a.x + (b.x-a.x)*t;
- q.y = a.y + (b.y-a.y)*t;
- q.z = a.z + (b.z-a.z)*t;
- q.w = a.w + (b.w-a.w)*t;
- return;
+ q.x = a.x + (b.x-a.x)*t
+ q.y = a.y + (b.y-a.y)*t
+ q.z = a.z + (b.z-a.z)*t
+ q.w = a.w + (b.w-a.w)*t
+ return
}
- angle := math.acos(cos_angle);
- sin_angle := math.sin(angle);
- factor_a := math.sin((1-t) * angle) / sin_angle;
- factor_b := math.sin(t * angle) / sin_angle;
+ angle := math.acos(cos_angle)
+ sin_angle := math.sin(angle)
+ factor_a := math.sin((1-t) * angle) / sin_angle
+ factor_b := math.sin(t * angle) / sin_angle
- q.x = factor_a * a.x + factor_b * b.x;
- q.y = factor_a * a.y + factor_b * b.y;
- q.z = factor_a * a.z + factor_b * b.z;
- q.w = factor_a * a.w + factor_b * b.w;
- return;
+ q.x = factor_a * a.x + factor_b * b.x
+ q.y = factor_a * a.y + factor_b * b.y
+ q.z = factor_a * a.z + factor_b * b.z
+ q.w = factor_a * a.w + factor_b * b.w
+ return
}
quaternion_slerp :: proc{
quaternion_slerp_f16,
quaternion_slerp_f32,
quaternion_slerp_f64,
-};
+}
quaternion_squad_f16 :: proc(q1, q2, s1, s2: Quaternionf16, h: f16) -> Quaternionf16 {
- slerp :: quaternion_slerp;
- return slerp(slerp(q1, q2, h), slerp(s1, s2, h), 2 * (1 - h) * h);
+ slerp :: quaternion_slerp
+ return slerp(slerp(q1, q2, h), slerp(s1, s2, h), 2 * (1 - h) * h)
}
quaternion_squad_f32 :: proc(q1, q2, s1, s2: Quaternionf32, h: f32) -> Quaternionf32 {
- slerp :: quaternion_slerp;
- return slerp(slerp(q1, q2, h), slerp(s1, s2, h), 2 * (1 - h) * h);
+ slerp :: quaternion_slerp
+ return slerp(slerp(q1, q2, h), slerp(s1, s2, h), 2 * (1 - h) * h)
}
quaternion_squad_f64 :: proc(q1, q2, s1, s2: Quaternionf64, h: f64) -> Quaternionf64 {
- slerp :: quaternion_slerp;
- return slerp(slerp(q1, q2, h), slerp(s1, s2, h), 2 * (1 - h) * h);
+ slerp :: quaternion_slerp
+ return slerp(slerp(q1, q2, h), slerp(s1, s2, h), 2 * (1 - h) * h)
}
quaternion_squad :: proc{
quaternion_squad_f16,
quaternion_squad_f32,
quaternion_squad_f64,
-};
+}
quaternion_from_matrix4_f16 :: proc(m: Matrix4f16) -> (q: Quaternionf16) {
- m3: Matrix3f16 = ---;
- m3[0][0], m3[0][1], m3[0][2] = m[0][0], m[0][1], m[0][2];
- m3[1][0], m3[1][1], m3[1][2] = m[1][0], m[1][1], m[1][2];
- m3[2][0], m3[2][1], m3[2][2] = m[2][0], m[2][1], m[2][2];
- return quaternion_from_matrix3(m3);
+ m3: Matrix3f16 = ---
+ m3[0][0], m3[0][1], m3[0][2] = m[0][0], m[0][1], m[0][2]
+ m3[1][0], m3[1][1], m3[1][2] = m[1][0], m[1][1], m[1][2]
+ m3[2][0], m3[2][1], m3[2][2] = m[2][0], m[2][1], m[2][2]
+ return quaternion_from_matrix3(m3)
}
quaternion_from_matrix4_f32 :: proc(m: Matrix4f32) -> (q: Quaternionf32) {
- m3: Matrix3f32 = ---;
- m3[0][0], m3[0][1], m3[0][2] = m[0][0], m[0][1], m[0][2];
- m3[1][0], m3[1][1], m3[1][2] = m[1][0], m[1][1], m[1][2];
- m3[2][0], m3[2][1], m3[2][2] = m[2][0], m[2][1], m[2][2];
- return quaternion_from_matrix3(m3);
+ m3: Matrix3f32 = ---
+ m3[0][0], m3[0][1], m3[0][2] = m[0][0], m[0][1], m[0][2]
+ m3[1][0], m3[1][1], m3[1][2] = m[1][0], m[1][1], m[1][2]
+ m3[2][0], m3[2][1], m3[2][2] = m[2][0], m[2][1], m[2][2]
+ return quaternion_from_matrix3(m3)
}
quaternion_from_matrix4_f64 :: proc(m: Matrix4f64) -> (q: Quaternionf64) {
- m3: Matrix3f64 = ---;
- m3[0][0], m3[0][1], m3[0][2] = m[0][0], m[0][1], m[0][2];
- m3[1][0], m3[1][1], m3[1][2] = m[1][0], m[1][1], m[1][2];
- m3[2][0], m3[2][1], m3[2][2] = m[2][0], m[2][1], m[2][2];
- return quaternion_from_matrix3(m3);
+ m3: Matrix3f64 = ---
+ m3[0][0], m3[0][1], m3[0][2] = m[0][0], m[0][1], m[0][2]
+ m3[1][0], m3[1][1], m3[1][2] = m[1][0], m[1][1], m[1][2]
+ m3[2][0], m3[2][1], m3[2][2] = m[2][0], m[2][1], m[2][2]
+ return quaternion_from_matrix3(m3)
}
quaternion_from_matrix4 :: proc{
quaternion_from_matrix4_f16,
quaternion_from_matrix4_f32,
quaternion_from_matrix4_f64,
-};
+}
quaternion_from_matrix3_f16 :: proc(m: Matrix3f16) -> (q: Quaternionf16) {
- four_x_squared_minus_1 := m[0][0] - m[1][1] - m[2][2];
- four_y_squared_minus_1 := m[1][1] - m[0][0] - m[2][2];
- four_z_squared_minus_1 := m[2][2] - m[0][0] - m[1][1];
- four_w_squared_minus_1 := m[0][0] + m[1][1] + m[2][2];
+ four_x_squared_minus_1 := m[0][0] - m[1][1] - m[2][2]
+ four_y_squared_minus_1 := m[1][1] - m[0][0] - m[2][2]
+ four_z_squared_minus_1 := m[2][2] - m[0][0] - m[1][1]
+ four_w_squared_minus_1 := m[0][0] + m[1][1] + m[2][2]
- biggest_index := 0;
- four_biggest_squared_minus_1 := four_w_squared_minus_1;
+ biggest_index := 0
+ four_biggest_squared_minus_1 := four_w_squared_minus_1
if four_x_squared_minus_1 > four_biggest_squared_minus_1 {
- four_biggest_squared_minus_1 = four_x_squared_minus_1;
- biggest_index = 1;
+ four_biggest_squared_minus_1 = four_x_squared_minus_1
+ biggest_index = 1
}
if four_y_squared_minus_1 > four_biggest_squared_minus_1 {
- four_biggest_squared_minus_1 = four_y_squared_minus_1;
- biggest_index = 2;
+ four_biggest_squared_minus_1 = four_y_squared_minus_1
+ biggest_index = 2
}
if four_z_squared_minus_1 > four_biggest_squared_minus_1 {
- four_biggest_squared_minus_1 = four_z_squared_minus_1;
- biggest_index = 3;
+ four_biggest_squared_minus_1 = four_z_squared_minus_1
+ biggest_index = 3
}
- biggest_val := math.sqrt(four_biggest_squared_minus_1 + 1) * 0.5;
- mult := 0.25 / biggest_val;
+ biggest_val := math.sqrt(four_biggest_squared_minus_1 + 1) * 0.5
+ mult := 0.25 / biggest_val
- q = 1;
+ q = 1
switch biggest_index {
case 0:
- q.w = biggest_val;
- q.x = (m[1][2] - m[2][1]) * mult;
- q.y = (m[2][0] - m[0][2]) * mult;
- q.z = (m[0][1] - m[1][0]) * mult;
+ q.w = biggest_val
+ q.x = (m[1][2] - m[2][1]) * mult
+ q.y = (m[2][0] - m[0][2]) * mult
+ q.z = (m[0][1] - m[1][0]) * mult
case 1:
- q.w = (m[1][2] - m[2][1]) * mult;
- q.x = biggest_val;
- q.y = (m[0][1] + m[1][0]) * mult;
- q.z = (m[2][0] + m[0][2]) * mult;
+ q.w = (m[1][2] - m[2][1]) * mult
+ q.x = biggest_val
+ q.y = (m[0][1] + m[1][0]) * mult
+ q.z = (m[2][0] + m[0][2]) * mult
case 2:
- q.w = (m[2][0] - m[0][2]) * mult;
- q.x = (m[0][1] + m[1][0]) * mult;
- q.y = biggest_val;
- q.z = (m[1][2] + m[2][1]) * mult;
+ q.w = (m[2][0] - m[0][2]) * mult
+ q.x = (m[0][1] + m[1][0]) * mult
+ q.y = biggest_val
+ q.z = (m[1][2] + m[2][1]) * mult
case 3:
- q.w = (m[0][1] - m[1][0]) * mult;
- q.x = (m[2][0] + m[0][2]) * mult;
- q.y = (m[1][2] + m[2][1]) * mult;
- q.z = biggest_val;
+ q.w = (m[0][1] - m[1][0]) * mult
+ q.x = (m[2][0] + m[0][2]) * mult
+ q.y = (m[1][2] + m[2][1]) * mult
+ q.z = biggest_val
}
- return;
+ return
}
quaternion_from_matrix3_f32 :: proc(m: Matrix3f32) -> (q: Quaternionf32) {
- four_x_squared_minus_1 := m[0][0] - m[1][1] - m[2][2];
- four_y_squared_minus_1 := m[1][1] - m[0][0] - m[2][2];
- four_z_squared_minus_1 := m[2][2] - m[0][0] - m[1][1];
- four_w_squared_minus_1 := m[0][0] + m[1][1] + m[2][2];
+ four_x_squared_minus_1 := m[0][0] - m[1][1] - m[2][2]
+ four_y_squared_minus_1 := m[1][1] - m[0][0] - m[2][2]
+ four_z_squared_minus_1 := m[2][2] - m[0][0] - m[1][1]
+ four_w_squared_minus_1 := m[0][0] + m[1][1] + m[2][2]
- biggest_index := 0;
- four_biggest_squared_minus_1 := four_w_squared_minus_1;
+ biggest_index := 0
+ four_biggest_squared_minus_1 := four_w_squared_minus_1
if four_x_squared_minus_1 > four_biggest_squared_minus_1 {
- four_biggest_squared_minus_1 = four_x_squared_minus_1;
- biggest_index = 1;
+ four_biggest_squared_minus_1 = four_x_squared_minus_1
+ biggest_index = 1
}
if four_y_squared_minus_1 > four_biggest_squared_minus_1 {
- four_biggest_squared_minus_1 = four_y_squared_minus_1;
- biggest_index = 2;
+ four_biggest_squared_minus_1 = four_y_squared_minus_1
+ biggest_index = 2
}
if four_z_squared_minus_1 > four_biggest_squared_minus_1 {
- four_biggest_squared_minus_1 = four_z_squared_minus_1;
- biggest_index = 3;
+ four_biggest_squared_minus_1 = four_z_squared_minus_1
+ biggest_index = 3
}
- biggest_val := math.sqrt(four_biggest_squared_minus_1 + 1) * 0.5;
- mult := 0.25 / biggest_val;
+ biggest_val := math.sqrt(four_biggest_squared_minus_1 + 1) * 0.5
+ mult := 0.25 / biggest_val
- q = 1;
+ q = 1
switch biggest_index {
case 0:
- q.w = biggest_val;
- q.x = (m[1][2] - m[2][1]) * mult;
- q.y = (m[2][0] - m[0][2]) * mult;
- q.z = (m[0][1] - m[1][0]) * mult;
+ q.w = biggest_val
+ q.x = (m[1][2] - m[2][1]) * mult
+ q.y = (m[2][0] - m[0][2]) * mult
+ q.z = (m[0][1] - m[1][0]) * mult
case 1:
- q.w = (m[1][2] - m[2][1]) * mult;
- q.x = biggest_val;
- q.y = (m[0][1] + m[1][0]) * mult;
- q.z = (m[2][0] + m[0][2]) * mult;
+ q.w = (m[1][2] - m[2][1]) * mult
+ q.x = biggest_val
+ q.y = (m[0][1] + m[1][0]) * mult
+ q.z = (m[2][0] + m[0][2]) * mult
case 2:
- q.w = (m[2][0] - m[0][2]) * mult;
- q.x = (m[0][1] + m[1][0]) * mult;
- q.y = biggest_val;
- q.z = (m[1][2] + m[2][1]) * mult;
+ q.w = (m[2][0] - m[0][2]) * mult
+ q.x = (m[0][1] + m[1][0]) * mult
+ q.y = biggest_val
+ q.z = (m[1][2] + m[2][1]) * mult
case 3:
- q.w = (m[0][1] - m[1][0]) * mult;
- q.x = (m[2][0] + m[0][2]) * mult;
- q.y = (m[1][2] + m[2][1]) * mult;
- q.z = biggest_val;
+ q.w = (m[0][1] - m[1][0]) * mult
+ q.x = (m[2][0] + m[0][2]) * mult
+ q.y = (m[1][2] + m[2][1]) * mult
+ q.z = biggest_val
}
- return;
+ return
}
quaternion_from_matrix3_f64 :: proc(m: Matrix3f64) -> (q: Quaternionf64) {
- four_x_squared_minus_1 := m[0][0] - m[1][1] - m[2][2];
- four_y_squared_minus_1 := m[1][1] - m[0][0] - m[2][2];
- four_z_squared_minus_1 := m[2][2] - m[0][0] - m[1][1];
- four_w_squared_minus_1 := m[0][0] + m[1][1] + m[2][2];
+ four_x_squared_minus_1 := m[0][0] - m[1][1] - m[2][2]
+ four_y_squared_minus_1 := m[1][1] - m[0][0] - m[2][2]
+ four_z_squared_minus_1 := m[2][2] - m[0][0] - m[1][1]
+ four_w_squared_minus_1 := m[0][0] + m[1][1] + m[2][2]
- biggest_index := 0;
- four_biggest_squared_minus_1 := four_w_squared_minus_1;
+ biggest_index := 0
+ four_biggest_squared_minus_1 := four_w_squared_minus_1
if four_x_squared_minus_1 > four_biggest_squared_minus_1 {
- four_biggest_squared_minus_1 = four_x_squared_minus_1;
- biggest_index = 1;
+ four_biggest_squared_minus_1 = four_x_squared_minus_1
+ biggest_index = 1
}
if four_y_squared_minus_1 > four_biggest_squared_minus_1 {
- four_biggest_squared_minus_1 = four_y_squared_minus_1;
- biggest_index = 2;
+ four_biggest_squared_minus_1 = four_y_squared_minus_1
+ biggest_index = 2
}
if four_z_squared_minus_1 > four_biggest_squared_minus_1 {
- four_biggest_squared_minus_1 = four_z_squared_minus_1;
- biggest_index = 3;
+ four_biggest_squared_minus_1 = four_z_squared_minus_1
+ biggest_index = 3
}
- biggest_val := math.sqrt(four_biggest_squared_minus_1 + 1) * 0.5;
- mult := 0.25 / biggest_val;
+ biggest_val := math.sqrt(four_biggest_squared_minus_1 + 1) * 0.5
+ mult := 0.25 / biggest_val
- q = 1;
+ q = 1
switch biggest_index {
case 0:
- q.w = biggest_val;
- q.x = (m[1][2] - m[2][1]) * mult;
- q.y = (m[2][0] - m[0][2]) * mult;
- q.z = (m[0][1] - m[1][0]) * mult;
+ q.w = biggest_val
+ q.x = (m[1][2] - m[2][1]) * mult
+ q.y = (m[2][0] - m[0][2]) * mult
+ q.z = (m[0][1] - m[1][0]) * mult
case 1:
- q.w = (m[1][2] - m[2][1]) * mult;
- q.x = biggest_val;
- q.y = (m[0][1] + m[1][0]) * mult;
- q.z = (m[2][0] + m[0][2]) * mult;
+ q.w = (m[1][2] - m[2][1]) * mult
+ q.x = biggest_val
+ q.y = (m[0][1] + m[1][0]) * mult
+ q.z = (m[2][0] + m[0][2]) * mult
case 2:
- q.w = (m[2][0] - m[0][2]) * mult;
- q.x = (m[0][1] + m[1][0]) * mult;
- q.y = biggest_val;
- q.z = (m[1][2] + m[2][1]) * mult;
+ q.w = (m[2][0] - m[0][2]) * mult
+ q.x = (m[0][1] + m[1][0]) * mult
+ q.y = biggest_val
+ q.z = (m[1][2] + m[2][1]) * mult
case 3:
- q.w = (m[0][1] - m[1][0]) * mult;
- q.x = (m[2][0] + m[0][2]) * mult;
- q.y = (m[1][2] + m[2][1]) * mult;
- q.z = biggest_val;
+ q.w = (m[0][1] - m[1][0]) * mult
+ q.x = (m[2][0] + m[0][2]) * mult
+ q.y = (m[1][2] + m[2][1]) * mult
+ q.z = biggest_val
}
- return;
+ return
}
quaternion_from_matrix3 :: proc{
quaternion_from_matrix3_f16,
quaternion_from_matrix3_f32,
quaternion_from_matrix3_f64,
-};
+}
quaternion_between_two_vector3_f16 :: proc(from, to: Vector3f16) -> (q: Quaternionf16) {
- x := normalize(from);
- y := normalize(to);
+ x := normalize(from)
+ y := normalize(to)
- cos_theta := dot(x, y);
+ cos_theta := dot(x, y)
if abs(cos_theta + 1) < 2*F32_EPSILON {
- v := vector3_orthogonal(x);
- q.x = v.x;
- q.y = v.y;
- q.z = v.z;
- q.w = 0;
- return;
- }
- v := cross(x, y);
- w := cos_theta + 1;
- q.w = w;
- q.x = v.x;
- q.y = v.y;
- q.z = v.z;
- return normalize(q);
+ v := vector3_orthogonal(x)
+ q.x = v.x
+ q.y = v.y
+ q.z = v.z
+ q.w = 0
+ return
+ }
+ v := cross(x, y)
+ w := cos_theta + 1
+ q.w = w
+ q.x = v.x
+ q.y = v.y
+ q.z = v.z
+ return normalize(q)
}
quaternion_between_two_vector3_f32 :: proc(from, to: Vector3f32) -> (q: Quaternionf32) {
- x := normalize(from);
- y := normalize(to);
+ x := normalize(from)
+ y := normalize(to)
- cos_theta := dot(x, y);
+ cos_theta := dot(x, y)
if abs(cos_theta + 1) < 2*F32_EPSILON {
- v := vector3_orthogonal(x);
- q.x = v.x;
- q.y = v.y;
- q.z = v.z;
- q.w = 0;
- return;
- }
- v := cross(x, y);
- w := cos_theta + 1;
- q.w = w;
- q.x = v.x;
- q.y = v.y;
- q.z = v.z;
- return normalize(q);
+ v := vector3_orthogonal(x)
+ q.x = v.x
+ q.y = v.y
+ q.z = v.z
+ q.w = 0
+ return
+ }
+ v := cross(x, y)
+ w := cos_theta + 1
+ q.w = w
+ q.x = v.x
+ q.y = v.y
+ q.z = v.z
+ return normalize(q)
}
quaternion_between_two_vector3_f64 :: proc(from, to: Vector3f64) -> (q: Quaternionf64) {
- x := normalize(from);
- y := normalize(to);
+ x := normalize(from)
+ y := normalize(to)
- cos_theta := dot(x, y);
+ cos_theta := dot(x, y)
if abs(cos_theta + 1) < 2*F64_EPSILON {
- v := vector3_orthogonal(x);
- q.x = v.x;
- q.y = v.y;
- q.z = v.z;
- q.w = 0;
- return;
- }
- v := cross(x, y);
- w := cos_theta + 1;
- q.w = w;
- q.x = v.x;
- q.y = v.y;
- q.z = v.z;
- return normalize(q);
+ v := vector3_orthogonal(x)
+ q.x = v.x
+ q.y = v.y
+ q.z = v.z
+ q.w = 0
+ return
+ }
+ v := cross(x, y)
+ w := cos_theta + 1
+ q.w = w
+ q.x = v.x
+ q.y = v.y
+ q.z = v.z
+ return normalize(q)
}
quaternion_between_two_vector3 :: proc{
quaternion_between_two_vector3_f16,
quaternion_between_two_vector3_f32,
quaternion_between_two_vector3_f64,
-};
+}
matrix2_inverse_transpose_f16 :: proc(m: Matrix2f16) -> (c: Matrix2f16) {
- d := m[0][0]*m[1][1] - m[1][0]*m[0][1];
- id := 1.0/d;
- c[0][0] = +m[1][1] * id;
- c[0][1] = -m[0][1] * id;
- c[1][0] = -m[1][0] * id;
- c[1][1] = +m[0][0] * id;
- return c;
+ d := m[0][0]*m[1][1] - m[1][0]*m[0][1]
+ id := 1.0/d
+ c[0][0] = +m[1][1] * id
+ c[0][1] = -m[0][1] * id
+ c[1][0] = -m[1][0] * id
+ c[1][1] = +m[0][0] * id
+ return c
}
matrix2_inverse_transpose_f32 :: proc(m: Matrix2f32) -> (c: Matrix2f32) {
- d := m[0][0]*m[1][1] - m[1][0]*m[0][1];
- id := 1.0/d;
- c[0][0] = +m[1][1] * id;
- c[0][1] = -m[0][1] * id;
- c[1][0] = -m[1][0] * id;
- c[1][1] = +m[0][0] * id;
- return c;
+ d := m[0][0]*m[1][1] - m[1][0]*m[0][1]
+ id := 1.0/d
+ c[0][0] = +m[1][1] * id
+ c[0][1] = -m[0][1] * id
+ c[1][0] = -m[1][0] * id
+ c[1][1] = +m[0][0] * id
+ return c
}
matrix2_inverse_transpose_f64 :: proc(m: Matrix2f64) -> (c: Matrix2f64) {
- d := m[0][0]*m[1][1] - m[1][0]*m[0][1];
- id := 1.0/d;
- c[0][0] = +m[1][1] * id;
- c[0][1] = -m[0][1] * id;
- c[1][0] = -m[1][0] * id;
- c[1][1] = +m[0][0] * id;
- return c;
+ d := m[0][0]*m[1][1] - m[1][0]*m[0][1]
+ id := 1.0/d
+ c[0][0] = +m[1][1] * id
+ c[0][1] = -m[0][1] * id
+ c[1][0] = -m[1][0] * id
+ c[1][1] = +m[0][0] * id
+ return c
}
matrix2_inverse_transpose :: proc{
matrix2_inverse_transpose_f16,
matrix2_inverse_transpose_f32,
matrix2_inverse_transpose_f64,
-};
+}
matrix2_determinant_f16 :: proc(m: Matrix2f16) -> f16 {
- return m[0][0]*m[1][1] - m[1][0]*m[0][1];
+ return m[0][0]*m[1][1] - m[1][0]*m[0][1]
}
matrix2_determinant_f32 :: proc(m: Matrix2f32) -> f32 {
- return m[0][0]*m[1][1] - m[1][0]*m[0][1];
+ return m[0][0]*m[1][1] - m[1][0]*m[0][1]
}
matrix2_determinant_f64 :: proc(m: Matrix2f64) -> f64 {
- return m[0][0]*m[1][1] - m[1][0]*m[0][1];
+ return m[0][0]*m[1][1] - m[1][0]*m[0][1]
}
matrix2_determinant :: proc{
matrix2_determinant_f16,
matrix2_determinant_f32,
matrix2_determinant_f64,
-};
+}
matrix2_inverse_f16 :: proc(m: Matrix2f16) -> (c: Matrix2f16) {
- d := m[0][0]*m[1][1] - m[1][0]*m[0][1];
- id := 1.0/d;
- c[0][0] = +m[1][1] * id;
- c[1][0] = -m[0][1] * id;
- c[0][1] = -m[1][0] * id;
- c[1][1] = +m[0][0] * id;
- return c;
+ d := m[0][0]*m[1][1] - m[1][0]*m[0][1]
+ id := 1.0/d
+ c[0][0] = +m[1][1] * id
+ c[1][0] = -m[0][1] * id
+ c[0][1] = -m[1][0] * id
+ c[1][1] = +m[0][0] * id
+ return c
}
matrix2_inverse_f32 :: proc(m: Matrix2f32) -> (c: Matrix2f32) {
- d := m[0][0]*m[1][1] - m[1][0]*m[0][1];
- id := 1.0/d;
- c[0][0] = +m[1][1] * id;
- c[1][0] = -m[0][1] * id;
- c[0][1] = -m[1][0] * id;
- c[1][1] = +m[0][0] * id;
- return c;
+ d := m[0][0]*m[1][1] - m[1][0]*m[0][1]
+ id := 1.0/d
+ c[0][0] = +m[1][1] * id
+ c[1][0] = -m[0][1] * id
+ c[0][1] = -m[1][0] * id
+ c[1][1] = +m[0][0] * id
+ return c
}
matrix2_inverse_f64 :: proc(m: Matrix2f64) -> (c: Matrix2f64) {
- d := m[0][0]*m[1][1] - m[1][0]*m[0][1];
- id := 1.0/d;
- c[0][0] = +m[1][1] * id;
- c[1][0] = -m[0][1] * id;
- c[0][1] = -m[1][0] * id;
- c[1][1] = +m[0][0] * id;
- return c;
+ d := m[0][0]*m[1][1] - m[1][0]*m[0][1]
+ id := 1.0/d
+ c[0][0] = +m[1][1] * id
+ c[1][0] = -m[0][1] * id
+ c[0][1] = -m[1][0] * id
+ c[1][1] = +m[0][0] * id
+ return c
}
matrix2_inverse :: proc{
matrix2_inverse_f16,
matrix2_inverse_f32,
matrix2_inverse_f64,
-};
+}
matrix2_adjoint_f16 :: proc(m: Matrix2f16) -> (c: Matrix2f16) {
- c[0][0] = +m[1][1];
- c[0][1] = -m[1][0];
- c[1][0] = -m[0][1];
- c[1][1] = +m[0][0];
- return c;
+ c[0][0] = +m[1][1]
+ c[0][1] = -m[1][0]
+ c[1][0] = -m[0][1]
+ c[1][1] = +m[0][0]
+ return c
}
matrix2_adjoint_f32 :: proc(m: Matrix2f32) -> (c: Matrix2f32) {
- c[0][0] = +m[1][1];
- c[0][1] = -m[1][0];
- c[1][0] = -m[0][1];
- c[1][1] = +m[0][0];
- return c;
+ c[0][0] = +m[1][1]
+ c[0][1] = -m[1][0]
+ c[1][0] = -m[0][1]
+ c[1][1] = +m[0][0]
+ return c
}
matrix2_adjoint_f64 :: proc(m: Matrix2f64) -> (c: Matrix2f64) {
- c[0][0] = +m[1][1];
- c[0][1] = -m[1][0];
- c[1][0] = -m[0][1];
- c[1][1] = +m[0][0];
- return c;
+ c[0][0] = +m[1][1]
+ c[0][1] = -m[1][0]
+ c[1][0] = -m[0][1]
+ c[1][1] = +m[0][0]
+ return c
}
matrix2_adjoint :: proc{
matrix2_adjoint_f16,
matrix2_adjoint_f32,
matrix2_adjoint_f64,
-};
+}
matrix3_from_quaternion_f16 :: proc(q: Quaternionf16) -> (m: Matrix3f16) {
- qxx := q.x * q.x;
- qyy := q.y * q.y;
- qzz := q.z * q.z;
- qxz := q.x * q.z;
- qxy := q.x * q.y;
- qyz := q.y * q.z;
- qwx := q.w * q.x;
- qwy := q.w * q.y;
- qwz := q.w * q.z;
-
- m[0][0] = 1 - 2 * (qyy + qzz);
- m[0][1] = 2 * (qxy + qwz);
- m[0][2] = 2 * (qxz - qwy);
-
- m[1][0] = 2 * (qxy - qwz);
- m[1][1] = 1 - 2 * (qxx + qzz);
- m[1][2] = 2 * (qyz + qwx);
-
- m[2][0] = 2 * (qxz + qwy);
- m[2][1] = 2 * (qyz - qwx);
- m[2][2] = 1 - 2 * (qxx + qyy);
- return m;
+ qxx := q.x * q.x
+ qyy := q.y * q.y
+ qzz := q.z * q.z
+ qxz := q.x * q.z
+ qxy := q.x * q.y
+ qyz := q.y * q.z
+ qwx := q.w * q.x
+ qwy := q.w * q.y
+ qwz := q.w * q.z
+
+ m[0][0] = 1 - 2 * (qyy + qzz)
+ m[0][1] = 2 * (qxy + qwz)
+ m[0][2] = 2 * (qxz - qwy)
+
+ m[1][0] = 2 * (qxy - qwz)
+ m[1][1] = 1 - 2 * (qxx + qzz)
+ m[1][2] = 2 * (qyz + qwx)
+
+ m[2][0] = 2 * (qxz + qwy)
+ m[2][1] = 2 * (qyz - qwx)
+ m[2][2] = 1 - 2 * (qxx + qyy)
+ return m
}
matrix3_from_quaternion_f32 :: proc(q: Quaternionf32) -> (m: Matrix3f32) {
- qxx := q.x * q.x;
- qyy := q.y * q.y;
- qzz := q.z * q.z;
- qxz := q.x * q.z;
- qxy := q.x * q.y;
- qyz := q.y * q.z;
- qwx := q.w * q.x;
- qwy := q.w * q.y;
- qwz := q.w * q.z;
-
- m[0][0] = 1 - 2 * (qyy + qzz);
- m[0][1] = 2 * (qxy + qwz);
- m[0][2] = 2 * (qxz - qwy);
-
- m[1][0] = 2 * (qxy - qwz);
- m[1][1] = 1 - 2 * (qxx + qzz);
- m[1][2] = 2 * (qyz + qwx);
-
- m[2][0] = 2 * (qxz + qwy);
- m[2][1] = 2 * (qyz - qwx);
- m[2][2] = 1 - 2 * (qxx + qyy);
- return m;
+ qxx := q.x * q.x
+ qyy := q.y * q.y
+ qzz := q.z * q.z
+ qxz := q.x * q.z
+ qxy := q.x * q.y
+ qyz := q.y * q.z
+ qwx := q.w * q.x
+ qwy := q.w * q.y
+ qwz := q.w * q.z
+
+ m[0][0] = 1 - 2 * (qyy + qzz)
+ m[0][1] = 2 * (qxy + qwz)
+ m[0][2] = 2 * (qxz - qwy)
+
+ m[1][0] = 2 * (qxy - qwz)
+ m[1][1] = 1 - 2 * (qxx + qzz)
+ m[1][2] = 2 * (qyz + qwx)
+
+ m[2][0] = 2 * (qxz + qwy)
+ m[2][1] = 2 * (qyz - qwx)
+ m[2][2] = 1 - 2 * (qxx + qyy)
+ return m
}
matrix3_from_quaternion_f64 :: proc(q: Quaternionf64) -> (m: Matrix3f64) {
- qxx := q.x * q.x;
- qyy := q.y * q.y;
- qzz := q.z * q.z;
- qxz := q.x * q.z;
- qxy := q.x * q.y;
- qyz := q.y * q.z;
- qwx := q.w * q.x;
- qwy := q.w * q.y;
- qwz := q.w * q.z;
-
- m[0][0] = 1 - 2 * (qyy + qzz);
- m[0][1] = 2 * (qxy + qwz);
- m[0][2] = 2 * (qxz - qwy);
-
- m[1][0] = 2 * (qxy - qwz);
- m[1][1] = 1 - 2 * (qxx + qzz);
- m[1][2] = 2 * (qyz + qwx);
-
- m[2][0] = 2 * (qxz + qwy);
- m[2][1] = 2 * (qyz - qwx);
- m[2][2] = 1 - 2 * (qxx + qyy);
- return m;
+ qxx := q.x * q.x
+ qyy := q.y * q.y
+ qzz := q.z * q.z
+ qxz := q.x * q.z
+ qxy := q.x * q.y
+ qyz := q.y * q.z
+ qwx := q.w * q.x
+ qwy := q.w * q.y
+ qwz := q.w * q.z
+
+ m[0][0] = 1 - 2 * (qyy + qzz)
+ m[0][1] = 2 * (qxy + qwz)
+ m[0][2] = 2 * (qxz - qwy)
+
+ m[1][0] = 2 * (qxy - qwz)
+ m[1][1] = 1 - 2 * (qxx + qzz)
+ m[1][2] = 2 * (qyz + qwx)
+
+ m[2][0] = 2 * (qxz + qwy)
+ m[2][1] = 2 * (qyz - qwx)
+ m[2][2] = 1 - 2 * (qxx + qyy)
+ return m
}
matrix3_from_quaternion :: proc{
matrix3_from_quaternion_f16,
matrix3_from_quaternion_f32,
matrix3_from_quaternion_f64,
-};
+}
matrix3_inverse_f16 :: proc(m: Matrix3f16) -> Matrix3f16 {
- return auto_cast transpose(matrix3_inverse_transpose(m));
+ return auto_cast transpose(matrix3_inverse_transpose(m))
}
matrix3_inverse_f32 :: proc(m: Matrix3f32) -> Matrix3f32 {
- return auto_cast transpose(matrix3_inverse_transpose(m));
+ return auto_cast transpose(matrix3_inverse_transpose(m))
}
matrix3_inverse_f64 :: proc(m: Matrix3f64) -> Matrix3f64 {
- return auto_cast transpose(matrix3_inverse_transpose(m));
+ return auto_cast transpose(matrix3_inverse_transpose(m))
}
matrix3_inverse :: proc{
matrix3_inverse_f16,
matrix3_inverse_f32,
matrix3_inverse_f64,
-};
+}
matrix3_determinant_f16 :: proc(m: Matrix3f16) -> f16 {
- a := +m[0][0] * (m[1][1] * m[2][2] - m[2][1] * m[1][2]);
- b := -m[1][0] * (m[0][1] * m[2][2] - m[2][1] * m[0][2]);
- c := +m[2][0] * (m[0][1] * m[1][2] - m[1][1] * m[0][2]);
- return a + b + c;
+ a := +m[0][0] * (m[1][1] * m[2][2] - m[2][1] * m[1][2])
+ b := -m[1][0] * (m[0][1] * m[2][2] - m[2][1] * m[0][2])
+ c := +m[2][0] * (m[0][1] * m[1][2] - m[1][1] * m[0][2])
+ return a + b + c
}
matrix3_determinant_f32 :: proc(m: Matrix3f32) -> f32 {
- a := +m[0][0] * (m[1][1] * m[2][2] - m[2][1] * m[1][2]);
- b := -m[1][0] * (m[0][1] * m[2][2] - m[2][1] * m[0][2]);
- c := +m[2][0] * (m[0][1] * m[1][2] - m[1][1] * m[0][2]);
- return a + b + c;
+ a := +m[0][0] * (m[1][1] * m[2][2] - m[2][1] * m[1][2])
+ b := -m[1][0] * (m[0][1] * m[2][2] - m[2][1] * m[0][2])
+ c := +m[2][0] * (m[0][1] * m[1][2] - m[1][1] * m[0][2])
+ return a + b + c
}
matrix3_determinant_f64 :: proc(m: Matrix3f64) -> f64 {
- a := +m[0][0] * (m[1][1] * m[2][2] - m[2][1] * m[1][2]);
- b := -m[1][0] * (m[0][1] * m[2][2] - m[2][1] * m[0][2]);
- c := +m[2][0] * (m[0][1] * m[1][2] - m[1][1] * m[0][2]);
- return a + b + c;
+ a := +m[0][0] * (m[1][1] * m[2][2] - m[2][1] * m[1][2])
+ b := -m[1][0] * (m[0][1] * m[2][2] - m[2][1] * m[0][2])
+ c := +m[2][0] * (m[0][1] * m[1][2] - m[1][1] * m[0][2])
+ return a + b + c
}
matrix3_determinant :: proc{
matrix3_determinant_f16,
matrix3_determinant_f32,
matrix3_determinant_f64,
-};
+}
matrix3_adjoint_f16 :: proc(m: Matrix3f16) -> (adjoint: Matrix3f16) {
- adjoint[0][0] = +(m[1][1] * m[2][2] - m[1][2] * m[2][1]);
- adjoint[1][0] = -(m[0][1] * m[2][2] - m[0][2] * m[2][1]);
- adjoint[2][0] = +(m[0][1] * m[1][2] - m[0][2] * m[1][1]);
- adjoint[0][1] = -(m[1][0] * m[2][2] - m[1][2] * m[2][0]);
- adjoint[1][1] = +(m[0][0] * m[2][2] - m[0][2] * m[2][0]);
- adjoint[2][1] = -(m[0][0] * m[1][2] - m[0][2] * m[1][0]);
- adjoint[0][2] = +(m[1][0] * m[2][1] - m[1][1] * m[2][0]);
- adjoint[1][2] = -(m[0][0] * m[2][1] - m[0][1] * m[2][0]);
- adjoint[2][2] = +(m[0][0] * m[1][1] - m[0][1] * m[1][0]);
- return adjoint;
+ adjoint[0][0] = +(m[1][1] * m[2][2] - m[1][2] * m[2][1])
+ adjoint[1][0] = -(m[0][1] * m[2][2] - m[0][2] * m[2][1])
+ adjoint[2][0] = +(m[0][1] * m[1][2] - m[0][2] * m[1][1])
+ adjoint[0][1] = -(m[1][0] * m[2][2] - m[1][2] * m[2][0])
+ adjoint[1][1] = +(m[0][0] * m[2][2] - m[0][2] * m[2][0])
+ adjoint[2][1] = -(m[0][0] * m[1][2] - m[0][2] * m[1][0])
+ adjoint[0][2] = +(m[1][0] * m[2][1] - m[1][1] * m[2][0])
+ adjoint[1][2] = -(m[0][0] * m[2][1] - m[0][1] * m[2][0])
+ adjoint[2][2] = +(m[0][0] * m[1][1] - m[0][1] * m[1][0])
+ return adjoint
}
matrix3_adjoint_f32 :: proc(m: Matrix3f32) -> (adjoint: Matrix3f32) {
- adjoint[0][0] = +(m[1][1] * m[2][2] - m[1][2] * m[2][1]);
- adjoint[1][0] = -(m[0][1] * m[2][2] - m[0][2] * m[2][1]);
- adjoint[2][0] = +(m[0][1] * m[1][2] - m[0][2] * m[1][1]);
- adjoint[0][1] = -(m[1][0] * m[2][2] - m[1][2] * m[2][0]);
- adjoint[1][1] = +(m[0][0] * m[2][2] - m[0][2] * m[2][0]);
- adjoint[2][1] = -(m[0][0] * m[1][2] - m[0][2] * m[1][0]);
- adjoint[0][2] = +(m[1][0] * m[2][1] - m[1][1] * m[2][0]);
- adjoint[1][2] = -(m[0][0] * m[2][1] - m[0][1] * m[2][0]);
- adjoint[2][2] = +(m[0][0] * m[1][1] - m[0][1] * m[1][0]);
- return adjoint;
+ adjoint[0][0] = +(m[1][1] * m[2][2] - m[1][2] * m[2][1])
+ adjoint[1][0] = -(m[0][1] * m[2][2] - m[0][2] * m[2][1])
+ adjoint[2][0] = +(m[0][1] * m[1][2] - m[0][2] * m[1][1])
+ adjoint[0][1] = -(m[1][0] * m[2][2] - m[1][2] * m[2][0])
+ adjoint[1][1] = +(m[0][0] * m[2][2] - m[0][2] * m[2][0])
+ adjoint[2][1] = -(m[0][0] * m[1][2] - m[0][2] * m[1][0])
+ adjoint[0][2] = +(m[1][0] * m[2][1] - m[1][1] * m[2][0])
+ adjoint[1][2] = -(m[0][0] * m[2][1] - m[0][1] * m[2][0])
+ adjoint[2][2] = +(m[0][0] * m[1][1] - m[0][1] * m[1][0])
+ return adjoint
}
matrix3_adjoint_f64 :: proc(m: Matrix3f64) -> (adjoint: Matrix3f64) {
- adjoint[0][0] = +(m[1][1] * m[2][2] - m[1][2] * m[2][1]);
- adjoint[1][0] = -(m[0][1] * m[2][2] - m[0][2] * m[2][1]);
- adjoint[2][0] = +(m[0][1] * m[1][2] - m[0][2] * m[1][1]);
- adjoint[0][1] = -(m[1][0] * m[2][2] - m[1][2] * m[2][0]);
- adjoint[1][1] = +(m[0][0] * m[2][2] - m[0][2] * m[2][0]);
- adjoint[2][1] = -(m[0][0] * m[1][2] - m[0][2] * m[1][0]);
- adjoint[0][2] = +(m[1][0] * m[2][1] - m[1][1] * m[2][0]);
- adjoint[1][2] = -(m[0][0] * m[2][1] - m[0][1] * m[2][0]);
- adjoint[2][2] = +(m[0][0] * m[1][1] - m[0][1] * m[1][0]);
- return adjoint;
+ adjoint[0][0] = +(m[1][1] * m[2][2] - m[1][2] * m[2][1])
+ adjoint[1][0] = -(m[0][1] * m[2][2] - m[0][2] * m[2][1])
+ adjoint[2][0] = +(m[0][1] * m[1][2] - m[0][2] * m[1][1])
+ adjoint[0][1] = -(m[1][0] * m[2][2] - m[1][2] * m[2][0])
+ adjoint[1][1] = +(m[0][0] * m[2][2] - m[0][2] * m[2][0])
+ adjoint[2][1] = -(m[0][0] * m[1][2] - m[0][2] * m[1][0])
+ adjoint[0][2] = +(m[1][0] * m[2][1] - m[1][1] * m[2][0])
+ adjoint[1][2] = -(m[0][0] * m[2][1] - m[0][1] * m[2][0])
+ adjoint[2][2] = +(m[0][0] * m[1][1] - m[0][1] * m[1][0])
+ return adjoint
}
matrix3_adjoint :: proc{
matrix3_adjoint_f16,
matrix3_adjoint_f32,
matrix3_adjoint_f64,
-};
+}
matrix3_inverse_transpose_f16 :: proc(m: Matrix3f16) -> (inverse_transpose: Matrix3f16) {
- adjoint := matrix3_adjoint(m);
- determinant := matrix3_determinant(m);
- inv_determinant := 1.0 / determinant;
+ adjoint := matrix3_adjoint(m)
+ determinant := matrix3_determinant(m)
+ inv_determinant := 1.0 / determinant
for i in 0..<3 {
for j in 0..<3 {
- inverse_transpose[i][j] = adjoint[i][j] * inv_determinant;
+ inverse_transpose[i][j] = adjoint[i][j] * inv_determinant
}
}
- return;
+ return
}
matrix3_inverse_transpose_f32 :: proc(m: Matrix3f32) -> (inverse_transpose: Matrix3f32) {
- adjoint := matrix3_adjoint(m);
- determinant := matrix3_determinant(m);
- inv_determinant := 1.0 / determinant;
+ adjoint := matrix3_adjoint(m)
+ determinant := matrix3_determinant(m)
+ inv_determinant := 1.0 / determinant
for i in 0..<3 {
for j in 0..<3 {
- inverse_transpose[i][j] = adjoint[i][j] * inv_determinant;
+ inverse_transpose[i][j] = adjoint[i][j] * inv_determinant
}
}
- return;
+ return
}
matrix3_inverse_transpose_f64 :: proc(m: Matrix3f64) -> (inverse_transpose: Matrix3f64) {
- adjoint := matrix3_adjoint(m);
- determinant := matrix3_determinant(m);
- inv_determinant := 1.0 / determinant;
+ adjoint := matrix3_adjoint(m)
+ determinant := matrix3_determinant(m)
+ inv_determinant := 1.0 / determinant
for i in 0..<3 {
for j in 0..<3 {
- inverse_transpose[i][j] = adjoint[i][j] * inv_determinant;
+ inverse_transpose[i][j] = adjoint[i][j] * inv_determinant
}
}
- return;
+ return
}
matrix3_inverse_transpose :: proc{
matrix3_inverse_transpose_f16,
matrix3_inverse_transpose_f32,
matrix3_inverse_transpose_f64,
-};
+}
matrix3_scale_f16 :: proc(s: Vector3f16) -> (m: Matrix3f16) {
- m[0][0] = s[0];
- m[1][1] = s[1];
- m[2][2] = s[2];
- return m;
+ m[0][0] = s[0]
+ m[1][1] = s[1]
+ m[2][2] = s[2]
+ return m
}
matrix3_scale_f32 :: proc(s: Vector3f32) -> (m: Matrix3f32) {
- m[0][0] = s[0];
- m[1][1] = s[1];
- m[2][2] = s[2];
- return m;
+ m[0][0] = s[0]
+ m[1][1] = s[1]
+ m[2][2] = s[2]
+ return m
}
matrix3_scale_f64 :: proc(s: Vector3f64) -> (m: Matrix3f64) {
- m[0][0] = s[0];
- m[1][1] = s[1];
- m[2][2] = s[2];
- return m;
+ m[0][0] = s[0]
+ m[1][1] = s[1]
+ m[2][2] = s[2]
+ return m
}
matrix3_scale :: proc{
matrix3_scale_f16,
matrix3_scale_f32,
matrix3_scale_f64,
-};
+}
matrix3_rotate_f16 :: proc(angle_radians: f16, v: Vector3f16) -> (rot: Matrix3f16) {
- c := math.cos(angle_radians);
- s := math.sin(angle_radians);
+ c := math.cos(angle_radians)
+ s := math.sin(angle_radians)
- a := normalize(v);
- t := a * (1-c);
+ a := normalize(v)
+ t := a * (1-c)
- rot[0][0] = c + t[0]*a[0];
- rot[0][1] = 0 + t[0]*a[1] + s*a[2];
- rot[0][2] = 0 + t[0]*a[2] - s*a[1];
+ rot[0][0] = c + t[0]*a[0]
+ rot[0][1] = 0 + t[0]*a[1] + s*a[2]
+ rot[0][2] = 0 + t[0]*a[2] - s*a[1]
- rot[1][0] = 0 + t[1]*a[0] - s*a[2];
- rot[1][1] = c + t[1]*a[1];
- rot[1][2] = 0 + t[1]*a[2] + s*a[0];
+ rot[1][0] = 0 + t[1]*a[0] - s*a[2]
+ rot[1][1] = c + t[1]*a[1]
+ rot[1][2] = 0 + t[1]*a[2] + s*a[0]
- rot[2][0] = 0 + t[2]*a[0] + s*a[1];
- rot[2][1] = 0 + t[2]*a[1] - s*a[0];
- rot[2][2] = c + t[2]*a[2];
+ rot[2][0] = 0 + t[2]*a[0] + s*a[1]
+ rot[2][1] = 0 + t[2]*a[1] - s*a[0]
+ rot[2][2] = c + t[2]*a[2]
- return rot;
+ return rot
}
matrix3_rotate_f32 :: proc(angle_radians: f32, v: Vector3f32) -> (rot: Matrix3f32) {
- c := math.cos(angle_radians);
- s := math.sin(angle_radians);
+ c := math.cos(angle_radians)
+ s := math.sin(angle_radians)
- a := normalize(v);
- t := a * (1-c);
+ a := normalize(v)
+ t := a * (1-c)
- rot[0][0] = c + t[0]*a[0];
- rot[0][1] = 0 + t[0]*a[1] + s*a[2];
- rot[0][2] = 0 + t[0]*a[2] - s*a[1];
+ rot[0][0] = c + t[0]*a[0]
+ rot[0][1] = 0 + t[0]*a[1] + s*a[2]
+ rot[0][2] = 0 + t[0]*a[2] - s*a[1]
- rot[1][0] = 0 + t[1]*a[0] - s*a[2];
- rot[1][1] = c + t[1]*a[1];
- rot[1][2] = 0 + t[1]*a[2] + s*a[0];
+ rot[1][0] = 0 + t[1]*a[0] - s*a[2]
+ rot[1][1] = c + t[1]*a[1]
+ rot[1][2] = 0 + t[1]*a[2] + s*a[0]
- rot[2][0] = 0 + t[2]*a[0] + s*a[1];
- rot[2][1] = 0 + t[2]*a[1] - s*a[0];
- rot[2][2] = c + t[2]*a[2];
+ rot[2][0] = 0 + t[2]*a[0] + s*a[1]
+ rot[2][1] = 0 + t[2]*a[1] - s*a[0]
+ rot[2][2] = c + t[2]*a[2]
- return rot;
+ return rot
}
matrix3_rotate_f64 :: proc(angle_radians: f64, v: Vector3f64) -> (rot: Matrix3f64) {
- c := math.cos(angle_radians);
- s := math.sin(angle_radians);
+ c := math.cos(angle_radians)
+ s := math.sin(angle_radians)
- a := normalize(v);
- t := a * (1-c);
+ a := normalize(v)
+ t := a * (1-c)
- rot[0][0] = c + t[0]*a[0];
- rot[0][1] = 0 + t[0]*a[1] + s*a[2];
- rot[0][2] = 0 + t[0]*a[2] - s*a[1];
+ rot[0][0] = c + t[0]*a[0]
+ rot[0][1] = 0 + t[0]*a[1] + s*a[2]
+ rot[0][2] = 0 + t[0]*a[2] - s*a[1]
- rot[1][0] = 0 + t[1]*a[0] - s*a[2];
- rot[1][1] = c + t[1]*a[1];
- rot[1][2] = 0 + t[1]*a[2] + s*a[0];
+ rot[1][0] = 0 + t[1]*a[0] - s*a[2]
+ rot[1][1] = c + t[1]*a[1]
+ rot[1][2] = 0 + t[1]*a[2] + s*a[0]
- rot[2][0] = 0 + t[2]*a[0] + s*a[1];
- rot[2][1] = 0 + t[2]*a[1] - s*a[0];
- rot[2][2] = c + t[2]*a[2];
+ rot[2][0] = 0 + t[2]*a[0] + s*a[1]
+ rot[2][1] = 0 + t[2]*a[1] - s*a[0]
+ rot[2][2] = c + t[2]*a[2]
- return rot;
+ return rot
}
matrix3_rotate :: proc{
matrix3_rotate_f16,
matrix3_rotate_f32,
matrix3_rotate_f64,
-};
+}
matrix3_look_at_f16 :: proc(eye, centre, up: Vector3f16) -> Matrix3f16 {
- f := normalize(centre - eye);
- s := normalize(cross(f, up));
- u := cross(s, f);
+ f := normalize(centre - eye)
+ s := normalize(cross(f, up))
+ u := cross(s, f)
return Matrix3f16{
{+s.x, +u.x, -f.x},
{+s.y, +u.y, -f.y},
{+s.z, +u.z, -f.z},
- };
+ }
}
matrix3_look_at_f32 :: proc(eye, centre, up: Vector3f32) -> Matrix3f32 {
- f := normalize(centre - eye);
- s := normalize(cross(f, up));
- u := cross(s, f);
+ f := normalize(centre - eye)
+ s := normalize(cross(f, up))
+ u := cross(s, f)
return Matrix3f32{
{+s.x, +u.x, -f.x},
{+s.y, +u.y, -f.y},
{+s.z, +u.z, -f.z},
- };
+ }
}
matrix3_look_at_f64 :: proc(eye, centre, up: Vector3f64) -> Matrix3f64 {
- f := normalize(centre - eye);
- s := normalize(cross(f, up));
- u := cross(s, f);
+ f := normalize(centre - eye)
+ s := normalize(cross(f, up))
+ u := cross(s, f)
return Matrix3f64{
{+s.x, +u.x, -f.x},
{+s.y, +u.y, -f.y},
{+s.z, +u.z, -f.z},
- };
+ }
}
matrix3_look_at :: proc{
matrix3_look_at_f16,
matrix3_look_at_f32,
matrix3_look_at_f64,
-};
+}
matrix4_from_quaternion_f16 :: proc(q: Quaternionf16) -> (m: Matrix4f16) {
- qxx := q.x * q.x;
- qyy := q.y * q.y;
- qzz := q.z * q.z;
- qxz := q.x * q.z;
- qxy := q.x * q.y;
- qyz := q.y * q.z;
- qwx := q.w * q.x;
- qwy := q.w * q.y;
- qwz := q.w * q.z;
+ qxx := q.x * q.x
+ qyy := q.y * q.y
+ qzz := q.z * q.z
+ qxz := q.x * q.z
+ qxy := q.x * q.y
+ qyz := q.y * q.z
+ qwx := q.w * q.x
+ qwy := q.w * q.y
+ qwz := q.w * q.z
- m[0][0] = 1 - 2 * (qyy + qzz);
- m[0][1] = 2 * (qxy + qwz);
- m[0][2] = 2 * (qxz - qwy);
+ m[0][0] = 1 - 2 * (qyy + qzz)
+ m[0][1] = 2 * (qxy + qwz)
+ m[0][2] = 2 * (qxz - qwy)
- m[1][0] = 2 * (qxy - qwz);
- m[1][1] = 1 - 2 * (qxx + qzz);
- m[1][2] = 2 * (qyz + qwx);
+ m[1][0] = 2 * (qxy - qwz)
+ m[1][1] = 1 - 2 * (qxx + qzz)
+ m[1][2] = 2 * (qyz + qwx)
- m[2][0] = 2 * (qxz + qwy);
- m[2][1] = 2 * (qyz - qwx);
- m[2][2] = 1 - 2 * (qxx + qyy);
+ m[2][0] = 2 * (qxz + qwy)
+ m[2][1] = 2 * (qyz - qwx)
+ m[2][2] = 1 - 2 * (qxx + qyy)
- m[3][3] = 1;
+ m[3][3] = 1
- return m;
+ return m
}
matrix4_from_quaternion_f32 :: proc(q: Quaternionf32) -> (m: Matrix4f32) {
- qxx := q.x * q.x;
- qyy := q.y * q.y;
- qzz := q.z * q.z;
- qxz := q.x * q.z;
- qxy := q.x * q.y;
- qyz := q.y * q.z;
- qwx := q.w * q.x;
- qwy := q.w * q.y;
- qwz := q.w * q.z;
+ qxx := q.x * q.x
+ qyy := q.y * q.y
+ qzz := q.z * q.z
+ qxz := q.x * q.z
+ qxy := q.x * q.y
+ qyz := q.y * q.z
+ qwx := q.w * q.x
+ qwy := q.w * q.y
+ qwz := q.w * q.z
- m[0][0] = 1 - 2 * (qyy + qzz);
- m[0][1] = 2 * (qxy + qwz);
- m[0][2] = 2 * (qxz - qwy);
+ m[0][0] = 1 - 2 * (qyy + qzz)
+ m[0][1] = 2 * (qxy + qwz)
+ m[0][2] = 2 * (qxz - qwy)
- m[1][0] = 2 * (qxy - qwz);
- m[1][1] = 1 - 2 * (qxx + qzz);
- m[1][2] = 2 * (qyz + qwx);
+ m[1][0] = 2 * (qxy - qwz)
+ m[1][1] = 1 - 2 * (qxx + qzz)
+ m[1][2] = 2 * (qyz + qwx)
- m[2][0] = 2 * (qxz + qwy);
- m[2][1] = 2 * (qyz - qwx);
- m[2][2] = 1 - 2 * (qxx + qyy);
+ m[2][0] = 2 * (qxz + qwy)
+ m[2][1] = 2 * (qyz - qwx)
+ m[2][2] = 1 - 2 * (qxx + qyy)
- m[3][3] = 1;
+ m[3][3] = 1
- return m;
+ return m
}
matrix4_from_quaternion_f64 :: proc(q: Quaternionf64) -> (m: Matrix4f64) {
- qxx := q.x * q.x;
- qyy := q.y * q.y;
- qzz := q.z * q.z;
- qxz := q.x * q.z;
- qxy := q.x * q.y;
- qyz := q.y * q.z;
- qwx := q.w * q.x;
- qwy := q.w * q.y;
- qwz := q.w * q.z;
+ qxx := q.x * q.x
+ qyy := q.y * q.y
+ qzz := q.z * q.z
+ qxz := q.x * q.z
+ qxy := q.x * q.y
+ qyz := q.y * q.z
+ qwx := q.w * q.x
+ qwy := q.w * q.y
+ qwz := q.w * q.z
- m[0][0] = 1 - 2 * (qyy + qzz);
- m[0][1] = 2 * (qxy + qwz);
- m[0][2] = 2 * (qxz - qwy);
+ m[0][0] = 1 - 2 * (qyy + qzz)
+ m[0][1] = 2 * (qxy + qwz)
+ m[0][2] = 2 * (qxz - qwy)
- m[1][0] = 2 * (qxy - qwz);
- m[1][1] = 1 - 2 * (qxx + qzz);
- m[1][2] = 2 * (qyz + qwx);
+ m[1][0] = 2 * (qxy - qwz)
+ m[1][1] = 1 - 2 * (qxx + qzz)
+ m[1][2] = 2 * (qyz + qwx)
- m[2][0] = 2 * (qxz + qwy);
- m[2][1] = 2 * (qyz - qwx);
- m[2][2] = 1 - 2 * (qxx + qyy);
+ m[2][0] = 2 * (qxz + qwy)
+ m[2][1] = 2 * (qyz - qwx)
+ m[2][2] = 1 - 2 * (qxx + qyy)
- m[3][3] = 1;
+ m[3][3] = 1
- return m;
+ return m
}
matrix4_from_quaternion :: proc{
matrix4_from_quaternion_f16,
matrix4_from_quaternion_f32,
matrix4_from_quaternion_f64,
-};
+}
matrix4_from_trs_f16 :: proc(t: Vector3f16, r: Quaternionf16, s: Vector3f16) -> Matrix4f16 {
- translation := matrix4_translate(t);
- rotation := matrix4_from_quaternion(r);
- scale := matrix4_scale(s);
- return mul(translation, mul(rotation, scale));
+ translation := matrix4_translate(t)
+ rotation := matrix4_from_quaternion(r)
+ scale := matrix4_scale(s)
+ return mul(translation, mul(rotation, scale))
}
matrix4_from_trs_f32 :: proc(t: Vector3f32, r: Quaternionf32, s: Vector3f32) -> Matrix4f32 {
- translation := matrix4_translate(t);
- rotation := matrix4_from_quaternion(r);
- scale := matrix4_scale(s);
- return mul(translation, mul(rotation, scale));
+ translation := matrix4_translate(t)
+ rotation := matrix4_from_quaternion(r)
+ scale := matrix4_scale(s)
+ return mul(translation, mul(rotation, scale))
}
matrix4_from_trs_f64 :: proc(t: Vector3f64, r: Quaternionf64, s: Vector3f64) -> Matrix4f64 {
- translation := matrix4_translate(t);
- rotation := matrix4_from_quaternion(r);
- scale := matrix4_scale(s);
- return mul(translation, mul(rotation, scale));
+ translation := matrix4_translate(t)
+ rotation := matrix4_from_quaternion(r)
+ scale := matrix4_scale(s)
+ return mul(translation, mul(rotation, scale))
}
matrix4_from_trs :: proc{
matrix4_from_trs_f16,
matrix4_from_trs_f32,
matrix4_from_trs_f64,
-};
+}
matrix4_inverse_f16 :: proc(m: Matrix4f16) -> Matrix4f16 {
- return auto_cast transpose(matrix4_inverse_transpose(m));
+ return auto_cast transpose(matrix4_inverse_transpose(m))
}
matrix4_inverse_f32 :: proc(m: Matrix4f32) -> Matrix4f32 {
- return auto_cast transpose(matrix4_inverse_transpose(m));
+ return auto_cast transpose(matrix4_inverse_transpose(m))
}
matrix4_inverse_f64 :: proc(m: Matrix4f64) -> Matrix4f64 {
- return auto_cast transpose(matrix4_inverse_transpose(m));
+ return auto_cast transpose(matrix4_inverse_transpose(m))
}
matrix4_inverse :: proc{
matrix4_inverse_f16,
matrix4_inverse_f32,
matrix4_inverse_f64,
-};
+}
matrix4_minor_f16 :: proc(m: Matrix4f16, c, r: int) -> f16 {
- cut_down: Matrix3f16;
+ cut_down: Matrix3f16
for i in 0..<3 {
- col := i if i < c else i+1;
+ col := i if i < c else i+1
for j in 0..<3 {
- row := j if j < r else j+1;
- cut_down[i][j] = m[col][row];
+ row := j if j < r else j+1
+ cut_down[i][j] = m[col][row]
}
}
- return matrix3_determinant(cut_down);
+ return matrix3_determinant(cut_down)
}
matrix4_minor_f32 :: proc(m: Matrix4f32, c, r: int) -> f32 {
- cut_down: Matrix3f32;
+ cut_down: Matrix3f32
for i in 0..<3 {
- col := i if i < c else i+1;
+ col := i if i < c else i+1
for j in 0..<3 {
- row := j if j < r else j+1;
- cut_down[i][j] = m[col][row];
+ row := j if j < r else j+1
+ cut_down[i][j] = m[col][row]
}
}
- return matrix3_determinant(cut_down);
+ return matrix3_determinant(cut_down)
}
matrix4_minor_f64 :: proc(m: Matrix4f64, c, r: int) -> f64 {
- cut_down: Matrix3f64;
+ cut_down: Matrix3f64
for i in 0..<3 {
- col := i if i < c else i+1;
+ col := i if i < c else i+1
for j in 0..<3 {
- row := j if j < r else j+1;
- cut_down[i][j] = m[col][row];
+ row := j if j < r else j+1
+ cut_down[i][j] = m[col][row]
}
}
- return matrix3_determinant(cut_down);
+ return matrix3_determinant(cut_down)
}
matrix4_minor :: proc{
matrix4_minor_f16,
matrix4_minor_f32,
matrix4_minor_f64,
-};
+}
matrix4_cofactor_f16 :: proc(m: Matrix4f16, c, r: int) -> f16 {
- sign, minor: f16;
- sign = 1 if (c + r) % 2 == 0 else -1;
- minor = matrix4_minor(m, c, r);
- return sign * minor;
+ sign, minor: f16
+ sign = 1 if (c + r) % 2 == 0 else -1
+ minor = matrix4_minor(m, c, r)
+ return sign * minor
}
matrix4_cofactor_f32 :: proc(m: Matrix4f32, c, r: int) -> f32 {
- sign, minor: f32;
- sign = 1 if (c + r) % 2 == 0 else -1;
- minor = matrix4_minor(m, c, r);
- return sign * minor;
+ sign, minor: f32
+ sign = 1 if (c + r) % 2 == 0 else -1
+ minor = matrix4_minor(m, c, r)
+ return sign * minor
}
matrix4_cofactor_f64 :: proc(m: Matrix4f64, c, r: int) -> f64 {
- sign, minor: f64;
- sign = 1 if (c + r) % 2 == 0 else -1;
- minor = matrix4_minor(m, c, r);
- return sign * minor;
+ sign, minor: f64
+ sign = 1 if (c + r) % 2 == 0 else -1
+ minor = matrix4_minor(m, c, r)
+ return sign * minor
}
matrix4_cofactor :: proc{
matrix4_cofactor_f16,
matrix4_cofactor_f32,
matrix4_cofactor_f64,
-};
+}
matrix4_adjoint_f16 :: proc(m: Matrix4f16) -> (adjoint: Matrix4f16) {
for i in 0..<4 {
for j in 0..<4 {
- adjoint[i][j] = matrix4_cofactor(m, i, j);
+ adjoint[i][j] = matrix4_cofactor(m, i, j)
}
}
- return;
+ return
}
matrix4_adjoint_f32 :: proc(m: Matrix4f32) -> (adjoint: Matrix4f32) {
for i in 0..<4 {
for j in 0..<4 {
- adjoint[i][j] = matrix4_cofactor(m, i, j);
+ adjoint[i][j] = matrix4_cofactor(m, i, j)
}
}
- return;
+ return
}
matrix4_adjoint_f64 :: proc(m: Matrix4f64) -> (adjoint: Matrix4f64) {
for i in 0..<4 {
for j in 0..<4 {
- adjoint[i][j] = matrix4_cofactor(m, i, j);
+ adjoint[i][j] = matrix4_cofactor(m, i, j)
}
}
- return;
+ return
}
matrix4_adjoint :: proc{
matrix4_adjoint_f16,
matrix4_adjoint_f32,
matrix4_adjoint_f64,
-};
+}
matrix4_determinant_f16 :: proc(m: Matrix4f16) -> (determinant: f16) {
- adjoint := matrix4_adjoint(m);
+ adjoint := matrix4_adjoint(m)
for i in 0..<4 {
- determinant += m[i][0] * adjoint[i][0];
+ determinant += m[i][0] * adjoint[i][0]
}
- return;
+ return
}
matrix4_determinant_f32 :: proc(m: Matrix4f32) -> (determinant: f32) {
- adjoint := matrix4_adjoint(m);
+ adjoint := matrix4_adjoint(m)
for i in 0..<4 {
- determinant += m[i][0] * adjoint[i][0];
+ determinant += m[i][0] * adjoint[i][0]
}
- return;
+ return
}
matrix4_determinant_f64 :: proc(m: Matrix4f64) -> (determinant: f64) {
- adjoint := matrix4_adjoint(m);
+ adjoint := matrix4_adjoint(m)
for i in 0..<4 {
- determinant += m[i][0] * adjoint[i][0];
+ determinant += m[i][0] * adjoint[i][0]
}
- return;
+ return
}
matrix4_determinant :: proc{
matrix4_determinant_f16,
matrix4_determinant_f32,
matrix4_determinant_f64,
-};
+}
matrix4_inverse_transpose_f16 :: proc(m: Matrix4f16) -> (inverse_transpose: Matrix4f16) {
- adjoint := matrix4_adjoint(m);
- determinant: f16 = 0;
+ adjoint := matrix4_adjoint(m)
+ determinant: f16 = 0
for i in 0..<4 {
- determinant += m[i][0] * adjoint[i][0];
+ determinant += m[i][0] * adjoint[i][0]
}
- inv_determinant := 1.0 / determinant;
+ inv_determinant := 1.0 / determinant
for i in 0..<4 {
for j in 0..<4 {
- inverse_transpose[i][j] = adjoint[i][j] * inv_determinant;
+ inverse_transpose[i][j] = adjoint[i][j] * inv_determinant
}
}
- return;
+ return
}
matrix4_inverse_transpose_f32 :: proc(m: Matrix4f32) -> (inverse_transpose: Matrix4f32) {
- adjoint := matrix4_adjoint(m);
- determinant: f32 = 0;
+ adjoint := matrix4_adjoint(m)
+ determinant: f32 = 0
for i in 0..<4 {
- determinant += m[i][0] * adjoint[i][0];
+ determinant += m[i][0] * adjoint[i][0]
}
- inv_determinant := 1.0 / determinant;
+ inv_determinant := 1.0 / determinant
for i in 0..<4 {
for j in 0..<4 {
- inverse_transpose[i][j] = adjoint[i][j] * inv_determinant;
+ inverse_transpose[i][j] = adjoint[i][j] * inv_determinant
}
}
- return;
+ return
}
matrix4_inverse_transpose_f64 :: proc(m: Matrix4f64) -> (inverse_transpose: Matrix4f64) {
- adjoint := matrix4_adjoint(m);
- determinant: f64 = 0;
+ adjoint := matrix4_adjoint(m)
+ determinant: f64 = 0
for i in 0..<4 {
- determinant += m[i][0] * adjoint[i][0];
+ determinant += m[i][0] * adjoint[i][0]
}
- inv_determinant := 1.0 / determinant;
+ inv_determinant := 1.0 / determinant
for i in 0..<4 {
for j in 0..<4 {
- inverse_transpose[i][j] = adjoint[i][j] * inv_determinant;
+ inverse_transpose[i][j] = adjoint[i][j] * inv_determinant
}
}
- return;
+ return
}
matrix4_inverse_transpose :: proc{
matrix4_inverse_transpose_f16,
matrix4_inverse_transpose_f32,
matrix4_inverse_transpose_f64,
-};
+}
matrix4_translate_f16 :: proc(v: Vector3f16) -> Matrix4f16 {
- m := MATRIX4F16_IDENTITY;
- m[3][0] = v[0];
- m[3][1] = v[1];
- m[3][2] = v[2];
- return m;
+ m := MATRIX4F16_IDENTITY
+ m[3][0] = v[0]
+ m[3][1] = v[1]
+ m[3][2] = v[2]
+ return m
}
matrix4_translate_f32 :: proc(v: Vector3f32) -> Matrix4f32 {
- m := MATRIX4F32_IDENTITY;
- m[3][0] = v[0];
- m[3][1] = v[1];
- m[3][2] = v[2];
- return m;
+ m := MATRIX4F32_IDENTITY
+ m[3][0] = v[0]
+ m[3][1] = v[1]
+ m[3][2] = v[2]
+ return m
}
matrix4_translate_f64 :: proc(v: Vector3f64) -> Matrix4f64 {
- m := MATRIX4F64_IDENTITY;
- m[3][0] = v[0];
- m[3][1] = v[1];
- m[3][2] = v[2];
- return m;
+ m := MATRIX4F64_IDENTITY
+ m[3][0] = v[0]
+ m[3][1] = v[1]
+ m[3][2] = v[2]
+ return m
}
matrix4_translate :: proc{
matrix4_translate_f16,
matrix4_translate_f32,
matrix4_translate_f64,
-};
+}
matrix4_rotate_f16 :: proc(angle_radians: f16, v: Vector3f16) -> Matrix4f16 {
- c := math.cos(angle_radians);
- s := math.sin(angle_radians);
+ c := math.cos(angle_radians)
+ s := math.sin(angle_radians)
- a := normalize(v);
- t := a * (1-c);
+ a := normalize(v)
+ t := a * (1-c)
- rot := MATRIX4F16_IDENTITY;
+ rot := MATRIX4F16_IDENTITY
- rot[0][0] = c + t[0]*a[0];
- rot[0][1] = 0 + t[0]*a[1] + s*a[2];
- rot[0][2] = 0 + t[0]*a[2] - s*a[1];
- rot[0][3] = 0;
+ rot[0][0] = c + t[0]*a[0]
+ rot[0][1] = 0 + t[0]*a[1] + s*a[2]
+ rot[0][2] = 0 + t[0]*a[2] - s*a[1]
+ rot[0][3] = 0
- rot[1][0] = 0 + t[1]*a[0] - s*a[2];
- rot[1][1] = c + t[1]*a[1];
- rot[1][2] = 0 + t[1]*a[2] + s*a[0];
- rot[1][3] = 0;
+ rot[1][0] = 0 + t[1]*a[0] - s*a[2]
+ rot[1][1] = c + t[1]*a[1]
+ rot[1][2] = 0 + t[1]*a[2] + s*a[0]
+ rot[1][3] = 0
- rot[2][0] = 0 + t[2]*a[0] + s*a[1];
- rot[2][1] = 0 + t[2]*a[1] - s*a[0];
- rot[2][2] = c + t[2]*a[2];
- rot[2][3] = 0;
+ rot[2][0] = 0 + t[2]*a[0] + s*a[1]
+ rot[2][1] = 0 + t[2]*a[1] - s*a[0]
+ rot[2][2] = c + t[2]*a[2]
+ rot[2][3] = 0
- return rot;
+ return rot
}
matrix4_rotate_f32 :: proc(angle_radians: f32, v: Vector3f32) -> Matrix4f32 {
- c := math.cos(angle_radians);
- s := math.sin(angle_radians);
+ c := math.cos(angle_radians)
+ s := math.sin(angle_radians)
- a := normalize(v);
- t := a * (1-c);
+ a := normalize(v)
+ t := a * (1-c)
- rot := MATRIX4F32_IDENTITY;
+ rot := MATRIX4F32_IDENTITY
- rot[0][0] = c + t[0]*a[0];
- rot[0][1] = 0 + t[0]*a[1] + s*a[2];
- rot[0][2] = 0 + t[0]*a[2] - s*a[1];
- rot[0][3] = 0;
+ rot[0][0] = c + t[0]*a[0]
+ rot[0][1] = 0 + t[0]*a[1] + s*a[2]
+ rot[0][2] = 0 + t[0]*a[2] - s*a[1]
+ rot[0][3] = 0
- rot[1][0] = 0 + t[1]*a[0] - s*a[2];
- rot[1][1] = c + t[1]*a[1];
- rot[1][2] = 0 + t[1]*a[2] + s*a[0];
- rot[1][3] = 0;
+ rot[1][0] = 0 + t[1]*a[0] - s*a[2]
+ rot[1][1] = c + t[1]*a[1]
+ rot[1][2] = 0 + t[1]*a[2] + s*a[0]
+ rot[1][3] = 0
- rot[2][0] = 0 + t[2]*a[0] + s*a[1];
- rot[2][1] = 0 + t[2]*a[1] - s*a[0];
- rot[2][2] = c + t[2]*a[2];
- rot[2][3] = 0;
+ rot[2][0] = 0 + t[2]*a[0] + s*a[1]
+ rot[2][1] = 0 + t[2]*a[1] - s*a[0]
+ rot[2][2] = c + t[2]*a[2]
+ rot[2][3] = 0
- return rot;
+ return rot
}
matrix4_rotate_f64 :: proc(angle_radians: f64, v: Vector3f64) -> Matrix4f64 {
- c := math.cos(angle_radians);
- s := math.sin(angle_radians);
+ c := math.cos(angle_radians)
+ s := math.sin(angle_radians)
- a := normalize(v);
- t := a * (1-c);
+ a := normalize(v)
+ t := a * (1-c)
- rot := MATRIX4F64_IDENTITY;
+ rot := MATRIX4F64_IDENTITY
- rot[0][0] = c + t[0]*a[0];
- rot[0][1] = 0 + t[0]*a[1] + s*a[2];
- rot[0][2] = 0 + t[0]*a[2] - s*a[1];
- rot[0][3] = 0;
+ rot[0][0] = c + t[0]*a[0]
+ rot[0][1] = 0 + t[0]*a[1] + s*a[2]
+ rot[0][2] = 0 + t[0]*a[2] - s*a[1]
+ rot[0][3] = 0
- rot[1][0] = 0 + t[1]*a[0] - s*a[2];
- rot[1][1] = c + t[1]*a[1];
- rot[1][2] = 0 + t[1]*a[2] + s*a[0];
- rot[1][3] = 0;
+ rot[1][0] = 0 + t[1]*a[0] - s*a[2]
+ rot[1][1] = c + t[1]*a[1]
+ rot[1][2] = 0 + t[1]*a[2] + s*a[0]
+ rot[1][3] = 0
- rot[2][0] = 0 + t[2]*a[0] + s*a[1];
- rot[2][1] = 0 + t[2]*a[1] - s*a[0];
- rot[2][2] = c + t[2]*a[2];
- rot[2][3] = 0;
+ rot[2][0] = 0 + t[2]*a[0] + s*a[1]
+ rot[2][1] = 0 + t[2]*a[1] - s*a[0]
+ rot[2][2] = c + t[2]*a[2]
+ rot[2][3] = 0
- return rot;
+ return rot
}
matrix4_rotate :: proc{
matrix4_rotate_f16,
matrix4_rotate_f32,
matrix4_rotate_f64,
-};
+}
matrix4_scale_f16 :: proc(v: Vector3f16) -> (m: Matrix4f16) {
- m[0][0] = v[0];
- m[1][1] = v[1];
- m[2][2] = v[2];
- m[3][3] = 1;
- return;
+ m[0][0] = v[0]
+ m[1][1] = v[1]
+ m[2][2] = v[2]
+ m[3][3] = 1
+ return
}
matrix4_scale_f32 :: proc(v: Vector3f32) -> (m: Matrix4f32) {
- m[0][0] = v[0];
- m[1][1] = v[1];
- m[2][2] = v[2];
- m[3][3] = 1;
- return;
+ m[0][0] = v[0]
+ m[1][1] = v[1]
+ m[2][2] = v[2]
+ m[3][3] = 1
+ return
}
matrix4_scale_f64 :: proc(v: Vector3f64) -> (m: Matrix4f64) {
- m[0][0] = v[0];
- m[1][1] = v[1];
- m[2][2] = v[2];
- m[3][3] = 1;
- return;
+ m[0][0] = v[0]
+ m[1][1] = v[1]
+ m[2][2] = v[2]
+ m[3][3] = 1
+ return
}
matrix4_scale :: proc{
matrix4_scale_f16,
matrix4_scale_f32,
matrix4_scale_f64,
-};
+}
matrix4_look_at_f16 :: proc(eye, centre, up: Vector3f16, flip_z_axis := true) -> (m: Matrix4f16) {
- f := normalize(centre - eye);
- s := normalize(cross(f, up));
- u := cross(s, f);
+ f := normalize(centre - eye)
+ s := normalize(cross(f, up))
+ u := cross(s, f)
- fe := dot(f, eye);
+ fe := dot(f, eye)
return {
{+s.x, +u.x, -f.x, 0},
{+s.y, +u.y, -f.y, 0},
{+s.z, +u.z, -f.z, 0},
{-dot(s, eye), -dot(u, eye), +fe if flip_z_axis else -fe, 1},
- };
+ }
}
matrix4_look_at_f32 :: proc(eye, centre, up: Vector3f32, flip_z_axis := true) -> (m: Matrix4f32) {
- f := normalize(centre - eye);
- s := normalize(cross(f, up));
- u := cross(s, f);
+ f := normalize(centre - eye)
+ s := normalize(cross(f, up))
+ u := cross(s, f)
- fe := dot(f, eye);
+ fe := dot(f, eye)
return {
{+s.x, +u.x, -f.x, 0},
{+s.y, +u.y, -f.y, 0},
{+s.z, +u.z, -f.z, 0},
{-dot(s, eye), -dot(u, eye), +fe if flip_z_axis else -fe, 1},
- };
+ }
}
matrix4_look_at_f64 :: proc(eye, centre, up: Vector3f64, flip_z_axis := true) -> (m: Matrix4f64) {
- f := normalize(centre - eye);
- s := normalize(cross(f, up));
- u := cross(s, f);
+ f := normalize(centre - eye)
+ s := normalize(cross(f, up))
+ u := cross(s, f)
- fe := dot(f, eye);
+ fe := dot(f, eye)
return {
{+s.x, +u.x, -f.x, 0},
{+s.y, +u.y, -f.y, 0},
{+s.z, +u.z, -f.z, 0},
{-dot(s, eye), -dot(u, eye), +fe if flip_z_axis else -fe, 1},
- };
+ }
}
matrix4_look_at :: proc{
matrix4_look_at_f16,
matrix4_look_at_f32,
matrix4_look_at_f64,
-};
+}
matrix4_perspective_f16 :: proc(fovy, aspect, near, far: f16, flip_z_axis := true) -> (m: Matrix4f16) {
- tan_half_fovy := math.tan(0.5 * fovy);
- m[0][0] = 1 / (aspect*tan_half_fovy);
- m[1][1] = 1 / (tan_half_fovy);
- m[2][2] = +(far + near) / (far - near);
- m[2][3] = +1;
- m[3][2] = -2*far*near / (far - near);
+ tan_half_fovy := math.tan(0.5 * fovy)
+ m[0][0] = 1 / (aspect*tan_half_fovy)
+ m[1][1] = 1 / (tan_half_fovy)
+ m[2][2] = +(far + near) / (far - near)
+ m[2][3] = +1
+ m[3][2] = -2*far*near / (far - near)
if flip_z_axis {
- m[2] = -m[2];
+ m[2] = -m[2]
}
- return;
+ return
}
matrix4_perspective_f32 :: proc(fovy, aspect, near, far: f32, flip_z_axis := true) -> (m: Matrix4f32) {
- tan_half_fovy := math.tan(0.5 * fovy);
- m[0][0] = 1 / (aspect*tan_half_fovy);
- m[1][1] = 1 / (tan_half_fovy);
- m[2][2] = +(far + near) / (far - near);
- m[2][3] = +1;
- m[3][2] = -2*far*near / (far - near);
+ tan_half_fovy := math.tan(0.5 * fovy)
+ m[0][0] = 1 / (aspect*tan_half_fovy)
+ m[1][1] = 1 / (tan_half_fovy)
+ m[2][2] = +(far + near) / (far - near)
+ m[2][3] = +1
+ m[3][2] = -2*far*near / (far - near)
if flip_z_axis {
- m[2] = -m[2];
+ m[2] = -m[2]
}
- return;
+ return
}
matrix4_perspective_f64 :: proc(fovy, aspect, near, far: f64, flip_z_axis := true) -> (m: Matrix4f64) {
- tan_half_fovy := math.tan(0.5 * fovy);
- m[0][0] = 1 / (aspect*tan_half_fovy);
- m[1][1] = 1 / (tan_half_fovy);
- m[2][2] = +(far + near) / (far - near);
- m[2][3] = +1;
- m[3][2] = -2*far*near / (far - near);
+ tan_half_fovy := math.tan(0.5 * fovy)
+ m[0][0] = 1 / (aspect*tan_half_fovy)
+ m[1][1] = 1 / (tan_half_fovy)
+ m[2][2] = +(far + near) / (far - near)
+ m[2][3] = +1
+ m[3][2] = -2*far*near / (far - near)
if flip_z_axis {
- m[2] = -m[2];
+ m[2] = -m[2]
}
- return;
+ return
}
matrix4_perspective :: proc{
matrix4_perspective_f16,
matrix4_perspective_f32,
matrix4_perspective_f64,
-};
+}
matrix_ortho3d_f16 :: proc(left, right, bottom, top, near, far: f16, flip_z_axis := true) -> (m: Matrix4f16) {
- m[0][0] = +2 / (right - left);
- m[1][1] = +2 / (top - bottom);
- m[2][2] = +2 / (far - near);
- m[3][0] = -(right + left) / (right - left);
- m[3][1] = -(top + bottom) / (top - bottom);
- m[3][2] = -(far + near) / (far- near);
- m[3][3] = 1;
+ m[0][0] = +2 / (right - left)
+ m[1][1] = +2 / (top - bottom)
+ m[2][2] = +2 / (far - near)
+ m[3][0] = -(right + left) / (right - left)
+ m[3][1] = -(top + bottom) / (top - bottom)
+ m[3][2] = -(far + near) / (far- near)
+ m[3][3] = 1
if flip_z_axis {
- m[2] = -m[2];
+ m[2] = -m[2]
}
- return;
+ return
}
matrix_ortho3d_f32 :: proc(left, right, bottom, top, near, far: f32, flip_z_axis := true) -> (m: Matrix4f32) {
- m[0][0] = +2 / (right - left);
- m[1][1] = +2 / (top - bottom);
- m[2][2] = +2 / (far - near);
- m[3][0] = -(right + left) / (right - left);
- m[3][1] = -(top + bottom) / (top - bottom);
- m[3][2] = -(far + near) / (far- near);
- m[3][3] = 1;
+ m[0][0] = +2 / (right - left)
+ m[1][1] = +2 / (top - bottom)
+ m[2][2] = +2 / (far - near)
+ m[3][0] = -(right + left) / (right - left)
+ m[3][1] = -(top + bottom) / (top - bottom)
+ m[3][2] = -(far + near) / (far- near)
+ m[3][3] = 1
if flip_z_axis {
- m[2] = -m[2];
+ m[2] = -m[2]
}
- return;
+ return
}
matrix_ortho3d_f64 :: proc(left, right, bottom, top, near, far: f64, flip_z_axis := true) -> (m: Matrix4f64) {
- m[0][0] = +2 / (right - left);
- m[1][1] = +2 / (top - bottom);
- m[2][2] = +2 / (far - near);
- m[3][0] = -(right + left) / (right - left);
- m[3][1] = -(top + bottom) / (top - bottom);
- m[3][2] = -(far + near) / (far- near);
- m[3][3] = 1;
+ m[0][0] = +2 / (right - left)
+ m[1][1] = +2 / (top - bottom)
+ m[2][2] = +2 / (far - near)
+ m[3][0] = -(right + left) / (right - left)
+ m[3][1] = -(top + bottom) / (top - bottom)
+ m[3][2] = -(far + near) / (far- near)
+ m[3][3] = 1
if flip_z_axis {
- m[2] = -m[2];
+ m[2] = -m[2]
}
- return;
+ return
}
matrix_ortho3d :: proc{
matrix_ortho3d_f16,
matrix_ortho3d_f32,
matrix_ortho3d_f64,
-};
+}
matrix4_infinite_perspective_f16 :: proc(fovy, aspect, near: f16, flip_z_axis := true) -> (m: Matrix4f16) {
- tan_half_fovy := math.tan(0.5 * fovy);
- m[0][0] = 1 / (aspect*tan_half_fovy);
- m[1][1] = 1 / (tan_half_fovy);
- m[2][2] = +1;
- m[2][3] = +1;
- m[3][2] = -2*near;
+ tan_half_fovy := math.tan(0.5 * fovy)
+ m[0][0] = 1 / (aspect*tan_half_fovy)
+ m[1][1] = 1 / (tan_half_fovy)
+ m[2][2] = +1
+ m[2][3] = +1
+ m[3][2] = -2*near
if flip_z_axis {
- m[2] = -m[2];
+ m[2] = -m[2]
}
- return;
+ return
}
matrix4_infinite_perspective_f32 :: proc(fovy, aspect, near: f32, flip_z_axis := true) -> (m: Matrix4f32) {
- tan_half_fovy := math.tan(0.5 * fovy);
- m[0][0] = 1 / (aspect*tan_half_fovy);
- m[1][1] = 1 / (tan_half_fovy);
- m[2][2] = +1;
- m[2][3] = +1;
- m[3][2] = -2*near;
+ tan_half_fovy := math.tan(0.5 * fovy)
+ m[0][0] = 1 / (aspect*tan_half_fovy)
+ m[1][1] = 1 / (tan_half_fovy)
+ m[2][2] = +1
+ m[2][3] = +1
+ m[3][2] = -2*near
if flip_z_axis {
- m[2] = -m[2];
+ m[2] = -m[2]
}
- return;
+ return
}
matrix4_infinite_perspective_f64 :: proc(fovy, aspect, near: f64, flip_z_axis := true) -> (m: Matrix4f64) {
- tan_half_fovy := math.tan(0.5 * fovy);
- m[0][0] = 1 / (aspect*tan_half_fovy);
- m[1][1] = 1 / (tan_half_fovy);
- m[2][2] = +1;
- m[2][3] = +1;
- m[3][2] = -2*near;
+ tan_half_fovy := math.tan(0.5 * fovy)
+ m[0][0] = 1 / (aspect*tan_half_fovy)
+ m[1][1] = 1 / (tan_half_fovy)
+ m[2][2] = +1
+ m[2][3] = +1
+ m[3][2] = -2*near
if flip_z_axis {
- m[2] = -m[2];
+ m[2] = -m[2]
}
- return;
+ return
}
matrix4_infinite_perspective :: proc{
matrix4_infinite_perspective_f16,
matrix4_infinite_perspective_f32,
matrix4_infinite_perspective_f64,
-};
+}
matrix2_from_scalar_f16 :: proc(f: f16) -> (m: Matrix2f16) {
- m[0][0], m[0][1] = f, 0;
- m[1][0], m[1][1] = 0, f;
- return;
+ m[0][0], m[0][1] = f, 0
+ m[1][0], m[1][1] = 0, f
+ return
}
matrix2_from_scalar_f32 :: proc(f: f32) -> (m: Matrix2f32) {
- m[0][0], m[0][1] = f, 0;
- m[1][0], m[1][1] = 0, f;
- return;
+ m[0][0], m[0][1] = f, 0
+ m[1][0], m[1][1] = 0, f
+ return
}
matrix2_from_scalar_f64 :: proc(f: f64) -> (m: Matrix2f64) {
- m[0][0], m[0][1] = f, 0;
- m[1][0], m[1][1] = 0, f;
- return;
+ m[0][0], m[0][1] = f, 0
+ m[1][0], m[1][1] = 0, f
+ return
}
matrix2_from_scalar :: proc{
matrix2_from_scalar_f16,
matrix2_from_scalar_f32,
matrix2_from_scalar_f64,
-};
+}
matrix3_from_scalar_f16 :: proc(f: f16) -> (m: Matrix3f16) {
- m[0][0], m[0][1], m[0][2] = f, 0, 0;
- m[1][0], m[1][1], m[1][2] = 0, f, 0;
- m[2][0], m[2][1], m[2][2] = 0, 0, f;
- return;
+ m[0][0], m[0][1], m[0][2] = f, 0, 0
+ m[1][0], m[1][1], m[1][2] = 0, f, 0
+ m[2][0], m[2][1], m[2][2] = 0, 0, f
+ return
}
matrix3_from_scalar_f32 :: proc(f: f32) -> (m: Matrix3f32) {
- m[0][0], m[0][1], m[0][2] = f, 0, 0;
- m[1][0], m[1][1], m[1][2] = 0, f, 0;
- m[2][0], m[2][1], m[2][2] = 0, 0, f;
- return;
+ m[0][0], m[0][1], m[0][2] = f, 0, 0
+ m[1][0], m[1][1], m[1][2] = 0, f, 0
+ m[2][0], m[2][1], m[2][2] = 0, 0, f
+ return
}
matrix3_from_scalar_f64 :: proc(f: f64) -> (m: Matrix3f64) {
- m[0][0], m[0][1], m[0][2] = f, 0, 0;
- m[1][0], m[1][1], m[1][2] = 0, f, 0;
- m[2][0], m[2][1], m[2][2] = 0, 0, f;
- return;
+ m[0][0], m[0][1], m[0][2] = f, 0, 0
+ m[1][0], m[1][1], m[1][2] = 0, f, 0
+ m[2][0], m[2][1], m[2][2] = 0, 0, f
+ return
}
matrix3_from_scalar :: proc{
matrix3_from_scalar_f16,
matrix3_from_scalar_f32,
matrix3_from_scalar_f64,
-};
+}
matrix4_from_scalar_f16 :: proc(f: f16) -> (m: Matrix4f16) {
- m[0][0], m[0][1], m[0][2], m[0][3] = f, 0, 0, 0;
- m[1][0], m[1][1], m[1][2], m[1][3] = 0, f, 0, 0;
- m[2][0], m[2][1], m[2][2], m[2][3] = 0, 0, f, 0;
- m[3][0], m[3][1], m[3][2], m[3][3] = 0, 0, 0, f;
- return;
+ m[0][0], m[0][1], m[0][2], m[0][3] = f, 0, 0, 0
+ m[1][0], m[1][1], m[1][2], m[1][3] = 0, f, 0, 0
+ m[2][0], m[2][1], m[2][2], m[2][3] = 0, 0, f, 0
+ m[3][0], m[3][1], m[3][2], m[3][3] = 0, 0, 0, f
+ return
}
matrix4_from_scalar_f32 :: proc(f: f32) -> (m: Matrix4f32) {
- m[0][0], m[0][1], m[0][2], m[0][3] = f, 0, 0, 0;
- m[1][0], m[1][1], m[1][2], m[1][3] = 0, f, 0, 0;
- m[2][0], m[2][1], m[2][2], m[2][3] = 0, 0, f, 0;
- m[3][0], m[3][1], m[3][2], m[3][3] = 0, 0, 0, f;
- return;
+ m[0][0], m[0][1], m[0][2], m[0][3] = f, 0, 0, 0
+ m[1][0], m[1][1], m[1][2], m[1][3] = 0, f, 0, 0
+ m[2][0], m[2][1], m[2][2], m[2][3] = 0, 0, f, 0
+ m[3][0], m[3][1], m[3][2], m[3][3] = 0, 0, 0, f
+ return
}
matrix4_from_scalar_f64 :: proc(f: f64) -> (m: Matrix4f64) {
- m[0][0], m[0][1], m[0][2], m[0][3] = f, 0, 0, 0;
- m[1][0], m[1][1], m[1][2], m[1][3] = 0, f, 0, 0;
- m[2][0], m[2][1], m[2][2], m[2][3] = 0, 0, f, 0;
- m[3][0], m[3][1], m[3][2], m[3][3] = 0, 0, 0, f;
- return;
+ m[0][0], m[0][1], m[0][2], m[0][3] = f, 0, 0, 0
+ m[1][0], m[1][1], m[1][2], m[1][3] = 0, f, 0, 0
+ m[2][0], m[2][1], m[2][2], m[2][3] = 0, 0, f, 0
+ m[3][0], m[3][1], m[3][2], m[3][3] = 0, 0, 0, f
+ return
}
matrix4_from_scalar :: proc{
matrix4_from_scalar_f16,
matrix4_from_scalar_f32,
matrix4_from_scalar_f64,
-};
+}
matrix2_from_matrix3_f16 :: proc(m: Matrix3f16) -> (r: Matrix2f16) {
- r[0][0], r[0][1] = m[0][0], m[0][1];
- r[1][0], r[1][1] = m[1][0], m[1][1];
- return;
+ r[0][0], r[0][1] = m[0][0], m[0][1]
+ r[1][0], r[1][1] = m[1][0], m[1][1]
+ return
}
matrix2_from_matrix3_f32 :: proc(m: Matrix3f32) -> (r: Matrix2f32) {
- r[0][0], r[0][1] = m[0][0], m[0][1];
- r[1][0], r[1][1] = m[1][0], m[1][1];
- return;
+ r[0][0], r[0][1] = m[0][0], m[0][1]
+ r[1][0], r[1][1] = m[1][0], m[1][1]
+ return
}
matrix2_from_matrix3_f64 :: proc(m: Matrix3f64) -> (r: Matrix2f64) {
- r[0][0], r[0][1] = m[0][0], m[0][1];
- r[1][0], r[1][1] = m[1][0], m[1][1];
- return;
+ r[0][0], r[0][1] = m[0][0], m[0][1]
+ r[1][0], r[1][1] = m[1][0], m[1][1]
+ return
}
matrix2_from_matrix3 :: proc{
matrix2_from_matrix3_f16,
matrix2_from_matrix3_f32,
matrix2_from_matrix3_f64,
-};
+}
matrix2_from_matrix4_f16 :: proc(m: Matrix4f16) -> (r: Matrix2f16) {
- r[0][0], r[0][1] = m[0][0], m[0][1];
- r[1][0], r[1][1] = m[1][0], m[1][1];
- return;
+ r[0][0], r[0][1] = m[0][0], m[0][1]
+ r[1][0], r[1][1] = m[1][0], m[1][1]
+ return
}
matrix2_from_matrix4_f32 :: proc(m: Matrix4f32) -> (r: Matrix2f32) {
- r[0][0], r[0][1] = m[0][0], m[0][1];
- r[1][0], r[1][1] = m[1][0], m[1][1];
- return;
+ r[0][0], r[0][1] = m[0][0], m[0][1]
+ r[1][0], r[1][1] = m[1][0], m[1][1]
+ return
}
matrix2_from_matrix4_f64 :: proc(m: Matrix4f64) -> (r: Matrix2f64) {
- r[0][0], r[0][1] = m[0][0], m[0][1];
- r[1][0], r[1][1] = m[1][0], m[1][1];
- return;
+ r[0][0], r[0][1] = m[0][0], m[0][1]
+ r[1][0], r[1][1] = m[1][0], m[1][1]
+ return
}
matrix2_from_matrix4 :: proc{
matrix2_from_matrix4_f16,
matrix2_from_matrix4_f32,
matrix2_from_matrix4_f64,
-};
+}
matrix3_from_matrix2_f16 :: proc(m: Matrix2f16) -> (r: Matrix3f16) {
- r[0][0], r[0][1], r[0][2] = m[0][0], m[0][1], 0;
- r[1][0], r[1][1], r[1][2] = m[1][0], m[1][1], 0;
- r[2][0], r[2][1], r[2][2] = 0, 0, 1;
- return;
+ r[0][0], r[0][1], r[0][2] = m[0][0], m[0][1], 0
+ r[1][0], r[1][1], r[1][2] = m[1][0], m[1][1], 0
+ r[2][0], r[2][1], r[2][2] = 0, 0, 1
+ return
}
matrix3_from_matrix2_f32 :: proc(m: Matrix2f32) -> (r: Matrix3f32) {
- r[0][0], r[0][1], r[0][2] = m[0][0], m[0][1], 0;
- r[1][0], r[1][1], r[1][2] = m[1][0], m[1][1], 0;
- r[2][0], r[2][1], r[2][2] = 0, 0, 1;
- return;
+ r[0][0], r[0][1], r[0][2] = m[0][0], m[0][1], 0
+ r[1][0], r[1][1], r[1][2] = m[1][0], m[1][1], 0
+ r[2][0], r[2][1], r[2][2] = 0, 0, 1
+ return
}
matrix3_from_matrix2_f64 :: proc(m: Matrix2f64) -> (r: Matrix3f64) {
- r[0][0], r[0][1], r[0][2] = m[0][0], m[0][1], 0;
- r[1][0], r[1][1], r[1][2] = m[1][0], m[1][1], 0;
- r[2][0], r[2][1], r[2][2] = 0, 0, 1;
- return;
+ r[0][0], r[0][1], r[0][2] = m[0][0], m[0][1], 0
+ r[1][0], r[1][1], r[1][2] = m[1][0], m[1][1], 0
+ r[2][0], r[2][1], r[2][2] = 0, 0, 1
+ return
}
matrix3_from_matrix2 :: proc{
matrix3_from_matrix2_f16,
matrix3_from_matrix2_f32,
matrix3_from_matrix2_f64,
-};
+}
matrix3_from_matrix4_f16 :: proc(m: Matrix4f16) -> (r: Matrix3f16) {
- r[0][0], r[0][1], r[0][2] = m[0][0], m[0][1], m[0][2];
- r[1][0], r[1][1], r[1][2] = m[1][0], m[1][1], m[1][2];
- r[2][0], r[2][1], r[2][2] = m[2][0], m[2][1], m[2][2];
- return;
+ r[0][0], r[0][1], r[0][2] = m[0][0], m[0][1], m[0][2]
+ r[1][0], r[1][1], r[1][2] = m[1][0], m[1][1], m[1][2]
+ r[2][0], r[2][1], r[2][2] = m[2][0], m[2][1], m[2][2]
+ return
}
matrix3_from_matrix4_f32 :: proc(m: Matrix4f32) -> (r: Matrix3f32) {
- r[0][0], r[0][1], r[0][2] = m[0][0], m[0][1], m[0][2];
- r[1][0], r[1][1], r[1][2] = m[1][0], m[1][1], m[1][2];
- r[2][0], r[2][1], r[2][2] = m[2][0], m[2][1], m[2][2];
- return;
+ r[0][0], r[0][1], r[0][2] = m[0][0], m[0][1], m[0][2]
+ r[1][0], r[1][1], r[1][2] = m[1][0], m[1][1], m[1][2]
+ r[2][0], r[2][1], r[2][2] = m[2][0], m[2][1], m[2][2]
+ return
}
matrix3_from_matrix4_f64 :: proc(m: Matrix4f64) -> (r: Matrix3f64) {
- r[0][0], r[0][1], r[0][2] = m[0][0], m[0][1], m[0][2];
- r[1][0], r[1][1], r[1][2] = m[1][0], m[1][1], m[1][2];
- r[2][0], r[2][1], r[2][2] = m[2][0], m[2][1], m[2][2];
- return;
+ r[0][0], r[0][1], r[0][2] = m[0][0], m[0][1], m[0][2]
+ r[1][0], r[1][1], r[1][2] = m[1][0], m[1][1], m[1][2]
+ r[2][0], r[2][1], r[2][2] = m[2][0], m[2][1], m[2][2]
+ return
}
matrix3_from_matrix4 :: proc{
matrix3_from_matrix4_f16,
matrix3_from_matrix4_f32,
matrix3_from_matrix4_f64,
-};
+}
matrix4_from_matrix2_f16 :: proc(m: Matrix2f16) -> (r: Matrix4f16) {
- r[0][0], r[0][1], r[0][2], r[0][3] = m[0][0], m[0][1], 0, 0;
- r[1][0], r[1][1], r[1][2], r[1][3] = m[1][0], m[1][1], 0, 0;
- r[2][0], r[2][1], r[2][2], r[2][3] = 0, 0, 1, 0;
- r[3][0], r[3][1], r[3][2], r[3][3] = 0, 0, 0, 1;
- return;
+ r[0][0], r[0][1], r[0][2], r[0][3] = m[0][0], m[0][1], 0, 0
+ r[1][0], r[1][1], r[1][2], r[1][3] = m[1][0], m[1][1], 0, 0
+ r[2][0], r[2][1], r[2][2], r[2][3] = 0, 0, 1, 0
+ r[3][0], r[3][1], r[3][2], r[3][3] = 0, 0, 0, 1
+ return
}
matrix4_from_matrix2_f32 :: proc(m: Matrix2f32) -> (r: Matrix4f32) {
- r[0][0], r[0][1], r[0][2], r[0][3] = m[0][0], m[0][1], 0, 0;
- r[1][0], r[1][1], r[1][2], r[1][3] = m[1][0], m[1][1], 0, 0;
- r[2][0], r[2][1], r[2][2], r[2][3] = 0, 0, 1, 0;
- r[3][0], r[3][1], r[3][2], r[3][3] = 0, 0, 0, 1;
- return;
+ r[0][0], r[0][1], r[0][2], r[0][3] = m[0][0], m[0][1], 0, 0
+ r[1][0], r[1][1], r[1][2], r[1][3] = m[1][0], m[1][1], 0, 0
+ r[2][0], r[2][1], r[2][2], r[2][3] = 0, 0, 1, 0
+ r[3][0], r[3][1], r[3][2], r[3][3] = 0, 0, 0, 1
+ return
}
matrix4_from_matrix2_f64 :: proc(m: Matrix2f64) -> (r: Matrix4f64) {
- r[0][0], r[0][1], r[0][2], r[0][3] = m[0][0], m[0][1], 0, 0;
- r[1][0], r[1][1], r[1][2], r[1][3] = m[1][0], m[1][1], 0, 0;
- r[2][0], r[2][1], r[2][2], r[2][3] = 0, 0, 1, 0;
- r[3][0], r[3][1], r[3][2], r[3][3] = 0, 0, 0, 1;
- return;
+ r[0][0], r[0][1], r[0][2], r[0][3] = m[0][0], m[0][1], 0, 0
+ r[1][0], r[1][1], r[1][2], r[1][3] = m[1][0], m[1][1], 0, 0
+ r[2][0], r[2][1], r[2][2], r[2][3] = 0, 0, 1, 0
+ r[3][0], r[3][1], r[3][2], r[3][3] = 0, 0, 0, 1
+ return
}
matrix4_from_matrix2 :: proc{
matrix4_from_matrix2_f16,
matrix4_from_matrix2_f32,
matrix4_from_matrix2_f64,
-};
+}
matrix4_from_matrix3_f16 :: proc(m: Matrix3f16) -> (r: Matrix4f16) {
- r[0][0], r[0][1], r[0][2], r[0][3] = m[0][0], m[0][1], m[0][2], 0;
- r[1][0], r[1][1], r[1][2], r[1][3] = m[1][0], m[1][1], m[1][2], 0;
- r[2][0], r[2][1], r[2][2], r[2][3] = m[2][0], m[2][1], m[2][2], 0;
- r[3][0], r[3][1], r[3][2], r[3][3] = 0, 0, 0, 1;
- return;
+ r[0][0], r[0][1], r[0][2], r[0][3] = m[0][0], m[0][1], m[0][2], 0
+ r[1][0], r[1][1], r[1][2], r[1][3] = m[1][0], m[1][1], m[1][2], 0
+ r[2][0], r[2][1], r[2][2], r[2][3] = m[2][0], m[2][1], m[2][2], 0
+ r[3][0], r[3][1], r[3][2], r[3][3] = 0, 0, 0, 1
+ return
}
matrix4_from_matrix3_f32 :: proc(m: Matrix3f32) -> (r: Matrix4f32) {
- r[0][0], r[0][1], r[0][2], r[0][3] = m[0][0], m[0][1], m[0][2], 0;
- r[1][0], r[1][1], r[1][2], r[1][3] = m[1][0], m[1][1], m[1][2], 0;
- r[2][0], r[2][1], r[2][2], r[2][3] = m[2][0], m[2][1], m[2][2], 0;
- r[3][0], r[3][1], r[3][2], r[3][3] = 0, 0, 0, 1;
- return;
+ r[0][0], r[0][1], r[0][2], r[0][3] = m[0][0], m[0][1], m[0][2], 0
+ r[1][0], r[1][1], r[1][2], r[1][3] = m[1][0], m[1][1], m[1][2], 0
+ r[2][0], r[2][1], r[2][2], r[2][3] = m[2][0], m[2][1], m[2][2], 0
+ r[3][0], r[3][1], r[3][2], r[3][3] = 0, 0, 0, 1
+ return
}
matrix4_from_matrix3_f64 :: proc(m: Matrix3f64) -> (r: Matrix4f64) {
- r[0][0], r[0][1], r[0][2], r[0][3] = m[0][0], m[0][1], m[0][2], 0;
- r[1][0], r[1][1], r[1][2], r[1][3] = m[1][0], m[1][1], m[1][2], 0;
- r[2][0], r[2][1], r[2][2], r[2][3] = m[2][0], m[2][1], m[2][2], 0;
- r[3][0], r[3][1], r[3][2], r[3][3] = 0, 0, 0, 1;
- return;
+ r[0][0], r[0][1], r[0][2], r[0][3] = m[0][0], m[0][1], m[0][2], 0
+ r[1][0], r[1][1], r[1][2], r[1][3] = m[1][0], m[1][1], m[1][2], 0
+ r[2][0], r[2][1], r[2][2], r[2][3] = m[2][0], m[2][1], m[2][2], 0
+ r[3][0], r[3][1], r[3][2], r[3][3] = 0, 0, 0, 1
+ return
}
matrix4_from_matrix3 :: proc{
matrix4_from_matrix3_f16,
matrix4_from_matrix3_f32,
matrix4_from_matrix3_f64,
-};
+}
quaternion_from_scalar_f16 :: proc(f: f16) -> (q: Quaternionf16) {
- q.w = f;
- return;
+ q.w = f
+ return
}
quaternion_from_scalar_f32 :: proc(f: f32) -> (q: Quaternionf32) {
- q.w = f;
- return;
+ q.w = f
+ return
}
quaternion_from_scalar_f64 :: proc(f: f64) -> (q: Quaternionf64) {
- q.w = f;
- return;
+ q.w = f
+ return
}
quaternion_from_scalar :: proc{
quaternion_from_scalar_f16,
quaternion_from_scalar_f32,
quaternion_from_scalar_f64,
-};
+}
-to_matrix2f16 :: proc{matrix2_from_scalar_f16, matrix2_from_matrix3_f16, matrix2_from_matrix4_f16};
-to_matrix3f16 :: proc{matrix3_from_scalar_f16, matrix3_from_matrix2_f16, matrix3_from_matrix4_f16, matrix3_from_quaternion_f16};
-to_matrix4f16 :: proc{matrix4_from_scalar_f16, matrix4_from_matrix2_f16, matrix4_from_matrix3_f16, matrix4_from_quaternion_f16};
-to_quaternionf16 :: proc{quaternion_from_scalar_f16, quaternion_from_matrix3_f16, quaternion_from_matrix4_f16};
+to_matrix2f16 :: proc{matrix2_from_scalar_f16, matrix2_from_matrix3_f16, matrix2_from_matrix4_f16}
+to_matrix3f16 :: proc{matrix3_from_scalar_f16, matrix3_from_matrix2_f16, matrix3_from_matrix4_f16, matrix3_from_quaternion_f16}
+to_matrix4f16 :: proc{matrix4_from_scalar_f16, matrix4_from_matrix2_f16, matrix4_from_matrix3_f16, matrix4_from_quaternion_f16}
+to_quaternionf16 :: proc{quaternion_from_scalar_f16, quaternion_from_matrix3_f16, quaternion_from_matrix4_f16}
-to_matrix2f32 :: proc{matrix2_from_scalar_f32, matrix2_from_matrix3_f32, matrix2_from_matrix4_f32};
-to_matrix3f32 :: proc{matrix3_from_scalar_f32, matrix3_from_matrix2_f32, matrix3_from_matrix4_f32, matrix3_from_quaternion_f32};
-to_matrix4f32 :: proc{matrix4_from_scalar_f32, matrix4_from_matrix2_f32, matrix4_from_matrix3_f32, matrix4_from_quaternion_f32};
-to_quaternionf32 :: proc{quaternion_from_scalar_f32, quaternion_from_matrix3_f32, quaternion_from_matrix4_f32};
+to_matrix2f32 :: proc{matrix2_from_scalar_f32, matrix2_from_matrix3_f32, matrix2_from_matrix4_f32}
+to_matrix3f32 :: proc{matrix3_from_scalar_f32, matrix3_from_matrix2_f32, matrix3_from_matrix4_f32, matrix3_from_quaternion_f32}
+to_matrix4f32 :: proc{matrix4_from_scalar_f32, matrix4_from_matrix2_f32, matrix4_from_matrix3_f32, matrix4_from_quaternion_f32}
+to_quaternionf32 :: proc{quaternion_from_scalar_f32, quaternion_from_matrix3_f32, quaternion_from_matrix4_f32}
-to_matrix2f64 :: proc{matrix2_from_scalar_f64, matrix2_from_matrix3_f64, matrix2_from_matrix4_f64};
-to_matrix3f64 :: proc{matrix3_from_scalar_f64, matrix3_from_matrix2_f64, matrix3_from_matrix4_f64, matrix3_from_quaternion_f64};
-to_matrix4f64 :: proc{matrix4_from_scalar_f64, matrix4_from_matrix2_f64, matrix4_from_matrix3_f64, matrix4_from_quaternion_f64};
-to_quaternionf64 :: proc{quaternion_from_scalar_f64, quaternion_from_matrix3_f64, quaternion_from_matrix4_f64};
+to_matrix2f64 :: proc{matrix2_from_scalar_f64, matrix2_from_matrix3_f64, matrix2_from_matrix4_f64}
+to_matrix3f64 :: proc{matrix3_from_scalar_f64, matrix3_from_matrix2_f64, matrix3_from_matrix4_f64, matrix3_from_quaternion_f64}
+to_matrix4f64 :: proc{matrix4_from_scalar_f64, matrix4_from_matrix2_f64, matrix4_from_matrix3_f64, matrix4_from_quaternion_f64}
+to_quaternionf64 :: proc{quaternion_from_scalar_f64, quaternion_from_matrix3_f64, quaternion_from_matrix4_f64}
@@ -2457,250 +2457,250 @@ to_matrix2f :: proc{
matrix2_from_scalar_f16, matrix2_from_matrix3_f16, matrix2_from_matrix4_f16,
matrix2_from_scalar_f32, matrix2_from_matrix3_f32, matrix2_from_matrix4_f32,
matrix2_from_scalar_f64, matrix2_from_matrix3_f64, matrix2_from_matrix4_f64,
-};
+}
to_matrix3 :: proc{
matrix3_from_scalar_f16, matrix3_from_matrix2_f16, matrix3_from_matrix4_f16, matrix3_from_quaternion_f16,
matrix3_from_scalar_f32, matrix3_from_matrix2_f32, matrix3_from_matrix4_f32, matrix3_from_quaternion_f32,
matrix3_from_scalar_f64, matrix3_from_matrix2_f64, matrix3_from_matrix4_f64, matrix3_from_quaternion_f64,
-};
+}
to_matrix4 :: proc{
matrix4_from_scalar_f16, matrix4_from_matrix2_f16, matrix4_from_matrix3_f16, matrix4_from_quaternion_f16,
matrix4_from_scalar_f32, matrix4_from_matrix2_f32, matrix4_from_matrix3_f32, matrix4_from_quaternion_f32,
matrix4_from_scalar_f64, matrix4_from_matrix2_f64, matrix4_from_matrix3_f64, matrix4_from_quaternion_f64,
-};
+}
to_quaternion :: proc{
quaternion_from_scalar_f16, quaternion_from_matrix3_f16, quaternion_from_matrix4_f16,
quaternion_from_scalar_f32, quaternion_from_matrix3_f32, quaternion_from_matrix4_f32,
quaternion_from_scalar_f64, quaternion_from_matrix3_f64, quaternion_from_matrix4_f64,
-};
+}
matrix2_orthonormalize_f16 :: proc(m: Matrix2f16) -> (r: Matrix2f16) {
- r[0] = normalize(m[0]);
+ r[0] = normalize(m[0])
- d0 := dot(r[0], r[1]);
- r[1] -= r[0] * d0;
- r[1] = normalize(r[1]);
+ d0 := dot(r[0], r[1])
+ r[1] -= r[0] * d0
+ r[1] = normalize(r[1])
- return;
+ return
}
matrix2_orthonormalize_f32 :: proc(m: Matrix2f32) -> (r: Matrix2f32) {
- r[0] = normalize(m[0]);
+ r[0] = normalize(m[0])
- d0 := dot(r[0], r[1]);
- r[1] -= r[0] * d0;
- r[1] = normalize(r[1]);
+ d0 := dot(r[0], r[1])
+ r[1] -= r[0] * d0
+ r[1] = normalize(r[1])
- return;
+ return
}
matrix2_orthonormalize_f64 :: proc(m: Matrix2f64) -> (r: Matrix2f64) {
- r[0] = normalize(m[0]);
+ r[0] = normalize(m[0])
- d0 := dot(r[0], r[1]);
- r[1] -= r[0] * d0;
- r[1] = normalize(r[1]);
+ d0 := dot(r[0], r[1])
+ r[1] -= r[0] * d0
+ r[1] = normalize(r[1])
- return;
+ return
}
matrix2_orthonormalize :: proc{
matrix2_orthonormalize_f16,
matrix2_orthonormalize_f32,
matrix2_orthonormalize_f64,
-};
+}
matrix3_orthonormalize_f16 :: proc(m: Matrix3f16) -> (r: Matrix3f16) {
- r[0] = normalize(m[0]);
+ r[0] = normalize(m[0])
- d0 := dot(r[0], r[1]);
- r[1] -= r[0] * d0;
- r[1] = normalize(r[1]);
+ d0 := dot(r[0], r[1])
+ r[1] -= r[0] * d0
+ r[1] = normalize(r[1])
- d1 := dot(r[1], r[2]);
- d0 = dot(r[0], r[2]);
- r[2] -= r[0]*d0 + r[1]*d1;
- r[2] = normalize(r[2]);
+ d1 := dot(r[1], r[2])
+ d0 = dot(r[0], r[2])
+ r[2] -= r[0]*d0 + r[1]*d1
+ r[2] = normalize(r[2])
- return;
+ return
}
matrix3_orthonormalize_f32 :: proc(m: Matrix3f32) -> (r: Matrix3f32) {
- r[0] = normalize(m[0]);
+ r[0] = normalize(m[0])
- d0 := dot(r[0], r[1]);
- r[1] -= r[0] * d0;
- r[1] = normalize(r[1]);
+ d0 := dot(r[0], r[1])
+ r[1] -= r[0] * d0
+ r[1] = normalize(r[1])
- d1 := dot(r[1], r[2]);
- d0 = dot(r[0], r[2]);
- r[2] -= r[0]*d0 + r[1]*d1;
- r[2] = normalize(r[2]);
+ d1 := dot(r[1], r[2])
+ d0 = dot(r[0], r[2])
+ r[2] -= r[0]*d0 + r[1]*d1
+ r[2] = normalize(r[2])
- return;
+ return
}
matrix3_orthonormalize_f64 :: proc(m: Matrix3f64) -> (r: Matrix3f64) {
- r[0] = normalize(m[0]);
+ r[0] = normalize(m[0])
- d0 := dot(r[0], r[1]);
- r[1] -= r[0] * d0;
- r[1] = normalize(r[1]);
+ d0 := dot(r[0], r[1])
+ r[1] -= r[0] * d0
+ r[1] = normalize(r[1])
- d1 := dot(r[1], r[2]);
- d0 = dot(r[0], r[2]);
- r[2] -= r[0]*d0 + r[1]*d1;
- r[2] = normalize(r[2]);
+ d1 := dot(r[1], r[2])
+ d0 = dot(r[0], r[2])
+ r[2] -= r[0]*d0 + r[1]*d1
+ r[2] = normalize(r[2])
- return;
+ return
}
matrix3_orthonormalize :: proc{
matrix3_orthonormalize_f16,
matrix3_orthonormalize_f32,
matrix3_orthonormalize_f64,
-};
+}
vector3_orthonormalize_f16 :: proc(x, y: Vector3f16) -> (z: Vector3f16) {
- return normalize(x - y * dot(y, x));
+ return normalize(x - y * dot(y, x))
}
vector3_orthonormalize_f32 :: proc(x, y: Vector3f32) -> (z: Vector3f32) {
- return normalize(x - y * dot(y, x));
+ return normalize(x - y * dot(y, x))
}
vector3_orthonormalize_f64 :: proc(x, y: Vector3f64) -> (z: Vector3f64) {
- return normalize(x - y * dot(y, x));
+ return normalize(x - y * dot(y, x))
}
vector3_orthonormalize :: proc{
vector3_orthonormalize_f16,
vector3_orthonormalize_f32,
vector3_orthonormalize_f64,
-};
+}
orthonormalize :: proc{
matrix2_orthonormalize_f16, matrix3_orthonormalize_f16, vector3_orthonormalize_f16,
matrix2_orthonormalize_f32, matrix3_orthonormalize_f32, vector3_orthonormalize_f32,
matrix2_orthonormalize_f64, matrix3_orthonormalize_f64, vector3_orthonormalize_f64,
-};
+}
matrix4_orientation_f16 :: proc(normal, up: Vector3f16) -> Matrix4f16 {
if all(equal(normal, up)) {
- return MATRIX4F16_IDENTITY;
+ return MATRIX4F16_IDENTITY
}
- rotation_axis := cross(up, normal);
- angle := math.acos(dot(normal, up));
+ rotation_axis := cross(up, normal)
+ angle := math.acos(dot(normal, up))
- return matrix4_rotate(angle, rotation_axis);
+ return matrix4_rotate(angle, rotation_axis)
}
matrix4_orientation_f32 :: proc(normal, up: Vector3f32) -> Matrix4f32 {
if all(equal(normal, up)) {
- return MATRIX4F32_IDENTITY;
+ return MATRIX4F32_IDENTITY
}
- rotation_axis := cross(up, normal);
- angle := math.acos(dot(normal, up));
+ rotation_axis := cross(up, normal)
+ angle := math.acos(dot(normal, up))
- return matrix4_rotate(angle, rotation_axis);
+ return matrix4_rotate(angle, rotation_axis)
}
matrix4_orientation_f64 :: proc(normal, up: Vector3f64) -> Matrix4f64 {
if all(equal(normal, up)) {
- return MATRIX4F64_IDENTITY;
+ return MATRIX4F64_IDENTITY
}
- rotation_axis := cross(up, normal);
- angle := math.acos(dot(normal, up));
+ rotation_axis := cross(up, normal)
+ angle := math.acos(dot(normal, up))
- return matrix4_rotate(angle, rotation_axis);
+ return matrix4_rotate(angle, rotation_axis)
}
matrix4_orientation :: proc{
matrix4_orientation_f16,
matrix4_orientation_f32,
matrix4_orientation_f64,
-};
+}
euclidean_from_polar_f16 :: proc(polar: Vector2f16) -> Vector3f16 {
- latitude, longitude := polar.x, polar.y;
- cx, sx := math.cos(latitude), math.sin(latitude);
- cy, sy := math.cos(longitude), math.sin(longitude);
+ latitude, longitude := polar.x, polar.y
+ cx, sx := math.cos(latitude), math.sin(latitude)
+ cy, sy := math.cos(longitude), math.sin(longitude)
return {
cx*sy,
sx,
cx*cy,
- };
+ }
}
euclidean_from_polar_f32 :: proc(polar: Vector2f32) -> Vector3f32 {
- latitude, longitude := polar.x, polar.y;
- cx, sx := math.cos(latitude), math.sin(latitude);
- cy, sy := math.cos(longitude), math.sin(longitude);
+ latitude, longitude := polar.x, polar.y
+ cx, sx := math.cos(latitude), math.sin(latitude)
+ cy, sy := math.cos(longitude), math.sin(longitude)
return {
cx*sy,
sx,
cx*cy,
- };
+ }
}
euclidean_from_polar_f64 :: proc(polar: Vector2f64) -> Vector3f64 {
- latitude, longitude := polar.x, polar.y;
- cx, sx := math.cos(latitude), math.sin(latitude);
- cy, sy := math.cos(longitude), math.sin(longitude);
+ latitude, longitude := polar.x, polar.y
+ cx, sx := math.cos(latitude), math.sin(latitude)
+ cy, sy := math.cos(longitude), math.sin(longitude)
return {
cx*sy,
sx,
cx*cy,
- };
+ }
}
euclidean_from_polar :: proc{
euclidean_from_polar_f16,
euclidean_from_polar_f32,
euclidean_from_polar_f64,
-};
+}
polar_from_euclidean_f16 :: proc(euclidean: Vector3f16) -> Vector3f16 {
- n := length(euclidean);
- tmp := euclidean / n;
+ n := length(euclidean)
+ tmp := euclidean / n
- xz_dist := math.sqrt(tmp.x*tmp.x + tmp.z*tmp.z);
+ xz_dist := math.sqrt(tmp.x*tmp.x + tmp.z*tmp.z)
return {
math.asin(tmp.y),
math.atan2(tmp.x, tmp.z),
xz_dist,
- };
+ }
}
polar_from_euclidean_f32 :: proc(euclidean: Vector3f32) -> Vector3f32 {
- n := length(euclidean);
- tmp := euclidean / n;
+ n := length(euclidean)
+ tmp := euclidean / n
- xz_dist := math.sqrt(tmp.x*tmp.x + tmp.z*tmp.z);
+ xz_dist := math.sqrt(tmp.x*tmp.x + tmp.z*tmp.z)
return {
math.asin(tmp.y),
math.atan2(tmp.x, tmp.z),
xz_dist,
- };
+ }
}
polar_from_euclidean_f64 :: proc(euclidean: Vector3f64) -> Vector3f64 {
- n := length(euclidean);
- tmp := euclidean / n;
+ n := length(euclidean)
+ tmp := euclidean / n
- xz_dist := math.sqrt(tmp.x*tmp.x + tmp.z*tmp.z);
+ xz_dist := math.sqrt(tmp.x*tmp.x + tmp.z*tmp.z)
return {
math.asin(tmp.y),
math.atan2(tmp.x, tmp.z),
xz_dist,
- };
+ }
}
polar_from_euclidean :: proc{
polar_from_euclidean_f16,
polar_from_euclidean_f32,
polar_from_euclidean_f64,
-};
+}
diff --git a/core/math/linalg/specific_euler_angles.odin b/core/math/linalg/specific_euler_angles.odin
index 000edda12..4d714be54 100644
--- a/core/math/linalg/specific_euler_angles.odin
+++ b/core/math/linalg/specific_euler_angles.odin
@@ -19,109 +19,109 @@ Euler_Angle_Order :: enum {
}
-quaternion_from_euler_angles :: proc{quaternion_from_euler_angles_f16, quaternion_from_euler_angles_f32, quaternion_from_euler_angles_f64};
-quaternion_from_euler_angle_x :: proc{quaternion_from_euler_angle_x_f16, quaternion_from_euler_angle_x_f32, quaternion_from_euler_angle_x_f64};
-quaternion_from_euler_angle_y :: proc{quaternion_from_euler_angle_y_f16, quaternion_from_euler_angle_y_f32, quaternion_from_euler_angle_y_f64};
-quaternion_from_euler_angle_z :: proc{quaternion_from_euler_angle_z_f16, quaternion_from_euler_angle_z_f32, quaternion_from_euler_angle_z_f64};
-quaternion_from_pitch_yaw_roll :: proc{quaternion_from_pitch_yaw_roll_f16, quaternion_from_pitch_yaw_roll_f32, quaternion_from_pitch_yaw_roll_f64};
+quaternion_from_euler_angles :: proc{quaternion_from_euler_angles_f16, quaternion_from_euler_angles_f32, quaternion_from_euler_angles_f64}
+quaternion_from_euler_angle_x :: proc{quaternion_from_euler_angle_x_f16, quaternion_from_euler_angle_x_f32, quaternion_from_euler_angle_x_f64}
+quaternion_from_euler_angle_y :: proc{quaternion_from_euler_angle_y_f16, quaternion_from_euler_angle_y_f32, quaternion_from_euler_angle_y_f64}
+quaternion_from_euler_angle_z :: proc{quaternion_from_euler_angle_z_f16, quaternion_from_euler_angle_z_f32, quaternion_from_euler_angle_z_f64}
+quaternion_from_pitch_yaw_roll :: proc{quaternion_from_pitch_yaw_roll_f16, quaternion_from_pitch_yaw_roll_f32, quaternion_from_pitch_yaw_roll_f64}
-euler_angles_from_quaternion :: proc{euler_angles_from_quaternion_f16, euler_angles_from_quaternion_f32, euler_angles_from_quaternion_f64};
-euler_angles_xyz_from_quaternion :: proc{euler_angles_xyz_from_quaternion_f16, euler_angles_xyz_from_quaternion_f32, euler_angles_xyz_from_quaternion_f64};
-euler_angles_yxz_from_quaternion :: proc{euler_angles_yxz_from_quaternion_f16, euler_angles_yxz_from_quaternion_f32, euler_angles_yxz_from_quaternion_f64};
-euler_angles_xzx_from_quaternion :: proc{euler_angles_xzx_from_quaternion_f16, euler_angles_xzx_from_quaternion_f32, euler_angles_xzx_from_quaternion_f64};
-euler_angles_xyx_from_quaternion :: proc{euler_angles_xyx_from_quaternion_f16, euler_angles_xyx_from_quaternion_f32, euler_angles_xyx_from_quaternion_f64};
-euler_angles_yxy_from_quaternion :: proc{euler_angles_yxy_from_quaternion_f16, euler_angles_yxy_from_quaternion_f32, euler_angles_yxy_from_quaternion_f64};
-euler_angles_yzy_from_quaternion :: proc{euler_angles_yzy_from_quaternion_f16, euler_angles_yzy_from_quaternion_f32, euler_angles_yzy_from_quaternion_f64};
-euler_angles_zyz_from_quaternion :: proc{euler_angles_zyz_from_quaternion_f16, euler_angles_zyz_from_quaternion_f32, euler_angles_zyz_from_quaternion_f64};
-euler_angles_zxz_from_quaternion :: proc{euler_angles_zxz_from_quaternion_f16, euler_angles_zxz_from_quaternion_f32, euler_angles_zxz_from_quaternion_f64};
-euler_angles_xzy_from_quaternion :: proc{euler_angles_xzy_from_quaternion_f16, euler_angles_xzy_from_quaternion_f32, euler_angles_xzy_from_quaternion_f64};
-euler_angles_yzx_from_quaternion :: proc{euler_angles_yzx_from_quaternion_f16, euler_angles_yzx_from_quaternion_f32, euler_angles_yzx_from_quaternion_f64};
-euler_angles_zyx_from_quaternion :: proc{euler_angles_zyx_from_quaternion_f16, euler_angles_zyx_from_quaternion_f32, euler_angles_zyx_from_quaternion_f64};
-euler_angles_zxy_from_quaternion :: proc{euler_angles_zxy_from_quaternion_f16, euler_angles_zxy_from_quaternion_f32, euler_angles_zxy_from_quaternion_f64};
+euler_angles_from_quaternion :: proc{euler_angles_from_quaternion_f16, euler_angles_from_quaternion_f32, euler_angles_from_quaternion_f64}
+euler_angles_xyz_from_quaternion :: proc{euler_angles_xyz_from_quaternion_f16, euler_angles_xyz_from_quaternion_f32, euler_angles_xyz_from_quaternion_f64}
+euler_angles_yxz_from_quaternion :: proc{euler_angles_yxz_from_quaternion_f16, euler_angles_yxz_from_quaternion_f32, euler_angles_yxz_from_quaternion_f64}
+euler_angles_xzx_from_quaternion :: proc{euler_angles_xzx_from_quaternion_f16, euler_angles_xzx_from_quaternion_f32, euler_angles_xzx_from_quaternion_f64}
+euler_angles_xyx_from_quaternion :: proc{euler_angles_xyx_from_quaternion_f16, euler_angles_xyx_from_quaternion_f32, euler_angles_xyx_from_quaternion_f64}
+euler_angles_yxy_from_quaternion :: proc{euler_angles_yxy_from_quaternion_f16, euler_angles_yxy_from_quaternion_f32, euler_angles_yxy_from_quaternion_f64}
+euler_angles_yzy_from_quaternion :: proc{euler_angles_yzy_from_quaternion_f16, euler_angles_yzy_from_quaternion_f32, euler_angles_yzy_from_quaternion_f64}
+euler_angles_zyz_from_quaternion :: proc{euler_angles_zyz_from_quaternion_f16, euler_angles_zyz_from_quaternion_f32, euler_angles_zyz_from_quaternion_f64}
+euler_angles_zxz_from_quaternion :: proc{euler_angles_zxz_from_quaternion_f16, euler_angles_zxz_from_quaternion_f32, euler_angles_zxz_from_quaternion_f64}
+euler_angles_xzy_from_quaternion :: proc{euler_angles_xzy_from_quaternion_f16, euler_angles_xzy_from_quaternion_f32, euler_angles_xzy_from_quaternion_f64}
+euler_angles_yzx_from_quaternion :: proc{euler_angles_yzx_from_quaternion_f16, euler_angles_yzx_from_quaternion_f32, euler_angles_yzx_from_quaternion_f64}
+euler_angles_zyx_from_quaternion :: proc{euler_angles_zyx_from_quaternion_f16, euler_angles_zyx_from_quaternion_f32, euler_angles_zyx_from_quaternion_f64}
+euler_angles_zxy_from_quaternion :: proc{euler_angles_zxy_from_quaternion_f16, euler_angles_zxy_from_quaternion_f32, euler_angles_zxy_from_quaternion_f64}
-roll_from_quaternion :: proc{roll_from_quaternion_f16, roll_from_quaternion_f32, roll_from_quaternion_f64};
-pitch_from_quaternion :: proc{pitch_from_quaternion_f16, pitch_from_quaternion_f32, pitch_from_quaternion_f64};
-yaw_from_quaternion :: proc{yaw_from_quaternion_f16, yaw_from_quaternion_f32, yaw_from_quaternion_f64};
-pitch_yaw_roll_from_quaternion :: proc{pitch_yaw_roll_from_quaternion_f16, pitch_yaw_roll_from_quaternion_f32, pitch_yaw_roll_from_quaternion_f64};
+roll_from_quaternion :: proc{roll_from_quaternion_f16, roll_from_quaternion_f32, roll_from_quaternion_f64}
+pitch_from_quaternion :: proc{pitch_from_quaternion_f16, pitch_from_quaternion_f32, pitch_from_quaternion_f64}
+yaw_from_quaternion :: proc{yaw_from_quaternion_f16, yaw_from_quaternion_f32, yaw_from_quaternion_f64}
+pitch_yaw_roll_from_quaternion :: proc{pitch_yaw_roll_from_quaternion_f16, pitch_yaw_roll_from_quaternion_f32, pitch_yaw_roll_from_quaternion_f64}
-matrix3_from_euler_angles :: proc{matrix3_from_euler_angles_f16, matrix3_from_euler_angles_f32, matrix3_from_euler_angles_f64};
-matrix3_from_euler_angle_x :: proc{matrix3_from_euler_angle_x_f16, matrix3_from_euler_angle_x_f32, matrix3_from_euler_angle_x_f64};
-matrix3_from_euler_angle_y :: proc{matrix3_from_euler_angle_y_f16, matrix3_from_euler_angle_y_f32, matrix3_from_euler_angle_y_f64};
-matrix3_from_euler_angle_z :: proc{matrix3_from_euler_angle_z_f16, matrix3_from_euler_angle_z_f32, matrix3_from_euler_angle_z_f64};
-matrix3_from_derived_euler_angle_x :: proc{matrix3_from_derived_euler_angle_x_f16, matrix3_from_derived_euler_angle_x_f32, matrix3_from_derived_euler_angle_x_f64};
-matrix3_from_derived_euler_angle_y :: proc{matrix3_from_derived_euler_angle_y_f16, matrix3_from_derived_euler_angle_y_f32, matrix3_from_derived_euler_angle_y_f64};
-matrix3_from_derived_euler_angle_z :: proc{matrix3_from_derived_euler_angle_z_f16, matrix3_from_derived_euler_angle_z_f32, matrix3_from_derived_euler_angle_z_f64};
-matrix3_from_euler_angles_xy :: proc{matrix3_from_euler_angles_xy_f16, matrix3_from_euler_angles_xy_f32, matrix3_from_euler_angles_xy_f64};
-matrix3_from_euler_angles_yx :: proc{matrix3_from_euler_angles_yx_f16, matrix3_from_euler_angles_yx_f32, matrix3_from_euler_angles_yx_f64};
-matrix3_from_euler_angles_xz :: proc{matrix3_from_euler_angles_xz_f16, matrix3_from_euler_angles_xz_f32, matrix3_from_euler_angles_xz_f64};
-matrix3_from_euler_angles_zx :: proc{matrix3_from_euler_angles_zx_f16, matrix3_from_euler_angles_zx_f32, matrix3_from_euler_angles_zx_f64};
-matrix3_from_euler_angles_yz :: proc{matrix3_from_euler_angles_yz_f16, matrix3_from_euler_angles_yz_f32, matrix3_from_euler_angles_yz_f64};
-matrix3_from_euler_angles_zy :: proc{matrix3_from_euler_angles_zy_f16, matrix3_from_euler_angles_zy_f32, matrix3_from_euler_angles_zy_f64};
-matrix3_from_euler_angles_xyz :: proc{matrix3_from_euler_angles_xyz_f16, matrix3_from_euler_angles_xyz_f32, matrix3_from_euler_angles_xyz_f64};
-matrix3_from_euler_angles_yxz :: proc{matrix3_from_euler_angles_yxz_f16, matrix3_from_euler_angles_yxz_f32, matrix3_from_euler_angles_yxz_f64};
-matrix3_from_euler_angles_xzx :: proc{matrix3_from_euler_angles_xzx_f16, matrix3_from_euler_angles_xzx_f32, matrix3_from_euler_angles_xzx_f64};
-matrix3_from_euler_angles_xyx :: proc{matrix3_from_euler_angles_xyx_f16, matrix3_from_euler_angles_xyx_f32, matrix3_from_euler_angles_xyx_f64};
-matrix3_from_euler_angles_yxy :: proc{matrix3_from_euler_angles_yxy_f16, matrix3_from_euler_angles_yxy_f32, matrix3_from_euler_angles_yxy_f64};
-matrix3_from_euler_angles_yzy :: proc{matrix3_from_euler_angles_yzy_f16, matrix3_from_euler_angles_yzy_f32, matrix3_from_euler_angles_yzy_f64};
-matrix3_from_euler_angles_zyz :: proc{matrix3_from_euler_angles_zyz_f16, matrix3_from_euler_angles_zyz_f32, matrix3_from_euler_angles_zyz_f64};
-matrix3_from_euler_angles_zxz :: proc{matrix3_from_euler_angles_zxz_f16, matrix3_from_euler_angles_zxz_f32, matrix3_from_euler_angles_zxz_f64};
-matrix3_from_euler_angles_xzy :: proc{matrix3_from_euler_angles_xzy_f16, matrix3_from_euler_angles_xzy_f32, matrix3_from_euler_angles_xzy_f64};
-matrix3_from_euler_angles_yzx :: proc{matrix3_from_euler_angles_yzx_f16, matrix3_from_euler_angles_yzx_f32, matrix3_from_euler_angles_yzx_f64};
-matrix3_from_euler_angles_zyx :: proc{matrix3_from_euler_angles_zyx_f16, matrix3_from_euler_angles_zyx_f32, matrix3_from_euler_angles_zyx_f64};
-matrix3_from_euler_angles_zxy :: proc{matrix3_from_euler_angles_zxy_f16, matrix3_from_euler_angles_zxy_f32, matrix3_from_euler_angles_zxy_f64};
-matrix3_from_yaw_pitch_roll :: proc{matrix3_from_yaw_pitch_roll_f16, matrix3_from_yaw_pitch_roll_f32, matrix3_from_yaw_pitch_roll_f64};
+matrix3_from_euler_angles :: proc{matrix3_from_euler_angles_f16, matrix3_from_euler_angles_f32, matrix3_from_euler_angles_f64}
+matrix3_from_euler_angle_x :: proc{matrix3_from_euler_angle_x_f16, matrix3_from_euler_angle_x_f32, matrix3_from_euler_angle_x_f64}
+matrix3_from_euler_angle_y :: proc{matrix3_from_euler_angle_y_f16, matrix3_from_euler_angle_y_f32, matrix3_from_euler_angle_y_f64}
+matrix3_from_euler_angle_z :: proc{matrix3_from_euler_angle_z_f16, matrix3_from_euler_angle_z_f32, matrix3_from_euler_angle_z_f64}
+matrix3_from_derived_euler_angle_x :: proc{matrix3_from_derived_euler_angle_x_f16, matrix3_from_derived_euler_angle_x_f32, matrix3_from_derived_euler_angle_x_f64}
+matrix3_from_derived_euler_angle_y :: proc{matrix3_from_derived_euler_angle_y_f16, matrix3_from_derived_euler_angle_y_f32, matrix3_from_derived_euler_angle_y_f64}
+matrix3_from_derived_euler_angle_z :: proc{matrix3_from_derived_euler_angle_z_f16, matrix3_from_derived_euler_angle_z_f32, matrix3_from_derived_euler_angle_z_f64}
+matrix3_from_euler_angles_xy :: proc{matrix3_from_euler_angles_xy_f16, matrix3_from_euler_angles_xy_f32, matrix3_from_euler_angles_xy_f64}
+matrix3_from_euler_angles_yx :: proc{matrix3_from_euler_angles_yx_f16, matrix3_from_euler_angles_yx_f32, matrix3_from_euler_angles_yx_f64}
+matrix3_from_euler_angles_xz :: proc{matrix3_from_euler_angles_xz_f16, matrix3_from_euler_angles_xz_f32, matrix3_from_euler_angles_xz_f64}
+matrix3_from_euler_angles_zx :: proc{matrix3_from_euler_angles_zx_f16, matrix3_from_euler_angles_zx_f32, matrix3_from_euler_angles_zx_f64}
+matrix3_from_euler_angles_yz :: proc{matrix3_from_euler_angles_yz_f16, matrix3_from_euler_angles_yz_f32, matrix3_from_euler_angles_yz_f64}
+matrix3_from_euler_angles_zy :: proc{matrix3_from_euler_angles_zy_f16, matrix3_from_euler_angles_zy_f32, matrix3_from_euler_angles_zy_f64}
+matrix3_from_euler_angles_xyz :: proc{matrix3_from_euler_angles_xyz_f16, matrix3_from_euler_angles_xyz_f32, matrix3_from_euler_angles_xyz_f64}
+matrix3_from_euler_angles_yxz :: proc{matrix3_from_euler_angles_yxz_f16, matrix3_from_euler_angles_yxz_f32, matrix3_from_euler_angles_yxz_f64}
+matrix3_from_euler_angles_xzx :: proc{matrix3_from_euler_angles_xzx_f16, matrix3_from_euler_angles_xzx_f32, matrix3_from_euler_angles_xzx_f64}
+matrix3_from_euler_angles_xyx :: proc{matrix3_from_euler_angles_xyx_f16, matrix3_from_euler_angles_xyx_f32, matrix3_from_euler_angles_xyx_f64}
+matrix3_from_euler_angles_yxy :: proc{matrix3_from_euler_angles_yxy_f16, matrix3_from_euler_angles_yxy_f32, matrix3_from_euler_angles_yxy_f64}
+matrix3_from_euler_angles_yzy :: proc{matrix3_from_euler_angles_yzy_f16, matrix3_from_euler_angles_yzy_f32, matrix3_from_euler_angles_yzy_f64}
+matrix3_from_euler_angles_zyz :: proc{matrix3_from_euler_angles_zyz_f16, matrix3_from_euler_angles_zyz_f32, matrix3_from_euler_angles_zyz_f64}
+matrix3_from_euler_angles_zxz :: proc{matrix3_from_euler_angles_zxz_f16, matrix3_from_euler_angles_zxz_f32, matrix3_from_euler_angles_zxz_f64}
+matrix3_from_euler_angles_xzy :: proc{matrix3_from_euler_angles_xzy_f16, matrix3_from_euler_angles_xzy_f32, matrix3_from_euler_angles_xzy_f64}
+matrix3_from_euler_angles_yzx :: proc{matrix3_from_euler_angles_yzx_f16, matrix3_from_euler_angles_yzx_f32, matrix3_from_euler_angles_yzx_f64}
+matrix3_from_euler_angles_zyx :: proc{matrix3_from_euler_angles_zyx_f16, matrix3_from_euler_angles_zyx_f32, matrix3_from_euler_angles_zyx_f64}
+matrix3_from_euler_angles_zxy :: proc{matrix3_from_euler_angles_zxy_f16, matrix3_from_euler_angles_zxy_f32, matrix3_from_euler_angles_zxy_f64}
+matrix3_from_yaw_pitch_roll :: proc{matrix3_from_yaw_pitch_roll_f16, matrix3_from_yaw_pitch_roll_f32, matrix3_from_yaw_pitch_roll_f64}
-euler_angles_from_matrix3 :: proc{euler_angles_from_matrix3_f16, euler_angles_from_matrix3_f32, euler_angles_from_matrix3_f64};
-euler_angles_xyz_from_matrix3 :: proc{euler_angles_xyz_from_matrix3_f16, euler_angles_xyz_from_matrix3_f32, euler_angles_xyz_from_matrix3_f64};
-euler_angles_yxz_from_matrix3 :: proc{euler_angles_yxz_from_matrix3_f16, euler_angles_yxz_from_matrix3_f32, euler_angles_yxz_from_matrix3_f64};
-euler_angles_xzx_from_matrix3 :: proc{euler_angles_xzx_from_matrix3_f16, euler_angles_xzx_from_matrix3_f32, euler_angles_xzx_from_matrix3_f64};
-euler_angles_xyx_from_matrix3 :: proc{euler_angles_xyx_from_matrix3_f16, euler_angles_xyx_from_matrix3_f32, euler_angles_xyx_from_matrix3_f64};
-euler_angles_yxy_from_matrix3 :: proc{euler_angles_yxy_from_matrix3_f16, euler_angles_yxy_from_matrix3_f32, euler_angles_yxy_from_matrix3_f64};
-euler_angles_yzy_from_matrix3 :: proc{euler_angles_yzy_from_matrix3_f16, euler_angles_yzy_from_matrix3_f32, euler_angles_yzy_from_matrix3_f64};
-euler_angles_zyz_from_matrix3 :: proc{euler_angles_zyz_from_matrix3_f16, euler_angles_zyz_from_matrix3_f32, euler_angles_zyz_from_matrix3_f64};
-euler_angles_zxz_from_matrix3 :: proc{euler_angles_zxz_from_matrix3_f16, euler_angles_zxz_from_matrix3_f32, euler_angles_zxz_from_matrix3_f64};
-euler_angles_xzy_from_matrix3 :: proc{euler_angles_xzy_from_matrix3_f16, euler_angles_xzy_from_matrix3_f32, euler_angles_xzy_from_matrix3_f64};
-euler_angles_yzx_from_matrix3 :: proc{euler_angles_yzx_from_matrix3_f16, euler_angles_yzx_from_matrix3_f32, euler_angles_yzx_from_matrix3_f64};
-euler_angles_zyx_from_matrix3 :: proc{euler_angles_zyx_from_matrix3_f16, euler_angles_zyx_from_matrix3_f32, euler_angles_zyx_from_matrix3_f64};
-euler_angles_zxy_from_matrix3 :: proc{euler_angles_zxy_from_matrix3_f16, euler_angles_zxy_from_matrix3_f32, euler_angles_zxy_from_matrix3_f64};
+euler_angles_from_matrix3 :: proc{euler_angles_from_matrix3_f16, euler_angles_from_matrix3_f32, euler_angles_from_matrix3_f64}
+euler_angles_xyz_from_matrix3 :: proc{euler_angles_xyz_from_matrix3_f16, euler_angles_xyz_from_matrix3_f32, euler_angles_xyz_from_matrix3_f64}
+euler_angles_yxz_from_matrix3 :: proc{euler_angles_yxz_from_matrix3_f16, euler_angles_yxz_from_matrix3_f32, euler_angles_yxz_from_matrix3_f64}
+euler_angles_xzx_from_matrix3 :: proc{euler_angles_xzx_from_matrix3_f16, euler_angles_xzx_from_matrix3_f32, euler_angles_xzx_from_matrix3_f64}
+euler_angles_xyx_from_matrix3 :: proc{euler_angles_xyx_from_matrix3_f16, euler_angles_xyx_from_matrix3_f32, euler_angles_xyx_from_matrix3_f64}
+euler_angles_yxy_from_matrix3 :: proc{euler_angles_yxy_from_matrix3_f16, euler_angles_yxy_from_matrix3_f32, euler_angles_yxy_from_matrix3_f64}
+euler_angles_yzy_from_matrix3 :: proc{euler_angles_yzy_from_matrix3_f16, euler_angles_yzy_from_matrix3_f32, euler_angles_yzy_from_matrix3_f64}
+euler_angles_zyz_from_matrix3 :: proc{euler_angles_zyz_from_matrix3_f16, euler_angles_zyz_from_matrix3_f32, euler_angles_zyz_from_matrix3_f64}
+euler_angles_zxz_from_matrix3 :: proc{euler_angles_zxz_from_matrix3_f16, euler_angles_zxz_from_matrix3_f32, euler_angles_zxz_from_matrix3_f64}
+euler_angles_xzy_from_matrix3 :: proc{euler_angles_xzy_from_matrix3_f16, euler_angles_xzy_from_matrix3_f32, euler_angles_xzy_from_matrix3_f64}
+euler_angles_yzx_from_matrix3 :: proc{euler_angles_yzx_from_matrix3_f16, euler_angles_yzx_from_matrix3_f32, euler_angles_yzx_from_matrix3_f64}
+euler_angles_zyx_from_matrix3 :: proc{euler_angles_zyx_from_matrix3_f16, euler_angles_zyx_from_matrix3_f32, euler_angles_zyx_from_matrix3_f64}
+euler_angles_zxy_from_matrix3 :: proc{euler_angles_zxy_from_matrix3_f16, euler_angles_zxy_from_matrix3_f32, euler_angles_zxy_from_matrix3_f64}
-matrix4_from_euler_angles :: proc{matrix4_from_euler_angles_f16, matrix4_from_euler_angles_f32, matrix4_from_euler_angles_f64};
-matrix4_from_euler_angle_x :: proc{matrix4_from_euler_angle_x_f16, matrix4_from_euler_angle_x_f32, matrix4_from_euler_angle_x_f64};
-matrix4_from_euler_angle_y :: proc{matrix4_from_euler_angle_y_f16, matrix4_from_euler_angle_y_f32, matrix4_from_euler_angle_y_f64};
-matrix4_from_euler_angle_z :: proc{matrix4_from_euler_angle_z_f16, matrix4_from_euler_angle_z_f32, matrix4_from_euler_angle_z_f64};
-matrix4_from_derived_euler_angle_x :: proc{matrix4_from_derived_euler_angle_x_f16, matrix4_from_derived_euler_angle_x_f32, matrix4_from_derived_euler_angle_x_f64};
-matrix4_from_derived_euler_angle_y :: proc{matrix4_from_derived_euler_angle_y_f16, matrix4_from_derived_euler_angle_y_f32, matrix4_from_derived_euler_angle_y_f64};
-matrix4_from_derived_euler_angle_z :: proc{matrix4_from_derived_euler_angle_z_f16, matrix4_from_derived_euler_angle_z_f32, matrix4_from_derived_euler_angle_z_f64};
-matrix4_from_euler_angles_xy :: proc{matrix4_from_euler_angles_xy_f16, matrix4_from_euler_angles_xy_f32, matrix4_from_euler_angles_xy_f64};
-matrix4_from_euler_angles_yx :: proc{matrix4_from_euler_angles_yx_f16, matrix4_from_euler_angles_yx_f32, matrix4_from_euler_angles_yx_f64};
-matrix4_from_euler_angles_xz :: proc{matrix4_from_euler_angles_xz_f16, matrix4_from_euler_angles_xz_f32, matrix4_from_euler_angles_xz_f64};
-matrix4_from_euler_angles_zx :: proc{matrix4_from_euler_angles_zx_f16, matrix4_from_euler_angles_zx_f32, matrix4_from_euler_angles_zx_f64};
-matrix4_from_euler_angles_yz :: proc{matrix4_from_euler_angles_yz_f16, matrix4_from_euler_angles_yz_f32, matrix4_from_euler_angles_yz_f64};
-matrix4_from_euler_angles_zy :: proc{matrix4_from_euler_angles_zy_f16, matrix4_from_euler_angles_zy_f32, matrix4_from_euler_angles_zy_f64};
-matrix4_from_euler_angles_xyz :: proc{matrix4_from_euler_angles_xyz_f16, matrix4_from_euler_angles_xyz_f32, matrix4_from_euler_angles_xyz_f64};
-matrix4_from_euler_angles_yxz :: proc{matrix4_from_euler_angles_yxz_f16, matrix4_from_euler_angles_yxz_f32, matrix4_from_euler_angles_yxz_f64};
-matrix4_from_euler_angles_xzx :: proc{matrix4_from_euler_angles_xzx_f16, matrix4_from_euler_angles_xzx_f32, matrix4_from_euler_angles_xzx_f64};
-matrix4_from_euler_angles_xyx :: proc{matrix4_from_euler_angles_xyx_f16, matrix4_from_euler_angles_xyx_f32, matrix4_from_euler_angles_xyx_f64};
-matrix4_from_euler_angles_yxy :: proc{matrix4_from_euler_angles_yxy_f16, matrix4_from_euler_angles_yxy_f32, matrix4_from_euler_angles_yxy_f64};
-matrix4_from_euler_angles_yzy :: proc{matrix4_from_euler_angles_yzy_f16, matrix4_from_euler_angles_yzy_f32, matrix4_from_euler_angles_yzy_f64};
-matrix4_from_euler_angles_zyz :: proc{matrix4_from_euler_angles_zyz_f16, matrix4_from_euler_angles_zyz_f32, matrix4_from_euler_angles_zyz_f64};
-matrix4_from_euler_angles_zxz :: proc{matrix4_from_euler_angles_zxz_f16, matrix4_from_euler_angles_zxz_f32, matrix4_from_euler_angles_zxz_f64};
-matrix4_from_euler_angles_xzy :: proc{matrix4_from_euler_angles_xzy_f16, matrix4_from_euler_angles_xzy_f32, matrix4_from_euler_angles_xzy_f64};
-matrix4_from_euler_angles_yzx :: proc{matrix4_from_euler_angles_yzx_f16, matrix4_from_euler_angles_yzx_f32, matrix4_from_euler_angles_yzx_f64};
-matrix4_from_euler_angles_zyx :: proc{matrix4_from_euler_angles_zyx_f16, matrix4_from_euler_angles_zyx_f32, matrix4_from_euler_angles_zyx_f64};
-matrix4_from_euler_angles_zxy :: proc{matrix4_from_euler_angles_zxy_f16, matrix4_from_euler_angles_zxy_f32, matrix4_from_euler_angles_zxy_f64};
-matrix4_from_yaw_pitch_roll :: proc{matrix4_from_yaw_pitch_roll_f16, matrix4_from_yaw_pitch_roll_f32, matrix4_from_yaw_pitch_roll_f64};
+matrix4_from_euler_angles :: proc{matrix4_from_euler_angles_f16, matrix4_from_euler_angles_f32, matrix4_from_euler_angles_f64}
+matrix4_from_euler_angle_x :: proc{matrix4_from_euler_angle_x_f16, matrix4_from_euler_angle_x_f32, matrix4_from_euler_angle_x_f64}
+matrix4_from_euler_angle_y :: proc{matrix4_from_euler_angle_y_f16, matrix4_from_euler_angle_y_f32, matrix4_from_euler_angle_y_f64}
+matrix4_from_euler_angle_z :: proc{matrix4_from_euler_angle_z_f16, matrix4_from_euler_angle_z_f32, matrix4_from_euler_angle_z_f64}
+matrix4_from_derived_euler_angle_x :: proc{matrix4_from_derived_euler_angle_x_f16, matrix4_from_derived_euler_angle_x_f32, matrix4_from_derived_euler_angle_x_f64}
+matrix4_from_derived_euler_angle_y :: proc{matrix4_from_derived_euler_angle_y_f16, matrix4_from_derived_euler_angle_y_f32, matrix4_from_derived_euler_angle_y_f64}
+matrix4_from_derived_euler_angle_z :: proc{matrix4_from_derived_euler_angle_z_f16, matrix4_from_derived_euler_angle_z_f32, matrix4_from_derived_euler_angle_z_f64}
+matrix4_from_euler_angles_xy :: proc{matrix4_from_euler_angles_xy_f16, matrix4_from_euler_angles_xy_f32, matrix4_from_euler_angles_xy_f64}
+matrix4_from_euler_angles_yx :: proc{matrix4_from_euler_angles_yx_f16, matrix4_from_euler_angles_yx_f32, matrix4_from_euler_angles_yx_f64}
+matrix4_from_euler_angles_xz :: proc{matrix4_from_euler_angles_xz_f16, matrix4_from_euler_angles_xz_f32, matrix4_from_euler_angles_xz_f64}
+matrix4_from_euler_angles_zx :: proc{matrix4_from_euler_angles_zx_f16, matrix4_from_euler_angles_zx_f32, matrix4_from_euler_angles_zx_f64}
+matrix4_from_euler_angles_yz :: proc{matrix4_from_euler_angles_yz_f16, matrix4_from_euler_angles_yz_f32, matrix4_from_euler_angles_yz_f64}
+matrix4_from_euler_angles_zy :: proc{matrix4_from_euler_angles_zy_f16, matrix4_from_euler_angles_zy_f32, matrix4_from_euler_angles_zy_f64}
+matrix4_from_euler_angles_xyz :: proc{matrix4_from_euler_angles_xyz_f16, matrix4_from_euler_angles_xyz_f32, matrix4_from_euler_angles_xyz_f64}
+matrix4_from_euler_angles_yxz :: proc{matrix4_from_euler_angles_yxz_f16, matrix4_from_euler_angles_yxz_f32, matrix4_from_euler_angles_yxz_f64}
+matrix4_from_euler_angles_xzx :: proc{matrix4_from_euler_angles_xzx_f16, matrix4_from_euler_angles_xzx_f32, matrix4_from_euler_angles_xzx_f64}
+matrix4_from_euler_angles_xyx :: proc{matrix4_from_euler_angles_xyx_f16, matrix4_from_euler_angles_xyx_f32, matrix4_from_euler_angles_xyx_f64}
+matrix4_from_euler_angles_yxy :: proc{matrix4_from_euler_angles_yxy_f16, matrix4_from_euler_angles_yxy_f32, matrix4_from_euler_angles_yxy_f64}
+matrix4_from_euler_angles_yzy :: proc{matrix4_from_euler_angles_yzy_f16, matrix4_from_euler_angles_yzy_f32, matrix4_from_euler_angles_yzy_f64}
+matrix4_from_euler_angles_zyz :: proc{matrix4_from_euler_angles_zyz_f16, matrix4_from_euler_angles_zyz_f32, matrix4_from_euler_angles_zyz_f64}
+matrix4_from_euler_angles_zxz :: proc{matrix4_from_euler_angles_zxz_f16, matrix4_from_euler_angles_zxz_f32, matrix4_from_euler_angles_zxz_f64}
+matrix4_from_euler_angles_xzy :: proc{matrix4_from_euler_angles_xzy_f16, matrix4_from_euler_angles_xzy_f32, matrix4_from_euler_angles_xzy_f64}
+matrix4_from_euler_angles_yzx :: proc{matrix4_from_euler_angles_yzx_f16, matrix4_from_euler_angles_yzx_f32, matrix4_from_euler_angles_yzx_f64}
+matrix4_from_euler_angles_zyx :: proc{matrix4_from_euler_angles_zyx_f16, matrix4_from_euler_angles_zyx_f32, matrix4_from_euler_angles_zyx_f64}
+matrix4_from_euler_angles_zxy :: proc{matrix4_from_euler_angles_zxy_f16, matrix4_from_euler_angles_zxy_f32, matrix4_from_euler_angles_zxy_f64}
+matrix4_from_yaw_pitch_roll :: proc{matrix4_from_yaw_pitch_roll_f16, matrix4_from_yaw_pitch_roll_f32, matrix4_from_yaw_pitch_roll_f64}
-euler_angles_from_matrix4 :: proc{euler_angles_from_matrix4_f16, euler_angles_from_matrix4_f32, euler_angles_from_matrix4_f64};
-euler_angles_xyz_from_matrix4 :: proc{euler_angles_xyz_from_matrix4_f16, euler_angles_xyz_from_matrix4_f32, euler_angles_xyz_from_matrix4_f64};
-euler_angles_yxz_from_matrix4 :: proc{euler_angles_yxz_from_matrix4_f16, euler_angles_yxz_from_matrix4_f32, euler_angles_yxz_from_matrix4_f64};
-euler_angles_xzx_from_matrix4 :: proc{euler_angles_xzx_from_matrix4_f16, euler_angles_xzx_from_matrix4_f32, euler_angles_xzx_from_matrix4_f64};
-euler_angles_xyx_from_matrix4 :: proc{euler_angles_xyx_from_matrix4_f16, euler_angles_xyx_from_matrix4_f32, euler_angles_xyx_from_matrix4_f64};
-euler_angles_yxy_from_matrix4 :: proc{euler_angles_yxy_from_matrix4_f16, euler_angles_yxy_from_matrix4_f32, euler_angles_yxy_from_matrix4_f64};
-euler_angles_yzy_from_matrix4 :: proc{euler_angles_yzy_from_matrix4_f16, euler_angles_yzy_from_matrix4_f32, euler_angles_yzy_from_matrix4_f64};
-euler_angles_zyz_from_matrix4 :: proc{euler_angles_zyz_from_matrix4_f16, euler_angles_zyz_from_matrix4_f32, euler_angles_zyz_from_matrix4_f64};
-euler_angles_zxz_from_matrix4 :: proc{euler_angles_zxz_from_matrix4_f16, euler_angles_zxz_from_matrix4_f32, euler_angles_zxz_from_matrix4_f64};
-euler_angles_xzy_from_matrix4 :: proc{euler_angles_xzy_from_matrix4_f16, euler_angles_xzy_from_matrix4_f32, euler_angles_xzy_from_matrix4_f64};
-euler_angles_yzx_from_matrix4 :: proc{euler_angles_yzx_from_matrix4_f16, euler_angles_yzx_from_matrix4_f32, euler_angles_yzx_from_matrix4_f64};
-euler_angles_zyx_from_matrix4 :: proc{euler_angles_zyx_from_matrix4_f16, euler_angles_zyx_from_matrix4_f32, euler_angles_zyx_from_matrix4_f64};
-euler_angles_zxy_from_matrix4 :: proc{euler_angles_zxy_from_matrix4_f16, euler_angles_zxy_from_matrix4_f32, euler_angles_zxy_from_matrix4_f64};
+euler_angles_from_matrix4 :: proc{euler_angles_from_matrix4_f16, euler_angles_from_matrix4_f32, euler_angles_from_matrix4_f64}
+euler_angles_xyz_from_matrix4 :: proc{euler_angles_xyz_from_matrix4_f16, euler_angles_xyz_from_matrix4_f32, euler_angles_xyz_from_matrix4_f64}
+euler_angles_yxz_from_matrix4 :: proc{euler_angles_yxz_from_matrix4_f16, euler_angles_yxz_from_matrix4_f32, euler_angles_yxz_from_matrix4_f64}
+euler_angles_xzx_from_matrix4 :: proc{euler_angles_xzx_from_matrix4_f16, euler_angles_xzx_from_matrix4_f32, euler_angles_xzx_from_matrix4_f64}
+euler_angles_xyx_from_matrix4 :: proc{euler_angles_xyx_from_matrix4_f16, euler_angles_xyx_from_matrix4_f32, euler_angles_xyx_from_matrix4_f64}
+euler_angles_yxy_from_matrix4 :: proc{euler_angles_yxy_from_matrix4_f16, euler_angles_yxy_from_matrix4_f32, euler_angles_yxy_from_matrix4_f64}
+euler_angles_yzy_from_matrix4 :: proc{euler_angles_yzy_from_matrix4_f16, euler_angles_yzy_from_matrix4_f32, euler_angles_yzy_from_matrix4_f64}
+euler_angles_zyz_from_matrix4 :: proc{euler_angles_zyz_from_matrix4_f16, euler_angles_zyz_from_matrix4_f32, euler_angles_zyz_from_matrix4_f64}
+euler_angles_zxz_from_matrix4 :: proc{euler_angles_zxz_from_matrix4_f16, euler_angles_zxz_from_matrix4_f32, euler_angles_zxz_from_matrix4_f64}
+euler_angles_xzy_from_matrix4 :: proc{euler_angles_xzy_from_matrix4_f16, euler_angles_xzy_from_matrix4_f32, euler_angles_xzy_from_matrix4_f64}
+euler_angles_yzx_from_matrix4 :: proc{euler_angles_yzx_from_matrix4_f16, euler_angles_yzx_from_matrix4_f32, euler_angles_yzx_from_matrix4_f64}
+euler_angles_zyx_from_matrix4 :: proc{euler_angles_zyx_from_matrix4_f16, euler_angles_zyx_from_matrix4_f32, euler_angles_zyx_from_matrix4_f64}
+euler_angles_zxy_from_matrix4 :: proc{euler_angles_zxy_from_matrix4_f16, euler_angles_zxy_from_matrix4_f32, euler_angles_zxy_from_matrix4_f64}
diff --git a/core/math/linalg/specific_euler_angles_f16.odin b/core/math/linalg/specific_euler_angles_f16.odin
index bcfac6039..d0fb1beb3 100644
--- a/core/math/linalg/specific_euler_angles_f16.odin
+++ b/core/math/linalg/specific_euler_angles_f16.odin
@@ -4,206 +4,206 @@ import "core:math"
euler_angles_from_matrix3_f16 :: proc(m: Matrix3f16, order: Euler_Angle_Order) -> (t1, t2, t3: f16) {
switch order {
- case .XYZ: t1, t2, t3 = euler_angles_xyz_from_matrix3(m);
- case .XZY: t1, t2, t3 = euler_angles_xzy_from_matrix3(m);
- case .YXZ: t1, t2, t3 = euler_angles_yxz_from_matrix3(m);
- case .YZX: t1, t2, t3 = euler_angles_yzx_from_matrix3(m);
- case .ZXY: t1, t2, t3 = euler_angles_zxy_from_matrix3(m);
- case .ZYX: t1, t2, t3 = euler_angles_zyx_from_matrix3(m);
- case .XYX: t1, t2, t3 = euler_angles_xyx_from_matrix3(m);
- case .XZX: t1, t2, t3 = euler_angles_xzx_from_matrix3(m);
- case .YXY: t1, t2, t3 = euler_angles_yxy_from_matrix3(m);
- case .YZY: t1, t2, t3 = euler_angles_yzy_from_matrix3(m);
- case .ZXZ: t1, t2, t3 = euler_angles_zxz_from_matrix3(m);
- case .ZYZ: t1, t2, t3 = euler_angles_zyz_from_matrix3(m);
+ case .XYZ: t1, t2, t3 = euler_angles_xyz_from_matrix3(m)
+ case .XZY: t1, t2, t3 = euler_angles_xzy_from_matrix3(m)
+ case .YXZ: t1, t2, t3 = euler_angles_yxz_from_matrix3(m)
+ case .YZX: t1, t2, t3 = euler_angles_yzx_from_matrix3(m)
+ case .ZXY: t1, t2, t3 = euler_angles_zxy_from_matrix3(m)
+ case .ZYX: t1, t2, t3 = euler_angles_zyx_from_matrix3(m)
+ case .XYX: t1, t2, t3 = euler_angles_xyx_from_matrix3(m)
+ case .XZX: t1, t2, t3 = euler_angles_xzx_from_matrix3(m)
+ case .YXY: t1, t2, t3 = euler_angles_yxy_from_matrix3(m)
+ case .YZY: t1, t2, t3 = euler_angles_yzy_from_matrix3(m)
+ case .ZXZ: t1, t2, t3 = euler_angles_zxz_from_matrix3(m)
+ case .ZYZ: t1, t2, t3 = euler_angles_zyz_from_matrix3(m)
}
- return;
+ return
}
euler_angles_from_matrix4_f16 :: proc(m: Matrix4f16, order: Euler_Angle_Order) -> (t1, t2, t3: f16) {
switch order {
- case .XYZ: t1, t2, t3 = euler_angles_xyz_from_matrix4(m);
- case .XZY: t1, t2, t3 = euler_angles_xzy_from_matrix4(m);
- case .YXZ: t1, t2, t3 = euler_angles_yxz_from_matrix4(m);
- case .YZX: t1, t2, t3 = euler_angles_yzx_from_matrix4(m);
- case .ZXY: t1, t2, t3 = euler_angles_zxy_from_matrix4(m);
- case .ZYX: t1, t2, t3 = euler_angles_zyx_from_matrix4(m);
- case .XYX: t1, t2, t3 = euler_angles_xyx_from_matrix4(m);
- case .XZX: t1, t2, t3 = euler_angles_xzx_from_matrix4(m);
- case .YXY: t1, t2, t3 = euler_angles_yxy_from_matrix4(m);
- case .YZY: t1, t2, t3 = euler_angles_yzy_from_matrix4(m);
- case .ZXZ: t1, t2, t3 = euler_angles_zxz_from_matrix4(m);
- case .ZYZ: t1, t2, t3 = euler_angles_zyz_from_matrix4(m);
+ case .XYZ: t1, t2, t3 = euler_angles_xyz_from_matrix4(m)
+ case .XZY: t1, t2, t3 = euler_angles_xzy_from_matrix4(m)
+ case .YXZ: t1, t2, t3 = euler_angles_yxz_from_matrix4(m)
+ case .YZX: t1, t2, t3 = euler_angles_yzx_from_matrix4(m)
+ case .ZXY: t1, t2, t3 = euler_angles_zxy_from_matrix4(m)
+ case .ZYX: t1, t2, t3 = euler_angles_zyx_from_matrix4(m)
+ case .XYX: t1, t2, t3 = euler_angles_xyx_from_matrix4(m)
+ case .XZX: t1, t2, t3 = euler_angles_xzx_from_matrix4(m)
+ case .YXY: t1, t2, t3 = euler_angles_yxy_from_matrix4(m)
+ case .YZY: t1, t2, t3 = euler_angles_yzy_from_matrix4(m)
+ case .ZXZ: t1, t2, t3 = euler_angles_zxz_from_matrix4(m)
+ case .ZYZ: t1, t2, t3 = euler_angles_zyz_from_matrix4(m)
}
- return;
+ return
}
euler_angles_from_quaternion_f16 :: proc(m: Quaternionf16, order: Euler_Angle_Order) -> (t1, t2, t3: f16) {
switch order {
- case .XYZ: t1, t2, t3 = euler_angles_xyz_from_quaternion(m);
- case .XZY: t1, t2, t3 = euler_angles_xzy_from_quaternion(m);
- case .YXZ: t1, t2, t3 = euler_angles_yxz_from_quaternion(m);
- case .YZX: t1, t2, t3 = euler_angles_yzx_from_quaternion(m);
- case .ZXY: t1, t2, t3 = euler_angles_zxy_from_quaternion(m);
- case .ZYX: t1, t2, t3 = euler_angles_zyx_from_quaternion(m);
- case .XYX: t1, t2, t3 = euler_angles_xyx_from_quaternion(m);
- case .XZX: t1, t2, t3 = euler_angles_xzx_from_quaternion(m);
- case .YXY: t1, t2, t3 = euler_angles_yxy_from_quaternion(m);
- case .YZY: t1, t2, t3 = euler_angles_yzy_from_quaternion(m);
- case .ZXZ: t1, t2, t3 = euler_angles_zxz_from_quaternion(m);
- case .ZYZ: t1, t2, t3 = euler_angles_zyz_from_quaternion(m);
+ case .XYZ: t1, t2, t3 = euler_angles_xyz_from_quaternion(m)
+ case .XZY: t1, t2, t3 = euler_angles_xzy_from_quaternion(m)
+ case .YXZ: t1, t2, t3 = euler_angles_yxz_from_quaternion(m)
+ case .YZX: t1, t2, t3 = euler_angles_yzx_from_quaternion(m)
+ case .ZXY: t1, t2, t3 = euler_angles_zxy_from_quaternion(m)
+ case .ZYX: t1, t2, t3 = euler_angles_zyx_from_quaternion(m)
+ case .XYX: t1, t2, t3 = euler_angles_xyx_from_quaternion(m)
+ case .XZX: t1, t2, t3 = euler_angles_xzx_from_quaternion(m)
+ case .YXY: t1, t2, t3 = euler_angles_yxy_from_quaternion(m)
+ case .YZY: t1, t2, t3 = euler_angles_yzy_from_quaternion(m)
+ case .ZXZ: t1, t2, t3 = euler_angles_zxz_from_quaternion(m)
+ case .ZYZ: t1, t2, t3 = euler_angles_zyz_from_quaternion(m)
}
- return;
+ return
}
matrix3_from_euler_angles_f16 :: proc(t1, t2, t3: f16, order: Euler_Angle_Order) -> (m: Matrix3f16) {
switch order {
- case .XYZ: return matrix3_from_euler_angles_xyz(t1, t2, t3); // m1, m2, m3 = X(t1), Y(t2), Z(t3);
- case .XZY: return matrix3_from_euler_angles_xzy(t1, t2, t3); // m1, m2, m3 = X(t1), Z(t2), Y(t3);
- case .YXZ: return matrix3_from_euler_angles_yxz(t1, t2, t3); // m1, m2, m3 = Y(t1), X(t2), Z(t3);
- case .YZX: return matrix3_from_euler_angles_yzx(t1, t2, t3); // m1, m2, m3 = Y(t1), Z(t2), X(t3);
- case .ZXY: return matrix3_from_euler_angles_zxy(t1, t2, t3); // m1, m2, m3 = Z(t1), X(t2), Y(t3);
- case .ZYX: return matrix3_from_euler_angles_zyx(t1, t2, t3); // m1, m2, m3 = Z(t1), Y(t2), X(t3);
- case .XYX: return matrix3_from_euler_angles_xyx(t1, t2, t3); // m1, m2, m3 = X(t1), Y(t2), X(t3);
- case .XZX: return matrix3_from_euler_angles_xzx(t1, t2, t3); // m1, m2, m3 = X(t1), Z(t2), X(t3);
- case .YXY: return matrix3_from_euler_angles_yxy(t1, t2, t3); // m1, m2, m3 = Y(t1), X(t2), Y(t3);
- case .YZY: return matrix3_from_euler_angles_yzy(t1, t2, t3); // m1, m2, m3 = Y(t1), Z(t2), Y(t3);
- case .ZXZ: return matrix3_from_euler_angles_zxz(t1, t2, t3); // m1, m2, m3 = Z(t1), X(t2), Z(t3);
- case .ZYZ: return matrix3_from_euler_angles_zyz(t1, t2, t3); // m1, m2, m3 = Z(t1), Y(t2), Z(t3);
+ case .XYZ: return matrix3_from_euler_angles_xyz(t1, t2, t3) // m1, m2, m3 = X(t1), Y(t2), Z(t3);
+ case .XZY: return matrix3_from_euler_angles_xzy(t1, t2, t3) // m1, m2, m3 = X(t1), Z(t2), Y(t3);
+ case .YXZ: return matrix3_from_euler_angles_yxz(t1, t2, t3) // m1, m2, m3 = Y(t1), X(t2), Z(t3);
+ case .YZX: return matrix3_from_euler_angles_yzx(t1, t2, t3) // m1, m2, m3 = Y(t1), Z(t2), X(t3);
+ case .ZXY: return matrix3_from_euler_angles_zxy(t1, t2, t3) // m1, m2, m3 = Z(t1), X(t2), Y(t3);
+ case .ZYX: return matrix3_from_euler_angles_zyx(t1, t2, t3) // m1, m2, m3 = Z(t1), Y(t2), X(t3);
+ case .XYX: return matrix3_from_euler_angles_xyx(t1, t2, t3) // m1, m2, m3 = X(t1), Y(t2), X(t3);
+ case .XZX: return matrix3_from_euler_angles_xzx(t1, t2, t3) // m1, m2, m3 = X(t1), Z(t2), X(t3);
+ case .YXY: return matrix3_from_euler_angles_yxy(t1, t2, t3) // m1, m2, m3 = Y(t1), X(t2), Y(t3);
+ case .YZY: return matrix3_from_euler_angles_yzy(t1, t2, t3) // m1, m2, m3 = Y(t1), Z(t2), Y(t3);
+ case .ZXZ: return matrix3_from_euler_angles_zxz(t1, t2, t3) // m1, m2, m3 = Z(t1), X(t2), Z(t3);
+ case .ZYZ: return matrix3_from_euler_angles_zyz(t1, t2, t3) // m1, m2, m3 = Z(t1), Y(t2), Z(t3);
}
- return;
+ return
}
matrix4_from_euler_angles_f16 :: proc(t1, t2, t3: f16, order: Euler_Angle_Order) -> (m: Matrix4f16) {
switch order {
- case .XYZ: return matrix4_from_euler_angles_xyz(t1, t2, t3); // m1, m2, m3 = X(t1), Y(t2), Z(t3);
- case .XZY: return matrix4_from_euler_angles_xzy(t1, t2, t3); // m1, m2, m3 = X(t1), Z(t2), Y(t3);
- case .YXZ: return matrix4_from_euler_angles_yxz(t1, t2, t3); // m1, m2, m3 = Y(t1), X(t2), Z(t3);
- case .YZX: return matrix4_from_euler_angles_yzx(t1, t2, t3); // m1, m2, m3 = Y(t1), Z(t2), X(t3);
- case .ZXY: return matrix4_from_euler_angles_zxy(t1, t2, t3); // m1, m2, m3 = Z(t1), X(t2), Y(t3);
- case .ZYX: return matrix4_from_euler_angles_zyx(t1, t2, t3); // m1, m2, m3 = Z(t1), Y(t2), X(t3);
- case .XYX: return matrix4_from_euler_angles_xyx(t1, t2, t3); // m1, m2, m3 = X(t1), Y(t2), X(t3);
- case .XZX: return matrix4_from_euler_angles_xzx(t1, t2, t3); // m1, m2, m3 = X(t1), Z(t2), X(t3);
- case .YXY: return matrix4_from_euler_angles_yxy(t1, t2, t3); // m1, m2, m3 = Y(t1), X(t2), Y(t3);
- case .YZY: return matrix4_from_euler_angles_yzy(t1, t2, t3); // m1, m2, m3 = Y(t1), Z(t2), Y(t3);
- case .ZXZ: return matrix4_from_euler_angles_zxz(t1, t2, t3); // m1, m2, m3 = Z(t1), X(t2), Z(t3);
- case .ZYZ: return matrix4_from_euler_angles_zyz(t1, t2, t3); // m1, m2, m3 = Z(t1), Y(t2), Z(t3);
+ case .XYZ: return matrix4_from_euler_angles_xyz(t1, t2, t3) // m1, m2, m3 = X(t1), Y(t2), Z(t3);
+ case .XZY: return matrix4_from_euler_angles_xzy(t1, t2, t3) // m1, m2, m3 = X(t1), Z(t2), Y(t3);
+ case .YXZ: return matrix4_from_euler_angles_yxz(t1, t2, t3) // m1, m2, m3 = Y(t1), X(t2), Z(t3);
+ case .YZX: return matrix4_from_euler_angles_yzx(t1, t2, t3) // m1, m2, m3 = Y(t1), Z(t2), X(t3);
+ case .ZXY: return matrix4_from_euler_angles_zxy(t1, t2, t3) // m1, m2, m3 = Z(t1), X(t2), Y(t3);
+ case .ZYX: return matrix4_from_euler_angles_zyx(t1, t2, t3) // m1, m2, m3 = Z(t1), Y(t2), X(t3);
+ case .XYX: return matrix4_from_euler_angles_xyx(t1, t2, t3) // m1, m2, m3 = X(t1), Y(t2), X(t3);
+ case .XZX: return matrix4_from_euler_angles_xzx(t1, t2, t3) // m1, m2, m3 = X(t1), Z(t2), X(t3);
+ case .YXY: return matrix4_from_euler_angles_yxy(t1, t2, t3) // m1, m2, m3 = Y(t1), X(t2), Y(t3);
+ case .YZY: return matrix4_from_euler_angles_yzy(t1, t2, t3) // m1, m2, m3 = Y(t1), Z(t2), Y(t3);
+ case .ZXZ: return matrix4_from_euler_angles_zxz(t1, t2, t3) // m1, m2, m3 = Z(t1), X(t2), Z(t3);
+ case .ZYZ: return matrix4_from_euler_angles_zyz(t1, t2, t3) // m1, m2, m3 = Z(t1), Y(t2), Z(t3);
}
- return;
+ return
}
quaternion_from_euler_angles_f16 :: proc(t1, t2, t3: f16, order: Euler_Angle_Order) -> Quaternionf16 {
- X :: quaternion_from_euler_angle_x;
- Y :: quaternion_from_euler_angle_y;
- Z :: quaternion_from_euler_angle_z;
+ X :: quaternion_from_euler_angle_x
+ Y :: quaternion_from_euler_angle_y
+ Z :: quaternion_from_euler_angle_z
- q1, q2, q3: Quaternionf16;
+ q1, q2, q3: Quaternionf16
switch order {
- case .XYZ: q1, q2, q3 = X(t1), Y(t2), Z(t3);
- case .XZY: q1, q2, q3 = X(t1), Z(t2), Y(t3);
- case .YXZ: q1, q2, q3 = Y(t1), X(t2), Z(t3);
- case .YZX: q1, q2, q3 = Y(t1), Z(t2), X(t3);
- case .ZXY: q1, q2, q3 = Z(t1), X(t2), Y(t3);
- case .ZYX: q1, q2, q3 = Z(t1), Y(t2), X(t3);
- case .XYX: q1, q2, q3 = X(t1), Y(t2), X(t3);
- case .XZX: q1, q2, q3 = X(t1), Z(t2), X(t3);
- case .YXY: q1, q2, q3 = Y(t1), X(t2), Y(t3);
- case .YZY: q1, q2, q3 = Y(t1), Z(t2), Y(t3);
- case .ZXZ: q1, q2, q3 = Z(t1), X(t2), Z(t3);
- case .ZYZ: q1, q2, q3 = Z(t1), Y(t2), Z(t3);
+ case .XYZ: q1, q2, q3 = X(t1), Y(t2), Z(t3)
+ case .XZY: q1, q2, q3 = X(t1), Z(t2), Y(t3)
+ case .YXZ: q1, q2, q3 = Y(t1), X(t2), Z(t3)
+ case .YZX: q1, q2, q3 = Y(t1), Z(t2), X(t3)
+ case .ZXY: q1, q2, q3 = Z(t1), X(t2), Y(t3)
+ case .ZYX: q1, q2, q3 = Z(t1), Y(t2), X(t3)
+ case .XYX: q1, q2, q3 = X(t1), Y(t2), X(t3)
+ case .XZX: q1, q2, q3 = X(t1), Z(t2), X(t3)
+ case .YXY: q1, q2, q3 = Y(t1), X(t2), Y(t3)
+ case .YZY: q1, q2, q3 = Y(t1), Z(t2), Y(t3)
+ case .ZXZ: q1, q2, q3 = Z(t1), X(t2), Z(t3)
+ case .ZYZ: q1, q2, q3 = Z(t1), Y(t2), Z(t3)
}
- return q1 * (q2 * q3);
+ return q1 * (q2 * q3)
}
// Quaternionf16s
quaternion_from_euler_angle_x_f16 :: proc(angle_x: f16) -> (q: Quaternionf16) {
- return quaternion_angle_axis_f16(angle_x, {1, 0, 0});
+ return quaternion_angle_axis_f16(angle_x, {1, 0, 0})
}
quaternion_from_euler_angle_y_f16 :: proc(angle_y: f16) -> (q: Quaternionf16) {
- return quaternion_angle_axis_f16(angle_y, {0, 1, 0});
+ return quaternion_angle_axis_f16(angle_y, {0, 1, 0})
}
quaternion_from_euler_angle_z_f16 :: proc(angle_z: f16) -> (q: Quaternionf16) {
- return quaternion_angle_axis_f16(angle_z, {0, 0, 1});
+ return quaternion_angle_axis_f16(angle_z, {0, 0, 1})
}
quaternion_from_pitch_yaw_roll_f16 :: proc(pitch, yaw, roll: f16) -> Quaternionf16 {
- a, b, c := pitch, yaw, roll;
+ a, b, c := pitch, yaw, roll
- ca, sa := math.cos(a*0.5), math.sin(a*0.5);
- cb, sb := math.cos(b*0.5), math.sin(b*0.5);
- cc, sc := math.cos(c*0.5), math.sin(c*0.5);
+ ca, sa := math.cos(a*0.5), math.sin(a*0.5)
+ cb, sb := math.cos(b*0.5), math.sin(b*0.5)
+ cc, sc := math.cos(c*0.5), math.sin(c*0.5)
- q: Quaternionf16;
- q.x = sa*cb*cc - ca*sb*sc;
- q.y = ca*sb*cc + sa*cb*sc;
- q.z = ca*cb*sc - sa*sb*cc;
- q.w = ca*cb*cc + sa*sb*sc;
- return q;
+ q: Quaternionf16
+ q.x = sa*cb*cc - ca*sb*sc
+ q.y = ca*sb*cc + sa*cb*sc
+ q.z = ca*cb*sc - sa*sb*cc
+ q.w = ca*cb*cc + sa*sb*sc
+ return q
}
roll_from_quaternion_f16 :: proc(q: Quaternionf16) -> f16 {
- return math.atan2(2 * q.x*q.y + q.w*q.z, q.w*q.w + q.x*q.x - q.y*q.y - q.z*q.z);
+ return math.atan2(2 * q.x*q.y + q.w*q.z, q.w*q.w + q.x*q.x - q.y*q.y - q.z*q.z)
}
pitch_from_quaternion_f16 :: proc(q: Quaternionf16) -> f16 {
- y := 2 * (q.y*q.z + q.w*q.w);
- x := q.w*q.w - q.x*q.x - q.y*q.y + q.z*q.z;
+ y := 2 * (q.y*q.z + q.w*q.w)
+ x := q.w*q.w - q.x*q.x - q.y*q.y + q.z*q.z
if abs(x) <= F16_EPSILON && abs(y) <= F16_EPSILON {
- return 2 * math.atan2(q.x, q.w);
+ return 2 * math.atan2(q.x, q.w)
}
- return math.atan2(y, x);
+ return math.atan2(y, x)
}
yaw_from_quaternion_f16 :: proc(q: Quaternionf16) -> f16 {
- return math.asin(clamp(-2 * (q.x*q.z - q.w*q.y), -1, 1));
+ return math.asin(clamp(-2 * (q.x*q.z - q.w*q.y), -1, 1))
}
pitch_yaw_roll_from_quaternion_f16 :: proc(q: Quaternionf16) -> (pitch, yaw, roll: f16) {
- pitch = pitch_from_quaternion(q);
- yaw = yaw_from_quaternion(q);
- roll = roll_from_quaternion(q);
- return;
+ pitch = pitch_from_quaternion(q)
+ yaw = yaw_from_quaternion(q)
+ roll = roll_from_quaternion(q)
+ return
}
euler_angles_xyz_from_quaternion_f16 :: proc(q: Quaternionf16) -> (t1, t2, t3: f16) {
- return euler_angles_xyz_from_matrix4(matrix4_from_quaternion(q));
+ return euler_angles_xyz_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_yxz_from_quaternion_f16 :: proc(q: Quaternionf16) -> (t1, t2, t3: f16) {
- return euler_angles_yxz_from_matrix4(matrix4_from_quaternion(q));
+ return euler_angles_yxz_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_xzx_from_quaternion_f16 :: proc(q: Quaternionf16) -> (t1, t2, t3: f16) {
- return euler_angles_xzx_from_matrix4(matrix4_from_quaternion(q));
+ return euler_angles_xzx_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_xyx_from_quaternion_f16 :: proc(q: Quaternionf16) -> (t1, t2, t3: f16) {
- return euler_angles_xyx_from_matrix4(matrix4_from_quaternion(q));
+ return euler_angles_xyx_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_yxy_from_quaternion_f16 :: proc(q: Quaternionf16) -> (t1, t2, t3: f16) {
- return euler_angles_yxy_from_matrix4(matrix4_from_quaternion(q));
+ return euler_angles_yxy_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_yzy_from_quaternion_f16 :: proc(q: Quaternionf16) -> (t1, t2, t3: f16) {
- return euler_angles_yzy_from_matrix4(matrix4_from_quaternion(q));
+ return euler_angles_yzy_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_zyz_from_quaternion_f16 :: proc(q: Quaternionf16) -> (t1, t2, t3: f16) {
- return euler_angles_zyz_from_matrix4(matrix4_from_quaternion(q));
+ return euler_angles_zyz_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_zxz_from_quaternion_f16 :: proc(q: Quaternionf16) -> (t1, t2, t3: f16) {
- return euler_angles_zxz_from_matrix4(matrix4_from_quaternion(q));
+ return euler_angles_zxz_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_xzy_from_quaternion_f16 :: proc(q: Quaternionf16) -> (t1, t2, t3: f16) {
- return euler_angles_xzy_from_matrix4(matrix4_from_quaternion(q));
+ return euler_angles_xzy_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_yzx_from_quaternion_f16 :: proc(q: Quaternionf16) -> (t1, t2, t3: f16) {
- return euler_angles_yzx_from_matrix4(matrix4_from_quaternion(q));
+ return euler_angles_yzx_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_zyx_from_quaternion_f16 :: proc(q: Quaternionf16) -> (t1, t2, t3: f16) {
- return euler_angles_zyx_from_matrix4(matrix4_from_quaternion(q));
+ return euler_angles_zyx_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_zxy_from_quaternion_f16 :: proc(q: Quaternionf16) -> (t1, t2, t3: f16) {
- return euler_angles_zxy_from_matrix4(matrix4_from_quaternion(q));
+ return euler_angles_zxy_from_matrix4(matrix4_from_quaternion(q))
}
@@ -211,524 +211,524 @@ euler_angles_zxy_from_quaternion_f16 :: proc(q: Quaternionf16) -> (t1, t2, t3: f
matrix3_from_euler_angle_x_f16 :: proc(angle_x: f16) -> (m: Matrix3f16) {
- cos_x, sin_x := math.cos(angle_x), math.sin(angle_x);
- m[0][0] = 1;
- m[1][1] = +cos_x;
- m[2][1] = +sin_x;
- m[1][2] = -sin_x;
- m[2][2] = +cos_x;
- return;
+ cos_x, sin_x := math.cos(angle_x), math.sin(angle_x)
+ m[0][0] = 1
+ m[1][1] = +cos_x
+ m[2][1] = +sin_x
+ m[1][2] = -sin_x
+ m[2][2] = +cos_x
+ return
}
matrix3_from_euler_angle_y_f16 :: proc(angle_y: f16) -> (m: Matrix3f16) {
- cos_y, sin_y := math.cos(angle_y), math.sin(angle_y);
- m[0][0] = +cos_y;
- m[2][0] = -sin_y;
- m[1][1] = 1;
- m[0][2] = +sin_y;
- m[2][2] = +cos_y;
- return;
+ cos_y, sin_y := math.cos(angle_y), math.sin(angle_y)
+ m[0][0] = +cos_y
+ m[2][0] = -sin_y
+ m[1][1] = 1
+ m[0][2] = +sin_y
+ m[2][2] = +cos_y
+ return
}
matrix3_from_euler_angle_z_f16 :: proc(angle_z: f16) -> (m: Matrix3f16) {
- cos_z, sin_z := math.cos(angle_z), math.sin(angle_z);
- m[0][0] = +cos_z;
- m[1][0] = +sin_z;
- m[1][1] = +cos_z;
- m[0][1] = -sin_z;
- m[2][2] = 1;
- return;
+ cos_z, sin_z := math.cos(angle_z), math.sin(angle_z)
+ m[0][0] = +cos_z
+ m[1][0] = +sin_z
+ m[1][1] = +cos_z
+ m[0][1] = -sin_z
+ m[2][2] = 1
+ return
}
matrix3_from_derived_euler_angle_x_f16 :: proc(angle_x: f16, angular_velocity_x: f16) -> (m: Matrix3f16) {
- cos_x := math.cos(angle_x) * angular_velocity_x;
- sin_x := math.sin(angle_x) * angular_velocity_x;
- m[0][0] = 1;
- m[1][1] = +cos_x;
- m[2][1] = +sin_x;
- m[1][2] = -sin_x;
- m[2][2] = +cos_x;
- return;
+ cos_x := math.cos(angle_x) * angular_velocity_x
+ sin_x := math.sin(angle_x) * angular_velocity_x
+ m[0][0] = 1
+ m[1][1] = +cos_x
+ m[2][1] = +sin_x
+ m[1][2] = -sin_x
+ m[2][2] = +cos_x
+ return
}
matrix3_from_derived_euler_angle_y_f16 :: proc(angle_y: f16, angular_velocity_y: f16) -> (m: Matrix3f16) {
- cos_y := math.cos(angle_y) * angular_velocity_y;
- sin_y := math.sin(angle_y) * angular_velocity_y;
- m[0][0] = +cos_y;
- m[2][0] = -sin_y;
- m[1][1] = 1;
- m[0][2] = +sin_y;
- m[2][2] = +cos_y;
- return;
+ cos_y := math.cos(angle_y) * angular_velocity_y
+ sin_y := math.sin(angle_y) * angular_velocity_y
+ m[0][0] = +cos_y
+ m[2][0] = -sin_y
+ m[1][1] = 1
+ m[0][2] = +sin_y
+ m[2][2] = +cos_y
+ return
}
matrix3_from_derived_euler_angle_z_f16 :: proc(angle_z: f16, angular_velocity_z: f16) -> (m: Matrix3f16) {
- cos_z := math.cos(angle_z) * angular_velocity_z;
- sin_z := math.sin(angle_z) * angular_velocity_z;
- m[0][0] = +cos_z;
- m[1][0] = +sin_z;
- m[1][1] = +cos_z;
- m[0][1] = -sin_z;
- m[2][2] = 1;
- return;
+ cos_z := math.cos(angle_z) * angular_velocity_z
+ sin_z := math.sin(angle_z) * angular_velocity_z
+ m[0][0] = +cos_z
+ m[1][0] = +sin_z
+ m[1][1] = +cos_z
+ m[0][1] = -sin_z
+ m[2][2] = 1
+ return
}
matrix3_from_euler_angles_xy_f16 :: proc(angle_x, angle_y: f16) -> (m: Matrix3f16) {
- cos_x, sin_x := math.cos(angle_x), math.sin(angle_x);
- cos_y, sin_y := math.cos(angle_y), math.sin(angle_y);
- m[0][0] = cos_y;
- m[1][0] = -sin_x * - sin_y;
- m[2][0] = -cos_x * - sin_y;
- m[1][1] = cos_x;
- m[2][1] = sin_x;
- m[0][2] = sin_y;
- m[1][2] = -sin_x * cos_y;
- m[2][2] = cos_x * cos_y;
- return;
+ cos_x, sin_x := math.cos(angle_x), math.sin(angle_x)
+ cos_y, sin_y := math.cos(angle_y), math.sin(angle_y)
+ m[0][0] = cos_y
+ m[1][0] = -sin_x * - sin_y
+ m[2][0] = -cos_x * - sin_y
+ m[1][1] = cos_x
+ m[2][1] = sin_x
+ m[0][2] = sin_y
+ m[1][2] = -sin_x * cos_y
+ m[2][2] = cos_x * cos_y
+ return
}
matrix3_from_euler_angles_yx_f16 :: proc(angle_y, angle_x: f16) -> (m: Matrix3f16) {
- cos_x, sin_x := math.cos(angle_x), math.sin(angle_x);
- cos_y, sin_y := math.cos(angle_y), math.sin(angle_y);
- m[0][0] = cos_y;
- m[2][0] = -sin_y;
- m[0][1] = sin_y*sin_x;
- m[1][1] = cos_x;
- m[2][1] = cos_y*sin_x;
- m[0][2] = sin_y*cos_x;
- m[1][2] = -sin_x;
- m[2][2] = cos_y*cos_x;
- return;
+ cos_x, sin_x := math.cos(angle_x), math.sin(angle_x)
+ cos_y, sin_y := math.cos(angle_y), math.sin(angle_y)
+ m[0][0] = cos_y
+ m[2][0] = -sin_y
+ m[0][1] = sin_y*sin_x
+ m[1][1] = cos_x
+ m[2][1] = cos_y*sin_x
+ m[0][2] = sin_y*cos_x
+ m[1][2] = -sin_x
+ m[2][2] = cos_y*cos_x
+ return
}
matrix3_from_euler_angles_xz_f16 :: proc(angle_x, angle_z: f16) -> (m: Matrix3f16) {
- return mul(matrix3_from_euler_angle_x(angle_x), matrix3_from_euler_angle_z(angle_z));
+ return mul(matrix3_from_euler_angle_x(angle_x), matrix3_from_euler_angle_z(angle_z))
}
matrix3_from_euler_angles_zx_f16 :: proc(angle_z, angle_x: f16) -> (m: Matrix3f16) {
- return mul(matrix3_from_euler_angle_z(angle_z), matrix3_from_euler_angle_x(angle_x));
+ return mul(matrix3_from_euler_angle_z(angle_z), matrix3_from_euler_angle_x(angle_x))
}
matrix3_from_euler_angles_yz_f16 :: proc(angle_y, angle_z: f16) -> (m: Matrix3f16) {
- return mul(matrix3_from_euler_angle_y(angle_y), matrix3_from_euler_angle_z(angle_z));
+ return mul(matrix3_from_euler_angle_y(angle_y), matrix3_from_euler_angle_z(angle_z))
}
matrix3_from_euler_angles_zy_f16 :: proc(angle_z, angle_y: f16) -> (m: Matrix3f16) {
- return mul(matrix3_from_euler_angle_z(angle_z), matrix3_from_euler_angle_y(angle_y));
+ return mul(matrix3_from_euler_angle_z(angle_z), matrix3_from_euler_angle_y(angle_y))
}
matrix3_from_euler_angles_xyz_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) {
- c1 := math.cos(-t1);
- c2 := math.cos(-t2);
- c3 := math.cos(-t3);
- s1 := math.sin(-t1);
- s2 := math.sin(-t2);
- s3 := math.sin(-t3);
-
- m[0][0] = c2 * c3;
- m[0][1] =-c1 * s3 + s1 * s2 * c3;
- m[0][2] = s1 * s3 + c1 * s2 * c3;
- m[1][0] = c2 * s3;
- m[1][1] = c1 * c3 + s1 * s2 * s3;
- m[1][2] =-s1 * c3 + c1 * s2 * s3;
- m[2][0] =-s2;
- m[2][1] = s1 * c2;
- m[2][2] = c1 * c2;
- return;
+ c1 := math.cos(-t1)
+ c2 := math.cos(-t2)
+ c3 := math.cos(-t3)
+ s1 := math.sin(-t1)
+ s2 := math.sin(-t2)
+ s3 := math.sin(-t3)
+
+ m[0][0] = c2 * c3
+ m[0][1] =-c1 * s3 + s1 * s2 * c3
+ m[0][2] = s1 * s3 + c1 * s2 * c3
+ m[1][0] = c2 * s3
+ m[1][1] = c1 * c3 + s1 * s2 * s3
+ m[1][2] =-s1 * c3 + c1 * s2 * s3
+ m[2][0] =-s2
+ m[2][1] = s1 * c2
+ m[2][2] = c1 * c2
+ return
}
matrix3_from_euler_angles_yxz_f16 :: proc(yaw, pitch, roll: f16) -> (m: Matrix3f16) {
- ch := math.cos(yaw);
- sh := math.sin(yaw);
- cp := math.cos(pitch);
- sp := math.sin(pitch);
- cb := math.cos(roll);
- sb := math.sin(roll);
-
- m[0][0] = ch * cb + sh * sp * sb;
- m[0][1] = sb * cp;
- m[0][2] = -sh * cb + ch * sp * sb;
- m[1][0] = -ch * sb + sh * sp * cb;
- m[1][1] = cb * cp;
- m[1][2] = sb * sh + ch * sp * cb;
- m[2][0] = sh * cp;
- m[2][1] = -sp;
- m[2][2] = ch * cp;
- return;
+ ch := math.cos(yaw)
+ sh := math.sin(yaw)
+ cp := math.cos(pitch)
+ sp := math.sin(pitch)
+ cb := math.cos(roll)
+ sb := math.sin(roll)
+
+ m[0][0] = ch * cb + sh * sp * sb
+ m[0][1] = sb * cp
+ m[0][2] = -sh * cb + ch * sp * sb
+ m[1][0] = -ch * sb + sh * sp * cb
+ m[1][1] = cb * cp
+ m[1][2] = sb * sh + ch * sp * cb
+ m[2][0] = sh * cp
+ m[2][1] = -sp
+ m[2][2] = ch * cp
+ return
}
matrix3_from_euler_angles_xzx_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) {
- c1 := math.cos(t1);
- s1 := math.sin(t1);
- c2 := math.cos(t2);
- s2 := math.sin(t2);
- c3 := math.cos(t3);
- s3 := math.sin(t3);
-
- m[0][0] = c2;
- m[0][1] = c1 * s2;
- m[0][2] = s1 * s2;
- m[1][0] =-c3 * s2;
- m[1][1] = c1 * c2 * c3 - s1 * s3;
- m[1][2] = c1 * s3 + c2 * c3 * s1;
- m[2][0] = s2 * s3;
- m[2][1] =-c3 * s1 - c1 * c2 * s3;
- m[2][2] = c1 * c3 - c2 * s1 * s3;
- return;
+ c1 := math.cos(t1)
+ s1 := math.sin(t1)
+ c2 := math.cos(t2)
+ s2 := math.sin(t2)
+ c3 := math.cos(t3)
+ s3 := math.sin(t3)
+
+ m[0][0] = c2
+ m[0][1] = c1 * s2
+ m[0][2] = s1 * s2
+ m[1][0] =-c3 * s2
+ m[1][1] = c1 * c2 * c3 - s1 * s3
+ m[1][2] = c1 * s3 + c2 * c3 * s1
+ m[2][0] = s2 * s3
+ m[2][1] =-c3 * s1 - c1 * c2 * s3
+ m[2][2] = c1 * c3 - c2 * s1 * s3
+ return
}
matrix3_from_euler_angles_xyx_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) {
- c1 := math.cos(t1);
- s1 := math.sin(t1);
- c2 := math.cos(t2);
- s2 := math.sin(t2);
- c3 := math.cos(t3);
- s3 := math.sin(t3);
-
- m[0][0] = c2;
- m[0][1] = s1 * s2;
- m[0][2] =-c1 * s2;
- m[1][0] = s2 * s3;
- m[1][1] = c1 * c3 - c2 * s1 * s3;
- m[1][2] = c3 * s1 + c1 * c2 * s3;
- m[2][0] = c3 * s2;
- m[2][1] =-c1 * s3 - c2 * c3 * s1;
- m[2][2] = c1 * c2 * c3 - s1 * s3;
- return;
+ c1 := math.cos(t1)
+ s1 := math.sin(t1)
+ c2 := math.cos(t2)
+ s2 := math.sin(t2)
+ c3 := math.cos(t3)
+ s3 := math.sin(t3)
+
+ m[0][0] = c2
+ m[0][1] = s1 * s2
+ m[0][2] =-c1 * s2
+ m[1][0] = s2 * s3
+ m[1][1] = c1 * c3 - c2 * s1 * s3
+ m[1][2] = c3 * s1 + c1 * c2 * s3
+ m[2][0] = c3 * s2
+ m[2][1] =-c1 * s3 - c2 * c3 * s1
+ m[2][2] = c1 * c2 * c3 - s1 * s3
+ return
}
matrix3_from_euler_angles_yxy_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) {
- c1 := math.cos(t1);
- s1 := math.sin(t1);
- c2 := math.cos(t2);
- s2 := math.sin(t2);
- c3 := math.cos(t3);
- s3 := math.sin(t3);
-
- m[0][0] = c1 * c3 - c2 * s1 * s3;
- m[0][1] = s2* s3;
- m[0][2] =-c3 * s1 - c1 * c2 * s3;
- m[1][0] = s1 * s2;
- m[1][1] = c2;
- m[1][2] = c1 * s2;
- m[2][0] = c1 * s3 + c2 * c3 * s1;
- m[2][1] =-c3 * s2;
- m[2][2] = c1 * c2 * c3 - s1 * s3;
- return;
+ c1 := math.cos(t1)
+ s1 := math.sin(t1)
+ c2 := math.cos(t2)
+ s2 := math.sin(t2)
+ c3 := math.cos(t3)
+ s3 := math.sin(t3)
+
+ m[0][0] = c1 * c3 - c2 * s1 * s3
+ m[0][1] = s2* s3
+ m[0][2] =-c3 * s1 - c1 * c2 * s3
+ m[1][0] = s1 * s2
+ m[1][1] = c2
+ m[1][2] = c1 * s2
+ m[2][0] = c1 * s3 + c2 * c3 * s1
+ m[2][1] =-c3 * s2
+ m[2][2] = c1 * c2 * c3 - s1 * s3
+ return
}
matrix3_from_euler_angles_yzy_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) {
- c1 := math.cos(t1);
- s1 := math.sin(t1);
- c2 := math.cos(t2);
- s2 := math.sin(t2);
- c3 := math.cos(t3);
- s3 := math.sin(t3);
-
- m[0][0] = c1 * c2 * c3 - s1 * s3;
- m[0][1] = c3 * s2;
- m[0][2] =-c1 * s3 - c2 * c3 * s1;
- m[1][0] =-c1 * s2;
- m[1][1] = c2;
- m[1][2] = s1 * s2;
- m[2][0] = c3 * s1 + c1 * c2 * s3;
- m[2][1] = s2 * s3;
- m[2][2] = c1 * c3 - c2 * s1 * s3;
- return;
+ c1 := math.cos(t1)
+ s1 := math.sin(t1)
+ c2 := math.cos(t2)
+ s2 := math.sin(t2)
+ c3 := math.cos(t3)
+ s3 := math.sin(t3)
+
+ m[0][0] = c1 * c2 * c3 - s1 * s3
+ m[0][1] = c3 * s2
+ m[0][2] =-c1 * s3 - c2 * c3 * s1
+ m[1][0] =-c1 * s2
+ m[1][1] = c2
+ m[1][2] = s1 * s2
+ m[2][0] = c3 * s1 + c1 * c2 * s3
+ m[2][1] = s2 * s3
+ m[2][2] = c1 * c3 - c2 * s1 * s3
+ return
}
matrix3_from_euler_angles_zyz_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) {
- c1 := math.cos(t1);
- s1 := math.sin(t1);
- c2 := math.cos(t2);
- s2 := math.sin(t2);
- c3 := math.cos(t3);
- s3 := math.sin(t3);
-
- m[0][0] = c1 * c2 * c3 - s1 * s3;
- m[0][1] = c1 * s3 + c2 * c3 * s1;
- m[0][2] =-c3 * s2;
- m[1][0] =-c3 * s1 - c1 * c2 * s3;
- m[1][1] = c1 * c3 - c2 * s1 * s3;
- m[1][2] = s2 * s3;
- m[2][0] = c1 * s2;
- m[2][1] = s1 * s2;
- m[2][2] = c2;
- return;
+ c1 := math.cos(t1)
+ s1 := math.sin(t1)
+ c2 := math.cos(t2)
+ s2 := math.sin(t2)
+ c3 := math.cos(t3)
+ s3 := math.sin(t3)
+
+ m[0][0] = c1 * c2 * c3 - s1 * s3
+ m[0][1] = c1 * s3 + c2 * c3 * s1
+ m[0][2] =-c3 * s2
+ m[1][0] =-c3 * s1 - c1 * c2 * s3
+ m[1][1] = c1 * c3 - c2 * s1 * s3
+ m[1][2] = s2 * s3
+ m[2][0] = c1 * s2
+ m[2][1] = s1 * s2
+ m[2][2] = c2
+ return
}
matrix3_from_euler_angles_zxz_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) {
- c1 := math.cos(t1);
- s1 := math.sin(t1);
- c2 := math.cos(t2);
- s2 := math.sin(t2);
- c3 := math.cos(t3);
- s3 := math.sin(t3);
-
- m[0][0] = c1 * c3 - c2 * s1 * s3;
- m[0][1] = c3 * s1 + c1 * c2 * s3;
- m[0][2] = s2 *s3;
- m[1][0] =-c1 * s3 - c2 * c3 * s1;
- m[1][1] = c1 * c2 * c3 - s1 * s3;
- m[1][2] = c3 * s2;
- m[2][0] = s1 * s2;
- m[2][1] =-c1 * s2;
- m[2][2] = c2;
- return;
+ c1 := math.cos(t1)
+ s1 := math.sin(t1)
+ c2 := math.cos(t2)
+ s2 := math.sin(t2)
+ c3 := math.cos(t3)
+ s3 := math.sin(t3)
+
+ m[0][0] = c1 * c3 - c2 * s1 * s3
+ m[0][1] = c3 * s1 + c1 * c2 * s3
+ m[0][2] = s2 *s3
+ m[1][0] =-c1 * s3 - c2 * c3 * s1
+ m[1][1] = c1 * c2 * c3 - s1 * s3
+ m[1][2] = c3 * s2
+ m[2][0] = s1 * s2
+ m[2][1] =-c1 * s2
+ m[2][2] = c2
+ return
}
matrix3_from_euler_angles_xzy_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) {
- c1 := math.cos(t1);
- s1 := math.sin(t1);
- c2 := math.cos(t2);
- s2 := math.sin(t2);
- c3 := math.cos(t3);
- s3 := math.sin(t3);
-
- m[0][0] = c2 * c3;
- m[0][1] = s1 * s3 + c1 * c3 * s2;
- m[0][2] = c3 * s1 * s2 - c1 * s3;
- m[1][0] =-s2;
- m[1][1] = c1 * c2;
- m[1][2] = c2 * s1;
- m[2][0] = c2 * s3;
- m[2][1] = c1 * s2 * s3 - c3 * s1;
- m[2][2] = c1 * c3 + s1 * s2 *s3;
- return;
+ c1 := math.cos(t1)
+ s1 := math.sin(t1)
+ c2 := math.cos(t2)
+ s2 := math.sin(t2)
+ c3 := math.cos(t3)
+ s3 := math.sin(t3)
+
+ m[0][0] = c2 * c3
+ m[0][1] = s1 * s3 + c1 * c3 * s2
+ m[0][2] = c3 * s1 * s2 - c1 * s3
+ m[1][0] =-s2
+ m[1][1] = c1 * c2
+ m[1][2] = c2 * s1
+ m[2][0] = c2 * s3
+ m[2][1] = c1 * s2 * s3 - c3 * s1
+ m[2][2] = c1 * c3 + s1 * s2 *s3
+ return
}
matrix3_from_euler_angles_yzx_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) {
- c1 := math.cos(t1);
- s1 := math.sin(t1);
- c2 := math.cos(t2);
- s2 := math.sin(t2);
- c3 := math.cos(t3);
- s3 := math.sin(t3);
-
- m[0][0] = c1 * c2;
- m[0][1] = s2;
- m[0][2] =-c2 * s1;
- m[1][0] = s1 * s3 - c1 * c3 * s2;
- m[1][1] = c2 * c3;
- m[1][2] = c1 * s3 + c3 * s1 * s2;
- m[2][0] = c3 * s1 + c1 * s2 * s3;
- m[2][1] =-c2 * s3;
- m[2][2] = c1 * c3 - s1 * s2 * s3;
- return;
+ c1 := math.cos(t1)
+ s1 := math.sin(t1)
+ c2 := math.cos(t2)
+ s2 := math.sin(t2)
+ c3 := math.cos(t3)
+ s3 := math.sin(t3)
+
+ m[0][0] = c1 * c2
+ m[0][1] = s2
+ m[0][2] =-c2 * s1
+ m[1][0] = s1 * s3 - c1 * c3 * s2
+ m[1][1] = c2 * c3
+ m[1][2] = c1 * s3 + c3 * s1 * s2
+ m[2][0] = c3 * s1 + c1 * s2 * s3
+ m[2][1] =-c2 * s3
+ m[2][2] = c1 * c3 - s1 * s2 * s3
+ return
}
matrix3_from_euler_angles_zyx_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) {
- c1 := math.cos(t1);
- s1 := math.sin(t1);
- c2 := math.cos(t2);
- s2 := math.sin(t2);
- c3 := math.cos(t3);
- s3 := math.sin(t3);
-
- m[0][0] = c1 * c2;
- m[0][1] = c2 * s1;
- m[0][2] =-s2;
- m[1][0] = c1 * s2 * s3 - c3 * s1;
- m[1][1] = c1 * c3 + s1 * s2 * s3;
- m[1][2] = c2 * s3;
- m[2][0] = s1 * s3 + c1 * c3 * s2;
- m[2][1] = c3 * s1 * s2 - c1 * s3;
- m[2][2] = c2 * c3;
- return;
+ c1 := math.cos(t1)
+ s1 := math.sin(t1)
+ c2 := math.cos(t2)
+ s2 := math.sin(t2)
+ c3 := math.cos(t3)
+ s3 := math.sin(t3)
+
+ m[0][0] = c1 * c2
+ m[0][1] = c2 * s1
+ m[0][2] =-s2
+ m[1][0] = c1 * s2 * s3 - c3 * s1
+ m[1][1] = c1 * c3 + s1 * s2 * s3
+ m[1][2] = c2 * s3
+ m[2][0] = s1 * s3 + c1 * c3 * s2
+ m[2][1] = c3 * s1 * s2 - c1 * s3
+ m[2][2] = c2 * c3
+ return
}
matrix3_from_euler_angles_zxy_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) {
- c1 := math.cos(t1);
- s1 := math.sin(t1);
- c2 := math.cos(t2);
- s2 := math.sin(t2);
- c3 := math.cos(t3);
- s3 := math.sin(t3);
-
- m[0][0] = c1 * c3 - s1 * s2 * s3;
- m[0][1] = c3 * s1 + c1 * s2 * s3;
- m[0][2] =-c2 * s3;
- m[1][0] =-c2 * s1;
- m[1][1] = c1 * c2;
- m[1][2] = s2;
- m[2][0] = c1 * s3 + c3 * s1 * s2;
- m[2][1] = s1 * s3 - c1 * c3 * s2;
- m[2][2] = c2 * c3;
- return;
+ c1 := math.cos(t1)
+ s1 := math.sin(t1)
+ c2 := math.cos(t2)
+ s2 := math.sin(t2)
+ c3 := math.cos(t3)
+ s3 := math.sin(t3)
+
+ m[0][0] = c1 * c3 - s1 * s2 * s3
+ m[0][1] = c3 * s1 + c1 * s2 * s3
+ m[0][2] =-c2 * s3
+ m[1][0] =-c2 * s1
+ m[1][1] = c1 * c2
+ m[1][2] = s2
+ m[2][0] = c1 * s3 + c3 * s1 * s2
+ m[2][1] = s1 * s3 - c1 * c3 * s2
+ m[2][2] = c2 * c3
+ return
}
matrix3_from_yaw_pitch_roll_f16 :: proc(yaw, pitch, roll: f16) -> (m: Matrix3f16) {
- ch := math.cos(yaw);
- sh := math.sin(yaw);
- cp := math.cos(pitch);
- sp := math.sin(pitch);
- cb := math.cos(roll);
- sb := math.sin(roll);
-
- m[0][0] = ch * cb + sh * sp * sb;
- m[0][1] = sb * cp;
- m[0][2] = -sh * cb + ch * sp * sb;
- m[1][0] = -ch * sb + sh * sp * cb;
- m[1][1] = cb * cp;
- m[1][2] = sb * sh + ch * sp * cb;
- m[2][0] = sh * cp;
- m[2][1] = -sp;
- m[2][2] = ch * cp;
- return m;
+ ch := math.cos(yaw)
+ sh := math.sin(yaw)
+ cp := math.cos(pitch)
+ sp := math.sin(pitch)
+ cb := math.cos(roll)
+ sb := math.sin(roll)
+
+ m[0][0] = ch * cb + sh * sp * sb
+ m[0][1] = sb * cp
+ m[0][2] = -sh * cb + ch * sp * sb
+ m[1][0] = -ch * sb + sh * sp * cb
+ m[1][1] = cb * cp
+ m[1][2] = sb * sh + ch * sp * cb
+ m[2][0] = sh * cp
+ m[2][1] = -sp
+ m[2][2] = ch * cp
+ return m
}
euler_angles_xyz_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) {
- T1 := math.atan2(m[2][1], m[2][2]);
- C2 := math.sqrt(m[0][0]*m[0][0] + m[1][0]*m[1][0]);
- T2 := math.atan2(-m[2][0], C2);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(S1*m[0][2] - C1*m[0][1], C1*m[1][1] - S1*m[1][2]);
- t1 = -T1;
- t2 = -T2;
- t3 = -T3;
- return;
+ T1 := math.atan2(m[2][1], m[2][2])
+ C2 := math.sqrt(m[0][0]*m[0][0] + m[1][0]*m[1][0])
+ T2 := math.atan2(-m[2][0], C2)
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(S1*m[0][2] - C1*m[0][1], C1*m[1][1] - S1*m[1][2])
+ t1 = -T1
+ t2 = -T2
+ t3 = -T3
+ return
}
euler_angles_yxz_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) {
- T1 := math.atan2(m[2][0], m[2][2]);
- C2 := math.sqrt(m[0][1]*m[0][1] + m[1][1]*m[1][1]);
- T2 := math.atan2(-m[2][1], C2);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(S1*m[1][2] - C1*m[1][0], C1*m[0][0] - S1*m[0][2]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(m[2][0], m[2][2])
+ C2 := math.sqrt(m[0][1]*m[0][1] + m[1][1]*m[1][1])
+ T2 := math.atan2(-m[2][1], C2)
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(S1*m[1][2] - C1*m[1][0], C1*m[0][0] - S1*m[0][2])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
euler_angles_xzx_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) {
- T1 := math.atan2(m[0][2], m[0][1]);
- S2 := math.sqrt(m[1][0]*m[1][0] + m[2][0]*m[2][0]);
- T2 := math.atan2(S2, m[0][0]);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(C1*m[1][2] - S1*m[1][1], C1*m[2][2] - S1*m[2][1]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(m[0][2], m[0][1])
+ S2 := math.sqrt(m[1][0]*m[1][0] + m[2][0]*m[2][0])
+ T2 := math.atan2(S2, m[0][0])
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(C1*m[1][2] - S1*m[1][1], C1*m[2][2] - S1*m[2][1])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
euler_angles_xyx_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) {
- T1 := math.atan2(m[0][1], -m[0][2]);
- S2 := math.sqrt(m[1][0]*m[1][0] + m[2][0]*m[2][0]);
- T2 := math.atan2(S2, m[0][0]);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(-C1*m[2][1] - S1*m[2][2], C1*m[1][1] + S1*m[1][2]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(m[0][1], -m[0][2])
+ S2 := math.sqrt(m[1][0]*m[1][0] + m[2][0]*m[2][0])
+ T2 := math.atan2(S2, m[0][0])
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(-C1*m[2][1] - S1*m[2][2], C1*m[1][1] + S1*m[1][2])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
euler_angles_yxy_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) {
- T1 := math.atan2(m[1][0], m[1][2]);
- S2 := math.sqrt(m[0][1]*m[0][1] + m[2][1]*m[2][1]);
- T2 := math.atan2(S2, m[1][1]);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(C1*m[2][0] - S1*m[2][2], C1*m[0][0] - S1*m[0][2]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(m[1][0], m[1][2])
+ S2 := math.sqrt(m[0][1]*m[0][1] + m[2][1]*m[2][1])
+ T2 := math.atan2(S2, m[1][1])
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(C1*m[2][0] - S1*m[2][2], C1*m[0][0] - S1*m[0][2])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
euler_angles_yzy_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) {
- T1 := math.atan2(m[1][2], -m[1][0]);
- S2 := math.sqrt(m[0][1]*m[0][1] + m[2][1]*m[2][1]);
- T2 := math.atan2(S2, m[1][1]);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(-S1*m[0][0] - C1*m[0][2], S1*m[2][0] + C1*m[2][2]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(m[1][2], -m[1][0])
+ S2 := math.sqrt(m[0][1]*m[0][1] + m[2][1]*m[2][1])
+ T2 := math.atan2(S2, m[1][1])
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(-S1*m[0][0] - C1*m[0][2], S1*m[2][0] + C1*m[2][2])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
euler_angles_zyz_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) {
- T1 := math.atan2(m[2][1], m[2][0]);
- S2 := math.sqrt(m[0][2]*m[0][2] + m[1][2]*m[1][2]);
- T2 := math.atan2(S2, m[2][2]);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(C1*m[0][1] - S1*m[0][0], C1*m[1][1] - S1*m[1][0]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(m[2][1], m[2][0])
+ S2 := math.sqrt(m[0][2]*m[0][2] + m[1][2]*m[1][2])
+ T2 := math.atan2(S2, m[2][2])
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(C1*m[0][1] - S1*m[0][0], C1*m[1][1] - S1*m[1][0])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
euler_angles_zxz_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) {
- T1 := math.atan2(m[2][0], -m[2][1]);
- S2 := math.sqrt(m[0][2]*m[0][2] + m[1][2]*m[1][2]);
- T2 := math.atan2(S2, m[2][2]);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(-C1*m[1][0] - S1*m[1][1], C1*m[0][0] + S1*m[0][1]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(m[2][0], -m[2][1])
+ S2 := math.sqrt(m[0][2]*m[0][2] + m[1][2]*m[1][2])
+ T2 := math.atan2(S2, m[2][2])
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(-C1*m[1][0] - S1*m[1][1], C1*m[0][0] + S1*m[0][1])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
euler_angles_xzy_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) {
- T1 := math.atan2(m[1][2], m[1][1]);
- C2 := math.sqrt(m[0][0]*m[0][0] + m[2][0]*m[2][0]);
- T2 := math.atan2(-m[1][0], C2);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(S1*m[0][1] - C1*m[0][2], C1*m[2][2] - S1*m[2][1]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(m[1][2], m[1][1])
+ C2 := math.sqrt(m[0][0]*m[0][0] + m[2][0]*m[2][0])
+ T2 := math.atan2(-m[1][0], C2)
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(S1*m[0][1] - C1*m[0][2], C1*m[2][2] - S1*m[2][1])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
euler_angles_yzx_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) {
- T1 := math.atan2(-m[0][2], m[0][0]);
- C2 := math.sqrt(m[1][1]*m[1][1] + m[2][1]*m[2][1]);
- T2 := math.atan2(m[0][1], C2);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(S1*m[1][0] + C1*m[1][2], S1*m[2][0] + C1*m[2][2]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(-m[0][2], m[0][0])
+ C2 := math.sqrt(m[1][1]*m[1][1] + m[2][1]*m[2][1])
+ T2 := math.atan2(m[0][1], C2)
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(S1*m[1][0] + C1*m[1][2], S1*m[2][0] + C1*m[2][2])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
euler_angles_zyx_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) {
- T1 := math.atan2(m[0][1], m[0][0]);
- C2 := math.sqrt(m[1][2]*m[1][2] + m[2][2]*m[2][2]);
- T2 := math.atan2(-m[0][2], C2);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(S1*m[2][0] - C1*m[2][1], C1*m[1][1] - S1*m[1][0]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(m[0][1], m[0][0])
+ C2 := math.sqrt(m[1][2]*m[1][2] + m[2][2]*m[2][2])
+ T2 := math.atan2(-m[0][2], C2)
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(S1*m[2][0] - C1*m[2][1], C1*m[1][1] - S1*m[1][0])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
euler_angles_zxy_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) {
- T1 := math.atan2(-m[1][0], m[1][1]);
- C2 := math.sqrt(m[0][2]*m[0][2] + m[2][2]*m[2][2]);
- T2 := math.atan2(m[1][2], C2);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(C1*m[2][0] + S1*m[2][1], C1*m[0][0] + S1*m[0][1]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(-m[1][0], m[1][1])
+ C2 := math.sqrt(m[0][2]*m[0][2] + m[2][2]*m[2][2])
+ T2 := math.atan2(m[1][2], C2)
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(C1*m[2][0] + S1*m[2][1], C1*m[0][0] + S1*m[0][1])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
@@ -736,621 +736,621 @@ euler_angles_zxy_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) {
matrix4_from_euler_angle_x_f16 :: proc(angle_x: f16) -> (m: Matrix4f16) {
- cos_x, sin_x := math.cos(angle_x), math.sin(angle_x);
- m[0][0] = 1;
- m[1][1] = +cos_x;
- m[2][1] = +sin_x;
- m[1][2] = -sin_x;
- m[2][2] = +cos_x;
- m[3][3] = 1;
- return;
+ cos_x, sin_x := math.cos(angle_x), math.sin(angle_x)
+ m[0][0] = 1
+ m[1][1] = +cos_x
+ m[2][1] = +sin_x
+ m[1][2] = -sin_x
+ m[2][2] = +cos_x
+ m[3][3] = 1
+ return
}
matrix4_from_euler_angle_y_f16 :: proc(angle_y: f16) -> (m: Matrix4f16) {
- cos_y, sin_y := math.cos(angle_y), math.sin(angle_y);
- m[0][0] = +cos_y;
- m[2][0] = -sin_y;
- m[1][1] = 1;
- m[0][2] = +sin_y;
- m[2][2] = +cos_y;
- m[3][3] = 1;
- return;
+ cos_y, sin_y := math.cos(angle_y), math.sin(angle_y)
+ m[0][0] = +cos_y
+ m[2][0] = -sin_y
+ m[1][1] = 1
+ m[0][2] = +sin_y
+ m[2][2] = +cos_y
+ m[3][3] = 1
+ return
}
matrix4_from_euler_angle_z_f16 :: proc(angle_z: f16) -> (m: Matrix4f16) {
- cos_z, sin_z := math.cos(angle_z), math.sin(angle_z);
- m[0][0] = +cos_z;
- m[1][0] = +sin_z;
- m[1][1] = +cos_z;
- m[0][1] = -sin_z;
- m[2][2] = 1;
- m[3][3] = 1;
- return;
+ cos_z, sin_z := math.cos(angle_z), math.sin(angle_z)
+ m[0][0] = +cos_z
+ m[1][0] = +sin_z
+ m[1][1] = +cos_z
+ m[0][1] = -sin_z
+ m[2][2] = 1
+ m[3][3] = 1
+ return
}
matrix4_from_derived_euler_angle_x_f16 :: proc(angle_x: f16, angular_velocity_x: f16) -> (m: Matrix4f16) {
- cos_x := math.cos(angle_x) * angular_velocity_x;
- sin_x := math.sin(angle_x) * angular_velocity_x;
- m[0][0] = 1;
- m[1][1] = +cos_x;
- m[2][1] = +sin_x;
- m[1][2] = -sin_x;
- m[2][2] = +cos_x;
- m[3][3] = 1;
- return;
+ cos_x := math.cos(angle_x) * angular_velocity_x
+ sin_x := math.sin(angle_x) * angular_velocity_x
+ m[0][0] = 1
+ m[1][1] = +cos_x
+ m[2][1] = +sin_x
+ m[1][2] = -sin_x
+ m[2][2] = +cos_x
+ m[3][3] = 1
+ return
}
matrix4_from_derived_euler_angle_y_f16 :: proc(angle_y: f16, angular_velocity_y: f16) -> (m: Matrix4f16) {
- cos_y := math.cos(angle_y) * angular_velocity_y;
- sin_y := math.sin(angle_y) * angular_velocity_y;
- m[0][0] = +cos_y;
- m[2][0] = -sin_y;
- m[1][1] = 1;
- m[0][2] = +sin_y;
- m[2][2] = +cos_y;
- m[3][3] = 1;
- return;
+ cos_y := math.cos(angle_y) * angular_velocity_y
+ sin_y := math.sin(angle_y) * angular_velocity_y
+ m[0][0] = +cos_y
+ m[2][0] = -sin_y
+ m[1][1] = 1
+ m[0][2] = +sin_y
+ m[2][2] = +cos_y
+ m[3][3] = 1
+ return
}
matrix4_from_derived_euler_angle_z_f16 :: proc(angle_z: f16, angular_velocity_z: f16) -> (m: Matrix4f16) {
- cos_z := math.cos(angle_z) * angular_velocity_z;
- sin_z := math.sin(angle_z) * angular_velocity_z;
- m[0][0] = +cos_z;
- m[1][0] = +sin_z;
- m[1][1] = +cos_z;
- m[0][1] = -sin_z;
- m[2][2] = 1;
- m[3][3] = 1;
- return;
+ cos_z := math.cos(angle_z) * angular_velocity_z
+ sin_z := math.sin(angle_z) * angular_velocity_z
+ m[0][0] = +cos_z
+ m[1][0] = +sin_z
+ m[1][1] = +cos_z
+ m[0][1] = -sin_z
+ m[2][2] = 1
+ m[3][3] = 1
+ return
}
matrix4_from_euler_angles_xy_f16 :: proc(angle_x, angle_y: f16) -> (m: Matrix4f16) {
- cos_x, sin_x := math.cos(angle_x), math.sin(angle_x);
- cos_y, sin_y := math.cos(angle_y), math.sin(angle_y);
- m[0][0] = cos_y;
- m[1][0] = -sin_x * - sin_y;
- m[2][0] = -cos_x * - sin_y;
- m[1][1] = cos_x;
- m[2][1] = sin_x;
- m[0][2] = sin_y;
- m[1][2] = -sin_x * cos_y;
- m[2][2] = cos_x * cos_y;
- m[3][3] = 1;
- return;
+ cos_x, sin_x := math.cos(angle_x), math.sin(angle_x)
+ cos_y, sin_y := math.cos(angle_y), math.sin(angle_y)
+ m[0][0] = cos_y
+ m[1][0] = -sin_x * - sin_y
+ m[2][0] = -cos_x * - sin_y
+ m[1][1] = cos_x
+ m[2][1] = sin_x
+ m[0][2] = sin_y
+ m[1][2] = -sin_x * cos_y
+ m[2][2] = cos_x * cos_y
+ m[3][3] = 1
+ return
}
matrix4_from_euler_angles_yx_f16 :: proc(angle_y, angle_x: f16) -> (m: Matrix4f16) {
- cos_x, sin_x := math.cos(angle_x), math.sin(angle_x);
- cos_y, sin_y := math.cos(angle_y), math.sin(angle_y);
- m[0][0] = cos_y;
- m[2][0] = -sin_y;
- m[0][1] = sin_y*sin_x;
- m[1][1] = cos_x;
- m[2][1] = cos_y*sin_x;
- m[0][2] = sin_y*cos_x;
- m[1][2] = -sin_x;
- m[2][2] = cos_y*cos_x;
- m[3][3] = 1;
- return;
+ cos_x, sin_x := math.cos(angle_x), math.sin(angle_x)
+ cos_y, sin_y := math.cos(angle_y), math.sin(angle_y)
+ m[0][0] = cos_y
+ m[2][0] = -sin_y
+ m[0][1] = sin_y*sin_x
+ m[1][1] = cos_x
+ m[2][1] = cos_y*sin_x
+ m[0][2] = sin_y*cos_x
+ m[1][2] = -sin_x
+ m[2][2] = cos_y*cos_x
+ m[3][3] = 1
+ return
}
matrix4_from_euler_angles_xz_f16 :: proc(angle_x, angle_z: f16) -> (m: Matrix4f16) {
- return mul(matrix4_from_euler_angle_x(angle_x), matrix4_from_euler_angle_z(angle_z));
+ return mul(matrix4_from_euler_angle_x(angle_x), matrix4_from_euler_angle_z(angle_z))
}
matrix4_from_euler_angles_zx_f16 :: proc(angle_z, angle_x: f16) -> (m: Matrix4f16) {
- return mul(matrix4_from_euler_angle_z(angle_z), matrix4_from_euler_angle_x(angle_x));
+ return mul(matrix4_from_euler_angle_z(angle_z), matrix4_from_euler_angle_x(angle_x))
}
matrix4_from_euler_angles_yz_f16 :: proc(angle_y, angle_z: f16) -> (m: Matrix4f16) {
- return mul(matrix4_from_euler_angle_y(angle_y), matrix4_from_euler_angle_z(angle_z));
+ return mul(matrix4_from_euler_angle_y(angle_y), matrix4_from_euler_angle_z(angle_z))
}
matrix4_from_euler_angles_zy_f16 :: proc(angle_z, angle_y: f16) -> (m: Matrix4f16) {
- return mul(matrix4_from_euler_angle_z(angle_z), matrix4_from_euler_angle_y(angle_y));
+ return mul(matrix4_from_euler_angle_z(angle_z), matrix4_from_euler_angle_y(angle_y))
}
matrix4_from_euler_angles_xyz_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) {
- c1 := math.cos(-t1);
- c2 := math.cos(-t2);
- c3 := math.cos(-t3);
- s1 := math.sin(-t1);
- s2 := math.sin(-t2);
- s3 := math.sin(-t3);
-
- m[0][0] = c2 * c3;
- m[0][1] =-c1 * s3 + s1 * s2 * c3;
- m[0][2] = s1 * s3 + c1 * s2 * c3;
- m[0][3] = 0;
- m[1][0] = c2 * s3;
- m[1][1] = c1 * c3 + s1 * s2 * s3;
- m[1][2] =-s1 * c3 + c1 * s2 * s3;
- m[1][3] = 0;
- m[2][0] =-s2;
- m[2][1] = s1 * c2;
- m[2][2] = c1 * c2;
- m[2][3] = 0;
- m[3][0] = 0;
- m[3][1] = 0;
- m[3][2] = 0;
- m[3][3] = 1;
- return;
+ c1 := math.cos(-t1)
+ c2 := math.cos(-t2)
+ c3 := math.cos(-t3)
+ s1 := math.sin(-t1)
+ s2 := math.sin(-t2)
+ s3 := math.sin(-t3)
+
+ m[0][0] = c2 * c3
+ m[0][1] =-c1 * s3 + s1 * s2 * c3
+ m[0][2] = s1 * s3 + c1 * s2 * c3
+ m[0][3] = 0
+ m[1][0] = c2 * s3
+ m[1][1] = c1 * c3 + s1 * s2 * s3
+ m[1][2] =-s1 * c3 + c1 * s2 * s3
+ m[1][3] = 0
+ m[2][0] =-s2
+ m[2][1] = s1 * c2
+ m[2][2] = c1 * c2
+ m[2][3] = 0
+ m[3][0] = 0
+ m[3][1] = 0
+ m[3][2] = 0
+ m[3][3] = 1
+ return
}
matrix4_from_euler_angles_yxz_f16 :: proc(yaw, pitch, roll: f16) -> (m: Matrix4f16) {
- ch := math.cos(yaw);
- sh := math.sin(yaw);
- cp := math.cos(pitch);
- sp := math.sin(pitch);
- cb := math.cos(roll);
- sb := math.sin(roll);
-
- m[0][0] = ch * cb + sh * sp * sb;
- m[0][1] = sb * cp;
- m[0][2] = -sh * cb + ch * sp * sb;
- m[0][3] = 0;
- m[1][0] = -ch * sb + sh * sp * cb;
- m[1][1] = cb * cp;
- m[1][2] = sb * sh + ch * sp * cb;
- m[1][3] = 0;
- m[2][0] = sh * cp;
- m[2][1] = -sp;
- m[2][2] = ch * cp;
- m[2][3] = 0;
- m[3][0] = 0;
- m[3][1] = 0;
- m[3][2] = 0;
- m[3][3] = 1;
- return;
+ ch := math.cos(yaw)
+ sh := math.sin(yaw)
+ cp := math.cos(pitch)
+ sp := math.sin(pitch)
+ cb := math.cos(roll)
+ sb := math.sin(roll)
+
+ m[0][0] = ch * cb + sh * sp * sb
+ m[0][1] = sb * cp
+ m[0][2] = -sh * cb + ch * sp * sb
+ m[0][3] = 0
+ m[1][0] = -ch * sb + sh * sp * cb
+ m[1][1] = cb * cp
+ m[1][2] = sb * sh + ch * sp * cb
+ m[1][3] = 0
+ m[2][0] = sh * cp
+ m[2][1] = -sp
+ m[2][2] = ch * cp
+ m[2][3] = 0
+ m[3][0] = 0
+ m[3][1] = 0
+ m[3][2] = 0
+ m[3][3] = 1
+ return
}
matrix4_from_euler_angles_xzx_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) {
- c1 := math.cos(t1);
- s1 := math.sin(t1);
- c2 := math.cos(t2);
- s2 := math.sin(t2);
- c3 := math.cos(t3);
- s3 := math.sin(t3);
-
- m[0][0] = c2;
- m[0][1] = c1 * s2;
- m[0][2] = s1 * s2;
- m[0][3] = 0;
- m[1][0] =-c3 * s2;
- m[1][1] = c1 * c2 * c3 - s1 * s3;
- m[1][2] = c1 * s3 + c2 * c3 * s1;
- m[1][3] = 0;
- m[2][0] = s2 * s3;
- m[2][1] =-c3 * s1 - c1 * c2 * s3;
- m[2][2] = c1 * c3 - c2 * s1 * s3;
- m[2][3] = 0;
- m[3][0] = 0;
- m[3][1] = 0;
- m[3][2] = 0;
- m[3][3] = 1;
- return;
+ c1 := math.cos(t1)
+ s1 := math.sin(t1)
+ c2 := math.cos(t2)
+ s2 := math.sin(t2)
+ c3 := math.cos(t3)
+ s3 := math.sin(t3)
+
+ m[0][0] = c2
+ m[0][1] = c1 * s2
+ m[0][2] = s1 * s2
+ m[0][3] = 0
+ m[1][0] =-c3 * s2
+ m[1][1] = c1 * c2 * c3 - s1 * s3
+ m[1][2] = c1 * s3 + c2 * c3 * s1
+ m[1][3] = 0
+ m[2][0] = s2 * s3
+ m[2][1] =-c3 * s1 - c1 * c2 * s3
+ m[2][2] = c1 * c3 - c2 * s1 * s3
+ m[2][3] = 0
+ m[3][0] = 0
+ m[3][1] = 0
+ m[3][2] = 0
+ m[3][3] = 1
+ return
}
matrix4_from_euler_angles_xyx_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) {
- c1 := math.cos(t1);
- s1 := math.sin(t1);
- c2 := math.cos(t2);
- s2 := math.sin(t2);
- c3 := math.cos(t3);
- s3 := math.sin(t3);
-
- m[0][0] = c2;
- m[0][1] = s1 * s2;
- m[0][2] =-c1 * s2;
- m[0][3] = 0;
- m[1][0] = s2 * s3;
- m[1][1] = c1 * c3 - c2 * s1 * s3;
- m[1][2] = c3 * s1 + c1 * c2 * s3;
- m[1][3] = 0;
- m[2][0] = c3 * s2;
- m[2][1] =-c1 * s3 - c2 * c3 * s1;
- m[2][2] = c1 * c2 * c3 - s1 * s3;
- m[2][3] = 0;
- m[3][0] = 0;
- m[3][1] = 0;
- m[3][2] = 0;
- m[3][3] = 1;
- return;
+ c1 := math.cos(t1)
+ s1 := math.sin(t1)
+ c2 := math.cos(t2)
+ s2 := math.sin(t2)
+ c3 := math.cos(t3)
+ s3 := math.sin(t3)
+
+ m[0][0] = c2
+ m[0][1] = s1 * s2
+ m[0][2] =-c1 * s2
+ m[0][3] = 0
+ m[1][0] = s2 * s3
+ m[1][1] = c1 * c3 - c2 * s1 * s3
+ m[1][2] = c3 * s1 + c1 * c2 * s3
+ m[1][3] = 0
+ m[2][0] = c3 * s2
+ m[2][1] =-c1 * s3 - c2 * c3 * s1
+ m[2][2] = c1 * c2 * c3 - s1 * s3
+ m[2][3] = 0
+ m[3][0] = 0
+ m[3][1] = 0
+ m[3][2] = 0
+ m[3][3] = 1
+ return
}
matrix4_from_euler_angles_yxy_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) {
- c1 := math.cos(t1);
- s1 := math.sin(t1);
- c2 := math.cos(t2);
- s2 := math.sin(t2);
- c3 := math.cos(t3);
- s3 := math.sin(t3);
-
- m[0][0] = c1 * c3 - c2 * s1 * s3;
- m[0][1] = s2* s3;
- m[0][2] =-c3 * s1 - c1 * c2 * s3;
- m[0][3] = 0;
- m[1][0] = s1 * s2;
- m[1][1] = c2;
- m[1][2] = c1 * s2;
- m[1][3] = 0;
- m[2][0] = c1 * s3 + c2 * c3 * s1;
- m[2][1] =-c3 * s2;
- m[2][2] = c1 * c2 * c3 - s1 * s3;
- m[2][3] = 0;
- m[3][0] = 0;
- m[3][1] = 0;
- m[3][2] = 0;
- m[3][3] = 1;
- return;
+ c1 := math.cos(t1)
+ s1 := math.sin(t1)
+ c2 := math.cos(t2)
+ s2 := math.sin(t2)
+ c3 := math.cos(t3)
+ s3 := math.sin(t3)
+
+ m[0][0] = c1 * c3 - c2 * s1 * s3
+ m[0][1] = s2* s3
+ m[0][2] =-c3 * s1 - c1 * c2 * s3
+ m[0][3] = 0
+ m[1][0] = s1 * s2
+ m[1][1] = c2
+ m[1][2] = c1 * s2
+ m[1][3] = 0
+ m[2][0] = c1 * s3 + c2 * c3 * s1
+ m[2][1] =-c3 * s2
+ m[2][2] = c1 * c2 * c3 - s1 * s3
+ m[2][3] = 0
+ m[3][0] = 0
+ m[3][1] = 0
+ m[3][2] = 0
+ m[3][3] = 1
+ return
}
matrix4_from_euler_angles_yzy_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) {
- c1 := math.cos(t1);
- s1 := math.sin(t1);
- c2 := math.cos(t2);
- s2 := math.sin(t2);
- c3 := math.cos(t3);
- s3 := math.sin(t3);
-
- m[0][0] = c1 * c2 * c3 - s1 * s3;
- m[0][1] = c3 * s2;
- m[0][2] =-c1 * s3 - c2 * c3 * s1;
- m[0][3] = 0;
- m[1][0] =-c1 * s2;
- m[1][1] = c2;
- m[1][2] = s1 * s2;
- m[1][3] = 0;
- m[2][0] = c3 * s1 + c1 * c2 * s3;
- m[2][1] = s2 * s3;
- m[2][2] = c1 * c3 - c2 * s1 * s3;
- m[2][3] = 0;
- m[3][0] = 0;
- m[3][1] = 0;
- m[3][2] = 0;
- m[3][3] = 1;
- return;
+ c1 := math.cos(t1)
+ s1 := math.sin(t1)
+ c2 := math.cos(t2)
+ s2 := math.sin(t2)
+ c3 := math.cos(t3)
+ s3 := math.sin(t3)
+
+ m[0][0] = c1 * c2 * c3 - s1 * s3
+ m[0][1] = c3 * s2
+ m[0][2] =-c1 * s3 - c2 * c3 * s1
+ m[0][3] = 0
+ m[1][0] =-c1 * s2
+ m[1][1] = c2
+ m[1][2] = s1 * s2
+ m[1][3] = 0
+ m[2][0] = c3 * s1 + c1 * c2 * s3
+ m[2][1] = s2 * s3
+ m[2][2] = c1 * c3 - c2 * s1 * s3
+ m[2][3] = 0
+ m[3][0] = 0
+ m[3][1] = 0
+ m[3][2] = 0
+ m[3][3] = 1
+ return
}
matrix4_from_euler_angles_zyz_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) {
- c1 := math.cos(t1);
- s1 := math.sin(t1);
- c2 := math.cos(t2);
- s2 := math.sin(t2);
- c3 := math.cos(t3);
- s3 := math.sin(t3);
-
- m[0][0] = c1 * c2 * c3 - s1 * s3;
- m[0][1] = c1 * s3 + c2 * c3 * s1;
- m[0][2] =-c3 * s2;
- m[0][3] = 0;
- m[1][0] =-c3 * s1 - c1 * c2 * s3;
- m[1][1] = c1 * c3 - c2 * s1 * s3;
- m[1][2] = s2 * s3;
- m[1][3] = 0;
- m[2][0] = c1 * s2;
- m[2][1] = s1 * s2;
- m[2][2] = c2;
- m[2][3] = 0;
- m[3][0] = 0;
- m[3][1] = 0;
- m[3][2] = 0;
- m[3][3] = 1;
- return;
+ c1 := math.cos(t1)
+ s1 := math.sin(t1)
+ c2 := math.cos(t2)
+ s2 := math.sin(t2)
+ c3 := math.cos(t3)
+ s3 := math.sin(t3)
+
+ m[0][0] = c1 * c2 * c3 - s1 * s3
+ m[0][1] = c1 * s3 + c2 * c3 * s1
+ m[0][2] =-c3 * s2
+ m[0][3] = 0
+ m[1][0] =-c3 * s1 - c1 * c2 * s3
+ m[1][1] = c1 * c3 - c2 * s1 * s3
+ m[1][2] = s2 * s3
+ m[1][3] = 0
+ m[2][0] = c1 * s2
+ m[2][1] = s1 * s2
+ m[2][2] = c2
+ m[2][3] = 0
+ m[3][0] = 0
+ m[3][1] = 0
+ m[3][2] = 0
+ m[3][3] = 1
+ return
}
matrix4_from_euler_angles_zxz_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) {
- c1 := math.cos(t1);
- s1 := math.sin(t1);
- c2 := math.cos(t2);
- s2 := math.sin(t2);
- c3 := math.cos(t3);
- s3 := math.sin(t3);
-
- m[0][0] = c1 * c3 - c2 * s1 * s3;
- m[0][1] = c3 * s1 + c1 * c2 * s3;
- m[0][2] = s2 *s3;
- m[0][3] = 0;
- m[1][0] =-c1 * s3 - c2 * c3 * s1;
- m[1][1] = c1 * c2 * c3 - s1 * s3;
- m[1][2] = c3 * s2;
- m[1][3] = 0;
- m[2][0] = s1 * s2;
- m[2][1] =-c1 * s2;
- m[2][2] = c2;
- m[2][3] = 0;
- m[3][0] = 0;
- m[3][1] = 0;
- m[3][2] = 0;
- m[3][3] = 1;
- return;
+ c1 := math.cos(t1)
+ s1 := math.sin(t1)
+ c2 := math.cos(t2)
+ s2 := math.sin(t2)
+ c3 := math.cos(t3)
+ s3 := math.sin(t3)
+
+ m[0][0] = c1 * c3 - c2 * s1 * s3
+ m[0][1] = c3 * s1 + c1 * c2 * s3
+ m[0][2] = s2 *s3
+ m[0][3] = 0
+ m[1][0] =-c1 * s3 - c2 * c3 * s1
+ m[1][1] = c1 * c2 * c3 - s1 * s3
+ m[1][2] = c3 * s2
+ m[1][3] = 0
+ m[2][0] = s1 * s2
+ m[2][1] =-c1 * s2
+ m[2][2] = c2
+ m[2][3] = 0
+ m[3][0] = 0
+ m[3][1] = 0
+ m[3][2] = 0
+ m[3][3] = 1
+ return
}
matrix4_from_euler_angles_xzy_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) {
- c1 := math.cos(t1);
- s1 := math.sin(t1);
- c2 := math.cos(t2);
- s2 := math.sin(t2);
- c3 := math.cos(t3);
- s3 := math.sin(t3);
-
- m[0][0] = c2 * c3;
- m[0][1] = s1 * s3 + c1 * c3 * s2;
- m[0][2] = c3 * s1 * s2 - c1 * s3;
- m[0][3] = 0;
- m[1][0] =-s2;
- m[1][1] = c1 * c2;
- m[1][2] = c2 * s1;
- m[1][3] = 0;
- m[2][0] = c2 * s3;
- m[2][1] = c1 * s2 * s3 - c3 * s1;
- m[2][2] = c1 * c3 + s1 * s2 *s3;
- m[2][3] = 0;
- m[3][0] = 0;
- m[3][1] = 0;
- m[3][2] = 0;
- m[3][3] = 1;
- return;
+ c1 := math.cos(t1)
+ s1 := math.sin(t1)
+ c2 := math.cos(t2)
+ s2 := math.sin(t2)
+ c3 := math.cos(t3)
+ s3 := math.sin(t3)
+
+ m[0][0] = c2 * c3
+ m[0][1] = s1 * s3 + c1 * c3 * s2
+ m[0][2] = c3 * s1 * s2 - c1 * s3
+ m[0][3] = 0
+ m[1][0] =-s2
+ m[1][1] = c1 * c2
+ m[1][2] = c2 * s1
+ m[1][3] = 0
+ m[2][0] = c2 * s3
+ m[2][1] = c1 * s2 * s3 - c3 * s1
+ m[2][2] = c1 * c3 + s1 * s2 *s3
+ m[2][3] = 0
+ m[3][0] = 0
+ m[3][1] = 0
+ m[3][2] = 0
+ m[3][3] = 1
+ return
}
matrix4_from_euler_angles_yzx_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) {
- c1 := math.cos(t1);
- s1 := math.sin(t1);
- c2 := math.cos(t2);
- s2 := math.sin(t2);
- c3 := math.cos(t3);
- s3 := math.sin(t3);
-
- m[0][0] = c1 * c2;
- m[0][1] = s2;
- m[0][2] =-c2 * s1;
- m[0][3] = 0;
- m[1][0] = s1 * s3 - c1 * c3 * s2;
- m[1][1] = c2 * c3;
- m[1][2] = c1 * s3 + c3 * s1 * s2;
- m[1][3] = 0;
- m[2][0] = c3 * s1 + c1 * s2 * s3;
- m[2][1] =-c2 * s3;
- m[2][2] = c1 * c3 - s1 * s2 * s3;
- m[2][3] = 0;
- m[3][0] = 0;
- m[3][1] = 0;
- m[3][2] = 0;
- m[3][3] = 1;
- return;
+ c1 := math.cos(t1)
+ s1 := math.sin(t1)
+ c2 := math.cos(t2)
+ s2 := math.sin(t2)
+ c3 := math.cos(t3)
+ s3 := math.sin(t3)
+
+ m[0][0] = c1 * c2
+ m[0][1] = s2
+ m[0][2] =-c2 * s1
+ m[0][3] = 0
+ m[1][0] = s1 * s3 - c1 * c3 * s2
+ m[1][1] = c2 * c3
+ m[1][2] = c1 * s3 + c3 * s1 * s2
+ m[1][3] = 0
+ m[2][0] = c3 * s1 + c1 * s2 * s3
+ m[2][1] =-c2 * s3
+ m[2][2] = c1 * c3 - s1 * s2 * s3
+ m[2][3] = 0
+ m[3][0] = 0
+ m[3][1] = 0
+ m[3][2] = 0
+ m[3][3] = 1
+ return
}
matrix4_from_euler_angles_zyx_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) {
- c1 := math.cos(t1);
- s1 := math.sin(t1);
- c2 := math.cos(t2);
- s2 := math.sin(t2);
- c3 := math.cos(t3);
- s3 := math.sin(t3);
-
- m[0][0] = c1 * c2;
- m[0][1] = c2 * s1;
- m[0][2] =-s2;
- m[0][3] = 0;
- m[1][0] = c1 * s2 * s3 - c3 * s1;
- m[1][1] = c1 * c3 + s1 * s2 * s3;
- m[1][2] = c2 * s3;
- m[1][3] = 0;
- m[2][0] = s1 * s3 + c1 * c3 * s2;
- m[2][1] = c3 * s1 * s2 - c1 * s3;
- m[2][2] = c2 * c3;
- m[2][3] = 0;
- m[3][0] = 0;
- m[3][1] = 0;
- m[3][2] = 0;
- m[3][3] = 1;
- return;
+ c1 := math.cos(t1)
+ s1 := math.sin(t1)
+ c2 := math.cos(t2)
+ s2 := math.sin(t2)
+ c3 := math.cos(t3)
+ s3 := math.sin(t3)
+
+ m[0][0] = c1 * c2
+ m[0][1] = c2 * s1
+ m[0][2] =-s2
+ m[0][3] = 0
+ m[1][0] = c1 * s2 * s3 - c3 * s1
+ m[1][1] = c1 * c3 + s1 * s2 * s3
+ m[1][2] = c2 * s3
+ m[1][3] = 0
+ m[2][0] = s1 * s3 + c1 * c3 * s2
+ m[2][1] = c3 * s1 * s2 - c1 * s3
+ m[2][2] = c2 * c3
+ m[2][3] = 0
+ m[3][0] = 0
+ m[3][1] = 0
+ m[3][2] = 0
+ m[3][3] = 1
+ return
}
matrix4_from_euler_angles_zxy_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) {
- c1 := math.cos(t1);
- s1 := math.sin(t1);
- c2 := math.cos(t2);
- s2 := math.sin(t2);
- c3 := math.cos(t3);
- s3 := math.sin(t3);
-
- m[0][0] = c1 * c3 - s1 * s2 * s3;
- m[0][1] = c3 * s1 + c1 * s2 * s3;
- m[0][2] =-c2 * s3;
- m[0][3] = 0;
- m[1][0] =-c2 * s1;
- m[1][1] = c1 * c2;
- m[1][2] = s2;
- m[1][3] = 0;
- m[2][0] = c1 * s3 + c3 * s1 * s2;
- m[2][1] = s1 * s3 - c1 * c3 * s2;
- m[2][2] = c2 * c3;
- m[2][3] = 0;
- m[3][0] = 0;
- m[3][1] = 0;
- m[3][2] = 0;
- m[3][3] = 1;
- return;
+ c1 := math.cos(t1)
+ s1 := math.sin(t1)
+ c2 := math.cos(t2)
+ s2 := math.sin(t2)
+ c3 := math.cos(t3)
+ s3 := math.sin(t3)
+
+ m[0][0] = c1 * c3 - s1 * s2 * s3
+ m[0][1] = c3 * s1 + c1 * s2 * s3
+ m[0][2] =-c2 * s3
+ m[0][3] = 0
+ m[1][0] =-c2 * s1
+ m[1][1] = c1 * c2
+ m[1][2] = s2
+ m[1][3] = 0
+ m[2][0] = c1 * s3 + c3 * s1 * s2
+ m[2][1] = s1 * s3 - c1 * c3 * s2
+ m[2][2] = c2 * c3
+ m[2][3] = 0
+ m[3][0] = 0
+ m[3][1] = 0
+ m[3][2] = 0
+ m[3][3] = 1
+ return
}
matrix4_from_yaw_pitch_roll_f16 :: proc(yaw, pitch, roll: f16) -> (m: Matrix4f16) {
- ch := math.cos(yaw);
- sh := math.sin(yaw);
- cp := math.cos(pitch);
- sp := math.sin(pitch);
- cb := math.cos(roll);
- sb := math.sin(roll);
-
- m[0][0] = ch * cb + sh * sp * sb;
- m[0][1] = sb * cp;
- m[0][2] = -sh * cb + ch * sp * sb;
- m[0][3] = 0;
- m[1][0] = -ch * sb + sh * sp * cb;
- m[1][1] = cb * cp;
- m[1][2] = sb * sh + ch * sp * cb;
- m[1][3] = 0;
- m[2][0] = sh * cp;
- m[2][1] = -sp;
- m[2][2] = ch * cp;
- m[2][3] = 0;
- m[3][0] = 0;
- m[3][1] = 0;
- m[3][2] = 0;
- m[3][3] = 1;
- return m;
+ ch := math.cos(yaw)
+ sh := math.sin(yaw)
+ cp := math.cos(pitch)
+ sp := math.sin(pitch)
+ cb := math.cos(roll)
+ sb := math.sin(roll)
+
+ m[0][0] = ch * cb + sh * sp * sb
+ m[0][1] = sb * cp
+ m[0][2] = -sh * cb + ch * sp * sb
+ m[0][3] = 0
+ m[1][0] = -ch * sb + sh * sp * cb
+ m[1][1] = cb * cp
+ m[1][2] = sb * sh + ch * sp * cb
+ m[1][3] = 0
+ m[2][0] = sh * cp
+ m[2][1] = -sp
+ m[2][2] = ch * cp
+ m[2][3] = 0
+ m[3][0] = 0
+ m[3][1] = 0
+ m[3][2] = 0
+ m[3][3] = 1
+ return m
}
euler_angles_xyz_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) {
- T1 := math.atan2(m[2][1], m[2][2]);
- C2 := math.sqrt(m[0][0]*m[0][0] + m[1][0]*m[1][0]);
- T2 := math.atan2(-m[2][0], C2);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(S1*m[0][2] - C1*m[0][1], C1*m[1][1] - S1*m[1][2]);
- t1 = -T1;
- t2 = -T2;
- t3 = -T3;
- return;
+ T1 := math.atan2(m[2][1], m[2][2])
+ C2 := math.sqrt(m[0][0]*m[0][0] + m[1][0]*m[1][0])
+ T2 := math.atan2(-m[2][0], C2)
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(S1*m[0][2] - C1*m[0][1], C1*m[1][1] - S1*m[1][2])
+ t1 = -T1
+ t2 = -T2
+ t3 = -T3
+ return
}
euler_angles_yxz_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) {
- T1 := math.atan2(m[2][0], m[2][2]);
- C2 := math.sqrt(m[0][1]*m[0][1] + m[1][1]*m[1][1]);
- T2 := math.atan2(-m[2][1], C2);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(S1*m[1][2] - C1*m[1][0], C1*m[0][0] - S1*m[0][2]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(m[2][0], m[2][2])
+ C2 := math.sqrt(m[0][1]*m[0][1] + m[1][1]*m[1][1])
+ T2 := math.atan2(-m[2][1], C2)
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(S1*m[1][2] - C1*m[1][0], C1*m[0][0] - S1*m[0][2])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
euler_angles_xzx_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) {
- T1 := math.atan2(m[0][2], m[0][1]);
- S2 := math.sqrt(m[1][0]*m[1][0] + m[2][0]*m[2][0]);
- T2 := math.atan2(S2, m[0][0]);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(C1*m[1][2] - S1*m[1][1], C1*m[2][2] - S1*m[2][1]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(m[0][2], m[0][1])
+ S2 := math.sqrt(m[1][0]*m[1][0] + m[2][0]*m[2][0])
+ T2 := math.atan2(S2, m[0][0])
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(C1*m[1][2] - S1*m[1][1], C1*m[2][2] - S1*m[2][1])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
euler_angles_xyx_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) {
- T1 := math.atan2(m[0][1], -m[0][2]);
- S2 := math.sqrt(m[1][0]*m[1][0] + m[2][0]*m[2][0]);
- T2 := math.atan2(S2, m[0][0]);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(-C1*m[2][1] - S1*m[2][2], C1*m[1][1] + S1*m[1][2]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(m[0][1], -m[0][2])
+ S2 := math.sqrt(m[1][0]*m[1][0] + m[2][0]*m[2][0])
+ T2 := math.atan2(S2, m[0][0])
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(-C1*m[2][1] - S1*m[2][2], C1*m[1][1] + S1*m[1][2])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
euler_angles_yxy_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) {
- T1 := math.atan2(m[1][0], m[1][2]);
- S2 := math.sqrt(m[0][1]*m[0][1] + m[2][1]*m[2][1]);
- T2 := math.atan2(S2, m[1][1]);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(C1*m[2][0] - S1*m[2][2], C1*m[0][0] - S1*m[0][2]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(m[1][0], m[1][2])
+ S2 := math.sqrt(m[0][1]*m[0][1] + m[2][1]*m[2][1])
+ T2 := math.atan2(S2, m[1][1])
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(C1*m[2][0] - S1*m[2][2], C1*m[0][0] - S1*m[0][2])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
euler_angles_yzy_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) {
- T1 := math.atan2(m[1][2], -m[1][0]);
- S2 := math.sqrt(m[0][1]*m[0][1] + m[2][1]*m[2][1]);
- T2 := math.atan2(S2, m[1][1]);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(-S1*m[0][0] - C1*m[0][2], S1*m[2][0] + C1*m[2][2]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(m[1][2], -m[1][0])
+ S2 := math.sqrt(m[0][1]*m[0][1] + m[2][1]*m[2][1])
+ T2 := math.atan2(S2, m[1][1])
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(-S1*m[0][0] - C1*m[0][2], S1*m[2][0] + C1*m[2][2])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
euler_angles_zyz_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) {
- T1 := math.atan2(m[2][1], m[2][0]);
- S2 := math.sqrt(m[0][2]*m[0][2] + m[1][2]*m[1][2]);
- T2 := math.atan2(S2, m[2][2]);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(C1*m[0][1] - S1*m[0][0], C1*m[1][1] - S1*m[1][0]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(m[2][1], m[2][0])
+ S2 := math.sqrt(m[0][2]*m[0][2] + m[1][2]*m[1][2])
+ T2 := math.atan2(S2, m[2][2])
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(C1*m[0][1] - S1*m[0][0], C1*m[1][1] - S1*m[1][0])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
euler_angles_zxz_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) {
- T1 := math.atan2(m[2][0], -m[2][1]);
- S2 := math.sqrt(m[0][2]*m[0][2] + m[1][2]*m[1][2]);
- T2 := math.atan2(S2, m[2][2]);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(-C1*m[1][0] - S1*m[1][1], C1*m[0][0] + S1*m[0][1]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(m[2][0], -m[2][1])
+ S2 := math.sqrt(m[0][2]*m[0][2] + m[1][2]*m[1][2])
+ T2 := math.atan2(S2, m[2][2])
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(-C1*m[1][0] - S1*m[1][1], C1*m[0][0] + S1*m[0][1])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
euler_angles_xzy_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) {
- T1 := math.atan2(m[1][2], m[1][1]);
- C2 := math.sqrt(m[0][0]*m[0][0] + m[2][0]*m[2][0]);
- T2 := math.atan2(-m[1][0], C2);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(S1*m[0][1] - C1*m[0][2], C1*m[2][2] - S1*m[2][1]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(m[1][2], m[1][1])
+ C2 := math.sqrt(m[0][0]*m[0][0] + m[2][0]*m[2][0])
+ T2 := math.atan2(-m[1][0], C2)
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(S1*m[0][1] - C1*m[0][2], C1*m[2][2] - S1*m[2][1])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
euler_angles_yzx_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) {
- T1 := math.atan2(-m[0][2], m[0][0]);
- C2 := math.sqrt(m[1][1]*m[1][1] + m[2][1]*m[2][1]);
- T2 := math.atan2(m[0][1], C2);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(S1*m[1][0] + C1*m[1][2], S1*m[2][0] + C1*m[2][2]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(-m[0][2], m[0][0])
+ C2 := math.sqrt(m[1][1]*m[1][1] + m[2][1]*m[2][1])
+ T2 := math.atan2(m[0][1], C2)
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(S1*m[1][0] + C1*m[1][2], S1*m[2][0] + C1*m[2][2])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
euler_angles_zyx_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) {
- T1 := math.atan2(m[0][1], m[0][0]);
- C2 := math.sqrt(m[1][2]*m[1][2] + m[2][2]*m[2][2]);
- T2 := math.atan2(-m[0][2], C2);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(S1*m[2][0] - C1*m[2][1], C1*m[1][1] - S1*m[1][0]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(m[0][1], m[0][0])
+ C2 := math.sqrt(m[1][2]*m[1][2] + m[2][2]*m[2][2])
+ T2 := math.atan2(-m[0][2], C2)
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(S1*m[2][0] - C1*m[2][1], C1*m[1][1] - S1*m[1][0])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
euler_angles_zxy_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) {
- T1 := math.atan2(-m[1][0], m[1][1]);
- C2 := math.sqrt(m[0][2]*m[0][2] + m[2][2]*m[2][2]);
- T2 := math.atan2(m[1][2], C2);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(C1*m[2][0] + S1*m[2][1], C1*m[0][0] + S1*m[0][1]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(-m[1][0], m[1][1])
+ C2 := math.sqrt(m[0][2]*m[0][2] + m[2][2]*m[2][2])
+ T2 := math.atan2(m[1][2], C2)
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(C1*m[2][0] + S1*m[2][1], C1*m[0][0] + S1*m[0][1])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
diff --git a/core/math/linalg/specific_euler_angles_f32.odin b/core/math/linalg/specific_euler_angles_f32.odin
index e7069bd81..6ae1b0fa0 100644
--- a/core/math/linalg/specific_euler_angles_f32.odin
+++ b/core/math/linalg/specific_euler_angles_f32.odin
@@ -4,206 +4,206 @@ import "core:math"
euler_angles_from_matrix3_f32 :: proc(m: Matrix3f32, order: Euler_Angle_Order) -> (t1, t2, t3: f32) {
switch order {
- case .XYZ: t1, t2, t3 = euler_angles_xyz_from_matrix3(m);
- case .XZY: t1, t2, t3 = euler_angles_xzy_from_matrix3(m);
- case .YXZ: t1, t2, t3 = euler_angles_yxz_from_matrix3(m);
- case .YZX: t1, t2, t3 = euler_angles_yzx_from_matrix3(m);
- case .ZXY: t1, t2, t3 = euler_angles_zxy_from_matrix3(m);
- case .ZYX: t1, t2, t3 = euler_angles_zyx_from_matrix3(m);
- case .XYX: t1, t2, t3 = euler_angles_xyx_from_matrix3(m);
- case .XZX: t1, t2, t3 = euler_angles_xzx_from_matrix3(m);
- case .YXY: t1, t2, t3 = euler_angles_yxy_from_matrix3(m);
- case .YZY: t1, t2, t3 = euler_angles_yzy_from_matrix3(m);
- case .ZXZ: t1, t2, t3 = euler_angles_zxz_from_matrix3(m);
- case .ZYZ: t1, t2, t3 = euler_angles_zyz_from_matrix3(m);
+ case .XYZ: t1, t2, t3 = euler_angles_xyz_from_matrix3(m)
+ case .XZY: t1, t2, t3 = euler_angles_xzy_from_matrix3(m)
+ case .YXZ: t1, t2, t3 = euler_angles_yxz_from_matrix3(m)
+ case .YZX: t1, t2, t3 = euler_angles_yzx_from_matrix3(m)
+ case .ZXY: t1, t2, t3 = euler_angles_zxy_from_matrix3(m)
+ case .ZYX: t1, t2, t3 = euler_angles_zyx_from_matrix3(m)
+ case .XYX: t1, t2, t3 = euler_angles_xyx_from_matrix3(m)
+ case .XZX: t1, t2, t3 = euler_angles_xzx_from_matrix3(m)
+ case .YXY: t1, t2, t3 = euler_angles_yxy_from_matrix3(m)
+ case .YZY: t1, t2, t3 = euler_angles_yzy_from_matrix3(m)
+ case .ZXZ: t1, t2, t3 = euler_angles_zxz_from_matrix3(m)
+ case .ZYZ: t1, t2, t3 = euler_angles_zyz_from_matrix3(m)
}
- return;
+ return
}
euler_angles_from_matrix4_f32 :: proc(m: Matrix4f32, order: Euler_Angle_Order) -> (t1, t2, t3: f32) {
switch order {
- case .XYZ: t1, t2, t3 = euler_angles_xyz_from_matrix4(m);
- case .XZY: t1, t2, t3 = euler_angles_xzy_from_matrix4(m);
- case .YXZ: t1, t2, t3 = euler_angles_yxz_from_matrix4(m);
- case .YZX: t1, t2, t3 = euler_angles_yzx_from_matrix4(m);
- case .ZXY: t1, t2, t3 = euler_angles_zxy_from_matrix4(m);
- case .ZYX: t1, t2, t3 = euler_angles_zyx_from_matrix4(m);
- case .XYX: t1, t2, t3 = euler_angles_xyx_from_matrix4(m);
- case .XZX: t1, t2, t3 = euler_angles_xzx_from_matrix4(m);
- case .YXY: t1, t2, t3 = euler_angles_yxy_from_matrix4(m);
- case .YZY: t1, t2, t3 = euler_angles_yzy_from_matrix4(m);
- case .ZXZ: t1, t2, t3 = euler_angles_zxz_from_matrix4(m);
- case .ZYZ: t1, t2, t3 = euler_angles_zyz_from_matrix4(m);
+ case .XYZ: t1, t2, t3 = euler_angles_xyz_from_matrix4(m)
+ case .XZY: t1, t2, t3 = euler_angles_xzy_from_matrix4(m)
+ case .YXZ: t1, t2, t3 = euler_angles_yxz_from_matrix4(m)
+ case .YZX: t1, t2, t3 = euler_angles_yzx_from_matrix4(m)
+ case .ZXY: t1, t2, t3 = euler_angles_zxy_from_matrix4(m)
+ case .ZYX: t1, t2, t3 = euler_angles_zyx_from_matrix4(m)
+ case .XYX: t1, t2, t3 = euler_angles_xyx_from_matrix4(m)
+ case .XZX: t1, t2, t3 = euler_angles_xzx_from_matrix4(m)
+ case .YXY: t1, t2, t3 = euler_angles_yxy_from_matrix4(m)
+ case .YZY: t1, t2, t3 = euler_angles_yzy_from_matrix4(m)
+ case .ZXZ: t1, t2, t3 = euler_angles_zxz_from_matrix4(m)
+ case .ZYZ: t1, t2, t3 = euler_angles_zyz_from_matrix4(m)
}
- return;
+ return
}
euler_angles_from_quaternion_f32 :: proc(m: Quaternionf32, order: Euler_Angle_Order) -> (t1, t2, t3: f32) {
switch order {
- case .XYZ: t1, t2, t3 = euler_angles_xyz_from_quaternion(m);
- case .XZY: t1, t2, t3 = euler_angles_xzy_from_quaternion(m);
- case .YXZ: t1, t2, t3 = euler_angles_yxz_from_quaternion(m);
- case .YZX: t1, t2, t3 = euler_angles_yzx_from_quaternion(m);
- case .ZXY: t1, t2, t3 = euler_angles_zxy_from_quaternion(m);
- case .ZYX: t1, t2, t3 = euler_angles_zyx_from_quaternion(m);
- case .XYX: t1, t2, t3 = euler_angles_xyx_from_quaternion(m);
- case .XZX: t1, t2, t3 = euler_angles_xzx_from_quaternion(m);
- case .YXY: t1, t2, t3 = euler_angles_yxy_from_quaternion(m);
- case .YZY: t1, t2, t3 = euler_angles_yzy_from_quaternion(m);
- case .ZXZ: t1, t2, t3 = euler_angles_zxz_from_quaternion(m);
- case .ZYZ: t1, t2, t3 = euler_angles_zyz_from_quaternion(m);
+ case .XYZ: t1, t2, t3 = euler_angles_xyz_from_quaternion(m)
+ case .XZY: t1, t2, t3 = euler_angles_xzy_from_quaternion(m)
+ case .YXZ: t1, t2, t3 = euler_angles_yxz_from_quaternion(m)
+ case .YZX: t1, t2, t3 = euler_angles_yzx_from_quaternion(m)
+ case .ZXY: t1, t2, t3 = euler_angles_zxy_from_quaternion(m)
+ case .ZYX: t1, t2, t3 = euler_angles_zyx_from_quaternion(m)
+ case .XYX: t1, t2, t3 = euler_angles_xyx_from_quaternion(m)
+ case .XZX: t1, t2, t3 = euler_angles_xzx_from_quaternion(m)
+ case .YXY: t1, t2, t3 = euler_angles_yxy_from_quaternion(m)
+ case .YZY: t1, t2, t3 = euler_angles_yzy_from_quaternion(m)
+ case .ZXZ: t1, t2, t3 = euler_angles_zxz_from_quaternion(m)
+ case .ZYZ: t1, t2, t3 = euler_angles_zyz_from_quaternion(m)
}
- return;
+ return
}
matrix3_from_euler_angles_f32 :: proc(t1, t2, t3: f32, order: Euler_Angle_Order) -> (m: Matrix3f32) {
switch order {
- case .XYZ: return matrix3_from_euler_angles_xyz(t1, t2, t3); // m1, m2, m3 = X(t1), Y(t2), Z(t3);
- case .XZY: return matrix3_from_euler_angles_xzy(t1, t2, t3); // m1, m2, m3 = X(t1), Z(t2), Y(t3);
- case .YXZ: return matrix3_from_euler_angles_yxz(t1, t2, t3); // m1, m2, m3 = Y(t1), X(t2), Z(t3);
- case .YZX: return matrix3_from_euler_angles_yzx(t1, t2, t3); // m1, m2, m3 = Y(t1), Z(t2), X(t3);
- case .ZXY: return matrix3_from_euler_angles_zxy(t1, t2, t3); // m1, m2, m3 = Z(t1), X(t2), Y(t3);
- case .ZYX: return matrix3_from_euler_angles_zyx(t1, t2, t3); // m1, m2, m3 = Z(t1), Y(t2), X(t3);
- case .XYX: return matrix3_from_euler_angles_xyx(t1, t2, t3); // m1, m2, m3 = X(t1), Y(t2), X(t3);
- case .XZX: return matrix3_from_euler_angles_xzx(t1, t2, t3); // m1, m2, m3 = X(t1), Z(t2), X(t3);
- case .YXY: return matrix3_from_euler_angles_yxy(t1, t2, t3); // m1, m2, m3 = Y(t1), X(t2), Y(t3);
- case .YZY: return matrix3_from_euler_angles_yzy(t1, t2, t3); // m1, m2, m3 = Y(t1), Z(t2), Y(t3);
- case .ZXZ: return matrix3_from_euler_angles_zxz(t1, t2, t3); // m1, m2, m3 = Z(t1), X(t2), Z(t3);
- case .ZYZ: return matrix3_from_euler_angles_zyz(t1, t2, t3); // m1, m2, m3 = Z(t1), Y(t2), Z(t3);
+ case .XYZ: return matrix3_from_euler_angles_xyz(t1, t2, t3) // m1, m2, m3 = X(t1), Y(t2), Z(t3);
+ case .XZY: return matrix3_from_euler_angles_xzy(t1, t2, t3) // m1, m2, m3 = X(t1), Z(t2), Y(t3);
+ case .YXZ: return matrix3_from_euler_angles_yxz(t1, t2, t3) // m1, m2, m3 = Y(t1), X(t2), Z(t3);
+ case .YZX: return matrix3_from_euler_angles_yzx(t1, t2, t3) // m1, m2, m3 = Y(t1), Z(t2), X(t3);
+ case .ZXY: return matrix3_from_euler_angles_zxy(t1, t2, t3) // m1, m2, m3 = Z(t1), X(t2), Y(t3);
+ case .ZYX: return matrix3_from_euler_angles_zyx(t1, t2, t3) // m1, m2, m3 = Z(t1), Y(t2), X(t3);
+ case .XYX: return matrix3_from_euler_angles_xyx(t1, t2, t3) // m1, m2, m3 = X(t1), Y(t2), X(t3);
+ case .XZX: return matrix3_from_euler_angles_xzx(t1, t2, t3) // m1, m2, m3 = X(t1), Z(t2), X(t3);
+ case .YXY: return matrix3_from_euler_angles_yxy(t1, t2, t3) // m1, m2, m3 = Y(t1), X(t2), Y(t3);
+ case .YZY: return matrix3_from_euler_angles_yzy(t1, t2, t3) // m1, m2, m3 = Y(t1), Z(t2), Y(t3);
+ case .ZXZ: return matrix3_from_euler_angles_zxz(t1, t2, t3) // m1, m2, m3 = Z(t1), X(t2), Z(t3);
+ case .ZYZ: return matrix3_from_euler_angles_zyz(t1, t2, t3) // m1, m2, m3 = Z(t1), Y(t2), Z(t3);
}
- return;
+ return
}
matrix4_from_euler_angles_f32 :: proc(t1, t2, t3: f32, order: Euler_Angle_Order) -> (m: Matrix4f32) {
switch order {
- case .XYZ: return matrix4_from_euler_angles_xyz(t1, t2, t3); // m1, m2, m3 = X(t1), Y(t2), Z(t3);
- case .XZY: return matrix4_from_euler_angles_xzy(t1, t2, t3); // m1, m2, m3 = X(t1), Z(t2), Y(t3);
- case .YXZ: return matrix4_from_euler_angles_yxz(t1, t2, t3); // m1, m2, m3 = Y(t1), X(t2), Z(t3);
- case .YZX: return matrix4_from_euler_angles_yzx(t1, t2, t3); // m1, m2, m3 = Y(t1), Z(t2), X(t3);
- case .ZXY: return matrix4_from_euler_angles_zxy(t1, t2, t3); // m1, m2, m3 = Z(t1), X(t2), Y(t3);
- case .ZYX: return matrix4_from_euler_angles_zyx(t1, t2, t3); // m1, m2, m3 = Z(t1), Y(t2), X(t3);
- case .XYX: return matrix4_from_euler_angles_xyx(t1, t2, t3); // m1, m2, m3 = X(t1), Y(t2), X(t3);
- case .XZX: return matrix4_from_euler_angles_xzx(t1, t2, t3); // m1, m2, m3 = X(t1), Z(t2), X(t3);
- case .YXY: return matrix4_from_euler_angles_yxy(t1, t2, t3); // m1, m2, m3 = Y(t1), X(t2), Y(t3);
- case .YZY: return matrix4_from_euler_angles_yzy(t1, t2, t3); // m1, m2, m3 = Y(t1), Z(t2), Y(t3);
- case .ZXZ: return matrix4_from_euler_angles_zxz(t1, t2, t3); // m1, m2, m3 = Z(t1), X(t2), Z(t3);
- case .ZYZ: return matrix4_from_euler_angles_zyz(t1, t2, t3); // m1, m2, m3 = Z(t1), Y(t2), Z(t3);
+ case .XYZ: return matrix4_from_euler_angles_xyz(t1, t2, t3) // m1, m2, m3 = X(t1), Y(t2), Z(t3);
+ case .XZY: return matrix4_from_euler_angles_xzy(t1, t2, t3) // m1, m2, m3 = X(t1), Z(t2), Y(t3);
+ case .YXZ: return matrix4_from_euler_angles_yxz(t1, t2, t3) // m1, m2, m3 = Y(t1), X(t2), Z(t3);
+ case .YZX: return matrix4_from_euler_angles_yzx(t1, t2, t3) // m1, m2, m3 = Y(t1), Z(t2), X(t3);
+ case .ZXY: return matrix4_from_euler_angles_zxy(t1, t2, t3) // m1, m2, m3 = Z(t1), X(t2), Y(t3);
+ case .ZYX: return matrix4_from_euler_angles_zyx(t1, t2, t3) // m1, m2, m3 = Z(t1), Y(t2), X(t3);
+ case .XYX: return matrix4_from_euler_angles_xyx(t1, t2, t3) // m1, m2, m3 = X(t1), Y(t2), X(t3);
+ case .XZX: return matrix4_from_euler_angles_xzx(t1, t2, t3) // m1, m2, m3 = X(t1), Z(t2), X(t3);
+ case .YXY: return matrix4_from_euler_angles_yxy(t1, t2, t3) // m1, m2, m3 = Y(t1), X(t2), Y(t3);
+ case .YZY: return matrix4_from_euler_angles_yzy(t1, t2, t3) // m1, m2, m3 = Y(t1), Z(t2), Y(t3);
+ case .ZXZ: return matrix4_from_euler_angles_zxz(t1, t2, t3) // m1, m2, m3 = Z(t1), X(t2), Z(t3);
+ case .ZYZ: return matrix4_from_euler_angles_zyz(t1, t2, t3) // m1, m2, m3 = Z(t1), Y(t2), Z(t3);
}
- return;
+ return
}
quaternion_from_euler_angles_f32 :: proc(t1, t2, t3: f32, order: Euler_Angle_Order) -> Quaternionf32 {
- X :: quaternion_from_euler_angle_x;
- Y :: quaternion_from_euler_angle_y;
- Z :: quaternion_from_euler_angle_z;
+ X :: quaternion_from_euler_angle_x
+ Y :: quaternion_from_euler_angle_y
+ Z :: quaternion_from_euler_angle_z
- q1, q2, q3: Quaternionf32;
+ q1, q2, q3: Quaternionf32
switch order {
- case .XYZ: q1, q2, q3 = X(t1), Y(t2), Z(t3);
- case .XZY: q1, q2, q3 = X(t1), Z(t2), Y(t3);
- case .YXZ: q1, q2, q3 = Y(t1), X(t2), Z(t3);
- case .YZX: q1, q2, q3 = Y(t1), Z(t2), X(t3);
- case .ZXY: q1, q2, q3 = Z(t1), X(t2), Y(t3);
- case .ZYX: q1, q2, q3 = Z(t1), Y(t2), X(t3);
- case .XYX: q1, q2, q3 = X(t1), Y(t2), X(t3);
- case .XZX: q1, q2, q3 = X(t1), Z(t2), X(t3);
- case .YXY: q1, q2, q3 = Y(t1), X(t2), Y(t3);
- case .YZY: q1, q2, q3 = Y(t1), Z(t2), Y(t3);
- case .ZXZ: q1, q2, q3 = Z(t1), X(t2), Z(t3);
- case .ZYZ: q1, q2, q3 = Z(t1), Y(t2), Z(t3);
+ case .XYZ: q1, q2, q3 = X(t1), Y(t2), Z(t3)
+ case .XZY: q1, q2, q3 = X(t1), Z(t2), Y(t3)
+ case .YXZ: q1, q2, q3 = Y(t1), X(t2), Z(t3)
+ case .YZX: q1, q2, q3 = Y(t1), Z(t2), X(t3)
+ case .ZXY: q1, q2, q3 = Z(t1), X(t2), Y(t3)
+ case .ZYX: q1, q2, q3 = Z(t1), Y(t2), X(t3)
+ case .XYX: q1, q2, q3 = X(t1), Y(t2), X(t3)
+ case .XZX: q1, q2, q3 = X(t1), Z(t2), X(t3)
+ case .YXY: q1, q2, q3 = Y(t1), X(t2), Y(t3)
+ case .YZY: q1, q2, q3 = Y(t1), Z(t2), Y(t3)
+ case .ZXZ: q1, q2, q3 = Z(t1), X(t2), Z(t3)
+ case .ZYZ: q1, q2, q3 = Z(t1), Y(t2), Z(t3)
}
- return q1 * (q2 * q3);
+ return q1 * (q2 * q3)
}
// Quaternionf32s
quaternion_from_euler_angle_x_f32 :: proc(angle_x: f32) -> (q: Quaternionf32) {
- return quaternion_angle_axis_f32(angle_x, {1, 0, 0});
+ return quaternion_angle_axis_f32(angle_x, {1, 0, 0})
}
quaternion_from_euler_angle_y_f32 :: proc(angle_y: f32) -> (q: Quaternionf32) {
- return quaternion_angle_axis_f32(angle_y, {0, 1, 0});
+ return quaternion_angle_axis_f32(angle_y, {0, 1, 0})
}
quaternion_from_euler_angle_z_f32 :: proc(angle_z: f32) -> (q: Quaternionf32) {
- return quaternion_angle_axis_f32(angle_z, {0, 0, 1});
+ return quaternion_angle_axis_f32(angle_z, {0, 0, 1})
}
quaternion_from_pitch_yaw_roll_f32 :: proc(pitch, yaw, roll: f32) -> Quaternionf32 {
- a, b, c := pitch, yaw, roll;
+ a, b, c := pitch, yaw, roll
- ca, sa := math.cos(a*0.5), math.sin(a*0.5);
- cb, sb := math.cos(b*0.5), math.sin(b*0.5);
- cc, sc := math.cos(c*0.5), math.sin(c*0.5);
+ ca, sa := math.cos(a*0.5), math.sin(a*0.5)
+ cb, sb := math.cos(b*0.5), math.sin(b*0.5)
+ cc, sc := math.cos(c*0.5), math.sin(c*0.5)
- q: Quaternionf32;
- q.x = sa*cb*cc - ca*sb*sc;
- q.y = ca*sb*cc + sa*cb*sc;
- q.z = ca*cb*sc - sa*sb*cc;
- q.w = ca*cb*cc + sa*sb*sc;
- return q;
+ q: Quaternionf32
+ q.x = sa*cb*cc - ca*sb*sc
+ q.y = ca*sb*cc + sa*cb*sc
+ q.z = ca*cb*sc - sa*sb*cc
+ q.w = ca*cb*cc + sa*sb*sc
+ return q
}
roll_from_quaternion_f32 :: proc(q: Quaternionf32) -> f32 {
- return math.atan2(2 * q.x*q.y + q.w*q.z, q.w*q.w + q.x*q.x - q.y*q.y - q.z*q.z);
+ return math.atan2(2 * q.x*q.y + q.w*q.z, q.w*q.w + q.x*q.x - q.y*q.y - q.z*q.z)
}
pitch_from_quaternion_f32 :: proc(q: Quaternionf32) -> f32 {
- y := 2 * (q.y*q.z + q.w*q.w);
- x := q.w*q.w - q.x*q.x - q.y*q.y + q.z*q.z;
+ y := 2 * (q.y*q.z + q.w*q.w)
+ x := q.w*q.w - q.x*q.x - q.y*q.y + q.z*q.z
if abs(x) <= F32_EPSILON && abs(y) <= F32_EPSILON {
- return 2 * math.atan2(q.x, q.w);
+ return 2 * math.atan2(q.x, q.w)
}
- return math.atan2(y, x);
+ return math.atan2(y, x)
}
yaw_from_quaternion_f32 :: proc(q: Quaternionf32) -> f32 {
- return math.asin(clamp(-2 * (q.x*q.z - q.w*q.y), -1, 1));
+ return math.asin(clamp(-2 * (q.x*q.z - q.w*q.y), -1, 1))
}
pitch_yaw_roll_from_quaternion_f32 :: proc(q: Quaternionf32) -> (pitch, yaw, roll: f32) {
- pitch = pitch_from_quaternion(q);
- yaw = yaw_from_quaternion(q);
- roll = roll_from_quaternion(q);
- return;
+ pitch = pitch_from_quaternion(q)
+ yaw = yaw_from_quaternion(q)
+ roll = roll_from_quaternion(q)
+ return
}
euler_angles_xyz_from_quaternion_f32 :: proc(q: Quaternionf32) -> (t1, t2, t3: f32) {
- return euler_angles_xyz_from_matrix4(matrix4_from_quaternion(q));
+ return euler_angles_xyz_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_yxz_from_quaternion_f32 :: proc(q: Quaternionf32) -> (t1, t2, t3: f32) {
- return euler_angles_yxz_from_matrix4(matrix4_from_quaternion(q));
+ return euler_angles_yxz_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_xzx_from_quaternion_f32 :: proc(q: Quaternionf32) -> (t1, t2, t3: f32) {
- return euler_angles_xzx_from_matrix4(matrix4_from_quaternion(q));
+ return euler_angles_xzx_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_xyx_from_quaternion_f32 :: proc(q: Quaternionf32) -> (t1, t2, t3: f32) {
- return euler_angles_xyx_from_matrix4(matrix4_from_quaternion(q));
+ return euler_angles_xyx_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_yxy_from_quaternion_f32 :: proc(q: Quaternionf32) -> (t1, t2, t3: f32) {
- return euler_angles_yxy_from_matrix4(matrix4_from_quaternion(q));
+ return euler_angles_yxy_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_yzy_from_quaternion_f32 :: proc(q: Quaternionf32) -> (t1, t2, t3: f32) {
- return euler_angles_yzy_from_matrix4(matrix4_from_quaternion(q));
+ return euler_angles_yzy_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_zyz_from_quaternion_f32 :: proc(q: Quaternionf32) -> (t1, t2, t3: f32) {
- return euler_angles_zyz_from_matrix4(matrix4_from_quaternion(q));
+ return euler_angles_zyz_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_zxz_from_quaternion_f32 :: proc(q: Quaternionf32) -> (t1, t2, t3: f32) {
- return euler_angles_zxz_from_matrix4(matrix4_from_quaternion(q));
+ return euler_angles_zxz_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_xzy_from_quaternion_f32 :: proc(q: Quaternionf32) -> (t1, t2, t3: f32) {
- return euler_angles_xzy_from_matrix4(matrix4_from_quaternion(q));
+ return euler_angles_xzy_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_yzx_from_quaternion_f32 :: proc(q: Quaternionf32) -> (t1, t2, t3: f32) {
- return euler_angles_yzx_from_matrix4(matrix4_from_quaternion(q));
+ return euler_angles_yzx_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_zyx_from_quaternion_f32 :: proc(q: Quaternionf32) -> (t1, t2, t3: f32) {
- return euler_angles_zyx_from_matrix4(matrix4_from_quaternion(q));
+ return euler_angles_zyx_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_zxy_from_quaternion_f32 :: proc(q: Quaternionf32) -> (t1, t2, t3: f32) {
- return euler_angles_zxy_from_matrix4(matrix4_from_quaternion(q));
+ return euler_angles_zxy_from_matrix4(matrix4_from_quaternion(q))
}
@@ -211,524 +211,524 @@ euler_angles_zxy_from_quaternion_f32 :: proc(q: Quaternionf32) -> (t1, t2, t3: f
matrix3_from_euler_angle_x_f32 :: proc(angle_x: f32) -> (m: Matrix3f32) {
- cos_x, sin_x := math.cos(angle_x), math.sin(angle_x);
- m[0][0] = 1;
- m[1][1] = +cos_x;
- m[2][1] = +sin_x;
- m[1][2] = -sin_x;
- m[2][2] = +cos_x;
- return;
+ cos_x, sin_x := math.cos(angle_x), math.sin(angle_x)
+ m[0][0] = 1
+ m[1][1] = +cos_x
+ m[2][1] = +sin_x
+ m[1][2] = -sin_x
+ m[2][2] = +cos_x
+ return
}
matrix3_from_euler_angle_y_f32 :: proc(angle_y: f32) -> (m: Matrix3f32) {
- cos_y, sin_y := math.cos(angle_y), math.sin(angle_y);
- m[0][0] = +cos_y;
- m[2][0] = -sin_y;
- m[1][1] = 1;
- m[0][2] = +sin_y;
- m[2][2] = +cos_y;
- return;
+ cos_y, sin_y := math.cos(angle_y), math.sin(angle_y)
+ m[0][0] = +cos_y
+ m[2][0] = -sin_y
+ m[1][1] = 1
+ m[0][2] = +sin_y
+ m[2][2] = +cos_y
+ return
}
matrix3_from_euler_angle_z_f32 :: proc(angle_z: f32) -> (m: Matrix3f32) {
- cos_z, sin_z := math.cos(angle_z), math.sin(angle_z);
- m[0][0] = +cos_z;
- m[1][0] = +sin_z;
- m[1][1] = +cos_z;
- m[0][1] = -sin_z;
- m[2][2] = 1;
- return;
+ cos_z, sin_z := math.cos(angle_z), math.sin(angle_z)
+ m[0][0] = +cos_z
+ m[1][0] = +sin_z
+ m[1][1] = +cos_z
+ m[0][1] = -sin_z
+ m[2][2] = 1
+ return
}
matrix3_from_derived_euler_angle_x_f32 :: proc(angle_x: f32, angular_velocity_x: f32) -> (m: Matrix3f32) {
- cos_x := math.cos(angle_x) * angular_velocity_x;
- sin_x := math.sin(angle_x) * angular_velocity_x;
- m[0][0] = 1;
- m[1][1] = +cos_x;
- m[2][1] = +sin_x;
- m[1][2] = -sin_x;
- m[2][2] = +cos_x;
- return;
+ cos_x := math.cos(angle_x) * angular_velocity_x
+ sin_x := math.sin(angle_x) * angular_velocity_x
+ m[0][0] = 1
+ m[1][1] = +cos_x
+ m[2][1] = +sin_x
+ m[1][2] = -sin_x
+ m[2][2] = +cos_x
+ return
}
matrix3_from_derived_euler_angle_y_f32 :: proc(angle_y: f32, angular_velocity_y: f32) -> (m: Matrix3f32) {
- cos_y := math.cos(angle_y) * angular_velocity_y;
- sin_y := math.sin(angle_y) * angular_velocity_y;
- m[0][0] = +cos_y;
- m[2][0] = -sin_y;
- m[1][1] = 1;
- m[0][2] = +sin_y;
- m[2][2] = +cos_y;
- return;
+ cos_y := math.cos(angle_y) * angular_velocity_y
+ sin_y := math.sin(angle_y) * angular_velocity_y
+ m[0][0] = +cos_y
+ m[2][0] = -sin_y
+ m[1][1] = 1
+ m[0][2] = +sin_y
+ m[2][2] = +cos_y
+ return
}
matrix3_from_derived_euler_angle_z_f32 :: proc(angle_z: f32, angular_velocity_z: f32) -> (m: Matrix3f32) {
- cos_z := math.cos(angle_z) * angular_velocity_z;
- sin_z := math.sin(angle_z) * angular_velocity_z;
- m[0][0] = +cos_z;
- m[1][0] = +sin_z;
- m[1][1] = +cos_z;
- m[0][1] = -sin_z;
- m[2][2] = 1;
- return;
+ cos_z := math.cos(angle_z) * angular_velocity_z
+ sin_z := math.sin(angle_z) * angular_velocity_z
+ m[0][0] = +cos_z
+ m[1][0] = +sin_z
+ m[1][1] = +cos_z
+ m[0][1] = -sin_z
+ m[2][2] = 1
+ return
}
matrix3_from_euler_angles_xy_f32 :: proc(angle_x, angle_y: f32) -> (m: Matrix3f32) {
- cos_x, sin_x := math.cos(angle_x), math.sin(angle_x);
- cos_y, sin_y := math.cos(angle_y), math.sin(angle_y);
- m[0][0] = cos_y;
- m[1][0] = -sin_x * - sin_y;
- m[2][0] = -cos_x * - sin_y;
- m[1][1] = cos_x;
- m[2][1] = sin_x;
- m[0][2] = sin_y;
- m[1][2] = -sin_x * cos_y;
- m[2][2] = cos_x * cos_y;
- return;
+ cos_x, sin_x := math.cos(angle_x), math.sin(angle_x)
+ cos_y, sin_y := math.cos(angle_y), math.sin(angle_y)
+ m[0][0] = cos_y
+ m[1][0] = -sin_x * - sin_y
+ m[2][0] = -cos_x * - sin_y
+ m[1][1] = cos_x
+ m[2][1] = sin_x
+ m[0][2] = sin_y
+ m[1][2] = -sin_x * cos_y
+ m[2][2] = cos_x * cos_y
+ return
}
matrix3_from_euler_angles_yx_f32 :: proc(angle_y, angle_x: f32) -> (m: Matrix3f32) {
- cos_x, sin_x := math.cos(angle_x), math.sin(angle_x);
- cos_y, sin_y := math.cos(angle_y), math.sin(angle_y);
- m[0][0] = cos_y;
- m[2][0] = -sin_y;
- m[0][1] = sin_y*sin_x;
- m[1][1] = cos_x;
- m[2][1] = cos_y*sin_x;
- m[0][2] = sin_y*cos_x;
- m[1][2] = -sin_x;
- m[2][2] = cos_y*cos_x;
- return;
+ cos_x, sin_x := math.cos(angle_x), math.sin(angle_x)
+ cos_y, sin_y := math.cos(angle_y), math.sin(angle_y)
+ m[0][0] = cos_y
+ m[2][0] = -sin_y
+ m[0][1] = sin_y*sin_x
+ m[1][1] = cos_x
+ m[2][1] = cos_y*sin_x
+ m[0][2] = sin_y*cos_x
+ m[1][2] = -sin_x
+ m[2][2] = cos_y*cos_x
+ return
}
matrix3_from_euler_angles_xz_f32 :: proc(angle_x, angle_z: f32) -> (m: Matrix3f32) {
- return mul(matrix3_from_euler_angle_x(angle_x), matrix3_from_euler_angle_z(angle_z));
+ return mul(matrix3_from_euler_angle_x(angle_x), matrix3_from_euler_angle_z(angle_z))
}
matrix3_from_euler_angles_zx_f32 :: proc(angle_z, angle_x: f32) -> (m: Matrix3f32) {
- return mul(matrix3_from_euler_angle_z(angle_z), matrix3_from_euler_angle_x(angle_x));
+ return mul(matrix3_from_euler_angle_z(angle_z), matrix3_from_euler_angle_x(angle_x))
}
matrix3_from_euler_angles_yz_f32 :: proc(angle_y, angle_z: f32) -> (m: Matrix3f32) {
- return mul(matrix3_from_euler_angle_y(angle_y), matrix3_from_euler_angle_z(angle_z));
+ return mul(matrix3_from_euler_angle_y(angle_y), matrix3_from_euler_angle_z(angle_z))
}
matrix3_from_euler_angles_zy_f32 :: proc(angle_z, angle_y: f32) -> (m: Matrix3f32) {
- return mul(matrix3_from_euler_angle_z(angle_z), matrix3_from_euler_angle_y(angle_y));
+ return mul(matrix3_from_euler_angle_z(angle_z), matrix3_from_euler_angle_y(angle_y))
}
matrix3_from_euler_angles_xyz_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) {
- c1 := math.cos(-t1);
- c2 := math.cos(-t2);
- c3 := math.cos(-t3);
- s1 := math.sin(-t1);
- s2 := math.sin(-t2);
- s3 := math.sin(-t3);
-
- m[0][0] = c2 * c3;
- m[0][1] =-c1 * s3 + s1 * s2 * c3;
- m[0][2] = s1 * s3 + c1 * s2 * c3;
- m[1][0] = c2 * s3;
- m[1][1] = c1 * c3 + s1 * s2 * s3;
- m[1][2] =-s1 * c3 + c1 * s2 * s3;
- m[2][0] =-s2;
- m[2][1] = s1 * c2;
- m[2][2] = c1 * c2;
- return;
+ c1 := math.cos(-t1)
+ c2 := math.cos(-t2)
+ c3 := math.cos(-t3)
+ s1 := math.sin(-t1)
+ s2 := math.sin(-t2)
+ s3 := math.sin(-t3)
+
+ m[0][0] = c2 * c3
+ m[0][1] =-c1 * s3 + s1 * s2 * c3
+ m[0][2] = s1 * s3 + c1 * s2 * c3
+ m[1][0] = c2 * s3
+ m[1][1] = c1 * c3 + s1 * s2 * s3
+ m[1][2] =-s1 * c3 + c1 * s2 * s3
+ m[2][0] =-s2
+ m[2][1] = s1 * c2
+ m[2][2] = c1 * c2
+ return
}
matrix3_from_euler_angles_yxz_f32 :: proc(yaw, pitch, roll: f32) -> (m: Matrix3f32) {
- ch := math.cos(yaw);
- sh := math.sin(yaw);
- cp := math.cos(pitch);
- sp := math.sin(pitch);
- cb := math.cos(roll);
- sb := math.sin(roll);
-
- m[0][0] = ch * cb + sh * sp * sb;
- m[0][1] = sb * cp;
- m[0][2] = -sh * cb + ch * sp * sb;
- m[1][0] = -ch * sb + sh * sp * cb;
- m[1][1] = cb * cp;
- m[1][2] = sb * sh + ch * sp * cb;
- m[2][0] = sh * cp;
- m[2][1] = -sp;
- m[2][2] = ch * cp;
- return;
+ ch := math.cos(yaw)
+ sh := math.sin(yaw)
+ cp := math.cos(pitch)
+ sp := math.sin(pitch)
+ cb := math.cos(roll)
+ sb := math.sin(roll)
+
+ m[0][0] = ch * cb + sh * sp * sb
+ m[0][1] = sb * cp
+ m[0][2] = -sh * cb + ch * sp * sb
+ m[1][0] = -ch * sb + sh * sp * cb
+ m[1][1] = cb * cp
+ m[1][2] = sb * sh + ch * sp * cb
+ m[2][0] = sh * cp
+ m[2][1] = -sp
+ m[2][2] = ch * cp
+ return
}
matrix3_from_euler_angles_xzx_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) {
- c1 := math.cos(t1);
- s1 := math.sin(t1);
- c2 := math.cos(t2);
- s2 := math.sin(t2);
- c3 := math.cos(t3);
- s3 := math.sin(t3);
-
- m[0][0] = c2;
- m[0][1] = c1 * s2;
- m[0][2] = s1 * s2;
- m[1][0] =-c3 * s2;
- m[1][1] = c1 * c2 * c3 - s1 * s3;
- m[1][2] = c1 * s3 + c2 * c3 * s1;
- m[2][0] = s2 * s3;
- m[2][1] =-c3 * s1 - c1 * c2 * s3;
- m[2][2] = c1 * c3 - c2 * s1 * s3;
- return;
+ c1 := math.cos(t1)
+ s1 := math.sin(t1)
+ c2 := math.cos(t2)
+ s2 := math.sin(t2)
+ c3 := math.cos(t3)
+ s3 := math.sin(t3)
+
+ m[0][0] = c2
+ m[0][1] = c1 * s2
+ m[0][2] = s1 * s2
+ m[1][0] =-c3 * s2
+ m[1][1] = c1 * c2 * c3 - s1 * s3
+ m[1][2] = c1 * s3 + c2 * c3 * s1
+ m[2][0] = s2 * s3
+ m[2][1] =-c3 * s1 - c1 * c2 * s3
+ m[2][2] = c1 * c3 - c2 * s1 * s3
+ return
}
matrix3_from_euler_angles_xyx_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) {
- c1 := math.cos(t1);
- s1 := math.sin(t1);
- c2 := math.cos(t2);
- s2 := math.sin(t2);
- c3 := math.cos(t3);
- s3 := math.sin(t3);
-
- m[0][0] = c2;
- m[0][1] = s1 * s2;
- m[0][2] =-c1 * s2;
- m[1][0] = s2 * s3;
- m[1][1] = c1 * c3 - c2 * s1 * s3;
- m[1][2] = c3 * s1 + c1 * c2 * s3;
- m[2][0] = c3 * s2;
- m[2][1] =-c1 * s3 - c2 * c3 * s1;
- m[2][2] = c1 * c2 * c3 - s1 * s3;
- return;
+ c1 := math.cos(t1)
+ s1 := math.sin(t1)
+ c2 := math.cos(t2)
+ s2 := math.sin(t2)
+ c3 := math.cos(t3)
+ s3 := math.sin(t3)
+
+ m[0][0] = c2
+ m[0][1] = s1 * s2
+ m[0][2] =-c1 * s2
+ m[1][0] = s2 * s3
+ m[1][1] = c1 * c3 - c2 * s1 * s3
+ m[1][2] = c3 * s1 + c1 * c2 * s3
+ m[2][0] = c3 * s2
+ m[2][1] =-c1 * s3 - c2 * c3 * s1
+ m[2][2] = c1 * c2 * c3 - s1 * s3
+ return
}
matrix3_from_euler_angles_yxy_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) {
- c1 := math.cos(t1);
- s1 := math.sin(t1);
- c2 := math.cos(t2);
- s2 := math.sin(t2);
- c3 := math.cos(t3);
- s3 := math.sin(t3);
-
- m[0][0] = c1 * c3 - c2 * s1 * s3;
- m[0][1] = s2* s3;
- m[0][2] =-c3 * s1 - c1 * c2 * s3;
- m[1][0] = s1 * s2;
- m[1][1] = c2;
- m[1][2] = c1 * s2;
- m[2][0] = c1 * s3 + c2 * c3 * s1;
- m[2][1] =-c3 * s2;
- m[2][2] = c1 * c2 * c3 - s1 * s3;
- return;
+ c1 := math.cos(t1)
+ s1 := math.sin(t1)
+ c2 := math.cos(t2)
+ s2 := math.sin(t2)
+ c3 := math.cos(t3)
+ s3 := math.sin(t3)
+
+ m[0][0] = c1 * c3 - c2 * s1 * s3
+ m[0][1] = s2* s3
+ m[0][2] =-c3 * s1 - c1 * c2 * s3
+ m[1][0] = s1 * s2
+ m[1][1] = c2
+ m[1][2] = c1 * s2
+ m[2][0] = c1 * s3 + c2 * c3 * s1
+ m[2][1] =-c3 * s2
+ m[2][2] = c1 * c2 * c3 - s1 * s3
+ return
}
matrix3_from_euler_angles_yzy_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) {
- c1 := math.cos(t1);
- s1 := math.sin(t1);
- c2 := math.cos(t2);
- s2 := math.sin(t2);
- c3 := math.cos(t3);
- s3 := math.sin(t3);
-
- m[0][0] = c1 * c2 * c3 - s1 * s3;
- m[0][1] = c3 * s2;
- m[0][2] =-c1 * s3 - c2 * c3 * s1;
- m[1][0] =-c1 * s2;
- m[1][1] = c2;
- m[1][2] = s1 * s2;
- m[2][0] = c3 * s1 + c1 * c2 * s3;
- m[2][1] = s2 * s3;
- m[2][2] = c1 * c3 - c2 * s1 * s3;
- return;
+ c1 := math.cos(t1)
+ s1 := math.sin(t1)
+ c2 := math.cos(t2)
+ s2 := math.sin(t2)
+ c3 := math.cos(t3)
+ s3 := math.sin(t3)
+
+ m[0][0] = c1 * c2 * c3 - s1 * s3
+ m[0][1] = c3 * s2
+ m[0][2] =-c1 * s3 - c2 * c3 * s1
+ m[1][0] =-c1 * s2
+ m[1][1] = c2
+ m[1][2] = s1 * s2
+ m[2][0] = c3 * s1 + c1 * c2 * s3
+ m[2][1] = s2 * s3
+ m[2][2] = c1 * c3 - c2 * s1 * s3
+ return
}
matrix3_from_euler_angles_zyz_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) {
- c1 := math.cos(t1);
- s1 := math.sin(t1);
- c2 := math.cos(t2);
- s2 := math.sin(t2);
- c3 := math.cos(t3);
- s3 := math.sin(t3);
-
- m[0][0] = c1 * c2 * c3 - s1 * s3;
- m[0][1] = c1 * s3 + c2 * c3 * s1;
- m[0][2] =-c3 * s2;
- m[1][0] =-c3 * s1 - c1 * c2 * s3;
- m[1][1] = c1 * c3 - c2 * s1 * s3;
- m[1][2] = s2 * s3;
- m[2][0] = c1 * s2;
- m[2][1] = s1 * s2;
- m[2][2] = c2;
- return;
+ c1 := math.cos(t1)
+ s1 := math.sin(t1)
+ c2 := math.cos(t2)
+ s2 := math.sin(t2)
+ c3 := math.cos(t3)
+ s3 := math.sin(t3)
+
+ m[0][0] = c1 * c2 * c3 - s1 * s3
+ m[0][1] = c1 * s3 + c2 * c3 * s1
+ m[0][2] =-c3 * s2
+ m[1][0] =-c3 * s1 - c1 * c2 * s3
+ m[1][1] = c1 * c3 - c2 * s1 * s3
+ m[1][2] = s2 * s3
+ m[2][0] = c1 * s2
+ m[2][1] = s1 * s2
+ m[2][2] = c2
+ return
}
matrix3_from_euler_angles_zxz_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) {
- c1 := math.cos(t1);
- s1 := math.sin(t1);
- c2 := math.cos(t2);
- s2 := math.sin(t2);
- c3 := math.cos(t3);
- s3 := math.sin(t3);
-
- m[0][0] = c1 * c3 - c2 * s1 * s3;
- m[0][1] = c3 * s1 + c1 * c2 * s3;
- m[0][2] = s2 *s3;
- m[1][0] =-c1 * s3 - c2 * c3 * s1;
- m[1][1] = c1 * c2 * c3 - s1 * s3;
- m[1][2] = c3 * s2;
- m[2][0] = s1 * s2;
- m[2][1] =-c1 * s2;
- m[2][2] = c2;
- return;
+ c1 := math.cos(t1)
+ s1 := math.sin(t1)
+ c2 := math.cos(t2)
+ s2 := math.sin(t2)
+ c3 := math.cos(t3)
+ s3 := math.sin(t3)
+
+ m[0][0] = c1 * c3 - c2 * s1 * s3
+ m[0][1] = c3 * s1 + c1 * c2 * s3
+ m[0][2] = s2 *s3
+ m[1][0] =-c1 * s3 - c2 * c3 * s1
+ m[1][1] = c1 * c2 * c3 - s1 * s3
+ m[1][2] = c3 * s2
+ m[2][0] = s1 * s2
+ m[2][1] =-c1 * s2
+ m[2][2] = c2
+ return
}
matrix3_from_euler_angles_xzy_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) {
- c1 := math.cos(t1);
- s1 := math.sin(t1);
- c2 := math.cos(t2);
- s2 := math.sin(t2);
- c3 := math.cos(t3);
- s3 := math.sin(t3);
-
- m[0][0] = c2 * c3;
- m[0][1] = s1 * s3 + c1 * c3 * s2;
- m[0][2] = c3 * s1 * s2 - c1 * s3;
- m[1][0] =-s2;
- m[1][1] = c1 * c2;
- m[1][2] = c2 * s1;
- m[2][0] = c2 * s3;
- m[2][1] = c1 * s2 * s3 - c3 * s1;
- m[2][2] = c1 * c3 + s1 * s2 *s3;
- return;
+ c1 := math.cos(t1)
+ s1 := math.sin(t1)
+ c2 := math.cos(t2)
+ s2 := math.sin(t2)
+ c3 := math.cos(t3)
+ s3 := math.sin(t3)
+
+ m[0][0] = c2 * c3
+ m[0][1] = s1 * s3 + c1 * c3 * s2
+ m[0][2] = c3 * s1 * s2 - c1 * s3
+ m[1][0] =-s2
+ m[1][1] = c1 * c2
+ m[1][2] = c2 * s1
+ m[2][0] = c2 * s3
+ m[2][1] = c1 * s2 * s3 - c3 * s1
+ m[2][2] = c1 * c3 + s1 * s2 *s3
+ return
}
matrix3_from_euler_angles_yzx_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) {
- c1 := math.cos(t1);
- s1 := math.sin(t1);
- c2 := math.cos(t2);
- s2 := math.sin(t2);
- c3 := math.cos(t3);
- s3 := math.sin(t3);
-
- m[0][0] = c1 * c2;
- m[0][1] = s2;
- m[0][2] =-c2 * s1;
- m[1][0] = s1 * s3 - c1 * c3 * s2;
- m[1][1] = c2 * c3;
- m[1][2] = c1 * s3 + c3 * s1 * s2;
- m[2][0] = c3 * s1 + c1 * s2 * s3;
- m[2][1] =-c2 * s3;
- m[2][2] = c1 * c3 - s1 * s2 * s3;
- return;
+ c1 := math.cos(t1)
+ s1 := math.sin(t1)
+ c2 := math.cos(t2)
+ s2 := math.sin(t2)
+ c3 := math.cos(t3)
+ s3 := math.sin(t3)
+
+ m[0][0] = c1 * c2
+ m[0][1] = s2
+ m[0][2] =-c2 * s1
+ m[1][0] = s1 * s3 - c1 * c3 * s2
+ m[1][1] = c2 * c3
+ m[1][2] = c1 * s3 + c3 * s1 * s2
+ m[2][0] = c3 * s1 + c1 * s2 * s3
+ m[2][1] =-c2 * s3
+ m[2][2] = c1 * c3 - s1 * s2 * s3
+ return
}
matrix3_from_euler_angles_zyx_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) {
- c1 := math.cos(t1);
- s1 := math.sin(t1);
- c2 := math.cos(t2);
- s2 := math.sin(t2);
- c3 := math.cos(t3);
- s3 := math.sin(t3);
-
- m[0][0] = c1 * c2;
- m[0][1] = c2 * s1;
- m[0][2] =-s2;
- m[1][0] = c1 * s2 * s3 - c3 * s1;
- m[1][1] = c1 * c3 + s1 * s2 * s3;
- m[1][2] = c2 * s3;
- m[2][0] = s1 * s3 + c1 * c3 * s2;
- m[2][1] = c3 * s1 * s2 - c1 * s3;
- m[2][2] = c2 * c3;
- return;
+ c1 := math.cos(t1)
+ s1 := math.sin(t1)
+ c2 := math.cos(t2)
+ s2 := math.sin(t2)
+ c3 := math.cos(t3)
+ s3 := math.sin(t3)
+
+ m[0][0] = c1 * c2
+ m[0][1] = c2 * s1
+ m[0][2] =-s2
+ m[1][0] = c1 * s2 * s3 - c3 * s1
+ m[1][1] = c1 * c3 + s1 * s2 * s3
+ m[1][2] = c2 * s3
+ m[2][0] = s1 * s3 + c1 * c3 * s2
+ m[2][1] = c3 * s1 * s2 - c1 * s3
+ m[2][2] = c2 * c3
+ return
}
matrix3_from_euler_angles_zxy_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) {
- c1 := math.cos(t1);
- s1 := math.sin(t1);
- c2 := math.cos(t2);
- s2 := math.sin(t2);
- c3 := math.cos(t3);
- s3 := math.sin(t3);
-
- m[0][0] = c1 * c3 - s1 * s2 * s3;
- m[0][1] = c3 * s1 + c1 * s2 * s3;
- m[0][2] =-c2 * s3;
- m[1][0] =-c2 * s1;
- m[1][1] = c1 * c2;
- m[1][2] = s2;
- m[2][0] = c1 * s3 + c3 * s1 * s2;
- m[2][1] = s1 * s3 - c1 * c3 * s2;
- m[2][2] = c2 * c3;
- return;
+ c1 := math.cos(t1)
+ s1 := math.sin(t1)
+ c2 := math.cos(t2)
+ s2 := math.sin(t2)
+ c3 := math.cos(t3)
+ s3 := math.sin(t3)
+
+ m[0][0] = c1 * c3 - s1 * s2 * s3
+ m[0][1] = c3 * s1 + c1 * s2 * s3
+ m[0][2] =-c2 * s3
+ m[1][0] =-c2 * s1
+ m[1][1] = c1 * c2
+ m[1][2] = s2
+ m[2][0] = c1 * s3 + c3 * s1 * s2
+ m[2][1] = s1 * s3 - c1 * c3 * s2
+ m[2][2] = c2 * c3
+ return
}
matrix3_from_yaw_pitch_roll_f32 :: proc(yaw, pitch, roll: f32) -> (m: Matrix3f32) {
- ch := math.cos(yaw);
- sh := math.sin(yaw);
- cp := math.cos(pitch);
- sp := math.sin(pitch);
- cb := math.cos(roll);
- sb := math.sin(roll);
-
- m[0][0] = ch * cb + sh * sp * sb;
- m[0][1] = sb * cp;
- m[0][2] = -sh * cb + ch * sp * sb;
- m[1][0] = -ch * sb + sh * sp * cb;
- m[1][1] = cb * cp;
- m[1][2] = sb * sh + ch * sp * cb;
- m[2][0] = sh * cp;
- m[2][1] = -sp;
- m[2][2] = ch * cp;
- return m;
+ ch := math.cos(yaw)
+ sh := math.sin(yaw)
+ cp := math.cos(pitch)
+ sp := math.sin(pitch)
+ cb := math.cos(roll)
+ sb := math.sin(roll)
+
+ m[0][0] = ch * cb + sh * sp * sb
+ m[0][1] = sb * cp
+ m[0][2] = -sh * cb + ch * sp * sb
+ m[1][0] = -ch * sb + sh * sp * cb
+ m[1][1] = cb * cp
+ m[1][2] = sb * sh + ch * sp * cb
+ m[2][0] = sh * cp
+ m[2][1] = -sp
+ m[2][2] = ch * cp
+ return m
}
euler_angles_xyz_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) {
- T1 := math.atan2(m[2][1], m[2][2]);
- C2 := math.sqrt(m[0][0]*m[0][0] + m[1][0]*m[1][0]);
- T2 := math.atan2(-m[2][0], C2);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(S1*m[0][2] - C1*m[0][1], C1*m[1][1] - S1*m[1][2]);
- t1 = -T1;
- t2 = -T2;
- t3 = -T3;
- return;
+ T1 := math.atan2(m[2][1], m[2][2])
+ C2 := math.sqrt(m[0][0]*m[0][0] + m[1][0]*m[1][0])
+ T2 := math.atan2(-m[2][0], C2)
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(S1*m[0][2] - C1*m[0][1], C1*m[1][1] - S1*m[1][2])
+ t1 = -T1
+ t2 = -T2
+ t3 = -T3
+ return
}
euler_angles_yxz_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) {
- T1 := math.atan2(m[2][0], m[2][2]);
- C2 := math.sqrt(m[0][1]*m[0][1] + m[1][1]*m[1][1]);
- T2 := math.atan2(-m[2][1], C2);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(S1*m[1][2] - C1*m[1][0], C1*m[0][0] - S1*m[0][2]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(m[2][0], m[2][2])
+ C2 := math.sqrt(m[0][1]*m[0][1] + m[1][1]*m[1][1])
+ T2 := math.atan2(-m[2][1], C2)
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(S1*m[1][2] - C1*m[1][0], C1*m[0][0] - S1*m[0][2])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
euler_angles_xzx_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) {
- T1 := math.atan2(m[0][2], m[0][1]);
- S2 := math.sqrt(m[1][0]*m[1][0] + m[2][0]*m[2][0]);
- T2 := math.atan2(S2, m[0][0]);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(C1*m[1][2] - S1*m[1][1], C1*m[2][2] - S1*m[2][1]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(m[0][2], m[0][1])
+ S2 := math.sqrt(m[1][0]*m[1][0] + m[2][0]*m[2][0])
+ T2 := math.atan2(S2, m[0][0])
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(C1*m[1][2] - S1*m[1][1], C1*m[2][2] - S1*m[2][1])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
euler_angles_xyx_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) {
- T1 := math.atan2(m[0][1], -m[0][2]);
- S2 := math.sqrt(m[1][0]*m[1][0] + m[2][0]*m[2][0]);
- T2 := math.atan2(S2, m[0][0]);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(-C1*m[2][1] - S1*m[2][2], C1*m[1][1] + S1*m[1][2]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(m[0][1], -m[0][2])
+ S2 := math.sqrt(m[1][0]*m[1][0] + m[2][0]*m[2][0])
+ T2 := math.atan2(S2, m[0][0])
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(-C1*m[2][1] - S1*m[2][2], C1*m[1][1] + S1*m[1][2])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
euler_angles_yxy_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) {
- T1 := math.atan2(m[1][0], m[1][2]);
- S2 := math.sqrt(m[0][1]*m[0][1] + m[2][1]*m[2][1]);
- T2 := math.atan2(S2, m[1][1]);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(C1*m[2][0] - S1*m[2][2], C1*m[0][0] - S1*m[0][2]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(m[1][0], m[1][2])
+ S2 := math.sqrt(m[0][1]*m[0][1] + m[2][1]*m[2][1])
+ T2 := math.atan2(S2, m[1][1])
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(C1*m[2][0] - S1*m[2][2], C1*m[0][0] - S1*m[0][2])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
euler_angles_yzy_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) {
- T1 := math.atan2(m[1][2], -m[1][0]);
- S2 := math.sqrt(m[0][1]*m[0][1] + m[2][1]*m[2][1]);
- T2 := math.atan2(S2, m[1][1]);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(-S1*m[0][0] - C1*m[0][2], S1*m[2][0] + C1*m[2][2]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(m[1][2], -m[1][0])
+ S2 := math.sqrt(m[0][1]*m[0][1] + m[2][1]*m[2][1])
+ T2 := math.atan2(S2, m[1][1])
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(-S1*m[0][0] - C1*m[0][2], S1*m[2][0] + C1*m[2][2])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
euler_angles_zyz_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) {
- T1 := math.atan2(m[2][1], m[2][0]);
- S2 := math.sqrt(m[0][2]*m[0][2] + m[1][2]*m[1][2]);
- T2 := math.atan2(S2, m[2][2]);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(C1*m[0][1] - S1*m[0][0], C1*m[1][1] - S1*m[1][0]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(m[2][1], m[2][0])
+ S2 := math.sqrt(m[0][2]*m[0][2] + m[1][2]*m[1][2])
+ T2 := math.atan2(S2, m[2][2])
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(C1*m[0][1] - S1*m[0][0], C1*m[1][1] - S1*m[1][0])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
euler_angles_zxz_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) {
- T1 := math.atan2(m[2][0], -m[2][1]);
- S2 := math.sqrt(m[0][2]*m[0][2] + m[1][2]*m[1][2]);
- T2 := math.atan2(S2, m[2][2]);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(-C1*m[1][0] - S1*m[1][1], C1*m[0][0] + S1*m[0][1]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(m[2][0], -m[2][1])
+ S2 := math.sqrt(m[0][2]*m[0][2] + m[1][2]*m[1][2])
+ T2 := math.atan2(S2, m[2][2])
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(-C1*m[1][0] - S1*m[1][1], C1*m[0][0] + S1*m[0][1])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
euler_angles_xzy_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) {
- T1 := math.atan2(m[1][2], m[1][1]);
- C2 := math.sqrt(m[0][0]*m[0][0] + m[2][0]*m[2][0]);
- T2 := math.atan2(-m[1][0], C2);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(S1*m[0][1] - C1*m[0][2], C1*m[2][2] - S1*m[2][1]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(m[1][2], m[1][1])
+ C2 := math.sqrt(m[0][0]*m[0][0] + m[2][0]*m[2][0])
+ T2 := math.atan2(-m[1][0], C2)
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(S1*m[0][1] - C1*m[0][2], C1*m[2][2] - S1*m[2][1])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
euler_angles_yzx_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) {
- T1 := math.atan2(-m[0][2], m[0][0]);
- C2 := math.sqrt(m[1][1]*m[1][1] + m[2][1]*m[2][1]);
- T2 := math.atan2(m[0][1], C2);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(S1*m[1][0] + C1*m[1][2], S1*m[2][0] + C1*m[2][2]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(-m[0][2], m[0][0])
+ C2 := math.sqrt(m[1][1]*m[1][1] + m[2][1]*m[2][1])
+ T2 := math.atan2(m[0][1], C2)
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(S1*m[1][0] + C1*m[1][2], S1*m[2][0] + C1*m[2][2])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
euler_angles_zyx_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) {
- T1 := math.atan2(m[0][1], m[0][0]);
- C2 := math.sqrt(m[1][2]*m[1][2] + m[2][2]*m[2][2]);
- T2 := math.atan2(-m[0][2], C2);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(S1*m[2][0] - C1*m[2][1], C1*m[1][1] - S1*m[1][0]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(m[0][1], m[0][0])
+ C2 := math.sqrt(m[1][2]*m[1][2] + m[2][2]*m[2][2])
+ T2 := math.atan2(-m[0][2], C2)
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(S1*m[2][0] - C1*m[2][1], C1*m[1][1] - S1*m[1][0])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
euler_angles_zxy_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) {
- T1 := math.atan2(-m[1][0], m[1][1]);
- C2 := math.sqrt(m[0][2]*m[0][2] + m[2][2]*m[2][2]);
- T2 := math.atan2(m[1][2], C2);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(C1*m[2][0] + S1*m[2][1], C1*m[0][0] + S1*m[0][1]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(-m[1][0], m[1][1])
+ C2 := math.sqrt(m[0][2]*m[0][2] + m[2][2]*m[2][2])
+ T2 := math.atan2(m[1][2], C2)
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(C1*m[2][0] + S1*m[2][1], C1*m[0][0] + S1*m[0][1])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
@@ -736,621 +736,621 @@ euler_angles_zxy_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) {
matrix4_from_euler_angle_x_f32 :: proc(angle_x: f32) -> (m: Matrix4f32) {
- cos_x, sin_x := math.cos(angle_x), math.sin(angle_x);
- m[0][0] = 1;
- m[1][1] = +cos_x;
- m[2][1] = +sin_x;
- m[1][2] = -sin_x;
- m[2][2] = +cos_x;
- m[3][3] = 1;
- return;
+ cos_x, sin_x := math.cos(angle_x), math.sin(angle_x)
+ m[0][0] = 1
+ m[1][1] = +cos_x
+ m[2][1] = +sin_x
+ m[1][2] = -sin_x
+ m[2][2] = +cos_x
+ m[3][3] = 1
+ return
}
matrix4_from_euler_angle_y_f32 :: proc(angle_y: f32) -> (m: Matrix4f32) {
- cos_y, sin_y := math.cos(angle_y), math.sin(angle_y);
- m[0][0] = +cos_y;
- m[2][0] = -sin_y;
- m[1][1] = 1;
- m[0][2] = +sin_y;
- m[2][2] = +cos_y;
- m[3][3] = 1;
- return;
+ cos_y, sin_y := math.cos(angle_y), math.sin(angle_y)
+ m[0][0] = +cos_y
+ m[2][0] = -sin_y
+ m[1][1] = 1
+ m[0][2] = +sin_y
+ m[2][2] = +cos_y
+ m[3][3] = 1
+ return
}
matrix4_from_euler_angle_z_f32 :: proc(angle_z: f32) -> (m: Matrix4f32) {
- cos_z, sin_z := math.cos(angle_z), math.sin(angle_z);
- m[0][0] = +cos_z;
- m[1][0] = +sin_z;
- m[1][1] = +cos_z;
- m[0][1] = -sin_z;
- m[2][2] = 1;
- m[3][3] = 1;
- return;
+ cos_z, sin_z := math.cos(angle_z), math.sin(angle_z)
+ m[0][0] = +cos_z
+ m[1][0] = +sin_z
+ m[1][1] = +cos_z
+ m[0][1] = -sin_z
+ m[2][2] = 1
+ m[3][3] = 1
+ return
}
matrix4_from_derived_euler_angle_x_f32 :: proc(angle_x: f32, angular_velocity_x: f32) -> (m: Matrix4f32) {
- cos_x := math.cos(angle_x) * angular_velocity_x;
- sin_x := math.sin(angle_x) * angular_velocity_x;
- m[0][0] = 1;
- m[1][1] = +cos_x;
- m[2][1] = +sin_x;
- m[1][2] = -sin_x;
- m[2][2] = +cos_x;
- m[3][3] = 1;
- return;
+ cos_x := math.cos(angle_x) * angular_velocity_x
+ sin_x := math.sin(angle_x) * angular_velocity_x
+ m[0][0] = 1
+ m[1][1] = +cos_x
+ m[2][1] = +sin_x
+ m[1][2] = -sin_x
+ m[2][2] = +cos_x
+ m[3][3] = 1
+ return
}
matrix4_from_derived_euler_angle_y_f32 :: proc(angle_y: f32, angular_velocity_y: f32) -> (m: Matrix4f32) {
- cos_y := math.cos(angle_y) * angular_velocity_y;
- sin_y := math.sin(angle_y) * angular_velocity_y;
- m[0][0] = +cos_y;
- m[2][0] = -sin_y;
- m[1][1] = 1;
- m[0][2] = +sin_y;
- m[2][2] = +cos_y;
- m[3][3] = 1;
- return;
+ cos_y := math.cos(angle_y) * angular_velocity_y
+ sin_y := math.sin(angle_y) * angular_velocity_y
+ m[0][0] = +cos_y
+ m[2][0] = -sin_y
+ m[1][1] = 1
+ m[0][2] = +sin_y
+ m[2][2] = +cos_y
+ m[3][3] = 1
+ return
}
matrix4_from_derived_euler_angle_z_f32 :: proc(angle_z: f32, angular_velocity_z: f32) -> (m: Matrix4f32) {
- cos_z := math.cos(angle_z) * angular_velocity_z;
- sin_z := math.sin(angle_z) * angular_velocity_z;
- m[0][0] = +cos_z;
- m[1][0] = +sin_z;
- m[1][1] = +cos_z;
- m[0][1] = -sin_z;
- m[2][2] = 1;
- m[3][3] = 1;
- return;
+ cos_z := math.cos(angle_z) * angular_velocity_z
+ sin_z := math.sin(angle_z) * angular_velocity_z
+ m[0][0] = +cos_z
+ m[1][0] = +sin_z
+ m[1][1] = +cos_z
+ m[0][1] = -sin_z
+ m[2][2] = 1
+ m[3][3] = 1
+ return
}
matrix4_from_euler_angles_xy_f32 :: proc(angle_x, angle_y: f32) -> (m: Matrix4f32) {
- cos_x, sin_x := math.cos(angle_x), math.sin(angle_x);
- cos_y, sin_y := math.cos(angle_y), math.sin(angle_y);
- m[0][0] = cos_y;
- m[1][0] = -sin_x * - sin_y;
- m[2][0] = -cos_x * - sin_y;
- m[1][1] = cos_x;
- m[2][1] = sin_x;
- m[0][2] = sin_y;
- m[1][2] = -sin_x * cos_y;
- m[2][2] = cos_x * cos_y;
- m[3][3] = 1;
- return;
+ cos_x, sin_x := math.cos(angle_x), math.sin(angle_x)
+ cos_y, sin_y := math.cos(angle_y), math.sin(angle_y)
+ m[0][0] = cos_y
+ m[1][0] = -sin_x * - sin_y
+ m[2][0] = -cos_x * - sin_y
+ m[1][1] = cos_x
+ m[2][1] = sin_x
+ m[0][2] = sin_y
+ m[1][2] = -sin_x * cos_y
+ m[2][2] = cos_x * cos_y
+ m[3][3] = 1
+ return
}
matrix4_from_euler_angles_yx_f32 :: proc(angle_y, angle_x: f32) -> (m: Matrix4f32) {
- cos_x, sin_x := math.cos(angle_x), math.sin(angle_x);
- cos_y, sin_y := math.cos(angle_y), math.sin(angle_y);
- m[0][0] = cos_y;
- m[2][0] = -sin_y;
- m[0][1] = sin_y*sin_x;
- m[1][1] = cos_x;
- m[2][1] = cos_y*sin_x;
- m[0][2] = sin_y*cos_x;
- m[1][2] = -sin_x;
- m[2][2] = cos_y*cos_x;
- m[3][3] = 1;
- return;
+ cos_x, sin_x := math.cos(angle_x), math.sin(angle_x)
+ cos_y, sin_y := math.cos(angle_y), math.sin(angle_y)
+ m[0][0] = cos_y
+ m[2][0] = -sin_y
+ m[0][1] = sin_y*sin_x
+ m[1][1] = cos_x
+ m[2][1] = cos_y*sin_x
+ m[0][2] = sin_y*cos_x
+ m[1][2] = -sin_x
+ m[2][2] = cos_y*cos_x
+ m[3][3] = 1
+ return
}
matrix4_from_euler_angles_xz_f32 :: proc(angle_x, angle_z: f32) -> (m: Matrix4f32) {
- return mul(matrix4_from_euler_angle_x(angle_x), matrix4_from_euler_angle_z(angle_z));
+ return mul(matrix4_from_euler_angle_x(angle_x), matrix4_from_euler_angle_z(angle_z))
}
matrix4_from_euler_angles_zx_f32 :: proc(angle_z, angle_x: f32) -> (m: Matrix4f32) {
- return mul(matrix4_from_euler_angle_z(angle_z), matrix4_from_euler_angle_x(angle_x));
+ return mul(matrix4_from_euler_angle_z(angle_z), matrix4_from_euler_angle_x(angle_x))
}
matrix4_from_euler_angles_yz_f32 :: proc(angle_y, angle_z: f32) -> (m: Matrix4f32) {
- return mul(matrix4_from_euler_angle_y(angle_y), matrix4_from_euler_angle_z(angle_z));
+ return mul(matrix4_from_euler_angle_y(angle_y), matrix4_from_euler_angle_z(angle_z))
}
matrix4_from_euler_angles_zy_f32 :: proc(angle_z, angle_y: f32) -> (m: Matrix4f32) {
- return mul(matrix4_from_euler_angle_z(angle_z), matrix4_from_euler_angle_y(angle_y));
+ return mul(matrix4_from_euler_angle_z(angle_z), matrix4_from_euler_angle_y(angle_y))
}
matrix4_from_euler_angles_xyz_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) {
- c1 := math.cos(-t1);
- c2 := math.cos(-t2);
- c3 := math.cos(-t3);
- s1 := math.sin(-t1);
- s2 := math.sin(-t2);
- s3 := math.sin(-t3);
-
- m[0][0] = c2 * c3;
- m[0][1] =-c1 * s3 + s1 * s2 * c3;
- m[0][2] = s1 * s3 + c1 * s2 * c3;
- m[0][3] = 0;
- m[1][0] = c2 * s3;
- m[1][1] = c1 * c3 + s1 * s2 * s3;
- m[1][2] =-s1 * c3 + c1 * s2 * s3;
- m[1][3] = 0;
- m[2][0] =-s2;
- m[2][1] = s1 * c2;
- m[2][2] = c1 * c2;
- m[2][3] = 0;
- m[3][0] = 0;
- m[3][1] = 0;
- m[3][2] = 0;
- m[3][3] = 1;
- return;
+ c1 := math.cos(-t1)
+ c2 := math.cos(-t2)
+ c3 := math.cos(-t3)
+ s1 := math.sin(-t1)
+ s2 := math.sin(-t2)
+ s3 := math.sin(-t3)
+
+ m[0][0] = c2 * c3
+ m[0][1] =-c1 * s3 + s1 * s2 * c3
+ m[0][2] = s1 * s3 + c1 * s2 * c3
+ m[0][3] = 0
+ m[1][0] = c2 * s3
+ m[1][1] = c1 * c3 + s1 * s2 * s3
+ m[1][2] =-s1 * c3 + c1 * s2 * s3
+ m[1][3] = 0
+ m[2][0] =-s2
+ m[2][1] = s1 * c2
+ m[2][2] = c1 * c2
+ m[2][3] = 0
+ m[3][0] = 0
+ m[3][1] = 0
+ m[3][2] = 0
+ m[3][3] = 1
+ return
}
matrix4_from_euler_angles_yxz_f32 :: proc(yaw, pitch, roll: f32) -> (m: Matrix4f32) {
- ch := math.cos(yaw);
- sh := math.sin(yaw);
- cp := math.cos(pitch);
- sp := math.sin(pitch);
- cb := math.cos(roll);
- sb := math.sin(roll);
-
- m[0][0] = ch * cb + sh * sp * sb;
- m[0][1] = sb * cp;
- m[0][2] = -sh * cb + ch * sp * sb;
- m[0][3] = 0;
- m[1][0] = -ch * sb + sh * sp * cb;
- m[1][1] = cb * cp;
- m[1][2] = sb * sh + ch * sp * cb;
- m[1][3] = 0;
- m[2][0] = sh * cp;
- m[2][1] = -sp;
- m[2][2] = ch * cp;
- m[2][3] = 0;
- m[3][0] = 0;
- m[3][1] = 0;
- m[3][2] = 0;
- m[3][3] = 1;
- return;
+ ch := math.cos(yaw)
+ sh := math.sin(yaw)
+ cp := math.cos(pitch)
+ sp := math.sin(pitch)
+ cb := math.cos(roll)
+ sb := math.sin(roll)
+
+ m[0][0] = ch * cb + sh * sp * sb
+ m[0][1] = sb * cp
+ m[0][2] = -sh * cb + ch * sp * sb
+ m[0][3] = 0
+ m[1][0] = -ch * sb + sh * sp * cb
+ m[1][1] = cb * cp
+ m[1][2] = sb * sh + ch * sp * cb
+ m[1][3] = 0
+ m[2][0] = sh * cp
+ m[2][1] = -sp
+ m[2][2] = ch * cp
+ m[2][3] = 0
+ m[3][0] = 0
+ m[3][1] = 0
+ m[3][2] = 0
+ m[3][3] = 1
+ return
}
matrix4_from_euler_angles_xzx_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) {
- c1 := math.cos(t1);
- s1 := math.sin(t1);
- c2 := math.cos(t2);
- s2 := math.sin(t2);
- c3 := math.cos(t3);
- s3 := math.sin(t3);
-
- m[0][0] = c2;
- m[0][1] = c1 * s2;
- m[0][2] = s1 * s2;
- m[0][3] = 0;
- m[1][0] =-c3 * s2;
- m[1][1] = c1 * c2 * c3 - s1 * s3;
- m[1][2] = c1 * s3 + c2 * c3 * s1;
- m[1][3] = 0;
- m[2][0] = s2 * s3;
- m[2][1] =-c3 * s1 - c1 * c2 * s3;
- m[2][2] = c1 * c3 - c2 * s1 * s3;
- m[2][3] = 0;
- m[3][0] = 0;
- m[3][1] = 0;
- m[3][2] = 0;
- m[3][3] = 1;
- return;
+ c1 := math.cos(t1)
+ s1 := math.sin(t1)
+ c2 := math.cos(t2)
+ s2 := math.sin(t2)
+ c3 := math.cos(t3)
+ s3 := math.sin(t3)
+
+ m[0][0] = c2
+ m[0][1] = c1 * s2
+ m[0][2] = s1 * s2
+ m[0][3] = 0
+ m[1][0] =-c3 * s2
+ m[1][1] = c1 * c2 * c3 - s1 * s3
+ m[1][2] = c1 * s3 + c2 * c3 * s1
+ m[1][3] = 0
+ m[2][0] = s2 * s3
+ m[2][1] =-c3 * s1 - c1 * c2 * s3
+ m[2][2] = c1 * c3 - c2 * s1 * s3
+ m[2][3] = 0
+ m[3][0] = 0
+ m[3][1] = 0
+ m[3][2] = 0
+ m[3][3] = 1
+ return
}
matrix4_from_euler_angles_xyx_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) {
- c1 := math.cos(t1);
- s1 := math.sin(t1);
- c2 := math.cos(t2);
- s2 := math.sin(t2);
- c3 := math.cos(t3);
- s3 := math.sin(t3);
-
- m[0][0] = c2;
- m[0][1] = s1 * s2;
- m[0][2] =-c1 * s2;
- m[0][3] = 0;
- m[1][0] = s2 * s3;
- m[1][1] = c1 * c3 - c2 * s1 * s3;
- m[1][2] = c3 * s1 + c1 * c2 * s3;
- m[1][3] = 0;
- m[2][0] = c3 * s2;
- m[2][1] =-c1 * s3 - c2 * c3 * s1;
- m[2][2] = c1 * c2 * c3 - s1 * s3;
- m[2][3] = 0;
- m[3][0] = 0;
- m[3][1] = 0;
- m[3][2] = 0;
- m[3][3] = 1;
- return;
+ c1 := math.cos(t1)
+ s1 := math.sin(t1)
+ c2 := math.cos(t2)
+ s2 := math.sin(t2)
+ c3 := math.cos(t3)
+ s3 := math.sin(t3)
+
+ m[0][0] = c2
+ m[0][1] = s1 * s2
+ m[0][2] =-c1 * s2
+ m[0][3] = 0
+ m[1][0] = s2 * s3
+ m[1][1] = c1 * c3 - c2 * s1 * s3
+ m[1][2] = c3 * s1 + c1 * c2 * s3
+ m[1][3] = 0
+ m[2][0] = c3 * s2
+ m[2][1] =-c1 * s3 - c2 * c3 * s1
+ m[2][2] = c1 * c2 * c3 - s1 * s3
+ m[2][3] = 0
+ m[3][0] = 0
+ m[3][1] = 0
+ m[3][2] = 0
+ m[3][3] = 1
+ return
}
matrix4_from_euler_angles_yxy_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) {
- c1 := math.cos(t1);
- s1 := math.sin(t1);
- c2 := math.cos(t2);
- s2 := math.sin(t2);
- c3 := math.cos(t3);
- s3 := math.sin(t3);
-
- m[0][0] = c1 * c3 - c2 * s1 * s3;
- m[0][1] = s2* s3;
- m[0][2] =-c3 * s1 - c1 * c2 * s3;
- m[0][3] = 0;
- m[1][0] = s1 * s2;
- m[1][1] = c2;
- m[1][2] = c1 * s2;
- m[1][3] = 0;
- m[2][0] = c1 * s3 + c2 * c3 * s1;
- m[2][1] =-c3 * s2;
- m[2][2] = c1 * c2 * c3 - s1 * s3;
- m[2][3] = 0;
- m[3][0] = 0;
- m[3][1] = 0;
- m[3][2] = 0;
- m[3][3] = 1;
- return;
+ c1 := math.cos(t1)
+ s1 := math.sin(t1)
+ c2 := math.cos(t2)
+ s2 := math.sin(t2)
+ c3 := math.cos(t3)
+ s3 := math.sin(t3)
+
+ m[0][0] = c1 * c3 - c2 * s1 * s3
+ m[0][1] = s2* s3
+ m[0][2] =-c3 * s1 - c1 * c2 * s3
+ m[0][3] = 0
+ m[1][0] = s1 * s2
+ m[1][1] = c2
+ m[1][2] = c1 * s2
+ m[1][3] = 0
+ m[2][0] = c1 * s3 + c2 * c3 * s1
+ m[2][1] =-c3 * s2
+ m[2][2] = c1 * c2 * c3 - s1 * s3
+ m[2][3] = 0
+ m[3][0] = 0
+ m[3][1] = 0
+ m[3][2] = 0
+ m[3][3] = 1
+ return
}
matrix4_from_euler_angles_yzy_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) {
- c1 := math.cos(t1);
- s1 := math.sin(t1);
- c2 := math.cos(t2);
- s2 := math.sin(t2);
- c3 := math.cos(t3);
- s3 := math.sin(t3);
-
- m[0][0] = c1 * c2 * c3 - s1 * s3;
- m[0][1] = c3 * s2;
- m[0][2] =-c1 * s3 - c2 * c3 * s1;
- m[0][3] = 0;
- m[1][0] =-c1 * s2;
- m[1][1] = c2;
- m[1][2] = s1 * s2;
- m[1][3] = 0;
- m[2][0] = c3 * s1 + c1 * c2 * s3;
- m[2][1] = s2 * s3;
- m[2][2] = c1 * c3 - c2 * s1 * s3;
- m[2][3] = 0;
- m[3][0] = 0;
- m[3][1] = 0;
- m[3][2] = 0;
- m[3][3] = 1;
- return;
+ c1 := math.cos(t1)
+ s1 := math.sin(t1)
+ c2 := math.cos(t2)
+ s2 := math.sin(t2)
+ c3 := math.cos(t3)
+ s3 := math.sin(t3)
+
+ m[0][0] = c1 * c2 * c3 - s1 * s3
+ m[0][1] = c3 * s2
+ m[0][2] =-c1 * s3 - c2 * c3 * s1
+ m[0][3] = 0
+ m[1][0] =-c1 * s2
+ m[1][1] = c2
+ m[1][2] = s1 * s2
+ m[1][3] = 0
+ m[2][0] = c3 * s1 + c1 * c2 * s3
+ m[2][1] = s2 * s3
+ m[2][2] = c1 * c3 - c2 * s1 * s3
+ m[2][3] = 0
+ m[3][0] = 0
+ m[3][1] = 0
+ m[3][2] = 0
+ m[3][3] = 1
+ return
}
matrix4_from_euler_angles_zyz_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) {
- c1 := math.cos(t1);
- s1 := math.sin(t1);
- c2 := math.cos(t2);
- s2 := math.sin(t2);
- c3 := math.cos(t3);
- s3 := math.sin(t3);
-
- m[0][0] = c1 * c2 * c3 - s1 * s3;
- m[0][1] = c1 * s3 + c2 * c3 * s1;
- m[0][2] =-c3 * s2;
- m[0][3] = 0;
- m[1][0] =-c3 * s1 - c1 * c2 * s3;
- m[1][1] = c1 * c3 - c2 * s1 * s3;
- m[1][2] = s2 * s3;
- m[1][3] = 0;
- m[2][0] = c1 * s2;
- m[2][1] = s1 * s2;
- m[2][2] = c2;
- m[2][3] = 0;
- m[3][0] = 0;
- m[3][1] = 0;
- m[3][2] = 0;
- m[3][3] = 1;
- return;
+ c1 := math.cos(t1)
+ s1 := math.sin(t1)
+ c2 := math.cos(t2)
+ s2 := math.sin(t2)
+ c3 := math.cos(t3)
+ s3 := math.sin(t3)
+
+ m[0][0] = c1 * c2 * c3 - s1 * s3
+ m[0][1] = c1 * s3 + c2 * c3 * s1
+ m[0][2] =-c3 * s2
+ m[0][3] = 0
+ m[1][0] =-c3 * s1 - c1 * c2 * s3
+ m[1][1] = c1 * c3 - c2 * s1 * s3
+ m[1][2] = s2 * s3
+ m[1][3] = 0
+ m[2][0] = c1 * s2
+ m[2][1] = s1 * s2
+ m[2][2] = c2
+ m[2][3] = 0
+ m[3][0] = 0
+ m[3][1] = 0
+ m[3][2] = 0
+ m[3][3] = 1
+ return
}
matrix4_from_euler_angles_zxz_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) {
- c1 := math.cos(t1);
- s1 := math.sin(t1);
- c2 := math.cos(t2);
- s2 := math.sin(t2);
- c3 := math.cos(t3);
- s3 := math.sin(t3);
-
- m[0][0] = c1 * c3 - c2 * s1 * s3;
- m[0][1] = c3 * s1 + c1 * c2 * s3;
- m[0][2] = s2 *s3;
- m[0][3] = 0;
- m[1][0] =-c1 * s3 - c2 * c3 * s1;
- m[1][1] = c1 * c2 * c3 - s1 * s3;
- m[1][2] = c3 * s2;
- m[1][3] = 0;
- m[2][0] = s1 * s2;
- m[2][1] =-c1 * s2;
- m[2][2] = c2;
- m[2][3] = 0;
- m[3][0] = 0;
- m[3][1] = 0;
- m[3][2] = 0;
- m[3][3] = 1;
- return;
+ c1 := math.cos(t1)
+ s1 := math.sin(t1)
+ c2 := math.cos(t2)
+ s2 := math.sin(t2)
+ c3 := math.cos(t3)
+ s3 := math.sin(t3)
+
+ m[0][0] = c1 * c3 - c2 * s1 * s3
+ m[0][1] = c3 * s1 + c1 * c2 * s3
+ m[0][2] = s2 *s3
+ m[0][3] = 0
+ m[1][0] =-c1 * s3 - c2 * c3 * s1
+ m[1][1] = c1 * c2 * c3 - s1 * s3
+ m[1][2] = c3 * s2
+ m[1][3] = 0
+ m[2][0] = s1 * s2
+ m[2][1] =-c1 * s2
+ m[2][2] = c2
+ m[2][3] = 0
+ m[3][0] = 0
+ m[3][1] = 0
+ m[3][2] = 0
+ m[3][3] = 1
+ return
}
matrix4_from_euler_angles_xzy_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) {
- c1 := math.cos(t1);
- s1 := math.sin(t1);
- c2 := math.cos(t2);
- s2 := math.sin(t2);
- c3 := math.cos(t3);
- s3 := math.sin(t3);
-
- m[0][0] = c2 * c3;
- m[0][1] = s1 * s3 + c1 * c3 * s2;
- m[0][2] = c3 * s1 * s2 - c1 * s3;
- m[0][3] = 0;
- m[1][0] =-s2;
- m[1][1] = c1 * c2;
- m[1][2] = c2 * s1;
- m[1][3] = 0;
- m[2][0] = c2 * s3;
- m[2][1] = c1 * s2 * s3 - c3 * s1;
- m[2][2] = c1 * c3 + s1 * s2 *s3;
- m[2][3] = 0;
- m[3][0] = 0;
- m[3][1] = 0;
- m[3][2] = 0;
- m[3][3] = 1;
- return;
+ c1 := math.cos(t1)
+ s1 := math.sin(t1)
+ c2 := math.cos(t2)
+ s2 := math.sin(t2)
+ c3 := math.cos(t3)
+ s3 := math.sin(t3)
+
+ m[0][0] = c2 * c3
+ m[0][1] = s1 * s3 + c1 * c3 * s2
+ m[0][2] = c3 * s1 * s2 - c1 * s3
+ m[0][3] = 0
+ m[1][0] =-s2
+ m[1][1] = c1 * c2
+ m[1][2] = c2 * s1
+ m[1][3] = 0
+ m[2][0] = c2 * s3
+ m[2][1] = c1 * s2 * s3 - c3 * s1
+ m[2][2] = c1 * c3 + s1 * s2 *s3
+ m[2][3] = 0
+ m[3][0] = 0
+ m[3][1] = 0
+ m[3][2] = 0
+ m[3][3] = 1
+ return
}
matrix4_from_euler_angles_yzx_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) {
- c1 := math.cos(t1);
- s1 := math.sin(t1);
- c2 := math.cos(t2);
- s2 := math.sin(t2);
- c3 := math.cos(t3);
- s3 := math.sin(t3);
-
- m[0][0] = c1 * c2;
- m[0][1] = s2;
- m[0][2] =-c2 * s1;
- m[0][3] = 0;
- m[1][0] = s1 * s3 - c1 * c3 * s2;
- m[1][1] = c2 * c3;
- m[1][2] = c1 * s3 + c3 * s1 * s2;
- m[1][3] = 0;
- m[2][0] = c3 * s1 + c1 * s2 * s3;
- m[2][1] =-c2 * s3;
- m[2][2] = c1 * c3 - s1 * s2 * s3;
- m[2][3] = 0;
- m[3][0] = 0;
- m[3][1] = 0;
- m[3][2] = 0;
- m[3][3] = 1;
- return;
+ c1 := math.cos(t1)
+ s1 := math.sin(t1)
+ c2 := math.cos(t2)
+ s2 := math.sin(t2)
+ c3 := math.cos(t3)
+ s3 := math.sin(t3)
+
+ m[0][0] = c1 * c2
+ m[0][1] = s2
+ m[0][2] =-c2 * s1
+ m[0][3] = 0
+ m[1][0] = s1 * s3 - c1 * c3 * s2
+ m[1][1] = c2 * c3
+ m[1][2] = c1 * s3 + c3 * s1 * s2
+ m[1][3] = 0
+ m[2][0] = c3 * s1 + c1 * s2 * s3
+ m[2][1] =-c2 * s3
+ m[2][2] = c1 * c3 - s1 * s2 * s3
+ m[2][3] = 0
+ m[3][0] = 0
+ m[3][1] = 0
+ m[3][2] = 0
+ m[3][3] = 1
+ return
}
matrix4_from_euler_angles_zyx_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) {
- c1 := math.cos(t1);
- s1 := math.sin(t1);
- c2 := math.cos(t2);
- s2 := math.sin(t2);
- c3 := math.cos(t3);
- s3 := math.sin(t3);
-
- m[0][0] = c1 * c2;
- m[0][1] = c2 * s1;
- m[0][2] =-s2;
- m[0][3] = 0;
- m[1][0] = c1 * s2 * s3 - c3 * s1;
- m[1][1] = c1 * c3 + s1 * s2 * s3;
- m[1][2] = c2 * s3;
- m[1][3] = 0;
- m[2][0] = s1 * s3 + c1 * c3 * s2;
- m[2][1] = c3 * s1 * s2 - c1 * s3;
- m[2][2] = c2 * c3;
- m[2][3] = 0;
- m[3][0] = 0;
- m[3][1] = 0;
- m[3][2] = 0;
- m[3][3] = 1;
- return;
+ c1 := math.cos(t1)
+ s1 := math.sin(t1)
+ c2 := math.cos(t2)
+ s2 := math.sin(t2)
+ c3 := math.cos(t3)
+ s3 := math.sin(t3)
+
+ m[0][0] = c1 * c2
+ m[0][1] = c2 * s1
+ m[0][2] =-s2
+ m[0][3] = 0
+ m[1][0] = c1 * s2 * s3 - c3 * s1
+ m[1][1] = c1 * c3 + s1 * s2 * s3
+ m[1][2] = c2 * s3
+ m[1][3] = 0
+ m[2][0] = s1 * s3 + c1 * c3 * s2
+ m[2][1] = c3 * s1 * s2 - c1 * s3
+ m[2][2] = c2 * c3
+ m[2][3] = 0
+ m[3][0] = 0
+ m[3][1] = 0
+ m[3][2] = 0
+ m[3][3] = 1
+ return
}
matrix4_from_euler_angles_zxy_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) {
- c1 := math.cos(t1);
- s1 := math.sin(t1);
- c2 := math.cos(t2);
- s2 := math.sin(t2);
- c3 := math.cos(t3);
- s3 := math.sin(t3);
-
- m[0][0] = c1 * c3 - s1 * s2 * s3;
- m[0][1] = c3 * s1 + c1 * s2 * s3;
- m[0][2] =-c2 * s3;
- m[0][3] = 0;
- m[1][0] =-c2 * s1;
- m[1][1] = c1 * c2;
- m[1][2] = s2;
- m[1][3] = 0;
- m[2][0] = c1 * s3 + c3 * s1 * s2;
- m[2][1] = s1 * s3 - c1 * c3 * s2;
- m[2][2] = c2 * c3;
- m[2][3] = 0;
- m[3][0] = 0;
- m[3][1] = 0;
- m[3][2] = 0;
- m[3][3] = 1;
- return;
+ c1 := math.cos(t1)
+ s1 := math.sin(t1)
+ c2 := math.cos(t2)
+ s2 := math.sin(t2)
+ c3 := math.cos(t3)
+ s3 := math.sin(t3)
+
+ m[0][0] = c1 * c3 - s1 * s2 * s3
+ m[0][1] = c3 * s1 + c1 * s2 * s3
+ m[0][2] =-c2 * s3
+ m[0][3] = 0
+ m[1][0] =-c2 * s1
+ m[1][1] = c1 * c2
+ m[1][2] = s2
+ m[1][3] = 0
+ m[2][0] = c1 * s3 + c3 * s1 * s2
+ m[2][1] = s1 * s3 - c1 * c3 * s2
+ m[2][2] = c2 * c3
+ m[2][3] = 0
+ m[3][0] = 0
+ m[3][1] = 0
+ m[3][2] = 0
+ m[3][3] = 1
+ return
}
matrix4_from_yaw_pitch_roll_f32 :: proc(yaw, pitch, roll: f32) -> (m: Matrix4f32) {
- ch := math.cos(yaw);
- sh := math.sin(yaw);
- cp := math.cos(pitch);
- sp := math.sin(pitch);
- cb := math.cos(roll);
- sb := math.sin(roll);
-
- m[0][0] = ch * cb + sh * sp * sb;
- m[0][1] = sb * cp;
- m[0][2] = -sh * cb + ch * sp * sb;
- m[0][3] = 0;
- m[1][0] = -ch * sb + sh * sp * cb;
- m[1][1] = cb * cp;
- m[1][2] = sb * sh + ch * sp * cb;
- m[1][3] = 0;
- m[2][0] = sh * cp;
- m[2][1] = -sp;
- m[2][2] = ch * cp;
- m[2][3] = 0;
- m[3][0] = 0;
- m[3][1] = 0;
- m[3][2] = 0;
- m[3][3] = 1;
- return m;
+ ch := math.cos(yaw)
+ sh := math.sin(yaw)
+ cp := math.cos(pitch)
+ sp := math.sin(pitch)
+ cb := math.cos(roll)
+ sb := math.sin(roll)
+
+ m[0][0] = ch * cb + sh * sp * sb
+ m[0][1] = sb * cp
+ m[0][2] = -sh * cb + ch * sp * sb
+ m[0][3] = 0
+ m[1][0] = -ch * sb + sh * sp * cb
+ m[1][1] = cb * cp
+ m[1][2] = sb * sh + ch * sp * cb
+ m[1][3] = 0
+ m[2][0] = sh * cp
+ m[2][1] = -sp
+ m[2][2] = ch * cp
+ m[2][3] = 0
+ m[3][0] = 0
+ m[3][1] = 0
+ m[3][2] = 0
+ m[3][3] = 1
+ return m
}
euler_angles_xyz_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) {
- T1 := math.atan2(m[2][1], m[2][2]);
- C2 := math.sqrt(m[0][0]*m[0][0] + m[1][0]*m[1][0]);
- T2 := math.atan2(-m[2][0], C2);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(S1*m[0][2] - C1*m[0][1], C1*m[1][1] - S1*m[1][2]);
- t1 = -T1;
- t2 = -T2;
- t3 = -T3;
- return;
+ T1 := math.atan2(m[2][1], m[2][2])
+ C2 := math.sqrt(m[0][0]*m[0][0] + m[1][0]*m[1][0])
+ T2 := math.atan2(-m[2][0], C2)
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(S1*m[0][2] - C1*m[0][1], C1*m[1][1] - S1*m[1][2])
+ t1 = -T1
+ t2 = -T2
+ t3 = -T3
+ return
}
euler_angles_yxz_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) {
- T1 := math.atan2(m[2][0], m[2][2]);
- C2 := math.sqrt(m[0][1]*m[0][1] + m[1][1]*m[1][1]);
- T2 := math.atan2(-m[2][1], C2);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(S1*m[1][2] - C1*m[1][0], C1*m[0][0] - S1*m[0][2]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(m[2][0], m[2][2])
+ C2 := math.sqrt(m[0][1]*m[0][1] + m[1][1]*m[1][1])
+ T2 := math.atan2(-m[2][1], C2)
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(S1*m[1][2] - C1*m[1][0], C1*m[0][0] - S1*m[0][2])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
euler_angles_xzx_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) {
- T1 := math.atan2(m[0][2], m[0][1]);
- S2 := math.sqrt(m[1][0]*m[1][0] + m[2][0]*m[2][0]);
- T2 := math.atan2(S2, m[0][0]);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(C1*m[1][2] - S1*m[1][1], C1*m[2][2] - S1*m[2][1]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(m[0][2], m[0][1])
+ S2 := math.sqrt(m[1][0]*m[1][0] + m[2][0]*m[2][0])
+ T2 := math.atan2(S2, m[0][0])
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(C1*m[1][2] - S1*m[1][1], C1*m[2][2] - S1*m[2][1])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
euler_angles_xyx_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) {
- T1 := math.atan2(m[0][1], -m[0][2]);
- S2 := math.sqrt(m[1][0]*m[1][0] + m[2][0]*m[2][0]);
- T2 := math.atan2(S2, m[0][0]);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(-C1*m[2][1] - S1*m[2][2], C1*m[1][1] + S1*m[1][2]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(m[0][1], -m[0][2])
+ S2 := math.sqrt(m[1][0]*m[1][0] + m[2][0]*m[2][0])
+ T2 := math.atan2(S2, m[0][0])
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(-C1*m[2][1] - S1*m[2][2], C1*m[1][1] + S1*m[1][2])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
euler_angles_yxy_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) {
- T1 := math.atan2(m[1][0], m[1][2]);
- S2 := math.sqrt(m[0][1]*m[0][1] + m[2][1]*m[2][1]);
- T2 := math.atan2(S2, m[1][1]);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(C1*m[2][0] - S1*m[2][2], C1*m[0][0] - S1*m[0][2]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(m[1][0], m[1][2])
+ S2 := math.sqrt(m[0][1]*m[0][1] + m[2][1]*m[2][1])
+ T2 := math.atan2(S2, m[1][1])
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(C1*m[2][0] - S1*m[2][2], C1*m[0][0] - S1*m[0][2])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
euler_angles_yzy_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) {
- T1 := math.atan2(m[1][2], -m[1][0]);
- S2 := math.sqrt(m[0][1]*m[0][1] + m[2][1]*m[2][1]);
- T2 := math.atan2(S2, m[1][1]);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(-S1*m[0][0] - C1*m[0][2], S1*m[2][0] + C1*m[2][2]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(m[1][2], -m[1][0])
+ S2 := math.sqrt(m[0][1]*m[0][1] + m[2][1]*m[2][1])
+ T2 := math.atan2(S2, m[1][1])
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(-S1*m[0][0] - C1*m[0][2], S1*m[2][0] + C1*m[2][2])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
euler_angles_zyz_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) {
- T1 := math.atan2(m[2][1], m[2][0]);
- S2 := math.sqrt(m[0][2]*m[0][2] + m[1][2]*m[1][2]);
- T2 := math.atan2(S2, m[2][2]);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(C1*m[0][1] - S1*m[0][0], C1*m[1][1] - S1*m[1][0]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(m[2][1], m[2][0])
+ S2 := math.sqrt(m[0][2]*m[0][2] + m[1][2]*m[1][2])
+ T2 := math.atan2(S2, m[2][2])
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(C1*m[0][1] - S1*m[0][0], C1*m[1][1] - S1*m[1][0])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
euler_angles_zxz_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) {
- T1 := math.atan2(m[2][0], -m[2][1]);
- S2 := math.sqrt(m[0][2]*m[0][2] + m[1][2]*m[1][2]);
- T2 := math.atan2(S2, m[2][2]);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(-C1*m[1][0] - S1*m[1][1], C1*m[0][0] + S1*m[0][1]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(m[2][0], -m[2][1])
+ S2 := math.sqrt(m[0][2]*m[0][2] + m[1][2]*m[1][2])
+ T2 := math.atan2(S2, m[2][2])
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(-C1*m[1][0] - S1*m[1][1], C1*m[0][0] + S1*m[0][1])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
euler_angles_xzy_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) {
- T1 := math.atan2(m[1][2], m[1][1]);
- C2 := math.sqrt(m[0][0]*m[0][0] + m[2][0]*m[2][0]);
- T2 := math.atan2(-m[1][0], C2);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(S1*m[0][1] - C1*m[0][2], C1*m[2][2] - S1*m[2][1]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(m[1][2], m[1][1])
+ C2 := math.sqrt(m[0][0]*m[0][0] + m[2][0]*m[2][0])
+ T2 := math.atan2(-m[1][0], C2)
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(S1*m[0][1] - C1*m[0][2], C1*m[2][2] - S1*m[2][1])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
euler_angles_yzx_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) {
- T1 := math.atan2(-m[0][2], m[0][0]);
- C2 := math.sqrt(m[1][1]*m[1][1] + m[2][1]*m[2][1]);
- T2 := math.atan2(m[0][1], C2);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(S1*m[1][0] + C1*m[1][2], S1*m[2][0] + C1*m[2][2]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(-m[0][2], m[0][0])
+ C2 := math.sqrt(m[1][1]*m[1][1] + m[2][1]*m[2][1])
+ T2 := math.atan2(m[0][1], C2)
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(S1*m[1][0] + C1*m[1][2], S1*m[2][0] + C1*m[2][2])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
euler_angles_zyx_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) {
- T1 := math.atan2(m[0][1], m[0][0]);
- C2 := math.sqrt(m[1][2]*m[1][2] + m[2][2]*m[2][2]);
- T2 := math.atan2(-m[0][2], C2);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(S1*m[2][0] - C1*m[2][1], C1*m[1][1] - S1*m[1][0]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(m[0][1], m[0][0])
+ C2 := math.sqrt(m[1][2]*m[1][2] + m[2][2]*m[2][2])
+ T2 := math.atan2(-m[0][2], C2)
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(S1*m[2][0] - C1*m[2][1], C1*m[1][1] - S1*m[1][0])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
euler_angles_zxy_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) {
- T1 := math.atan2(-m[1][0], m[1][1]);
- C2 := math.sqrt(m[0][2]*m[0][2] + m[2][2]*m[2][2]);
- T2 := math.atan2(m[1][2], C2);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(C1*m[2][0] + S1*m[2][1], C1*m[0][0] + S1*m[0][1]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(-m[1][0], m[1][1])
+ C2 := math.sqrt(m[0][2]*m[0][2] + m[2][2]*m[2][2])
+ T2 := math.atan2(m[1][2], C2)
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(C1*m[2][0] + S1*m[2][1], C1*m[0][0] + S1*m[0][1])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
diff --git a/core/math/linalg/specific_euler_angles_f64.odin b/core/math/linalg/specific_euler_angles_f64.odin
index a62c2d5e8..efaddd651 100644
--- a/core/math/linalg/specific_euler_angles_f64.odin
+++ b/core/math/linalg/specific_euler_angles_f64.odin
@@ -4,206 +4,206 @@ import "core:math"
euler_angles_from_matrix3_f64 :: proc(m: Matrix3f64, order: Euler_Angle_Order) -> (t1, t2, t3: f64) {
switch order {
- case .XYZ: t1, t2, t3 = euler_angles_xyz_from_matrix3(m);
- case .XZY: t1, t2, t3 = euler_angles_xzy_from_matrix3(m);
- case .YXZ: t1, t2, t3 = euler_angles_yxz_from_matrix3(m);
- case .YZX: t1, t2, t3 = euler_angles_yzx_from_matrix3(m);
- case .ZXY: t1, t2, t3 = euler_angles_zxy_from_matrix3(m);
- case .ZYX: t1, t2, t3 = euler_angles_zyx_from_matrix3(m);
- case .XYX: t1, t2, t3 = euler_angles_xyx_from_matrix3(m);
- case .XZX: t1, t2, t3 = euler_angles_xzx_from_matrix3(m);
- case .YXY: t1, t2, t3 = euler_angles_yxy_from_matrix3(m);
- case .YZY: t1, t2, t3 = euler_angles_yzy_from_matrix3(m);
- case .ZXZ: t1, t2, t3 = euler_angles_zxz_from_matrix3(m);
- case .ZYZ: t1, t2, t3 = euler_angles_zyz_from_matrix3(m);
+ case .XYZ: t1, t2, t3 = euler_angles_xyz_from_matrix3(m)
+ case .XZY: t1, t2, t3 = euler_angles_xzy_from_matrix3(m)
+ case .YXZ: t1, t2, t3 = euler_angles_yxz_from_matrix3(m)
+ case .YZX: t1, t2, t3 = euler_angles_yzx_from_matrix3(m)
+ case .ZXY: t1, t2, t3 = euler_angles_zxy_from_matrix3(m)
+ case .ZYX: t1, t2, t3 = euler_angles_zyx_from_matrix3(m)
+ case .XYX: t1, t2, t3 = euler_angles_xyx_from_matrix3(m)
+ case .XZX: t1, t2, t3 = euler_angles_xzx_from_matrix3(m)
+ case .YXY: t1, t2, t3 = euler_angles_yxy_from_matrix3(m)
+ case .YZY: t1, t2, t3 = euler_angles_yzy_from_matrix3(m)
+ case .ZXZ: t1, t2, t3 = euler_angles_zxz_from_matrix3(m)
+ case .ZYZ: t1, t2, t3 = euler_angles_zyz_from_matrix3(m)
}
- return;
+ return
}
euler_angles_from_matrix4_f64 :: proc(m: Matrix4f64, order: Euler_Angle_Order) -> (t1, t2, t3: f64) {
switch order {
- case .XYZ: t1, t2, t3 = euler_angles_xyz_from_matrix4(m);
- case .XZY: t1, t2, t3 = euler_angles_xzy_from_matrix4(m);
- case .YXZ: t1, t2, t3 = euler_angles_yxz_from_matrix4(m);
- case .YZX: t1, t2, t3 = euler_angles_yzx_from_matrix4(m);
- case .ZXY: t1, t2, t3 = euler_angles_zxy_from_matrix4(m);
- case .ZYX: t1, t2, t3 = euler_angles_zyx_from_matrix4(m);
- case .XYX: t1, t2, t3 = euler_angles_xyx_from_matrix4(m);
- case .XZX: t1, t2, t3 = euler_angles_xzx_from_matrix4(m);
- case .YXY: t1, t2, t3 = euler_angles_yxy_from_matrix4(m);
- case .YZY: t1, t2, t3 = euler_angles_yzy_from_matrix4(m);
- case .ZXZ: t1, t2, t3 = euler_angles_zxz_from_matrix4(m);
- case .ZYZ: t1, t2, t3 = euler_angles_zyz_from_matrix4(m);
+ case .XYZ: t1, t2, t3 = euler_angles_xyz_from_matrix4(m)
+ case .XZY: t1, t2, t3 = euler_angles_xzy_from_matrix4(m)
+ case .YXZ: t1, t2, t3 = euler_angles_yxz_from_matrix4(m)
+ case .YZX: t1, t2, t3 = euler_angles_yzx_from_matrix4(m)
+ case .ZXY: t1, t2, t3 = euler_angles_zxy_from_matrix4(m)
+ case .ZYX: t1, t2, t3 = euler_angles_zyx_from_matrix4(m)
+ case .XYX: t1, t2, t3 = euler_angles_xyx_from_matrix4(m)
+ case .XZX: t1, t2, t3 = euler_angles_xzx_from_matrix4(m)
+ case .YXY: t1, t2, t3 = euler_angles_yxy_from_matrix4(m)
+ case .YZY: t1, t2, t3 = euler_angles_yzy_from_matrix4(m)
+ case .ZXZ: t1, t2, t3 = euler_angles_zxz_from_matrix4(m)
+ case .ZYZ: t1, t2, t3 = euler_angles_zyz_from_matrix4(m)
}
- return;
+ return
}
euler_angles_from_quaternion_f64 :: proc(m: Quaternionf64, order: Euler_Angle_Order) -> (t1, t2, t3: f64) {
switch order {
- case .XYZ: t1, t2, t3 = euler_angles_xyz_from_quaternion(m);
- case .XZY: t1, t2, t3 = euler_angles_xzy_from_quaternion(m);
- case .YXZ: t1, t2, t3 = euler_angles_yxz_from_quaternion(m);
- case .YZX: t1, t2, t3 = euler_angles_yzx_from_quaternion(m);
- case .ZXY: t1, t2, t3 = euler_angles_zxy_from_quaternion(m);
- case .ZYX: t1, t2, t3 = euler_angles_zyx_from_quaternion(m);
- case .XYX: t1, t2, t3 = euler_angles_xyx_from_quaternion(m);
- case .XZX: t1, t2, t3 = euler_angles_xzx_from_quaternion(m);
- case .YXY: t1, t2, t3 = euler_angles_yxy_from_quaternion(m);
- case .YZY: t1, t2, t3 = euler_angles_yzy_from_quaternion(m);
- case .ZXZ: t1, t2, t3 = euler_angles_zxz_from_quaternion(m);
- case .ZYZ: t1, t2, t3 = euler_angles_zyz_from_quaternion(m);
+ case .XYZ: t1, t2, t3 = euler_angles_xyz_from_quaternion(m)
+ case .XZY: t1, t2, t3 = euler_angles_xzy_from_quaternion(m)
+ case .YXZ: t1, t2, t3 = euler_angles_yxz_from_quaternion(m)
+ case .YZX: t1, t2, t3 = euler_angles_yzx_from_quaternion(m)
+ case .ZXY: t1, t2, t3 = euler_angles_zxy_from_quaternion(m)
+ case .ZYX: t1, t2, t3 = euler_angles_zyx_from_quaternion(m)
+ case .XYX: t1, t2, t3 = euler_angles_xyx_from_quaternion(m)
+ case .XZX: t1, t2, t3 = euler_angles_xzx_from_quaternion(m)
+ case .YXY: t1, t2, t3 = euler_angles_yxy_from_quaternion(m)
+ case .YZY: t1, t2, t3 = euler_angles_yzy_from_quaternion(m)
+ case .ZXZ: t1, t2, t3 = euler_angles_zxz_from_quaternion(m)
+ case .ZYZ: t1, t2, t3 = euler_angles_zyz_from_quaternion(m)
}
- return;
+ return
}
matrix3_from_euler_angles_f64 :: proc(t1, t2, t3: f64, order: Euler_Angle_Order) -> (m: Matrix3f64) {
switch order {
- case .XYZ: return matrix3_from_euler_angles_xyz(t1, t2, t3); // m1, m2, m3 = X(t1), Y(t2), Z(t3);
- case .XZY: return matrix3_from_euler_angles_xzy(t1, t2, t3); // m1, m2, m3 = X(t1), Z(t2), Y(t3);
- case .YXZ: return matrix3_from_euler_angles_yxz(t1, t2, t3); // m1, m2, m3 = Y(t1), X(t2), Z(t3);
- case .YZX: return matrix3_from_euler_angles_yzx(t1, t2, t3); // m1, m2, m3 = Y(t1), Z(t2), X(t3);
- case .ZXY: return matrix3_from_euler_angles_zxy(t1, t2, t3); // m1, m2, m3 = Z(t1), X(t2), Y(t3);
- case .ZYX: return matrix3_from_euler_angles_zyx(t1, t2, t3); // m1, m2, m3 = Z(t1), Y(t2), X(t3);
- case .XYX: return matrix3_from_euler_angles_xyx(t1, t2, t3); // m1, m2, m3 = X(t1), Y(t2), X(t3);
- case .XZX: return matrix3_from_euler_angles_xzx(t1, t2, t3); // m1, m2, m3 = X(t1), Z(t2), X(t3);
- case .YXY: return matrix3_from_euler_angles_yxy(t1, t2, t3); // m1, m2, m3 = Y(t1), X(t2), Y(t3);
- case .YZY: return matrix3_from_euler_angles_yzy(t1, t2, t3); // m1, m2, m3 = Y(t1), Z(t2), Y(t3);
- case .ZXZ: return matrix3_from_euler_angles_zxz(t1, t2, t3); // m1, m2, m3 = Z(t1), X(t2), Z(t3);
- case .ZYZ: return matrix3_from_euler_angles_zyz(t1, t2, t3); // m1, m2, m3 = Z(t1), Y(t2), Z(t3);
+ case .XYZ: return matrix3_from_euler_angles_xyz(t1, t2, t3) // m1, m2, m3 = X(t1), Y(t2), Z(t3);
+ case .XZY: return matrix3_from_euler_angles_xzy(t1, t2, t3) // m1, m2, m3 = X(t1), Z(t2), Y(t3);
+ case .YXZ: return matrix3_from_euler_angles_yxz(t1, t2, t3) // m1, m2, m3 = Y(t1), X(t2), Z(t3);
+ case .YZX: return matrix3_from_euler_angles_yzx(t1, t2, t3) // m1, m2, m3 = Y(t1), Z(t2), X(t3);
+ case .ZXY: return matrix3_from_euler_angles_zxy(t1, t2, t3) // m1, m2, m3 = Z(t1), X(t2), Y(t3);
+ case .ZYX: return matrix3_from_euler_angles_zyx(t1, t2, t3) // m1, m2, m3 = Z(t1), Y(t2), X(t3);
+ case .XYX: return matrix3_from_euler_angles_xyx(t1, t2, t3) // m1, m2, m3 = X(t1), Y(t2), X(t3);
+ case .XZX: return matrix3_from_euler_angles_xzx(t1, t2, t3) // m1, m2, m3 = X(t1), Z(t2), X(t3);
+ case .YXY: return matrix3_from_euler_angles_yxy(t1, t2, t3) // m1, m2, m3 = Y(t1), X(t2), Y(t3);
+ case .YZY: return matrix3_from_euler_angles_yzy(t1, t2, t3) // m1, m2, m3 = Y(t1), Z(t2), Y(t3);
+ case .ZXZ: return matrix3_from_euler_angles_zxz(t1, t2, t3) // m1, m2, m3 = Z(t1), X(t2), Z(t3);
+ case .ZYZ: return matrix3_from_euler_angles_zyz(t1, t2, t3) // m1, m2, m3 = Z(t1), Y(t2), Z(t3);
}
- return;
+ return
}
matrix4_from_euler_angles_f64 :: proc(t1, t2, t3: f64, order: Euler_Angle_Order) -> (m: Matrix4f64) {
switch order {
- case .XYZ: return matrix4_from_euler_angles_xyz(t1, t2, t3); // m1, m2, m3 = X(t1), Y(t2), Z(t3);
- case .XZY: return matrix4_from_euler_angles_xzy(t1, t2, t3); // m1, m2, m3 = X(t1), Z(t2), Y(t3);
- case .YXZ: return matrix4_from_euler_angles_yxz(t1, t2, t3); // m1, m2, m3 = Y(t1), X(t2), Z(t3);
- case .YZX: return matrix4_from_euler_angles_yzx(t1, t2, t3); // m1, m2, m3 = Y(t1), Z(t2), X(t3);
- case .ZXY: return matrix4_from_euler_angles_zxy(t1, t2, t3); // m1, m2, m3 = Z(t1), X(t2), Y(t3);
- case .ZYX: return matrix4_from_euler_angles_zyx(t1, t2, t3); // m1, m2, m3 = Z(t1), Y(t2), X(t3);
- case .XYX: return matrix4_from_euler_angles_xyx(t1, t2, t3); // m1, m2, m3 = X(t1), Y(t2), X(t3);
- case .XZX: return matrix4_from_euler_angles_xzx(t1, t2, t3); // m1, m2, m3 = X(t1), Z(t2), X(t3);
- case .YXY: return matrix4_from_euler_angles_yxy(t1, t2, t3); // m1, m2, m3 = Y(t1), X(t2), Y(t3);
- case .YZY: return matrix4_from_euler_angles_yzy(t1, t2, t3); // m1, m2, m3 = Y(t1), Z(t2), Y(t3);
- case .ZXZ: return matrix4_from_euler_angles_zxz(t1, t2, t3); // m1, m2, m3 = Z(t1), X(t2), Z(t3);
- case .ZYZ: return matrix4_from_euler_angles_zyz(t1, t2, t3); // m1, m2, m3 = Z(t1), Y(t2), Z(t3);
+ case .XYZ: return matrix4_from_euler_angles_xyz(t1, t2, t3) // m1, m2, m3 = X(t1), Y(t2), Z(t3);
+ case .XZY: return matrix4_from_euler_angles_xzy(t1, t2, t3) // m1, m2, m3 = X(t1), Z(t2), Y(t3);
+ case .YXZ: return matrix4_from_euler_angles_yxz(t1, t2, t3) // m1, m2, m3 = Y(t1), X(t2), Z(t3);
+ case .YZX: return matrix4_from_euler_angles_yzx(t1, t2, t3) // m1, m2, m3 = Y(t1), Z(t2), X(t3);
+ case .ZXY: return matrix4_from_euler_angles_zxy(t1, t2, t3) // m1, m2, m3 = Z(t1), X(t2), Y(t3);
+ case .ZYX: return matrix4_from_euler_angles_zyx(t1, t2, t3) // m1, m2, m3 = Z(t1), Y(t2), X(t3);
+ case .XYX: return matrix4_from_euler_angles_xyx(t1, t2, t3) // m1, m2, m3 = X(t1), Y(t2), X(t3);
+ case .XZX: return matrix4_from_euler_angles_xzx(t1, t2, t3) // m1, m2, m3 = X(t1), Z(t2), X(t3);
+ case .YXY: return matrix4_from_euler_angles_yxy(t1, t2, t3) // m1, m2, m3 = Y(t1), X(t2), Y(t3);
+ case .YZY: return matrix4_from_euler_angles_yzy(t1, t2, t3) // m1, m2, m3 = Y(t1), Z(t2), Y(t3);
+ case .ZXZ: return matrix4_from_euler_angles_zxz(t1, t2, t3) // m1, m2, m3 = Z(t1), X(t2), Z(t3);
+ case .ZYZ: return matrix4_from_euler_angles_zyz(t1, t2, t3) // m1, m2, m3 = Z(t1), Y(t2), Z(t3);
}
- return;
+ return
}
quaternion_from_euler_angles_f64 :: proc(t1, t2, t3: f64, order: Euler_Angle_Order) -> Quaternionf64 {
- X :: quaternion_from_euler_angle_x;
- Y :: quaternion_from_euler_angle_y;
- Z :: quaternion_from_euler_angle_z;
+ X :: quaternion_from_euler_angle_x
+ Y :: quaternion_from_euler_angle_y
+ Z :: quaternion_from_euler_angle_z
- q1, q2, q3: Quaternionf64;
+ q1, q2, q3: Quaternionf64
switch order {
- case .XYZ: q1, q2, q3 = X(t1), Y(t2), Z(t3);
- case .XZY: q1, q2, q3 = X(t1), Z(t2), Y(t3);
- case .YXZ: q1, q2, q3 = Y(t1), X(t2), Z(t3);
- case .YZX: q1, q2, q3 = Y(t1), Z(t2), X(t3);
- case .ZXY: q1, q2, q3 = Z(t1), X(t2), Y(t3);
- case .ZYX: q1, q2, q3 = Z(t1), Y(t2), X(t3);
- case .XYX: q1, q2, q3 = X(t1), Y(t2), X(t3);
- case .XZX: q1, q2, q3 = X(t1), Z(t2), X(t3);
- case .YXY: q1, q2, q3 = Y(t1), X(t2), Y(t3);
- case .YZY: q1, q2, q3 = Y(t1), Z(t2), Y(t3);
- case .ZXZ: q1, q2, q3 = Z(t1), X(t2), Z(t3);
- case .ZYZ: q1, q2, q3 = Z(t1), Y(t2), Z(t3);
+ case .XYZ: q1, q2, q3 = X(t1), Y(t2), Z(t3)
+ case .XZY: q1, q2, q3 = X(t1), Z(t2), Y(t3)
+ case .YXZ: q1, q2, q3 = Y(t1), X(t2), Z(t3)
+ case .YZX: q1, q2, q3 = Y(t1), Z(t2), X(t3)
+ case .ZXY: q1, q2, q3 = Z(t1), X(t2), Y(t3)
+ case .ZYX: q1, q2, q3 = Z(t1), Y(t2), X(t3)
+ case .XYX: q1, q2, q3 = X(t1), Y(t2), X(t3)
+ case .XZX: q1, q2, q3 = X(t1), Z(t2), X(t3)
+ case .YXY: q1, q2, q3 = Y(t1), X(t2), Y(t3)
+ case .YZY: q1, q2, q3 = Y(t1), Z(t2), Y(t3)
+ case .ZXZ: q1, q2, q3 = Z(t1), X(t2), Z(t3)
+ case .ZYZ: q1, q2, q3 = Z(t1), Y(t2), Z(t3)
}
- return q1 * (q2 * q3);
+ return q1 * (q2 * q3)
}
// Quaternionf64s
quaternion_from_euler_angle_x_f64 :: proc(angle_x: f64) -> (q: Quaternionf64) {
- return quaternion_angle_axis_f64(angle_x, {1, 0, 0});
+ return quaternion_angle_axis_f64(angle_x, {1, 0, 0})
}
quaternion_from_euler_angle_y_f64 :: proc(angle_y: f64) -> (q: Quaternionf64) {
- return quaternion_angle_axis_f64(angle_y, {0, 1, 0});
+ return quaternion_angle_axis_f64(angle_y, {0, 1, 0})
}
quaternion_from_euler_angle_z_f64 :: proc(angle_z: f64) -> (q: Quaternionf64) {
- return quaternion_angle_axis_f64(angle_z, {0, 0, 1});
+ return quaternion_angle_axis_f64(angle_z, {0, 0, 1})
}
quaternion_from_pitch_yaw_roll_f64 :: proc(pitch, yaw, roll: f64) -> Quaternionf64 {
- a, b, c := pitch, yaw, roll;
+ a, b, c := pitch, yaw, roll
- ca, sa := math.cos(a*0.5), math.sin(a*0.5);
- cb, sb := math.cos(b*0.5), math.sin(b*0.5);
- cc, sc := math.cos(c*0.5), math.sin(c*0.5);
+ ca, sa := math.cos(a*0.5), math.sin(a*0.5)
+ cb, sb := math.cos(b*0.5), math.sin(b*0.5)
+ cc, sc := math.cos(c*0.5), math.sin(c*0.5)
- q: Quaternionf64;
- q.x = sa*cb*cc - ca*sb*sc;
- q.y = ca*sb*cc + sa*cb*sc;
- q.z = ca*cb*sc - sa*sb*cc;
- q.w = ca*cb*cc + sa*sb*sc;
- return q;
+ q: Quaternionf64
+ q.x = sa*cb*cc - ca*sb*sc
+ q.y = ca*sb*cc + sa*cb*sc
+ q.z = ca*cb*sc - sa*sb*cc
+ q.w = ca*cb*cc + sa*sb*sc
+ return q
}
roll_from_quaternion_f64 :: proc(q: Quaternionf64) -> f64 {
- return math.atan2(2 * q.x*q.y + q.w*q.z, q.w*q.w + q.x*q.x - q.y*q.y - q.z*q.z);
+ return math.atan2(2 * q.x*q.y + q.w*q.z, q.w*q.w + q.x*q.x - q.y*q.y - q.z*q.z)
}
pitch_from_quaternion_f64 :: proc(q: Quaternionf64) -> f64 {
- y := 2 * (q.y*q.z + q.w*q.w);
- x := q.w*q.w - q.x*q.x - q.y*q.y + q.z*q.z;
+ y := 2 * (q.y*q.z + q.w*q.w)
+ x := q.w*q.w - q.x*q.x - q.y*q.y + q.z*q.z
if abs(x) <= F64_EPSILON && abs(y) <= F64_EPSILON {
- return 2 * math.atan2(q.x, q.w);
+ return 2 * math.atan2(q.x, q.w)
}
- return math.atan2(y, x);
+ return math.atan2(y, x)
}
yaw_from_quaternion_f64 :: proc(q: Quaternionf64) -> f64 {
- return math.asin(clamp(-2 * (q.x*q.z - q.w*q.y), -1, 1));
+ return math.asin(clamp(-2 * (q.x*q.z - q.w*q.y), -1, 1))
}
pitch_yaw_roll_from_quaternion_f64 :: proc(q: Quaternionf64) -> (pitch, yaw, roll: f64) {
- pitch = pitch_from_quaternion(q);
- yaw = yaw_from_quaternion(q);
- roll = roll_from_quaternion(q);
- return;
+ pitch = pitch_from_quaternion(q)
+ yaw = yaw_from_quaternion(q)
+ roll = roll_from_quaternion(q)
+ return
}
euler_angles_xyz_from_quaternion_f64 :: proc(q: Quaternionf64) -> (t1, t2, t3: f64) {
- return euler_angles_xyz_from_matrix4(matrix4_from_quaternion(q));
+ return euler_angles_xyz_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_yxz_from_quaternion_f64 :: proc(q: Quaternionf64) -> (t1, t2, t3: f64) {
- return euler_angles_yxz_from_matrix4(matrix4_from_quaternion(q));
+ return euler_angles_yxz_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_xzx_from_quaternion_f64 :: proc(q: Quaternionf64) -> (t1, t2, t3: f64) {
- return euler_angles_xzx_from_matrix4(matrix4_from_quaternion(q));
+ return euler_angles_xzx_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_xyx_from_quaternion_f64 :: proc(q: Quaternionf64) -> (t1, t2, t3: f64) {
- return euler_angles_xyx_from_matrix4(matrix4_from_quaternion(q));
+ return euler_angles_xyx_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_yxy_from_quaternion_f64 :: proc(q: Quaternionf64) -> (t1, t2, t3: f64) {
- return euler_angles_yxy_from_matrix4(matrix4_from_quaternion(q));
+ return euler_angles_yxy_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_yzy_from_quaternion_f64 :: proc(q: Quaternionf64) -> (t1, t2, t3: f64) {
- return euler_angles_yzy_from_matrix4(matrix4_from_quaternion(q));
+ return euler_angles_yzy_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_zyz_from_quaternion_f64 :: proc(q: Quaternionf64) -> (t1, t2, t3: f64) {
- return euler_angles_zyz_from_matrix4(matrix4_from_quaternion(q));
+ return euler_angles_zyz_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_zxz_from_quaternion_f64 :: proc(q: Quaternionf64) -> (t1, t2, t3: f64) {
- return euler_angles_zxz_from_matrix4(matrix4_from_quaternion(q));
+ return euler_angles_zxz_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_xzy_from_quaternion_f64 :: proc(q: Quaternionf64) -> (t1, t2, t3: f64) {
- return euler_angles_xzy_from_matrix4(matrix4_from_quaternion(q));
+ return euler_angles_xzy_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_yzx_from_quaternion_f64 :: proc(q: Quaternionf64) -> (t1, t2, t3: f64) {
- return euler_angles_yzx_from_matrix4(matrix4_from_quaternion(q));
+ return euler_angles_yzx_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_zyx_from_quaternion_f64 :: proc(q: Quaternionf64) -> (t1, t2, t3: f64) {
- return euler_angles_zyx_from_matrix4(matrix4_from_quaternion(q));
+ return euler_angles_zyx_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_zxy_from_quaternion_f64 :: proc(q: Quaternionf64) -> (t1, t2, t3: f64) {
- return euler_angles_zxy_from_matrix4(matrix4_from_quaternion(q));
+ return euler_angles_zxy_from_matrix4(matrix4_from_quaternion(q))
}
@@ -211,524 +211,524 @@ euler_angles_zxy_from_quaternion_f64 :: proc(q: Quaternionf64) -> (t1, t2, t3: f
matrix3_from_euler_angle_x_f64 :: proc(angle_x: f64) -> (m: Matrix3f64) {
- cos_x, sin_x := math.cos(angle_x), math.sin(angle_x);
- m[0][0] = 1;
- m[1][1] = +cos_x;
- m[2][1] = +sin_x;
- m[1][2] = -sin_x;
- m[2][2] = +cos_x;
- return;
+ cos_x, sin_x := math.cos(angle_x), math.sin(angle_x)
+ m[0][0] = 1
+ m[1][1] = +cos_x
+ m[2][1] = +sin_x
+ m[1][2] = -sin_x
+ m[2][2] = +cos_x
+ return
}
matrix3_from_euler_angle_y_f64 :: proc(angle_y: f64) -> (m: Matrix3f64) {
- cos_y, sin_y := math.cos(angle_y), math.sin(angle_y);
- m[0][0] = +cos_y;
- m[2][0] = -sin_y;
- m[1][1] = 1;
- m[0][2] = +sin_y;
- m[2][2] = +cos_y;
- return;
+ cos_y, sin_y := math.cos(angle_y), math.sin(angle_y)
+ m[0][0] = +cos_y
+ m[2][0] = -sin_y
+ m[1][1] = 1
+ m[0][2] = +sin_y
+ m[2][2] = +cos_y
+ return
}
matrix3_from_euler_angle_z_f64 :: proc(angle_z: f64) -> (m: Matrix3f64) {
- cos_z, sin_z := math.cos(angle_z), math.sin(angle_z);
- m[0][0] = +cos_z;
- m[1][0] = +sin_z;
- m[1][1] = +cos_z;
- m[0][1] = -sin_z;
- m[2][2] = 1;
- return;
+ cos_z, sin_z := math.cos(angle_z), math.sin(angle_z)
+ m[0][0] = +cos_z
+ m[1][0] = +sin_z
+ m[1][1] = +cos_z
+ m[0][1] = -sin_z
+ m[2][2] = 1
+ return
}
matrix3_from_derived_euler_angle_x_f64 :: proc(angle_x: f64, angular_velocity_x: f64) -> (m: Matrix3f64) {
- cos_x := math.cos(angle_x) * angular_velocity_x;
- sin_x := math.sin(angle_x) * angular_velocity_x;
- m[0][0] = 1;
- m[1][1] = +cos_x;
- m[2][1] = +sin_x;
- m[1][2] = -sin_x;
- m[2][2] = +cos_x;
- return;
+ cos_x := math.cos(angle_x) * angular_velocity_x
+ sin_x := math.sin(angle_x) * angular_velocity_x
+ m[0][0] = 1
+ m[1][1] = +cos_x
+ m[2][1] = +sin_x
+ m[1][2] = -sin_x
+ m[2][2] = +cos_x
+ return
}
matrix3_from_derived_euler_angle_y_f64 :: proc(angle_y: f64, angular_velocity_y: f64) -> (m: Matrix3f64) {
- cos_y := math.cos(angle_y) * angular_velocity_y;
- sin_y := math.sin(angle_y) * angular_velocity_y;
- m[0][0] = +cos_y;
- m[2][0] = -sin_y;
- m[1][1] = 1;
- m[0][2] = +sin_y;
- m[2][2] = +cos_y;
- return;
+ cos_y := math.cos(angle_y) * angular_velocity_y
+ sin_y := math.sin(angle_y) * angular_velocity_y
+ m[0][0] = +cos_y
+ m[2][0] = -sin_y
+ m[1][1] = 1
+ m[0][2] = +sin_y
+ m[2][2] = +cos_y
+ return
}
matrix3_from_derived_euler_angle_z_f64 :: proc(angle_z: f64, angular_velocity_z: f64) -> (m: Matrix3f64) {
- cos_z := math.cos(angle_z) * angular_velocity_z;
- sin_z := math.sin(angle_z) * angular_velocity_z;
- m[0][0] = +cos_z;
- m[1][0] = +sin_z;
- m[1][1] = +cos_z;
- m[0][1] = -sin_z;
- m[2][2] = 1;
- return;
+ cos_z := math.cos(angle_z) * angular_velocity_z
+ sin_z := math.sin(angle_z) * angular_velocity_z
+ m[0][0] = +cos_z
+ m[1][0] = +sin_z
+ m[1][1] = +cos_z
+ m[0][1] = -sin_z
+ m[2][2] = 1
+ return
}
matrix3_from_euler_angles_xy_f64 :: proc(angle_x, angle_y: f64) -> (m: Matrix3f64) {
- cos_x, sin_x := math.cos(angle_x), math.sin(angle_x);
- cos_y, sin_y := math.cos(angle_y), math.sin(angle_y);
- m[0][0] = cos_y;
- m[1][0] = -sin_x * - sin_y;
- m[2][0] = -cos_x * - sin_y;
- m[1][1] = cos_x;
- m[2][1] = sin_x;
- m[0][2] = sin_y;
- m[1][2] = -sin_x * cos_y;
- m[2][2] = cos_x * cos_y;
- return;
+ cos_x, sin_x := math.cos(angle_x), math.sin(angle_x)
+ cos_y, sin_y := math.cos(angle_y), math.sin(angle_y)
+ m[0][0] = cos_y
+ m[1][0] = -sin_x * - sin_y
+ m[2][0] = -cos_x * - sin_y
+ m[1][1] = cos_x
+ m[2][1] = sin_x
+ m[0][2] = sin_y
+ m[1][2] = -sin_x * cos_y
+ m[2][2] = cos_x * cos_y
+ return
}
matrix3_from_euler_angles_yx_f64 :: proc(angle_y, angle_x: f64) -> (m: Matrix3f64) {
- cos_x, sin_x := math.cos(angle_x), math.sin(angle_x);
- cos_y, sin_y := math.cos(angle_y), math.sin(angle_y);
- m[0][0] = cos_y;
- m[2][0] = -sin_y;
- m[0][1] = sin_y*sin_x;
- m[1][1] = cos_x;
- m[2][1] = cos_y*sin_x;
- m[0][2] = sin_y*cos_x;
- m[1][2] = -sin_x;
- m[2][2] = cos_y*cos_x;
- return;
+ cos_x, sin_x := math.cos(angle_x), math.sin(angle_x)
+ cos_y, sin_y := math.cos(angle_y), math.sin(angle_y)
+ m[0][0] = cos_y
+ m[2][0] = -sin_y
+ m[0][1] = sin_y*sin_x
+ m[1][1] = cos_x
+ m[2][1] = cos_y*sin_x
+ m[0][2] = sin_y*cos_x
+ m[1][2] = -sin_x
+ m[2][2] = cos_y*cos_x
+ return
}
matrix3_from_euler_angles_xz_f64 :: proc(angle_x, angle_z: f64) -> (m: Matrix3f64) {
- return mul(matrix3_from_euler_angle_x(angle_x), matrix3_from_euler_angle_z(angle_z));
+ return mul(matrix3_from_euler_angle_x(angle_x), matrix3_from_euler_angle_z(angle_z))
}
matrix3_from_euler_angles_zx_f64 :: proc(angle_z, angle_x: f64) -> (m: Matrix3f64) {
- return mul(matrix3_from_euler_angle_z(angle_z), matrix3_from_euler_angle_x(angle_x));
+ return mul(matrix3_from_euler_angle_z(angle_z), matrix3_from_euler_angle_x(angle_x))
}
matrix3_from_euler_angles_yz_f64 :: proc(angle_y, angle_z: f64) -> (m: Matrix3f64) {
- return mul(matrix3_from_euler_angle_y(angle_y), matrix3_from_euler_angle_z(angle_z));
+ return mul(matrix3_from_euler_angle_y(angle_y), matrix3_from_euler_angle_z(angle_z))
}
matrix3_from_euler_angles_zy_f64 :: proc(angle_z, angle_y: f64) -> (m: Matrix3f64) {
- return mul(matrix3_from_euler_angle_z(angle_z), matrix3_from_euler_angle_y(angle_y));
+ return mul(matrix3_from_euler_angle_z(angle_z), matrix3_from_euler_angle_y(angle_y))
}
matrix3_from_euler_angles_xyz_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) {
- c1 := math.cos(-t1);
- c2 := math.cos(-t2);
- c3 := math.cos(-t3);
- s1 := math.sin(-t1);
- s2 := math.sin(-t2);
- s3 := math.sin(-t3);
-
- m[0][0] = c2 * c3;
- m[0][1] =-c1 * s3 + s1 * s2 * c3;
- m[0][2] = s1 * s3 + c1 * s2 * c3;
- m[1][0] = c2 * s3;
- m[1][1] = c1 * c3 + s1 * s2 * s3;
- m[1][2] =-s1 * c3 + c1 * s2 * s3;
- m[2][0] =-s2;
- m[2][1] = s1 * c2;
- m[2][2] = c1 * c2;
- return;
+ c1 := math.cos(-t1)
+ c2 := math.cos(-t2)
+ c3 := math.cos(-t3)
+ s1 := math.sin(-t1)
+ s2 := math.sin(-t2)
+ s3 := math.sin(-t3)
+
+ m[0][0] = c2 * c3
+ m[0][1] =-c1 * s3 + s1 * s2 * c3
+ m[0][2] = s1 * s3 + c1 * s2 * c3
+ m[1][0] = c2 * s3
+ m[1][1] = c1 * c3 + s1 * s2 * s3
+ m[1][2] =-s1 * c3 + c1 * s2 * s3
+ m[2][0] =-s2
+ m[2][1] = s1 * c2
+ m[2][2] = c1 * c2
+ return
}
matrix3_from_euler_angles_yxz_f64 :: proc(yaw, pitch, roll: f64) -> (m: Matrix3f64) {
- ch := math.cos(yaw);
- sh := math.sin(yaw);
- cp := math.cos(pitch);
- sp := math.sin(pitch);
- cb := math.cos(roll);
- sb := math.sin(roll);
-
- m[0][0] = ch * cb + sh * sp * sb;
- m[0][1] = sb * cp;
- m[0][2] = -sh * cb + ch * sp * sb;
- m[1][0] = -ch * sb + sh * sp * cb;
- m[1][1] = cb * cp;
- m[1][2] = sb * sh + ch * sp * cb;
- m[2][0] = sh * cp;
- m[2][1] = -sp;
- m[2][2] = ch * cp;
- return;
+ ch := math.cos(yaw)
+ sh := math.sin(yaw)
+ cp := math.cos(pitch)
+ sp := math.sin(pitch)
+ cb := math.cos(roll)
+ sb := math.sin(roll)
+
+ m[0][0] = ch * cb + sh * sp * sb
+ m[0][1] = sb * cp
+ m[0][2] = -sh * cb + ch * sp * sb
+ m[1][0] = -ch * sb + sh * sp * cb
+ m[1][1] = cb * cp
+ m[1][2] = sb * sh + ch * sp * cb
+ m[2][0] = sh * cp
+ m[2][1] = -sp
+ m[2][2] = ch * cp
+ return
}
matrix3_from_euler_angles_xzx_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) {
- c1 := math.cos(t1);
- s1 := math.sin(t1);
- c2 := math.cos(t2);
- s2 := math.sin(t2);
- c3 := math.cos(t3);
- s3 := math.sin(t3);
-
- m[0][0] = c2;
- m[0][1] = c1 * s2;
- m[0][2] = s1 * s2;
- m[1][0] =-c3 * s2;
- m[1][1] = c1 * c2 * c3 - s1 * s3;
- m[1][2] = c1 * s3 + c2 * c3 * s1;
- m[2][0] = s2 * s3;
- m[2][1] =-c3 * s1 - c1 * c2 * s3;
- m[2][2] = c1 * c3 - c2 * s1 * s3;
- return;
+ c1 := math.cos(t1)
+ s1 := math.sin(t1)
+ c2 := math.cos(t2)
+ s2 := math.sin(t2)
+ c3 := math.cos(t3)
+ s3 := math.sin(t3)
+
+ m[0][0] = c2
+ m[0][1] = c1 * s2
+ m[0][2] = s1 * s2
+ m[1][0] =-c3 * s2
+ m[1][1] = c1 * c2 * c3 - s1 * s3
+ m[1][2] = c1 * s3 + c2 * c3 * s1
+ m[2][0] = s2 * s3
+ m[2][1] =-c3 * s1 - c1 * c2 * s3
+ m[2][2] = c1 * c3 - c2 * s1 * s3
+ return
}
matrix3_from_euler_angles_xyx_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) {
- c1 := math.cos(t1);
- s1 := math.sin(t1);
- c2 := math.cos(t2);
- s2 := math.sin(t2);
- c3 := math.cos(t3);
- s3 := math.sin(t3);
-
- m[0][0] = c2;
- m[0][1] = s1 * s2;
- m[0][2] =-c1 * s2;
- m[1][0] = s2 * s3;
- m[1][1] = c1 * c3 - c2 * s1 * s3;
- m[1][2] = c3 * s1 + c1 * c2 * s3;
- m[2][0] = c3 * s2;
- m[2][1] =-c1 * s3 - c2 * c3 * s1;
- m[2][2] = c1 * c2 * c3 - s1 * s3;
- return;
+ c1 := math.cos(t1)
+ s1 := math.sin(t1)
+ c2 := math.cos(t2)
+ s2 := math.sin(t2)
+ c3 := math.cos(t3)
+ s3 := math.sin(t3)
+
+ m[0][0] = c2
+ m[0][1] = s1 * s2
+ m[0][2] =-c1 * s2
+ m[1][0] = s2 * s3
+ m[1][1] = c1 * c3 - c2 * s1 * s3
+ m[1][2] = c3 * s1 + c1 * c2 * s3
+ m[2][0] = c3 * s2
+ m[2][1] =-c1 * s3 - c2 * c3 * s1
+ m[2][2] = c1 * c2 * c3 - s1 * s3
+ return
}
matrix3_from_euler_angles_yxy_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) {
- c1 := math.cos(t1);
- s1 := math.sin(t1);
- c2 := math.cos(t2);
- s2 := math.sin(t2);
- c3 := math.cos(t3);
- s3 := math.sin(t3);
-
- m[0][0] = c1 * c3 - c2 * s1 * s3;
- m[0][1] = s2* s3;
- m[0][2] =-c3 * s1 - c1 * c2 * s3;
- m[1][0] = s1 * s2;
- m[1][1] = c2;
- m[1][2] = c1 * s2;
- m[2][0] = c1 * s3 + c2 * c3 * s1;
- m[2][1] =-c3 * s2;
- m[2][2] = c1 * c2 * c3 - s1 * s3;
- return;
+ c1 := math.cos(t1)
+ s1 := math.sin(t1)
+ c2 := math.cos(t2)
+ s2 := math.sin(t2)
+ c3 := math.cos(t3)
+ s3 := math.sin(t3)
+
+ m[0][0] = c1 * c3 - c2 * s1 * s3
+ m[0][1] = s2* s3
+ m[0][2] =-c3 * s1 - c1 * c2 * s3
+ m[1][0] = s1 * s2
+ m[1][1] = c2
+ m[1][2] = c1 * s2
+ m[2][0] = c1 * s3 + c2 * c3 * s1
+ m[2][1] =-c3 * s2
+ m[2][2] = c1 * c2 * c3 - s1 * s3
+ return
}
matrix3_from_euler_angles_yzy_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) {
- c1 := math.cos(t1);
- s1 := math.sin(t1);
- c2 := math.cos(t2);
- s2 := math.sin(t2);
- c3 := math.cos(t3);
- s3 := math.sin(t3);
-
- m[0][0] = c1 * c2 * c3 - s1 * s3;
- m[0][1] = c3 * s2;
- m[0][2] =-c1 * s3 - c2 * c3 * s1;
- m[1][0] =-c1 * s2;
- m[1][1] = c2;
- m[1][2] = s1 * s2;
- m[2][0] = c3 * s1 + c1 * c2 * s3;
- m[2][1] = s2 * s3;
- m[2][2] = c1 * c3 - c2 * s1 * s3;
- return;
+ c1 := math.cos(t1)
+ s1 := math.sin(t1)
+ c2 := math.cos(t2)
+ s2 := math.sin(t2)
+ c3 := math.cos(t3)
+ s3 := math.sin(t3)
+
+ m[0][0] = c1 * c2 * c3 - s1 * s3
+ m[0][1] = c3 * s2
+ m[0][2] =-c1 * s3 - c2 * c3 * s1
+ m[1][0] =-c1 * s2
+ m[1][1] = c2
+ m[1][2] = s1 * s2
+ m[2][0] = c3 * s1 + c1 * c2 * s3
+ m[2][1] = s2 * s3
+ m[2][2] = c1 * c3 - c2 * s1 * s3
+ return
}
matrix3_from_euler_angles_zyz_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) {
- c1 := math.cos(t1);
- s1 := math.sin(t1);
- c2 := math.cos(t2);
- s2 := math.sin(t2);
- c3 := math.cos(t3);
- s3 := math.sin(t3);
-
- m[0][0] = c1 * c2 * c3 - s1 * s3;
- m[0][1] = c1 * s3 + c2 * c3 * s1;
- m[0][2] =-c3 * s2;
- m[1][0] =-c3 * s1 - c1 * c2 * s3;
- m[1][1] = c1 * c3 - c2 * s1 * s3;
- m[1][2] = s2 * s3;
- m[2][0] = c1 * s2;
- m[2][1] = s1 * s2;
- m[2][2] = c2;
- return;
+ c1 := math.cos(t1)
+ s1 := math.sin(t1)
+ c2 := math.cos(t2)
+ s2 := math.sin(t2)
+ c3 := math.cos(t3)
+ s3 := math.sin(t3)
+
+ m[0][0] = c1 * c2 * c3 - s1 * s3
+ m[0][1] = c1 * s3 + c2 * c3 * s1
+ m[0][2] =-c3 * s2
+ m[1][0] =-c3 * s1 - c1 * c2 * s3
+ m[1][1] = c1 * c3 - c2 * s1 * s3
+ m[1][2] = s2 * s3
+ m[2][0] = c1 * s2
+ m[2][1] = s1 * s2
+ m[2][2] = c2
+ return
}
matrix3_from_euler_angles_zxz_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) {
- c1 := math.cos(t1);
- s1 := math.sin(t1);
- c2 := math.cos(t2);
- s2 := math.sin(t2);
- c3 := math.cos(t3);
- s3 := math.sin(t3);
-
- m[0][0] = c1 * c3 - c2 * s1 * s3;
- m[0][1] = c3 * s1 + c1 * c2 * s3;
- m[0][2] = s2 *s3;
- m[1][0] =-c1 * s3 - c2 * c3 * s1;
- m[1][1] = c1 * c2 * c3 - s1 * s3;
- m[1][2] = c3 * s2;
- m[2][0] = s1 * s2;
- m[2][1] =-c1 * s2;
- m[2][2] = c2;
- return;
+ c1 := math.cos(t1)
+ s1 := math.sin(t1)
+ c2 := math.cos(t2)
+ s2 := math.sin(t2)
+ c3 := math.cos(t3)
+ s3 := math.sin(t3)
+
+ m[0][0] = c1 * c3 - c2 * s1 * s3
+ m[0][1] = c3 * s1 + c1 * c2 * s3
+ m[0][2] = s2 *s3
+ m[1][0] =-c1 * s3 - c2 * c3 * s1
+ m[1][1] = c1 * c2 * c3 - s1 * s3
+ m[1][2] = c3 * s2
+ m[2][0] = s1 * s2
+ m[2][1] =-c1 * s2
+ m[2][2] = c2
+ return
}
matrix3_from_euler_angles_xzy_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) {
- c1 := math.cos(t1);
- s1 := math.sin(t1);
- c2 := math.cos(t2);
- s2 := math.sin(t2);
- c3 := math.cos(t3);
- s3 := math.sin(t3);
-
- m[0][0] = c2 * c3;
- m[0][1] = s1 * s3 + c1 * c3 * s2;
- m[0][2] = c3 * s1 * s2 - c1 * s3;
- m[1][0] =-s2;
- m[1][1] = c1 * c2;
- m[1][2] = c2 * s1;
- m[2][0] = c2 * s3;
- m[2][1] = c1 * s2 * s3 - c3 * s1;
- m[2][2] = c1 * c3 + s1 * s2 *s3;
- return;
+ c1 := math.cos(t1)
+ s1 := math.sin(t1)
+ c2 := math.cos(t2)
+ s2 := math.sin(t2)
+ c3 := math.cos(t3)
+ s3 := math.sin(t3)
+
+ m[0][0] = c2 * c3
+ m[0][1] = s1 * s3 + c1 * c3 * s2
+ m[0][2] = c3 * s1 * s2 - c1 * s3
+ m[1][0] =-s2
+ m[1][1] = c1 * c2
+ m[1][2] = c2 * s1
+ m[2][0] = c2 * s3
+ m[2][1] = c1 * s2 * s3 - c3 * s1
+ m[2][2] = c1 * c3 + s1 * s2 *s3
+ return
}
matrix3_from_euler_angles_yzx_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) {
- c1 := math.cos(t1);
- s1 := math.sin(t1);
- c2 := math.cos(t2);
- s2 := math.sin(t2);
- c3 := math.cos(t3);
- s3 := math.sin(t3);
-
- m[0][0] = c1 * c2;
- m[0][1] = s2;
- m[0][2] =-c2 * s1;
- m[1][0] = s1 * s3 - c1 * c3 * s2;
- m[1][1] = c2 * c3;
- m[1][2] = c1 * s3 + c3 * s1 * s2;
- m[2][0] = c3 * s1 + c1 * s2 * s3;
- m[2][1] =-c2 * s3;
- m[2][2] = c1 * c3 - s1 * s2 * s3;
- return;
+ c1 := math.cos(t1)
+ s1 := math.sin(t1)
+ c2 := math.cos(t2)
+ s2 := math.sin(t2)
+ c3 := math.cos(t3)
+ s3 := math.sin(t3)
+
+ m[0][0] = c1 * c2
+ m[0][1] = s2
+ m[0][2] =-c2 * s1
+ m[1][0] = s1 * s3 - c1 * c3 * s2
+ m[1][1] = c2 * c3
+ m[1][2] = c1 * s3 + c3 * s1 * s2
+ m[2][0] = c3 * s1 + c1 * s2 * s3
+ m[2][1] =-c2 * s3
+ m[2][2] = c1 * c3 - s1 * s2 * s3
+ return
}
matrix3_from_euler_angles_zyx_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) {
- c1 := math.cos(t1);
- s1 := math.sin(t1);
- c2 := math.cos(t2);
- s2 := math.sin(t2);
- c3 := math.cos(t3);
- s3 := math.sin(t3);
-
- m[0][0] = c1 * c2;
- m[0][1] = c2 * s1;
- m[0][2] =-s2;
- m[1][0] = c1 * s2 * s3 - c3 * s1;
- m[1][1] = c1 * c3 + s1 * s2 * s3;
- m[1][2] = c2 * s3;
- m[2][0] = s1 * s3 + c1 * c3 * s2;
- m[2][1] = c3 * s1 * s2 - c1 * s3;
- m[2][2] = c2 * c3;
- return;
+ c1 := math.cos(t1)
+ s1 := math.sin(t1)
+ c2 := math.cos(t2)
+ s2 := math.sin(t2)
+ c3 := math.cos(t3)
+ s3 := math.sin(t3)
+
+ m[0][0] = c1 * c2
+ m[0][1] = c2 * s1
+ m[0][2] =-s2
+ m[1][0] = c1 * s2 * s3 - c3 * s1
+ m[1][1] = c1 * c3 + s1 * s2 * s3
+ m[1][2] = c2 * s3
+ m[2][0] = s1 * s3 + c1 * c3 * s2
+ m[2][1] = c3 * s1 * s2 - c1 * s3
+ m[2][2] = c2 * c3
+ return
}
matrix3_from_euler_angles_zxy_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) {
- c1 := math.cos(t1);
- s1 := math.sin(t1);
- c2 := math.cos(t2);
- s2 := math.sin(t2);
- c3 := math.cos(t3);
- s3 := math.sin(t3);
-
- m[0][0] = c1 * c3 - s1 * s2 * s3;
- m[0][1] = c3 * s1 + c1 * s2 * s3;
- m[0][2] =-c2 * s3;
- m[1][0] =-c2 * s1;
- m[1][1] = c1 * c2;
- m[1][2] = s2;
- m[2][0] = c1 * s3 + c3 * s1 * s2;
- m[2][1] = s1 * s3 - c1 * c3 * s2;
- m[2][2] = c2 * c3;
- return;
+ c1 := math.cos(t1)
+ s1 := math.sin(t1)
+ c2 := math.cos(t2)
+ s2 := math.sin(t2)
+ c3 := math.cos(t3)
+ s3 := math.sin(t3)
+
+ m[0][0] = c1 * c3 - s1 * s2 * s3
+ m[0][1] = c3 * s1 + c1 * s2 * s3
+ m[0][2] =-c2 * s3
+ m[1][0] =-c2 * s1
+ m[1][1] = c1 * c2
+ m[1][2] = s2
+ m[2][0] = c1 * s3 + c3 * s1 * s2
+ m[2][1] = s1 * s3 - c1 * c3 * s2
+ m[2][2] = c2 * c3
+ return
}
matrix3_from_yaw_pitch_roll_f64 :: proc(yaw, pitch, roll: f64) -> (m: Matrix3f64) {
- ch := math.cos(yaw);
- sh := math.sin(yaw);
- cp := math.cos(pitch);
- sp := math.sin(pitch);
- cb := math.cos(roll);
- sb := math.sin(roll);
-
- m[0][0] = ch * cb + sh * sp * sb;
- m[0][1] = sb * cp;
- m[0][2] = -sh * cb + ch * sp * sb;
- m[1][0] = -ch * sb + sh * sp * cb;
- m[1][1] = cb * cp;
- m[1][2] = sb * sh + ch * sp * cb;
- m[2][0] = sh * cp;
- m[2][1] = -sp;
- m[2][2] = ch * cp;
- return m;
+ ch := math.cos(yaw)
+ sh := math.sin(yaw)
+ cp := math.cos(pitch)
+ sp := math.sin(pitch)
+ cb := math.cos(roll)
+ sb := math.sin(roll)
+
+ m[0][0] = ch * cb + sh * sp * sb
+ m[0][1] = sb * cp
+ m[0][2] = -sh * cb + ch * sp * sb
+ m[1][0] = -ch * sb + sh * sp * cb
+ m[1][1] = cb * cp
+ m[1][2] = sb * sh + ch * sp * cb
+ m[2][0] = sh * cp
+ m[2][1] = -sp
+ m[2][2] = ch * cp
+ return m
}
euler_angles_xyz_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) {
- T1 := math.atan2(m[2][1], m[2][2]);
- C2 := math.sqrt(m[0][0]*m[0][0] + m[1][0]*m[1][0]);
- T2 := math.atan2(-m[2][0], C2);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(S1*m[0][2] - C1*m[0][1], C1*m[1][1] - S1*m[1][2]);
- t1 = -T1;
- t2 = -T2;
- t3 = -T3;
- return;
+ T1 := math.atan2(m[2][1], m[2][2])
+ C2 := math.sqrt(m[0][0]*m[0][0] + m[1][0]*m[1][0])
+ T2 := math.atan2(-m[2][0], C2)
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(S1*m[0][2] - C1*m[0][1], C1*m[1][1] - S1*m[1][2])
+ t1 = -T1
+ t2 = -T2
+ t3 = -T3
+ return
}
euler_angles_yxz_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) {
- T1 := math.atan2(m[2][0], m[2][2]);
- C2 := math.sqrt(m[0][1]*m[0][1] + m[1][1]*m[1][1]);
- T2 := math.atan2(-m[2][1], C2);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(S1*m[1][2] - C1*m[1][0], C1*m[0][0] - S1*m[0][2]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(m[2][0], m[2][2])
+ C2 := math.sqrt(m[0][1]*m[0][1] + m[1][1]*m[1][1])
+ T2 := math.atan2(-m[2][1], C2)
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(S1*m[1][2] - C1*m[1][0], C1*m[0][0] - S1*m[0][2])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
euler_angles_xzx_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) {
- T1 := math.atan2(m[0][2], m[0][1]);
- S2 := math.sqrt(m[1][0]*m[1][0] + m[2][0]*m[2][0]);
- T2 := math.atan2(S2, m[0][0]);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(C1*m[1][2] - S1*m[1][1], C1*m[2][2] - S1*m[2][1]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(m[0][2], m[0][1])
+ S2 := math.sqrt(m[1][0]*m[1][0] + m[2][0]*m[2][0])
+ T2 := math.atan2(S2, m[0][0])
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(C1*m[1][2] - S1*m[1][1], C1*m[2][2] - S1*m[2][1])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
euler_angles_xyx_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) {
- T1 := math.atan2(m[0][1], -m[0][2]);
- S2 := math.sqrt(m[1][0]*m[1][0] + m[2][0]*m[2][0]);
- T2 := math.atan2(S2, m[0][0]);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(-C1*m[2][1] - S1*m[2][2], C1*m[1][1] + S1*m[1][2]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(m[0][1], -m[0][2])
+ S2 := math.sqrt(m[1][0]*m[1][0] + m[2][0]*m[2][0])
+ T2 := math.atan2(S2, m[0][0])
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(-C1*m[2][1] - S1*m[2][2], C1*m[1][1] + S1*m[1][2])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
euler_angles_yxy_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) {
- T1 := math.atan2(m[1][0], m[1][2]);
- S2 := math.sqrt(m[0][1]*m[0][1] + m[2][1]*m[2][1]);
- T2 := math.atan2(S2, m[1][1]);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(C1*m[2][0] - S1*m[2][2], C1*m[0][0] - S1*m[0][2]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(m[1][0], m[1][2])
+ S2 := math.sqrt(m[0][1]*m[0][1] + m[2][1]*m[2][1])
+ T2 := math.atan2(S2, m[1][1])
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(C1*m[2][0] - S1*m[2][2], C1*m[0][0] - S1*m[0][2])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
euler_angles_yzy_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) {
- T1 := math.atan2(m[1][2], -m[1][0]);
- S2 := math.sqrt(m[0][1]*m[0][1] + m[2][1]*m[2][1]);
- T2 := math.atan2(S2, m[1][1]);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(-S1*m[0][0] - C1*m[0][2], S1*m[2][0] + C1*m[2][2]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(m[1][2], -m[1][0])
+ S2 := math.sqrt(m[0][1]*m[0][1] + m[2][1]*m[2][1])
+ T2 := math.atan2(S2, m[1][1])
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(-S1*m[0][0] - C1*m[0][2], S1*m[2][0] + C1*m[2][2])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
euler_angles_zyz_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) {
- T1 := math.atan2(m[2][1], m[2][0]);
- S2 := math.sqrt(m[0][2]*m[0][2] + m[1][2]*m[1][2]);
- T2 := math.atan2(S2, m[2][2]);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(C1*m[0][1] - S1*m[0][0], C1*m[1][1] - S1*m[1][0]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(m[2][1], m[2][0])
+ S2 := math.sqrt(m[0][2]*m[0][2] + m[1][2]*m[1][2])
+ T2 := math.atan2(S2, m[2][2])
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(C1*m[0][1] - S1*m[0][0], C1*m[1][1] - S1*m[1][0])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
euler_angles_zxz_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) {
- T1 := math.atan2(m[2][0], -m[2][1]);
- S2 := math.sqrt(m[0][2]*m[0][2] + m[1][2]*m[1][2]);
- T2 := math.atan2(S2, m[2][2]);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(-C1*m[1][0] - S1*m[1][1], C1*m[0][0] + S1*m[0][1]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(m[2][0], -m[2][1])
+ S2 := math.sqrt(m[0][2]*m[0][2] + m[1][2]*m[1][2])
+ T2 := math.atan2(S2, m[2][2])
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(-C1*m[1][0] - S1*m[1][1], C1*m[0][0] + S1*m[0][1])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
euler_angles_xzy_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) {
- T1 := math.atan2(m[1][2], m[1][1]);
- C2 := math.sqrt(m[0][0]*m[0][0] + m[2][0]*m[2][0]);
- T2 := math.atan2(-m[1][0], C2);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(S1*m[0][1] - C1*m[0][2], C1*m[2][2] - S1*m[2][1]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(m[1][2], m[1][1])
+ C2 := math.sqrt(m[0][0]*m[0][0] + m[2][0]*m[2][0])
+ T2 := math.atan2(-m[1][0], C2)
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(S1*m[0][1] - C1*m[0][2], C1*m[2][2] - S1*m[2][1])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
euler_angles_yzx_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) {
- T1 := math.atan2(-m[0][2], m[0][0]);
- C2 := math.sqrt(m[1][1]*m[1][1] + m[2][1]*m[2][1]);
- T2 := math.atan2(m[0][1], C2);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(S1*m[1][0] + C1*m[1][2], S1*m[2][0] + C1*m[2][2]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(-m[0][2], m[0][0])
+ C2 := math.sqrt(m[1][1]*m[1][1] + m[2][1]*m[2][1])
+ T2 := math.atan2(m[0][1], C2)
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(S1*m[1][0] + C1*m[1][2], S1*m[2][0] + C1*m[2][2])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
euler_angles_zyx_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) {
- T1 := math.atan2(m[0][1], m[0][0]);
- C2 := math.sqrt(m[1][2]*m[1][2] + m[2][2]*m[2][2]);
- T2 := math.atan2(-m[0][2], C2);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(S1*m[2][0] - C1*m[2][1], C1*m[1][1] - S1*m[1][0]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(m[0][1], m[0][0])
+ C2 := math.sqrt(m[1][2]*m[1][2] + m[2][2]*m[2][2])
+ T2 := math.atan2(-m[0][2], C2)
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(S1*m[2][0] - C1*m[2][1], C1*m[1][1] - S1*m[1][0])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
euler_angles_zxy_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) {
- T1 := math.atan2(-m[1][0], m[1][1]);
- C2 := math.sqrt(m[0][2]*m[0][2] + m[2][2]*m[2][2]);
- T2 := math.atan2(m[1][2], C2);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(C1*m[2][0] + S1*m[2][1], C1*m[0][0] + S1*m[0][1]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(-m[1][0], m[1][1])
+ C2 := math.sqrt(m[0][2]*m[0][2] + m[2][2]*m[2][2])
+ T2 := math.atan2(m[1][2], C2)
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(C1*m[2][0] + S1*m[2][1], C1*m[0][0] + S1*m[0][1])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
@@ -736,621 +736,621 @@ euler_angles_zxy_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) {
matrix4_from_euler_angle_x_f64 :: proc(angle_x: f64) -> (m: Matrix4f64) {
- cos_x, sin_x := math.cos(angle_x), math.sin(angle_x);
- m[0][0] = 1;
- m[1][1] = +cos_x;
- m[2][1] = +sin_x;
- m[1][2] = -sin_x;
- m[2][2] = +cos_x;
- m[3][3] = 1;
- return;
+ cos_x, sin_x := math.cos(angle_x), math.sin(angle_x)
+ m[0][0] = 1
+ m[1][1] = +cos_x
+ m[2][1] = +sin_x
+ m[1][2] = -sin_x
+ m[2][2] = +cos_x
+ m[3][3] = 1
+ return
}
matrix4_from_euler_angle_y_f64 :: proc(angle_y: f64) -> (m: Matrix4f64) {
- cos_y, sin_y := math.cos(angle_y), math.sin(angle_y);
- m[0][0] = +cos_y;
- m[2][0] = -sin_y;
- m[1][1] = 1;
- m[0][2] = +sin_y;
- m[2][2] = +cos_y;
- m[3][3] = 1;
- return;
+ cos_y, sin_y := math.cos(angle_y), math.sin(angle_y)
+ m[0][0] = +cos_y
+ m[2][0] = -sin_y
+ m[1][1] = 1
+ m[0][2] = +sin_y
+ m[2][2] = +cos_y
+ m[3][3] = 1
+ return
}
matrix4_from_euler_angle_z_f64 :: proc(angle_z: f64) -> (m: Matrix4f64) {
- cos_z, sin_z := math.cos(angle_z), math.sin(angle_z);
- m[0][0] = +cos_z;
- m[1][0] = +sin_z;
- m[1][1] = +cos_z;
- m[0][1] = -sin_z;
- m[2][2] = 1;
- m[3][3] = 1;
- return;
+ cos_z, sin_z := math.cos(angle_z), math.sin(angle_z)
+ m[0][0] = +cos_z
+ m[1][0] = +sin_z
+ m[1][1] = +cos_z
+ m[0][1] = -sin_z
+ m[2][2] = 1
+ m[3][3] = 1
+ return
}
matrix4_from_derived_euler_angle_x_f64 :: proc(angle_x: f64, angular_velocity_x: f64) -> (m: Matrix4f64) {
- cos_x := math.cos(angle_x) * angular_velocity_x;
- sin_x := math.sin(angle_x) * angular_velocity_x;
- m[0][0] = 1;
- m[1][1] = +cos_x;
- m[2][1] = +sin_x;
- m[1][2] = -sin_x;
- m[2][2] = +cos_x;
- m[3][3] = 1;
- return;
+ cos_x := math.cos(angle_x) * angular_velocity_x
+ sin_x := math.sin(angle_x) * angular_velocity_x
+ m[0][0] = 1
+ m[1][1] = +cos_x
+ m[2][1] = +sin_x
+ m[1][2] = -sin_x
+ m[2][2] = +cos_x
+ m[3][3] = 1
+ return
}
matrix4_from_derived_euler_angle_y_f64 :: proc(angle_y: f64, angular_velocity_y: f64) -> (m: Matrix4f64) {
- cos_y := math.cos(angle_y) * angular_velocity_y;
- sin_y := math.sin(angle_y) * angular_velocity_y;
- m[0][0] = +cos_y;
- m[2][0] = -sin_y;
- m[1][1] = 1;
- m[0][2] = +sin_y;
- m[2][2] = +cos_y;
- m[3][3] = 1;
- return;
+ cos_y := math.cos(angle_y) * angular_velocity_y
+ sin_y := math.sin(angle_y) * angular_velocity_y
+ m[0][0] = +cos_y
+ m[2][0] = -sin_y
+ m[1][1] = 1
+ m[0][2] = +sin_y
+ m[2][2] = +cos_y
+ m[3][3] = 1
+ return
}
matrix4_from_derived_euler_angle_z_f64 :: proc(angle_z: f64, angular_velocity_z: f64) -> (m: Matrix4f64) {
- cos_z := math.cos(angle_z) * angular_velocity_z;
- sin_z := math.sin(angle_z) * angular_velocity_z;
- m[0][0] = +cos_z;
- m[1][0] = +sin_z;
- m[1][1] = +cos_z;
- m[0][1] = -sin_z;
- m[2][2] = 1;
- m[3][3] = 1;
- return;
+ cos_z := math.cos(angle_z) * angular_velocity_z
+ sin_z := math.sin(angle_z) * angular_velocity_z
+ m[0][0] = +cos_z
+ m[1][0] = +sin_z
+ m[1][1] = +cos_z
+ m[0][1] = -sin_z
+ m[2][2] = 1
+ m[3][3] = 1
+ return
}
matrix4_from_euler_angles_xy_f64 :: proc(angle_x, angle_y: f64) -> (m: Matrix4f64) {
- cos_x, sin_x := math.cos(angle_x), math.sin(angle_x);
- cos_y, sin_y := math.cos(angle_y), math.sin(angle_y);
- m[0][0] = cos_y;
- m[1][0] = -sin_x * - sin_y;
- m[2][0] = -cos_x * - sin_y;
- m[1][1] = cos_x;
- m[2][1] = sin_x;
- m[0][2] = sin_y;
- m[1][2] = -sin_x * cos_y;
- m[2][2] = cos_x * cos_y;
- m[3][3] = 1;
- return;
+ cos_x, sin_x := math.cos(angle_x), math.sin(angle_x)
+ cos_y, sin_y := math.cos(angle_y), math.sin(angle_y)
+ m[0][0] = cos_y
+ m[1][0] = -sin_x * - sin_y
+ m[2][0] = -cos_x * - sin_y
+ m[1][1] = cos_x
+ m[2][1] = sin_x
+ m[0][2] = sin_y
+ m[1][2] = -sin_x * cos_y
+ m[2][2] = cos_x * cos_y
+ m[3][3] = 1
+ return
}
matrix4_from_euler_angles_yx_f64 :: proc(angle_y, angle_x: f64) -> (m: Matrix4f64) {
- cos_x, sin_x := math.cos(angle_x), math.sin(angle_x);
- cos_y, sin_y := math.cos(angle_y), math.sin(angle_y);
- m[0][0] = cos_y;
- m[2][0] = -sin_y;
- m[0][1] = sin_y*sin_x;
- m[1][1] = cos_x;
- m[2][1] = cos_y*sin_x;
- m[0][2] = sin_y*cos_x;
- m[1][2] = -sin_x;
- m[2][2] = cos_y*cos_x;
- m[3][3] = 1;
- return;
+ cos_x, sin_x := math.cos(angle_x), math.sin(angle_x)
+ cos_y, sin_y := math.cos(angle_y), math.sin(angle_y)
+ m[0][0] = cos_y
+ m[2][0] = -sin_y
+ m[0][1] = sin_y*sin_x
+ m[1][1] = cos_x
+ m[2][1] = cos_y*sin_x
+ m[0][2] = sin_y*cos_x
+ m[1][2] = -sin_x
+ m[2][2] = cos_y*cos_x
+ m[3][3] = 1
+ return
}
matrix4_from_euler_angles_xz_f64 :: proc(angle_x, angle_z: f64) -> (m: Matrix4f64) {
- return mul(matrix4_from_euler_angle_x(angle_x), matrix4_from_euler_angle_z(angle_z));
+ return mul(matrix4_from_euler_angle_x(angle_x), matrix4_from_euler_angle_z(angle_z))
}
matrix4_from_euler_angles_zx_f64 :: proc(angle_z, angle_x: f64) -> (m: Matrix4f64) {
- return mul(matrix4_from_euler_angle_z(angle_z), matrix4_from_euler_angle_x(angle_x));
+ return mul(matrix4_from_euler_angle_z(angle_z), matrix4_from_euler_angle_x(angle_x))
}
matrix4_from_euler_angles_yz_f64 :: proc(angle_y, angle_z: f64) -> (m: Matrix4f64) {
- return mul(matrix4_from_euler_angle_y(angle_y), matrix4_from_euler_angle_z(angle_z));
+ return mul(matrix4_from_euler_angle_y(angle_y), matrix4_from_euler_angle_z(angle_z))
}
matrix4_from_euler_angles_zy_f64 :: proc(angle_z, angle_y: f64) -> (m: Matrix4f64) {
- return mul(matrix4_from_euler_angle_z(angle_z), matrix4_from_euler_angle_y(angle_y));
+ return mul(matrix4_from_euler_angle_z(angle_z), matrix4_from_euler_angle_y(angle_y))
}
matrix4_from_euler_angles_xyz_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) {
- c1 := math.cos(-t1);
- c2 := math.cos(-t2);
- c3 := math.cos(-t3);
- s1 := math.sin(-t1);
- s2 := math.sin(-t2);
- s3 := math.sin(-t3);
-
- m[0][0] = c2 * c3;
- m[0][1] =-c1 * s3 + s1 * s2 * c3;
- m[0][2] = s1 * s3 + c1 * s2 * c3;
- m[0][3] = 0;
- m[1][0] = c2 * s3;
- m[1][1] = c1 * c3 + s1 * s2 * s3;
- m[1][2] =-s1 * c3 + c1 * s2 * s3;
- m[1][3] = 0;
- m[2][0] =-s2;
- m[2][1] = s1 * c2;
- m[2][2] = c1 * c2;
- m[2][3] = 0;
- m[3][0] = 0;
- m[3][1] = 0;
- m[3][2] = 0;
- m[3][3] = 1;
- return;
+ c1 := math.cos(-t1)
+ c2 := math.cos(-t2)
+ c3 := math.cos(-t3)
+ s1 := math.sin(-t1)
+ s2 := math.sin(-t2)
+ s3 := math.sin(-t3)
+
+ m[0][0] = c2 * c3
+ m[0][1] =-c1 * s3 + s1 * s2 * c3
+ m[0][2] = s1 * s3 + c1 * s2 * c3
+ m[0][3] = 0
+ m[1][0] = c2 * s3
+ m[1][1] = c1 * c3 + s1 * s2 * s3
+ m[1][2] =-s1 * c3 + c1 * s2 * s3
+ m[1][3] = 0
+ m[2][0] =-s2
+ m[2][1] = s1 * c2
+ m[2][2] = c1 * c2
+ m[2][3] = 0
+ m[3][0] = 0
+ m[3][1] = 0
+ m[3][2] = 0
+ m[3][3] = 1
+ return
}
matrix4_from_euler_angles_yxz_f64 :: proc(yaw, pitch, roll: f64) -> (m: Matrix4f64) {
- ch := math.cos(yaw);
- sh := math.sin(yaw);
- cp := math.cos(pitch);
- sp := math.sin(pitch);
- cb := math.cos(roll);
- sb := math.sin(roll);
-
- m[0][0] = ch * cb + sh * sp * sb;
- m[0][1] = sb * cp;
- m[0][2] = -sh * cb + ch * sp * sb;
- m[0][3] = 0;
- m[1][0] = -ch * sb + sh * sp * cb;
- m[1][1] = cb * cp;
- m[1][2] = sb * sh + ch * sp * cb;
- m[1][3] = 0;
- m[2][0] = sh * cp;
- m[2][1] = -sp;
- m[2][2] = ch * cp;
- m[2][3] = 0;
- m[3][0] = 0;
- m[3][1] = 0;
- m[3][2] = 0;
- m[3][3] = 1;
- return;
+ ch := math.cos(yaw)
+ sh := math.sin(yaw)
+ cp := math.cos(pitch)
+ sp := math.sin(pitch)
+ cb := math.cos(roll)
+ sb := math.sin(roll)
+
+ m[0][0] = ch * cb + sh * sp * sb
+ m[0][1] = sb * cp
+ m[0][2] = -sh * cb + ch * sp * sb
+ m[0][3] = 0
+ m[1][0] = -ch * sb + sh * sp * cb
+ m[1][1] = cb * cp
+ m[1][2] = sb * sh + ch * sp * cb
+ m[1][3] = 0
+ m[2][0] = sh * cp
+ m[2][1] = -sp
+ m[2][2] = ch * cp
+ m[2][3] = 0
+ m[3][0] = 0
+ m[3][1] = 0
+ m[3][2] = 0
+ m[3][3] = 1
+ return
}
matrix4_from_euler_angles_xzx_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) {
- c1 := math.cos(t1);
- s1 := math.sin(t1);
- c2 := math.cos(t2);
- s2 := math.sin(t2);
- c3 := math.cos(t3);
- s3 := math.sin(t3);
-
- m[0][0] = c2;
- m[0][1] = c1 * s2;
- m[0][2] = s1 * s2;
- m[0][3] = 0;
- m[1][0] =-c3 * s2;
- m[1][1] = c1 * c2 * c3 - s1 * s3;
- m[1][2] = c1 * s3 + c2 * c3 * s1;
- m[1][3] = 0;
- m[2][0] = s2 * s3;
- m[2][1] =-c3 * s1 - c1 * c2 * s3;
- m[2][2] = c1 * c3 - c2 * s1 * s3;
- m[2][3] = 0;
- m[3][0] = 0;
- m[3][1] = 0;
- m[3][2] = 0;
- m[3][3] = 1;
- return;
+ c1 := math.cos(t1)
+ s1 := math.sin(t1)
+ c2 := math.cos(t2)
+ s2 := math.sin(t2)
+ c3 := math.cos(t3)
+ s3 := math.sin(t3)
+
+ m[0][0] = c2
+ m[0][1] = c1 * s2
+ m[0][2] = s1 * s2
+ m[0][3] = 0
+ m[1][0] =-c3 * s2
+ m[1][1] = c1 * c2 * c3 - s1 * s3
+ m[1][2] = c1 * s3 + c2 * c3 * s1
+ m[1][3] = 0
+ m[2][0] = s2 * s3
+ m[2][1] =-c3 * s1 - c1 * c2 * s3
+ m[2][2] = c1 * c3 - c2 * s1 * s3
+ m[2][3] = 0
+ m[3][0] = 0
+ m[3][1] = 0
+ m[3][2] = 0
+ m[3][3] = 1
+ return
}
matrix4_from_euler_angles_xyx_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) {
- c1 := math.cos(t1);
- s1 := math.sin(t1);
- c2 := math.cos(t2);
- s2 := math.sin(t2);
- c3 := math.cos(t3);
- s3 := math.sin(t3);
-
- m[0][0] = c2;
- m[0][1] = s1 * s2;
- m[0][2] =-c1 * s2;
- m[0][3] = 0;
- m[1][0] = s2 * s3;
- m[1][1] = c1 * c3 - c2 * s1 * s3;
- m[1][2] = c3 * s1 + c1 * c2 * s3;
- m[1][3] = 0;
- m[2][0] = c3 * s2;
- m[2][1] =-c1 * s3 - c2 * c3 * s1;
- m[2][2] = c1 * c2 * c3 - s1 * s3;
- m[2][3] = 0;
- m[3][0] = 0;
- m[3][1] = 0;
- m[3][2] = 0;
- m[3][3] = 1;
- return;
+ c1 := math.cos(t1)
+ s1 := math.sin(t1)
+ c2 := math.cos(t2)
+ s2 := math.sin(t2)
+ c3 := math.cos(t3)
+ s3 := math.sin(t3)
+
+ m[0][0] = c2
+ m[0][1] = s1 * s2
+ m[0][2] =-c1 * s2
+ m[0][3] = 0
+ m[1][0] = s2 * s3
+ m[1][1] = c1 * c3 - c2 * s1 * s3
+ m[1][2] = c3 * s1 + c1 * c2 * s3
+ m[1][3] = 0
+ m[2][0] = c3 * s2
+ m[2][1] =-c1 * s3 - c2 * c3 * s1
+ m[2][2] = c1 * c2 * c3 - s1 * s3
+ m[2][3] = 0
+ m[3][0] = 0
+ m[3][1] = 0
+ m[3][2] = 0
+ m[3][3] = 1
+ return
}
matrix4_from_euler_angles_yxy_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) {
- c1 := math.cos(t1);
- s1 := math.sin(t1);
- c2 := math.cos(t2);
- s2 := math.sin(t2);
- c3 := math.cos(t3);
- s3 := math.sin(t3);
-
- m[0][0] = c1 * c3 - c2 * s1 * s3;
- m[0][1] = s2* s3;
- m[0][2] =-c3 * s1 - c1 * c2 * s3;
- m[0][3] = 0;
- m[1][0] = s1 * s2;
- m[1][1] = c2;
- m[1][2] = c1 * s2;
- m[1][3] = 0;
- m[2][0] = c1 * s3 + c2 * c3 * s1;
- m[2][1] =-c3 * s2;
- m[2][2] = c1 * c2 * c3 - s1 * s3;
- m[2][3] = 0;
- m[3][0] = 0;
- m[3][1] = 0;
- m[3][2] = 0;
- m[3][3] = 1;
- return;
+ c1 := math.cos(t1)
+ s1 := math.sin(t1)
+ c2 := math.cos(t2)
+ s2 := math.sin(t2)
+ c3 := math.cos(t3)
+ s3 := math.sin(t3)
+
+ m[0][0] = c1 * c3 - c2 * s1 * s3
+ m[0][1] = s2* s3
+ m[0][2] =-c3 * s1 - c1 * c2 * s3
+ m[0][3] = 0
+ m[1][0] = s1 * s2
+ m[1][1] = c2
+ m[1][2] = c1 * s2
+ m[1][3] = 0
+ m[2][0] = c1 * s3 + c2 * c3 * s1
+ m[2][1] =-c3 * s2
+ m[2][2] = c1 * c2 * c3 - s1 * s3
+ m[2][3] = 0
+ m[3][0] = 0
+ m[3][1] = 0
+ m[3][2] = 0
+ m[3][3] = 1
+ return
}
matrix4_from_euler_angles_yzy_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) {
- c1 := math.cos(t1);
- s1 := math.sin(t1);
- c2 := math.cos(t2);
- s2 := math.sin(t2);
- c3 := math.cos(t3);
- s3 := math.sin(t3);
-
- m[0][0] = c1 * c2 * c3 - s1 * s3;
- m[0][1] = c3 * s2;
- m[0][2] =-c1 * s3 - c2 * c3 * s1;
- m[0][3] = 0;
- m[1][0] =-c1 * s2;
- m[1][1] = c2;
- m[1][2] = s1 * s2;
- m[1][3] = 0;
- m[2][0] = c3 * s1 + c1 * c2 * s3;
- m[2][1] = s2 * s3;
- m[2][2] = c1 * c3 - c2 * s1 * s3;
- m[2][3] = 0;
- m[3][0] = 0;
- m[3][1] = 0;
- m[3][2] = 0;
- m[3][3] = 1;
- return;
+ c1 := math.cos(t1)
+ s1 := math.sin(t1)
+ c2 := math.cos(t2)
+ s2 := math.sin(t2)
+ c3 := math.cos(t3)
+ s3 := math.sin(t3)
+
+ m[0][0] = c1 * c2 * c3 - s1 * s3
+ m[0][1] = c3 * s2
+ m[0][2] =-c1 * s3 - c2 * c3 * s1
+ m[0][3] = 0
+ m[1][0] =-c1 * s2
+ m[1][1] = c2
+ m[1][2] = s1 * s2
+ m[1][3] = 0
+ m[2][0] = c3 * s1 + c1 * c2 * s3
+ m[2][1] = s2 * s3
+ m[2][2] = c1 * c3 - c2 * s1 * s3
+ m[2][3] = 0
+ m[3][0] = 0
+ m[3][1] = 0
+ m[3][2] = 0
+ m[3][3] = 1
+ return
}
matrix4_from_euler_angles_zyz_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) {
- c1 := math.cos(t1);
- s1 := math.sin(t1);
- c2 := math.cos(t2);
- s2 := math.sin(t2);
- c3 := math.cos(t3);
- s3 := math.sin(t3);
-
- m[0][0] = c1 * c2 * c3 - s1 * s3;
- m[0][1] = c1 * s3 + c2 * c3 * s1;
- m[0][2] =-c3 * s2;
- m[0][3] = 0;
- m[1][0] =-c3 * s1 - c1 * c2 * s3;
- m[1][1] = c1 * c3 - c2 * s1 * s3;
- m[1][2] = s2 * s3;
- m[1][3] = 0;
- m[2][0] = c1 * s2;
- m[2][1] = s1 * s2;
- m[2][2] = c2;
- m[2][3] = 0;
- m[3][0] = 0;
- m[3][1] = 0;
- m[3][2] = 0;
- m[3][3] = 1;
- return;
+ c1 := math.cos(t1)
+ s1 := math.sin(t1)
+ c2 := math.cos(t2)
+ s2 := math.sin(t2)
+ c3 := math.cos(t3)
+ s3 := math.sin(t3)
+
+ m[0][0] = c1 * c2 * c3 - s1 * s3
+ m[0][1] = c1 * s3 + c2 * c3 * s1
+ m[0][2] =-c3 * s2
+ m[0][3] = 0
+ m[1][0] =-c3 * s1 - c1 * c2 * s3
+ m[1][1] = c1 * c3 - c2 * s1 * s3
+ m[1][2] = s2 * s3
+ m[1][3] = 0
+ m[2][0] = c1 * s2
+ m[2][1] = s1 * s2
+ m[2][2] = c2
+ m[2][3] = 0
+ m[3][0] = 0
+ m[3][1] = 0
+ m[3][2] = 0
+ m[3][3] = 1
+ return
}
matrix4_from_euler_angles_zxz_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) {
- c1 := math.cos(t1);
- s1 := math.sin(t1);
- c2 := math.cos(t2);
- s2 := math.sin(t2);
- c3 := math.cos(t3);
- s3 := math.sin(t3);
-
- m[0][0] = c1 * c3 - c2 * s1 * s3;
- m[0][1] = c3 * s1 + c1 * c2 * s3;
- m[0][2] = s2 *s3;
- m[0][3] = 0;
- m[1][0] =-c1 * s3 - c2 * c3 * s1;
- m[1][1] = c1 * c2 * c3 - s1 * s3;
- m[1][2] = c3 * s2;
- m[1][3] = 0;
- m[2][0] = s1 * s2;
- m[2][1] =-c1 * s2;
- m[2][2] = c2;
- m[2][3] = 0;
- m[3][0] = 0;
- m[3][1] = 0;
- m[3][2] = 0;
- m[3][3] = 1;
- return;
+ c1 := math.cos(t1)
+ s1 := math.sin(t1)
+ c2 := math.cos(t2)
+ s2 := math.sin(t2)
+ c3 := math.cos(t3)
+ s3 := math.sin(t3)
+
+ m[0][0] = c1 * c3 - c2 * s1 * s3
+ m[0][1] = c3 * s1 + c1 * c2 * s3
+ m[0][2] = s2 *s3
+ m[0][3] = 0
+ m[1][0] =-c1 * s3 - c2 * c3 * s1
+ m[1][1] = c1 * c2 * c3 - s1 * s3
+ m[1][2] = c3 * s2
+ m[1][3] = 0
+ m[2][0] = s1 * s2
+ m[2][1] =-c1 * s2
+ m[2][2] = c2
+ m[2][3] = 0
+ m[3][0] = 0
+ m[3][1] = 0
+ m[3][2] = 0
+ m[3][3] = 1
+ return
}
matrix4_from_euler_angles_xzy_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) {
- c1 := math.cos(t1);
- s1 := math.sin(t1);
- c2 := math.cos(t2);
- s2 := math.sin(t2);
- c3 := math.cos(t3);
- s3 := math.sin(t3);
-
- m[0][0] = c2 * c3;
- m[0][1] = s1 * s3 + c1 * c3 * s2;
- m[0][2] = c3 * s1 * s2 - c1 * s3;
- m[0][3] = 0;
- m[1][0] =-s2;
- m[1][1] = c1 * c2;
- m[1][2] = c2 * s1;
- m[1][3] = 0;
- m[2][0] = c2 * s3;
- m[2][1] = c1 * s2 * s3 - c3 * s1;
- m[2][2] = c1 * c3 + s1 * s2 *s3;
- m[2][3] = 0;
- m[3][0] = 0;
- m[3][1] = 0;
- m[3][2] = 0;
- m[3][3] = 1;
- return;
+ c1 := math.cos(t1)
+ s1 := math.sin(t1)
+ c2 := math.cos(t2)
+ s2 := math.sin(t2)
+ c3 := math.cos(t3)
+ s3 := math.sin(t3)
+
+ m[0][0] = c2 * c3
+ m[0][1] = s1 * s3 + c1 * c3 * s2
+ m[0][2] = c3 * s1 * s2 - c1 * s3
+ m[0][3] = 0
+ m[1][0] =-s2
+ m[1][1] = c1 * c2
+ m[1][2] = c2 * s1
+ m[1][3] = 0
+ m[2][0] = c2 * s3
+ m[2][1] = c1 * s2 * s3 - c3 * s1
+ m[2][2] = c1 * c3 + s1 * s2 *s3
+ m[2][3] = 0
+ m[3][0] = 0
+ m[3][1] = 0
+ m[3][2] = 0
+ m[3][3] = 1
+ return
}
matrix4_from_euler_angles_yzx_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) {
- c1 := math.cos(t1);
- s1 := math.sin(t1);
- c2 := math.cos(t2);
- s2 := math.sin(t2);
- c3 := math.cos(t3);
- s3 := math.sin(t3);
-
- m[0][0] = c1 * c2;
- m[0][1] = s2;
- m[0][2] =-c2 * s1;
- m[0][3] = 0;
- m[1][0] = s1 * s3 - c1 * c3 * s2;
- m[1][1] = c2 * c3;
- m[1][2] = c1 * s3 + c3 * s1 * s2;
- m[1][3] = 0;
- m[2][0] = c3 * s1 + c1 * s2 * s3;
- m[2][1] =-c2 * s3;
- m[2][2] = c1 * c3 - s1 * s2 * s3;
- m[2][3] = 0;
- m[3][0] = 0;
- m[3][1] = 0;
- m[3][2] = 0;
- m[3][3] = 1;
- return;
+ c1 := math.cos(t1)
+ s1 := math.sin(t1)
+ c2 := math.cos(t2)
+ s2 := math.sin(t2)
+ c3 := math.cos(t3)
+ s3 := math.sin(t3)
+
+ m[0][0] = c1 * c2
+ m[0][1] = s2
+ m[0][2] =-c2 * s1
+ m[0][3] = 0
+ m[1][0] = s1 * s3 - c1 * c3 * s2
+ m[1][1] = c2 * c3
+ m[1][2] = c1 * s3 + c3 * s1 * s2
+ m[1][3] = 0
+ m[2][0] = c3 * s1 + c1 * s2 * s3
+ m[2][1] =-c2 * s3
+ m[2][2] = c1 * c3 - s1 * s2 * s3
+ m[2][3] = 0
+ m[3][0] = 0
+ m[3][1] = 0
+ m[3][2] = 0
+ m[3][3] = 1
+ return
}
matrix4_from_euler_angles_zyx_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) {
- c1 := math.cos(t1);
- s1 := math.sin(t1);
- c2 := math.cos(t2);
- s2 := math.sin(t2);
- c3 := math.cos(t3);
- s3 := math.sin(t3);
-
- m[0][0] = c1 * c2;
- m[0][1] = c2 * s1;
- m[0][2] =-s2;
- m[0][3] = 0;
- m[1][0] = c1 * s2 * s3 - c3 * s1;
- m[1][1] = c1 * c3 + s1 * s2 * s3;
- m[1][2] = c2 * s3;
- m[1][3] = 0;
- m[2][0] = s1 * s3 + c1 * c3 * s2;
- m[2][1] = c3 * s1 * s2 - c1 * s3;
- m[2][2] = c2 * c3;
- m[2][3] = 0;
- m[3][0] = 0;
- m[3][1] = 0;
- m[3][2] = 0;
- m[3][3] = 1;
- return;
+ c1 := math.cos(t1)
+ s1 := math.sin(t1)
+ c2 := math.cos(t2)
+ s2 := math.sin(t2)
+ c3 := math.cos(t3)
+ s3 := math.sin(t3)
+
+ m[0][0] = c1 * c2
+ m[0][1] = c2 * s1
+ m[0][2] =-s2
+ m[0][3] = 0
+ m[1][0] = c1 * s2 * s3 - c3 * s1
+ m[1][1] = c1 * c3 + s1 * s2 * s3
+ m[1][2] = c2 * s3
+ m[1][3] = 0
+ m[2][0] = s1 * s3 + c1 * c3 * s2
+ m[2][1] = c3 * s1 * s2 - c1 * s3
+ m[2][2] = c2 * c3
+ m[2][3] = 0
+ m[3][0] = 0
+ m[3][1] = 0
+ m[3][2] = 0
+ m[3][3] = 1
+ return
}
matrix4_from_euler_angles_zxy_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) {
- c1 := math.cos(t1);
- s1 := math.sin(t1);
- c2 := math.cos(t2);
- s2 := math.sin(t2);
- c3 := math.cos(t3);
- s3 := math.sin(t3);
-
- m[0][0] = c1 * c3 - s1 * s2 * s3;
- m[0][1] = c3 * s1 + c1 * s2 * s3;
- m[0][2] =-c2 * s3;
- m[0][3] = 0;
- m[1][0] =-c2 * s1;
- m[1][1] = c1 * c2;
- m[1][2] = s2;
- m[1][3] = 0;
- m[2][0] = c1 * s3 + c3 * s1 * s2;
- m[2][1] = s1 * s3 - c1 * c3 * s2;
- m[2][2] = c2 * c3;
- m[2][3] = 0;
- m[3][0] = 0;
- m[3][1] = 0;
- m[3][2] = 0;
- m[3][3] = 1;
- return;
+ c1 := math.cos(t1)
+ s1 := math.sin(t1)
+ c2 := math.cos(t2)
+ s2 := math.sin(t2)
+ c3 := math.cos(t3)
+ s3 := math.sin(t3)
+
+ m[0][0] = c1 * c3 - s1 * s2 * s3
+ m[0][1] = c3 * s1 + c1 * s2 * s3
+ m[0][2] =-c2 * s3
+ m[0][3] = 0
+ m[1][0] =-c2 * s1
+ m[1][1] = c1 * c2
+ m[1][2] = s2
+ m[1][3] = 0
+ m[2][0] = c1 * s3 + c3 * s1 * s2
+ m[2][1] = s1 * s3 - c1 * c3 * s2
+ m[2][2] = c2 * c3
+ m[2][3] = 0
+ m[3][0] = 0
+ m[3][1] = 0
+ m[3][2] = 0
+ m[3][3] = 1
+ return
}
matrix4_from_yaw_pitch_roll_f64 :: proc(yaw, pitch, roll: f64) -> (m: Matrix4f64) {
- ch := math.cos(yaw);
- sh := math.sin(yaw);
- cp := math.cos(pitch);
- sp := math.sin(pitch);
- cb := math.cos(roll);
- sb := math.sin(roll);
-
- m[0][0] = ch * cb + sh * sp * sb;
- m[0][1] = sb * cp;
- m[0][2] = -sh * cb + ch * sp * sb;
- m[0][3] = 0;
- m[1][0] = -ch * sb + sh * sp * cb;
- m[1][1] = cb * cp;
- m[1][2] = sb * sh + ch * sp * cb;
- m[1][3] = 0;
- m[2][0] = sh * cp;
- m[2][1] = -sp;
- m[2][2] = ch * cp;
- m[2][3] = 0;
- m[3][0] = 0;
- m[3][1] = 0;
- m[3][2] = 0;
- m[3][3] = 1;
- return m;
+ ch := math.cos(yaw)
+ sh := math.sin(yaw)
+ cp := math.cos(pitch)
+ sp := math.sin(pitch)
+ cb := math.cos(roll)
+ sb := math.sin(roll)
+
+ m[0][0] = ch * cb + sh * sp * sb
+ m[0][1] = sb * cp
+ m[0][2] = -sh * cb + ch * sp * sb
+ m[0][3] = 0
+ m[1][0] = -ch * sb + sh * sp * cb
+ m[1][1] = cb * cp
+ m[1][2] = sb * sh + ch * sp * cb
+ m[1][3] = 0
+ m[2][0] = sh * cp
+ m[2][1] = -sp
+ m[2][2] = ch * cp
+ m[2][3] = 0
+ m[3][0] = 0
+ m[3][1] = 0
+ m[3][2] = 0
+ m[3][3] = 1
+ return m
}
euler_angles_xyz_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) {
- T1 := math.atan2(m[2][1], m[2][2]);
- C2 := math.sqrt(m[0][0]*m[0][0] + m[1][0]*m[1][0]);
- T2 := math.atan2(-m[2][0], C2);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(S1*m[0][2] - C1*m[0][1], C1*m[1][1] - S1*m[1][2]);
- t1 = -T1;
- t2 = -T2;
- t3 = -T3;
- return;
+ T1 := math.atan2(m[2][1], m[2][2])
+ C2 := math.sqrt(m[0][0]*m[0][0] + m[1][0]*m[1][0])
+ T2 := math.atan2(-m[2][0], C2)
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(S1*m[0][2] - C1*m[0][1], C1*m[1][1] - S1*m[1][2])
+ t1 = -T1
+ t2 = -T2
+ t3 = -T3
+ return
}
euler_angles_yxz_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) {
- T1 := math.atan2(m[2][0], m[2][2]);
- C2 := math.sqrt(m[0][1]*m[0][1] + m[1][1]*m[1][1]);
- T2 := math.atan2(-m[2][1], C2);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(S1*m[1][2] - C1*m[1][0], C1*m[0][0] - S1*m[0][2]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(m[2][0], m[2][2])
+ C2 := math.sqrt(m[0][1]*m[0][1] + m[1][1]*m[1][1])
+ T2 := math.atan2(-m[2][1], C2)
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(S1*m[1][2] - C1*m[1][0], C1*m[0][0] - S1*m[0][2])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
euler_angles_xzx_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) {
- T1 := math.atan2(m[0][2], m[0][1]);
- S2 := math.sqrt(m[1][0]*m[1][0] + m[2][0]*m[2][0]);
- T2 := math.atan2(S2, m[0][0]);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(C1*m[1][2] - S1*m[1][1], C1*m[2][2] - S1*m[2][1]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(m[0][2], m[0][1])
+ S2 := math.sqrt(m[1][0]*m[1][0] + m[2][0]*m[2][0])
+ T2 := math.atan2(S2, m[0][0])
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(C1*m[1][2] - S1*m[1][1], C1*m[2][2] - S1*m[2][1])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
euler_angles_xyx_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) {
- T1 := math.atan2(m[0][1], -m[0][2]);
- S2 := math.sqrt(m[1][0]*m[1][0] + m[2][0]*m[2][0]);
- T2 := math.atan2(S2, m[0][0]);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(-C1*m[2][1] - S1*m[2][2], C1*m[1][1] + S1*m[1][2]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(m[0][1], -m[0][2])
+ S2 := math.sqrt(m[1][0]*m[1][0] + m[2][0]*m[2][0])
+ T2 := math.atan2(S2, m[0][0])
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(-C1*m[2][1] - S1*m[2][2], C1*m[1][1] + S1*m[1][2])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
euler_angles_yxy_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) {
- T1 := math.atan2(m[1][0], m[1][2]);
- S2 := math.sqrt(m[0][1]*m[0][1] + m[2][1]*m[2][1]);
- T2 := math.atan2(S2, m[1][1]);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(C1*m[2][0] - S1*m[2][2], C1*m[0][0] - S1*m[0][2]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(m[1][0], m[1][2])
+ S2 := math.sqrt(m[0][1]*m[0][1] + m[2][1]*m[2][1])
+ T2 := math.atan2(S2, m[1][1])
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(C1*m[2][0] - S1*m[2][2], C1*m[0][0] - S1*m[0][2])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
euler_angles_yzy_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) {
- T1 := math.atan2(m[1][2], -m[1][0]);
- S2 := math.sqrt(m[0][1]*m[0][1] + m[2][1]*m[2][1]);
- T2 := math.atan2(S2, m[1][1]);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(-S1*m[0][0] - C1*m[0][2], S1*m[2][0] + C1*m[2][2]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(m[1][2], -m[1][0])
+ S2 := math.sqrt(m[0][1]*m[0][1] + m[2][1]*m[2][1])
+ T2 := math.atan2(S2, m[1][1])
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(-S1*m[0][0] - C1*m[0][2], S1*m[2][0] + C1*m[2][2])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
euler_angles_zyz_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) {
- T1 := math.atan2(m[2][1], m[2][0]);
- S2 := math.sqrt(m[0][2]*m[0][2] + m[1][2]*m[1][2]);
- T2 := math.atan2(S2, m[2][2]);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(C1*m[0][1] - S1*m[0][0], C1*m[1][1] - S1*m[1][0]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(m[2][1], m[2][0])
+ S2 := math.sqrt(m[0][2]*m[0][2] + m[1][2]*m[1][2])
+ T2 := math.atan2(S2, m[2][2])
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(C1*m[0][1] - S1*m[0][0], C1*m[1][1] - S1*m[1][0])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
euler_angles_zxz_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) {
- T1 := math.atan2(m[2][0], -m[2][1]);
- S2 := math.sqrt(m[0][2]*m[0][2] + m[1][2]*m[1][2]);
- T2 := math.atan2(S2, m[2][2]);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(-C1*m[1][0] - S1*m[1][1], C1*m[0][0] + S1*m[0][1]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(m[2][0], -m[2][1])
+ S2 := math.sqrt(m[0][2]*m[0][2] + m[1][2]*m[1][2])
+ T2 := math.atan2(S2, m[2][2])
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(-C1*m[1][0] - S1*m[1][1], C1*m[0][0] + S1*m[0][1])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
euler_angles_xzy_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) {
- T1 := math.atan2(m[1][2], m[1][1]);
- C2 := math.sqrt(m[0][0]*m[0][0] + m[2][0]*m[2][0]);
- T2 := math.atan2(-m[1][0], C2);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(S1*m[0][1] - C1*m[0][2], C1*m[2][2] - S1*m[2][1]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(m[1][2], m[1][1])
+ C2 := math.sqrt(m[0][0]*m[0][0] + m[2][0]*m[2][0])
+ T2 := math.atan2(-m[1][0], C2)
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(S1*m[0][1] - C1*m[0][2], C1*m[2][2] - S1*m[2][1])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
euler_angles_yzx_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) {
- T1 := math.atan2(-m[0][2], m[0][0]);
- C2 := math.sqrt(m[1][1]*m[1][1] + m[2][1]*m[2][1]);
- T2 := math.atan2(m[0][1], C2);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(S1*m[1][0] + C1*m[1][2], S1*m[2][0] + C1*m[2][2]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(-m[0][2], m[0][0])
+ C2 := math.sqrt(m[1][1]*m[1][1] + m[2][1]*m[2][1])
+ T2 := math.atan2(m[0][1], C2)
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(S1*m[1][0] + C1*m[1][2], S1*m[2][0] + C1*m[2][2])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
euler_angles_zyx_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) {
- T1 := math.atan2(m[0][1], m[0][0]);
- C2 := math.sqrt(m[1][2]*m[1][2] + m[2][2]*m[2][2]);
- T2 := math.atan2(-m[0][2], C2);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(S1*m[2][0] - C1*m[2][1], C1*m[1][1] - S1*m[1][0]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(m[0][1], m[0][0])
+ C2 := math.sqrt(m[1][2]*m[1][2] + m[2][2]*m[2][2])
+ T2 := math.atan2(-m[0][2], C2)
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(S1*m[2][0] - C1*m[2][1], C1*m[1][1] - S1*m[1][0])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
euler_angles_zxy_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) {
- T1 := math.atan2(-m[1][0], m[1][1]);
- C2 := math.sqrt(m[0][2]*m[0][2] + m[2][2]*m[2][2]);
- T2 := math.atan2(m[1][2], C2);
- S1 := math.sin(T1);
- C1 := math.cos(T1);
- T3 := math.atan2(C1*m[2][0] + S1*m[2][1], C1*m[0][0] + S1*m[0][1]);
- t1 = T1;
- t2 = T2;
- t3 = T3;
- return;
+ T1 := math.atan2(-m[1][0], m[1][1])
+ C2 := math.sqrt(m[0][2]*m[0][2] + m[2][2]*m[2][2])
+ T2 := math.atan2(m[1][2], C2)
+ S1 := math.sin(T1)
+ C1 := math.cos(T1)
+ T3 := math.atan2(C1*m[2][0] + S1*m[2][1], C1*m[0][0] + S1*m[0][1])
+ t1 = T1
+ t2 = T2
+ t3 = T3
+ return
}
diff --git a/core/math/linalg/swizzle.odin b/core/math/linalg/swizzle.odin
index 335d22b9b..f035a5276 100644
--- a/core/math/linalg/swizzle.odin
+++ b/core/math/linalg/swizzle.odin
@@ -33,110 +33,110 @@ Vector4_Components :: enum u8 {
}
scalar_f32_swizzle1 :: proc(f: f32, c0: Scalar_Components) -> f32 {
- return f;
+ return f
}
scalar_f32_swizzle2 :: proc(f: f32, c0, c1: Scalar_Components) -> Vector2f32 {
- return {f, f};
+ return {f, f}
}
scalar_f32_swizzle3 :: proc(f: f32, c0, c1, c2: Scalar_Components) -> Vector3f32 {
- return {f, f, f};
+ return {f, f, f}
}
scalar_f32_swizzle4 :: proc(f: f32, c0, c1, c2, c3: Scalar_Components) -> Vector4f32 {
- return {f, f, f, f};
+ return {f, f, f, f}
}
vector2f32_swizzle1 :: proc(v: Vector2f32, c0: Vector2_Components) -> f32 {
- return v[c0];
+ return v[c0]
}
vector2f32_swizzle2 :: proc(v: Vector2f32, c0, c1: Vector2_Components) -> Vector2f32 {
- return {v[c0], v[c1]};
+ return {v[c0], v[c1]}
}
vector2f32_swizzle3 :: proc(v: Vector2f32, c0, c1, c2: Vector2_Components) -> Vector3f32 {
- return {v[c0], v[c1], v[c2]};
+ return {v[c0], v[c1], v[c2]}
}
vector2f32_swizzle4 :: proc(v: Vector2f32, c0, c1, c2, c3: Vector2_Components) -> Vector4f32 {
- return {v[c0], v[c1], v[c2], v[c3]};
+ return {v[c0], v[c1], v[c2], v[c3]}
}
vector3f32_swizzle1 :: proc(v: Vector3f32, c0: Vector3_Components) -> f32 {
- return v[c0];
+ return v[c0]
}
vector3f32_swizzle2 :: proc(v: Vector3f32, c0, c1: Vector3_Components) -> Vector2f32 {
- return {v[c0], v[c1]};
+ return {v[c0], v[c1]}
}
vector3f32_swizzle3 :: proc(v: Vector3f32, c0, c1, c2: Vector3_Components) -> Vector3f32 {
- return {v[c0], v[c1], v[c2]};
+ return {v[c0], v[c1], v[c2]}
}
vector3f32_swizzle4 :: proc(v: Vector3f32, c0, c1, c2, c3: Vector3_Components) -> Vector4f32 {
- return {v[c0], v[c1], v[c2], v[c3]};
+ return {v[c0], v[c1], v[c2], v[c3]}
}
vector4f32_swizzle1 :: proc(v: Vector4f32, c0: Vector4_Components) -> f32 {
- return v[c0];
+ return v[c0]
}
vector4f32_swizzle2 :: proc(v: Vector4f32, c0, c1: Vector4_Components) -> Vector2f32 {
- return {v[c0], v[c1]};
+ return {v[c0], v[c1]}
}
vector4f32_swizzle3 :: proc(v: Vector4f32, c0, c1, c2: Vector4_Components) -> Vector3f32 {
- return {v[c0], v[c1], v[c2]};
+ return {v[c0], v[c1], v[c2]}
}
vector4f32_swizzle4 :: proc(v: Vector4f32, c0, c1, c2, c3: Vector4_Components) -> Vector4f32 {
- return {v[c0], v[c1], v[c2], v[c3]};
+ return {v[c0], v[c1], v[c2], v[c3]}
}
scalar_f64_swizzle1 :: proc(f: f64, c0: Scalar_Components) -> f64 {
- return f;
+ return f
}
scalar_f64_swizzle2 :: proc(f: f64, c0, c1: Scalar_Components) -> Vector2f64 {
- return {f, f};
+ return {f, f}
}
scalar_f64_swizzle3 :: proc(f: f64, c0, c1, c2: Scalar_Components) -> Vector3f64 {
- return {f, f, f};
+ return {f, f, f}
}
scalar_f64_swizzle4 :: proc(f: f64, c0, c1, c2, c3: Scalar_Components) -> Vector4f64 {
- return {f, f, f, f};
+ return {f, f, f, f}
}
vector2f64_swizzle1 :: proc(v: Vector2f64, c0: Vector2_Components) -> f64 {
- return v[c0];
+ return v[c0]
}
vector2f64_swizzle2 :: proc(v: Vector2f64, c0, c1: Vector2_Components) -> Vector2f64 {
- return {v[c0], v[c1]};
+ return {v[c0], v[c1]}
}
vector2f64_swizzle3 :: proc(v: Vector2f64, c0, c1, c2: Vector2_Components) -> Vector3f64 {
- return {v[c0], v[c1], v[c2]};
+ return {v[c0], v[c1], v[c2]}
}
vector2f64_swizzle4 :: proc(v: Vector2f64, c0, c1, c2, c3: Vector2_Components) -> Vector4f64 {
- return {v[c0], v[c1], v[c2], v[c3]};
+ return {v[c0], v[c1], v[c2], v[c3]}
}
vector3f64_swizzle1 :: proc(v: Vector3f64, c0: Vector3_Components) -> f64 {
- return v[c0];
+ return v[c0]
}
vector3f64_swizzle2 :: proc(v: Vector3f64, c0, c1: Vector3_Components) -> Vector2f64 {
- return {v[c0], v[c1]};
+ return {v[c0], v[c1]}
}
vector3f64_swizzle3 :: proc(v: Vector3f64, c0, c1, c2: Vector3_Components) -> Vector3f64 {
- return {v[c0], v[c1], v[c2]};
+ return {v[c0], v[c1], v[c2]}
}
vector3f64_swizzle4 :: proc(v: Vector3f64, c0, c1, c2, c3: Vector3_Components) -> Vector4f64 {
- return {v[c0], v[c1], v[c2], v[c3]};
+ return {v[c0], v[c1], v[c2], v[c3]}
}
vector4f64_swizzle1 :: proc(v: Vector4f64, c0: Vector4_Components) -> f64 {
- return v[c0];
+ return v[c0]
}
vector4f64_swizzle2 :: proc(v: Vector4f64, c0, c1: Vector4_Components) -> Vector2f64 {
- return {v[c0], v[c1]};
+ return {v[c0], v[c1]}
}
vector4f64_swizzle3 :: proc(v: Vector4f64, c0, c1, c2: Vector4_Components) -> Vector3f64 {
- return {v[c0], v[c1], v[c2]};
+ return {v[c0], v[c1], v[c2]}
}
vector4f64_swizzle4 :: proc(v: Vector4f64, c0, c1, c2, c3: Vector4_Components) -> Vector4f64 {
- return {v[c0], v[c1], v[c2], v[c3]};
+ return {v[c0], v[c1], v[c2], v[c3]}
}
@@ -151,7 +151,7 @@ scalar_swizzle :: proc{
scalar_f64_swizzle2,
scalar_f64_swizzle3,
scalar_f64_swizzle4,
-};
+}
vector2_swizzle :: proc{
vector2f32_swizzle1,
@@ -162,7 +162,7 @@ vector2_swizzle :: proc{
vector2f64_swizzle2,
vector2f64_swizzle3,
vector2f64_swizzle4,
-};
+}
vector3_swizzle :: proc{
vector3f32_swizzle1,
@@ -173,7 +173,7 @@ vector3_swizzle :: proc{
vector3f64_swizzle2,
vector3f64_swizzle3,
vector3f64_swizzle4,
-};
+}
vector4_swizzle :: proc{
vector4f32_swizzle1,
@@ -184,7 +184,7 @@ vector4_swizzle :: proc{
vector4f64_swizzle2,
vector4f64_swizzle3,
vector4f64_swizzle4,
-};
+}
swizzle :: proc{
scalar_f32_swizzle1,
@@ -219,4 +219,4 @@ swizzle :: proc{
vector4f64_swizzle2,
vector4f64_swizzle3,
vector4f64_swizzle4,
-};
+}
diff --git a/core/math/math.odin b/core/math/math.odin
index 28b0c42fc..6a094cfd4 100644
--- a/core/math/math.odin
+++ b/core/math/math.odin
@@ -1,7 +1,7 @@
package math
import "core:intrinsics"
-_ :: intrinsics;
+_ :: intrinsics
Float_Class :: enum {
Normal, // an ordinary nonzero floating point value
@@ -11,89 +11,89 @@ Float_Class :: enum {
NaN, // Not-A-Number (NaN)
Inf, // positive infinity
Neg_Inf, // negative infinity
-};
+}
-TAU :: 6.28318530717958647692528676655900576;
-PI :: 3.14159265358979323846264338327950288;
+TAU :: 6.28318530717958647692528676655900576
+PI :: 3.14159265358979323846264338327950288
-E :: 2.71828182845904523536;
+E :: 2.71828182845904523536
-Ï„ :: TAU;
-Ï€ :: PI;
-e :: E;
+Ï„ :: TAU
+Ï€ :: PI
+e :: E
-SQRT_TWO :: 1.41421356237309504880168872420969808;
-SQRT_THREE :: 1.73205080756887729352744634150587236;
-SQRT_FIVE :: 2.23606797749978969640917366873127623;
+SQRT_TWO :: 1.41421356237309504880168872420969808
+SQRT_THREE :: 1.73205080756887729352744634150587236
+SQRT_FIVE :: 2.23606797749978969640917366873127623
-LN2 :: 0.693147180559945309417232121458176568;
-LN10 :: 2.30258509299404568401799145468436421;
+LN2 :: 0.693147180559945309417232121458176568
+LN10 :: 2.30258509299404568401799145468436421
-MAX_F64_PRECISION :: 16; // Maximum number of meaningful digits after the decimal point for 'f64'
-MAX_F32_PRECISION :: 8; // Maximum number of meaningful digits after the decimal point for 'f32'
-MAX_F16_PRECISION :: 4; // Maximum number of meaningful digits after the decimal point for 'f16'
+MAX_F64_PRECISION :: 16 // Maximum number of meaningful digits after the decimal point for 'f64'
+MAX_F32_PRECISION :: 8 // Maximum number of meaningful digits after the decimal point for 'f32'
+MAX_F16_PRECISION :: 4 // Maximum number of meaningful digits after the decimal point for 'f16'
-RAD_PER_DEG :: TAU/360.0;
-DEG_PER_RAD :: 360.0/TAU;
+RAD_PER_DEG :: TAU/360.0
+DEG_PER_RAD :: 360.0/TAU
@(default_calling_convention="none")
foreign _ {
@(link_name="llvm.sqrt.f16")
- sqrt_f16 :: proc(x: f16) -> f16 ---;
+ sqrt_f16 :: proc(x: f16) -> f16 ---
@(link_name="llvm.sqrt.f32")
- sqrt_f32 :: proc(x: f32) -> f32 ---;
+ sqrt_f32 :: proc(x: f32) -> f32 ---
@(link_name="llvm.sqrt.f64")
- sqrt_f64 :: proc(x: f64) -> f64 ---;
+ sqrt_f64 :: proc(x: f64) -> f64 ---
@(link_name="llvm.sin.f16")
- sin_f16 :: proc(θ: f16) -> f16 ---;
+ sin_f16 :: proc(θ: f16) -> f16 ---
@(link_name="llvm.sin.f32")
- sin_f32 :: proc(θ: f32) -> f32 ---;
+ sin_f32 :: proc(θ: f32) -> f32 ---
@(link_name="llvm.sin.f64")
- sin_f64 :: proc(θ: f64) -> f64 ---;
+ sin_f64 :: proc(θ: f64) -> f64 ---
@(link_name="llvm.cos.f16")
- cos_f16 :: proc(θ: f16) -> f16 ---;
+ cos_f16 :: proc(θ: f16) -> f16 ---
@(link_name="llvm.cos.f32")
- cos_f32 :: proc(θ: f32) -> f32 ---;
+ cos_f32 :: proc(θ: f32) -> f32 ---
@(link_name="llvm.cos.f64")
- cos_f64 :: proc(θ: f64) -> f64 ---;
+ cos_f64 :: proc(θ: f64) -> f64 ---
@(link_name="llvm.pow.f16")
- pow_f16 :: proc(x, power: f16) -> f16 ---;
+ pow_f16 :: proc(x, power: f16) -> f16 ---
@(link_name="llvm.pow.f32")
- pow_f32 :: proc(x, power: f32) -> f32 ---;
+ pow_f32 :: proc(x, power: f32) -> f32 ---
@(link_name="llvm.pow.f64")
- pow_f64 :: proc(x, power: f64) -> f64 ---;
+ pow_f64 :: proc(x, power: f64) -> f64 ---
@(link_name="llvm.fmuladd.f16")
- fmuladd_f16 :: proc(a, b, c: f16) -> f16 ---;
+ fmuladd_f16 :: proc(a, b, c: f16) -> f16 ---
@(link_name="llvm.fmuladd.f32")
- fmuladd_f32 :: proc(a, b, c: f32) -> f32 ---;
+ fmuladd_f32 :: proc(a, b, c: f32) -> f32 ---
@(link_name="llvm.fmuladd.f64")
- fmuladd_f64 :: proc(a, b, c: f64) -> f64 ---;
+ fmuladd_f64 :: proc(a, b, c: f64) -> f64 ---
@(link_name="llvm.log.f16")
- ln_f16 :: proc(x: f16) -> f16 ---;
+ ln_f16 :: proc(x: f16) -> f16 ---
@(link_name="llvm.log.f32")
- ln_f32 :: proc(x: f32) -> f32 ---;
+ ln_f32 :: proc(x: f32) -> f32 ---
@(link_name="llvm.log.f64")
- ln_f64 :: proc(x: f64) -> f64 ---;
+ ln_f64 :: proc(x: f64) -> f64 ---
@(link_name="llvm.exp.f16")
- exp_f16 :: proc(x: f16) -> f16 ---;
+ exp_f16 :: proc(x: f16) -> f16 ---
@(link_name="llvm.exp.f32")
- exp_f32 :: proc(x: f32) -> f32 ---;
+ exp_f32 :: proc(x: f32) -> f32 ---
@(link_name="llvm.exp.f64")
- exp_f64 :: proc(x: f64) -> f64 ---;
+ exp_f64 :: proc(x: f64) -> f64 ---
@(link_name="llvm.ldexp.f16")
- ldexp_f16 :: proc(val: f16, exp: i32) -> f16 ---;
+ ldexp_f16 :: proc(val: f16, exp: i32) -> f16 ---
@(link_name="llvm.ldexp.f32")
- ldexp_f32 :: proc(val: f32, exp: i32) -> f32 ---;
+ ldexp_f32 :: proc(val: f32, exp: i32) -> f32 ---
@(link_name="llvm.ldexp.f64")
- ldexp_f64 :: proc(val: f64, exp: i32) -> f64 ---;
+ ldexp_f64 :: proc(val: f64, exp: i32) -> f64 ---
}
sqrt_f16le :: proc(x: f16le) -> f16le { return #force_inline f16le(sqrt_f16(f16(x))); }
@@ -106,7 +106,7 @@ sqrt :: proc{
sqrt_f16, sqrt_f16le, sqrt_f16be,
sqrt_f32, sqrt_f32le, sqrt_f32be,
sqrt_f64, sqrt_f64le, sqrt_f64be,
-};
+}
sin_f16le :: proc(θ: f16le) -> f16le { return #force_inline f16le(sin_f16(f16(θ))); }
sin_f16be :: proc(θ: f16be) -> f16be { return #force_inline f16be(sin_f16(f16(θ))); }
@@ -118,7 +118,7 @@ sin :: proc{
sin_f16, sin_f16le, sin_f16be,
sin_f32, sin_f32le, sin_f32be,
sin_f64, sin_f64le, sin_f64be,
-};
+}
cos_f16le :: proc(θ: f16le) -> f16le { return #force_inline f16le(cos_f16(f16(θ))); }
cos_f16be :: proc(θ: f16be) -> f16be { return #force_inline f16be(cos_f16(f16(θ))); }
@@ -130,7 +130,7 @@ cos :: proc{
cos_f16, cos_f16le, cos_f16be,
cos_f32, cos_f32le, cos_f32be,
cos_f64, cos_f64le, cos_f64be,
-};
+}
pow_f16le :: proc(x, power: f16le) -> f16le { return #force_inline f16le(pow_f16(f16(x), f16(power))); }
pow_f16be :: proc(x, power: f16be) -> f16be { return #force_inline f16be(pow_f16(f16(x), f16(power))); }
@@ -142,7 +142,7 @@ pow :: proc{
pow_f16, pow_f16le, pow_f16be,
pow_f32, pow_f32le, pow_f32be,
pow_f64, pow_f64le, pow_f64be,
-};
+}
fmuladd_f16le :: proc(a, b, c: f16le) -> f16le { return #force_inline f16le(fmuladd_f16(f16(a), f16(b), f16(c))); }
fmuladd_f16be :: proc(a, b, c: f16be) -> f16be { return #force_inline f16be(fmuladd_f16(f16(a), f16(b), f16(c))); }
@@ -154,7 +154,7 @@ fmuladd :: proc{
fmuladd_f16, fmuladd_f16le, fmuladd_f16be,
fmuladd_f32, fmuladd_f32le, fmuladd_f32be,
fmuladd_f64, fmuladd_f64le, fmuladd_f64be,
-};
+}
ln_f16le :: proc(x: f16le) -> f16le { return #force_inline f16le(ln_f16(f16(x))); }
ln_f16be :: proc(x: f16be) -> f16be { return #force_inline f16be(ln_f16(f16(x))); }
@@ -166,7 +166,7 @@ ln :: proc{
ln_f16, ln_f16le, ln_f16be,
ln_f32, ln_f32le, ln_f32be,
ln_f64, ln_f64le, ln_f64be,
-};
+}
exp_f16le :: proc(x: f16le) -> f16le { return #force_inline f16le(exp_f16(f16(x))); }
exp_f16be :: proc(x: f16be) -> f16be { return #force_inline f16be(exp_f16(f16(x))); }
@@ -178,7 +178,7 @@ exp :: proc{
exp_f16, exp_f16le, exp_f16be,
exp_f32, exp_f32le, exp_f32be,
exp_f64, exp_f64le, exp_f64be,
-};
+}
ldexp_f16le :: proc(val: f16le, exp: i32) -> f16le { return #force_inline f16le(ldexp_f16(f16(val), exp)); }
ldexp_f16be :: proc(val: f16be, exp: i32) -> f16be { return #force_inline f16be(ldexp_f16(f16(val), exp)); }
@@ -190,7 +190,7 @@ ldexp :: proc{
ldexp_f16, ldexp_f16le, ldexp_f16be,
ldexp_f32, ldexp_f32le, ldexp_f32be,
ldexp_f64, ldexp_f64le, ldexp_f64be,
-};
+}
log_f16 :: proc(x, base: f16) -> f16 { return ln(x) / ln(base); }
@@ -208,7 +208,7 @@ log :: proc{
log_f16, log_f16le, log_f16be,
log_f32, log_f32le, log_f32be,
log_f64, log_f64le, log_f64be,
-};
+}
log2_f16 :: proc(x: f16) -> f16 { return ln(x)/LN2; }
log2_f16le :: proc(x: f16le) -> f16le { return f16le(log2_f16(f16(x))); }
@@ -225,7 +225,7 @@ log2 :: proc{
log2_f16, log2_f16le, log2_f16be,
log2_f32, log2_f32le, log2_f32be,
log2_f64, log2_f64le, log2_f64be,
-};
+}
log10_f16 :: proc(x: f16) -> f16 { return ln(x)/LN10; }
log10_f16le :: proc(x: f16le) -> f16le { return f16le(log10_f16(f16(x))); }
@@ -242,7 +242,7 @@ log10 :: proc{
log10_f16, log10_f16le, log10_f16be,
log10_f32, log10_f32le, log10_f32be,
log10_f64, log10_f64le, log10_f64be,
-};
+}
tan_f16 :: proc(θ: f16) -> f16 { return sin(θ)/cos(θ); }
tan_f16le :: proc(θ: f16le) -> f16le { return f16le(tan_f16(f16(θ))); }
@@ -259,55 +259,55 @@ tan :: proc{
tan_f16, tan_f16le, tan_f16be,
tan_f32, tan_f32le, tan_f32be,
tan_f64, tan_f64le, tan_f64be,
-};
+}
lerp :: proc(a, b: $T, t: $E) -> (x: T) { return a*(1-t) + b*t; }
-saturate :: proc(a: $T) -> (x: T) { return clamp(a, 0, 1); };
+saturate :: proc(a: $T) -> (x: T) { return clamp(a, 0, 1); }
unlerp :: proc(a, b, x: $T) -> (t: T) where intrinsics.type_is_float(T), !intrinsics.type_is_array(T) {
- return (x-a)/(b-a);
+ return (x-a)/(b-a)
}
remap :: proc(old_value, old_min, old_max, new_min, new_max: $T) -> (x: T) where intrinsics.type_is_numeric(T), !intrinsics.type_is_array(T) {
- old_range := old_max - old_min;
- new_range := new_max - new_min;
+ old_range := old_max - old_min
+ new_range := new_max - new_min
if old_range == 0 {
- return new_range / 2;
+ return new_range / 2
}
- return ((old_value - old_min) / old_range) * new_range + new_min;
+ return ((old_value - old_min) / old_range) * new_range + new_min
}
wrap :: proc(x, y: $T) -> T where intrinsics.type_is_numeric(T), !intrinsics.type_is_array(T) {
- tmp := mod(x, y);
- return y + tmp if tmp < 0 else tmp;
+ tmp := mod(x, y)
+ return y + tmp if tmp < 0 else tmp
}
angle_diff :: proc(a, b: $T) -> T where intrinsics.type_is_numeric(T), !intrinsics.type_is_array(T) {
- dist := wrap(b - a, TAU);
- return wrap(dist*2, TAU) - dist;
+ dist := wrap(b - a, TAU)
+ return wrap(dist*2, TAU) - dist
}
angle_lerp :: proc(a, b, t: $T) -> T where intrinsics.type_is_numeric(T), !intrinsics.type_is_array(T) {
- return a + angle_diff(a, b) * t;
+ return a + angle_diff(a, b) * t
}
step :: proc(edge, x: $T) -> T where intrinsics.type_is_numeric(T), !intrinsics.type_is_array(T) {
- return 0 if x < edge else 1;
+ return 0 if x < edge else 1
}
smoothstep :: proc(edge0, edge1, x: $T) -> T where intrinsics.type_is_numeric(T), !intrinsics.type_is_array(T) {
- t := clamp((x - edge0) / (edge1 - edge0), 0, 1);
- return t * t * (3 - 2*t);
+ t := clamp((x - edge0) / (edge1 - edge0), 0, 1)
+ return t * t * (3 - 2*t)
}
bias :: proc(t, b: $T) -> T where intrinsics.type_is_numeric(T) {
- return t / (((1/b) - 2) * (1 - t) + 1);
+ return t / (((1/b) - 2) * (1 - t) + 1)
}
gain :: proc(t, g: $T) -> T where intrinsics.type_is_numeric(T) {
if t < 0.5 {
- return bias(t*2, g)*0.5;
+ return bias(t*2, g)*0.5
}
- return bias(t*2 - 1, 1 - g)*0.5 + 0.5;
+ return bias(t*2 - 1, 1 - g)*0.5 + 0.5
}
@@ -324,20 +324,20 @@ sign :: proc{
sign_f16, sign_f16le, sign_f16be,
sign_f32, sign_f32le, sign_f32be,
sign_f64, sign_f64le, sign_f64be,
-};
+}
sign_bit_f16 :: proc(x: f16) -> bool {
- return (transmute(u16)x) & (1<<15) != 0;
+ return (transmute(u16)x) & (1<<15) != 0
}
sign_bit_f16le :: proc(x: f16le) -> bool { return #force_inline sign_bit_f16(f16(x)); }
sign_bit_f16be :: proc(x: f16be) -> bool { return #force_inline sign_bit_f16(f16(x)); }
sign_bit_f32 :: proc(x: f32) -> bool {
- return (transmute(u32)x) & (1<<31) != 0;
+ return (transmute(u32)x) & (1<<31) != 0
}
sign_bit_f32le :: proc(x: f32le) -> bool { return #force_inline sign_bit_f32(f32(x)); }
sign_bit_f32be :: proc(x: f32be) -> bool { return #force_inline sign_bit_f32(f32(x)); }
sign_bit_f64 :: proc(x: f64) -> bool {
- return (transmute(u64)x) & (1<<63) != 0;
+ return (transmute(u64)x) & (1<<63) != 0
}
sign_bit_f64le :: proc(x: f64le) -> bool { return #force_inline sign_bit_f64(f64(x)); }
sign_bit_f64be :: proc(x: f64be) -> bool { return #force_inline sign_bit_f64(f64(x)); }
@@ -345,32 +345,32 @@ sign_bit :: proc{
sign_bit_f16, sign_bit_f16le, sign_bit_f16be,
sign_bit_f32, sign_bit_f32le, sign_bit_f32be,
sign_bit_f64, sign_bit_f64le, sign_bit_f64be,
-};
+}
copy_sign_f16 :: proc(x, y: f16) -> f16 {
- ix := transmute(u16)x;
- iy := transmute(u16)y;
- ix &= 0x7fff;
- ix |= iy & 0x8000;
- return transmute(f16)ix;
+ ix := transmute(u16)x
+ iy := transmute(u16)y
+ ix &= 0x7fff
+ ix |= iy & 0x8000
+ return transmute(f16)ix
}
copy_sign_f16le :: proc(x, y: f16le) -> f16le { return #force_inline f16le(copy_sign_f16(f16(x), f16(y))); }
copy_sign_f16be :: proc(x, y: f16be) -> f16be { return #force_inline f16be(copy_sign_f16(f16(x), f16(y))); }
copy_sign_f32 :: proc(x, y: f32) -> f32 {
- ix := transmute(u32)x;
- iy := transmute(u32)y;
- ix &= 0x7fff_ffff;
- ix |= iy & 0x8000_0000;
- return transmute(f32)ix;
+ ix := transmute(u32)x
+ iy := transmute(u32)y
+ ix &= 0x7fff_ffff
+ ix |= iy & 0x8000_0000
+ return transmute(f32)ix
}
copy_sign_f32le :: proc(x, y: f32le) -> f32le { return #force_inline f32le(copy_sign_f32(f32(x), f32(y))); }
copy_sign_f32be :: proc(x, y: f32be) -> f32be { return #force_inline f32be(copy_sign_f32(f32(x), f32(y))); }
copy_sign_f64 :: proc(x, y: f64) -> f64 {
- ix := transmute(u64)x;
- iy := transmute(u64)y;
- ix &= 0x7fff_ffff_ffff_ffff;
- ix |= iy & 0x8000_0000_0000_0000;
- return transmute(f64)ix;
+ ix := transmute(u64)x
+ iy := transmute(u64)y
+ ix &= 0x7fff_ffff_ffff_ffff
+ ix |= iy & 0x8000_0000_0000_0000
+ return transmute(f64)ix
}
copy_sign_f64le :: proc(x, y: f64le) -> f64le { return #force_inline f64le(copy_sign_f64(f64(x), f64(y))); }
copy_sign_f64be :: proc(x, y: f64be) -> f64be { return #force_inline f64be(copy_sign_f64(f64(x), f64(y))); }
@@ -378,7 +378,7 @@ copy_sign :: proc{
copy_sign_f16, copy_sign_f16le, copy_sign_f16be,
copy_sign_f32, copy_sign_f32le, copy_sign_f32be,
copy_sign_f64, copy_sign_f64le, copy_sign_f64be,
-};
+}
to_radians_f16 :: proc(degrees: f16) -> f16 { return degrees * RAD_PER_DEG; }
to_radians_f16le :: proc(degrees: f16le) -> f16le { return degrees * RAD_PER_DEG; }
@@ -402,105 +402,105 @@ to_radians :: proc{
to_radians_f16, to_radians_f16le, to_radians_f16be,
to_radians_f32, to_radians_f32le, to_radians_f32be,
to_radians_f64, to_radians_f64le, to_radians_f64be,
-};
+}
to_degrees :: proc{
to_degrees_f16, to_degrees_f16le, to_degrees_f16be,
to_degrees_f32, to_degrees_f32le, to_degrees_f32be,
to_degrees_f64, to_degrees_f64le, to_degrees_f64be,
-};
+}
trunc_f16 :: proc(x: f16) -> f16 {
trunc_internal :: proc(f: f16) -> f16 {
- mask :: 0x1f;
- shift :: 16 - 6;
- bias :: 0xf;
+ mask :: 0x1f
+ shift :: 16 - 6
+ bias :: 0xf
if f < 1 {
switch {
- case f < 0: return -trunc_internal(-f);
- case f == 0: return f;
- case: return 0;
+ case f < 0: return -trunc_internal(-f)
+ case f == 0: return f
+ case: return 0
}
}
- x := transmute(u16)f;
- e := (x >> shift) & mask - bias;
+ x := transmute(u16)f
+ e := (x >> shift) & mask - bias
if e < shift {
- x &= ~(1 << (shift-e)) - 1;
+ x &= ~(1 << (shift-e)) - 1
}
- return transmute(f16)x;
+ return transmute(f16)x
}
switch classify(x) {
case .Zero, .Neg_Zero, .NaN, .Inf, .Neg_Inf:
- return x;
+ return x
case .Normal, .Subnormal: // carry on
}
- return trunc_internal(x);
+ return trunc_internal(x)
}
trunc_f16le :: proc(x: f16le) -> f16le { return #force_inline f16le(trunc_f16(f16(x))); }
trunc_f16be :: proc(x: f16be) -> f16be { return #force_inline f16be(trunc_f16(f16(x))); }
trunc_f32 :: proc(x: f32) -> f32 {
trunc_internal :: proc(f: f32) -> f32 {
- mask :: 0xff;
- shift :: 32 - 9;
- bias :: 0x7f;
+ mask :: 0xff
+ shift :: 32 - 9
+ bias :: 0x7f
if f < 1 {
switch {
- case f < 0: return -trunc_internal(-f);
- case f == 0: return f;
- case: return 0;
+ case f < 0: return -trunc_internal(-f)
+ case f == 0: return f
+ case: return 0
}
}
- x := transmute(u32)f;
- e := (x >> shift) & mask - bias;
+ x := transmute(u32)f
+ e := (x >> shift) & mask - bias
if e < shift {
- x &= ~(1 << (shift-e)) - 1;
+ x &= ~(1 << (shift-e)) - 1
}
- return transmute(f32)x;
+ return transmute(f32)x
}
switch classify(x) {
case .Zero, .Neg_Zero, .NaN, .Inf, .Neg_Inf:
- return x;
+ return x
case .Normal, .Subnormal: // carry on
}
- return trunc_internal(x);
+ return trunc_internal(x)
}
trunc_f32le :: proc(x: f32le) -> f32le { return #force_inline f32le(trunc_f32(f32(x))); }
trunc_f32be :: proc(x: f32be) -> f32be { return #force_inline f32be(trunc_f32(f32(x))); }
trunc_f64 :: proc(x: f64) -> f64 {
trunc_internal :: proc(f: f64) -> f64 {
- mask :: 0x7ff;
- shift :: 64 - 12;
- bias :: 0x3ff;
+ mask :: 0x7ff
+ shift :: 64 - 12
+ bias :: 0x3ff
if f < 1 {
switch {
- case f < 0: return -trunc_internal(-f);
- case f == 0: return f;
- case: return 0;
+ case f < 0: return -trunc_internal(-f)
+ case f == 0: return f
+ case: return 0
}
}
- x := transmute(u64)f;
- e := (x >> shift) & mask - bias;
+ x := transmute(u64)f
+ e := (x >> shift) & mask - bias
if e < shift {
- x &= ~(1 << (shift-e)) - 1;
+ x &= ~(1 << (shift-e)) - 1
}
- return transmute(f64)x;
+ return transmute(f64)x
}
switch classify(x) {
case .Zero, .Neg_Zero, .NaN, .Inf, .Neg_Inf:
- return x;
+ return x
case .Normal, .Subnormal: // carry on
}
- return trunc_internal(x);
+ return trunc_internal(x)
}
trunc_f64le :: proc(x: f64le) -> f64le { return #force_inline f64le(trunc_f64(f64(x))); }
trunc_f64be :: proc(x: f64be) -> f64be { return #force_inline f64be(trunc_f64(f64(x))); }
@@ -508,41 +508,41 @@ trunc :: proc{
trunc_f16, trunc_f16le, trunc_f16be,
trunc_f32, trunc_f32le, trunc_f32be,
trunc_f64, trunc_f64le, trunc_f64be,
-};
+}
round_f16 :: proc(x: f16) -> f16 {
- return ceil(x - 0.5) if x < 0 else floor(x + 0.5);
+ return ceil(x - 0.5) if x < 0 else floor(x + 0.5)
}
round_f16le :: proc(x: f16le) -> f16le {
- return ceil(x - 0.5) if x < 0 else floor(x + 0.5);
+ return ceil(x - 0.5) if x < 0 else floor(x + 0.5)
}
round_f16be :: proc(x: f16be) -> f16be {
- return ceil(x - 0.5) if x < 0 else floor(x + 0.5);
+ return ceil(x - 0.5) if x < 0 else floor(x + 0.5)
}
round_f32 :: proc(x: f32) -> f32 {
- return ceil(x - 0.5) if x < 0 else floor(x + 0.5);
+ return ceil(x - 0.5) if x < 0 else floor(x + 0.5)
}
round_f32le :: proc(x: f32le) -> f32le {
- return ceil(x - 0.5) if x < 0 else floor(x + 0.5);
+ return ceil(x - 0.5) if x < 0 else floor(x + 0.5)
}
round_f32be :: proc(x: f32be) -> f32be {
- return ceil(x - 0.5) if x < 0 else floor(x + 0.5);
+ return ceil(x - 0.5) if x < 0 else floor(x + 0.5)
}
round_f64 :: proc(x: f64) -> f64 {
- return ceil(x - 0.5) if x < 0 else floor(x + 0.5);
+ return ceil(x - 0.5) if x < 0 else floor(x + 0.5)
}
round_f64le :: proc(x: f64le) -> f64le {
- return ceil(x - 0.5) if x < 0 else floor(x + 0.5);
+ return ceil(x - 0.5) if x < 0 else floor(x + 0.5)
}
round_f64be :: proc(x: f64be) -> f64be {
- return ceil(x - 0.5) if x < 0 else floor(x + 0.5);
+ return ceil(x - 0.5) if x < 0 else floor(x + 0.5)
}
round :: proc{
round_f16, round_f16le, round_f16be,
round_f32, round_f32le, round_f32be,
round_f64, round_f64le, round_f64be,
-};
+}
ceil_f16 :: proc(x: f16) -> f16 { return -floor(-x); }
@@ -561,53 +561,53 @@ ceil :: proc{
ceil_f16, ceil_f16le, ceil_f16be,
ceil_f32, ceil_f32le, ceil_f32be,
ceil_f64, ceil_f64le, ceil_f64be,
-};
+}
floor_f16 :: proc(x: f16) -> f16 {
if x == 0 || is_nan(x) || is_inf(x) {
- return x;
+ return x
}
if x < 0 {
- d, fract := modf(-x);
+ d, fract := modf(-x)
if fract != 0.0 {
- d = d + 1;
+ d = d + 1
}
- return -d;
+ return -d
}
- d, _ := modf(x);
- return d;
+ d, _ := modf(x)
+ return d
}
floor_f16le :: proc(x: f16le) -> f16le { return #force_inline f16le(floor_f16(f16(x))); }
floor_f16be :: proc(x: f16be) -> f16be { return #force_inline f16be(floor_f16(f16(x))); }
floor_f32 :: proc(x: f32) -> f32 {
if x == 0 || is_nan(x) || is_inf(x) {
- return x;
+ return x
}
if x < 0 {
- d, fract := modf(-x);
+ d, fract := modf(-x)
if fract != 0.0 {
- d = d + 1;
+ d = d + 1
}
- return -d;
+ return -d
}
- d, _ := modf(x);
- return d;
+ d, _ := modf(x)
+ return d
}
floor_f32le :: proc(x: f32le) -> f32le { return #force_inline f32le(floor_f32(f32(x))); }
floor_f32be :: proc(x: f32be) -> f32be { return #force_inline f32be(floor_f32(f32(x))); }
floor_f64 :: proc(x: f64) -> f64 {
if x == 0 || is_nan(x) || is_inf(x) {
- return x;
+ return x
}
if x < 0 {
- d, fract := modf(-x);
+ d, fract := modf(-x)
if fract != 0.0 {
- d = d + 1;
+ d = d + 1
}
- return -d;
+ return -d
}
- d, _ := modf(x);
- return d;
+ d, _ := modf(x)
+ return d
}
floor_f64le :: proc(x: f64le) -> f64le { return #force_inline f64le(floor_f64(f64(x))); }
floor_f64be :: proc(x: f64be) -> f64be { return #force_inline f64be(floor_f64(f64(x))); }
@@ -615,164 +615,164 @@ floor :: proc{
floor_f16, floor_f16le, floor_f16be,
floor_f32, floor_f32le, floor_f32be,
floor_f64, floor_f64le, floor_f64be,
-};
+}
floor_div :: proc(x, y: $T) -> T
where intrinsics.type_is_integer(T) {
- a := x / y;
- r := x % y;
+ a := x / y
+ r := x % y
if (r > 0 && y < 0) || (r < 0 && y > 0) {
- a -= 1;
+ a -= 1
}
- return a;
+ return a
}
floor_mod :: proc(x, y: $T) -> T
where intrinsics.type_is_integer(T) {
- r := x % y;
+ r := x % y
if (r > 0 && y < 0) || (r < 0 && y > 0) {
- r += y;
+ r += y
}
- return r;
+ return r
}
modf_f16 :: proc(x: f16) -> (int: f16, frac: f16) {
- shift :: 16 - 5 - 1;
- mask :: 0x1f;
- bias :: 15;
+ shift :: 16 - 5 - 1
+ mask :: 0x1f
+ bias :: 15
if x < 1 {
switch {
case x < 0:
- int, frac = modf(-x);
- return -int, -frac;
+ int, frac = modf(-x)
+ return -int, -frac
case x == 0:
- return x, x;
+ return x, x
}
- return 0, x;
+ return 0, x
}
- i := transmute(u16)x;
- e := uint(i>>shift)&mask - bias;
+ i := transmute(u16)x
+ e := uint(i>>shift)&mask - bias
if e < shift {
- i &~= 1<<(shift-e) - 1;
+ i &~= 1<<(shift-e) - 1
}
- int = transmute(f16)i;
- frac = x - int;
- return;
+ int = transmute(f16)i
+ frac = x - int
+ return
}
modf_f16le :: proc(x: f16le) -> (int: f16le, frac: f16le) {
- i, f := #force_inline modf_f16(f16(x));
- return f16le(i), f16le(f);
+ i, f := #force_inline modf_f16(f16(x))
+ return f16le(i), f16le(f)
}
modf_f16be :: proc(x: f16be) -> (int: f16be, frac: f16be) {
- i, f := #force_inline modf_f16(f16(x));
- return f16be(i), f16be(f);
+ i, f := #force_inline modf_f16(f16(x))
+ return f16be(i), f16be(f)
}
modf_f32 :: proc(x: f32) -> (int: f32, frac: f32) {
- shift :: 32 - 8 - 1;
- mask :: 0xff;
- bias :: 127;
+ shift :: 32 - 8 - 1
+ mask :: 0xff
+ bias :: 127
if x < 1 {
switch {
case x < 0:
- int, frac = modf(-x);
- return -int, -frac;
+ int, frac = modf(-x)
+ return -int, -frac
case x == 0:
- return x, x;
+ return x, x
}
- return 0, x;
+ return 0, x
}
- i := transmute(u32)x;
- e := uint(i>>shift)&mask - bias;
+ i := transmute(u32)x
+ e := uint(i>>shift)&mask - bias
if e < shift {
- i &~= 1<<(shift-e) - 1;
+ i &~= 1<<(shift-e) - 1
}
- int = transmute(f32)i;
- frac = x - int;
- return;
+ int = transmute(f32)i
+ frac = x - int
+ return
}
modf_f32le :: proc(x: f32le) -> (int: f32le, frac: f32le) {
- i, f := #force_inline modf_f32(f32(x));
- return f32le(i), f32le(f);
+ i, f := #force_inline modf_f32(f32(x))
+ return f32le(i), f32le(f)
}
modf_f32be :: proc(x: f32be) -> (int: f32be, frac: f32be) {
- i, f := #force_inline modf_f32(f32(x));
- return f32be(i), f32be(f);
+ i, f := #force_inline modf_f32(f32(x))
+ return f32be(i), f32be(f)
}
modf_f64 :: proc(x: f64) -> (int: f64, frac: f64) {
- shift :: 64 - 11 - 1;
- mask :: 0x7ff;
- bias :: 1023;
+ shift :: 64 - 11 - 1
+ mask :: 0x7ff
+ bias :: 1023
if x < 1 {
switch {
case x < 0:
- int, frac = modf(-x);
- return -int, -frac;
+ int, frac = modf(-x)
+ return -int, -frac
case x == 0:
- return x, x;
+ return x, x
}
- return 0, x;
+ return 0, x
}
- i := transmute(u64)x;
- e := uint(i>>shift)&mask - bias;
+ i := transmute(u64)x
+ e := uint(i>>shift)&mask - bias
if e < shift {
- i &~= 1<<(shift-e) - 1;
+ i &~= 1<<(shift-e) - 1
}
- int = transmute(f64)i;
- frac = x - int;
- return;
+ int = transmute(f64)i
+ frac = x - int
+ return
}
modf_f64le :: proc(x: f64le) -> (int: f64le, frac: f64le) {
- i, f := #force_inline modf_f64(f64(x));
- return f64le(i), f64le(f);
+ i, f := #force_inline modf_f64(f64(x))
+ return f64le(i), f64le(f)
}
modf_f64be :: proc(x: f64be) -> (int: f64be, frac: f64be) {
- i, f := #force_inline modf_f64(f64(x));
- return f64be(i), f64be(f);
+ i, f := #force_inline modf_f64(f64(x))
+ return f64be(i), f64be(f)
}
modf :: proc{
modf_f16, modf_f16le, modf_f16be,
modf_f32, modf_f32le, modf_f32be,
modf_f64, modf_f64le, modf_f64be,
-};
-split_decimal :: modf;
+}
+split_decimal :: modf
mod_f16 :: proc(x, y: f16) -> (n: f16) {
- z := abs(y);
- n = remainder(abs(x), z);
+ z := abs(y)
+ n = remainder(abs(x), z)
if sign(n) < 0 {
- n += z;
+ n += z
}
- return copy_sign(n, x);
+ return copy_sign(n, x)
}
mod_f16le :: proc(x, y: f16le) -> (n: f16le) { return #force_inline f16le(mod_f16(f16(x), f16(y))); }
mod_f16be :: proc(x, y: f16be) -> (n: f16be) { return #force_inline f16be(mod_f16(f16(x), f16(y))); }
mod_f32 :: proc(x, y: f32) -> (n: f32) {
- z := abs(y);
- n = remainder(abs(x), z);
+ z := abs(y)
+ n = remainder(abs(x), z)
if sign(n) < 0 {
- n += z;
+ n += z
}
- return copy_sign(n, x);
+ return copy_sign(n, x)
}
mod_f32le :: proc(x, y: f32le) -> (n: f32le) { return #force_inline f32le(mod_f32(f32(x), f32(y))); }
mod_f32be :: proc(x, y: f32be) -> (n: f32be) { return #force_inline f32be(mod_f32(f32(x), f32(y))); }
mod_f64 :: proc(x, y: f64) -> (n: f64) {
- z := abs(y);
- n = remainder(abs(x), z);
+ z := abs(y)
+ n = remainder(abs(x), z)
if sign(n) < 0 {
- n += z;
+ n += z
}
- return copy_sign(n, x);
+ return copy_sign(n, x)
}
mod_f64le :: proc(x, y: f64le) -> (n: f64le) { return #force_inline f64le(mod_f64(f64(x), f64(y))); }
mod_f64be :: proc(x, y: f64be) -> (n: f64be) { return #force_inline f64be(mod_f64(f64(x), f64(y))); }
@@ -780,7 +780,7 @@ mod :: proc{
mod_f16, mod_f16le, mod_f16be,
mod_f32, mod_f32le, mod_f32be,
mod_f64, mod_f64le, mod_f64be,
-};
+}
remainder_f16 :: proc(x, y: f16 ) -> f16 { return x - round(x/y) * y; }
remainder_f16le :: proc(x, y: f16le) -> f16le { return x - round(x/y) * y; }
@@ -795,95 +795,95 @@ remainder :: proc{
remainder_f16, remainder_f16le, remainder_f16be,
remainder_f32, remainder_f32le, remainder_f32be,
remainder_f64, remainder_f64le, remainder_f64be,
-};
+}
gcd :: proc(x, y: $T) -> T
where intrinsics.type_is_ordered_numeric(T) {
- x, y := x, y;
+ x, y := x, y
for y != 0 {
- x %= y;
- x, y = y, x;
+ x %= y
+ x, y = y, x
}
- return abs(x);
+ return abs(x)
}
lcm :: proc(x, y: $T) -> T
where intrinsics.type_is_ordered_numeric(T) {
- return x / gcd(x, y) * y;
+ return x / gcd(x, y) * y
}
frexp_f16 :: proc(x: f16) -> (significand: f16, exponent: int) {
- f, e := frexp_f64(f64(x));
- return f16(f), e;
+ f, e := frexp_f64(f64(x))
+ return f16(f), e
}
frexp_f16le :: proc(x: f16le) -> (significand: f16le, exponent: int) {
- f, e := frexp_f64(f64(x));
- return f16le(f), e;
+ f, e := frexp_f64(f64(x))
+ return f16le(f), e
}
frexp_f16be :: proc(x: f16be) -> (significand: f16be, exponent: int) {
- f, e := frexp_f64(f64(x));
- return f16be(f), e;
+ f, e := frexp_f64(f64(x))
+ return f16be(f), e
}
frexp_f32 :: proc(x: f32) -> (significand: f32, exponent: int) {
- f, e := frexp_f64(f64(x));
- return f32(f), e;
+ f, e := frexp_f64(f64(x))
+ return f32(f), e
}
frexp_f32le :: proc(x: f32le) -> (significand: f32le, exponent: int) {
- f, e := frexp_f64(f64(x));
- return f32le(f), e;
+ f, e := frexp_f64(f64(x))
+ return f32le(f), e
}
frexp_f32be :: proc(x: f32be) -> (significand: f32be, exponent: int) {
- f, e := frexp_f64(f64(x));
- return f32be(f), e;
+ f, e := frexp_f64(f64(x))
+ return f32be(f), e
}
frexp_f64 :: proc(x: f64) -> (significand: f64, exponent: int) {
switch {
case x == 0:
- return 0, 0;
+ return 0, 0
case x < 0:
- significand, exponent = frexp(-x);
- return -significand, exponent;
+ significand, exponent = frexp(-x)
+ return -significand, exponent
}
- ex := trunc(log2(x));
- exponent = int(ex);
- significand = x / pow(2.0, ex);
+ ex := trunc(log2(x))
+ exponent = int(ex)
+ significand = x / pow(2.0, ex)
if abs(significand) >= 1 {
- exponent += 1;
- significand /= 2;
+ exponent += 1
+ significand /= 2
}
if exponent == 1024 && significand == 0 {
- significand = 0.99999999999999988898;
+ significand = 0.99999999999999988898
}
- return;
+ return
}
frexp_f64le :: proc(x: f64le) -> (significand: f64le, exponent: int) {
- f, e := frexp_f64(f64(x));
- return f64le(f), e;
+ f, e := frexp_f64(f64(x))
+ return f64le(f), e
}
frexp_f64be :: proc(x: f64be) -> (significand: f64be, exponent: int) {
- f, e := frexp_f64(f64(x));
- return f64be(f), e;
+ f, e := frexp_f64(f64(x))
+ return f64be(f), e
}
frexp :: proc{
frexp_f16, frexp_f16le, frexp_f16be,
frexp_f32, frexp_f32le, frexp_f32be,
frexp_f64, frexp_f64le, frexp_f64be,
-};
+}
binomial :: proc(n, k: int) -> int {
switch {
- case k <= 0: return 1;
- case 2*k > n: return binomial(n, n-k);
+ case k <= 0: return 1
+ case 2*k > n: return binomial(n, n-k)
}
- b := n;
+ b := n
for i in 2..<k {
- b = (b * (n+1-i))/i;
+ b = (b * (n+1-i))/i
}
- return b;
+ return b
}
factorial :: proc(n: int) -> int {
@@ -910,7 +910,7 @@ factorial :: proc(n: int) -> int {
6_402_373_705_728_000,
121_645_100_408_832_000,
2_432_902_008_176_640_000,
- };
+ }
} else {
@static table := [13]int{
1,
@@ -926,88 +926,88 @@ factorial :: proc(n: int) -> int {
3_628_800,
39_916_800,
479_001_600,
- };
+ }
}
- assert(n >= 0, "parameter must not be negative");
- assert(n < len(table), "parameter is too large to lookup in the table");
- return table[n];
+ assert(n >= 0, "parameter must not be negative")
+ assert(n < len(table), "parameter is too large to lookup in the table")
+ return table[n]
}
classify_f16 :: proc(x: f16) -> Float_Class {
switch {
case x == 0:
- i := transmute(i16)x;
+ i := transmute(i16)x
if i < 0 {
- return .Neg_Zero;
+ return .Neg_Zero
}
- return .Zero;
+ return .Zero
case x*0.5 == x:
if x < 0 {
- return .Neg_Inf;
+ return .Neg_Inf
}
- return .Inf;
+ return .Inf
case !(x == x):
- return .NaN;
+ return .NaN
}
- u := transmute(u16)x;
- exp := int(u>>10) & (1<<5 - 1);
+ u := transmute(u16)x
+ exp := int(u>>10) & (1<<5 - 1)
if exp == 0 {
- return .Subnormal;
+ return .Subnormal
}
- return .Normal;
+ return .Normal
}
classify_f16le :: proc(x: f16le) -> Float_Class { return #force_inline classify_f16(f16(x)); }
classify_f16be :: proc(x: f16be) -> Float_Class { return #force_inline classify_f16(f16(x)); }
classify_f32 :: proc(x: f32) -> Float_Class {
switch {
case x == 0:
- i := transmute(i32)x;
+ i := transmute(i32)x
if i < 0 {
- return .Neg_Zero;
+ return .Neg_Zero
}
- return .Zero;
+ return .Zero
case x*0.5 == x:
if x < 0 {
- return .Neg_Inf;
+ return .Neg_Inf
}
- return .Inf;
+ return .Inf
case !(x == x):
- return .NaN;
+ return .NaN
}
- u := transmute(u32)x;
- exp := int(u>>23) & (1<<8 - 1);
+ u := transmute(u32)x
+ exp := int(u>>23) & (1<<8 - 1)
if exp == 0 {
- return .Subnormal;
+ return .Subnormal
}
- return .Normal;
+ return .Normal
}
classify_f32le :: proc(x: f32le) -> Float_Class { return #force_inline classify_f32(f32(x)); }
classify_f32be :: proc(x: f32be) -> Float_Class { return #force_inline classify_f32(f32(x)); }
classify_f64 :: proc(x: f64) -> Float_Class {
switch {
case x == 0:
- i := transmute(i64)x;
+ i := transmute(i64)x
if i < 0 {
- return .Neg_Zero;
+ return .Neg_Zero
}
- return .Zero;
+ return .Zero
case x*0.5 == x:
if x < 0 {
- return .Neg_Inf;
+ return .Neg_Inf
}
- return .Inf;
+ return .Inf
case !(x == x):
- return .NaN;
+ return .NaN
}
- u := transmute(u64)x;
- exp := int(u>>52) & (1<<11 - 1);
+ u := transmute(u64)x
+ exp := int(u>>52) & (1<<11 - 1)
if exp == 0 {
- return .Subnormal;
+ return .Subnormal
}
- return .Normal;
+ return .Normal
}
classify_f64le :: proc(x: f64le) -> Float_Class { return #force_inline classify_f64(f64(x)); }
classify_f64be :: proc(x: f64be) -> Float_Class { return #force_inline classify_f64(f64(x)); }
@@ -1015,7 +1015,7 @@ classify :: proc{
classify_f16, classify_f16le, classify_f16be,
classify_f32, classify_f32le, classify_f32be,
classify_f64, classify_f64le, classify_f64be,
-};
+}
is_nan_f16 :: proc(x: f16) -> bool { return classify(x) == .NaN; }
is_nan_f16le :: proc(x: f16le) -> bool { return classify(x) == .NaN; }
@@ -1030,209 +1030,209 @@ is_nan :: proc{
is_nan_f16, is_nan_f16le, is_nan_f16be,
is_nan_f32, is_nan_f32le, is_nan_f32be,
is_nan_f64, is_nan_f64le, is_nan_f64be,
-};
+}
// is_inf reports whether f is an infinity, according to sign.
// If sign > 0, is_inf reports whether f is positive infinity.
// If sign < 0, is_inf reports whether f is negative infinity.
// If sign == 0, is_inf reports whether f is either infinity.
is_inf_f16 :: proc(x: f16, sign: int = 0) -> bool {
- class := classify(abs(x));
+ class := classify(abs(x))
switch {
case sign > 0:
- return class == .Inf;
+ return class == .Inf
case sign < 0:
- return class == .Neg_Inf;
+ return class == .Neg_Inf
}
- return class == .Inf || class == .Neg_Inf;
+ return class == .Inf || class == .Neg_Inf
}
is_inf_f16le :: proc(x: f16le, sign: int = 0) -> bool {
- return #force_inline is_inf_f16(f16(x), sign);
+ return #force_inline is_inf_f16(f16(x), sign)
}
is_inf_f16be :: proc(x: f16be, sign: int = 0) -> bool {
- return #force_inline is_inf_f16(f16(x), sign);
+ return #force_inline is_inf_f16(f16(x), sign)
}
is_inf_f32 :: proc(x: f32, sign: int = 0) -> bool {
- class := classify(abs(x));
+ class := classify(abs(x))
switch {
case sign > 0:
- return class == .Inf;
+ return class == .Inf
case sign < 0:
- return class == .Neg_Inf;
+ return class == .Neg_Inf
}
- return class == .Inf || class == .Neg_Inf;
+ return class == .Inf || class == .Neg_Inf
}
is_inf_f32le :: proc(x: f32le, sign: int = 0) -> bool {
- return #force_inline is_inf_f32(f32(x), sign);
+ return #force_inline is_inf_f32(f32(x), sign)
}
is_inf_f32be :: proc(x: f32be, sign: int = 0) -> bool {
- return #force_inline is_inf_f32(f32(x), sign);
+ return #force_inline is_inf_f32(f32(x), sign)
}
is_inf_f64 :: proc(x: f64, sign: int = 0) -> bool {
- class := classify(abs(x));
+ class := classify(abs(x))
switch {
case sign > 0:
- return class == .Inf;
+ return class == .Inf
case sign < 0:
- return class == .Neg_Inf;
+ return class == .Neg_Inf
}
- return class == .Inf || class == .Neg_Inf;
+ return class == .Inf || class == .Neg_Inf
}
is_inf_f64le :: proc(x: f64le, sign: int = 0) -> bool {
- return #force_inline is_inf_f64(f64(x), sign);
+ return #force_inline is_inf_f64(f64(x), sign)
}
is_inf_f64be :: proc(x: f64be, sign: int = 0) -> bool {
- return #force_inline is_inf_f64(f64(x), sign);
+ return #force_inline is_inf_f64(f64(x), sign)
}
is_inf :: proc{
is_inf_f16, is_inf_f16le, is_inf_f16be,
is_inf_f32, is_inf_f32le, is_inf_f32be,
is_inf_f64, is_inf_f64le, is_inf_f64be,
-};
+}
inf_f16 :: proc(sign: int) -> f16 {
- return f16(inf_f64(sign));
+ return f16(inf_f64(sign))
}
inf_f16le :: proc(sign: int) -> f16le {
- return f16le(inf_f64(sign));
+ return f16le(inf_f64(sign))
}
inf_f16be :: proc(sign: int) -> f16be {
- return f16be(inf_f64(sign));
+ return f16be(inf_f64(sign))
}
inf_f32 :: proc(sign: int) -> f32 {
- return f32(inf_f64(sign));
+ return f32(inf_f64(sign))
}
inf_f32le :: proc(sign: int) -> f32le {
- return f32le(inf_f64(sign));
+ return f32le(inf_f64(sign))
}
inf_f32be :: proc(sign: int) -> f32be {
- return f32be(inf_f64(sign));
+ return f32be(inf_f64(sign))
}
inf_f64 :: proc(sign: int) -> f64 {
- v: u64;
+ v: u64
if sign >= 0 {
- v = 0x7ff00000_00000000;
+ v = 0x7ff00000_00000000
} else {
- v = 0xfff00000_00000000;
+ v = 0xfff00000_00000000
}
- return transmute(f64)v;
+ return transmute(f64)v
}
inf_f64le :: proc(sign: int) -> f64le {
- return f64le(inf_f64(sign));
+ return f64le(inf_f64(sign))
}
inf_f64be :: proc(sign: int) -> f64be {
- return f64be(inf_f64(sign));
+ return f64be(inf_f64(sign))
}
nan_f16 :: proc() -> f16 {
- return f16(nan_f64());
+ return f16(nan_f64())
}
nan_f16le :: proc() -> f16le {
- return f16le(nan_f64());
+ return f16le(nan_f64())
}
nan_f16be :: proc() -> f16be {
- return f16be(nan_f64());
+ return f16be(nan_f64())
}
nan_f32 :: proc() -> f32 {
- return f32(nan_f64());
+ return f32(nan_f64())
}
nan_f32le :: proc() -> f32le {
- return f32le(nan_f64());
+ return f32le(nan_f64())
}
nan_f32be :: proc() -> f32be {
- return f32be(nan_f64());
+ return f32be(nan_f64())
}
nan_f64 :: proc() -> f64 {
- v: u64 = 0x7ff80000_00000001;
- return transmute(f64)v;
+ v: u64 = 0x7ff80000_00000001
+ return transmute(f64)v
}
nan_f64le :: proc() -> f64le {
- return f64le(nan_f64());
+ return f64le(nan_f64())
}
nan_f64be :: proc() -> f64be {
- return f64be(nan_f64());
+ return f64be(nan_f64())
}
is_power_of_two :: proc(x: int) -> bool {
- return x > 0 && (x & (x-1)) == 0;
+ return x > 0 && (x & (x-1)) == 0
}
next_power_of_two :: proc(x: int) -> int {
- k := x -1;
+ k := x -1
when size_of(int) == 8 {
- k = k | (k >> 32);
+ k = k | (k >> 32)
}
- k = k | (k >> 16);
- k = k | (k >> 8);
- k = k | (k >> 4);
- k = k | (k >> 2);
- k = k | (k >> 1);
- k += 1 + int(x <= 0);
- return k;
+ k = k | (k >> 16)
+ k = k | (k >> 8)
+ k = k | (k >> 4)
+ k = k | (k >> 2)
+ k = k | (k >> 1)
+ k += 1 + int(x <= 0)
+ return k
}
sum :: proc(x: $T/[]$E) -> (res: E)
where intrinsics.type_is_numeric(E) {
for i in x {
- res += i;
+ res += i
}
- return;
+ return
}
prod :: proc(x: $T/[]$E) -> (res: E)
where intrinsics.type_is_numeric(E) {
for i in x {
- res *= i;
+ res *= i
}
- return;
+ return
}
cumsum_inplace :: proc(x: $T/[]$E) -> T
where intrinsics.type_is_numeric(E) {
for i in 1..<len(x) {
- x[i] = x[i-1] + x[i];
+ x[i] = x[i-1] + x[i]
}
}
cumsum :: proc(dst, src: $T/[]$E) -> T
where intrinsics.type_is_numeric(E) {
- N := min(len(dst), len(src));
+ N := min(len(dst), len(src))
if N > 0 {
- dst[0] = src[0];
+ dst[0] = src[0]
for i in 1..<N {
- dst[i] = dst[i-1] + src[i];
+ dst[i] = dst[i-1] + src[i]
}
}
- return dst[:N];
+ return dst[:N]
}
atan2_f16 :: proc(y, x: f16) -> f16 {
// TODO(bill): Better atan2_f16
- return f16(atan2_f64(f64(y), f64(x)));
+ return f16(atan2_f64(f64(y), f64(x)))
}
atan2_f16le :: proc(y, x: f16le) -> f16le {
// TODO(bill): Better atan2_f16
- return f16le(atan2_f64(f64(y), f64(x)));
+ return f16le(atan2_f64(f64(y), f64(x)))
}
atan2_f16be :: proc(y, x: f16be) -> f16be {
// TODO(bill): Better atan2_f16
- return f16be(atan2_f64(f64(y), f64(x)));
+ return f16be(atan2_f64(f64(y), f64(x)))
}
atan2_f32 :: proc(y, x: f32) -> f32 {
// TODO(bill): Better atan2_f32
- return f32(atan2_f64(f64(y), f64(x)));
+ return f32(atan2_f64(f64(y), f64(x)))
}
atan2_f32le :: proc(y, x: f32le) -> f32le {
// TODO(bill): Better atan2_f32
- return f32le(atan2_f64(f64(y), f64(x)));
+ return f32le(atan2_f64(f64(y), f64(x)))
}
atan2_f32be :: proc(y, x: f32be) -> f32be {
// TODO(bill): Better atan2_f32
- return f32be(atan2_f64(f64(y), f64(x)));
+ return f32be(atan2_f64(f64(y), f64(x)))
}
atan2_f64 :: proc(y, x: f64) -> f64 {
@@ -1242,161 +1242,161 @@ atan2_f64 :: proc(y, x: f64) -> f64 {
// Stephen L. Moshier
// moshier@na-net.ornl.gov
- NAN :: 0h7fff_ffff_ffff_ffff;
- INF :: 0h7FF0_0000_0000_0000;
- PI :: 0h4009_21fb_5444_2d18;
+ NAN :: 0h7fff_ffff_ffff_ffff
+ INF :: 0h7FF0_0000_0000_0000
+ PI :: 0h4009_21fb_5444_2d18
atan :: proc(x: f64) -> f64 {
if x == 0 {
- return x;
+ return x
}
if x > 0 {
- return s_atan(x);
+ return s_atan(x)
}
- return -s_atan(-x);
+ return -s_atan(-x)
}
// s_atan reduces its argument (known to be positive) to the range [0, 0.66] and calls x_atan.
s_atan :: proc(x: f64) -> f64 {
- MORE_BITS :: 6.123233995736765886130e-17; // pi/2 = PIO2 + MORE_BITS
- TAN3PI08 :: 2.41421356237309504880; // tan(3*pi/8)
+ MORE_BITS :: 6.123233995736765886130e-17 // pi/2 = PIO2 + MORE_BITS
+ TAN3PI08 :: 2.41421356237309504880 // tan(3*pi/8)
if x <= 0.66 {
- return x_atan(x);
+ return x_atan(x)
}
if x > TAN3PI08 {
- return PI/2 - x_atan(1/x) + MORE_BITS;
+ return PI/2 - x_atan(1/x) + MORE_BITS
}
- return PI/4 + x_atan((x-1)/(x+1)) + 0.5*MORE_BITS;
+ return PI/4 + x_atan((x-1)/(x+1)) + 0.5*MORE_BITS
}
// x_atan evaluates a series valid in the range [0, 0.66].
x_atan :: proc(x: f64) -> f64 {
- P0 :: -8.750608600031904122785e-01;
- P1 :: -1.615753718733365076637e+01;
- P2 :: -7.500855792314704667340e+01;
- P3 :: -1.228866684490136173410e+02;
- P4 :: -6.485021904942025371773e+01;
- Q0 :: +2.485846490142306297962e+01;
- Q1 :: +1.650270098316988542046e+02;
- Q2 :: +4.328810604912902668951e+02;
- Q3 :: +4.853903996359136964868e+02;
- Q4 :: +1.945506571482613964425e+02;
-
- z := x * x;
- z = z * ((((P0*z+P1)*z+P2)*z+P3)*z + P4) / (((((z+Q0)*z+Q1)*z+Q2)*z+Q3)*z + Q4);
- z = x*z + x;
- return z;
+ P0 :: -8.750608600031904122785e-01
+ P1 :: -1.615753718733365076637e+01
+ P2 :: -7.500855792314704667340e+01
+ P3 :: -1.228866684490136173410e+02
+ P4 :: -6.485021904942025371773e+01
+ Q0 :: +2.485846490142306297962e+01
+ Q1 :: +1.650270098316988542046e+02
+ Q2 :: +4.328810604912902668951e+02
+ Q3 :: +4.853903996359136964868e+02
+ Q4 :: +1.945506571482613964425e+02
+
+ z := x * x
+ z = z * ((((P0*z+P1)*z+P2)*z+P3)*z + P4) / (((((z+Q0)*z+Q1)*z+Q2)*z+Q3)*z + Q4)
+ z = x*z + x
+ return z
}
switch {
case is_nan(y) || is_nan(x):
- return NAN;
+ return NAN
case y == 0:
if x >= 0 && !sign_bit(x) {
- return copy_sign(0.0, y);
+ return copy_sign(0.0, y)
}
- return copy_sign(PI, y);
+ return copy_sign(PI, y)
case x == 0:
- return copy_sign(PI*0.5, y);
+ return copy_sign(PI*0.5, y)
case is_inf(x, 0):
if is_inf(x, 1) {
if is_inf(y, 0) {
- return copy_sign(PI*0.25, y);
+ return copy_sign(PI*0.25, y)
}
- return copy_sign(0, y);
+ return copy_sign(0, y)
}
if is_inf(y, 0) {
- return copy_sign(PI*0.75, y);
+ return copy_sign(PI*0.75, y)
}
- return copy_sign(PI, y);
+ return copy_sign(PI, y)
case is_inf(y, 0):
- return copy_sign(PI*0.5, y);
+ return copy_sign(PI*0.5, y)
}
- q := atan(y / x);
+ q := atan(y / x)
if x < 0 {
if q <= 0 {
- return q + PI;
+ return q + PI
}
- return q - PI;
+ return q - PI
}
- return q;
+ return q
}
atan2_f64le :: proc(y, x: f64le) -> f64le {
// TODO(bill): Better atan2_f32
- return f64le(atan2_f64(f64(y), f64(x)));
+ return f64le(atan2_f64(f64(y), f64(x)))
}
atan2_f64be :: proc(y, x: f64be) -> f64be {
// TODO(bill): Better atan2_f32
- return f64be(atan2_f64(f64(y), f64(x)));
+ return f64be(atan2_f64(f64(y), f64(x)))
}
atan2 :: proc{
atan2_f16, atan2_f16le, atan2_f16be,
atan2_f32, atan2_f32le, atan2_f32be,
atan2_f64, atan2_f64le, atan2_f64be,
-};
+}
atan :: proc(x: $T) -> T where intrinsics.type_is_float(T) {
- return atan2(x, 1);
+ return atan2(x, 1)
}
asin :: proc(x: $T) -> T where intrinsics.type_is_float(T) {
- return atan2(x, 1 + sqrt(1 - x*x));
+ return atan2(x, 1 + sqrt(1 - x*x))
}
acos :: proc(x: $T) -> T where intrinsics.type_is_float(T) {
- return 2 * atan2(sqrt(1 - x), sqrt(1 + x));
+ return 2 * atan2(sqrt(1 - x), sqrt(1 + x))
}
sinh :: proc(x: $T) -> T where intrinsics.type_is_float(T) {
- return (exp(x) - exp(-x))*0.5;
+ return (exp(x) - exp(-x))*0.5
}
cosh :: proc(x: $T) -> T where intrinsics.type_is_float(T) {
- return (exp(x) + exp(-x))*0.5;
+ return (exp(x) + exp(-x))*0.5
}
tanh :: proc(x: $T) -> T where intrinsics.type_is_float(T) {
- t := exp(2*x);
- return (t - 1) / (t + 1);
-}
-
-F16_DIG :: 3;
-F16_EPSILON :: 0.00097656;
-F16_GUARD :: 0;
-F16_MANT_DIG :: 11;
-F16_MAX :: 65504.0;
-F16_MAX_10_EXP :: 4;
-F16_MAX_EXP :: 15;
-F16_MIN :: 6.10351562e-5;
-F16_MIN_10_EXP :: -4;
-F16_MIN_EXP :: -14;
-F16_NORMALIZE :: 0;
-F16_RADIX :: 2;
-F16_ROUNDS :: 1;
-
-
-F32_DIG :: 6;
-F32_EPSILON :: 1.192092896e-07;
-F32_GUARD :: 0;
-F32_MANT_DIG :: 24;
-F32_MAX :: 3.402823466e+38;
-F32_MAX_10_EXP :: 38;
-F32_MAX_EXP :: 128;
-F32_MIN :: 1.175494351e-38;
-F32_MIN_10_EXP :: -37;
-F32_MIN_EXP :: -125;
-F32_NORMALIZE :: 0;
-F32_RADIX :: 2;
-F32_ROUNDS :: 1;
-
-F64_DIG :: 15; // # of decimal digits of precision
-F64_EPSILON :: 2.2204460492503131e-016; // smallest such that 1.0+F64_EPSILON != 1.0
-F64_MANT_DIG :: 53; // # of bits in mantissa
-F64_MAX :: 1.7976931348623158e+308; // max value
-F64_MAX_10_EXP :: 308; // max decimal exponent
-F64_MAX_EXP :: 1024; // max binary exponent
-F64_MIN :: 2.2250738585072014e-308; // min positive value
-F64_MIN_10_EXP :: -307; // min decimal exponent
-F64_MIN_EXP :: -1021; // min binary exponent
-F64_RADIX :: 2; // exponent radix
-F64_ROUNDS :: 1; // addition rounding: near
+ t := exp(2*x)
+ return (t - 1) / (t + 1)
+}
+
+F16_DIG :: 3
+F16_EPSILON :: 0.00097656
+F16_GUARD :: 0
+F16_MANT_DIG :: 11
+F16_MAX :: 65504.0
+F16_MAX_10_EXP :: 4
+F16_MAX_EXP :: 15
+F16_MIN :: 6.10351562e-5
+F16_MIN_10_EXP :: -4
+F16_MIN_EXP :: -14
+F16_NORMALIZE :: 0
+F16_RADIX :: 2
+F16_ROUNDS :: 1
+
+
+F32_DIG :: 6
+F32_EPSILON :: 1.192092896e-07
+F32_GUARD :: 0
+F32_MANT_DIG :: 24
+F32_MAX :: 3.402823466e+38
+F32_MAX_10_EXP :: 38
+F32_MAX_EXP :: 128
+F32_MIN :: 1.175494351e-38
+F32_MIN_10_EXP :: -37
+F32_MIN_EXP :: -125
+F32_NORMALIZE :: 0
+F32_RADIX :: 2
+F32_ROUNDS :: 1
+
+F64_DIG :: 15 // # of decimal digits of precision
+F64_EPSILON :: 2.2204460492503131e-016 // smallest such that 1.0+F64_EPSILON != 1.0
+F64_MANT_DIG :: 53 // # of bits in mantissa
+F64_MAX :: 1.7976931348623158e+308 // max value
+F64_MAX_10_EXP :: 308 // max decimal exponent
+F64_MAX_EXP :: 1024 // max binary exponent
+F64_MIN :: 2.2250738585072014e-308 // min positive value
+F64_MIN_10_EXP :: -307 // min decimal exponent
+F64_MIN_EXP :: -1021 // min binary exponent
+F64_RADIX :: 2 // exponent radix
+F64_ROUNDS :: 1 // addition rounding: near
diff --git a/core/math/rand/normal.odin b/core/math/rand/normal.odin
index 653ca6c3b..4a77543ba 100644
--- a/core/math/rand/normal.odin
+++ b/core/math/rand/normal.odin
@@ -18,7 +18,7 @@ import "core:math"
// sample = norm_float64() * std_dev + mean
//
norm_float64 :: proc(r: ^Rand = nil) -> f64 {
- rn :: 3.442619855899;
+ rn :: 3.442619855899
@(static)
kn := [128]u32{
@@ -48,7 +48,7 @@ norm_float64 :: proc(r: ^Rand = nil) -> f64 {
0x7e3b737a, 0x7e268c2f, 0x7e0e3ff5, 0x7df1aa5d, 0x7dcf8c72,
0x7da61a1e, 0x7d72a0fb, 0x7d30e097, 0x7cd9b4ab, 0x7c600f1a,
0x7ba90bdc, 0x7a722176, 0x77d664e5,
- };
+ }
@(static)
wn := [128]f32{
@@ -84,7 +84,7 @@ norm_float64 :: proc(r: ^Rand = nil) -> f64 {
1.1781276e-09, 1.1962995e-09, 1.2158287e-09, 1.2369856e-09,
1.2601323e-09, 1.2857697e-09, 1.3146202e-09, 1.347784e-09,
1.3870636e-09, 1.4357403e-09, 1.5008659e-09, 1.6030948e-09,
- };
+ }
@(static)
fn := [128]f32{
@@ -114,39 +114,39 @@ norm_float64 :: proc(r: ^Rand = nil) -> f64 {
0.044660863, 0.040742867, 0.03688439, 0.033087887, 0.029356318,
0.025693292, 0.022103304, 0.018592102, 0.015167298, 0.011839478,
0.008624485, 0.005548995, 0.0026696292,
- };
+ }
- r := r;
+ r := r
if r == nil {
// NOTE(bill, 2020-09-07): Do this so that people can
// enforce the global random state if necessary with `nil`
- r = &global_rand;
+ r = &global_rand
}
for {
- j := i32(uint32(r));
- i := j & 0x7f;
- x := f64(j) * f64(wn[i]);
+ j := i32(uint32(r))
+ i := j & 0x7f
+ x := f64(j) * f64(wn[i])
if u32(abs(j)) < kn[i] {
// 99% of the time this will be hit
- return x;
+ return x
}
if i == 0 {
for {
- x = -math.ln(float64(r)) * (1.0/ rn);
- y := -math.ln(float64(r));
+ x = -math.ln(float64(r)) * (1.0/ rn)
+ y := -math.ln(float64(r))
if y+y >= x*x {
- break;
+ break
}
}
- return j > 0 ? rn + x : -rn - x;
+ return j > 0 ? rn + x : -rn - x
}
if fn[i]+f32(float64(r))*(fn[i-1]-fn[i]) < f32(math.exp(-0.5*x*x)) {
- return x;
+ return x
}
}
- return 0; // NOTE(bill): Will never be hit but this is here for sanity's sake
+ return 0 // NOTE(bill): Will never be hit but this is here for sanity's sake
}
diff --git a/core/math/rand/rand.odin b/core/math/rand/rand.odin
index 812cdc53d..1a833d3ca 100644
--- a/core/math/rand/rand.odin
+++ b/core/math/rand/rand.odin
@@ -7,56 +7,56 @@ Rand :: struct {
@(private)
-_GLOBAL_SEED_DATA := 1234567890;
+_GLOBAL_SEED_DATA := 1234567890
@(private)
-global_rand := create(u64(uintptr(&_GLOBAL_SEED_DATA)));
+global_rand := create(u64(uintptr(&_GLOBAL_SEED_DATA)))
set_global_seed :: proc(seed: u64) {
- init(&global_rand, seed);
+ init(&global_rand, seed)
}
create :: proc(seed: u64) -> Rand {
- r: Rand;
- init(&r, seed);
- return r;
+ r: Rand
+ init(&r, seed)
+ return r
}
init :: proc(r: ^Rand, seed: u64) {
- r.state = 0;
- r.inc = (seed << 1) | 1;
- _random(r);
- r.state += seed;
- _random(r);
+ r.state = 0
+ r.inc = (seed << 1) | 1
+ _random(r)
+ r.state += seed
+ _random(r)
}
_random :: proc(r: ^Rand) -> u32 {
- r := r;
+ r := r
if r == nil {
// NOTE(bill, 2020-09-07): Do this so that people can
// enforce the global random state if necessary with `nil`
- r = &global_rand;
+ r = &global_rand
}
- old_state := r.state;
- r.state = old_state * 6364136223846793005 + (r.inc|1);
- xor_shifted := u32(((old_state>>18) ~ old_state) >> 27);
- rot := u32(old_state >> 59);
- return (xor_shifted >> rot) | (xor_shifted << ((-rot) & 31));
+ old_state := r.state
+ r.state = old_state * 6364136223846793005 + (r.inc|1)
+ xor_shifted := u32(((old_state>>18) ~ old_state) >> 27)
+ rot := u32(old_state >> 59)
+ return (xor_shifted >> rot) | (xor_shifted << ((-rot) & 31))
}
uint32 :: proc(r: ^Rand = nil) -> u32 { return _random(r); }
uint64 :: proc(r: ^Rand = nil) -> u64 {
- a := u64(_random(r));
- b := u64(_random(r));
- return (a<<32) | b;
+ a := u64(_random(r))
+ b := u64(_random(r))
+ return (a<<32) | b
}
uint128 :: proc(r: ^Rand = nil) -> u128 {
- a := u128(_random(r));
- b := u128(_random(r));
- c := u128(_random(r));
- d := u128(_random(r));
- return (a<<96) | (b<<64) | (c<<32) | d;
+ a := u128(_random(r))
+ b := u128(_random(r))
+ c := u128(_random(r))
+ d := u128(_random(r))
+ return (a<<96) | (b<<64) | (c<<32) | d
}
int31 :: proc(r: ^Rand = nil) -> i32 { return i32(uint32(r) << 1 >> 1); }
@@ -65,57 +65,57 @@ int127 :: proc(r: ^Rand = nil) -> i128 { return i128(uint128(r) << 1 >> 1); }
int31_max :: proc(n: i32, r: ^Rand = nil) -> i32 {
if n <= 0 {
- panic("Invalid argument to int31_max");
+ panic("Invalid argument to int31_max")
}
if n&(n-1) == 0 {
- return int31(r) & (n-1);
+ return int31(r) & (n-1)
}
- max := i32((1<<31) - 1 - (1<<31)&u32(n));
- v := int31(r);
+ max := i32((1<<31) - 1 - (1<<31)&u32(n))
+ v := int31(r)
for v > max {
- v = int31(r);
+ v = int31(r)
}
- return v % n;
+ return v % n
}
int63_max :: proc(n: i64, r: ^Rand = nil) -> i64 {
if n <= 0 {
- panic("Invalid argument to int63_max");
+ panic("Invalid argument to int63_max")
}
if n&(n-1) == 0 {
- return int63(r) & (n-1);
+ return int63(r) & (n-1)
}
- max := i64((1<<63) - 1 - (1<<63)&u64(n));
- v := int63(r);
+ max := i64((1<<63) - 1 - (1<<63)&u64(n))
+ v := int63(r)
for v > max {
- v = int63(r);
+ v = int63(r)
}
- return v % n;
+ return v % n
}
int127_max :: proc(n: i128, r: ^Rand = nil) -> i128 {
if n <= 0 {
- panic("Invalid argument to int127_max");
+ panic("Invalid argument to int127_max")
}
if n&(n-1) == 0 {
- return int127(r) & (n-1);
+ return int127(r) & (n-1)
}
- max := i128((1<<63) - 1 - (1<<63)&u128(n));
- v := int127(r);
+ max := i128((1<<63) - 1 - (1<<63)&u128(n))
+ v := int127(r)
for v > max {
- v = int127(r);
+ v = int127(r)
}
- return v % n;
+ return v % n
}
int_max :: proc(n: int, r: ^Rand = nil) -> int {
if n <= 0 {
- panic("Invalid argument to int_max");
+ panic("Invalid argument to int_max")
}
when size_of(int) == 4 {
- return int(int31_max(i32(n), r));
+ return int(int31_max(i32(n), r))
} else {
- return int(int63_max(i64(n), r));
+ return int(int63_max(i64(n), r))
}
}
@@ -127,40 +127,40 @@ float32_range :: proc(lo, hi: f32, r: ^Rand = nil) -> f32 { return (hi-lo)*float
read :: proc(p: []byte, r: ^Rand = nil) -> (n: int) {
- pos := i8(0);
- val := i64(0);
+ pos := i8(0)
+ val := i64(0)
for n = 0; n < len(p); n += 1 {
if pos == 0 {
- val = int63(r);
- pos = 7;
+ val = int63(r)
+ pos = 7
}
- p[n] = byte(val);
- val >>= 8;
- pos -= 1;
+ p[n] = byte(val)
+ val >>= 8
+ pos -= 1
}
- return;
+ return
}
// perm returns a slice of n ints in a pseudo-random permutation of integers in the range [0, n)
perm :: proc(n: int, r: ^Rand = nil) -> []int {
- m := make([]int, n);
+ m := make([]int, n)
for i := 0; i < n; i += 1 {
- j := int_max(i+1, r);
- m[i] = m[j];
- m[j] = i;
+ j := int_max(i+1, r)
+ m[i] = m[j]
+ m[j] = i
}
- return m;
+ return m
}
shuffle :: proc(array: $T/[]$E, r: ^Rand = nil) {
- n := i64(len(array));
+ n := i64(len(array))
if n < 2 {
- return;
+ return
}
for i := i64(0); i < n; i += 1 {
- j := int63_max(n, r);
- array[i], array[j] = array[j], array[i];
+ j := int63_max(n, r)
+ array[i], array[j] = array[j], array[i]
}
}