mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-04 06:38:47 +00:00
Merge pull request #3147 from odin-lang/base-work
`base` library collection work
This commit is contained in:
@@ -5,6 +5,12 @@ package intrinsics
|
|||||||
// Package-Related
|
// Package-Related
|
||||||
is_package_imported :: proc(package_name: string) -> bool ---
|
is_package_imported :: proc(package_name: string) -> bool ---
|
||||||
|
|
||||||
|
// Matrix Related Procedures
|
||||||
|
transpose :: proc(m: $T/matrix[$R, $C]$E) -> matrix[C, R]E ---
|
||||||
|
outer_product :: proc(a: $A/[$X]$E, b: $B/[$Y]E) -> matrix[A, B]E ---
|
||||||
|
hadamard_product :: proc(a, b: $T/matrix[$R, $C]$E) -> T ---
|
||||||
|
matrix_flatten :: proc(m: $T/matrix[$R, $C]$E) -> [R*E]E ---
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
soa_struct :: proc($N: int, $T: typeid) -> type/#soa[N]T
|
soa_struct :: proc($N: int, $T: typeid) -> type/#soa[N]T
|
||||||
|
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
//+no-instrumentation
|
//+no-instrumentation
|
||||||
package runtime
|
package runtime
|
||||||
|
|
||||||
import "core:intrinsics"
|
import "base:intrinsics"
|
||||||
|
|
||||||
// NOTE(bill): This must match the compiler's
|
// NOTE(bill): This must match the compiler's
|
||||||
Calling_Convention :: enum u8 {
|
Calling_Convention :: enum u8 {
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
package runtime
|
package runtime
|
||||||
|
|
||||||
import "core:intrinsics"
|
import "base:intrinsics"
|
||||||
|
|
||||||
@builtin
|
@builtin
|
||||||
Maybe :: union($T: typeid) {T}
|
Maybe :: union($T: typeid) {T}
|
||||||
@@ -824,39 +824,6 @@ map_insert :: proc(m: ^$T/map[$K]$V, key: K, value: V, loc := #caller_location)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@builtin
|
|
||||||
incl_elem :: proc(s: ^$S/bit_set[$E; $U], elem: E) {
|
|
||||||
s^ |= {elem}
|
|
||||||
}
|
|
||||||
@builtin
|
|
||||||
incl_elems :: proc(s: ^$S/bit_set[$E; $U], elems: ..E) {
|
|
||||||
for elem in elems {
|
|
||||||
s^ |= {elem}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@builtin
|
|
||||||
incl_bit_set :: proc(s: ^$S/bit_set[$E; $U], other: S) {
|
|
||||||
s^ |= other
|
|
||||||
}
|
|
||||||
@builtin
|
|
||||||
excl_elem :: proc(s: ^$S/bit_set[$E; $U], elem: E) {
|
|
||||||
s^ &~= {elem}
|
|
||||||
}
|
|
||||||
@builtin
|
|
||||||
excl_elems :: proc(s: ^$S/bit_set[$E; $U], elems: ..E) {
|
|
||||||
for elem in elems {
|
|
||||||
s^ &~= {elem}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@builtin
|
|
||||||
excl_bit_set :: proc(s: ^$S/bit_set[$E; $U], other: S) {
|
|
||||||
s^ &~= other
|
|
||||||
}
|
|
||||||
|
|
||||||
@builtin incl :: proc{incl_elem, incl_elems, incl_bit_set}
|
|
||||||
@builtin excl :: proc{excl_elem, excl_elems, excl_bit_set}
|
|
||||||
|
|
||||||
|
|
||||||
@builtin
|
@builtin
|
||||||
card :: proc(s: $S/bit_set[$E; $U]) -> int {
|
card :: proc(s: $S/bit_set[$E; $U]) -> int {
|
||||||
when size_of(S) == 1 {
|
when size_of(S) == 1 {
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
package runtime
|
package runtime
|
||||||
|
|
||||||
import "core:intrinsics"
|
import "base:intrinsics"
|
||||||
_ :: intrinsics
|
_ :: intrinsics
|
||||||
|
|
||||||
/*
|
/*
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
package runtime
|
package runtime
|
||||||
|
|
||||||
import "core:intrinsics"
|
import "base:intrinsics"
|
||||||
|
|
||||||
DEFAULT_ARENA_GROWING_MINIMUM_BLOCK_SIZE :: uint(DEFAULT_TEMP_ALLOCATOR_BACKING_SIZE)
|
DEFAULT_ARENA_GROWING_MINIMUM_BLOCK_SIZE :: uint(DEFAULT_TEMP_ALLOCATOR_BACKING_SIZE)
|
||||||
|
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package runtime
|
||||||
|
|
||||||
|
when ODIN_DEFAULT_TO_NIL_ALLOCATOR {
|
||||||
|
default_allocator_proc :: nil_allocator_proc
|
||||||
|
default_allocator :: nil_allocator
|
||||||
|
} else when ODIN_DEFAULT_TO_PANIC_ALLOCATOR {
|
||||||
|
default_allocator_proc :: panic_allocator_proc
|
||||||
|
default_allocator :: panic_allocator
|
||||||
|
} else {
|
||||||
|
default_allocator :: heap_allocator
|
||||||
|
default_allocator_proc :: heap_allocator_proc
|
||||||
|
}
|
||||||
@@ -31,14 +31,6 @@ nil_allocator :: proc() -> Allocator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
when ODIN_OS == .Freestanding {
|
|
||||||
default_allocator_proc :: nil_allocator_proc
|
|
||||||
default_allocator :: nil_allocator
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
panic_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
|
panic_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
|
||||||
size, alignment: int,
|
size, alignment: int,
|
||||||
old_memory: rawptr, old_size: int, loc := #caller_location) -> ([]byte, Allocator_Error) {
|
old_memory: rawptr, old_size: int, loc := #caller_location) -> ([]byte, Allocator_Error) {
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
package runtime
|
package runtime
|
||||||
|
|
||||||
import "core:intrinsics"
|
import "base:intrinsics"
|
||||||
_ :: intrinsics
|
_ :: intrinsics
|
||||||
|
|
||||||
// High performance, cache-friendly, open-addressed Robin Hood hashing hash map
|
// High performance, cache-friendly, open-addressed Robin Hood hashing hash map
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
//+no-instrumentation
|
//+no-instrumentation
|
||||||
package runtime
|
package runtime
|
||||||
|
|
||||||
import "core:intrinsics"
|
import "base:intrinsics"
|
||||||
|
|
||||||
when ODIN_BUILD_MODE == .Dynamic {
|
when ODIN_BUILD_MODE == .Dynamic {
|
||||||
@(link_name="_odin_entry_point", linkage="strong", require/*, link_section=".init"*/)
|
@(link_name="_odin_entry_point", linkage="strong", require/*, link_section=".init"*/)
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
//+no-instrumentation
|
//+no-instrumentation
|
||||||
package runtime
|
package runtime
|
||||||
|
|
||||||
import "core:intrinsics"
|
import "base:intrinsics"
|
||||||
|
|
||||||
when !ODIN_TEST && !ODIN_NO_ENTRY_POINT {
|
when !ODIN_TEST && !ODIN_NO_ENTRY_POINT {
|
||||||
@(link_name="_start", linkage="strong", require, export)
|
@(link_name="_start", linkage="strong", require, export)
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
//+no-instrumentation
|
//+no-instrumentation
|
||||||
package runtime
|
package runtime
|
||||||
|
|
||||||
import "core:intrinsics"
|
import "base:intrinsics"
|
||||||
|
|
||||||
when ODIN_BUILD_MODE == .Dynamic {
|
when ODIN_BUILD_MODE == .Dynamic {
|
||||||
@(link_name="DllMain", linkage="strong", require)
|
@(link_name="DllMain", linkage="strong", require)
|
||||||
@@ -0,0 +1,110 @@
|
|||||||
|
package runtime
|
||||||
|
|
||||||
|
import "base:intrinsics"
|
||||||
|
|
||||||
|
heap_allocator :: proc() -> Allocator {
|
||||||
|
return Allocator{
|
||||||
|
procedure = heap_allocator_proc,
|
||||||
|
data = nil,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
heap_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
|
||||||
|
size, alignment: int,
|
||||||
|
old_memory: rawptr, old_size: int, loc := #caller_location) -> ([]byte, Allocator_Error) {
|
||||||
|
//
|
||||||
|
// NOTE(tetra, 2020-01-14): The heap doesn't respect alignment.
|
||||||
|
// Instead, we overallocate by `alignment + size_of(rawptr) - 1`, and insert
|
||||||
|
// padding. We also store the original pointer returned by heap_alloc right before
|
||||||
|
// the pointer we return to the user.
|
||||||
|
//
|
||||||
|
|
||||||
|
aligned_alloc :: proc(size, alignment: int, old_ptr: rawptr = nil, zero_memory := true) -> ([]byte, Allocator_Error) {
|
||||||
|
a := max(alignment, align_of(rawptr))
|
||||||
|
space := size + a - 1
|
||||||
|
|
||||||
|
allocated_mem: rawptr
|
||||||
|
if old_ptr != nil {
|
||||||
|
original_old_ptr := ([^]rawptr)(old_ptr)[-1]
|
||||||
|
allocated_mem = heap_resize(original_old_ptr, space+size_of(rawptr))
|
||||||
|
} else {
|
||||||
|
allocated_mem = heap_alloc(space+size_of(rawptr), zero_memory)
|
||||||
|
}
|
||||||
|
aligned_mem := rawptr(([^]u8)(allocated_mem)[size_of(rawptr):])
|
||||||
|
|
||||||
|
ptr := uintptr(aligned_mem)
|
||||||
|
aligned_ptr := (ptr - 1 + uintptr(a)) & -uintptr(a)
|
||||||
|
diff := int(aligned_ptr - ptr)
|
||||||
|
if (size + diff) > space || allocated_mem == nil {
|
||||||
|
return nil, .Out_Of_Memory
|
||||||
|
}
|
||||||
|
|
||||||
|
aligned_mem = rawptr(aligned_ptr)
|
||||||
|
([^]rawptr)(aligned_mem)[-1] = allocated_mem
|
||||||
|
|
||||||
|
return byte_slice(aligned_mem, size), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
aligned_free :: proc(p: rawptr) {
|
||||||
|
if p != nil {
|
||||||
|
heap_free(([^]rawptr)(p)[-1])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
aligned_resize :: proc(p: rawptr, old_size: int, new_size: int, new_alignment: int, zero_memory := true) -> (new_memory: []byte, err: Allocator_Error) {
|
||||||
|
if p == nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
new_memory = aligned_alloc(new_size, new_alignment, p, zero_memory) or_return
|
||||||
|
|
||||||
|
// NOTE: heap_resize does not zero the new memory, so we do it
|
||||||
|
if zero_memory && new_size > old_size {
|
||||||
|
new_region := raw_data(new_memory[old_size:])
|
||||||
|
intrinsics.mem_zero(new_region, new_size - old_size)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
switch mode {
|
||||||
|
case .Alloc, .Alloc_Non_Zeroed:
|
||||||
|
return aligned_alloc(size, alignment, nil, mode == .Alloc)
|
||||||
|
|
||||||
|
case .Free:
|
||||||
|
aligned_free(old_memory)
|
||||||
|
|
||||||
|
case .Free_All:
|
||||||
|
return nil, .Mode_Not_Implemented
|
||||||
|
|
||||||
|
case .Resize, .Resize_Non_Zeroed:
|
||||||
|
if old_memory == nil {
|
||||||
|
return aligned_alloc(size, alignment, nil, mode == .Resize)
|
||||||
|
}
|
||||||
|
return aligned_resize(old_memory, old_size, size, alignment, mode == .Resize)
|
||||||
|
|
||||||
|
case .Query_Features:
|
||||||
|
set := (^Allocator_Mode_Set)(old_memory)
|
||||||
|
if set != nil {
|
||||||
|
set^ = {.Alloc, .Alloc_Non_Zeroed, .Free, .Resize, .Resize_Non_Zeroed, .Query_Features}
|
||||||
|
}
|
||||||
|
return nil, nil
|
||||||
|
|
||||||
|
case .Query_Info:
|
||||||
|
return nil, .Mode_Not_Implemented
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
heap_alloc :: proc(size: int, zero_memory := true) -> rawptr {
|
||||||
|
return _heap_alloc(size, zero_memory)
|
||||||
|
}
|
||||||
|
|
||||||
|
heap_resize :: proc(ptr: rawptr, new_size: int) -> rawptr {
|
||||||
|
return _heap_resize(ptr, new_size)
|
||||||
|
}
|
||||||
|
|
||||||
|
heap_free :: proc(ptr: rawptr) {
|
||||||
|
_heap_free(ptr)
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
//+build js, wasi, freestanding, essence
|
||||||
|
//+private
|
||||||
|
package runtime
|
||||||
|
|
||||||
|
_heap_alloc :: proc(size: int, zero_memory := true) -> rawptr {
|
||||||
|
unimplemented("base:runtime 'heap_alloc' procedure is not supported on this platform")
|
||||||
|
}
|
||||||
|
|
||||||
|
_heap_resize :: proc(ptr: rawptr, new_size: int) -> rawptr {
|
||||||
|
unimplemented("base:runtime 'heap_resize' procedure is not supported on this platform")
|
||||||
|
}
|
||||||
|
|
||||||
|
_heap_free :: proc(ptr: rawptr) {
|
||||||
|
unimplemented("base:runtime 'heap_free' procedure is not supported on this platform")
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
//+build linux, darwin, freebsd, openbsd
|
||||||
|
//+private
|
||||||
|
package runtime
|
||||||
|
|
||||||
|
when ODIN_OS == .Darwin {
|
||||||
|
foreign import libc "system:System.framework"
|
||||||
|
} else {
|
||||||
|
foreign import libc "system:c"
|
||||||
|
}
|
||||||
|
|
||||||
|
@(default_calling_convention="c")
|
||||||
|
foreign libc {
|
||||||
|
@(link_name="malloc") _unix_malloc :: proc(size: int) -> rawptr ---
|
||||||
|
@(link_name="calloc") _unix_calloc :: proc(num, size: int) -> rawptr ---
|
||||||
|
@(link_name="free") _unix_free :: proc(ptr: rawptr) ---
|
||||||
|
@(link_name="realloc") _unix_realloc :: proc(ptr: rawptr, size: int) -> rawptr ---
|
||||||
|
}
|
||||||
|
|
||||||
|
_heap_alloc :: proc(size: int, zero_memory := true) -> rawptr {
|
||||||
|
if size <= 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if zero_memory {
|
||||||
|
return _unix_calloc(1, size)
|
||||||
|
} else {
|
||||||
|
return _unix_malloc(size)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_heap_resize :: proc(ptr: rawptr, new_size: int) -> rawptr {
|
||||||
|
// NOTE: _unix_realloc doesn't guarantee new memory will be zeroed on
|
||||||
|
// POSIX platforms. Ensure your caller takes this into account.
|
||||||
|
return _unix_realloc(ptr, new_size)
|
||||||
|
}
|
||||||
|
|
||||||
|
_heap_free :: proc(ptr: rawptr) {
|
||||||
|
_unix_free(ptr)
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
package runtime
|
||||||
|
|
||||||
|
foreign import kernel32 "system:Kernel32.lib"
|
||||||
|
|
||||||
|
@(private="file")
|
||||||
|
@(default_calling_convention="system")
|
||||||
|
foreign kernel32 {
|
||||||
|
// NOTE(bill): The types are not using the standard names (e.g. DWORD and LPVOID) to just minimizing the dependency
|
||||||
|
|
||||||
|
// default_allocator
|
||||||
|
GetProcessHeap :: proc() -> rawptr ---
|
||||||
|
HeapAlloc :: proc(hHeap: rawptr, dwFlags: u32, dwBytes: uint) -> rawptr ---
|
||||||
|
HeapReAlloc :: proc(hHeap: rawptr, dwFlags: u32, lpMem: rawptr, dwBytes: uint) -> rawptr ---
|
||||||
|
HeapFree :: proc(hHeap: rawptr, dwFlags: u32, lpMem: rawptr) -> b32 ---
|
||||||
|
}
|
||||||
|
|
||||||
|
_heap_alloc :: proc(size: int, zero_memory := true) -> rawptr {
|
||||||
|
HEAP_ZERO_MEMORY :: 0x00000008
|
||||||
|
return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY if zero_memory else 0, uint(size))
|
||||||
|
}
|
||||||
|
_heap_resize :: proc(ptr: rawptr, new_size: int) -> rawptr {
|
||||||
|
if new_size == 0 {
|
||||||
|
_heap_free(ptr)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if ptr == nil {
|
||||||
|
return _heap_alloc(new_size)
|
||||||
|
}
|
||||||
|
|
||||||
|
HEAP_ZERO_MEMORY :: 0x00000008
|
||||||
|
return HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ptr, uint(new_size))
|
||||||
|
}
|
||||||
|
_heap_free :: proc(ptr: rawptr) {
|
||||||
|
if ptr == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
HeapFree(GetProcessHeap(), 0, ptr)
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
package runtime
|
package runtime
|
||||||
|
|
||||||
import "core:intrinsics"
|
import "base:intrinsics"
|
||||||
|
|
||||||
@(private="file")
|
@(private="file")
|
||||||
IS_WASM :: ODIN_ARCH == .wasm32 || ODIN_ARCH == .wasm64p32
|
IS_WASM :: ODIN_ARCH == .wasm32 || ODIN_ARCH == .wasm64p32
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
//+build freebsd, openbsd
|
||||||
|
//+private
|
||||||
|
package runtime
|
||||||
|
|
||||||
|
foreign import libc "system:c"
|
||||||
|
|
||||||
|
@(default_calling_convention="c")
|
||||||
|
foreign libc {
|
||||||
|
@(link_name="write")
|
||||||
|
_unix_write :: proc(fd: i32, buf: rawptr, size: int) -> int ---
|
||||||
|
|
||||||
|
__error :: proc() -> ^i32 ---
|
||||||
|
}
|
||||||
|
|
||||||
|
_os_write :: proc "contextless" (data: []byte) -> (int, _OS_Errno) {
|
||||||
|
ret := _unix_write(2, raw_data(data), len(data))
|
||||||
|
if ret < len(data) {
|
||||||
|
err := __error()
|
||||||
|
return int(ret), _OS_Errno(err^ if err != nil else 0)
|
||||||
|
}
|
||||||
|
return int(ret), 0
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
//+build darwin
|
||||||
|
//+private
|
||||||
|
package runtime
|
||||||
|
|
||||||
|
foreign import libc "system:System.framework"
|
||||||
|
|
||||||
|
@(default_calling_convention="c")
|
||||||
|
foreign libc {
|
||||||
|
@(link_name="__stderrp")
|
||||||
|
_stderr: rawptr
|
||||||
|
|
||||||
|
@(link_name="fwrite")
|
||||||
|
_fwrite :: proc(ptr: rawptr, size: uint, nmemb: uint, stream: rawptr) -> uint ---
|
||||||
|
|
||||||
|
@(link_name="__error")
|
||||||
|
_get_errno :: proc() -> ^i32 ---
|
||||||
|
}
|
||||||
|
|
||||||
|
_os_write :: proc "contextless" (data: []byte) -> (int, _OS_Errno) {
|
||||||
|
ret := _fwrite(raw_data(data), 1, len(data), _stderr)
|
||||||
|
if ret < len(data) {
|
||||||
|
err := _get_errno()
|
||||||
|
return int(ret), _OS_Errno(err^ if err != nil else 0)
|
||||||
|
}
|
||||||
|
return int(ret), 0
|
||||||
|
}
|
||||||
+1
@@ -1,4 +1,5 @@
|
|||||||
//+build freestanding
|
//+build freestanding
|
||||||
|
//+private
|
||||||
package runtime
|
package runtime
|
||||||
|
|
||||||
// TODO(bill): reimplement `os.write`
|
// TODO(bill): reimplement `os.write`
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
//+build js
|
//+build js
|
||||||
|
//+private
|
||||||
package runtime
|
package runtime
|
||||||
|
|
||||||
foreign import "odin_env"
|
foreign import "odin_env"
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
//+private
|
||||||
|
package runtime
|
||||||
|
|
||||||
|
import "base:intrinsics"
|
||||||
|
|
||||||
|
_os_write :: proc "contextless" (data: []byte) -> (int, _OS_Errno) {
|
||||||
|
when ODIN_ARCH == .amd64 {
|
||||||
|
SYS_write :: uintptr(1)
|
||||||
|
} else when ODIN_ARCH == .arm64 {
|
||||||
|
SYS_write :: uintptr(64)
|
||||||
|
} else when ODIN_ARCH == .i386 {
|
||||||
|
SYS_write :: uintptr(4)
|
||||||
|
} else when ODIN_ARCH == .arm32 {
|
||||||
|
SYS_write :: uintptr(4)
|
||||||
|
}
|
||||||
|
|
||||||
|
stderr :: 2
|
||||||
|
|
||||||
|
ret := int(intrinsics.syscall(SYS_write, uintptr(stderr), uintptr(raw_data(data)), uintptr(len(data))))
|
||||||
|
if ret < 0 && ret > -4096 {
|
||||||
|
return 0, _OS_Errno(-ret)
|
||||||
|
}
|
||||||
|
return ret, 0
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
//+build wasi
|
//+build wasi
|
||||||
|
//+private
|
||||||
package runtime
|
package runtime
|
||||||
|
|
||||||
import "core:sys/wasm/wasi"
|
import "core:sys/wasm/wasi"
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
//+build windows
|
||||||
|
//+private
|
||||||
|
package runtime
|
||||||
|
|
||||||
|
foreign import kernel32 "system:Kernel32.lib"
|
||||||
|
|
||||||
|
@(private="file")
|
||||||
|
@(default_calling_convention="system")
|
||||||
|
foreign kernel32 {
|
||||||
|
// NOTE(bill): The types are not using the standard names (e.g. DWORD and LPVOID) to just minimizing the dependency
|
||||||
|
|
||||||
|
// os_write
|
||||||
|
GetStdHandle :: proc(which: u32) -> rawptr ---
|
||||||
|
SetHandleInformation :: proc(hObject: rawptr, dwMask: u32, dwFlags: u32) -> b32 ---
|
||||||
|
WriteFile :: proc(hFile: rawptr, lpBuffer: rawptr, nNumberOfBytesToWrite: u32, lpNumberOfBytesWritten: ^u32, lpOverlapped: rawptr) -> b32 ---
|
||||||
|
GetLastError :: proc() -> u32 ---
|
||||||
|
}
|
||||||
|
|
||||||
|
_os_write :: proc "contextless" (data: []byte) -> (n: int, err: _OS_Errno) #no_bounds_check {
|
||||||
|
if len(data) == 0 {
|
||||||
|
return 0, 0
|
||||||
|
}
|
||||||
|
|
||||||
|
STD_ERROR_HANDLE :: ~u32(0) -12 + 1
|
||||||
|
HANDLE_FLAG_INHERIT :: 0x00000001
|
||||||
|
MAX_RW :: 1<<30
|
||||||
|
|
||||||
|
h := GetStdHandle(STD_ERROR_HANDLE)
|
||||||
|
when size_of(uintptr) == 8 {
|
||||||
|
SetHandleInformation(h, HANDLE_FLAG_INHERIT, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
single_write_length: u32
|
||||||
|
total_write: i64
|
||||||
|
length := i64(len(data))
|
||||||
|
|
||||||
|
for total_write < length {
|
||||||
|
remaining := length - total_write
|
||||||
|
to_write := u32(min(i32(remaining), MAX_RW))
|
||||||
|
|
||||||
|
e := WriteFile(h, &data[total_write], to_write, &single_write_length, nil)
|
||||||
|
if single_write_length <= 0 || !e {
|
||||||
|
err = _OS_Errno(GetLastError())
|
||||||
|
n = int(total_write)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
total_write += i64(single_write_length)
|
||||||
|
}
|
||||||
|
n = int(total_write)
|
||||||
|
return
|
||||||
|
}
|
||||||
@@ -3,7 +3,7 @@ package runtime
|
|||||||
|
|
||||||
foreign import "system:Foundation.framework"
|
foreign import "system:Foundation.framework"
|
||||||
|
|
||||||
import "core:intrinsics"
|
import "base:intrinsics"
|
||||||
|
|
||||||
objc_id :: ^intrinsics.objc_object
|
objc_id :: ^intrinsics.objc_object
|
||||||
objc_Class :: ^intrinsics.objc_class
|
objc_Class :: ^intrinsics.objc_class
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
package runtime
|
package runtime
|
||||||
|
|
||||||
import "core:intrinsics"
|
import "base:intrinsics"
|
||||||
|
|
||||||
udivmod128 :: proc "c" (a, b: u128, rem: ^u128) -> u128 {
|
udivmod128 :: proc "c" (a, b: u128, rem: ^u128) -> u128 {
|
||||||
_ctz :: intrinsics.count_trailing_zeros
|
_ctz :: intrinsics.count_trailing_zeros
|
||||||
@@ -4,7 +4,7 @@ import "core:bytes"
|
|||||||
import "core:io"
|
import "core:io"
|
||||||
import "core:mem"
|
import "core:mem"
|
||||||
import "core:unicode/utf8"
|
import "core:unicode/utf8"
|
||||||
import "core:intrinsics"
|
import "base:intrinsics"
|
||||||
|
|
||||||
// Extra errors returns by scanning procedures
|
// Extra errors returns by scanning procedures
|
||||||
Scanner_Extra_Error :: enum i32 {
|
Scanner_Extra_Error :: enum i32 {
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
package c
|
package c
|
||||||
|
|
||||||
import builtin "core:builtin"
|
import builtin "base:builtin"
|
||||||
|
|
||||||
char :: builtin.u8 // assuming -funsigned-char
|
char :: builtin.u8 // assuming -funsigned-char
|
||||||
|
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ foreign libc {
|
|||||||
crealf :: proc(z: complex_float) -> float ---
|
crealf :: proc(z: complex_float) -> float ---
|
||||||
}
|
}
|
||||||
|
|
||||||
import builtin "core:builtin"
|
import builtin "base:builtin"
|
||||||
|
|
||||||
complex_float :: distinct builtin.complex64
|
complex_float :: distinct builtin.complex64
|
||||||
complex_double :: distinct builtin.complex128
|
complex_double :: distinct builtin.complex128
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package libc
|
|||||||
|
|
||||||
// 7.12 Mathematics
|
// 7.12 Mathematics
|
||||||
|
|
||||||
import "core:intrinsics"
|
import "base:intrinsics"
|
||||||
|
|
||||||
when ODIN_OS == .Windows {
|
when ODIN_OS == .Windows {
|
||||||
foreign import libc "system:libucrt.lib"
|
foreign import libc "system:libucrt.lib"
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package libc
|
|||||||
|
|
||||||
// 7.16 Variable arguments
|
// 7.16 Variable arguments
|
||||||
|
|
||||||
import "core:intrinsics"
|
import "base:intrinsics"
|
||||||
|
|
||||||
@(private="file")
|
@(private="file")
|
||||||
@(default_calling_convention="none")
|
@(default_calling_convention="none")
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package libc
|
|||||||
|
|
||||||
// 7.17 Atomics
|
// 7.17 Atomics
|
||||||
|
|
||||||
import "core:intrinsics"
|
import "base:intrinsics"
|
||||||
|
|
||||||
ATOMIC_BOOL_LOCK_FREE :: true
|
ATOMIC_BOOL_LOCK_FREE :: true
|
||||||
ATOMIC_CHAR_LOCK_FREE :: true
|
ATOMIC_CHAR_LOCK_FREE :: true
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package libc
|
package libc
|
||||||
|
|
||||||
import "core:runtime"
|
import "base:runtime"
|
||||||
|
|
||||||
// 7.24 String handling
|
// 7.24 String handling
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ package compress
|
|||||||
|
|
||||||
import "core:io"
|
import "core:io"
|
||||||
import "core:bytes"
|
import "core:bytes"
|
||||||
import "core:runtime"
|
import "base:runtime"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
These settings bound how much compression algorithms will allocate for their output buffer.
|
These settings bound how much compression algorithms will allocate for their output buffer.
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
// package shoco is an implementation of the shoco short string compressor
|
// package shoco is an implementation of the shoco short string compressor
|
||||||
package shoco
|
package shoco
|
||||||
|
|
||||||
import "core:intrinsics"
|
import "base:intrinsics"
|
||||||
import "core:compress"
|
import "core:compress"
|
||||||
|
|
||||||
Shoco_Pack :: struct {
|
Shoco_Pack :: struct {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package dynamic_bit_array
|
package dynamic_bit_array
|
||||||
|
|
||||||
import "core:intrinsics"
|
import "base:intrinsics"
|
||||||
import "core:mem"
|
import "core:mem"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package container_intrusive_list
|
package container_intrusive_list
|
||||||
|
|
||||||
import "core:intrinsics"
|
import "base:intrinsics"
|
||||||
|
|
||||||
// An intrusive doubly-linked list
|
// An intrusive doubly-linked list
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package container_lru
|
package container_lru
|
||||||
|
|
||||||
import "core:runtime"
|
import "base:runtime"
|
||||||
import "core:intrinsics"
|
import "base:intrinsics"
|
||||||
_ :: runtime
|
_ :: runtime
|
||||||
_ :: intrinsics
|
_ :: intrinsics
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package container_priority_queue
|
package container_priority_queue
|
||||||
|
|
||||||
import "core:builtin"
|
import "base:builtin"
|
||||||
|
|
||||||
Priority_Queue :: struct($T: typeid) {
|
Priority_Queue :: struct($T: typeid) {
|
||||||
queue: [dynamic]T,
|
queue: [dynamic]T,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package container_queue
|
package container_queue
|
||||||
|
|
||||||
import "core:builtin"
|
import "base:builtin"
|
||||||
import "core:runtime"
|
import "base:runtime"
|
||||||
_ :: runtime
|
_ :: runtime
|
||||||
|
|
||||||
// Dynamically resizable double-ended queue/ring-buffer
|
// Dynamically resizable double-ended queue/ring-buffer
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package container_small_array
|
package container_small_array
|
||||||
|
|
||||||
import "core:builtin"
|
import "base:builtin"
|
||||||
import "core:runtime"
|
import "base:runtime"
|
||||||
_ :: runtime
|
_ :: runtime
|
||||||
|
|
||||||
Small_Array :: struct($N: int, $T: typeid) where N >= 0 {
|
Small_Array :: struct($N: int, $T: typeid) where N >= 0 {
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
// map type is being used to accelerate lookups.
|
// map type is being used to accelerate lookups.
|
||||||
package container_topological_sort
|
package container_topological_sort
|
||||||
|
|
||||||
import "core:intrinsics"
|
import "base:intrinsics"
|
||||||
import "core:runtime"
|
import "base:runtime"
|
||||||
_ :: intrinsics
|
_ :: intrinsics
|
||||||
_ :: runtime
|
_ :: runtime
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
package dynlib
|
package dynlib
|
||||||
|
|
||||||
import "core:intrinsics"
|
import "base:intrinsics"
|
||||||
import "core:reflect"
|
import "core:reflect"
|
||||||
import "core:runtime"
|
import "base:runtime"
|
||||||
_ :: intrinsics
|
_ :: intrinsics
|
||||||
_ :: reflect
|
_ :: reflect
|
||||||
_ :: runtime
|
_ :: runtime
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ package dynlib
|
|||||||
|
|
||||||
import win32 "core:sys/windows"
|
import win32 "core:sys/windows"
|
||||||
import "core:strings"
|
import "core:strings"
|
||||||
import "core:runtime"
|
import "base:runtime"
|
||||||
import "core:reflect"
|
import "core:reflect"
|
||||||
|
|
||||||
_load_library :: proc(path: string, global_symbols := false) -> (Library, bool) {
|
_load_library :: proc(path: string, global_symbols := false) -> (Library, bool) {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package encoding_endian
|
package encoding_endian
|
||||||
|
|
||||||
import "core:intrinsics"
|
import "base:intrinsics"
|
||||||
import "core:math/bits"
|
import "core:math/bits"
|
||||||
|
|
||||||
Byte_Order :: enum u8 {
|
Byte_Order :: enum u8 {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package json
|
|||||||
|
|
||||||
import "core:mem"
|
import "core:mem"
|
||||||
import "core:math/bits"
|
import "core:math/bits"
|
||||||
import "core:runtime"
|
import "base:runtime"
|
||||||
import "core:strconv"
|
import "core:strconv"
|
||||||
import "core:strings"
|
import "core:strings"
|
||||||
import "core:reflect"
|
import "core:reflect"
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import "core:math"
|
|||||||
import "core:reflect"
|
import "core:reflect"
|
||||||
import "core:strconv"
|
import "core:strconv"
|
||||||
import "core:strings"
|
import "core:strings"
|
||||||
import "core:runtime"
|
import "base:runtime"
|
||||||
|
|
||||||
Unmarshal_Data_Error :: enum {
|
Unmarshal_Data_Error :: enum {
|
||||||
Invalid_Data,
|
Invalid_Data,
|
||||||
|
|||||||
@@ -29,11 +29,11 @@ package xml
|
|||||||
|
|
||||||
import "core:bytes"
|
import "core:bytes"
|
||||||
import "core:encoding/entity"
|
import "core:encoding/entity"
|
||||||
import "core:intrinsics"
|
import "base:intrinsics"
|
||||||
import "core:mem"
|
import "core:mem"
|
||||||
import "core:os"
|
import "core:os"
|
||||||
import "core:strings"
|
import "core:strings"
|
||||||
import "core:runtime"
|
import "base:runtime"
|
||||||
|
|
||||||
likely :: intrinsics.expect
|
likely :: intrinsics.expect
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -4,12 +4,12 @@ import "core:math/bits"
|
|||||||
import "core:mem"
|
import "core:mem"
|
||||||
import "core:io"
|
import "core:io"
|
||||||
import "core:reflect"
|
import "core:reflect"
|
||||||
import "core:runtime"
|
import "base:runtime"
|
||||||
import "core:strconv"
|
import "core:strconv"
|
||||||
import "core:strings"
|
import "core:strings"
|
||||||
import "core:time"
|
import "core:time"
|
||||||
import "core:unicode/utf8"
|
import "core:unicode/utf8"
|
||||||
import "core:intrinsics"
|
import "base:intrinsics"
|
||||||
|
|
||||||
// Internal data structure that stores the required information for formatted printing
|
// Internal data structure that stores the required information for formatted printing
|
||||||
Info :: struct {
|
Info :: struct {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
//+build !js
|
//+build !js
|
||||||
package fmt
|
package fmt
|
||||||
|
|
||||||
import "core:runtime"
|
import "base:runtime"
|
||||||
import "core:os"
|
import "core:os"
|
||||||
import "core:io"
|
import "core:io"
|
||||||
import "core:bufio"
|
import "core:bufio"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package hash
|
package hash
|
||||||
|
|
||||||
import "core:intrinsics"
|
import "base:intrinsics"
|
||||||
|
|
||||||
@(optimization_mode="speed")
|
@(optimization_mode="speed")
|
||||||
crc32 :: proc(data: []byte, seed := u32(0)) -> u32 #no_bounds_check {
|
crc32 :: proc(data: []byte, seed := u32(0)) -> u32 #no_bounds_check {
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
package hash
|
package hash
|
||||||
|
|
||||||
import "core:mem"
|
import "core:mem"
|
||||||
import "core:intrinsics"
|
import "base:intrinsics"
|
||||||
|
|
||||||
@(optimization_mode="speed")
|
@(optimization_mode="speed")
|
||||||
adler32 :: proc(data: []byte, seed := u32(1)) -> u32 #no_bounds_check {
|
adler32 :: proc(data: []byte, seed := u32(1)) -> u32 #no_bounds_check {
|
||||||
|
|||||||
@@ -9,8 +9,8 @@
|
|||||||
*/
|
*/
|
||||||
package xxhash
|
package xxhash
|
||||||
|
|
||||||
import "core:intrinsics"
|
import "base:intrinsics"
|
||||||
import "core:runtime"
|
import "base:runtime"
|
||||||
|
|
||||||
mem_copy :: runtime.mem_copy
|
mem_copy :: runtime.mem_copy
|
||||||
byte_swap :: intrinsics.byte_swap
|
byte_swap :: intrinsics.byte_swap
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
package xxhash
|
package xxhash
|
||||||
|
|
||||||
import "core:mem"
|
import "core:mem"
|
||||||
import "core:intrinsics"
|
import "base:intrinsics"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
=== XXH3 128-bit streaming ===
|
=== XXH3 128-bit streaming ===
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
*/
|
*/
|
||||||
package xxhash
|
package xxhash
|
||||||
|
|
||||||
import "core:intrinsics"
|
import "base:intrinsics"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*************************************************************************
|
*************************************************************************
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
*/
|
*/
|
||||||
package xxhash
|
package xxhash
|
||||||
|
|
||||||
import "core:intrinsics"
|
import "base:intrinsics"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
32-bit hash functions
|
32-bit hash functions
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
*/
|
*/
|
||||||
package xxhash
|
package xxhash
|
||||||
|
|
||||||
import "core:intrinsics"
|
import "base:intrinsics"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
64-bit hash functions
|
64-bit hash functions
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ package image
|
|||||||
import "core:bytes"
|
import "core:bytes"
|
||||||
import "core:mem"
|
import "core:mem"
|
||||||
import "core:compress"
|
import "core:compress"
|
||||||
import "core:runtime"
|
import "base:runtime"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
67_108_864 pixels max by default.
|
67_108_864 pixels max by default.
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import "core:mem"
|
|||||||
import "core:strconv"
|
import "core:strconv"
|
||||||
import "core:strings"
|
import "core:strings"
|
||||||
import "core:unicode"
|
import "core:unicode"
|
||||||
import "core:runtime"
|
import "base:runtime"
|
||||||
|
|
||||||
Image :: image.Image
|
Image :: image.Image
|
||||||
Format :: image.Netpbm_Format
|
Format :: image.Netpbm_Format
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import coretime "core:time"
|
|||||||
import "core:strings"
|
import "core:strings"
|
||||||
import "core:bytes"
|
import "core:bytes"
|
||||||
import "core:mem"
|
import "core:mem"
|
||||||
import "core:runtime"
|
import "base:runtime"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Cleanup of image-specific data.
|
Cleanup of image-specific data.
|
||||||
|
|||||||
@@ -22,8 +22,8 @@ import "core:hash"
|
|||||||
import "core:bytes"
|
import "core:bytes"
|
||||||
import "core:io"
|
import "core:io"
|
||||||
import "core:mem"
|
import "core:mem"
|
||||||
import "core:intrinsics"
|
import "base:intrinsics"
|
||||||
import "core:runtime"
|
import "base:runtime"
|
||||||
|
|
||||||
// Limit chunk sizes.
|
// Limit chunk sizes.
|
||||||
// By default: IDAT = 8k x 8k x 16-bits + 8k filter bytes.
|
// By default: IDAT = 8k x 8k x 16-bits + 8k filter bytes.
|
||||||
|
|||||||
+1
-1
@@ -3,7 +3,7 @@
|
|||||||
// operations into an abstracted stream interface.
|
// operations into an abstracted stream interface.
|
||||||
package io
|
package io
|
||||||
|
|
||||||
import "core:intrinsics"
|
import "base:intrinsics"
|
||||||
import "core:unicode/utf8"
|
import "core:unicode/utf8"
|
||||||
|
|
||||||
// Seek whence values
|
// Seek whence values
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
package log
|
package log
|
||||||
|
|
||||||
import "core:runtime"
|
import "base:runtime"
|
||||||
import "core:fmt"
|
import "core:fmt"
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package log
|
package log
|
||||||
|
|
||||||
import "core:runtime"
|
import "base:runtime"
|
||||||
import "core:fmt"
|
import "core:fmt"
|
||||||
|
|
||||||
Log_Allocator_Format :: enum {
|
Log_Allocator_Format :: enum {
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
package math_big
|
package math_big
|
||||||
|
|
||||||
import "core:intrinsics"
|
import "base:intrinsics"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
TODO: Make the tunables runtime adjustable where practical.
|
TODO: Make the tunables runtime adjustable where practical.
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
package math_big
|
package math_big
|
||||||
|
|
||||||
import "core:intrinsics"
|
import "base:intrinsics"
|
||||||
import rnd "core:math/rand"
|
import rnd "core:math/rand"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -28,9 +28,9 @@
|
|||||||
package math_big
|
package math_big
|
||||||
|
|
||||||
import "core:mem"
|
import "core:mem"
|
||||||
import "core:intrinsics"
|
import "base:intrinsics"
|
||||||
import rnd "core:math/rand"
|
import rnd "core:math/rand"
|
||||||
import "core:builtin"
|
import "base:builtin"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Low-level addition, unsigned. Handbook of Applied Cryptography, algorithm 14.7.
|
Low-level addition, unsigned. Handbook of Applied Cryptography, algorithm 14.7.
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
package math_big
|
package math_big
|
||||||
|
|
||||||
import "core:intrinsics"
|
import "base:intrinsics"
|
||||||
import "core:mem"
|
import "core:mem"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
package math_big
|
package math_big
|
||||||
|
|
||||||
import "core:intrinsics"
|
import "base:intrinsics"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
===========================
|
===========================
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
package math_big
|
package math_big
|
||||||
|
|
||||||
import "core:intrinsics"
|
import "base:intrinsics"
|
||||||
import "core:mem"
|
import "core:mem"
|
||||||
import "core:os"
|
import "core:os"
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package math_big
|
package math_big
|
||||||
|
|
||||||
import "core:builtin"
|
import "base:builtin"
|
||||||
import "core:intrinsics"
|
import "base:intrinsics"
|
||||||
import "core:math"
|
import "core:math"
|
||||||
|
|
||||||
Rat :: struct {
|
Rat :: struct {
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
package math_big
|
package math_big
|
||||||
|
|
||||||
import "core:time"
|
import "core:time"
|
||||||
import "core:runtime"
|
import "base:runtime"
|
||||||
|
|
||||||
print_value :: proc(name: string, value: i64) {
|
print_value :: proc(name: string, value: i64) {
|
||||||
runtime.print_string("\t")
|
runtime.print_string("\t")
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package math_bits
|
package math_bits
|
||||||
|
|
||||||
import "core:intrinsics"
|
import "base:intrinsics"
|
||||||
|
|
||||||
U8_MIN :: 0
|
U8_MIN :: 0
|
||||||
U16_MIN :: 0
|
U16_MIN :: 0
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package math_cmplx
|
package math_cmplx
|
||||||
|
|
||||||
import "core:builtin"
|
import "base:builtin"
|
||||||
import "core:math"
|
import "core:math"
|
||||||
|
|
||||||
// The original C code, the long comment, and the constants
|
// The original C code, the long comment, and the constants
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package math_cmplx
|
package math_cmplx
|
||||||
|
|
||||||
import "core:builtin"
|
import "base:builtin"
|
||||||
import "core:math"
|
import "core:math"
|
||||||
|
|
||||||
// The original C code, the long comment, and the constants
|
// The original C code, the long comment, and the constants
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
package ease
|
package ease
|
||||||
|
|
||||||
import "core:math"
|
import "core:math"
|
||||||
import "core:intrinsics"
|
import "base:intrinsics"
|
||||||
import "core:time"
|
import "core:time"
|
||||||
|
|
||||||
@(private) PI_2 :: math.PI / 2
|
@(private) PI_2 :: math.PI / 2
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package math_fixed
|
|||||||
|
|
||||||
import "core:math"
|
import "core:math"
|
||||||
import "core:strconv"
|
import "core:strconv"
|
||||||
import "core:intrinsics"
|
import "base:intrinsics"
|
||||||
_, _, _ :: intrinsics, strconv, math
|
_, _, _ :: intrinsics, strconv, math
|
||||||
|
|
||||||
Fixed :: struct($Backing: typeid, $Fraction_Width: uint)
|
Fixed :: struct($Backing: typeid, $Fraction_Width: uint)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package linalg
|
package linalg
|
||||||
|
|
||||||
import "core:builtin"
|
import "base:builtin"
|
||||||
import "core:math"
|
import "core:math"
|
||||||
|
|
||||||
@(require_results)
|
@(require_results)
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
package linalg
|
package linalg
|
||||||
|
|
||||||
import "core:math"
|
import "core:math"
|
||||||
import "core:builtin"
|
import "base:builtin"
|
||||||
import "core:intrinsics"
|
import "base:intrinsics"
|
||||||
|
|
||||||
// Generic
|
// Generic
|
||||||
|
|
||||||
@@ -66,7 +66,7 @@ quaternion256_dot :: proc "contextless" (a, b: $T/quaternion256) -> (c: f64) {
|
|||||||
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 :: builtin.outer_product
|
outer_product :: intrinsics.outer_product
|
||||||
|
|
||||||
@(require_results)
|
@(require_results)
|
||||||
quaternion_inverse :: proc "contextless" (q: $Q) -> Q where IS_QUATERNION(Q) {
|
quaternion_inverse :: proc "contextless" (q: $Q) -> Q where IS_QUATERNION(Q) {
|
||||||
@@ -179,8 +179,7 @@ identity :: proc "contextless" ($T: typeid/[$N][N]$E) -> (m: T) #no_bounds_check
|
|||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
trace :: builtin.matrix_trace
|
transpose :: intrinsics.transpose
|
||||||
transpose :: builtin.transpose
|
|
||||||
|
|
||||||
@(require_results)
|
@(require_results)
|
||||||
matrix_mul :: proc "contextless" (a, b: $M/matrix[$N, N]$E) -> (c: M)
|
matrix_mul :: proc "contextless" (a, b: $M/matrix[$N, N]$E) -> (c: M)
|
||||||
@@ -355,3 +354,273 @@ matrix_cast :: proc "contextless" (v: $A/matrix[$M, $N]$T, $Elem_Type: typeid) -
|
|||||||
@(require_results) to_quaternion64 :: #force_inline proc(v: $A/[$N]$T) -> [N]quaternion64 { return array_cast(v, quaternion64) }
|
@(require_results) to_quaternion64 :: #force_inline proc(v: $A/[$N]$T) -> [N]quaternion64 { return array_cast(v, quaternion64) }
|
||||||
@(require_results) to_quaternion128 :: #force_inline proc(v: $A/[$N]$T) -> [N]quaternion128 { return array_cast(v, quaternion128) }
|
@(require_results) to_quaternion128 :: #force_inline proc(v: $A/[$N]$T) -> [N]quaternion128 { return array_cast(v, quaternion128) }
|
||||||
@(require_results) to_quaternion256 :: #force_inline proc(v: $A/[$N]$T) -> [N]quaternion256 { return array_cast(v, quaternion256) }
|
@(require_results) to_quaternion256 :: #force_inline proc(v: $A/[$N]$T) -> [N]quaternion256 { return array_cast(v, quaternion256) }
|
||||||
|
|
||||||
|
|
||||||
|
hadamard_product :: intrinsics.hadamard_product
|
||||||
|
matrix_flatten :: intrinsics.matrix_flatten
|
||||||
|
|
||||||
|
|
||||||
|
determinant :: proc{
|
||||||
|
matrix1x1_determinant,
|
||||||
|
matrix2x2_determinant,
|
||||||
|
matrix3x3_determinant,
|
||||||
|
matrix4x4_determinant,
|
||||||
|
}
|
||||||
|
|
||||||
|
adjugate :: proc{
|
||||||
|
matrix1x1_adjugate,
|
||||||
|
matrix2x2_adjugate,
|
||||||
|
matrix3x3_adjugate,
|
||||||
|
matrix4x4_adjugate,
|
||||||
|
}
|
||||||
|
|
||||||
|
inverse_transpose :: proc{
|
||||||
|
matrix1x1_inverse_transpose,
|
||||||
|
matrix2x2_inverse_transpose,
|
||||||
|
matrix3x3_inverse_transpose,
|
||||||
|
matrix4x4_inverse_transpose,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inverse :: proc{
|
||||||
|
matrix1x1_inverse,
|
||||||
|
matrix2x2_inverse,
|
||||||
|
matrix3x3_inverse,
|
||||||
|
matrix4x4_inverse,
|
||||||
|
}
|
||||||
|
|
||||||
|
@(require_results)
|
||||||
|
hermitian_adjoint :: proc "contextless" (m: $M/matrix[$N, N]$T) -> M where intrinsics.type_is_complex(T), N >= 1 {
|
||||||
|
return conj(transpose(m))
|
||||||
|
}
|
||||||
|
|
||||||
|
@(require_results)
|
||||||
|
trace :: proc "contextless" (m: $M/matrix[$N, N]$T) -> (trace: T) {
|
||||||
|
for i in 0..<N {
|
||||||
|
trace += m[i, i]
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
@(require_results)
|
||||||
|
matrix_minor :: proc "contextless" (m: $M/matrix[$N, N]$T, #any_int row, column: int) -> (minor: T) where N > 1 {
|
||||||
|
K :: int(N-1)
|
||||||
|
cut_down: matrix[K, K]T
|
||||||
|
for col_idx in 0..<K {
|
||||||
|
j := col_idx + int(col_idx >= column)
|
||||||
|
for row_idx in 0..<K {
|
||||||
|
i := row_idx + int(row_idx >= row)
|
||||||
|
cut_down[row_idx, col_idx] = m[i, j]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return determinant(cut_down)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@(require_results)
|
||||||
|
matrix1x1_determinant :: proc "contextless" (m: $M/matrix[1, 1]$T) -> (det: T) {
|
||||||
|
return m[0, 0]
|
||||||
|
}
|
||||||
|
|
||||||
|
@(require_results)
|
||||||
|
matrix2x2_determinant :: proc "contextless" (m: $M/matrix[2, 2]$T) -> (det: T) {
|
||||||
|
return m[0, 0]*m[1, 1] - m[0, 1]*m[1, 0]
|
||||||
|
}
|
||||||
|
@(require_results)
|
||||||
|
matrix3x3_determinant :: proc "contextless" (m: $M/matrix[3, 3]$T) -> (det: T) {
|
||||||
|
a := +m[0, 0] * (m[1, 1] * m[2, 2] - m[1, 2] * m[2, 1])
|
||||||
|
b := -m[0, 1] * (m[1, 0] * m[2, 2] - m[1, 2] * m[2, 0])
|
||||||
|
c := +m[0, 2] * (m[1, 0] * m[2, 1] - m[1, 1] * m[2, 0])
|
||||||
|
return a + b + c
|
||||||
|
}
|
||||||
|
@(require_results)
|
||||||
|
matrix4x4_determinant :: proc "contextless" (m: $M/matrix[4, 4]$T) -> (det: T) {
|
||||||
|
a := adjugate(m)
|
||||||
|
#no_bounds_check for i in 0..<4 {
|
||||||
|
det += m[0, i] * a[0, i]
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@(require_results)
|
||||||
|
matrix1x1_adjugate :: proc "contextless" (x: $M/matrix[1, 1]$T) -> (y: M) {
|
||||||
|
y = x
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
@(require_results)
|
||||||
|
matrix2x2_adjugate :: proc "contextless" (x: $M/matrix[2, 2]$T) -> (y: M) {
|
||||||
|
y[0, 0] = +x[1, 1]
|
||||||
|
y[0, 1] = -x[1, 0]
|
||||||
|
y[1, 0] = -x[0, 1]
|
||||||
|
y[1, 1] = +x[0, 0]
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
@(require_results)
|
||||||
|
matrix3x3_adjugate :: proc "contextless" (m: $M/matrix[3, 3]$T) -> (y: M) {
|
||||||
|
y[0, 0] = +(m[1, 1] * m[2, 2] - m[2, 1] * m[1, 2])
|
||||||
|
y[0, 1] = -(m[1, 0] * m[2, 2] - m[2, 0] * m[1, 2])
|
||||||
|
y[0, 2] = +(m[1, 0] * m[2, 1] - m[2, 0] * m[1, 1])
|
||||||
|
y[1, 0] = -(m[0, 1] * m[2, 2] - m[2, 1] * m[0, 2])
|
||||||
|
y[1, 1] = +(m[0, 0] * m[2, 2] - m[2, 0] * m[0, 2])
|
||||||
|
y[1, 2] = -(m[0, 0] * m[2, 1] - m[2, 0] * m[0, 1])
|
||||||
|
y[2, 0] = +(m[0, 1] * m[1, 2] - m[1, 1] * m[0, 2])
|
||||||
|
y[2, 1] = -(m[0, 0] * m[1, 2] - m[1, 0] * m[0, 2])
|
||||||
|
y[2, 2] = +(m[0, 0] * m[1, 1] - m[1, 0] * m[0, 1])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@(require_results)
|
||||||
|
matrix4x4_adjugate :: proc "contextless" (x: $M/matrix[4, 4]$T) -> (y: M) {
|
||||||
|
for i in 0..<4 {
|
||||||
|
for j in 0..<4 {
|
||||||
|
sign: T = 1 if (i + j) % 2 == 0 else -1
|
||||||
|
y[i, j] = sign * matrix_minor(x, i, j)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
@(require_results)
|
||||||
|
matrix1x1_inverse_transpose :: proc "contextless" (x: $M/matrix[1, 1]$T) -> (y: M) {
|
||||||
|
y[0, 0] = 1/x[0, 0]
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
@(require_results)
|
||||||
|
matrix2x2_inverse_transpose :: proc "contextless" (x: $M/matrix[2, 2]$T) -> (y: M) {
|
||||||
|
d := x[0, 0]*x[1, 1] - x[0, 1]*x[1, 0]
|
||||||
|
when intrinsics.type_is_integer(T) {
|
||||||
|
y[0, 0] = +x[1, 1] / d
|
||||||
|
y[1, 0] = -x[0, 1] / d
|
||||||
|
y[0, 1] = -x[1, 0] / d
|
||||||
|
y[1, 1] = +x[0, 0] / d
|
||||||
|
} else {
|
||||||
|
id := 1 / d
|
||||||
|
y[0, 0] = +x[1, 1] * id
|
||||||
|
y[1, 0] = -x[0, 1] * id
|
||||||
|
y[0, 1] = -x[1, 0] * id
|
||||||
|
y[1, 1] = +x[0, 0] * id
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
@(require_results)
|
||||||
|
matrix3x3_inverse_transpose :: proc "contextless" (x: $M/matrix[3, 3]$T) -> (y: M) #no_bounds_check {
|
||||||
|
a := adjugate(x)
|
||||||
|
d := determinant(x)
|
||||||
|
when intrinsics.type_is_integer(T) {
|
||||||
|
for i in 0..<3 {
|
||||||
|
for j in 0..<3 {
|
||||||
|
y[i, j] = a[i, j] / d
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
id := 1/d
|
||||||
|
for i in 0..<3 {
|
||||||
|
for j in 0..<3 {
|
||||||
|
y[i, j] = a[i, j] * id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
@(require_results)
|
||||||
|
matrix4x4_inverse_transpose :: proc "contextless" (x: $M/matrix[4, 4]$T) -> (y: M) #no_bounds_check {
|
||||||
|
a := adjugate(x)
|
||||||
|
d: T
|
||||||
|
for i in 0..<4 {
|
||||||
|
d += x[0, i] * a[0, i]
|
||||||
|
}
|
||||||
|
when intrinsics.type_is_integer(T) {
|
||||||
|
for i in 0..<4 {
|
||||||
|
for j in 0..<4 {
|
||||||
|
y[i, j] = a[i, j] / d
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
id := 1/d
|
||||||
|
for i in 0..<4 {
|
||||||
|
for j in 0..<4 {
|
||||||
|
y[i, j] = a[i, j] * id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
@(require_results)
|
||||||
|
matrix1x1_inverse :: proc "contextless" (x: $M/matrix[1, 1]$T) -> (y: M) {
|
||||||
|
y[0, 0] = 1/x[0, 0]
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
@(require_results)
|
||||||
|
matrix2x2_inverse :: proc "contextless" (x: $M/matrix[2, 2]$T) -> (y: M) {
|
||||||
|
d := x[0, 0]*x[1, 1] - x[0, 1]*x[1, 0]
|
||||||
|
when intrinsics.type_is_integer(T) {
|
||||||
|
y[0, 0] = +x[1, 1] / d
|
||||||
|
y[0, 1] = -x[0, 1] / d
|
||||||
|
y[1, 0] = -x[1, 0] / d
|
||||||
|
y[1, 1] = +x[0, 0] / d
|
||||||
|
} else {
|
||||||
|
id := 1 / d
|
||||||
|
y[0, 0] = +x[1, 1] * id
|
||||||
|
y[0, 1] = -x[0, 1] * id
|
||||||
|
y[1, 0] = -x[1, 0] * id
|
||||||
|
y[1, 1] = +x[0, 0] * id
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
@(require_results)
|
||||||
|
matrix3x3_inverse :: proc "contextless" (x: $M/matrix[3, 3]$T) -> (y: M) #no_bounds_check {
|
||||||
|
a := adjugate(x)
|
||||||
|
d := determinant(x)
|
||||||
|
when intrinsics.type_is_integer(T) {
|
||||||
|
for i in 0..<3 {
|
||||||
|
for j in 0..<3 {
|
||||||
|
y[i, j] = a[j, i] / d
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
id := 1/d
|
||||||
|
for i in 0..<3 {
|
||||||
|
for j in 0..<3 {
|
||||||
|
y[i, j] = a[j, i] * id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
@(require_results)
|
||||||
|
matrix4x4_inverse :: proc "contextless" (x: $M/matrix[4, 4]$T) -> (y: M) #no_bounds_check {
|
||||||
|
a := adjugate(x)
|
||||||
|
d: T
|
||||||
|
for i in 0..<4 {
|
||||||
|
d += x[0, i] * a[0, i]
|
||||||
|
}
|
||||||
|
when intrinsics.type_is_integer(T) {
|
||||||
|
for i in 0..<4 {
|
||||||
|
for j in 0..<4 {
|
||||||
|
y[i, j] = a[j, i] / d
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
id := 1/d
|
||||||
|
for i in 0..<4 {
|
||||||
|
for j in 0..<4 {
|
||||||
|
y[i, j] = a[j, i] * id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
// core:math/linalg/glsl implements a GLSL-like mathematics library plus numerous other utility procedures
|
// core:math/linalg/glsl implements a GLSL-like mathematics library plus numerous other utility procedures
|
||||||
package math_linalg_glsl
|
package math_linalg_glsl
|
||||||
|
|
||||||
import "core:builtin"
|
import "base:builtin"
|
||||||
|
import "base:intrinsics"
|
||||||
|
|
||||||
TAU :: 6.28318530717958647692528676655900576
|
TAU :: 6.28318530717958647692528676655900576
|
||||||
PI :: 3.14159265358979323846264338327950288
|
PI :: 3.14159265358979323846264338327950288
|
||||||
@@ -1838,30 +1839,281 @@ dquatMulDvec3 :: proc "c" (q: dquat, v: dvec3) -> dvec3 {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
@(require_results) inverse_mat2 :: proc "c" (m: mat2) -> mat2 { return builtin.inverse(m) }
|
@(require_results) inverse_mat2 :: proc "c" (m: mat2) -> mat2 { return inverse_matrix2x2(m) }
|
||||||
@(require_results) inverse_mat3 :: proc "c" (m: mat3) -> mat3 { return builtin.inverse(m) }
|
@(require_results) inverse_mat3 :: proc "c" (m: mat3) -> mat3 { return inverse_matrix3x3(m) }
|
||||||
@(require_results) inverse_mat4 :: proc "c" (m: mat4) -> mat4 { return builtin.inverse(m) }
|
@(require_results) inverse_mat4 :: proc "c" (m: mat4) -> mat4 { return inverse_matrix4x4(m) }
|
||||||
@(require_results) inverse_dmat2 :: proc "c" (m: dmat2) -> dmat2 { return builtin.inverse(m) }
|
@(require_results) inverse_dmat2 :: proc "c" (m: dmat2) -> dmat2 { return inverse_matrix2x2(m) }
|
||||||
@(require_results) inverse_dmat3 :: proc "c" (m: dmat3) -> dmat3 { return builtin.inverse(m) }
|
@(require_results) inverse_dmat3 :: proc "c" (m: dmat3) -> dmat3 { return inverse_matrix3x3(m) }
|
||||||
@(require_results) inverse_dmat4 :: proc "c" (m: dmat4) -> dmat4 { return builtin.inverse(m) }
|
@(require_results) inverse_dmat4 :: proc "c" (m: dmat4) -> dmat4 { return inverse_matrix4x4(m) }
|
||||||
@(require_results) inverse_quat :: proc "c" (q: quat) -> quat { return 1/q }
|
@(require_results) inverse_quat :: proc "c" (q: quat) -> quat { return 1/q }
|
||||||
@(require_results) inverse_dquat :: proc "c" (q: dquat) -> dquat { return 1/q }
|
@(require_results) inverse_dquat :: proc "c" (q: dquat) -> dquat { return 1/q }
|
||||||
|
|
||||||
|
|
||||||
|
transpose :: intrinsics.transpose
|
||||||
|
|
||||||
|
|
||||||
|
determinant :: proc{
|
||||||
|
determinant_matrix1x1,
|
||||||
|
determinant_matrix2x2,
|
||||||
|
determinant_matrix3x3,
|
||||||
|
determinant_matrix4x4,
|
||||||
|
}
|
||||||
|
|
||||||
|
adjugate :: proc{
|
||||||
|
adjugate_matrix1x1,
|
||||||
|
adjugate_matrix2x2,
|
||||||
|
adjugate_matrix3x3,
|
||||||
|
adjugate_matrix4x4,
|
||||||
|
}
|
||||||
|
|
||||||
|
inverse_transpose :: proc{
|
||||||
|
inverse_transpose_matrix1x1,
|
||||||
|
inverse_transpose_matrix2x2,
|
||||||
|
inverse_transpose_matrix3x3,
|
||||||
|
inverse_transpose_matrix4x4,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
inverse :: proc{
|
inverse :: proc{
|
||||||
inverse_mat2,
|
inverse_matrix1x1,
|
||||||
inverse_mat3,
|
inverse_matrix2x2,
|
||||||
inverse_mat4,
|
inverse_matrix3x3,
|
||||||
inverse_dmat2,
|
inverse_matrix4x4,
|
||||||
inverse_dmat3,
|
}
|
||||||
inverse_dmat4,
|
|
||||||
inverse_quat,
|
@(require_results)
|
||||||
inverse_dquat,
|
hermitian_adjoint :: proc "contextless" (m: $M/matrix[$N, N]$T) -> M where intrinsics.type_is_complex(T), N >= 1 {
|
||||||
|
return conj(transpose(m))
|
||||||
|
}
|
||||||
|
|
||||||
|
@(require_results)
|
||||||
|
trace :: proc "contextless" (m: $M/matrix[$N, N]$T) -> (trace: T) {
|
||||||
|
for i in 0..<N {
|
||||||
|
trace += m[i, i]
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
@(require_results)
|
||||||
|
matrix_minor :: proc "contextless" (m: $M/matrix[$N, N]$T, #any_int row, column: int) -> (minor: T) where N > 1 {
|
||||||
|
K :: int(N-1)
|
||||||
|
cut_down: matrix[K, K]T
|
||||||
|
for col_idx in 0..<K {
|
||||||
|
j := col_idx + int(col_idx >= column)
|
||||||
|
for row_idx in 0..<K {
|
||||||
|
i := row_idx + int(row_idx >= row)
|
||||||
|
cut_down[row_idx, col_idx] = m[i, j]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return determinant(cut_down)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@(require_results)
|
||||||
|
determinant_matrix1x1 :: proc "contextless" (m: $M/matrix[1, 1]$T) -> (det: T) {
|
||||||
|
return m[0, 0]
|
||||||
|
}
|
||||||
|
|
||||||
|
@(require_results)
|
||||||
|
determinant_matrix2x2 :: proc "contextless" (m: $M/matrix[2, 2]$T) -> (det: T) {
|
||||||
|
return m[0, 0]*m[1, 1] - m[0, 1]*m[1, 0]
|
||||||
|
}
|
||||||
|
@(require_results)
|
||||||
|
determinant_matrix3x3 :: proc "contextless" (m: $M/matrix[3, 3]$T) -> (det: T) {
|
||||||
|
a := +m[0, 0] * (m[1, 1] * m[2, 2] - m[1, 2] * m[2, 1])
|
||||||
|
b := -m[0, 1] * (m[1, 0] * m[2, 2] - m[1, 2] * m[2, 0])
|
||||||
|
c := +m[0, 2] * (m[1, 0] * m[2, 1] - m[1, 1] * m[2, 0])
|
||||||
|
return a + b + c
|
||||||
|
}
|
||||||
|
@(require_results)
|
||||||
|
determinant_matrix4x4 :: proc "contextless" (m: $M/matrix[4, 4]$T) -> (det: T) {
|
||||||
|
a := adjugate(m)
|
||||||
|
#no_bounds_check for i in 0..<4 {
|
||||||
|
det += m[0, i] * a[0, i]
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@(require_results)
|
||||||
|
adjugate_matrix1x1 :: proc "contextless" (x: $M/matrix[1, 1]$T) -> (y: M) {
|
||||||
|
y = x
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
@(require_results)
|
||||||
|
adjugate_matrix2x2 :: proc "contextless" (x: $M/matrix[2, 2]$T) -> (y: M) {
|
||||||
|
y[0, 0] = +x[1, 1]
|
||||||
|
y[0, 1] = -x[1, 0]
|
||||||
|
y[1, 0] = -x[0, 1]
|
||||||
|
y[1, 1] = +x[0, 0]
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
@(require_results)
|
||||||
|
adjugate_matrix3x3 :: proc "contextless" (m: $M/matrix[3, 3]$T) -> (y: M) {
|
||||||
|
y[0, 0] = +(m[1, 1] * m[2, 2] - m[2, 1] * m[1, 2])
|
||||||
|
y[0, 1] = -(m[1, 0] * m[2, 2] - m[2, 0] * m[1, 2])
|
||||||
|
y[0, 2] = +(m[1, 0] * m[2, 1] - m[2, 0] * m[1, 1])
|
||||||
|
y[1, 0] = -(m[0, 1] * m[2, 2] - m[2, 1] * m[0, 2])
|
||||||
|
y[1, 1] = +(m[0, 0] * m[2, 2] - m[2, 0] * m[0, 2])
|
||||||
|
y[1, 2] = -(m[0, 0] * m[2, 1] - m[2, 0] * m[0, 1])
|
||||||
|
y[2, 0] = +(m[0, 1] * m[1, 2] - m[1, 1] * m[0, 2])
|
||||||
|
y[2, 1] = -(m[0, 0] * m[1, 2] - m[1, 0] * m[0, 2])
|
||||||
|
y[2, 2] = +(m[0, 0] * m[1, 1] - m[1, 0] * m[0, 1])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@(require_results)
|
||||||
|
adjugate_matrix4x4 :: proc "contextless" (x: $M/matrix[4, 4]$T) -> (y: M) {
|
||||||
|
for i in 0..<4 {
|
||||||
|
for j in 0..<4 {
|
||||||
|
sign: T = 1 if (i + j) % 2 == 0 else -1
|
||||||
|
y[i, j] = sign * matrix_minor(x, i, j)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
@(require_results)
|
||||||
|
inverse_transpose_matrix1x1 :: proc "contextless" (x: $M/matrix[1, 1]$T) -> (y: M) {
|
||||||
|
y[0, 0] = 1/x[0, 0]
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
@(require_results)
|
||||||
|
inverse_transpose_matrix2x2 :: proc "contextless" (x: $M/matrix[2, 2]$T) -> (y: M) {
|
||||||
|
d := x[0, 0]*x[1, 1] - x[0, 1]*x[1, 0]
|
||||||
|
when intrinsics.type_is_integer(T) {
|
||||||
|
y[0, 0] = +x[1, 1] / d
|
||||||
|
y[1, 0] = -x[0, 1] / d
|
||||||
|
y[0, 1] = -x[1, 0] / d
|
||||||
|
y[1, 1] = +x[0, 0] / d
|
||||||
|
} else {
|
||||||
|
id := 1 / d
|
||||||
|
y[0, 0] = +x[1, 1] * id
|
||||||
|
y[1, 0] = -x[0, 1] * id
|
||||||
|
y[0, 1] = -x[1, 0] * id
|
||||||
|
y[1, 1] = +x[0, 0] * id
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
@(require_results)
|
||||||
|
inverse_transpose_matrix3x3 :: proc "contextless" (x: $M/matrix[3, 3]$T) -> (y: M) #no_bounds_check {
|
||||||
|
a := adjugate(x)
|
||||||
|
d := determinant(x)
|
||||||
|
when intrinsics.type_is_integer(T) {
|
||||||
|
for i in 0..<3 {
|
||||||
|
for j in 0..<3 {
|
||||||
|
y[i, j] = a[i, j] / d
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
id := 1/d
|
||||||
|
for i in 0..<3 {
|
||||||
|
for j in 0..<3 {
|
||||||
|
y[i, j] = a[i, j] * id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
@(require_results)
|
||||||
|
inverse_transpose_matrix4x4 :: proc "contextless" (x: $M/matrix[4, 4]$T) -> (y: M) #no_bounds_check {
|
||||||
|
a := adjugate(x)
|
||||||
|
d: T
|
||||||
|
for i in 0..<4 {
|
||||||
|
d += x[0, i] * a[0, i]
|
||||||
|
}
|
||||||
|
when intrinsics.type_is_integer(T) {
|
||||||
|
for i in 0..<4 {
|
||||||
|
for j in 0..<4 {
|
||||||
|
y[i, j] = a[i, j] / d
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
id := 1/d
|
||||||
|
for i in 0..<4 {
|
||||||
|
for j in 0..<4 {
|
||||||
|
y[i, j] = a[i, j] * id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
@(require_results)
|
||||||
|
inverse_matrix1x1 :: proc "contextless" (x: $M/matrix[1, 1]$T) -> (y: M) {
|
||||||
|
y[0, 0] = 1/x[0, 0]
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
@(require_results)
|
||||||
|
inverse_matrix2x2 :: proc "contextless" (x: $M/matrix[2, 2]$T) -> (y: M) {
|
||||||
|
d := x[0, 0]*x[1, 1] - x[0, 1]*x[1, 0]
|
||||||
|
when intrinsics.type_is_integer(T) {
|
||||||
|
y[0, 0] = +x[1, 1] / d
|
||||||
|
y[0, 1] = -x[0, 1] / d
|
||||||
|
y[1, 0] = -x[1, 0] / d
|
||||||
|
y[1, 1] = +x[0, 0] / d
|
||||||
|
} else {
|
||||||
|
id := 1 / d
|
||||||
|
y[0, 0] = +x[1, 1] * id
|
||||||
|
y[0, 1] = -x[0, 1] * id
|
||||||
|
y[1, 0] = -x[1, 0] * id
|
||||||
|
y[1, 1] = +x[0, 0] * id
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
@(require_results)
|
||||||
|
inverse_matrix3x3 :: proc "contextless" (x: $M/matrix[3, 3]$T) -> (y: M) #no_bounds_check {
|
||||||
|
a := adjugate(x)
|
||||||
|
d := determinant(x)
|
||||||
|
when intrinsics.type_is_integer(T) {
|
||||||
|
for i in 0..<3 {
|
||||||
|
for j in 0..<3 {
|
||||||
|
y[i, j] = a[j, i] / d
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
id := 1/d
|
||||||
|
for i in 0..<3 {
|
||||||
|
for j in 0..<3 {
|
||||||
|
y[i, j] = a[j, i] * id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
@(require_results)
|
||||||
|
inverse_matrix4x4 :: proc "contextless" (x: $M/matrix[4, 4]$T) -> (y: M) #no_bounds_check {
|
||||||
|
a := adjugate(x)
|
||||||
|
d: T
|
||||||
|
for i in 0..<4 {
|
||||||
|
d += x[0, i] * a[0, i]
|
||||||
|
}
|
||||||
|
when intrinsics.type_is_integer(T) {
|
||||||
|
for i in 0..<4 {
|
||||||
|
for j in 0..<4 {
|
||||||
|
y[i, j] = a[j, i] / d
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
id := 1/d
|
||||||
|
for i in 0..<4 {
|
||||||
|
for j in 0..<4 {
|
||||||
|
y[i, j] = a[j, i] * id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
transpose :: builtin.transpose
|
|
||||||
inverse_transpose :: builtin.inverse_transpose
|
|
||||||
adjugate :: builtin.adjugate
|
|
||||||
hermitian_adjoint :: builtin.hermitian_adjoint
|
|
||||||
minor :: builtin.matrix_minor
|
|
||||||
determinant :: builtin.determinant
|
|
||||||
trace :: builtin.matrix_trace
|
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
// core:math/linalg/hlsl implements a HLSL-like mathematics library plus numerous other utility procedures
|
// core:math/linalg/hlsl implements a HLSL-like mathematics library plus numerous other utility procedures
|
||||||
package math_linalg_hlsl
|
package math_linalg_hlsl
|
||||||
|
|
||||||
import "core:builtin"
|
import "base:builtin"
|
||||||
|
import "base:intrinsics"
|
||||||
|
|
||||||
TAU :: 6.28318530717958647692528676655900576
|
TAU :: 6.28318530717958647692528676655900576
|
||||||
PI :: 3.14159265358979323846264338327950288
|
PI :: 3.14159265358979323846264338327950288
|
||||||
@@ -1471,14 +1472,14 @@ not :: proc{
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
@(require_results) inverse_float1x1 :: proc "c" (m: float1x1) -> float1x1 { return builtin.inverse(m) }
|
@(require_results) inverse_float1x1 :: proc "c" (m: float1x1) -> float1x1 { return inverse_matrix1x1(m) }
|
||||||
@(require_results) inverse_float2x2 :: proc "c" (m: float2x2) -> float2x2 { return builtin.inverse(m) }
|
@(require_results) inverse_float2x2 :: proc "c" (m: float2x2) -> float2x2 { return inverse_matrix2x2(m) }
|
||||||
@(require_results) inverse_float3x3 :: proc "c" (m: float3x3) -> float3x3 { return builtin.inverse(m) }
|
@(require_results) inverse_float3x3 :: proc "c" (m: float3x3) -> float3x3 { return inverse_matrix3x3(m) }
|
||||||
@(require_results) inverse_float4x4 :: proc "c" (m: float4x4) -> float4x4 { return builtin.inverse(m) }
|
@(require_results) inverse_float4x4 :: proc "c" (m: float4x4) -> float4x4 { return inverse_matrix4x4(m) }
|
||||||
@(require_results) inverse_double1x1 :: proc "c" (m: double1x1) -> double1x1 { return builtin.inverse(m) }
|
@(require_results) inverse_double1x1 :: proc "c" (m: double1x1) -> double1x1 { return inverse_matrix1x1(m) }
|
||||||
@(require_results) inverse_double2x2 :: proc "c" (m: double2x2) -> double2x2 { return builtin.inverse(m) }
|
@(require_results) inverse_double2x2 :: proc "c" (m: double2x2) -> double2x2 { return inverse_matrix2x2(m) }
|
||||||
@(require_results) inverse_double3x3 :: proc "c" (m: double3x3) -> double3x3 { return builtin.inverse(m) }
|
@(require_results) inverse_double3x3 :: proc "c" (m: double3x3) -> double3x3 { return inverse_matrix3x3(m) }
|
||||||
@(require_results) inverse_double4x4 :: proc "c" (m: double4x4) -> double4x4 { return builtin.inverse(m) }
|
@(require_results) inverse_double4x4 :: proc "c" (m: double4x4) -> double4x4 { return inverse_matrix4x4(m) }
|
||||||
|
|
||||||
inverse :: proc{
|
inverse :: proc{
|
||||||
inverse_float1x1,
|
inverse_float1x1,
|
||||||
@@ -1489,15 +1490,275 @@ inverse :: proc{
|
|||||||
inverse_double2x2,
|
inverse_double2x2,
|
||||||
inverse_double3x3,
|
inverse_double3x3,
|
||||||
inverse_double4x4,
|
inverse_double4x4,
|
||||||
|
|
||||||
|
inverse_matrix1x1,
|
||||||
|
inverse_matrix2x2,
|
||||||
|
inverse_matrix3x3,
|
||||||
|
inverse_matrix4x4,
|
||||||
}
|
}
|
||||||
|
|
||||||
transpose :: builtin.transpose
|
transpose :: intrinsics.transpose
|
||||||
inverse_transpose :: builtin.inverse_transpose
|
|
||||||
adjugate :: builtin.adjugate
|
|
||||||
hermitian_adjoint :: builtin.hermitian_adjoint
|
determinant :: proc{
|
||||||
minor :: builtin.matrix_minor
|
determinant_matrix1x1,
|
||||||
determinant :: builtin.determinant
|
determinant_matrix2x2,
|
||||||
trace :: builtin.matrix_trace
|
determinant_matrix3x3,
|
||||||
|
determinant_matrix4x4,
|
||||||
|
}
|
||||||
|
|
||||||
|
adjugate :: proc{
|
||||||
|
adjugate_matrix1x1,
|
||||||
|
adjugate_matrix2x2,
|
||||||
|
adjugate_matrix3x3,
|
||||||
|
adjugate_matrix4x4,
|
||||||
|
}
|
||||||
|
|
||||||
|
inverse_transpose :: proc{
|
||||||
|
inverse_transpose_matrix1x1,
|
||||||
|
inverse_transpose_matrix2x2,
|
||||||
|
inverse_transpose_matrix3x3,
|
||||||
|
inverse_transpose_matrix4x4,
|
||||||
|
}
|
||||||
|
|
||||||
|
@(require_results)
|
||||||
|
hermitian_adjoint :: proc "contextless" (m: $M/matrix[$N, N]$T) -> M where intrinsics.type_is_complex(T), N >= 1 {
|
||||||
|
return conj(transpose(m))
|
||||||
|
}
|
||||||
|
|
||||||
|
@(require_results)
|
||||||
|
trace :: proc "contextless" (m: $M/matrix[$N, N]$T) -> (trace: T) {
|
||||||
|
for i in 0..<N {
|
||||||
|
trace += m[i, i]
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
@(require_results)
|
||||||
|
matrix_minor :: proc "contextless" (m: $M/matrix[$N, N]$T, #any_int row, column: int) -> (minor: T) where N > 1 {
|
||||||
|
K :: int(N-1)
|
||||||
|
cut_down: matrix[K, K]T
|
||||||
|
for col_idx in 0..<K {
|
||||||
|
j := col_idx + int(col_idx >= column)
|
||||||
|
for row_idx in 0..<K {
|
||||||
|
i := row_idx + int(row_idx >= row)
|
||||||
|
cut_down[row_idx, col_idx] = m[i, j]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return determinant(cut_down)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@(require_results)
|
||||||
|
determinant_matrix1x1 :: proc "contextless" (m: $M/matrix[1, 1]$T) -> (det: T) {
|
||||||
|
return m[0, 0]
|
||||||
|
}
|
||||||
|
|
||||||
|
@(require_results)
|
||||||
|
determinant_matrix2x2 :: proc "contextless" (m: $M/matrix[2, 2]$T) -> (det: T) {
|
||||||
|
return m[0, 0]*m[1, 1] - m[0, 1]*m[1, 0]
|
||||||
|
}
|
||||||
|
@(require_results)
|
||||||
|
determinant_matrix3x3 :: proc "contextless" (m: $M/matrix[3, 3]$T) -> (det: T) {
|
||||||
|
a := +m[0, 0] * (m[1, 1] * m[2, 2] - m[1, 2] * m[2, 1])
|
||||||
|
b := -m[0, 1] * (m[1, 0] * m[2, 2] - m[1, 2] * m[2, 0])
|
||||||
|
c := +m[0, 2] * (m[1, 0] * m[2, 1] - m[1, 1] * m[2, 0])
|
||||||
|
return a + b + c
|
||||||
|
}
|
||||||
|
@(require_results)
|
||||||
|
determinant_matrix4x4 :: proc "contextless" (m: $M/matrix[4, 4]$T) -> (det: T) {
|
||||||
|
a := adjugate(m)
|
||||||
|
#no_bounds_check for i in 0..<4 {
|
||||||
|
det += m[0, i] * a[0, i]
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@(require_results)
|
||||||
|
adjugate_matrix1x1 :: proc "contextless" (x: $M/matrix[1, 1]$T) -> (y: M) {
|
||||||
|
y = x
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
@(require_results)
|
||||||
|
adjugate_matrix2x2 :: proc "contextless" (x: $M/matrix[2, 2]$T) -> (y: M) {
|
||||||
|
y[0, 0] = +x[1, 1]
|
||||||
|
y[0, 1] = -x[1, 0]
|
||||||
|
y[1, 0] = -x[0, 1]
|
||||||
|
y[1, 1] = +x[0, 0]
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
@(require_results)
|
||||||
|
adjugate_matrix3x3 :: proc "contextless" (m: $M/matrix[3, 3]$T) -> (y: M) {
|
||||||
|
y[0, 0] = +(m[1, 1] * m[2, 2] - m[2, 1] * m[1, 2])
|
||||||
|
y[0, 1] = -(m[1, 0] * m[2, 2] - m[2, 0] * m[1, 2])
|
||||||
|
y[0, 2] = +(m[1, 0] * m[2, 1] - m[2, 0] * m[1, 1])
|
||||||
|
y[1, 0] = -(m[0, 1] * m[2, 2] - m[2, 1] * m[0, 2])
|
||||||
|
y[1, 1] = +(m[0, 0] * m[2, 2] - m[2, 0] * m[0, 2])
|
||||||
|
y[1, 2] = -(m[0, 0] * m[2, 1] - m[2, 0] * m[0, 1])
|
||||||
|
y[2, 0] = +(m[0, 1] * m[1, 2] - m[1, 1] * m[0, 2])
|
||||||
|
y[2, 1] = -(m[0, 0] * m[1, 2] - m[1, 0] * m[0, 2])
|
||||||
|
y[2, 2] = +(m[0, 0] * m[1, 1] - m[1, 0] * m[0, 1])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@(require_results)
|
||||||
|
adjugate_matrix4x4 :: proc "contextless" (x: $M/matrix[4, 4]$T) -> (y: M) {
|
||||||
|
for i in 0..<4 {
|
||||||
|
for j in 0..<4 {
|
||||||
|
sign: T = 1 if (i + j) % 2 == 0 else -1
|
||||||
|
y[i, j] = sign * matrix_minor(x, i, j)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
@(require_results)
|
||||||
|
inverse_transpose_matrix1x1 :: proc "contextless" (x: $M/matrix[1, 1]$T) -> (y: M) {
|
||||||
|
y[0, 0] = 1/x[0, 0]
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
@(require_results)
|
||||||
|
inverse_transpose_matrix2x2 :: proc "contextless" (x: $M/matrix[2, 2]$T) -> (y: M) {
|
||||||
|
d := x[0, 0]*x[1, 1] - x[0, 1]*x[1, 0]
|
||||||
|
when intrinsics.type_is_integer(T) {
|
||||||
|
y[0, 0] = +x[1, 1] / d
|
||||||
|
y[1, 0] = -x[0, 1] / d
|
||||||
|
y[0, 1] = -x[1, 0] / d
|
||||||
|
y[1, 1] = +x[0, 0] / d
|
||||||
|
} else {
|
||||||
|
id := 1 / d
|
||||||
|
y[0, 0] = +x[1, 1] * id
|
||||||
|
y[1, 0] = -x[0, 1] * id
|
||||||
|
y[0, 1] = -x[1, 0] * id
|
||||||
|
y[1, 1] = +x[0, 0] * id
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
@(require_results)
|
||||||
|
inverse_transpose_matrix3x3 :: proc "contextless" (x: $M/matrix[3, 3]$T) -> (y: M) #no_bounds_check {
|
||||||
|
a := adjugate(x)
|
||||||
|
d := determinant(x)
|
||||||
|
when intrinsics.type_is_integer(T) {
|
||||||
|
for i in 0..<3 {
|
||||||
|
for j in 0..<3 {
|
||||||
|
y[i, j] = a[i, j] / d
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
id := 1/d
|
||||||
|
for i in 0..<3 {
|
||||||
|
for j in 0..<3 {
|
||||||
|
y[i, j] = a[i, j] * id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
@(require_results)
|
||||||
|
inverse_transpose_matrix4x4 :: proc "contextless" (x: $M/matrix[4, 4]$T) -> (y: M) #no_bounds_check {
|
||||||
|
a := adjugate(x)
|
||||||
|
d: T
|
||||||
|
for i in 0..<4 {
|
||||||
|
d += x[0, i] * a[0, i]
|
||||||
|
}
|
||||||
|
when intrinsics.type_is_integer(T) {
|
||||||
|
for i in 0..<4 {
|
||||||
|
for j in 0..<4 {
|
||||||
|
y[i, j] = a[i, j] / d
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
id := 1/d
|
||||||
|
for i in 0..<4 {
|
||||||
|
for j in 0..<4 {
|
||||||
|
y[i, j] = a[i, j] * id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
@(require_results)
|
||||||
|
inverse_matrix1x1 :: proc "contextless" (x: $M/matrix[1, 1]$T) -> (y: M) {
|
||||||
|
y[0, 0] = 1/x[0, 0]
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
@(require_results)
|
||||||
|
inverse_matrix2x2 :: proc "contextless" (x: $M/matrix[2, 2]$T) -> (y: M) {
|
||||||
|
d := x[0, 0]*x[1, 1] - x[0, 1]*x[1, 0]
|
||||||
|
when intrinsics.type_is_integer(T) {
|
||||||
|
y[0, 0] = +x[1, 1] / d
|
||||||
|
y[0, 1] = -x[0, 1] / d
|
||||||
|
y[1, 0] = -x[1, 0] / d
|
||||||
|
y[1, 1] = +x[0, 0] / d
|
||||||
|
} else {
|
||||||
|
id := 1 / d
|
||||||
|
y[0, 0] = +x[1, 1] * id
|
||||||
|
y[0, 1] = -x[0, 1] * id
|
||||||
|
y[1, 0] = -x[1, 0] * id
|
||||||
|
y[1, 1] = +x[0, 0] * id
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
@(require_results)
|
||||||
|
inverse_matrix3x3 :: proc "contextless" (x: $M/matrix[3, 3]$T) -> (y: M) #no_bounds_check {
|
||||||
|
a := adjugate(x)
|
||||||
|
d := determinant(x)
|
||||||
|
when intrinsics.type_is_integer(T) {
|
||||||
|
for i in 0..<3 {
|
||||||
|
for j in 0..<3 {
|
||||||
|
y[i, j] = a[j, i] / d
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
id := 1/d
|
||||||
|
for i in 0..<3 {
|
||||||
|
for j in 0..<3 {
|
||||||
|
y[i, j] = a[j, i] * id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
@(require_results)
|
||||||
|
inverse_matrix4x4 :: proc "contextless" (x: $M/matrix[4, 4]$T) -> (y: M) #no_bounds_check {
|
||||||
|
a := adjugate(x)
|
||||||
|
d: T
|
||||||
|
for i in 0..<4 {
|
||||||
|
d += x[0, i] * a[0, i]
|
||||||
|
}
|
||||||
|
when intrinsics.type_is_integer(T) {
|
||||||
|
for i in 0..<4 {
|
||||||
|
for j in 0..<4 {
|
||||||
|
y[i, j] = a[j, i] / d
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
id := 1/d
|
||||||
|
for i in 0..<4 {
|
||||||
|
for j in 0..<4 {
|
||||||
|
y[i, j] = a[j, i] * id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
asfloat :: proc{
|
asfloat :: proc{
|
||||||
asfloat_float,
|
asfloat_float,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package linalg
|
package linalg
|
||||||
|
|
||||||
import "core:builtin"
|
import "base:builtin"
|
||||||
import "core:math"
|
import "core:math"
|
||||||
|
|
||||||
F16_EPSILON :: 1e-3
|
F16_EPSILON :: 1e-3
|
||||||
@@ -1447,16 +1447,16 @@ matrix3_adjoint :: proc{
|
|||||||
|
|
||||||
|
|
||||||
@(require_results)
|
@(require_results)
|
||||||
matrix3_inverse_transpose_f16 :: proc "contextless" (m: Matrix3f16) -> (inverse_transpose: Matrix3f16) {
|
matrix3_inverse_transpose_f16 :: proc "contextless" (m: Matrix3f16) -> (p: Matrix3f16) {
|
||||||
return builtin.inverse_transpose(m)
|
return inverse_transpose(m)
|
||||||
}
|
}
|
||||||
@(require_results)
|
@(require_results)
|
||||||
matrix3_inverse_transpose_f32 :: proc "contextless" (m: Matrix3f32) -> (inverse_transpose: Matrix3f32) {
|
matrix3_inverse_transpose_f32 :: proc "contextless" (m: Matrix3f32) -> (p: Matrix3f32) {
|
||||||
return builtin.inverse_transpose(m)
|
return inverse_transpose(m)
|
||||||
}
|
}
|
||||||
@(require_results)
|
@(require_results)
|
||||||
matrix3_inverse_transpose_f64 :: proc "contextless" (m: Matrix3f64) -> (inverse_transpose: Matrix3f64) {
|
matrix3_inverse_transpose_f64 :: proc "contextless" (m: Matrix3f64) -> (p: Matrix3f64) {
|
||||||
return builtin.inverse_transpose(m)
|
return inverse_transpose(m)
|
||||||
}
|
}
|
||||||
matrix3_inverse_transpose :: proc{
|
matrix3_inverse_transpose :: proc{
|
||||||
matrix3_inverse_transpose_f16,
|
matrix3_inverse_transpose_f16,
|
||||||
|
|||||||
+2
-2
@@ -1,7 +1,7 @@
|
|||||||
package math
|
package math
|
||||||
|
|
||||||
import "core:intrinsics"
|
import "base:intrinsics"
|
||||||
import "core:builtin"
|
import "base:builtin"
|
||||||
_ :: intrinsics
|
_ :: intrinsics
|
||||||
|
|
||||||
Float_Class :: enum {
|
Float_Class :: enum {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
//+build !js
|
//+build !js
|
||||||
package math
|
package math
|
||||||
|
|
||||||
import "core:intrinsics"
|
import "base:intrinsics"
|
||||||
|
|
||||||
@(default_calling_convention="none", private="file")
|
@(default_calling_convention="none", private="file")
|
||||||
foreign _ {
|
foreign _ {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
//+build js
|
//+build js
|
||||||
package math
|
package math
|
||||||
|
|
||||||
import "core:intrinsics"
|
import "base:intrinsics"
|
||||||
|
|
||||||
foreign import "odin_env"
|
foreign import "odin_env"
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user