mirror of
https://github.com/Ed94/Odin.git
synced 2026-07-05 03:01:38 -07:00
Compare commits
431 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9453b2387b | |||
| a4de59c8ee | |||
| fab40080e4 | |||
| fb30bda7d7 | |||
| 65206fe33e | |||
| 2f094134a3 | |||
| 69e1f42aed | |||
| c35c58b023 | |||
| 4b57aec1c6 | |||
| 2038bd0c15 | |||
| 19b24fcce2 | |||
| ed3354b433 | |||
| 963eeee361 | |||
| c3a316664a | |||
| 3d16880d95 | |||
| be6f355665 | |||
| 5dba08fb3b | |||
| f17077c05c | |||
| 8aa36072fc | |||
| 44ea82f845 | |||
| 0de7df9eab | |||
| 60e509b1e0 | |||
| 551c379f1b | |||
| 683ee75703 | |||
| a99da47b0d | |||
| 5ac7fe453f | |||
| f9c083073e | |||
| 74338733ba | |||
| 1b3657122c | |||
| 0f28857c59 | |||
| 88485d5467 | |||
| 921530dd01 | |||
| dcf3023d93 | |||
| b12c46b28a | |||
| 635d671ee7 | |||
| 204c0fa4d8 | |||
| 3a0b66d5df | |||
| 07d3122c14 | |||
| c6957e4e31 | |||
| 8068a3899d | |||
| 3cce972125 | |||
| 52700d6a84 | |||
| 0c80a4b836 | |||
| 46f408cc9f | |||
| 5c068a9062 | |||
| e1fae5b902 | |||
| 20e5e95ff8 | |||
| a238f78855 | |||
| 5b96712ed0 | |||
| f141078073 | |||
| d47fed16a9 | |||
| bc43a8d38d | |||
| ccd5685cee | |||
| f0f8177a19 | |||
| 363b701925 | |||
| 0a897e2fae | |||
| 5f53d815d1 | |||
| 7b89f25818 | |||
| 3072479c3c | |||
| 62031c24a2 | |||
| aa38889704 | |||
| 17562e476f | |||
| 6495f2cf98 | |||
| ea20b644cc | |||
| bf848637aa | |||
| 759f846b2b | |||
| 3758be55f5 | |||
| 8f4c59b080 | |||
| 1ff6212ffa | |||
| b60d29ae9a | |||
| 38d71e668d | |||
| 7cdf37eaf6 | |||
| 8d9adfd548 | |||
| a3e2d90f4c | |||
| fc81008ab5 | |||
| a1eae6304f | |||
| 49058620f0 | |||
| f68a3639b4 | |||
| f4e87c9720 | |||
| 23bf7973fa | |||
| 67e0751124 | |||
| f76559daf6 | |||
| 5e99ff6769 | |||
| 1ecb4aa9aa | |||
| a2b3c72647 | |||
| 0180a4fcd4 | |||
| abca3ceac8 | |||
| 866a9fdf19 | |||
| 20e954a864 | |||
| 03e40b333a | |||
| ebed66d4ce | |||
| 9e9f3c485b | |||
| d50a844720 | |||
| 89e559296e | |||
| d352e2fa31 | |||
| 71bc452764 | |||
| f048ad13b5 | |||
| d03d5d8f03 | |||
| 6ff0ce15e7 | |||
| 330b393e16 | |||
| a820246f64 | |||
| 1bf4c8c9ba | |||
| ca1d437435 | |||
| 8b8310711e | |||
| cdcb64b0d0 | |||
| 3c0f1caa41 | |||
| 8182ba4ee0 | |||
| 3d9328fd79 | |||
| 6c6f9f7d25 | |||
| c8f475174e | |||
| 3dec55f009 | |||
| 00d60e28c2 | |||
| ea00619c3b | |||
| bbe50bdaf1 | |||
| 6b59aee336 | |||
| 26a5614572 | |||
| 19ea090633 | |||
| 9841b11a54 | |||
| 5a6d5374d7 | |||
| 9099bc0b6e | |||
| e3b43b6e1c | |||
| b0d801f629 | |||
| c48057081e | |||
| ea76e09ea7 | |||
| c9fb078c0f | |||
| 1800030356 | |||
| 43ba2c6226 | |||
| 735181dc0e | |||
| 8a890fd3d3 | |||
| 15e31e47fa | |||
| 9b54b99bf6 | |||
| 67ca9166d3 | |||
| b2ced834ba | |||
| 18746c1444 | |||
| 09f366bec7 | |||
| 3998d0c81e | |||
| 2a002c3882 | |||
| fb756e3463 | |||
| 3c5661b51b | |||
| 26e06ba6a6 | |||
| 7c57dde255 | |||
| 9ec927b9e9 | |||
| 15a0d9f900 | |||
| f26e3c6509 | |||
| 6568625dea | |||
| 427f212170 | |||
| c1fb8eaf1a | |||
| 37469dc9c2 | |||
| dce57627c9 | |||
| 2992ca5df1 | |||
| a5ed5883c7 | |||
| 0036509f74 | |||
| 003c470a4d | |||
| d6540d9077 | |||
| 091c515fea | |||
| 4f2b9835f5 | |||
| 242d3b3c4d | |||
| c66ac9725e | |||
| feacc5cd11 | |||
| 3a761395be | |||
| a78d6fe0b3 | |||
| 08e466938f | |||
| e036155bdb | |||
| 2149afabe1 | |||
| ec32967daa | |||
| fc4a5e61c2 | |||
| e9608c9d05 | |||
| 581eebb197 | |||
| 10fa67fdaa | |||
| 10f2136675 | |||
| d97dd99d91 | |||
| 296674e18b | |||
| 52a926dd90 | |||
| d38ea63c78 | |||
| 2022a7615a | |||
| dca0fae781 | |||
| e16c6c1b6b | |||
| ede9881458 | |||
| a7f8c78358 | |||
| 3a90b40425 | |||
| 454709559b | |||
| c3933cead4 | |||
| 420f93ce78 | |||
| 2a212a7556 | |||
| 145a7a24e8 | |||
| 6c040497ef | |||
| 9ee4b76cd9 | |||
| 3f6775e29b | |||
| 4c17e2e97e | |||
| eac53fed59 | |||
| fed0c2ea26 | |||
| 21c1618d94 | |||
| d37699f51a | |||
| d82bfa98a7 | |||
| 9b15bda055 | |||
| 635842b322 | |||
| 3b8515beb0 | |||
| 7b62b81ebd | |||
| dcf4e51787 | |||
| 7dc09ed450 | |||
| 349641e95f | |||
| 9941ec85d8 | |||
| ef944b903b | |||
| 0c477f2c6b | |||
| 151396507e | |||
| 8441c0c51e | |||
| ae7bf468d1 | |||
| 907ef82d4b | |||
| 7a1ab62987 | |||
| 295cfc905c | |||
| 204924927a | |||
| f622a8393c | |||
| d75df7fd8a | |||
| 2bc5e0ebd7 | |||
| ca6cef9a7d | |||
| 1c2a30d7e9 | |||
| 4a75a1e839 | |||
| 6a2ff3a371 | |||
| 7ce1386d1a | |||
| d6f45e4d76 | |||
| 356f66784f | |||
| 166ab7b600 | |||
| 1cdb0abf80 | |||
| 0defd1d141 | |||
| 24ed07b6d5 | |||
| ecad730945 | |||
| efb7fd919b | |||
| 5d6b923244 | |||
| d8752da7d5 | |||
| 6952124988 | |||
| a6c93e2c41 | |||
| 788f3c22bf | |||
| c194dfbdf7 | |||
| 5e996a1c02 | |||
| b52bf11ea5 | |||
| 7915dde43c | |||
| 7675b9c28f | |||
| ebe5636307 | |||
| 6fe2df1d7d | |||
| 5376d32772 | |||
| 2924e478ee | |||
| 297700ad11 | |||
| 9d29914304 | |||
| b223bc0302 | |||
| 3562a38f8c | |||
| 201544ef8b | |||
| 837ba6c33b | |||
| 3ab01dbc00 | |||
| c241edaa30 | |||
| e0530df98a | |||
| 6cbce9fdff | |||
| c1eb536726 | |||
| b848ae7abb | |||
| f07453d0ae | |||
| 052051244f | |||
| 97490c6445 | |||
| 1247d36a12 | |||
| f3a463000d | |||
| c38842ecb2 | |||
| 8b825b23b1 | |||
| d2f62730bc | |||
| d167d18bb3 | |||
| 508d7c3336 | |||
| 2b31d85cd4 | |||
| e350c37e6f | |||
| 319a465429 | |||
| 9371325246 | |||
| 2fda3cf988 | |||
| 03b7194c97 | |||
| 39bff40a75 | |||
| 3dc6edfd2d | |||
| 762747273e | |||
| 0f392a95ae | |||
| 29786b0024 | |||
| 32ca50a097 | |||
| 8012e6fa43 | |||
| 54b7cefb09 | |||
| 3a61350f4b | |||
| bdbbaf6c88 | |||
| 24a1a8a626 | |||
| 38b64dc5df | |||
| e3360a0e5d | |||
| 4181444734 | |||
| 7958708641 | |||
| 40a8ed535a | |||
| c7d571f0b5 | |||
| 5d54b710e7 | |||
| 248f14a1ef | |||
| b76fc58543 | |||
| 9fc9981a9e | |||
| 8f563df7c5 | |||
| 730192adc4 | |||
| 8bf32ac697 | |||
| 540f724b1f | |||
| d5a8f2298e | |||
| 18c5a53685 | |||
| a1172d31f4 | |||
| 396debb9cb | |||
| c4cb2f2378 | |||
| 74ce99e0d7 | |||
| 89a233ccd2 | |||
| 2df6cabee0 | |||
| 82023cd629 | |||
| 1e17f44991 | |||
| 600c97cc0f | |||
| 7298054974 | |||
| 4d5a442d1f | |||
| 249f42f054 | |||
| 87788142bf | |||
| f0b08a6c67 | |||
| a144a49a9a | |||
| 2167f1b567 | |||
| c5c723b80c | |||
| 66461c9dbc | |||
| d77103e53e | |||
| 963908e508 | |||
| 9e5677ab02 | |||
| 46bb9bc5c7 | |||
| 118ab60588 | |||
| 223ae61c89 | |||
| 1f4baba06e | |||
| fa1ce7d5d1 | |||
| 775a488a36 | |||
| 018904f0ec | |||
| b358641e7d | |||
| ff745e0ad8 | |||
| 4201834b18 | |||
| 2631e07bea | |||
| 76a1851cb8 | |||
| 87a1792677 | |||
| 413077a5d9 | |||
| d56fdd2937 | |||
| 6639b7d017 | |||
| 7702a488e5 | |||
| 3108752a0c | |||
| 56c0d32ea0 | |||
| c0e84b0592 | |||
| f2e590be7a | |||
| 60ec3594ab | |||
| 49d1f6aca0 | |||
| 49cd9648b0 | |||
| 1692dcf8d5 | |||
| 5ec4719124 | |||
| 911c98e235 | |||
| 535c64c318 | |||
| 171f38b9b5 | |||
| b2645b3201 | |||
| a9936d1570 | |||
| 3032a4274d | |||
| 31c21a054b | |||
| def4fdc3f3 | |||
| 3fed1af7df | |||
| adb4692ce8 | |||
| bb4ff84a4a | |||
| 5d2c1b175e | |||
| 2ab6de8ee4 | |||
| 1896ae5d15 | |||
| 6e4fab19a2 | |||
| 103dcfe897 | |||
| 8caadbacf7 | |||
| 870d776875 | |||
| 59e66ffe49 | |||
| 418a0132d0 | |||
| a381846034 | |||
| 1c5ce75d9f | |||
| 8693a045bb | |||
| b567679eb6 | |||
| e6c8d3d1db | |||
| 12c4afd824 | |||
| 968a07ed7a | |||
| f9c600a760 | |||
| 82561cfbac | |||
| 277ae4e2b0 | |||
| 0f9e747583 | |||
| 4e146a75b6 | |||
| 33d0e2037b | |||
| 7a04b7262e | |||
| f2d5e4b995 | |||
| ada42aa184 | |||
| ed580b3060 | |||
| 29e4762011 | |||
| eff4833840 | |||
| 9867037aa2 | |||
| 57c14f6a9b | |||
| 1ed105205c | |||
| 8233f49beb | |||
| 2c01a4613c | |||
| b0eda47b26 | |||
| 291111e626 | |||
| 47693da4aa | |||
| 9f39209712 | |||
| c47dcbbe2f | |||
| f313538ea5 | |||
| 956ffdf654 | |||
| ef4a527c36 | |||
| 3fe0680ad5 | |||
| 182b269e46 | |||
| 05856ac93e | |||
| 60c29e195a | |||
| 6b23662ce6 | |||
| 77d6364405 | |||
| 077a611a5e | |||
| e82146bf17 | |||
| f5dcbf517b | |||
| 808e7ed4ae | |||
| 4b4481ea27 | |||
| e84802468b | |||
| 1a5ed4eb7f | |||
| 5151403aaa | |||
| 67b6a8ee89 | |||
| 780375d865 | |||
| cbcf94669e | |||
| 46da53ba15 | |||
| 06e8d03fba | |||
| a6b9341593 | |||
| 47610725ea | |||
| c7d4af5c79 | |||
| 685f7d0fea | |||
| f5d9ca64f9 | |||
| cde442fa2c | |||
| 84f966cb8f | |||
| f36e19e86f | |||
| 86fada718e | |||
| 2a94b66f4d | |||
| 4ee413aa32 | |||
| 2d824e4809 | |||
| 9474c99795 | |||
| 84a7f222ff | |||
| d29423c24e | |||
| 02a8bba02e | |||
| 6ea68869c9 |
+19
-14
@@ -56,9 +56,9 @@ jobs:
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: Download LLVM and setup PATH
|
||||
- name: Download LLVM, botan and setup PATH
|
||||
run: |
|
||||
brew install llvm@11
|
||||
brew install llvm@11 botan
|
||||
echo "/usr/local/opt/llvm@11/bin" >> $GITHUB_PATH
|
||||
TMP_PATH=$(xcrun --show-sdk-path)/user/include
|
||||
echo "CPATH=$TMP_PATH" >> $GITHUB_ENV
|
||||
@@ -87,6 +87,11 @@ jobs:
|
||||
cd tests/core
|
||||
make
|
||||
timeout-minutes: 10
|
||||
- name: Vendor library tests
|
||||
run: |
|
||||
cd tests/vendor
|
||||
make
|
||||
timeout-minutes: 10
|
||||
- name: Odin internals tests
|
||||
run: |
|
||||
cd tests/internal
|
||||
@@ -99,13 +104,13 @@ jobs:
|
||||
run: ./odin check examples/all -vet -strict-style -target:linux_arm64
|
||||
timeout-minutes: 10
|
||||
build_windows:
|
||||
runs-on: windows-2019
|
||||
runs-on: windows-2022
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: build Odin
|
||||
shell: cmd
|
||||
run: |
|
||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat
|
||||
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat
|
||||
./build.bat 1
|
||||
- name: Odin version
|
||||
run: ./odin version
|
||||
@@ -116,65 +121,65 @@ jobs:
|
||||
- name: Odin check
|
||||
shell: cmd
|
||||
run: |
|
||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat
|
||||
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat
|
||||
odin check examples/demo -vet
|
||||
timeout-minutes: 10
|
||||
- name: Odin run
|
||||
shell: cmd
|
||||
run: |
|
||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat
|
||||
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat
|
||||
odin run examples/demo
|
||||
timeout-minutes: 10
|
||||
- name: Odin run -debug
|
||||
shell: cmd
|
||||
run: |
|
||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat
|
||||
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat
|
||||
odin run examples/demo -debug
|
||||
timeout-minutes: 10
|
||||
- name: Odin check examples/all
|
||||
shell: cmd
|
||||
run: |
|
||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat
|
||||
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat
|
||||
odin check examples/all -strict-style
|
||||
timeout-minutes: 10
|
||||
- name: Core library tests
|
||||
shell: cmd
|
||||
run: |
|
||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat
|
||||
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat
|
||||
cd tests\core
|
||||
call build.bat
|
||||
timeout-minutes: 10
|
||||
- name: Vendor library tests
|
||||
shell: cmd
|
||||
run: |
|
||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat
|
||||
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat
|
||||
cd tests\vendor
|
||||
call build.bat
|
||||
timeout-minutes: 10
|
||||
- name: Odin internals tests
|
||||
shell: cmd
|
||||
run: |
|
||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat
|
||||
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat
|
||||
cd tests\internal
|
||||
call build.bat
|
||||
timeout-minutes: 10
|
||||
- name: Odin documentation tests
|
||||
shell: cmd
|
||||
run: |
|
||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat
|
||||
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat
|
||||
cd tests\documentation
|
||||
call build.bat
|
||||
timeout-minutes: 10
|
||||
- name: core:math/big tests
|
||||
shell: cmd
|
||||
run: |
|
||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat
|
||||
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat
|
||||
cd tests\core\math\big
|
||||
call build.bat
|
||||
timeout-minutes: 10
|
||||
- name: Odin check examples/all for Windows 32bits
|
||||
shell: cmd
|
||||
run: |
|
||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat
|
||||
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat
|
||||
odin check examples/all -strict-style -target:windows_i386
|
||||
timeout-minutes: 10
|
||||
|
||||
@@ -7,18 +7,19 @@ on:
|
||||
|
||||
jobs:
|
||||
build_windows:
|
||||
runs-on: windows-2019
|
||||
if: github.repository == 'odin-lang/Odin'
|
||||
runs-on: windows-2022
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: build Odin
|
||||
shell: cmd
|
||||
run: |
|
||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat
|
||||
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat
|
||||
./build.bat 1 1
|
||||
- name: Odin run
|
||||
shell: cmd
|
||||
run: |
|
||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat
|
||||
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat
|
||||
odin run examples/demo
|
||||
- name: Copy artifacts
|
||||
run: |
|
||||
@@ -37,6 +38,7 @@ jobs:
|
||||
name: windows_artifacts
|
||||
path: dist
|
||||
build_ubuntu:
|
||||
if: github.repository == 'odin-lang/Odin'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
@@ -61,6 +63,7 @@ jobs:
|
||||
name: ubuntu_artifacts
|
||||
path: dist
|
||||
build_macos:
|
||||
if: github.repository == 'odin-lang/Odin'
|
||||
runs-on: macOS-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
|
||||
+2
-1
@@ -270,6 +270,7 @@ bin/
|
||||
|
||||
# - Linux/MacOS
|
||||
odin
|
||||
!odin/
|
||||
odin.dSYM
|
||||
*.bin
|
||||
demo.bin
|
||||
@@ -286,4 +287,4 @@ shared/
|
||||
*.sublime-workspace
|
||||
examples/bug/
|
||||
build.sh
|
||||
!core/debug/
|
||||
!core/debug/
|
||||
|
||||
@@ -3,18 +3,20 @@
|
||||
setlocal EnableDelayedExpansion
|
||||
|
||||
where /Q cl.exe || (
|
||||
set __VSCMD_ARG_NO_LOGO=1
|
||||
for /f "tokens=*" %%i in ('"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe" -latest -requires Microsoft.VisualStudio.Workload.NativeDesktop -property installationPath') do set VS=%%i
|
||||
if "!VS!" equ "" (
|
||||
echo ERROR: Visual Studio installation not found
|
||||
exit /b 1
|
||||
)
|
||||
call "!VS!\VC\Auxiliary\Build\vcvarsall.bat" amd64 || exit /b 1
|
||||
set __VSCMD_ARG_NO_LOGO=1
|
||||
for /f "tokens=*" %%i in ('"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe" -latest -requires Microsoft.VisualStudio.Workload.NativeDesktop -property installationPath') do set VS=%%i
|
||||
if "!VS!" equ "" (
|
||||
echo ERROR: Visual Studio installation not found
|
||||
exit /b 1
|
||||
)
|
||||
call "!VS!\VC\Auxiliary\Build\vcvarsall.bat" amd64 || exit /b 1
|
||||
)
|
||||
|
||||
if "%VSCMD_ARG_TGT_ARCH%" neq "x64" (
|
||||
echo ERROR: please run this from MSVC x64 native tools command prompt, 32-bit target is not supported!
|
||||
exit /b 1
|
||||
if "%ODIN_IGNORE_MSVC_CHECK%" == "" (
|
||||
echo ERROR: please run this from MSVC x64 native tools command prompt, 32-bit target is not supported!
|
||||
exit /b 1
|
||||
)
|
||||
)
|
||||
|
||||
for /f "usebackq tokens=1,2 delims=,=- " %%i in (`wmic os get LocalDateTime /value`) do @if %%i==LocalDateTime (
|
||||
@@ -49,7 +51,10 @@ set compiler_flags= -nologo -Oi -TP -fp:precise -Gm- -MP -FC -EHsc- -GR- -GF
|
||||
set compiler_defines= -DODIN_VERSION_RAW=\"%odin_version_raw%\"
|
||||
|
||||
if not exist .git\ goto skip_git_hash
|
||||
for /f %%i in ('git rev-parse --short HEAD') do set GIT_SHA=%%i
|
||||
for /f "tokens=1,2" %%i IN ('git show "--pretty=%%cd %%h" "--date=format:%%Y-%%m" --no-patch --no-notes HEAD') do (
|
||||
set odin_version_raw=dev-%%i
|
||||
set GIT_SHA=%%j
|
||||
)
|
||||
if %ERRORLEVEL% equ 0 set compiler_defines=%compiler_defines% -DGIT_SHA=\"%GIT_SHA%\"
|
||||
:skip_git_hash
|
||||
|
||||
|
||||
+16
-8
@@ -4,23 +4,24 @@ set -eu
|
||||
: ${CXX=clang++}
|
||||
: ${CPPFLAGS=}
|
||||
: ${CXXFLAGS=}
|
||||
: ${INCLUDE_DIRECTORIES=}
|
||||
: ${LDFLAGS=}
|
||||
: ${ODIN_VERSION=dev-$(date +"%Y-%m")}
|
||||
: ${GIT_SHA=}
|
||||
|
||||
CPPFLAGS="$CPPFLAGS -DODIN_VERSION_RAW=\"$ODIN_VERSION\""
|
||||
CXXFLAGS="$CXXFLAGS -std=c++14"
|
||||
INCLUDE_DIRECTORIES="$INCLUDE_DIRECTORIES -Isrc/"
|
||||
LDFLAGS="$LDFLAGS -pthread -lm -lstdc++"
|
||||
|
||||
if [ -d ".git" ]; then
|
||||
GIT_SHA=$(git rev-parse --short HEAD || :)
|
||||
if [ "$GIT_SHA" ]; then
|
||||
if [ -d ".git" ] && [ $(which git) ]; then
|
||||
versionTag=( $(git show --pretty='%cd %h' --date=format:%Y-%m --no-patch --no-notes HEAD) )
|
||||
if [ $? -eq 0 ]; then
|
||||
ODIN_VERSION="dev-${versionTag[0]}"
|
||||
GIT_SHA="${versionTag[1]}"
|
||||
CPPFLAGS="$CPPFLAGS -DGIT_SHA=\"$GIT_SHA\""
|
||||
fi
|
||||
fi
|
||||
|
||||
CPPFLAGS="$CPPFLAGS -DODIN_VERSION_RAW=\"$ODIN_VERSION\""
|
||||
|
||||
DISABLED_WARNINGS="-Wno-switch -Wno-macro-redefined -Wno-unused-value"
|
||||
OS=$(uname)
|
||||
|
||||
@@ -137,7 +138,14 @@ build_odin() {
|
||||
EXTRAFLAGS="-O3"
|
||||
;;
|
||||
release-native)
|
||||
EXTRAFLAGS="-O3 -march=native"
|
||||
local ARCH=$(uname -m)
|
||||
if [ "${ARCH}" == "arm64" ]; then
|
||||
# Use preferred flag for Arm (ie arm64 / aarch64 / etc)
|
||||
EXTRAFLAGS="-O3 -mcpu=native"
|
||||
else
|
||||
# Use preferred flag for x86 / amd64
|
||||
EXTRAFLAGS="-O3 -march=native"
|
||||
fi
|
||||
;;
|
||||
nightly)
|
||||
EXTRAFLAGS="-DNIGHTLY -O3"
|
||||
@@ -148,7 +156,7 @@ build_odin() {
|
||||
esac
|
||||
|
||||
set -x
|
||||
$CXX src/main.cpp src/libtommath.cpp $DISABLED_WARNINGS $CPPFLAGS $CXXFLAGS $INCLUDE_DIRECTORIES $EXTRAFLAGS $LDFLAGS -o odin
|
||||
$CXX src/main.cpp src/libtommath.cpp $DISABLED_WARNINGS $CPPFLAGS $CXXFLAGS $EXTRAFLAGS $LDFLAGS -o odin
|
||||
set +x
|
||||
}
|
||||
|
||||
|
||||
+22
-44
@@ -14,51 +14,29 @@ read_writer_init :: proc(rw: ^Read_Writer, r: ^Reader, w: ^Writer) {
|
||||
}
|
||||
|
||||
read_writer_to_stream :: proc(rw: ^Read_Writer) -> (s: io.Stream) {
|
||||
s.stream_data = rw
|
||||
s.stream_vtable = &_read_writer_vtable
|
||||
s.procedure = _read_writer_procedure
|
||||
s.data = rw
|
||||
return
|
||||
}
|
||||
|
||||
@(private)
|
||||
_read_writer_vtable := io.Stream_VTable{
|
||||
impl_read = proc(s: io.Stream, p: []byte) -> (n: int, err: io.Error) {
|
||||
b := (^Read_Writer)(s.stream_data).r
|
||||
return reader_read(b, p)
|
||||
},
|
||||
impl_unread_byte = proc(s: io.Stream) -> io.Error {
|
||||
b := (^Read_Writer)(s.stream_data).r
|
||||
return reader_unread_byte(b)
|
||||
},
|
||||
impl_read_rune = proc(s: io.Stream) -> (r: rune, size: int, err: io.Error) {
|
||||
b := (^Read_Writer)(s.stream_data).r
|
||||
return reader_read_rune(b)
|
||||
},
|
||||
impl_unread_rune = proc(s: io.Stream) -> io.Error {
|
||||
b := (^Read_Writer)(s.stream_data).r
|
||||
return reader_unread_rune(b)
|
||||
},
|
||||
impl_write_to = proc(s: io.Stream, w: io.Writer) -> (n: i64, err: io.Error) {
|
||||
b := (^Read_Writer)(s.stream_data).r
|
||||
return reader_write_to(b, w)
|
||||
},
|
||||
impl_flush = proc(s: io.Stream) -> io.Error {
|
||||
b := (^Read_Writer)(s.stream_data).w
|
||||
return writer_flush(b)
|
||||
},
|
||||
impl_write = proc(s: io.Stream, p: []byte) -> (n: int, err: io.Error) {
|
||||
b := (^Read_Writer)(s.stream_data).w
|
||||
return writer_write(b, p)
|
||||
},
|
||||
impl_write_byte = proc(s: io.Stream, c: byte) -> io.Error {
|
||||
b := (^Read_Writer)(s.stream_data).w
|
||||
return writer_write_byte(b, c)
|
||||
},
|
||||
impl_write_rune = proc(s: io.Stream, r: rune) -> (int, io.Error) {
|
||||
b := (^Read_Writer)(s.stream_data).w
|
||||
return writer_write_rune(b, r)
|
||||
},
|
||||
impl_read_from = proc(s: io.Stream, r: io.Reader) -> (n: i64, err: io.Error) {
|
||||
b := (^Read_Writer)(s.stream_data).w
|
||||
return writer_read_from(b, r)
|
||||
},
|
||||
}
|
||||
_read_writer_procedure := proc(stream_data: rawptr, mode: io.Stream_Mode, p: []byte, offset: i64, whence: io.Seek_From) -> (n: i64, err: io.Error) {
|
||||
rw := (^Read_Writer)(stream_data)
|
||||
n_int: int
|
||||
#partial switch mode {
|
||||
case .Flush:
|
||||
err = writer_flush(rw.w)
|
||||
return
|
||||
case .Read:
|
||||
n_int, err = reader_read(rw.r, p)
|
||||
n = i64(n_int)
|
||||
return
|
||||
case .Write:
|
||||
n_int, err = writer_write(rw.w, p)
|
||||
n = i64(n_int)
|
||||
return
|
||||
case .Query:
|
||||
return io.query_utility({.Flush, .Read, .Write, .Query})
|
||||
}
|
||||
return 0, .Empty
|
||||
}
|
||||
+13
-45
@@ -311,18 +311,6 @@ reader_write_to :: proc(b: ^Reader, w: io.Writer) -> (n: i64, err: io.Error) {
|
||||
}
|
||||
|
||||
m: i64
|
||||
if nr, ok := io.to_writer_to(b.rd); ok {
|
||||
m, err = io.write_to(nr, w)
|
||||
n += m
|
||||
return n, err
|
||||
}
|
||||
|
||||
if nw, ok := io.to_reader_from(w); ok {
|
||||
m, err = io.read_from(nw, b.rd)
|
||||
n += m
|
||||
return n, err
|
||||
}
|
||||
|
||||
if b.w-b.r < len(b.buf) {
|
||||
if err = _reader_read_new_chunk(b); err != nil {
|
||||
return
|
||||
@@ -352,48 +340,28 @@ reader_write_to :: proc(b: ^Reader, w: io.Writer) -> (n: i64, err: io.Error) {
|
||||
|
||||
// reader_to_stream converts a Reader into an io.Stream
|
||||
reader_to_stream :: proc(b: ^Reader) -> (s: io.Stream) {
|
||||
s.stream_data = b
|
||||
s.stream_vtable = &_reader_vtable
|
||||
s.data = b
|
||||
s.procedure = _reader_proc
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
|
||||
@(private)
|
||||
_reader_vtable := io.Stream_VTable{
|
||||
impl_destroy = proc(s: io.Stream) -> io.Error {
|
||||
b := (^Reader)(s.stream_data)
|
||||
_reader_proc :: proc(stream_data: rawptr, mode: io.Stream_Mode, p: []byte, offset: i64, whence: io.Seek_From) -> (n: i64, err: io.Error) {
|
||||
b := (^Reader)(stream_data)
|
||||
#partial switch mode {
|
||||
case .Read:
|
||||
return io._i64_err(reader_read(b, p))
|
||||
case .Destroy:
|
||||
reader_destroy(b)
|
||||
return nil
|
||||
},
|
||||
impl_read = proc(s: io.Stream, p: []byte) -> (n: int, err: io.Error) {
|
||||
b := (^Reader)(s.stream_data)
|
||||
return reader_read(b, p)
|
||||
},
|
||||
impl_read_byte = proc(s: io.Stream) -> (c: byte, err: io.Error) {
|
||||
b := (^Reader)(s.stream_data)
|
||||
return reader_read_byte(b)
|
||||
},
|
||||
impl_unread_byte = proc(s: io.Stream) -> io.Error {
|
||||
b := (^Reader)(s.stream_data)
|
||||
return reader_unread_byte(b)
|
||||
},
|
||||
impl_read_rune = proc(s: io.Stream) -> (r: rune, size: int, err: io.Error) {
|
||||
b := (^Reader)(s.stream_data)
|
||||
return reader_read_rune(b)
|
||||
},
|
||||
impl_unread_rune = proc(s: io.Stream) -> io.Error {
|
||||
b := (^Reader)(s.stream_data)
|
||||
return reader_unread_rune(b)
|
||||
},
|
||||
impl_write_to = proc(s: io.Stream, w: io.Writer) -> (n: i64, err: io.Error) {
|
||||
b := (^Reader)(s.stream_data)
|
||||
return reader_write_to(b, w)
|
||||
},
|
||||
return
|
||||
case .Query:
|
||||
return io.query_utility({.Read, .Destroy, .Query})
|
||||
}
|
||||
return 0, .Empty
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Utility procedures
|
||||
//
|
||||
|
||||
+20
-39
@@ -173,14 +173,6 @@ writer_read_from :: proc(b: ^Writer, r: io.Reader) -> (n: i64, err: io.Error) {
|
||||
if b.err != nil {
|
||||
return 0, b.err
|
||||
}
|
||||
if writer_buffered(b) == 0 {
|
||||
if w, ok := io.to_reader_from(b.wr); !ok {
|
||||
n, err = io.read_from(w, r)
|
||||
b.err = err
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
for {
|
||||
if writer_available(b) == 0 {
|
||||
writer_flush(b) or_return
|
||||
@@ -222,46 +214,35 @@ writer_read_from :: proc(b: ^Writer, r: io.Reader) -> (n: i64, err: io.Error) {
|
||||
|
||||
// writer_to_stream converts a Writer into an io.Stream
|
||||
writer_to_stream :: proc(b: ^Writer) -> (s: io.Stream) {
|
||||
s.stream_data = b
|
||||
s.stream_vtable = &_writer_vtable
|
||||
s.data = b
|
||||
s.procedure = _writer_proc
|
||||
return
|
||||
}
|
||||
|
||||
// writer_to_stream converts a Writer into an io.Stream
|
||||
writer_to_writer :: proc(b: ^Writer) -> (s: io.Writer) {
|
||||
s.stream_data = b
|
||||
s.stream_vtable = &_writer_vtable
|
||||
return
|
||||
return writer_to_stream(b)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@(private)
|
||||
_writer_vtable := io.Stream_VTable{
|
||||
impl_destroy = proc(s: io.Stream) -> io.Error {
|
||||
b := (^Writer)(s.stream_data)
|
||||
_writer_proc :: proc(stream_data: rawptr, mode: io.Stream_Mode, p: []byte, offset: i64, whence: io.Seek_From) -> (n: i64, err: io.Error) {
|
||||
b := (^Writer)(stream_data)
|
||||
#partial switch mode {
|
||||
case .Flush:
|
||||
err = writer_flush(b)
|
||||
return
|
||||
case .Write:
|
||||
n_int: int
|
||||
n_int, err = writer_write(b, p)
|
||||
n = i64(n_int)
|
||||
return
|
||||
case .Destroy:
|
||||
writer_destroy(b)
|
||||
return nil
|
||||
},
|
||||
impl_flush = proc(s: io.Stream) -> io.Error {
|
||||
b := (^Writer)(s.stream_data)
|
||||
return writer_flush(b)
|
||||
},
|
||||
impl_write = proc(s: io.Stream, p: []byte) -> (n: int, err: io.Error) {
|
||||
b := (^Writer)(s.stream_data)
|
||||
return writer_write(b, p)
|
||||
},
|
||||
impl_write_byte = proc(s: io.Stream, c: byte) -> io.Error {
|
||||
b := (^Writer)(s.stream_data)
|
||||
return writer_write_byte(b, c)
|
||||
},
|
||||
impl_write_rune = proc(s: io.Stream, r: rune) -> (int, io.Error) {
|
||||
b := (^Writer)(s.stream_data)
|
||||
return writer_write_rune(b, r)
|
||||
},
|
||||
impl_read_from = proc(s: io.Stream, r: io.Reader) -> (n: i64, err: io.Error) {
|
||||
b := (^Writer)(s.stream_data)
|
||||
return writer_read_from(b, r)
|
||||
},
|
||||
return
|
||||
case .Query:
|
||||
return io.query_utility({.Flush, .Write, .Destroy, .Query})
|
||||
}
|
||||
return 0, .Empty
|
||||
}
|
||||
|
||||
+27
-60
@@ -38,6 +38,11 @@ buffer_init_string :: proc(b: ^Buffer, s: string) {
|
||||
}
|
||||
|
||||
buffer_init_allocator :: proc(b: ^Buffer, len, cap: int, allocator := context.allocator) {
|
||||
if b.buf == nil {
|
||||
b.buf = make([dynamic]byte, len, cap, allocator)
|
||||
return
|
||||
}
|
||||
|
||||
b.buf.allocator = allocator
|
||||
reserve(&b.buf, cap)
|
||||
resize(&b.buf, len)
|
||||
@@ -370,69 +375,31 @@ buffer_read_from :: proc(b: ^Buffer, r: io.Reader) -> (n: i64, err: io.Error) #n
|
||||
|
||||
|
||||
buffer_to_stream :: proc(b: ^Buffer) -> (s: io.Stream) {
|
||||
s.stream_data = b
|
||||
s.stream_vtable = &_buffer_vtable
|
||||
s.data = b
|
||||
s.procedure = _buffer_proc
|
||||
return
|
||||
}
|
||||
|
||||
@(private)
|
||||
_buffer_vtable := io.Stream_VTable{
|
||||
impl_size = proc(s: io.Stream) -> i64 {
|
||||
b := (^Buffer)(s.stream_data)
|
||||
return i64(buffer_capacity(b))
|
||||
},
|
||||
impl_read = proc(s: io.Stream, p: []byte) -> (n: int, err: io.Error) {
|
||||
b := (^Buffer)(s.stream_data)
|
||||
return buffer_read(b, p)
|
||||
},
|
||||
impl_read_at = proc(s: io.Stream, p: []byte, offset: i64) -> (n: int, err: io.Error) {
|
||||
b := (^Buffer)(s.stream_data)
|
||||
return buffer_read_at(b, p, int(offset))
|
||||
},
|
||||
impl_read_byte = proc(s: io.Stream) -> (byte, io.Error) {
|
||||
b := (^Buffer)(s.stream_data)
|
||||
return buffer_read_byte(b)
|
||||
},
|
||||
impl_read_rune = proc(s: io.Stream) -> (r: rune, size: int, err: io.Error) {
|
||||
b := (^Buffer)(s.stream_data)
|
||||
return buffer_read_rune(b)
|
||||
},
|
||||
impl_write = proc(s: io.Stream, p: []byte) -> (n: int, err: io.Error) {
|
||||
b := (^Buffer)(s.stream_data)
|
||||
return buffer_write(b, p)
|
||||
},
|
||||
impl_write_at = proc(s: io.Stream, p: []byte, offset: i64) -> (n: int, err: io.Error) {
|
||||
b := (^Buffer)(s.stream_data)
|
||||
return buffer_write_at(b, p, int(offset))
|
||||
},
|
||||
impl_write_byte = proc(s: io.Stream, c: byte) -> io.Error {
|
||||
b := (^Buffer)(s.stream_data)
|
||||
return buffer_write_byte(b, c)
|
||||
},
|
||||
impl_write_rune = proc(s: io.Stream, r: rune) -> (int, io.Error) {
|
||||
b := (^Buffer)(s.stream_data)
|
||||
return buffer_write_rune(b, r)
|
||||
},
|
||||
impl_unread_byte = proc(s: io.Stream) -> io.Error {
|
||||
b := (^Buffer)(s.stream_data)
|
||||
return buffer_unread_byte(b)
|
||||
},
|
||||
impl_unread_rune = proc(s: io.Stream) -> io.Error {
|
||||
b := (^Buffer)(s.stream_data)
|
||||
return buffer_unread_rune(b)
|
||||
},
|
||||
impl_destroy = proc(s: io.Stream) -> io.Error {
|
||||
b := (^Buffer)(s.stream_data)
|
||||
_buffer_proc :: proc(stream_data: rawptr, mode: io.Stream_Mode, p: []byte, offset: i64, whence: io.Seek_From) -> (n: i64, err: io.Error) {
|
||||
b := (^Buffer)(stream_data)
|
||||
#partial switch mode {
|
||||
case .Read:
|
||||
return io._i64_err(buffer_read(b, p))
|
||||
case .Read_At:
|
||||
return io._i64_err(buffer_read_at(b, p, int(offset)))
|
||||
case .Write:
|
||||
return io._i64_err(buffer_write(b, p))
|
||||
case .Write_At:
|
||||
return io._i64_err(buffer_write_at(b, p, int(offset)))
|
||||
case .Size:
|
||||
n = i64(buffer_capacity(b))
|
||||
return
|
||||
case .Destroy:
|
||||
buffer_destroy(b)
|
||||
return nil
|
||||
},
|
||||
impl_write_to = proc(s: io.Stream, w: io.Writer) -> (n: i64, err: io.Error) {
|
||||
b := (^Buffer)(s.stream_data)
|
||||
return buffer_write_to(b, w)
|
||||
},
|
||||
impl_read_from = proc(s: io.Stream, r: io.Reader) -> (n: i64, err: io.Error) {
|
||||
b := (^Buffer)(s.stream_data)
|
||||
return buffer_read_from(b, r)
|
||||
},
|
||||
return
|
||||
case .Query:
|
||||
return io.query_utility({.Read, .Read_At, .Write, .Write_At, .Size, .Destroy})
|
||||
}
|
||||
return 0, .Empty
|
||||
}
|
||||
|
||||
|
||||
+20
-39
@@ -16,8 +16,8 @@ reader_init :: proc(r: ^Reader, s: []byte) {
|
||||
}
|
||||
|
||||
reader_to_stream :: proc(r: ^Reader) -> (s: io.Stream) {
|
||||
s.stream_data = r
|
||||
s.stream_vtable = &_reader_vtable
|
||||
s.data = r
|
||||
s.procedure = _reader_proc
|
||||
return
|
||||
}
|
||||
|
||||
@@ -137,41 +137,22 @@ reader_write_to :: proc(r: ^Reader, w: io.Writer) -> (n: i64, err: io.Error) {
|
||||
|
||||
|
||||
@(private)
|
||||
_reader_vtable := io.Stream_VTable{
|
||||
impl_size = proc(s: io.Stream) -> i64 {
|
||||
r := (^Reader)(s.stream_data)
|
||||
return reader_size(r)
|
||||
},
|
||||
impl_read = proc(s: io.Stream, p: []byte) -> (n: int, err: io.Error) {
|
||||
r := (^Reader)(s.stream_data)
|
||||
return reader_read(r, p)
|
||||
},
|
||||
impl_read_at = proc(s: io.Stream, p: []byte, off: i64) -> (n: int, err: io.Error) {
|
||||
r := (^Reader)(s.stream_data)
|
||||
return reader_read_at(r, p, off)
|
||||
},
|
||||
impl_read_byte = proc(s: io.Stream) -> (byte, io.Error) {
|
||||
r := (^Reader)(s.stream_data)
|
||||
return reader_read_byte(r)
|
||||
},
|
||||
impl_unread_byte = proc(s: io.Stream) -> io.Error {
|
||||
r := (^Reader)(s.stream_data)
|
||||
return reader_unread_byte(r)
|
||||
},
|
||||
impl_read_rune = proc(s: io.Stream) -> (ch: rune, size: int, err: io.Error) {
|
||||
r := (^Reader)(s.stream_data)
|
||||
return reader_read_rune(r)
|
||||
},
|
||||
impl_unread_rune = proc(s: io.Stream) -> io.Error {
|
||||
r := (^Reader)(s.stream_data)
|
||||
return reader_unread_rune(r)
|
||||
},
|
||||
impl_seek = proc(s: io.Stream, offset: i64, whence: io.Seek_From) -> (i64, io.Error) {
|
||||
r := (^Reader)(s.stream_data)
|
||||
return reader_seek(r, offset, whence)
|
||||
},
|
||||
impl_write_to = proc(s: io.Stream, w: io.Writer) -> (n: i64, err: io.Error) {
|
||||
r := (^Reader)(s.stream_data)
|
||||
return reader_write_to(r, w)
|
||||
},
|
||||
_reader_proc :: proc(stream_data: rawptr, mode: io.Stream_Mode, p: []byte, offset: i64, whence: io.Seek_From) -> (n: i64, err: io.Error) {
|
||||
r := (^Reader)(stream_data)
|
||||
#partial switch mode {
|
||||
case .Read:
|
||||
return io._i64_err(reader_read(r, p))
|
||||
case .Read_At:
|
||||
return io._i64_err(reader_read_at(r, p, offset))
|
||||
case .Seek:
|
||||
n, err = reader_seek(r, offset, whence)
|
||||
return
|
||||
case .Size:
|
||||
n = reader_size(r)
|
||||
return
|
||||
case .Query:
|
||||
return io.query_utility({.Read, .Read_At, .Seek, .Size, .Query})
|
||||
}
|
||||
return 0, .Empty
|
||||
}
|
||||
|
||||
|
||||
@@ -1118,7 +1118,7 @@ expand_macro :: proc(cpp: ^Preprocessor, rest: ^^Token, tok: ^Token) -> bool {
|
||||
|
||||
search_include_next :: proc(cpp: ^Preprocessor, filename: string) -> (path: string, ok: bool) {
|
||||
for ; cpp.include_next_index < len(cpp.include_paths); cpp.include_next_index += 1 {
|
||||
tpath := filepath.join(elems={cpp.include_paths[cpp.include_next_index], filename}, allocator=context.temp_allocator)
|
||||
tpath := filepath.join({cpp.include_paths[cpp.include_next_index], filename}, allocator=context.temp_allocator)
|
||||
if os.exists(tpath) {
|
||||
return strings.clone(tpath), true
|
||||
}
|
||||
@@ -1136,7 +1136,7 @@ search_include_paths :: proc(cpp: ^Preprocessor, filename: string) -> (path: str
|
||||
}
|
||||
|
||||
for include_path in cpp.include_paths {
|
||||
tpath := filepath.join(elems={include_path, filename}, allocator=context.temp_allocator)
|
||||
tpath := filepath.join({include_path, filename}, allocator=context.temp_allocator)
|
||||
if os.exists(tpath) {
|
||||
path, ok = strings.clone(tpath), true
|
||||
cpp.filepath_cache[filename] = path
|
||||
|
||||
@@ -188,7 +188,8 @@ input_size_from_memory :: proc(z: ^Context_Memory_Input) -> (res: i64, err: Erro
|
||||
}
|
||||
|
||||
input_size_from_stream :: proc(z: ^Context_Stream_Input) -> (res: i64, err: Error) {
|
||||
return io.size(z.input), nil
|
||||
res, _ = io.size(z.input)
|
||||
return
|
||||
}
|
||||
|
||||
input_size :: proc{input_size_from_memory, input_size_from_stream}
|
||||
@@ -215,7 +216,7 @@ read_slice_from_stream :: #force_inline proc(z: ^Context_Stream_Input, size: int
|
||||
// TODO: REMOVE ALL USE OF context.temp_allocator here
|
||||
// the is literally no need for it
|
||||
b := make([]u8, size, context.temp_allocator)
|
||||
_, e := z.input->impl_read(b[:])
|
||||
_, e := io.read(z.input, b[:])
|
||||
if e == .None {
|
||||
return b, .None
|
||||
}
|
||||
|
||||
@@ -335,7 +335,7 @@ load_from_context :: proc(z: ^$C, buf: ^bytes.Buffer, known_gzip_size := -1, exp
|
||||
|
||||
// fmt.printf("GZIP: Expected Payload Size: %v\n", expected_output_size);
|
||||
|
||||
zlib_error := zlib.inflate_raw(z=z, expected_output_size=expected_output_size)
|
||||
zlib_error := zlib.inflate_raw(z, expected_output_size=expected_output_size)
|
||||
if zlib_error != nil {
|
||||
return zlib_error
|
||||
}
|
||||
|
||||
@@ -177,12 +177,10 @@ decompress_slice_to_string :: proc(input: []u8, model := DEFAULT_MODEL, allocato
|
||||
max_output_size := decompress_bound(len(input), model)
|
||||
|
||||
buf: [dynamic]u8
|
||||
if !resize(&buf, max_output_size) {
|
||||
return "", .Out_Of_Memory
|
||||
}
|
||||
resize(&buf, max_output_size) or_return
|
||||
|
||||
length, result := decompress_slice_to_output_buffer(input, buf[:])
|
||||
resize(&buf, length)
|
||||
resize(&buf, length) or_return
|
||||
return string(buf[:]), result
|
||||
}
|
||||
decompress :: proc{decompress_slice_to_output_buffer, decompress_slice_to_string}
|
||||
@@ -307,12 +305,10 @@ compress_string :: proc(input: string, model := DEFAULT_MODEL, allocator := cont
|
||||
max_output_size := compress_bound(len(input))
|
||||
|
||||
buf: [dynamic]u8
|
||||
if !resize(&buf, max_output_size) {
|
||||
return {}, .Out_Of_Memory
|
||||
}
|
||||
resize(&buf, max_output_size) or_return
|
||||
|
||||
length, result := compress_string_to_buffer(input, buf[:])
|
||||
resize(&buf, length)
|
||||
resize(&buf, length) or_return
|
||||
return buf[:length], result
|
||||
}
|
||||
compress :: proc{compress_string_to_buffer, compress_string}
|
||||
@@ -1,3 +1,4 @@
|
||||
//+vet !using-param
|
||||
package zlib
|
||||
|
||||
/*
|
||||
@@ -471,7 +472,7 @@ inflate_from_context :: proc(using ctx: ^compress.Context_Memory_Input, raw := f
|
||||
}
|
||||
|
||||
// Parse ZLIB stream without header.
|
||||
inflate_raw(z=ctx, expected_output_size=expected_output_size) or_return
|
||||
inflate_raw(ctx, expected_output_size=expected_output_size) or_return
|
||||
|
||||
if !raw {
|
||||
compress.discard_to_next_byte_lsb(ctx)
|
||||
@@ -665,7 +666,7 @@ inflate_from_byte_array :: proc(input: []u8, buf: ^bytes.Buffer, raw := false, e
|
||||
ctx.input_data = input
|
||||
ctx.output = buf
|
||||
|
||||
return inflate_from_context(ctx=&ctx, raw=raw, expected_output_size=expected_output_size)
|
||||
return inflate_from_context(&ctx, raw=raw, expected_output_size=expected_output_size)
|
||||
}
|
||||
|
||||
inflate_from_byte_array_raw :: proc(input: []u8, buf: ^bytes.Buffer, raw := false, expected_output_size := -1) -> (err: Error) {
|
||||
@@ -674,7 +675,7 @@ inflate_from_byte_array_raw :: proc(input: []u8, buf: ^bytes.Buffer, raw := fals
|
||||
ctx.input_data = input
|
||||
ctx.output = buf
|
||||
|
||||
return inflate_raw(z=&ctx, expected_output_size=expected_output_size)
|
||||
return inflate_raw(&ctx, expected_output_size=expected_output_size)
|
||||
}
|
||||
|
||||
inflate :: proc{inflate_from_context, inflate_from_byte_array}
|
||||
|
||||
@@ -14,7 +14,7 @@ Queue :: struct($T: typeid) {
|
||||
DEFAULT_CAPACITY :: 16
|
||||
|
||||
// Procedure to initialize a queue
|
||||
init :: proc(q: ^$Q/Queue($T), capacity := DEFAULT_CAPACITY, allocator := context.allocator) -> bool {
|
||||
init :: proc(q: ^$Q/Queue($T), capacity := DEFAULT_CAPACITY, allocator := context.allocator) -> runtime.Allocator_Error {
|
||||
if q.data.allocator.procedure == nil {
|
||||
q.data.allocator = allocator
|
||||
}
|
||||
@@ -55,11 +55,11 @@ space :: proc(q: $Q/Queue($T)) -> int {
|
||||
}
|
||||
|
||||
// Reserve enough space for at least the specified capacity
|
||||
reserve :: proc(q: ^$Q/Queue($T), capacity: int) -> bool {
|
||||
reserve :: proc(q: ^$Q/Queue($T), capacity: int) -> runtime.Allocator_Error {
|
||||
if uint(capacity) > q.len {
|
||||
return _grow(q, uint(capacity))
|
||||
}
|
||||
return true
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -112,25 +112,25 @@ peek_back :: proc(q: ^$Q/Queue($T), loc := #caller_location) -> ^T {
|
||||
}
|
||||
|
||||
// Push an element to the back of the queue
|
||||
push_back :: proc(q: ^$Q/Queue($T), elem: T) -> bool {
|
||||
push_back :: proc(q: ^$Q/Queue($T), elem: T) -> (ok: bool, err: runtime.Allocator_Error) {
|
||||
if space(q^) == 0 {
|
||||
_grow(q) or_return
|
||||
}
|
||||
idx := (q.offset+uint(q.len))%builtin.len(q.data)
|
||||
q.data[idx] = elem
|
||||
q.len += 1
|
||||
return true
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// Push an element to the front of the queue
|
||||
push_front :: proc(q: ^$Q/Queue($T), elem: T) -> bool {
|
||||
push_front :: proc(q: ^$Q/Queue($T), elem: T) -> (ok: bool, err: runtime.Allocator_Error) {
|
||||
if space(q^) == 0 {
|
||||
_grow(q) or_return
|
||||
}
|
||||
q.offset = uint(q.offset - 1 + builtin.len(q.data)) % builtin.len(q.data)
|
||||
q.len += 1
|
||||
q.data[q.offset] = elem
|
||||
return true
|
||||
return true, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -173,7 +173,7 @@ pop_front_safe :: proc(q: ^$Q/Queue($T)) -> (elem: T, ok: bool) {
|
||||
}
|
||||
|
||||
// Push multiple elements to the front of the queue
|
||||
push_back_elems :: proc(q: ^$Q/Queue($T), elems: ..T) -> bool {
|
||||
push_back_elems :: proc(q: ^$Q/Queue($T), elems: ..T) -> (ok: bool, err: runtime.Allocator_Error) {
|
||||
n := uint(builtin.len(elems))
|
||||
if space(q^) < int(n) {
|
||||
_grow(q, q.len + n) or_return
|
||||
@@ -188,7 +188,7 @@ push_back_elems :: proc(q: ^$Q/Queue($T), elems: ..T) -> bool {
|
||||
copy(q.data[insert_from:], elems[:insert_to])
|
||||
copy(q.data[:insert_from], elems[insert_to:])
|
||||
q.len += n
|
||||
return true
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// Consume `n` elements from the front of the queue
|
||||
@@ -225,7 +225,7 @@ clear :: proc(q: ^$Q/Queue($T)) {
|
||||
|
||||
|
||||
// Internal growinh procedure
|
||||
_grow :: proc(q: ^$Q/Queue($T), min_capacity: uint = 0) -> bool {
|
||||
_grow :: proc(q: ^$Q/Queue($T), min_capacity: uint = 0) -> runtime.Allocator_Error {
|
||||
new_capacity := max(min_capacity, uint(8), uint(builtin.len(q.data))*2)
|
||||
n := uint(builtin.len(q.data))
|
||||
builtin.resize(&q.data, int(new_capacity)) or_return
|
||||
@@ -234,5 +234,5 @@ _grow :: proc(q: ^$Q/Queue($T), min_capacity: uint = 0) -> bool {
|
||||
copy(q.data[new_capacity-diff:], q.data[q.offset:][:diff])
|
||||
q.offset += new_capacity - n
|
||||
}
|
||||
return true
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ init :: proc(sorter: ^$S/Sorter($K)) {
|
||||
}
|
||||
|
||||
destroy :: proc(sorter: ^$S/Sorter($K)) {
|
||||
for _, v in &sorter.relations {
|
||||
for _, v in sorter.relations {
|
||||
delete(v.dependents)
|
||||
}
|
||||
delete(sorter.relations)
|
||||
@@ -80,7 +80,7 @@ sort :: proc(sorter: ^$S/Sorter($K)) -> (sorted, cycled: [dynamic]K) {
|
||||
}
|
||||
}
|
||||
|
||||
for root in &sorted do for k, _ in relations[root].dependents {
|
||||
for root in sorted do for k, _ in relations[root].dependents {
|
||||
relation := &relations[k]
|
||||
relation.dependencies -= 1
|
||||
if relation.dependencies == 0 {
|
||||
|
||||
@@ -70,7 +70,7 @@ hash_stream_224 :: proc(s: io.Stream) -> ([DIGEST_SIZE_224]byte, bool) {
|
||||
defer delete(buf)
|
||||
read := 1
|
||||
for read > 0 {
|
||||
read, _ = s->impl_read(buf)
|
||||
read, _ = io.read(s, buf)
|
||||
if read > 0 {
|
||||
update(&ctx, buf[:read])
|
||||
}
|
||||
@@ -149,7 +149,7 @@ hash_stream_256 :: proc(s: io.Stream) -> ([DIGEST_SIZE_256]byte, bool) {
|
||||
defer delete(buf)
|
||||
read := 1
|
||||
for read > 0 {
|
||||
read, _ = s->impl_read(buf)
|
||||
read, _ = io.read(s, buf)
|
||||
if read > 0 {
|
||||
update(&ctx, buf[:read])
|
||||
}
|
||||
@@ -228,7 +228,7 @@ hash_stream_384 :: proc(s: io.Stream) -> ([DIGEST_SIZE_384]byte, bool) {
|
||||
defer delete(buf)
|
||||
read := 1
|
||||
for read > 0 {
|
||||
read, _ = s->impl_read(buf)
|
||||
read, _ = io.read(s, buf)
|
||||
if read > 0 {
|
||||
update(&ctx, buf[:read])
|
||||
}
|
||||
@@ -307,7 +307,7 @@ hash_stream_512 :: proc(s: io.Stream) -> ([DIGEST_SIZE_512]byte, bool) {
|
||||
defer delete(buf)
|
||||
read := 1
|
||||
for read > 0 {
|
||||
read, _ = s->impl_read(buf)
|
||||
read, _ = io.read(s, buf)
|
||||
if read > 0 {
|
||||
update(&ctx, buf[:read])
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ hash_stream :: proc(s: io.Stream) -> ([DIGEST_SIZE]byte, bool) {
|
||||
defer delete(buf)
|
||||
read := 1
|
||||
for read > 0 {
|
||||
read, _ = s->impl_read(buf)
|
||||
read, _ = io.read(s, buf)
|
||||
if read > 0 {
|
||||
_blake2.update(&ctx, buf[:read])
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ hash_stream :: proc(s: io.Stream) -> ([DIGEST_SIZE]byte, bool) {
|
||||
defer delete(buf)
|
||||
read := 1
|
||||
for read > 0 {
|
||||
read, _ = s->impl_read(buf)
|
||||
read, _ = io.read(s, buf)
|
||||
if read > 0 {
|
||||
_blake2.update(&ctx, buf[:read])
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ hash_stream :: proc(s: io.Stream) -> ([DIGEST_SIZE]byte, bool) {
|
||||
defer delete(buf)
|
||||
read := 1
|
||||
for read > 0 {
|
||||
read, _ = s->impl_read(buf)
|
||||
read, _ = io.read(s, buf)
|
||||
if read > 0 {
|
||||
update(&ctx, buf[:read])
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ hash_stream_224 :: proc(s: io.Stream) -> ([DIGEST_SIZE_224]byte, bool) {
|
||||
defer delete(buf)
|
||||
read := 1
|
||||
for read > 0 {
|
||||
read, _ = s->impl_read(buf)
|
||||
read, _ = io.read(s, buf)
|
||||
if read > 0 {
|
||||
update(&ctx, buf[:read])
|
||||
}
|
||||
@@ -149,7 +149,7 @@ hash_stream_256 :: proc(s: io.Stream) -> ([DIGEST_SIZE_256]byte, bool) {
|
||||
defer delete(buf)
|
||||
read := 1
|
||||
for read > 0 {
|
||||
read, _ = s->impl_read(buf)
|
||||
read, _ = io.read(s, buf)
|
||||
if read > 0 {
|
||||
update(&ctx, buf[:read])
|
||||
}
|
||||
@@ -228,7 +228,7 @@ hash_stream_384 :: proc(s: io.Stream) -> ([DIGEST_SIZE_384]byte, bool) {
|
||||
defer delete(buf)
|
||||
read := 1
|
||||
for read > 0 {
|
||||
read, _ = s->impl_read(buf)
|
||||
read, _ = io.read(s, buf)
|
||||
if read > 0 {
|
||||
update(&ctx, buf[:read])
|
||||
}
|
||||
@@ -307,7 +307,7 @@ hash_stream_512 :: proc(s: io.Stream) -> ([DIGEST_SIZE_512]byte, bool) {
|
||||
defer delete(buf)
|
||||
read := 1
|
||||
for read > 0 {
|
||||
read, _ = s->impl_read(buf)
|
||||
read, _ = io.read(s, buf)
|
||||
if read > 0 {
|
||||
update(&ctx, buf[:read])
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ hash_stream_128_3 :: proc(s: io.Stream) -> ([DIGEST_SIZE_128]byte, bool) {
|
||||
defer delete(buf)
|
||||
read := 1
|
||||
for read > 0 {
|
||||
read, _ = s->impl_read(buf)
|
||||
read, _ = io.read(s, buf)
|
||||
ctx.str_len = u32(len(buf[:read]))
|
||||
if read > 0 {
|
||||
update(&ctx, buf[:read])
|
||||
@@ -164,7 +164,7 @@ hash_stream_128_4 :: proc(s: io.Stream) -> ([DIGEST_SIZE_128]byte, bool) {
|
||||
defer delete(buf)
|
||||
read := 1
|
||||
for read > 0 {
|
||||
read, _ = s->impl_read(buf)
|
||||
read, _ = io.read(s, buf)
|
||||
ctx.str_len = u32(len(buf[:read]))
|
||||
if read > 0 {
|
||||
update(&ctx, buf[:read])
|
||||
@@ -249,7 +249,7 @@ hash_stream_128_5 :: proc(s: io.Stream) -> ([DIGEST_SIZE_128]byte, bool) {
|
||||
defer delete(buf)
|
||||
read := 1
|
||||
for read > 0 {
|
||||
read, _ = s->impl_read(buf)
|
||||
read, _ = io.read(s, buf)
|
||||
ctx.str_len = u32(len(buf[:read]))
|
||||
if read > 0 {
|
||||
update(&ctx, buf[:read])
|
||||
@@ -334,7 +334,7 @@ hash_stream_160_3 :: proc(s: io.Stream) -> ([DIGEST_SIZE_160]byte, bool) {
|
||||
defer delete(buf)
|
||||
read := 1
|
||||
for read > 0 {
|
||||
read, _ = s->impl_read(buf)
|
||||
read, _ = io.read(s, buf)
|
||||
ctx.str_len = u32(len(buf[:read]))
|
||||
if read > 0 {
|
||||
update(&ctx, buf[:read])
|
||||
@@ -419,7 +419,7 @@ hash_stream_160_4 :: proc(s: io.Stream) -> ([DIGEST_SIZE_160]byte, bool) {
|
||||
defer delete(buf)
|
||||
read := 1
|
||||
for read > 0 {
|
||||
read, _ = s->impl_read(buf)
|
||||
read, _ = io.read(s, buf)
|
||||
ctx.str_len = u32(len(buf[:read]))
|
||||
if read > 0 {
|
||||
update(&ctx, buf[:read])
|
||||
@@ -504,7 +504,7 @@ hash_stream_160_5 :: proc(s: io.Stream) -> ([DIGEST_SIZE_160]byte, bool) {
|
||||
defer delete(buf)
|
||||
read := 1
|
||||
for read > 0 {
|
||||
read, _ = s->impl_read(buf)
|
||||
read, _ = io.read(s, buf)
|
||||
ctx.str_len = u32(len(buf[:read]))
|
||||
if read > 0 {
|
||||
update(&ctx, buf[:read])
|
||||
@@ -589,7 +589,7 @@ hash_stream_192_3 :: proc(s: io.Stream) -> ([DIGEST_SIZE_192]byte, bool) {
|
||||
defer delete(buf)
|
||||
read := 1
|
||||
for read > 0 {
|
||||
read, _ = s->impl_read(buf)
|
||||
read, _ = io.read(s, buf)
|
||||
ctx.str_len = u32(len(buf[:read]))
|
||||
if read > 0 {
|
||||
update(&ctx, buf[:read])
|
||||
@@ -674,7 +674,7 @@ hash_stream_192_4 :: proc(s: io.Stream) -> ([DIGEST_SIZE_192]byte, bool) {
|
||||
defer delete(buf)
|
||||
read := 1
|
||||
for read > 0 {
|
||||
read, _ = s->impl_read(buf)
|
||||
read, _ = io.read(s, buf)
|
||||
ctx.str_len = u32(len(buf[:read]))
|
||||
if read > 0 {
|
||||
update(&ctx, buf[:read])
|
||||
@@ -759,7 +759,7 @@ hash_stream_192_5 :: proc(s: io.Stream) -> ([DIGEST_SIZE_192]byte, bool) {
|
||||
defer delete(buf)
|
||||
read := 1
|
||||
for read > 0 {
|
||||
read, _ = s->impl_read(buf)
|
||||
read, _ = io.read(s, buf)
|
||||
ctx.str_len = u32(len(buf[:read]))
|
||||
if read > 0 {
|
||||
update(&ctx, buf[:read])
|
||||
@@ -844,7 +844,7 @@ hash_stream_224_3 :: proc(s: io.Stream) -> ([DIGEST_SIZE_224]byte, bool) {
|
||||
defer delete(buf)
|
||||
read := 1
|
||||
for read > 0 {
|
||||
read, _ = s->impl_read(buf)
|
||||
read, _ = io.read(s, buf)
|
||||
ctx.str_len = u32(len(buf[:read]))
|
||||
if read > 0 {
|
||||
update(&ctx, buf[:read])
|
||||
@@ -929,7 +929,7 @@ hash_stream_224_4 :: proc(s: io.Stream) -> ([DIGEST_SIZE_224]byte, bool) {
|
||||
defer delete(buf)
|
||||
read := 1
|
||||
for read > 0 {
|
||||
read, _ = s->impl_read(buf)
|
||||
read, _ = io.read(s, buf)
|
||||
ctx.str_len = u32(len(buf[:read]))
|
||||
if read > 0 {
|
||||
update(&ctx, buf[:read])
|
||||
@@ -1014,7 +1014,7 @@ hash_stream_224_5 :: proc(s: io.Stream) -> ([DIGEST_SIZE_224]byte, bool) {
|
||||
defer delete(buf)
|
||||
read := 1
|
||||
for read > 0 {
|
||||
read, _ = s->impl_read(buf)
|
||||
read, _ = io.read(s, buf)
|
||||
ctx.str_len = u32(len(buf[:read]))
|
||||
if read > 0 {
|
||||
update(&ctx, buf[:read])
|
||||
@@ -1099,7 +1099,7 @@ hash_stream_256_3 :: proc(s: io.Stream) -> ([DIGEST_SIZE_256]byte, bool) {
|
||||
defer delete(buf)
|
||||
read := 1
|
||||
for read > 0 {
|
||||
read, _ = s->impl_read(buf)
|
||||
read, _ = io.read(s, buf)
|
||||
ctx.str_len = u32(len(buf[:read]))
|
||||
if read > 0 {
|
||||
update(&ctx, buf[:read])
|
||||
@@ -1184,7 +1184,7 @@ hash_stream_256_4 :: proc(s: io.Stream) -> ([DIGEST_SIZE_256]byte, bool) {
|
||||
defer delete(buf)
|
||||
read := 1
|
||||
for read > 0 {
|
||||
read, _ = s->impl_read(buf)
|
||||
read, _ = io.read(s, buf)
|
||||
ctx.str_len = u32(len(buf[:read]))
|
||||
if read > 0 {
|
||||
update(&ctx, buf[:read])
|
||||
@@ -1270,7 +1270,7 @@ hash_stream_256_5 :: proc(s: io.Stream) -> ([DIGEST_SIZE_256]byte, bool) {
|
||||
defer delete(buf)
|
||||
read := 1
|
||||
for read > 0 {
|
||||
read, _ = s->impl_read(buf)
|
||||
read, _ = io.read(s, buf)
|
||||
ctx.str_len = u32(len(buf[:read]))
|
||||
if read > 0 {
|
||||
update(&ctx, buf[:read])
|
||||
|
||||
@@ -70,7 +70,7 @@ hash_stream_224 :: proc(s: io.Stream) -> ([DIGEST_SIZE_224]byte, bool) {
|
||||
defer delete(buf)
|
||||
read := 1
|
||||
for read > 0 {
|
||||
read, _ = s->impl_read(buf)
|
||||
read, _ = io.read(s, buf)
|
||||
if read > 0 {
|
||||
update(&ctx, buf[:read])
|
||||
}
|
||||
@@ -149,7 +149,7 @@ hash_stream_256 :: proc(s: io.Stream) -> ([DIGEST_SIZE_256]byte, bool) {
|
||||
defer delete(buf)
|
||||
read := 1
|
||||
for read > 0 {
|
||||
read, _ = s->impl_read(buf)
|
||||
read, _ = io.read(s, buf)
|
||||
if read > 0 {
|
||||
update(&ctx, buf[:read])
|
||||
}
|
||||
@@ -228,7 +228,7 @@ hash_stream_384 :: proc(s: io.Stream) -> ([DIGEST_SIZE_384]byte, bool) {
|
||||
defer delete(buf)
|
||||
read := 1
|
||||
for read > 0 {
|
||||
read, _ = s->impl_read(buf)
|
||||
read, _ = io.read(s, buf)
|
||||
if read > 0 {
|
||||
update(&ctx, buf[:read])
|
||||
}
|
||||
@@ -307,7 +307,7 @@ hash_stream_512 :: proc(s: io.Stream) -> ([DIGEST_SIZE_512]byte, bool) {
|
||||
defer delete(buf)
|
||||
read := 1
|
||||
for read > 0 {
|
||||
read, _ = s->impl_read(buf)
|
||||
read, _ = io.read(s, buf)
|
||||
if read > 0 {
|
||||
update(&ctx, buf[:read])
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ hash_stream_224 :: proc(s: io.Stream) -> ([DIGEST_SIZE_224]byte, bool) {
|
||||
defer delete(buf)
|
||||
read := 1
|
||||
for read > 0 {
|
||||
read, _ = s->impl_read(buf)
|
||||
read, _ = io.read(s, buf)
|
||||
if read > 0 {
|
||||
_sha3.update(&ctx, buf[:read])
|
||||
}
|
||||
@@ -159,7 +159,7 @@ hash_stream_256 :: proc(s: io.Stream) -> ([DIGEST_SIZE_256]byte, bool) {
|
||||
defer delete(buf)
|
||||
read := 1
|
||||
for read > 0 {
|
||||
read, _ = s->impl_read(buf)
|
||||
read, _ = io.read(s, buf)
|
||||
if read > 0 {
|
||||
_sha3.update(&ctx, buf[:read])
|
||||
}
|
||||
@@ -241,7 +241,7 @@ hash_stream_384 :: proc(s: io.Stream) -> ([DIGEST_SIZE_384]byte, bool) {
|
||||
defer delete(buf)
|
||||
read := 1
|
||||
for read > 0 {
|
||||
read, _ = s->impl_read(buf)
|
||||
read, _ = io.read(s, buf)
|
||||
if read > 0 {
|
||||
_sha3.update(&ctx, buf[:read])
|
||||
}
|
||||
@@ -323,7 +323,7 @@ hash_stream_512 :: proc(s: io.Stream) -> ([DIGEST_SIZE_512]byte, bool) {
|
||||
defer delete(buf)
|
||||
read := 1
|
||||
for read > 0 {
|
||||
read, _ = s->impl_read(buf)
|
||||
read, _ = io.read(s, buf)
|
||||
if read > 0 {
|
||||
_sha3.update(&ctx, buf[:read])
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ hash_stream :: proc(s: io.Stream) -> ([DIGEST_SIZE]byte, bool) {
|
||||
defer delete(buf)
|
||||
read := 1
|
||||
for read > 0 {
|
||||
read, _ = s->impl_read(buf)
|
||||
read, _ = io.read(s, buf)
|
||||
if read > 0 {
|
||||
update(&ctx, buf[:read])
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ hash_stream :: proc(s: io.Stream) -> ([DIGEST_SIZE]byte, bool) {
|
||||
defer delete(buf)
|
||||
read := 1
|
||||
for read > 0 {
|
||||
read, _ = s->impl_read(buf)
|
||||
read, _ = io.read(s, buf)
|
||||
if read > 0 {
|
||||
update(&ctx, buf[:read])
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ hash_stream :: proc(s: io.Stream) -> ([DIGEST_SIZE]byte, bool) {
|
||||
defer delete(buf)
|
||||
read := 1
|
||||
for read > 0 {
|
||||
read, _ = s->impl_read(buf)
|
||||
read, _ = io.read(s, buf)
|
||||
if read > 0 {
|
||||
update(&ctx, buf[:read])
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ hash_stream_128 :: proc(s: io.Stream) -> ([DIGEST_SIZE_128]byte, bool) {
|
||||
defer delete(buf)
|
||||
read := 1
|
||||
for read > 0 {
|
||||
read, _ = s->impl_read(buf)
|
||||
read, _ = io.read(s, buf)
|
||||
if read > 0 {
|
||||
update(&ctx, buf[:read])
|
||||
}
|
||||
@@ -145,7 +145,7 @@ hash_stream_160 :: proc(s: io.Stream) -> ([DIGEST_SIZE_160]byte, bool) {
|
||||
defer delete(buf)
|
||||
read := 1
|
||||
for read > 0 {
|
||||
read, _ = s->impl_read(buf)
|
||||
read, _ = io.read(s, buf)
|
||||
if read > 0 {
|
||||
update(&ctx, buf[:read])
|
||||
}
|
||||
@@ -221,7 +221,7 @@ hash_stream_256 :: proc(s: io.Stream) -> ([DIGEST_SIZE_256]byte, bool) {
|
||||
defer delete(buf)
|
||||
read := 1
|
||||
for read > 0 {
|
||||
read, _ = s->impl_read(buf)
|
||||
read, _ = io.read(s, buf)
|
||||
if read > 0 {
|
||||
update(&ctx, buf[:read])
|
||||
}
|
||||
@@ -297,7 +297,7 @@ hash_stream_320 :: proc(s: io.Stream) -> ([DIGEST_SIZE_320]byte, bool) {
|
||||
defer delete(buf)
|
||||
read := 1
|
||||
for read > 0 {
|
||||
read, _ = s->impl_read(buf)
|
||||
read, _ = io.read(s, buf)
|
||||
if read > 0 {
|
||||
update(&ctx, buf[:read])
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ hash_stream :: proc(s: io.Stream) -> ([DIGEST_SIZE]byte, bool) {
|
||||
defer delete(buf)
|
||||
read := 1
|
||||
for read > 0 {
|
||||
read, _ = s->impl_read(buf)
|
||||
read, _ = io.read(s, buf)
|
||||
if read > 0 {
|
||||
update(&ctx, buf[:read])
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ hash_stream_224 :: proc(s: io.Stream) -> ([DIGEST_SIZE_224]byte, bool) {
|
||||
defer delete(buf)
|
||||
read := 1
|
||||
for read > 0 {
|
||||
read, _ = s->impl_read(buf)
|
||||
read, _ = io.read(s, buf)
|
||||
if read > 0 {
|
||||
update(&ctx, buf[:read])
|
||||
}
|
||||
@@ -153,7 +153,7 @@ hash_stream_256 :: proc(s: io.Stream) -> ([DIGEST_SIZE_256]byte, bool) {
|
||||
defer delete(buf)
|
||||
read := 1
|
||||
for read > 0 {
|
||||
read, _ = s->impl_read(buf)
|
||||
read, _ = io.read(s, buf)
|
||||
if read > 0 {
|
||||
update(&ctx, buf[:read])
|
||||
}
|
||||
@@ -232,7 +232,7 @@ hash_stream_384 :: proc(s: io.Stream) -> ([DIGEST_SIZE_384]byte, bool) {
|
||||
defer delete(buf)
|
||||
read := 1
|
||||
for read > 0 {
|
||||
read, _ = s->impl_read(buf)
|
||||
read, _ = io.read(s, buf)
|
||||
if read > 0 {
|
||||
update(&ctx, buf[:read])
|
||||
}
|
||||
@@ -311,7 +311,7 @@ hash_stream_512 :: proc(s: io.Stream) -> ([DIGEST_SIZE_512]byte, bool) {
|
||||
defer delete(buf)
|
||||
read := 1
|
||||
for read > 0 {
|
||||
read, _ = s->impl_read(buf)
|
||||
read, _ = io.read(s, buf)
|
||||
if read > 0 {
|
||||
update(&ctx, buf[:read])
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ hash_stream_224 :: proc(s: io.Stream) -> ([DIGEST_SIZE_224]byte, bool) {
|
||||
defer delete(buf)
|
||||
read := 1
|
||||
for read > 0 {
|
||||
read, _ = s->impl_read(buf)
|
||||
read, _ = io.read(s, buf)
|
||||
if read > 0 {
|
||||
_sha3.update(&ctx, buf[:read])
|
||||
}
|
||||
@@ -152,7 +152,7 @@ hash_stream_256 :: proc(s: io.Stream) -> ([DIGEST_SIZE_256]byte, bool) {
|
||||
defer delete(buf)
|
||||
read := 1
|
||||
for read > 0 {
|
||||
read, _ = s->impl_read(buf)
|
||||
read, _ = io.read(s, buf)
|
||||
if read > 0 {
|
||||
_sha3.update(&ctx, buf[:read])
|
||||
}
|
||||
@@ -231,7 +231,7 @@ hash_stream_384 :: proc(s: io.Stream) -> ([DIGEST_SIZE_384]byte, bool) {
|
||||
defer delete(buf)
|
||||
read := 1
|
||||
for read > 0 {
|
||||
read, _ = s->impl_read(buf)
|
||||
read, _ = io.read(s, buf)
|
||||
if read > 0 {
|
||||
_sha3.update(&ctx, buf[:read])
|
||||
}
|
||||
@@ -310,7 +310,7 @@ hash_stream_512 :: proc(s: io.Stream) -> ([DIGEST_SIZE_512]byte, bool) {
|
||||
defer delete(buf)
|
||||
read := 1
|
||||
for read > 0 {
|
||||
read, _ = s->impl_read(buf)
|
||||
read, _ = io.read(s, buf)
|
||||
if read > 0 {
|
||||
_sha3.update(&ctx, buf[:read])
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ hash_stream_128 :: proc(s: io.Stream) -> ([DIGEST_SIZE_128]byte, bool) {
|
||||
defer delete(buf)
|
||||
read := 1
|
||||
for read > 0 {
|
||||
read, _ = s->impl_read(buf)
|
||||
read, _ = io.read(s, buf)
|
||||
if read > 0 {
|
||||
_sha3.update(&ctx, buf[:read])
|
||||
}
|
||||
@@ -155,7 +155,7 @@ hash_stream_256 :: proc(s: io.Stream) -> ([DIGEST_SIZE_256]byte, bool) {
|
||||
defer delete(buf)
|
||||
read := 1
|
||||
for read > 0 {
|
||||
read, _ = s->impl_read(buf)
|
||||
read, _ = io.read(s, buf)
|
||||
if read > 0 {
|
||||
_sha3.update(&ctx, buf[:read])
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ hash_stream :: proc(s: io.Stream) -> ([DIGEST_SIZE]byte, bool) {
|
||||
defer delete(buf)
|
||||
read := 1
|
||||
for read > 0 {
|
||||
read, _ = s->impl_read(buf)
|
||||
read, _ = io.read(s, buf)
|
||||
if read > 0 {
|
||||
update(&ctx, buf[:read])
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ hash_stream_256 :: proc(s: io.Stream) -> ([DIGEST_SIZE_256]byte, bool) {
|
||||
defer delete(buf)
|
||||
read := 1
|
||||
for read > 0 {
|
||||
read, _ = s->impl_read(buf)
|
||||
read, _ = io.read(s, buf)
|
||||
if read > 0 {
|
||||
update(&ctx, buf[:read])
|
||||
}
|
||||
@@ -146,7 +146,7 @@ hash_stream_512 :: proc(s: io.Stream) -> ([DIGEST_SIZE_512]byte, bool) {
|
||||
defer delete(buf)
|
||||
read := 1
|
||||
for read > 0 {
|
||||
read, _ = s->impl_read(buf)
|
||||
read, _ = io.read(s, buf)
|
||||
if read > 0 {
|
||||
update(&ctx, buf[:read])
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ hash_stream_128 :: proc(s: io.Stream) -> ([DIGEST_SIZE_128]byte, bool) {
|
||||
defer delete(buf)
|
||||
read := 1
|
||||
for read > 0 {
|
||||
read, _ = s->impl_read(buf)
|
||||
read, _ = io.read(s, buf)
|
||||
if read > 0 {
|
||||
_tiger.update(&ctx, buf[:read])
|
||||
}
|
||||
@@ -150,7 +150,7 @@ hash_stream_160 :: proc(s: io.Stream) -> ([DIGEST_SIZE_160]byte, bool) {
|
||||
defer delete(buf)
|
||||
read := 1
|
||||
for read > 0 {
|
||||
read, _ = s->impl_read(buf)
|
||||
read, _ = io.read(s, buf)
|
||||
if read > 0 {
|
||||
_tiger.update(&ctx, buf[:read])
|
||||
}
|
||||
@@ -229,7 +229,7 @@ hash_stream_192 :: proc(s: io.Stream) -> ([DIGEST_SIZE_192]byte, bool) {
|
||||
defer delete(buf)
|
||||
read := 1
|
||||
for read > 0 {
|
||||
read, _ = s->impl_read(buf)
|
||||
read, _ = io.read(s, buf)
|
||||
if read > 0 {
|
||||
_tiger.update(&ctx, buf[:read])
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ hash_stream_128 :: proc(s: io.Stream) -> ([DIGEST_SIZE_128]byte, bool) {
|
||||
defer delete(buf)
|
||||
read := 1
|
||||
for read > 0 {
|
||||
read, _ = s->impl_read(buf)
|
||||
read, _ = io.read(s, buf)
|
||||
if read > 0 {
|
||||
_tiger.update(&ctx, buf[:read])
|
||||
}
|
||||
@@ -150,7 +150,7 @@ hash_stream_160 :: proc(s: io.Stream) -> ([DIGEST_SIZE_160]byte, bool) {
|
||||
defer delete(buf)
|
||||
read := 1
|
||||
for read > 0 {
|
||||
read, _ = s->impl_read(buf)
|
||||
read, _ = io.read(s, buf)
|
||||
if read > 0 {
|
||||
_tiger.update(&ctx, buf[:read])
|
||||
}
|
||||
@@ -229,7 +229,7 @@ hash_stream_192 :: proc(s: io.Stream) -> ([DIGEST_SIZE_192]byte, bool) {
|
||||
defer delete(buf)
|
||||
read := 1
|
||||
for read > 0 {
|
||||
read, _ = s->impl_read(buf)
|
||||
read, _ = io.read(s, buf)
|
||||
if read > 0 {
|
||||
_tiger.update(&ctx, buf[:read])
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ hash_stream :: proc(s: io.Stream) -> ([DIGEST_SIZE]byte, bool) {
|
||||
defer delete(buf)
|
||||
read := 1
|
||||
for read > 0 {
|
||||
read, _ = s->impl_read(buf)
|
||||
read, _ = io.read(s, buf)
|
||||
if read > 0 {
|
||||
update(&ctx, buf[:read])
|
||||
}
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
package debug_pe
|
||||
|
||||
import "core:runtime"
|
||||
import "core:io"
|
||||
|
||||
Section_Header32 :: struct {
|
||||
name: [8]u8,
|
||||
virtual_size: u32le,
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
package dynlib
|
||||
|
||||
_load_library :: proc(path: string, global_symbols := false) -> (Library, bool) {
|
||||
return
|
||||
return nil, false
|
||||
}
|
||||
|
||||
_unload_library :: proc(library: Library) -> bool {
|
||||
return
|
||||
return false
|
||||
}
|
||||
|
||||
_symbol_address :: proc(library: Library, symbol: string) -> (ptr: rawptr, found: bool) {
|
||||
return
|
||||
return nil, false
|
||||
}
|
||||
|
||||
@@ -184,28 +184,26 @@ decode_xml :: proc(input: string, options := XML_Decode_Options{}, allocator :=
|
||||
|
||||
advance :: proc(t: ^Tokenizer) -> (err: Error) {
|
||||
if t == nil { return .Tokenizer_Is_Nil }
|
||||
using t
|
||||
|
||||
#no_bounds_check {
|
||||
if read_offset < len(src) {
|
||||
offset = read_offset
|
||||
r, w = rune(src[read_offset]), 1
|
||||
if t.read_offset < len(t.src) {
|
||||
t.offset = t.read_offset
|
||||
t.r, t.w = rune(t.src[t.read_offset]), 1
|
||||
switch {
|
||||
case r == 0:
|
||||
case t.r == 0:
|
||||
return .Illegal_NUL_Character
|
||||
case r >= utf8.RUNE_SELF:
|
||||
r, w = utf8.decode_rune_in_string(src[read_offset:])
|
||||
if r == utf8.RUNE_ERROR && w == 1 {
|
||||
case t.r >= utf8.RUNE_SELF:
|
||||
t.r, t.w = utf8.decode_rune_in_string(t.src[t.read_offset:])
|
||||
if t.r == utf8.RUNE_ERROR && t.w == 1 {
|
||||
return .Illegal_UTF_Encoding
|
||||
} else if r == utf8.RUNE_BOM && offset > 0 {
|
||||
} else if t.r == utf8.RUNE_BOM && t.offset > 0 {
|
||||
return .Illegal_BOM
|
||||
}
|
||||
}
|
||||
read_offset += w
|
||||
t.read_offset += t.w
|
||||
return .None
|
||||
} else {
|
||||
offset = len(src)
|
||||
r = -1
|
||||
t.offset = len(t.src)
|
||||
t.r = -1
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -273,26 +271,25 @@ _extract_xml_entity :: proc(t: ^Tokenizer) -> (entity: string, err: Error) {
|
||||
All of these would be in the ASCII range.
|
||||
Even if one is not, it doesn't matter. All characters we need to compare to extract are.
|
||||
*/
|
||||
using t
|
||||
|
||||
length := len(t.src)
|
||||
found := false
|
||||
|
||||
#no_bounds_check {
|
||||
for read_offset < length {
|
||||
if src[read_offset] == ';' {
|
||||
for t.read_offset < length {
|
||||
if t.src[t.read_offset] == ';' {
|
||||
t.read_offset += 1
|
||||
found = true
|
||||
read_offset += 1
|
||||
break
|
||||
}
|
||||
read_offset += 1
|
||||
t.read_offset += 1
|
||||
}
|
||||
}
|
||||
|
||||
if found {
|
||||
return string(src[offset + 1 : read_offset - 1]), .None
|
||||
return string(t.src[t.offset + 1 : t.read_offset - 1]), .None
|
||||
}
|
||||
return string(src[offset : read_offset]), .Invalid_Entity_Encoding
|
||||
return string(t.src[t.offset : t.read_offset]), .Invalid_Entity_Encoding
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
package hex
|
||||
|
||||
import "core:strings"
|
||||
|
||||
encode :: proc(src: []byte, allocator := context.allocator) -> []byte #no_bounds_check {
|
||||
dst := make([]byte, len(src) * 2, allocator)
|
||||
for i, j := 0, 0; i < len(src); i += 1 {
|
||||
v := src[i]
|
||||
dst[j] = HEXTABLE[v>>4]
|
||||
dst[j+1] = HEXTABLE[v&0x0f]
|
||||
j += 2
|
||||
}
|
||||
|
||||
return dst
|
||||
}
|
||||
|
||||
|
||||
decode :: proc(src: []byte, allocator := context.allocator) -> (dst: []byte, ok: bool) #no_bounds_check {
|
||||
if len(src) % 2 == 1 {
|
||||
return
|
||||
}
|
||||
|
||||
dst = make([]byte, len(src) / 2, allocator)
|
||||
for i, j := 0, 1; j < len(src); j += 2 {
|
||||
p := src[j-1]
|
||||
q := src[j]
|
||||
|
||||
a := hex_digit(p) or_return
|
||||
b := hex_digit(q) or_return
|
||||
|
||||
dst[i] = (a << 4) | b
|
||||
i += 1
|
||||
}
|
||||
|
||||
return dst, true
|
||||
}
|
||||
|
||||
// Decodes the given sequence into one byte.
|
||||
// Should be called with one byte worth of the source, eg: 0x23 -> '#'.
|
||||
decode_sequence :: proc(str: string) -> (res: byte, ok: bool) {
|
||||
str := str
|
||||
if strings.has_prefix(str, "0x") || strings.has_prefix(str, "0X") {
|
||||
str = str[2:]
|
||||
}
|
||||
|
||||
if len(str) != 2 {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
upper := hex_digit(str[0]) or_return
|
||||
lower := hex_digit(str[1]) or_return
|
||||
|
||||
return upper << 4 | lower, true
|
||||
}
|
||||
|
||||
@(private)
|
||||
HEXTABLE := [16]byte {
|
||||
'0', '1', '2', '3',
|
||||
'4', '5', '6', '7',
|
||||
'8', '9', 'a', 'b',
|
||||
'c', 'd', 'e', 'f',
|
||||
}
|
||||
|
||||
@(private)
|
||||
hex_digit :: proc(char: byte) -> (u8, bool) {
|
||||
switch char {
|
||||
case '0' ..= '9': return char - '0', true
|
||||
case 'a' ..= 'f': return char - 'a' + 10, true
|
||||
case 'A' ..= 'F': return char - 'A' + 10, true
|
||||
case: return 0, false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ read :: proc(data: []byte, filename := "<input>", print_error := false, allocato
|
||||
meta_data = make([]Meta, int(capacity))
|
||||
count := 0
|
||||
defer meta_data = meta_data[:count]
|
||||
for m in &meta_data {
|
||||
for &m in meta_data {
|
||||
m.name = read_name(r) or_return
|
||||
|
||||
type := read_value(r, Meta_Value_Type) or_return
|
||||
@@ -116,7 +116,7 @@ read :: proc(data: []byte, filename := "<input>", print_error := false, allocato
|
||||
layer_count := 0
|
||||
layers = make(Layer_Stack, stack_count)
|
||||
defer layers = layers[:layer_count]
|
||||
for layer in &layers {
|
||||
for &layer in layers {
|
||||
layer.name = read_name(r) or_return
|
||||
layer.components = read_value(r, u8) or_return
|
||||
type := read_value(r, Layer_Data_Type) or_return
|
||||
|
||||
@@ -153,7 +153,7 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err:
|
||||
case complex128: r, i = f64(real(z)), f64(imag(z))
|
||||
case: return .Unsupported_Type
|
||||
}
|
||||
|
||||
|
||||
io.write_byte(w, '[') or_return
|
||||
io.write_f64(w, r) or_return
|
||||
io.write_string(w, ", ") or_return
|
||||
@@ -165,8 +165,8 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err:
|
||||
|
||||
case runtime.Type_Info_String:
|
||||
switch s in a {
|
||||
case string: io.write_quoted_string(w, s) or_return
|
||||
case cstring: io.write_quoted_string(w, string(s)) or_return
|
||||
case string: io.write_quoted_string(w, s, '"', nil, true) or_return
|
||||
case cstring: io.write_quoted_string(w, string(s), '"', nil, true) or_return
|
||||
}
|
||||
|
||||
case runtime.Type_Info_Boolean:
|
||||
|
||||
@@ -2,6 +2,7 @@ package json
|
||||
|
||||
import "core:mem"
|
||||
import "core:unicode/utf8"
|
||||
import "core:unicode/utf16"
|
||||
import "core:strconv"
|
||||
|
||||
Parser :: struct {
|
||||
@@ -403,11 +404,19 @@ unquote_string :: proc(token: Token, spec: Specification, allocator := context.a
|
||||
}
|
||||
i += 6
|
||||
|
||||
// If this is a surrogate pair, decode as such by taking the next rune too.
|
||||
if r >= utf8.SURROGATE_MIN && r <= utf8.SURROGATE_HIGH_MAX && len(s) > i + 2 && s[i:i+2] == "\\u" {
|
||||
r2 := get_u4_rune(s[i:])
|
||||
if r2 >= utf8.SURROGATE_LOW_MIN && r2 <= utf8.SURROGATE_MAX {
|
||||
i += 6
|
||||
r = utf16.decode_surrogate_pair(r, r2)
|
||||
}
|
||||
}
|
||||
|
||||
buf, buf_width := utf8.encode_rune(r)
|
||||
copy(b[w:], buf[:buf_width])
|
||||
w += buf_width
|
||||
|
||||
|
||||
case '0':
|
||||
if spec != .JSON {
|
||||
b[w] = '\x00'
|
||||
|
||||
@@ -72,7 +72,7 @@ unmarshal_string :: proc(data: string, ptr: ^$T, spec := DEFAULT_SPECIFICATION,
|
||||
@(private)
|
||||
assign_bool :: proc(val: any, b: bool) -> bool {
|
||||
v := reflect.any_core(val)
|
||||
switch dst in &v {
|
||||
switch &dst in v {
|
||||
case bool: dst = bool(b)
|
||||
case b8: dst = b8 (b)
|
||||
case b16: dst = b16 (b)
|
||||
@@ -85,7 +85,7 @@ assign_bool :: proc(val: any, b: bool) -> bool {
|
||||
@(private)
|
||||
assign_int :: proc(val: any, i: $T) -> bool {
|
||||
v := reflect.any_core(val)
|
||||
switch dst in &v {
|
||||
switch &dst in v {
|
||||
case i8: dst = i8 (i)
|
||||
case i16: dst = i16 (i)
|
||||
case i16le: dst = i16le (i)
|
||||
@@ -122,7 +122,7 @@ assign_int :: proc(val: any, i: $T) -> bool {
|
||||
@(private)
|
||||
assign_float :: proc(val: any, f: $T) -> bool {
|
||||
v := reflect.any_core(val)
|
||||
switch dst in &v {
|
||||
switch &dst in v {
|
||||
case f16: dst = f16 (f)
|
||||
case f16le: dst = f16le(f)
|
||||
case f16be: dst = f16be(f)
|
||||
@@ -150,7 +150,7 @@ assign_float :: proc(val: any, f: $T) -> bool {
|
||||
@(private)
|
||||
unmarshal_string_token :: proc(p: ^Parser, val: any, str: string, ti: ^reflect.Type_Info) -> bool {
|
||||
val := val
|
||||
switch dst in &val {
|
||||
switch &dst in val {
|
||||
case string:
|
||||
dst = str
|
||||
return true
|
||||
@@ -215,7 +215,7 @@ unmarshal_value :: proc(p: ^Parser, v: any) -> (err: Unmarshal_Error) {
|
||||
}
|
||||
}
|
||||
|
||||
switch dst in &v {
|
||||
switch &dst in v {
|
||||
// Handle json.Value as an unknown type
|
||||
case Value:
|
||||
dst = parse_value(p) or_return
|
||||
|
||||
@@ -19,43 +19,39 @@ import "core:fmt"
|
||||
*/
|
||||
print :: proc(writer: io.Writer, doc: ^Document) -> (written: int, err: io.Error) {
|
||||
if doc == nil { return }
|
||||
using fmt
|
||||
|
||||
written += wprintf(writer, "[XML Prolog]\n")
|
||||
written += fmt.wprintf(writer, "[XML Prolog]\n")
|
||||
|
||||
for attr in doc.prologue {
|
||||
written += wprintf(writer, "\t%v: %v\n", attr.key, attr.val)
|
||||
written += fmt.wprintf(writer, "\t%v: %v\n", attr.key, attr.val)
|
||||
}
|
||||
|
||||
written += wprintf(writer, "[Encoding] %v\n", doc.encoding)
|
||||
written += fmt.wprintf(writer, "[Encoding] %v\n", doc.encoding)
|
||||
|
||||
if len(doc.doctype.ident) > 0 {
|
||||
written += wprintf(writer, "[DOCTYPE] %v\n", doc.doctype.ident)
|
||||
written += fmt.wprintf(writer, "[DOCTYPE] %v\n", doc.doctype.ident)
|
||||
|
||||
if len(doc.doctype.rest) > 0 {
|
||||
wprintf(writer, "\t%v\n", doc.doctype.rest)
|
||||
fmt.wprintf(writer, "\t%v\n", doc.doctype.rest)
|
||||
}
|
||||
}
|
||||
|
||||
for comment in doc.comments {
|
||||
written += wprintf(writer, "[Pre-root comment] %v\n", comment)
|
||||
written += fmt.wprintf(writer, "[Pre-root comment] %v\n", comment)
|
||||
}
|
||||
|
||||
if len(doc.elements) > 0 {
|
||||
wprintln(writer, " --- ")
|
||||
fmt.wprintln(writer, " --- ")
|
||||
print_element(writer, doc, 0)
|
||||
wprintln(writer, " --- ")
|
||||
fmt.wprintln(writer, " --- ")
|
||||
}
|
||||
|
||||
return written, .None
|
||||
}
|
||||
|
||||
print_element :: proc(writer: io.Writer, doc: ^Document, element_id: Element_ID, indent := 0) -> (written: int, err: io.Error) {
|
||||
using fmt
|
||||
|
||||
tab :: proc(writer: io.Writer, indent: int) {
|
||||
for _ in 0..=indent {
|
||||
wprintf(writer, "\t")
|
||||
fmt.wprintf(writer, "\t")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,22 +60,24 @@ print_element :: proc(writer: io.Writer, doc: ^Document, element_id: Element_ID,
|
||||
element := doc.elements[element_id]
|
||||
|
||||
if element.kind == .Element {
|
||||
wprintf(writer, "<%v>\n", element.ident)
|
||||
if len(element.value) > 0 {
|
||||
tab(writer, indent + 1)
|
||||
wprintf(writer, "[Value] %v\n", element.value)
|
||||
fmt.wprintf(writer, "<%v>\n", element.ident)
|
||||
|
||||
for value in element.value {
|
||||
switch v in value {
|
||||
case string:
|
||||
tab(writer, indent + 1)
|
||||
fmt.wprintf(writer, "[Value] %v\n", v)
|
||||
case Element_ID:
|
||||
print_element(writer, doc, v, indent + 1)
|
||||
}
|
||||
}
|
||||
|
||||
for attr in element.attribs {
|
||||
tab(writer, indent + 1)
|
||||
wprintf(writer, "[Attr] %v: %v\n", attr.key, attr.val)
|
||||
}
|
||||
|
||||
for child in element.children {
|
||||
print_element(writer, doc, child, indent + 1)
|
||||
fmt.wprintf(writer, "[Attr] %v: %v\n", attr.key, attr.val)
|
||||
}
|
||||
} else if element.kind == .Comment {
|
||||
wprintf(writer, "[COMMENT] %v\n", element.value)
|
||||
fmt.wprintf(writer, "[COMMENT] %v\n", element.value)
|
||||
}
|
||||
|
||||
return written, .None
|
||||
|
||||
@@ -72,10 +72,10 @@ example :: proc() {
|
||||
return
|
||||
}
|
||||
|
||||
printf("Found `<charlist>` with %v children, %v elements total\n", len(docs[0].elements[charlist].children), docs[0].element_count)
|
||||
printf("Found `<charlist>` with %v children, %v elements total\n", len(docs[0].elements[charlist].value), docs[0].element_count)
|
||||
|
||||
crc32 := doc_hash(docs[0])
|
||||
printf("[%v] CRC32: 0x%08x\n", "🎉" if crc32 == 0xcaa042b9 else "🤬", crc32)
|
||||
crc32 := doc_hash(docs[0], false)
|
||||
printf("[%v] CRC32: 0x%08x\n", "🎉" if crc32 == 0x420dbac5 else "🤬", crc32)
|
||||
|
||||
for round in 0..<N {
|
||||
defer xml.destroy(docs[round])
|
||||
|
||||
@@ -13,20 +13,25 @@ find_child_by_ident :: proc(doc: ^Document, parent_id: Element_ID, ident: string
|
||||
tag := doc.elements[parent_id]
|
||||
|
||||
count := 0
|
||||
for child_id in tag.children {
|
||||
child := doc.elements[child_id]
|
||||
/*
|
||||
Skip commments. They have no name.
|
||||
*/
|
||||
if child.kind != .Element { continue }
|
||||
for v in tag.value {
|
||||
switch child_id in v {
|
||||
case string: continue
|
||||
case Element_ID:
|
||||
child := doc.elements[child_id]
|
||||
/*
|
||||
Skip commments. They have no name.
|
||||
*/
|
||||
if child.kind != .Element { continue }
|
||||
|
||||
/*
|
||||
If the ident matches and it's the nth such child, return it.
|
||||
*/
|
||||
if child.ident == ident {
|
||||
if count == nth { return child_id, true }
|
||||
count += 1
|
||||
/*
|
||||
If the ident matches and it's the nth such child, return it.
|
||||
*/
|
||||
if child.ident == ident {
|
||||
if count == nth { return child_id, true }
|
||||
count += 1
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return 0, false
|
||||
}
|
||||
|
||||
@@ -125,38 +125,38 @@ error :: proc(t: ^Tokenizer, offset: int, msg: string, args: ..any) {
|
||||
}
|
||||
|
||||
@(optimization_mode="speed")
|
||||
advance_rune :: proc(using t: ^Tokenizer) {
|
||||
advance_rune :: proc(t: ^Tokenizer) {
|
||||
#no_bounds_check {
|
||||
/*
|
||||
Already bounds-checked here.
|
||||
*/
|
||||
if read_offset < len(src) {
|
||||
offset = read_offset
|
||||
if ch == '\n' {
|
||||
line_offset = offset
|
||||
line_count += 1
|
||||
if t.read_offset < len(t.src) {
|
||||
t.offset = t.read_offset
|
||||
if t.ch == '\n' {
|
||||
t.line_offset = t.offset
|
||||
t.line_count += 1
|
||||
}
|
||||
r, w := rune(src[read_offset]), 1
|
||||
r, w := rune(t.src[t.read_offset]), 1
|
||||
switch {
|
||||
case r == 0:
|
||||
error(t, t.offset, "illegal character NUL")
|
||||
case r >= utf8.RUNE_SELF:
|
||||
r, w = #force_inline utf8.decode_rune_in_string(src[read_offset:])
|
||||
r, w = #force_inline utf8.decode_rune_in_string(t.src[t.read_offset:])
|
||||
if r == utf8.RUNE_ERROR && w == 1 {
|
||||
error(t, t.offset, "illegal UTF-8 encoding")
|
||||
} else if r == utf8.RUNE_BOM && offset > 0 {
|
||||
} else if r == utf8.RUNE_BOM && t.offset > 0 {
|
||||
error(t, t.offset, "illegal byte order mark")
|
||||
}
|
||||
}
|
||||
read_offset += w
|
||||
ch = r
|
||||
t.read_offset += w
|
||||
t.ch = r
|
||||
} else {
|
||||
offset = len(src)
|
||||
if ch == '\n' {
|
||||
line_offset = offset
|
||||
line_count += 1
|
||||
t.offset = len(t.src)
|
||||
if t.ch == '\n' {
|
||||
t.line_offset = t.offset
|
||||
t.line_count += 1
|
||||
}
|
||||
ch = -1
|
||||
t.ch = -1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,16 +125,19 @@ Document :: struct {
|
||||
|
||||
Element :: struct {
|
||||
ident: string,
|
||||
value: string,
|
||||
value: [dynamic]Value,
|
||||
attribs: Attributes,
|
||||
|
||||
kind: enum {
|
||||
Element = 0,
|
||||
Comment,
|
||||
},
|
||||
|
||||
parent: Element_ID,
|
||||
children: [dynamic]Element_ID,
|
||||
}
|
||||
|
||||
Value :: union {
|
||||
string,
|
||||
Element_ID,
|
||||
}
|
||||
|
||||
Attribute :: struct {
|
||||
@@ -247,9 +250,6 @@ parse_bytes :: proc(data: []u8, options := DEFAULT_OPTIONS, path := "", error_ha
|
||||
|
||||
err = .Unexpected_Token
|
||||
element, parent: Element_ID
|
||||
|
||||
tag_is_open := false
|
||||
first_element := true
|
||||
open: Token
|
||||
|
||||
/*
|
||||
@@ -275,16 +275,10 @@ parse_bytes :: proc(data: []u8, options := DEFAULT_OPTIONS, path := "", error_ha
|
||||
e.g. <odin - Start of new element.
|
||||
*/
|
||||
element = new_element(doc)
|
||||
tag_is_open = true
|
||||
|
||||
if first_element {
|
||||
/*
|
||||
First element.
|
||||
*/
|
||||
parent = element
|
||||
first_element = false
|
||||
if element == 0 { // First Element
|
||||
parent = element
|
||||
} else {
|
||||
append(&doc.elements[parent].children, element)
|
||||
append(&doc.elements[parent].value, element)
|
||||
}
|
||||
|
||||
doc.elements[element].parent = parent
|
||||
@@ -324,7 +318,6 @@ parse_bytes :: proc(data: []u8, options := DEFAULT_OPTIONS, path := "", error_ha
|
||||
expect(t, .Gt) or_return
|
||||
parent = doc.elements[element].parent
|
||||
element = parent
|
||||
tag_is_open = false
|
||||
|
||||
case:
|
||||
error(t, t.offset, "Expected close tag, got: %#v\n", end_token)
|
||||
@@ -344,7 +337,6 @@ parse_bytes :: proc(data: []u8, options := DEFAULT_OPTIONS, path := "", error_ha
|
||||
}
|
||||
parent = doc.elements[element].parent
|
||||
element = parent
|
||||
tag_is_open = false
|
||||
|
||||
} else if open.kind == .Exclaim {
|
||||
/*
|
||||
@@ -392,8 +384,8 @@ parse_bytes :: proc(data: []u8, options := DEFAULT_OPTIONS, path := "", error_ha
|
||||
el := new_element(doc)
|
||||
doc.elements[el].parent = element
|
||||
doc.elements[el].kind = .Comment
|
||||
doc.elements[el].value = comment
|
||||
append(&doc.elements[element].children, el)
|
||||
append(&doc.elements[el].value, comment)
|
||||
append(&doc.elements[element].value, el)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -436,9 +428,6 @@ parse_bytes :: proc(data: []u8, options := DEFAULT_OPTIONS, path := "", error_ha
|
||||
/*
|
||||
End of file.
|
||||
*/
|
||||
if tag_is_open {
|
||||
return doc, .Premature_EOF
|
||||
}
|
||||
break loop
|
||||
|
||||
case:
|
||||
@@ -450,7 +439,7 @@ parse_bytes :: proc(data: []u8, options := DEFAULT_OPTIONS, path := "", error_ha
|
||||
needs_processing |= .Decode_SGML_Entities in opts.flags
|
||||
|
||||
if !needs_processing {
|
||||
doc.elements[element].value = body_text
|
||||
append(&doc.elements[element].value, body_text)
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -472,10 +461,10 @@ parse_bytes :: proc(data: []u8, options := DEFAULT_OPTIONS, path := "", error_ha
|
||||
|
||||
decoded, decode_err := entity.decode_xml(body_text, decode_opts)
|
||||
if decode_err == .None {
|
||||
doc.elements[element].value = decoded
|
||||
append(&doc.elements[element].value, decoded)
|
||||
append(&doc.strings_to_free, decoded)
|
||||
} else {
|
||||
doc.elements[element].value = body_text
|
||||
append(&doc.elements[element].value, body_text)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -518,7 +507,7 @@ destroy :: proc(doc: ^Document) {
|
||||
|
||||
for el in doc.elements {
|
||||
delete(el.attribs)
|
||||
delete(el.children)
|
||||
delete(el.value)
|
||||
}
|
||||
delete(doc.elements)
|
||||
|
||||
@@ -710,6 +699,5 @@ new_element :: proc(doc: ^Document) -> (id: Element_ID) {
|
||||
|
||||
cur := doc.element_count
|
||||
doc.element_count += 1
|
||||
|
||||
return cur
|
||||
}
|
||||
+45
-37
@@ -123,7 +123,7 @@ register_user_formatter :: proc(id: typeid, formatter: User_Formatter) -> Regist
|
||||
aprint :: proc(args: ..any, sep := " ") -> string {
|
||||
str: strings.Builder
|
||||
strings.builder_init(&str)
|
||||
sbprint(buf=&str, args=args, sep=sep)
|
||||
sbprint(&str, ..args, sep=sep)
|
||||
return strings.to_string(str)
|
||||
}
|
||||
// Creates a formatted string with a newline character at the end
|
||||
@@ -139,7 +139,7 @@ aprint :: proc(args: ..any, sep := " ") -> string {
|
||||
aprintln :: proc(args: ..any, sep := " ") -> string {
|
||||
str: strings.Builder
|
||||
strings.builder_init(&str)
|
||||
sbprintln(buf=&str, args=args, sep=sep)
|
||||
sbprintln(&str, ..args, sep=sep)
|
||||
return strings.to_string(str)
|
||||
}
|
||||
// Creates a formatted string using a format string and arguments
|
||||
@@ -171,7 +171,7 @@ aprintf :: proc(fmt: string, args: ..any) -> string {
|
||||
tprint :: proc(args: ..any, sep := " ") -> string {
|
||||
str: strings.Builder
|
||||
strings.builder_init(&str, context.temp_allocator)
|
||||
sbprint(buf=&str, args=args, sep=sep)
|
||||
sbprint(&str, ..args, sep=sep)
|
||||
return strings.to_string(str)
|
||||
}
|
||||
// Creates a formatted string with a newline character at the end
|
||||
@@ -187,7 +187,7 @@ tprint :: proc(args: ..any, sep := " ") -> string {
|
||||
tprintln :: proc(args: ..any, sep := " ") -> string {
|
||||
str: strings.Builder
|
||||
strings.builder_init(&str, context.temp_allocator)
|
||||
sbprintln(buf=&str, args=args, sep=sep)
|
||||
sbprintln(&str, ..args, sep=sep)
|
||||
return strings.to_string(str)
|
||||
}
|
||||
// Creates a formatted string using a format string and arguments
|
||||
@@ -217,7 +217,7 @@ tprintf :: proc(fmt: string, args: ..any) -> string {
|
||||
//
|
||||
bprint :: proc(buf: []byte, args: ..any, sep := " ") -> string {
|
||||
sb := strings.builder_from_bytes(buf[0:len(buf)])
|
||||
return sbprint(buf=&sb, args=args, sep=sep)
|
||||
return sbprint(&sb, ..args, sep=sep)
|
||||
}
|
||||
// Creates a formatted string using a supplied buffer as the backing array, appends newline. Writes into the buffer.
|
||||
//
|
||||
@@ -230,7 +230,7 @@ bprint :: proc(buf: []byte, args: ..any, sep := " ") -> string {
|
||||
//
|
||||
bprintln :: proc(buf: []byte, args: ..any, sep := " ") -> string {
|
||||
sb := strings.builder_from_bytes(buf[0:len(buf)])
|
||||
return sbprintln(buf=&sb, args=args, sep=sep)
|
||||
return sbprintln(&sb, ..args, sep=sep)
|
||||
}
|
||||
// Creates a formatted string using a supplied buffer as the backing array. Writes into the buffer.
|
||||
//
|
||||
@@ -327,7 +327,7 @@ ctprintf :: proc(format: string, args: ..any) -> cstring {
|
||||
// Returns: A formatted string
|
||||
//
|
||||
sbprint :: proc(buf: ^strings.Builder, args: ..any, sep := " ") -> string {
|
||||
wprint(w=strings.to_writer(buf), args=args, sep=sep)
|
||||
wprint(strings.to_writer(buf), ..args, sep=sep)
|
||||
return strings.to_string(buf^)
|
||||
}
|
||||
// Formats and writes to a strings.Builder buffer using the default print settings
|
||||
@@ -340,7 +340,7 @@ sbprint :: proc(buf: ^strings.Builder, args: ..any, sep := " ") -> string {
|
||||
// Returns: The resulting formatted string
|
||||
//
|
||||
sbprintln :: proc(buf: ^strings.Builder, args: ..any, sep := " ") -> string {
|
||||
wprintln(w=strings.to_writer(buf), args=args, sep=sep)
|
||||
wprintln(strings.to_writer(buf), ..args, sep=sep)
|
||||
return strings.to_string(buf^)
|
||||
}
|
||||
// Formats and writes to a strings.Builder buffer according to the specified format string
|
||||
@@ -353,7 +353,7 @@ sbprintln :: proc(buf: ^strings.Builder, args: ..any, sep := " ") -> string {
|
||||
// Returns: The resulting formatted string
|
||||
//
|
||||
sbprintf :: proc(buf: ^strings.Builder, fmt: string, args: ..any) -> string {
|
||||
wprintf(w=strings.to_writer(buf), fmt=fmt, args=args)
|
||||
wprintf(strings.to_writer(buf), fmt, ..args)
|
||||
return strings.to_string(buf^)
|
||||
}
|
||||
// Formats and writes to an io.Writer using the default print settings
|
||||
@@ -835,22 +835,22 @@ int_from_arg :: proc(args: []any, arg_index: int) -> (int, int, bool) {
|
||||
// - fi: A pointer to an Info structure
|
||||
// - verb: The invalid format verb
|
||||
//
|
||||
fmt_bad_verb :: proc(using fi: ^Info, verb: rune) {
|
||||
fmt_bad_verb :: proc(fi: ^Info, verb: rune) {
|
||||
prev_in_bad := fi.in_bad
|
||||
defer fi.in_bad = prev_in_bad
|
||||
fi.in_bad = true
|
||||
|
||||
io.write_string(writer, "%!", &fi.n)
|
||||
io.write_rune(writer, verb, &fi.n)
|
||||
io.write_byte(writer, '(', &fi.n)
|
||||
if arg.id != nil {
|
||||
reflect.write_typeid(writer, arg.id, &fi.n)
|
||||
io.write_byte(writer, '=', &fi.n)
|
||||
fmt_value(fi, arg, 'v')
|
||||
io.write_string(fi.writer, "%!", &fi.n)
|
||||
io.write_rune(fi.writer, verb, &fi.n)
|
||||
io.write_byte(fi.writer, '(', &fi.n)
|
||||
if fi.arg.id != nil {
|
||||
reflect.write_typeid(fi.writer, fi.arg.id, &fi.n)
|
||||
io.write_byte(fi.writer, '=', &fi.n)
|
||||
fmt_value(fi, fi.arg, 'v')
|
||||
} else {
|
||||
io.write_string(writer, "<nil>", &fi.n)
|
||||
io.write_string(fi.writer, "<nil>", &fi.n)
|
||||
}
|
||||
io.write_byte(writer, ')', &fi.n)
|
||||
io.write_byte(fi.writer, ')', &fi.n)
|
||||
}
|
||||
// Formats a boolean value according to the specified format verb
|
||||
//
|
||||
@@ -859,7 +859,7 @@ fmt_bad_verb :: proc(using fi: ^Info, verb: rune) {
|
||||
// - b: The boolean value to format
|
||||
// - verb: The format verb
|
||||
//
|
||||
fmt_bool :: proc(using fi: ^Info, b: bool, verb: rune) {
|
||||
fmt_bool :: proc(fi: ^Info, b: bool, verb: rune) {
|
||||
switch verb {
|
||||
case 't', 'v':
|
||||
fmt_string(fi, b ? "true" : "false", 's')
|
||||
@@ -1142,6 +1142,11 @@ _pad :: proc(fi: ^Info, s: string) {
|
||||
if fi.minus { // right pad
|
||||
io.write_string(fi.writer, s, &fi.n)
|
||||
fmt_write_padding(fi, width)
|
||||
} else if !fi.space && s != "" && s[0] == '-' {
|
||||
// left pad accounting for zero pad of negative number
|
||||
io.write_byte(fi.writer, '-', &fi.n)
|
||||
fmt_write_padding(fi, width)
|
||||
io.write_string(fi.writer, s[1:], &fi.n)
|
||||
} else { // left pad
|
||||
fmt_write_padding(fi, width)
|
||||
io.write_string(fi.writer, s, &fi.n)
|
||||
@@ -1961,11 +1966,22 @@ fmt_named :: proc(fi: ^Info, v: any, verb: rune, info: runtime.Type_Info_Named)
|
||||
switch a in v {
|
||||
case runtime.Source_Code_Location:
|
||||
io.write_string(fi.writer, a.file_path, &fi.n)
|
||||
io.write_byte(fi.writer, '(', &fi.n)
|
||||
io.write_int(fi.writer, int(a.line), 10, &fi.n)
|
||||
io.write_byte(fi.writer, ':', &fi.n)
|
||||
io.write_int(fi.writer, int(a.column), 10, &fi.n)
|
||||
io.write_byte(fi.writer, ')', &fi.n)
|
||||
|
||||
when ODIN_ERROR_POS_STYLE == .Default {
|
||||
io.write_byte(fi.writer, '(', &fi.n)
|
||||
io.write_int(fi.writer, int(a.line), 10, &fi.n)
|
||||
io.write_byte(fi.writer, ':', &fi.n)
|
||||
io.write_int(fi.writer, int(a.column), 10, &fi.n)
|
||||
io.write_byte(fi.writer, ')', &fi.n)
|
||||
} else when ODIN_ERROR_POS_STYLE == .Unix {
|
||||
io.write_byte(fi.writer, ':', &fi.n)
|
||||
io.write_int(fi.writer, int(a.line), 10, &fi.n)
|
||||
io.write_byte(fi.writer, ':', &fi.n)
|
||||
io.write_int(fi.writer, int(a.column), 10, &fi.n)
|
||||
io.write_byte(fi.writer, ':', &fi.n)
|
||||
} else {
|
||||
#panic("Unhandled ODIN_ERROR_POS_STYLE")
|
||||
}
|
||||
return
|
||||
|
||||
case time.Duration:
|
||||
@@ -2647,18 +2663,10 @@ fmt_arg :: proc(fi: ^Info, arg: any, verb: rune) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
custom_types: switch a in arg {
|
||||
case runtime.Source_Code_Location:
|
||||
if fi.hash && verb == 'v' {
|
||||
io.write_string(fi.writer, a.file_path, &fi.n)
|
||||
io.write_byte(fi.writer, '(', &fi.n)
|
||||
io.write_i64(fi.writer, i64(a.line), 10, &fi.n)
|
||||
io.write_byte(fi.writer, ':', &fi.n)
|
||||
io.write_i64(fi.writer, i64(a.column), 10, &fi.n)
|
||||
io.write_byte(fi.writer, ')', &fi.n)
|
||||
return
|
||||
}
|
||||
arg_info := type_info_of(arg.id)
|
||||
if info, ok := arg_info.variant.(runtime.Type_Info_Named); ok {
|
||||
fmt_named(fi, arg, verb, info)
|
||||
return
|
||||
}
|
||||
|
||||
base_arg := arg
|
||||
|
||||
+11
-14
@@ -7,31 +7,28 @@ foreign import "odin_env"
|
||||
|
||||
@(private="file")
|
||||
foreign odin_env {
|
||||
write :: proc "c" (fd: u32, p: []byte) ---
|
||||
write :: proc "contextless" (fd: u32, p: []byte) ---
|
||||
}
|
||||
|
||||
@(private="file")
|
||||
write_vtable := io.Stream_VTable{
|
||||
impl_write = proc(s: io.Stream, p: []byte) -> (n: int, err: io.Error) {
|
||||
fd := u32(uintptr(s.stream_data))
|
||||
write_stream_proc :: proc(stream_data: rawptr, mode: io.Stream_Mode, p: []byte, offset: i64, whence: io.Seek_From) -> (n: i64, err: io.Error) {
|
||||
if mode == .Write {
|
||||
fd := u32(uintptr(stream_data))
|
||||
write(fd, p)
|
||||
return len(p), nil
|
||||
},
|
||||
return i64(len(p)), nil
|
||||
}
|
||||
return 0, .Empty
|
||||
}
|
||||
|
||||
@(private="file")
|
||||
stdout := io.Writer{
|
||||
stream = {
|
||||
stream_vtable = &write_vtable,
|
||||
stream_data = rawptr(uintptr(1)),
|
||||
},
|
||||
procedure = write_stream_proc,
|
||||
data = rawptr(uintptr(1)),
|
||||
}
|
||||
@(private="file")
|
||||
stderr := io.Writer{
|
||||
stream = {
|
||||
stream_vtable = &write_vtable,
|
||||
stream_data = rawptr(uintptr(2)),
|
||||
},
|
||||
procedure = write_stream_proc,
|
||||
data = rawptr(uintptr(2)),
|
||||
}
|
||||
|
||||
// print formats using the default print settings and writes to stdout
|
||||
|
||||
+11
-11
@@ -12,9 +12,9 @@ fprint :: proc(fd: os.Handle, args: ..any, sep := " ") -> int {
|
||||
b: bufio.Writer
|
||||
defer bufio.writer_flush(&b)
|
||||
|
||||
bufio.writer_init_with_buf(&b, {os.stream_from_handle(fd)}, buf[:])
|
||||
bufio.writer_init_with_buf(&b, os.stream_from_handle(fd), buf[:])
|
||||
w := bufio.writer_to_writer(&b)
|
||||
return wprint(w=w, args=args, sep=sep)
|
||||
return wprint(w, ..args, sep=sep)
|
||||
}
|
||||
|
||||
// fprintln formats using the default print settings and writes to fd
|
||||
@@ -23,10 +23,10 @@ fprintln :: proc(fd: os.Handle, args: ..any, sep := " ") -> int {
|
||||
b: bufio.Writer
|
||||
defer bufio.writer_flush(&b)
|
||||
|
||||
bufio.writer_init_with_buf(&b, {os.stream_from_handle(fd)}, buf[:])
|
||||
bufio.writer_init_with_buf(&b, os.stream_from_handle(fd), buf[:])
|
||||
|
||||
w := bufio.writer_to_writer(&b)
|
||||
return wprintln(w=w, args=args, sep=sep)
|
||||
return wprintln(w, ..args, sep=sep)
|
||||
}
|
||||
// fprintf formats according to the specified format string and writes to fd
|
||||
fprintf :: proc(fd: os.Handle, fmt: string, args: ..any) -> int {
|
||||
@@ -34,7 +34,7 @@ fprintf :: proc(fd: os.Handle, fmt: string, args: ..any) -> int {
|
||||
b: bufio.Writer
|
||||
defer bufio.writer_flush(&b)
|
||||
|
||||
bufio.writer_init_with_buf(&b, {os.stream_from_handle(fd)}, buf[:])
|
||||
bufio.writer_init_with_buf(&b, os.stream_from_handle(fd), buf[:])
|
||||
|
||||
w := bufio.writer_to_writer(&b)
|
||||
return wprintf(w, fmt, ..args)
|
||||
@@ -44,7 +44,7 @@ fprint_type :: proc(fd: os.Handle, info: ^runtime.Type_Info) -> (n: int, err: io
|
||||
b: bufio.Writer
|
||||
defer bufio.writer_flush(&b)
|
||||
|
||||
bufio.writer_init_with_buf(&b, {os.stream_from_handle(fd)}, buf[:])
|
||||
bufio.writer_init_with_buf(&b, os.stream_from_handle(fd), buf[:])
|
||||
|
||||
w := bufio.writer_to_writer(&b)
|
||||
return wprint_type(w, info)
|
||||
@@ -54,22 +54,22 @@ fprint_typeid :: proc(fd: os.Handle, id: typeid) -> (n: int, err: io.Error) {
|
||||
b: bufio.Writer
|
||||
defer bufio.writer_flush(&b)
|
||||
|
||||
bufio.writer_init_with_buf(&b, {os.stream_from_handle(fd)}, buf[:])
|
||||
bufio.writer_init_with_buf(&b, os.stream_from_handle(fd), buf[:])
|
||||
|
||||
w := bufio.writer_to_writer(&b)
|
||||
return wprint_typeid(w, id)
|
||||
}
|
||||
|
||||
// print formats using the default print settings and writes to os.stdout
|
||||
print :: proc(args: ..any, sep := " ") -> int { return fprint(fd=os.stdout, args=args, sep=sep) }
|
||||
print :: proc(args: ..any, sep := " ") -> int { return fprint(os.stdout, ..args, sep=sep) }
|
||||
// println formats using the default print settings and writes to os.stdout
|
||||
println :: proc(args: ..any, sep := " ") -> int { return fprintln(fd=os.stdout, args=args, sep=sep) }
|
||||
println :: proc(args: ..any, sep := " ") -> int { return fprintln(os.stdout, ..args, sep=sep) }
|
||||
// printf formats according to the specified format string and writes to os.stdout
|
||||
printf :: proc(fmt: string, args: ..any) -> int { return fprintf(os.stdout, fmt, ..args) }
|
||||
|
||||
// eprint formats using the default print settings and writes to os.stderr
|
||||
eprint :: proc(args: ..any, sep := " ") -> int { return fprint(fd=os.stderr, args=args, sep=sep) }
|
||||
eprint :: proc(args: ..any, sep := " ") -> int { return fprint(os.stderr, ..args, sep=sep) }
|
||||
// eprintln formats using the default print settings and writes to os.stderr
|
||||
eprintln :: proc(args: ..any, sep := " ") -> int { return fprintln(fd=os.stderr, args=args, sep=sep) }
|
||||
eprintln :: proc(args: ..any, sep := " ") -> int { return fprintln(os.stderr, ..args, sep=sep) }
|
||||
// eprintf formats according to the specified format string and writes to os.stderr
|
||||
eprintf :: proc(fmt: string, args: ..any) -> int { return fprintf(os.stderr, fmt, ..args) }
|
||||
|
||||
@@ -634,7 +634,7 @@ alpha_add_if_missing :: proc(img: ^Image, alpha_key := Alpha_Key{}, allocator :=
|
||||
buf := bytes.Buffer{}
|
||||
|
||||
// Can we allocate the return buffer?
|
||||
if !resize(&buf.buf, bytes_wanted) {
|
||||
if resize(&buf.buf, bytes_wanted) != nil {
|
||||
delete(buf.buf)
|
||||
return false
|
||||
}
|
||||
@@ -826,7 +826,7 @@ alpha_drop_if_present :: proc(img: ^Image, options := Options{}, alpha_key := Al
|
||||
buf := bytes.Buffer{}
|
||||
|
||||
// Can we allocate the return buffer?
|
||||
if !resize(&buf.buf, bytes_wanted) {
|
||||
if resize(&buf.buf, bytes_wanted) != nil {
|
||||
delete(buf.buf)
|
||||
return false
|
||||
}
|
||||
@@ -1075,7 +1075,7 @@ apply_palette_rgb :: proc(img: ^Image, palette: [256]RGB_Pixel, allocator := con
|
||||
// Can we allocate the return buffer?
|
||||
buf := bytes.Buffer{}
|
||||
bytes_wanted := compute_buffer_size(img.width, img.height, 3, 8)
|
||||
if !resize(&buf.buf, bytes_wanted) {
|
||||
if resize(&buf.buf, bytes_wanted) != nil {
|
||||
delete(buf.buf)
|
||||
return false
|
||||
}
|
||||
@@ -1112,7 +1112,7 @@ apply_palette_rgba :: proc(img: ^Image, palette: [256]RGBA_Pixel, allocator := c
|
||||
// Can we allocate the return buffer?
|
||||
buf := bytes.Buffer{}
|
||||
bytes_wanted := compute_buffer_size(img.width, img.height, 4, 8)
|
||||
if !resize(&buf.buf, bytes_wanted) {
|
||||
if resize(&buf.buf, bytes_wanted) != nil {
|
||||
delete(buf.buf)
|
||||
return false
|
||||
}
|
||||
@@ -1147,7 +1147,7 @@ expand_grayscale :: proc(img: ^Image, allocator := context.allocator) -> (ok: bo
|
||||
// Can we allocate the return buffer?
|
||||
buf := bytes.Buffer{}
|
||||
bytes_wanted := compute_buffer_size(img.width, img.height, img.channels + 2, img.depth)
|
||||
if !resize(&buf.buf, bytes_wanted) {
|
||||
if resize(&buf.buf, bytes_wanted) != nil {
|
||||
delete(buf.buf)
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -4,13 +4,14 @@ import "core:bytes"
|
||||
import "core:image"
|
||||
|
||||
destroy :: proc(img: ^image.Image) -> bool {
|
||||
if img == nil do return false
|
||||
if img == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
defer free(img)
|
||||
bytes.buffer_destroy(&img.pixels)
|
||||
|
||||
info, ok := img.metadata.(^image.Netpbm_Info)
|
||||
if !ok do return false
|
||||
info := img.metadata.(^image.Netpbm_Info) or_return
|
||||
|
||||
header_destroy(&info.header)
|
||||
free(info)
|
||||
@@ -19,9 +20,9 @@ destroy :: proc(img: ^image.Image) -> bool {
|
||||
return true
|
||||
}
|
||||
|
||||
header_destroy :: proc(using header: ^Header) {
|
||||
if format == .P7 && tupltype != "" {
|
||||
delete(tupltype)
|
||||
tupltype = ""
|
||||
header_destroy :: proc(header: ^Header) {
|
||||
if header.format == .P7 && header.tupltype != "" {
|
||||
delete(header.tupltype)
|
||||
header.tupltype = ""
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//+vet !using-stmt
|
||||
package netpbm
|
||||
|
||||
import "core:bytes"
|
||||
@@ -161,18 +162,18 @@ save_to_buffer :: proc(img: ^Image, custom_info: Info = {}, allocator := context
|
||||
// convert from native endianness
|
||||
if img.depth == 16 {
|
||||
pixels := mem.slice_data_cast([]u16be, data.buf[len(header_buf):])
|
||||
for p in &pixels {
|
||||
for &p in pixels {
|
||||
p = u16be(transmute(u16) p)
|
||||
}
|
||||
} else if header.format in PFM {
|
||||
if header.little_endian {
|
||||
pixels := mem.slice_data_cast([]f32le, data.buf[len(header_buf):])
|
||||
for p in &pixels {
|
||||
for &p in pixels {
|
||||
p = f32le(transmute(f32) p)
|
||||
}
|
||||
} else {
|
||||
pixels := mem.slice_data_cast([]f32be, data.buf[len(header_buf):])
|
||||
for p in &pixels {
|
||||
for &p in pixels {
|
||||
p = f32be(transmute(f32) p)
|
||||
}
|
||||
}
|
||||
@@ -578,18 +579,18 @@ decode_image :: proc(img: ^Image, header: Header, data: []byte, allocator := con
|
||||
if header.format in PFM {
|
||||
pixels := mem.slice_data_cast([]f32, img.pixels.buf[:])
|
||||
if header.little_endian {
|
||||
for p in &pixels {
|
||||
for &p in pixels {
|
||||
p = f32(transmute(f32le) p)
|
||||
}
|
||||
} else {
|
||||
for p in &pixels {
|
||||
for &p in pixels {
|
||||
p = f32(transmute(f32be) p)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if img.depth == 16 {
|
||||
pixels := mem.slice_data_cast([]u16, img.pixels.buf[:])
|
||||
for p in &pixels {
|
||||
for &p in pixels {
|
||||
p = u16(transmute(u16be) p)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ destroy :: proc(img: ^Image) {
|
||||
bytes.buffer_destroy(&img.pixels)
|
||||
|
||||
if v, ok := img.metadata.(^image.PNG_Info); ok {
|
||||
for chunk in &v.chunks {
|
||||
for chunk in v.chunks {
|
||||
delete(chunk.data)
|
||||
}
|
||||
delete(v.chunks)
|
||||
@@ -80,11 +80,10 @@ time :: proc(c: image.PNG_Chunk) -> (res: tIME, ok: bool) {
|
||||
}
|
||||
|
||||
core_time :: proc(c: image.PNG_Chunk) -> (t: coretime.Time, ok: bool) {
|
||||
if png_time, png_ok := time(c); png_ok {
|
||||
using png_time
|
||||
if t, png_ok := time(c); png_ok {
|
||||
return coretime.datetime_to_time(
|
||||
int(year), int(month), int(day),
|
||||
int(hour), int(minute), int(second),
|
||||
int(t.year), int(t.month), int(t.day),
|
||||
int(t.hour), int(t.minute), int(t.second),
|
||||
)
|
||||
} else {
|
||||
return {}, false
|
||||
@@ -99,7 +98,7 @@ text :: proc(c: image.PNG_Chunk) -> (res: Text, ok: bool) {
|
||||
case .tEXt:
|
||||
ok = true
|
||||
|
||||
fields := bytes.split(s=c.data, sep=[]u8{0}, allocator=context.temp_allocator)
|
||||
fields := bytes.split(c.data, sep=[]u8{0}, allocator=context.temp_allocator)
|
||||
if len(fields) == 2 {
|
||||
res.keyword = strings.clone(string(fields[0]))
|
||||
res.text = strings.clone(string(fields[1]))
|
||||
@@ -110,7 +109,7 @@ text :: proc(c: image.PNG_Chunk) -> (res: Text, ok: bool) {
|
||||
case .zTXt:
|
||||
ok = true
|
||||
|
||||
fields := bytes.split_n(s=c.data, sep=[]u8{0}, n=3, allocator=context.temp_allocator)
|
||||
fields := bytes.split_n(c.data, sep=[]u8{0}, n=3, allocator=context.temp_allocator)
|
||||
if len(fields) != 3 || len(fields[1]) != 0 {
|
||||
// Compression method must be 0=Deflate, which thanks to the split above turns
|
||||
// into an empty slice
|
||||
@@ -199,7 +198,7 @@ text_destroy :: proc(text: Text) {
|
||||
iccp :: proc(c: image.PNG_Chunk) -> (res: iCCP, ok: bool) {
|
||||
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD(ignore = context.temp_allocator == context.allocator)
|
||||
|
||||
fields := bytes.split_n(s=c.data, sep=[]u8{0}, n=3, allocator=context.temp_allocator)
|
||||
fields := bytes.split_n(c.data, sep=[]u8{0}, n=3, allocator=context.temp_allocator)
|
||||
|
||||
if len(fields[0]) < 1 || len(fields[0]) > 79 {
|
||||
// Invalid profile name
|
||||
@@ -263,7 +262,7 @@ splt :: proc(c: image.PNG_Chunk) -> (res: sPLT, ok: bool) {
|
||||
}
|
||||
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD(ignore = context.temp_allocator == context.allocator)
|
||||
|
||||
fields := bytes.split_n(s=c.data, sep=[]u8{0}, n=2, allocator=context.temp_allocator)
|
||||
fields := bytes.split_n(c.data, sep=[]u8{0}, n=2, allocator=context.temp_allocator)
|
||||
if len(fields) != 2 {
|
||||
return
|
||||
}
|
||||
|
||||
+13
-13
@@ -11,6 +11,7 @@
|
||||
// package png implements a PNG image reader
|
||||
//
|
||||
// The PNG specification is at https://www.w3.org/TR/PNG/.
|
||||
//+vet !using-stmt
|
||||
package png
|
||||
|
||||
import "core:compress"
|
||||
@@ -444,15 +445,14 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a
|
||||
img.width = int(header.width)
|
||||
img.height = int(header.height)
|
||||
|
||||
using header
|
||||
h := image.PNG_IHDR{
|
||||
width = width,
|
||||
height = height,
|
||||
bit_depth = bit_depth,
|
||||
color_type = color_type,
|
||||
compression_method = compression_method,
|
||||
filter_method = filter_method,
|
||||
interlace_method = interlace_method,
|
||||
width = header.width,
|
||||
height = header.height,
|
||||
bit_depth = header.bit_depth,
|
||||
color_type = header.color_type,
|
||||
compression_method = header.compression_method,
|
||||
filter_method = header.filter_method,
|
||||
interlace_method = header.interlace_method,
|
||||
}
|
||||
info.header = h
|
||||
|
||||
@@ -731,7 +731,7 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a
|
||||
// We need to create a new image buffer
|
||||
dest_raw_size := compute_buffer_size(int(header.width), int(header.height), out_image_channels, 8)
|
||||
t := bytes.Buffer{}
|
||||
if !resize(&t.buf, dest_raw_size) {
|
||||
if resize(&t.buf, dest_raw_size) != nil {
|
||||
return {}, .Unable_To_Allocate_Or_Resize
|
||||
}
|
||||
|
||||
@@ -812,7 +812,7 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a
|
||||
// We need to create a new image buffer
|
||||
dest_raw_size := compute_buffer_size(int(header.width), int(header.height), out_image_channels, 16)
|
||||
t := bytes.Buffer{}
|
||||
if !resize(&t.buf, dest_raw_size) {
|
||||
if resize(&t.buf, dest_raw_size) != nil {
|
||||
return {}, .Unable_To_Allocate_Or_Resize
|
||||
}
|
||||
|
||||
@@ -1011,7 +1011,7 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a
|
||||
// We need to create a new image buffer
|
||||
dest_raw_size := compute_buffer_size(int(header.width), int(header.height), out_image_channels, 8)
|
||||
t := bytes.Buffer{}
|
||||
if !resize(&t.buf, dest_raw_size) {
|
||||
if resize(&t.buf, dest_raw_size) != nil {
|
||||
return {}, .Unable_To_Allocate_Or_Resize
|
||||
}
|
||||
|
||||
@@ -1522,7 +1522,7 @@ defilter :: proc(img: ^Image, filter_bytes: ^bytes.Buffer, header: ^image.PNG_IH
|
||||
bytes_per_channel := depth == 16 ? 2 : 1
|
||||
|
||||
num_bytes := compute_buffer_size(width, height, channels, depth == 16 ? 16 : 8)
|
||||
if !resize(&img.pixels.buf, num_bytes) {
|
||||
if resize(&img.pixels.buf, num_bytes) != nil {
|
||||
return .Unable_To_Allocate_Or_Resize
|
||||
}
|
||||
|
||||
@@ -1564,7 +1564,7 @@ defilter :: proc(img: ^Image, filter_bytes: ^bytes.Buffer, header: ^image.PNG_IH
|
||||
if x > 0 && y > 0 {
|
||||
temp: bytes.Buffer
|
||||
temp_len := compute_buffer_size(x, y, channels, depth == 16 ? 16 : 8)
|
||||
if !resize(&temp.buf, temp_len) {
|
||||
if resize(&temp.buf, temp_len) != nil {
|
||||
return .Unable_To_Allocate_Or_Resize
|
||||
}
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ save_to_buffer :: proc(output: ^bytes.Buffer, img: ^Image, options := Options{}
|
||||
// Calculate and allocate maximum size. We'll reclaim space to actually written output at the end.
|
||||
max_size := pixels * (img.channels + 1) + size_of(image.QOI_Header) + size_of(u64be)
|
||||
|
||||
if !resize(&output.buf, max_size) {
|
||||
if resize(&output.buf, max_size) != nil {
|
||||
return .Unable_To_Allocate_Or_Resize
|
||||
}
|
||||
|
||||
@@ -233,7 +233,7 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a
|
||||
|
||||
bytes_needed := image.compute_buffer_size(int(header.width), int(header.height), img.channels, 8)
|
||||
|
||||
if !resize(&img.pixels.buf, bytes_needed) {
|
||||
if resize(&img.pixels.buf, bytes_needed) != nil {
|
||||
return img, .Unable_To_Allocate_Or_Resize
|
||||
}
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ save_to_buffer :: proc(output: ^bytes.Buffer, img: ^Image, options := Options{}
|
||||
// Calculate and allocate necessary space.
|
||||
necessary := pixels * img.channels + size_of(image.TGA_Header)
|
||||
|
||||
if !resize(&output.buf, necessary) {
|
||||
if resize(&output.buf, necessary) != nil {
|
||||
return .Unable_To_Allocate_Or_Resize
|
||||
}
|
||||
|
||||
@@ -292,7 +292,7 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a
|
||||
return img, nil
|
||||
}
|
||||
|
||||
if !resize(&img.pixels.buf, dest_channels * img.width * img.height) {
|
||||
if resize(&img.pixels.buf, dest_channels * img.width * img.height) != nil {
|
||||
return img, .Unable_To_Allocate_Or_Resize
|
||||
}
|
||||
|
||||
|
||||
@@ -192,6 +192,7 @@ type_map_info :: proc($T: typeid/map[$K]$V) -> ^runtime.Map_Info ---
|
||||
type_map_cell_info :: proc($T: typeid) -> ^runtime.Map_Cell_Info ---
|
||||
|
||||
type_convert_variants_to_pointers :: proc($T: typeid) -> typeid where type_is_union(T) ---
|
||||
type_merge :: proc($U, $V: typeid) -> typeid where type_is_union(U), type_is_union(V) ---
|
||||
|
||||
constant_utf16_cstring :: proc($literal: string) -> [^]u16 ---
|
||||
|
||||
|
||||
+30
-74
@@ -1,124 +1,80 @@
|
||||
package io
|
||||
|
||||
to_reader :: proc(s: Stream) -> (r: Reader, ok: bool = true) #optional_ok {
|
||||
r.stream = s
|
||||
if s.stream_vtable == nil || s.impl_read == nil {
|
||||
ok = false
|
||||
}
|
||||
r = s
|
||||
ok = .Read in query(s)
|
||||
return
|
||||
}
|
||||
to_writer :: proc(s: Stream) -> (w: Writer, ok: bool = true) #optional_ok {
|
||||
w.stream = s
|
||||
if s.stream_vtable == nil || s.impl_write == nil {
|
||||
ok = false
|
||||
}
|
||||
w = s
|
||||
ok = .Write in query(s)
|
||||
return
|
||||
}
|
||||
|
||||
to_closer :: proc(s: Stream) -> (c: Closer, ok: bool = true) #optional_ok {
|
||||
c.stream = s
|
||||
if s.stream_vtable == nil || s.impl_close == nil {
|
||||
ok = false
|
||||
}
|
||||
c = s
|
||||
ok = .Close in query(s)
|
||||
return
|
||||
}
|
||||
to_flusher :: proc(s: Stream) -> (f: Flusher, ok: bool = true) #optional_ok {
|
||||
f.stream = s
|
||||
if s.stream_vtable == nil || s.impl_flush == nil {
|
||||
ok = false
|
||||
}
|
||||
f = s
|
||||
ok = .Flush in query(s)
|
||||
return
|
||||
}
|
||||
to_seeker :: proc(s: Stream) -> (seeker: Seeker, ok: bool = true) #optional_ok {
|
||||
seeker.stream = s
|
||||
if s.stream_vtable == nil || s.impl_seek == nil {
|
||||
ok = false
|
||||
}
|
||||
seeker = s
|
||||
ok = .Seek in query(s)
|
||||
return
|
||||
}
|
||||
|
||||
to_read_writer :: proc(s: Stream) -> (r: Read_Writer, ok: bool = true) #optional_ok {
|
||||
r.stream = s
|
||||
if s.stream_vtable == nil || s.impl_read == nil || s.impl_write == nil {
|
||||
ok = false
|
||||
}
|
||||
r = s
|
||||
ok = query(s) >= {.Read, .Write}
|
||||
return
|
||||
}
|
||||
to_read_closer :: proc(s: Stream) -> (r: Read_Closer, ok: bool = true) #optional_ok {
|
||||
r.stream = s
|
||||
if s.stream_vtable == nil || s.impl_read == nil || s.impl_close == nil {
|
||||
ok = false
|
||||
}
|
||||
r = s
|
||||
ok = query(s) >= {.Read, .Close}
|
||||
return
|
||||
}
|
||||
to_read_write_closer :: proc(s: Stream) -> (r: Read_Write_Closer, ok: bool = true) #optional_ok {
|
||||
r.stream = s
|
||||
if s.stream_vtable == nil || s.impl_read == nil || s.impl_write == nil || s.impl_close == nil {
|
||||
ok = false
|
||||
}
|
||||
r = s
|
||||
ok = query(s) >= {.Read, .Write, .Close}
|
||||
return
|
||||
}
|
||||
to_read_write_seeker :: proc(s: Stream) -> (r: Read_Write_Seeker, ok: bool = true) #optional_ok {
|
||||
r.stream = s
|
||||
if s.stream_vtable == nil || s.impl_read == nil || s.impl_write == nil || s.impl_seek == nil {
|
||||
ok = false
|
||||
}
|
||||
r = s
|
||||
ok = query(s) >= {.Read, .Write, .Seek}
|
||||
return
|
||||
}
|
||||
to_write_flusher :: proc(s: Stream) -> (w: Write_Flusher, ok: bool = true) #optional_ok {
|
||||
w.stream = s
|
||||
if s.stream_vtable == nil || s.impl_write == nil || s.impl_flush == nil {
|
||||
ok = false
|
||||
}
|
||||
w = s
|
||||
ok = query(s) >= {.Write, .Flush}
|
||||
return
|
||||
}
|
||||
to_write_flush_closer :: proc(s: Stream) -> (w: Write_Flush_Closer, ok: bool = true) #optional_ok {
|
||||
w.stream = s
|
||||
if s.stream_vtable == nil || s.impl_write == nil || s.impl_flush == nil || s.impl_close == nil {
|
||||
ok = false
|
||||
}
|
||||
w = s
|
||||
ok = query(s) >= {.Write, .Flush, .Close}
|
||||
return
|
||||
}
|
||||
|
||||
to_reader_at :: proc(s: Stream) -> (r: Reader_At, ok: bool = true) #optional_ok {
|
||||
r.stream = s
|
||||
if s.stream_vtable == nil || s.impl_read_at == nil {
|
||||
ok = false
|
||||
}
|
||||
r = s
|
||||
ok = query(s) >= {.Read_At}
|
||||
return
|
||||
}
|
||||
to_writer_at :: proc(s: Stream) -> (w: Writer_At, ok: bool = true) #optional_ok {
|
||||
w.stream = s
|
||||
if s.stream_vtable == nil || s.impl_write_at == nil {
|
||||
ok = false
|
||||
}
|
||||
return
|
||||
}
|
||||
to_reader_from :: proc(s: Stream) -> (r: Reader_From, ok: bool = true) #optional_ok {
|
||||
r.stream = s
|
||||
if s.stream_vtable == nil || s.impl_read_from == nil {
|
||||
ok = false
|
||||
}
|
||||
return
|
||||
}
|
||||
to_writer_to :: proc(s: Stream) -> (w: Writer_To, ok: bool = true) #optional_ok {
|
||||
w.stream = s
|
||||
if s.stream_vtable == nil || s.impl_write_to == nil {
|
||||
ok = false
|
||||
}
|
||||
w = s
|
||||
ok = query(s) >= {.Write_At}
|
||||
return
|
||||
}
|
||||
to_write_closer :: proc(s: Stream) -> (w: Write_Closer, ok: bool = true) #optional_ok {
|
||||
w.stream = s
|
||||
if s.stream_vtable == nil || s.impl_write == nil || s.impl_close == nil {
|
||||
ok = false
|
||||
}
|
||||
w = s
|
||||
ok = query(s) >= {.Write, .Close}
|
||||
return
|
||||
}
|
||||
to_write_seeker :: proc(s: Stream) -> (w: Write_Seeker, ok: bool = true) #optional_ok {
|
||||
w.stream = s
|
||||
if s.stream_vtable == nil || s.impl_write == nil || s.impl_seek == nil {
|
||||
ok = false
|
||||
}
|
||||
w = s
|
||||
ok = query(s) >= {.Write, .Seek}
|
||||
return
|
||||
}
|
||||
|
||||
+146
-298
@@ -53,137 +53,106 @@ Error :: enum i32 {
|
||||
Empty = -1,
|
||||
}
|
||||
|
||||
Close_Proc :: proc(using s: Stream) -> Error
|
||||
Flush_Proc :: proc(using s: Stream) -> Error
|
||||
Seek_Proc :: proc(using s: Stream, offset: i64, whence: Seek_From) -> (n: i64, err: Error)
|
||||
Size_Proc :: proc(using s: Stream) -> i64
|
||||
Read_Proc :: proc(using s: Stream, p: []byte) -> (n: int, err: Error)
|
||||
Read_At_Proc :: proc(using s: Stream, p: []byte, off: i64) -> (n: int, err: Error)
|
||||
Read_From_Proc :: proc(using s: Stream, r: Reader) -> (n: i64, err: Error)
|
||||
Read_Byte_Proc :: proc(using s: Stream) -> (byte, Error)
|
||||
Read_Rune_Proc :: proc(using s: Stream) -> (ch: rune, size: int, err: Error)
|
||||
Unread_Byte_Proc :: proc(using s: Stream) -> Error
|
||||
Unread_Rune_Proc :: proc(using s: Stream) -> Error
|
||||
Write_Proc :: proc(using s: Stream, p: []byte) -> (n: int, err: Error)
|
||||
Write_At_Proc :: proc(using s: Stream, p: []byte, off: i64) -> (n: int, err: Error)
|
||||
Write_To_Proc :: proc(using s: Stream, w: Writer) -> (n: i64, err: Error)
|
||||
Write_Byte_Proc :: proc(using s: Stream, c: byte) -> Error
|
||||
Write_Rune_Proc :: proc(using s: Stream, r: rune) -> (size: int, err: Error)
|
||||
Destroy_Proc :: proc(using s: Stream) -> Error
|
||||
Stream_Mode :: enum {
|
||||
Close,
|
||||
Flush,
|
||||
Read,
|
||||
Read_At,
|
||||
Write,
|
||||
Write_At,
|
||||
Seek,
|
||||
Size,
|
||||
Destroy,
|
||||
Query, // query what modes are available
|
||||
}
|
||||
|
||||
Stream_Mode_Set :: distinct bit_set[Stream_Mode; i64]
|
||||
|
||||
Stream_Proc :: #type proc(stream_data: rawptr, mode: Stream_Mode, p: []byte, offset: i64, whence: Seek_From) -> (n: i64, err: Error)
|
||||
|
||||
Stream :: struct {
|
||||
using stream_vtable: ^Stream_VTable,
|
||||
stream_data: rawptr,
|
||||
}
|
||||
Stream_VTable :: struct {
|
||||
impl_close: Close_Proc,
|
||||
impl_flush: Flush_Proc,
|
||||
|
||||
impl_seek: Seek_Proc,
|
||||
impl_size: Size_Proc,
|
||||
|
||||
impl_read: Read_Proc,
|
||||
impl_read_at: Read_At_Proc,
|
||||
impl_read_byte: Read_Byte_Proc,
|
||||
impl_read_rune: Read_Rune_Proc,
|
||||
impl_write_to: Write_To_Proc,
|
||||
|
||||
impl_write: Write_Proc,
|
||||
impl_write_at: Write_At_Proc,
|
||||
impl_write_byte: Write_Byte_Proc,
|
||||
impl_write_rune: Write_Rune_Proc,
|
||||
impl_read_from: Read_From_Proc,
|
||||
|
||||
impl_unread_byte: Unread_Byte_Proc,
|
||||
impl_unread_rune: Unread_Rune_Proc,
|
||||
|
||||
impl_destroy: Destroy_Proc,
|
||||
procedure: Stream_Proc,
|
||||
data: rawptr,
|
||||
}
|
||||
|
||||
Reader :: Stream
|
||||
Writer :: Stream
|
||||
Closer :: Stream
|
||||
Flusher :: Stream
|
||||
Seeker :: Stream
|
||||
|
||||
Reader :: struct {using stream: Stream}
|
||||
Writer :: struct {using stream: Stream}
|
||||
Closer :: struct {using stream: Stream}
|
||||
Flusher :: struct {using stream: Stream}
|
||||
Seeker :: struct {using stream: Stream}
|
||||
Read_Writer :: Stream
|
||||
Read_Closer :: Stream
|
||||
Read_Write_Closer :: Stream
|
||||
Read_Write_Seeker :: Stream
|
||||
|
||||
Read_Writer :: struct {using stream: Stream}
|
||||
Read_Closer :: struct {using stream: Stream}
|
||||
Read_Write_Closer :: struct {using stream: Stream}
|
||||
Read_Write_Seeker :: struct {using stream: Stream}
|
||||
Write_Closer :: Stream
|
||||
Write_Seeker :: Stream
|
||||
Write_Flusher :: Stream
|
||||
Write_Flush_Closer :: Stream
|
||||
|
||||
Write_Closer :: struct {using stream: Stream}
|
||||
Write_Seeker :: struct {using stream: Stream}
|
||||
Write_Flusher :: struct {using stream: Stream}
|
||||
Write_Flush_Closer :: struct {using stream: Stream}
|
||||
|
||||
Reader_At :: struct {using stream: Stream}
|
||||
Writer_At :: struct {using stream: Stream}
|
||||
Reader_From :: struct {using stream: Stream}
|
||||
Writer_To :: struct {using stream: Stream}
|
||||
Reader_At :: Stream
|
||||
Writer_At :: Stream
|
||||
|
||||
|
||||
destroy :: proc(s: Stream) -> Error {
|
||||
close_err := close({s})
|
||||
if s.stream_vtable != nil && s.impl_destroy != nil {
|
||||
return s->impl_destroy()
|
||||
destroy :: proc(s: Stream) -> (err: Error) {
|
||||
_ = flush(s)
|
||||
_ = close(s)
|
||||
if s.procedure != nil {
|
||||
_, err = s.procedure(s.data, .Destroy, nil, 0, nil)
|
||||
} else {
|
||||
err = .Empty
|
||||
}
|
||||
if close_err != .None {
|
||||
return close_err
|
||||
}
|
||||
return .Empty
|
||||
return
|
||||
}
|
||||
|
||||
query :: proc(s: Stream) -> (set: Stream_Mode_Set) {
|
||||
if s.procedure != nil {
|
||||
n, _ := s.procedure(s.data, .Query, nil, 0, nil)
|
||||
set = transmute(Stream_Mode_Set)n
|
||||
if set != nil {
|
||||
set += {.Query}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
query_utility :: #force_inline proc "contextless" (set: Stream_Mode_Set) -> (n: i64, err: Error) {
|
||||
return transmute(i64)set, nil
|
||||
}
|
||||
|
||||
_i64_err :: #force_inline proc "contextless" (n: int, err: Error) -> (i64, Error) {
|
||||
return i64(n), err
|
||||
}
|
||||
|
||||
|
||||
// read reads up to len(p) bytes into s. It returns the number of bytes read and any error if occurred.
|
||||
//
|
||||
// When read encounters an .EOF or error after successfully reading n > 0 bytes, it returns the number of
|
||||
// bytes read along with the error.
|
||||
read :: proc(s: Reader, p: []byte, n_read: ^int = nil) -> (n: int, err: Error) {
|
||||
if s.stream_vtable != nil {
|
||||
if s.impl_read != nil {
|
||||
n, err = s->impl_read(p)
|
||||
if n_read != nil {
|
||||
n_read^ += n
|
||||
}
|
||||
return
|
||||
} else if s.impl_read_byte != nil {
|
||||
bytes_read := 0
|
||||
defer if n_read != nil {
|
||||
n_read^ += bytes_read
|
||||
}
|
||||
for _, i in p {
|
||||
p[i] = s->impl_read_byte() or_return
|
||||
bytes_read += 1
|
||||
}
|
||||
return
|
||||
}
|
||||
if s.procedure != nil {
|
||||
n64: i64
|
||||
n64, err = s.procedure(s.data, .Read, p, 0, nil)
|
||||
n = int(n64)
|
||||
if n_read != nil { n_read^ += n }
|
||||
} else {
|
||||
err = .Empty
|
||||
}
|
||||
return 0, .Empty
|
||||
return
|
||||
}
|
||||
|
||||
// write writes up to len(p) bytes into s. It returns the number of bytes written and any error if occurred.
|
||||
write :: proc(s: Writer, p: []byte, n_written: ^int = nil) -> (n: int, err: Error) {
|
||||
if s.stream_vtable != nil {
|
||||
if s.impl_write != nil {
|
||||
n, err = s->impl_write(p)
|
||||
if n_written != nil {
|
||||
n_written^ += n
|
||||
}
|
||||
return
|
||||
} else if s.impl_write_byte != nil {
|
||||
bytes_written := 0
|
||||
defer if n_written != nil {
|
||||
n_written^ += bytes_written
|
||||
}
|
||||
for c in p {
|
||||
s->impl_write_byte(c) or_return
|
||||
bytes_written += 1
|
||||
}
|
||||
return
|
||||
}
|
||||
if s.procedure != nil {
|
||||
n64: i64
|
||||
n64, err = s.procedure(s.data, .Write, p, 0, nil)
|
||||
n = int(n64)
|
||||
if n_written != nil { n_written^ += n }
|
||||
} else {
|
||||
err = .Empty
|
||||
}
|
||||
return 0, .Empty
|
||||
return
|
||||
}
|
||||
|
||||
// seek sets the offset of the next read or write to offset.
|
||||
@@ -194,57 +163,45 @@ write :: proc(s: Writer, p: []byte, n_written: ^int = nil) -> (n: int, err: Erro
|
||||
//
|
||||
// seek returns the new offset to the start of the file/stream, and any error if occurred.
|
||||
seek :: proc(s: Seeker, offset: i64, whence: Seek_From) -> (n: i64, err: Error) {
|
||||
if s.stream_vtable != nil && s.impl_seek != nil {
|
||||
return s->impl_seek(offset, whence)
|
||||
if s.procedure != nil {
|
||||
n, err = s.procedure(s.data, .Seek, nil, offset, whence)
|
||||
} else {
|
||||
err = .Empty
|
||||
}
|
||||
return 0, .Empty
|
||||
return
|
||||
}
|
||||
|
||||
// The behaviour of close after the first call is stream implementation defined.
|
||||
// Different streams may document their own behaviour.
|
||||
close :: proc(s: Closer) -> Error {
|
||||
if s.stream_vtable != nil && s.impl_close != nil {
|
||||
return s->impl_close()
|
||||
close :: proc(s: Closer) -> (err: Error) {
|
||||
if s.procedure != nil {
|
||||
_, err = s.procedure(s.data, .Close, nil, 0, nil)
|
||||
}
|
||||
// Instead of .Empty, .None is fine in this case
|
||||
return .None
|
||||
return
|
||||
}
|
||||
|
||||
flush :: proc(s: Flusher) -> Error {
|
||||
if s.stream_vtable != nil && s.impl_flush != nil {
|
||||
return s->impl_flush()
|
||||
flush :: proc(s: Flusher) -> (err: Error) {
|
||||
if s.procedure != nil {
|
||||
_, err = s.procedure(s.data, .Flush, nil, 0, nil)
|
||||
}
|
||||
// Instead of .Empty, .None is fine in this case
|
||||
return .None
|
||||
return
|
||||
}
|
||||
|
||||
// size returns the size of the stream. If the stream does not support querying its size, 0 will be returned.
|
||||
size :: proc(s: Stream) -> i64 {
|
||||
if s.stream_vtable == nil {
|
||||
return 0
|
||||
size :: proc(s: Stream) -> (n: i64, err: Error) {
|
||||
if s.procedure != nil {
|
||||
n, err = s.procedure(s.data, .Size, nil, 0, nil)
|
||||
if err == .Empty {
|
||||
n = 0
|
||||
curr := seek(s, 0, .Current) or_return
|
||||
end := seek(s, 0, .End) or_return
|
||||
seek(s, curr, .Start) or_return
|
||||
n = end
|
||||
}
|
||||
} else {
|
||||
err = .Empty
|
||||
}
|
||||
if s.impl_size != nil {
|
||||
return s->impl_size()
|
||||
}
|
||||
if s.impl_seek == nil {
|
||||
return 0
|
||||
}
|
||||
|
||||
curr, end: i64
|
||||
err: Error
|
||||
if curr, err = s->impl_seek(0, .Current); err != nil {
|
||||
return 0
|
||||
}
|
||||
|
||||
if end, err = s->impl_seek(0, .End); err != nil {
|
||||
return 0
|
||||
}
|
||||
|
||||
if _, err = s->impl_seek(curr, .Start); err != nil {
|
||||
return 0
|
||||
}
|
||||
|
||||
return end
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -256,29 +213,24 @@ size :: proc(s: Stream) -> i64 {
|
||||
//
|
||||
// If n == len(p), err may be either nil or .EOF
|
||||
read_at :: proc(r: Reader_At, p: []byte, offset: i64, n_read: ^int = nil) -> (n: int, err: Error) {
|
||||
defer if n_read != nil {
|
||||
n_read^ += n
|
||||
}
|
||||
|
||||
if r.stream_vtable == nil {
|
||||
return 0, .Empty
|
||||
}
|
||||
if r.impl_read_at != nil {
|
||||
return r->impl_read_at(p, offset)
|
||||
}
|
||||
if r.impl_seek == nil || r.impl_read == nil {
|
||||
return 0, .Empty
|
||||
}
|
||||
|
||||
curr_offset := r->impl_seek(offset, .Current) or_return
|
||||
|
||||
n, err = r->impl_read(p)
|
||||
_, err1 := r->impl_seek(curr_offset, .Start)
|
||||
if err1 != nil && err == nil {
|
||||
err = err1
|
||||
if r.procedure != nil {
|
||||
n64: i64
|
||||
n64, err = r.procedure(r.data, .Read_At, p, offset, nil)
|
||||
if err != .Empty {
|
||||
n = int(n64)
|
||||
} else {
|
||||
curr := seek(r, offset, .Current) or_return
|
||||
n, err = read(r, p)
|
||||
_, err1 := seek(r, curr, .Start)
|
||||
if err1 != nil && err == nil {
|
||||
err = err1
|
||||
}
|
||||
}
|
||||
if n_read != nil { n_read^ += n }
|
||||
} else {
|
||||
err = .Empty
|
||||
}
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
// write_at writes len(p) bytes into p starting with the provided offset in the underlying Writer_At stream w.
|
||||
@@ -287,97 +239,39 @@ read_at :: proc(r: Reader_At, p: []byte, offset: i64, n_read: ^int = nil) -> (n:
|
||||
// If write_at is writing to a Writer_At which has a seek offset, then write_at should not affect the underlying
|
||||
// seek offset.
|
||||
write_at :: proc(w: Writer_At, p: []byte, offset: i64, n_written: ^int = nil) -> (n: int, err: Error) {
|
||||
defer if n_written != nil {
|
||||
n_written^ += n
|
||||
}
|
||||
|
||||
if w.stream_vtable == nil {
|
||||
return 0, .Empty
|
||||
}
|
||||
if w.impl_write_at != nil {
|
||||
return w->impl_write_at(p, offset)
|
||||
}
|
||||
if w.impl_seek == nil || w.impl_write == nil {
|
||||
return 0, .Empty
|
||||
}
|
||||
|
||||
curr_offset: i64
|
||||
curr_offset, err = w->impl_seek(offset, .Current)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
n, err = w->impl_write(p)
|
||||
_, err1 := w->impl_seek(curr_offset, .Start)
|
||||
if err1 != nil && err == nil {
|
||||
err = err1
|
||||
if w.procedure != nil {
|
||||
n64: i64
|
||||
n64, err = w.procedure(w.data, .Write_At, p, offset, nil)
|
||||
if err != .Empty {
|
||||
n = int(n64)
|
||||
} else {
|
||||
curr := seek(w, offset, .Current) or_return
|
||||
n, err = write(w, p)
|
||||
_, err1 := seek(w, curr, .Start)
|
||||
if err1 != nil && err == nil {
|
||||
err = err1
|
||||
}
|
||||
}
|
||||
if n_written != nil { n_written^ += n }
|
||||
} else {
|
||||
err = .Empty
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
write_to :: proc(r: Writer_To, w: Writer) -> (n: i64, err: Error) {
|
||||
if r.stream_vtable == nil || w.stream_vtable == nil {
|
||||
return 0, .Empty
|
||||
}
|
||||
if r.impl_write_to != nil {
|
||||
return r->impl_write_to(w)
|
||||
}
|
||||
return 0, .Empty
|
||||
}
|
||||
read_from :: proc(w: Reader_From, r: Reader) -> (n: i64, err: Error) {
|
||||
if r.stream_vtable == nil || w.stream_vtable == nil {
|
||||
return 0, .Empty
|
||||
}
|
||||
if r.impl_read_from != nil {
|
||||
return w->impl_read_from(r)
|
||||
}
|
||||
return 0, .Empty
|
||||
}
|
||||
|
||||
|
||||
// read_byte reads and returns the next byte from r.
|
||||
read_byte :: proc(r: Reader, n_read: ^int = nil) -> (b: byte, err: Error) {
|
||||
defer if err == nil && n_read != nil {
|
||||
n_read^ += 1
|
||||
}
|
||||
|
||||
if r.stream_vtable == nil {
|
||||
return 0, .Empty
|
||||
}
|
||||
if r.impl_read_byte != nil {
|
||||
return r->impl_read_byte()
|
||||
}
|
||||
if r.impl_read == nil {
|
||||
return 0, .Empty
|
||||
}
|
||||
|
||||
buf: [1]byte
|
||||
_, err = r->impl_read(buf[:])
|
||||
return buf[0], err
|
||||
_, err = read(r, buf[:], n_read)
|
||||
b = buf[0]
|
||||
return
|
||||
}
|
||||
|
||||
write_byte :: proc(w: Writer, c: byte, n_written: ^int = nil) -> Error {
|
||||
return _write_byte(auto_cast w, c, n_written)
|
||||
}
|
||||
|
||||
@(private)
|
||||
_write_byte :: proc(w: Writer, c: byte, n_written: ^int = nil) -> (err: Error) {
|
||||
defer if err == nil && n_written != nil {
|
||||
n_written^ += 1
|
||||
}
|
||||
if w.stream_vtable == nil {
|
||||
return .Empty
|
||||
}
|
||||
if w.impl_write_byte != nil {
|
||||
return w->impl_write_byte(c)
|
||||
}
|
||||
if w.impl_write == nil {
|
||||
return .Empty
|
||||
}
|
||||
|
||||
b := [1]byte{c}
|
||||
_, err = w->impl_write(b[:])
|
||||
return err
|
||||
buf: [1]byte
|
||||
buf[0] = c
|
||||
write(w, buf[:], n_written) or_return
|
||||
return nil
|
||||
}
|
||||
|
||||
// read_rune reads a single UTF-8 encoded Unicode codepoint and returns the rune and its size in bytes.
|
||||
@@ -385,19 +279,9 @@ read_rune :: proc(br: Reader, n_read: ^int = nil) -> (ch: rune, size: int, err:
|
||||
defer if err == nil && n_read != nil {
|
||||
n_read^ += size
|
||||
}
|
||||
if br.stream_vtable == nil {
|
||||
return 0, 0, .Empty
|
||||
}
|
||||
if br.impl_read_rune != nil {
|
||||
return br->impl_read_rune()
|
||||
}
|
||||
if br.impl_read == nil {
|
||||
return 0, 0, .Empty
|
||||
}
|
||||
|
||||
b: [utf8.UTF_MAX]byte
|
||||
_, err = br->impl_read(b[:1])
|
||||
|
||||
_, err = read(br, b[:1])
|
||||
|
||||
s0 := b[0]
|
||||
ch = rune(s0)
|
||||
@@ -415,7 +299,7 @@ read_rune :: proc(br: Reader, n_read: ^int = nil) -> (ch: rune, size: int, err:
|
||||
return
|
||||
}
|
||||
sz := int(x&7)
|
||||
size, err = br->impl_read(b[1:sz])
|
||||
size, err = read(br, b[1:sz])
|
||||
if err != nil || size+1 < sz {
|
||||
ch = utf8.RUNE_ERROR
|
||||
return
|
||||
@@ -425,28 +309,6 @@ read_rune :: proc(br: Reader, n_read: ^int = nil) -> (ch: rune, size: int, err:
|
||||
return
|
||||
}
|
||||
|
||||
unread_byte :: proc(s: Stream) -> Error {
|
||||
if s.stream_vtable == nil {
|
||||
return .Empty
|
||||
}
|
||||
if s.impl_unread_byte != nil {
|
||||
return s->impl_unread_byte()
|
||||
}
|
||||
if s.impl_seek != nil {
|
||||
_, err := s->impl_seek(-1, .Current)
|
||||
return err
|
||||
}
|
||||
|
||||
return .Empty
|
||||
}
|
||||
unread_rune :: proc(s: Writer) -> Error {
|
||||
if s.stream_vtable != nil && s.impl_unread_rune != nil {
|
||||
return s->impl_unread_rune()
|
||||
}
|
||||
return .Empty
|
||||
}
|
||||
|
||||
|
||||
// write_string writes the contents of the string s to w.
|
||||
write_string :: proc(s: Writer, str: string, n_written: ^int = nil) -> (n: int, err: Error) {
|
||||
return write(s, transmute([]byte)str, n_written)
|
||||
@@ -457,14 +319,6 @@ write_rune :: proc(s: Writer, r: rune, n_written: ^int = nil) -> (size: int, err
|
||||
defer if err == nil && n_written != nil {
|
||||
n_written^ += size
|
||||
}
|
||||
|
||||
if s.stream_vtable == nil {
|
||||
return 0, .Empty
|
||||
}
|
||||
if s.impl_write_rune != nil {
|
||||
return s->impl_write_rune(r)
|
||||
}
|
||||
|
||||
if r < utf8.RUNE_SELF {
|
||||
err = write_byte(s, byte(r))
|
||||
if err == nil {
|
||||
@@ -542,21 +396,15 @@ copy_n :: proc(dst: Writer, src: Reader, n: i64) -> (written: i64, err: Error) {
|
||||
|
||||
@(private)
|
||||
_copy_buffer :: proc(dst: Writer, src: Reader, buf: []byte) -> (written: i64, err: Error) {
|
||||
if dst.stream_vtable == nil || src.stream_vtable == nil {
|
||||
if dst.procedure == nil || src.procedure == nil {
|
||||
return 0, .Empty
|
||||
}
|
||||
if src.impl_write_to != nil {
|
||||
return src->impl_write_to(dst)
|
||||
}
|
||||
if src.impl_read_from != nil {
|
||||
return dst->impl_read_from(src)
|
||||
}
|
||||
buf := buf
|
||||
if buf == nil {
|
||||
DEFAULT_SIZE :: 4 * 1024
|
||||
size := DEFAULT_SIZE
|
||||
if src.stream_vtable == _limited_reader_vtable {
|
||||
l := (^Limited_Reader)(src.stream_data)
|
||||
if src.procedure == _limited_reader_proc {
|
||||
l := (^Limited_Reader)(src.data)
|
||||
if i64(size) > l.n {
|
||||
if l.n < 1 {
|
||||
size = 1
|
||||
|
||||
+48
-40
@@ -5,33 +5,37 @@ Multi_Reader :: struct {
|
||||
}
|
||||
|
||||
@(private)
|
||||
_multi_reader_vtable := &Stream_VTable{
|
||||
impl_read = proc(s: Stream, p: []byte) -> (n: int, err: Error) {
|
||||
mr := (^Multi_Reader)(s.stream_data)
|
||||
for len(mr.readers) > 0 {
|
||||
r := mr.readers[0]
|
||||
n, err = read(r, p)
|
||||
if err == .EOF {
|
||||
ordered_remove(&mr.readers, 0)
|
||||
}
|
||||
if n > 0 || err != .EOF {
|
||||
if err == .EOF && len(mr.readers) > 0 {
|
||||
// Don't return EOF yet, more readers remain
|
||||
err = nil
|
||||
}
|
||||
return
|
||||
}
|
||||
_multi_reader_proc :: proc(stream_data: rawptr, mode: Stream_Mode, p: []byte, offset: i64, whence: Seek_From) -> (n: i64, err: Error) {
|
||||
if mode == .Query {
|
||||
return query_utility({.Read, .Query})
|
||||
} else if mode != .Read {
|
||||
return 0, .Empty
|
||||
}
|
||||
mr := (^Multi_Reader)(stream_data)
|
||||
for len(mr.readers) > 0 {
|
||||
r := mr.readers[0]
|
||||
n, err = _i64_err(read(r, p))
|
||||
if err == .EOF {
|
||||
ordered_remove(&mr.readers, 0)
|
||||
}
|
||||
return 0, .EOF
|
||||
},
|
||||
if n > 0 || err != .EOF {
|
||||
if err == .EOF && len(mr.readers) > 0 {
|
||||
// Don't return EOF yet, more readers remain
|
||||
err = nil
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
return 0, .EOF
|
||||
}
|
||||
|
||||
|
||||
multi_reader_init :: proc(mr: ^Multi_Reader, readers: ..Reader, allocator := context.allocator) -> (r: Reader) {
|
||||
all_readers := make([dynamic]Reader, 0, len(readers), allocator)
|
||||
|
||||
for w in readers {
|
||||
if w.stream_vtable == _multi_reader_vtable {
|
||||
other := (^Multi_Reader)(w.stream_data)
|
||||
if w.procedure == _multi_reader_proc {
|
||||
other := (^Multi_Reader)(w.data)
|
||||
append(&all_readers, ..other.readers[:])
|
||||
} else {
|
||||
append(&all_readers, w)
|
||||
@@ -40,8 +44,8 @@ multi_reader_init :: proc(mr: ^Multi_Reader, readers: ..Reader, allocator := con
|
||||
|
||||
mr.readers = all_readers
|
||||
|
||||
r.stream_vtable = _multi_reader_vtable
|
||||
r.stream_data = mr
|
||||
r.procedure = _multi_reader_proc
|
||||
r.data = mr
|
||||
return
|
||||
}
|
||||
|
||||
@@ -55,38 +59,42 @@ Multi_Writer :: struct {
|
||||
}
|
||||
|
||||
@(private)
|
||||
_multi_writer_vtable := &Stream_VTable{
|
||||
impl_write = proc(s: Stream, p: []byte) -> (n: int, err: Error) {
|
||||
mw := (^Multi_Writer)(s.stream_data)
|
||||
for w in mw.writers {
|
||||
n, err = write(w, p)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if n != len(p) {
|
||||
err = .Short_Write
|
||||
return
|
||||
}
|
||||
_multi_writer_proc :: proc(stream_data: rawptr, mode: Stream_Mode, p: []byte, offset: i64, whence: Seek_From) -> (n: i64, err: Error) {
|
||||
if mode == .Query {
|
||||
return query_utility({.Write, .Query})
|
||||
} else if mode != .Write {
|
||||
return 0, .Empty
|
||||
}
|
||||
mw := (^Multi_Writer)(stream_data)
|
||||
for w in mw.writers {
|
||||
n, err = _i64_err(write(w, p))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if n != i64(len(p)) {
|
||||
err = .Short_Write
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
return len(p), nil
|
||||
},
|
||||
return i64(len(p)), nil
|
||||
}
|
||||
|
||||
|
||||
multi_writer_init :: proc(mw: ^Multi_Writer, writers: ..Writer, allocator := context.allocator) -> (out: Writer) {
|
||||
mw.writers = make([dynamic]Writer, 0, len(writers), allocator)
|
||||
|
||||
for w in writers {
|
||||
if w.stream_vtable == _multi_writer_vtable {
|
||||
other := (^Multi_Writer)(w.stream_data)
|
||||
if w.procedure == _multi_writer_proc {
|
||||
other := (^Multi_Writer)(w.data)
|
||||
append(&mw.writers, ..other.writers[:])
|
||||
} else {
|
||||
append(&mw.writers, w)
|
||||
}
|
||||
}
|
||||
|
||||
out.stream_vtable = _multi_writer_vtable
|
||||
out.stream_data = mw
|
||||
out.procedure = _multi_writer_proc
|
||||
out.data = mw
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
+64
-44
@@ -2,6 +2,7 @@ package io
|
||||
|
||||
import "core:strconv"
|
||||
import "core:unicode/utf8"
|
||||
import "core:unicode/utf16"
|
||||
|
||||
read_ptr :: proc(r: Reader, p: rawptr, byte_size: int, n_read: ^int = nil) -> (n: int, err: Error) {
|
||||
return read(r, ([^]byte)(p)[:byte_size], n_read)
|
||||
@@ -146,7 +147,7 @@ write_encoded_rune :: proc(w: Writer, r: rune, write_quote := true, n_written: ^
|
||||
return
|
||||
}
|
||||
|
||||
write_escaped_rune :: proc(w: Writer, r: rune, quote: byte, html_safe := false, n_written: ^int = nil) -> (n: int, err: Error) {
|
||||
write_escaped_rune :: proc(w: Writer, r: rune, quote: byte, html_safe := false, n_written: ^int = nil, for_json := false) -> (n: int, err: Error) {
|
||||
is_printable :: proc(r: rune) -> bool {
|
||||
if r <= 0xff {
|
||||
switch r {
|
||||
@@ -163,7 +164,7 @@ write_escaped_rune :: proc(w: Writer, r: rune, quote: byte, html_safe := false,
|
||||
defer if n_written != nil {
|
||||
n_written^ += n
|
||||
}
|
||||
|
||||
|
||||
if html_safe {
|
||||
switch r {
|
||||
case '<', '>', '&':
|
||||
@@ -211,17 +212,29 @@ write_escaped_rune :: proc(w: Writer, r: rune, quote: byte, html_safe := false,
|
||||
write_byte(w, DIGITS_LOWER[c>>uint(s) & 0xf], &n) or_return
|
||||
}
|
||||
case:
|
||||
write_byte(w, '\\', &n) or_return
|
||||
write_byte(w, 'U', &n) or_return
|
||||
for s := 28; s >= 0; s -= 4 {
|
||||
write_byte(w, DIGITS_LOWER[c>>uint(s) & 0xf], &n) or_return
|
||||
if for_json {
|
||||
buf: [2]u16
|
||||
utf16.encode(buf[:], []rune{c})
|
||||
for bc in buf {
|
||||
write_byte(w, '\\', &n) or_return
|
||||
write_byte(w, 'u', &n) or_return
|
||||
for s := 12; s >= 0; s -= 4 {
|
||||
write_byte(w, DIGITS_LOWER[bc>>uint(s) & 0xf], &n) or_return
|
||||
}
|
||||
}
|
||||
} else {
|
||||
write_byte(w, '\\', &n) or_return
|
||||
write_byte(w, 'U', &n) or_return
|
||||
for s := 24; s >= 0; s -= 4 {
|
||||
write_byte(w, DIGITS_LOWER[c>>uint(s) & 0xf], &n) or_return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
write_quoted_string :: proc(w: Writer, str: string, quote: byte = '"', n_written: ^int = nil) -> (n: int, err: Error) {
|
||||
write_quoted_string :: proc(w: Writer, str: string, quote: byte = '"', n_written: ^int = nil, for_json := false) -> (n: int, err: Error) {
|
||||
defer if n_written != nil {
|
||||
n_written^ += n
|
||||
}
|
||||
@@ -240,7 +253,7 @@ write_quoted_string :: proc(w: Writer, str: string, quote: byte = '"', n_written
|
||||
continue
|
||||
}
|
||||
|
||||
n_wrapper(write_escaped_rune(w, r, quote), &n) or_return
|
||||
n_wrapper(write_escaped_rune(w, r, quote, false, nil, for_json), &n) or_return
|
||||
|
||||
}
|
||||
write_byte(w, quote, &n) or_return
|
||||
@@ -279,17 +292,21 @@ Tee_Reader :: struct {
|
||||
}
|
||||
|
||||
@(private)
|
||||
_tee_reader_vtable := &Stream_VTable{
|
||||
impl_read = proc(s: Stream, p: []byte) -> (n: int, err: Error) {
|
||||
t := (^Tee_Reader)(s.stream_data)
|
||||
n, err = read(t.r, p)
|
||||
_tee_reader_proc :: proc(stream_data: rawptr, mode: Stream_Mode, p: []byte, offset: i64, whence: Seek_From) -> (n: i64, err: Error) {
|
||||
t := (^Tee_Reader)(stream_data)
|
||||
#partial switch mode {
|
||||
case .Read:
|
||||
n, err = _i64_err(read(t.r, p))
|
||||
if n > 0 {
|
||||
if wn, werr := write(t.w, p[:n]); werr != nil {
|
||||
return wn, werr
|
||||
return i64(wn), werr
|
||||
}
|
||||
}
|
||||
return
|
||||
},
|
||||
case .Query:
|
||||
return query_utility({.Read, .Query})
|
||||
}
|
||||
return 0, .Empty
|
||||
}
|
||||
|
||||
// tee_reader_init returns a Reader that writes to 'w' what it reads from 'r'
|
||||
@@ -304,8 +321,8 @@ tee_reader_init :: proc(t: ^Tee_Reader, r: Reader, w: Writer, allocator := conte
|
||||
}
|
||||
|
||||
tee_reader_to_reader :: proc(t: ^Tee_Reader) -> (r: Reader) {
|
||||
r.stream_data = t
|
||||
r.stream_vtable = _tee_reader_vtable
|
||||
r.data = t
|
||||
r.procedure = _tee_reader_proc
|
||||
return
|
||||
}
|
||||
|
||||
@@ -319,9 +336,10 @@ Limited_Reader :: struct {
|
||||
}
|
||||
|
||||
@(private)
|
||||
_limited_reader_vtable := &Stream_VTable{
|
||||
impl_read = proc(s: Stream, p: []byte) -> (n: int, err: Error) {
|
||||
l := (^Limited_Reader)(s.stream_data)
|
||||
_limited_reader_proc :: proc(stream_data: rawptr, mode: Stream_Mode, p: []byte, offset: i64, whence: Seek_From) -> (n: i64, err: Error) {
|
||||
l := (^Limited_Reader)(stream_data)
|
||||
#partial switch mode {
|
||||
case .Read:
|
||||
if l.n <= 0 {
|
||||
return 0, .EOF
|
||||
}
|
||||
@@ -329,10 +347,13 @@ _limited_reader_vtable := &Stream_VTable{
|
||||
if i64(len(p)) > l.n {
|
||||
p = p[0:l.n]
|
||||
}
|
||||
n, err = read(l.r, p)
|
||||
n, err = _i64_err(read(l.r, p))
|
||||
l.n -= i64(n)
|
||||
return
|
||||
},
|
||||
case .Query:
|
||||
return query_utility({.Read, .Query})
|
||||
}
|
||||
return 0, .Empty
|
||||
}
|
||||
|
||||
limited_reader_init :: proc(l: ^Limited_Reader, r: Reader, n: i64) -> Reader {
|
||||
@@ -342,8 +363,8 @@ limited_reader_init :: proc(l: ^Limited_Reader, r: Reader, n: i64) -> Reader {
|
||||
}
|
||||
|
||||
limited_reader_to_reader :: proc(l: ^Limited_Reader) -> (r: Reader) {
|
||||
r.stream_vtable = _limited_reader_vtable
|
||||
r.stream_data = l
|
||||
r.procedure = _limited_reader_proc
|
||||
r.data = l
|
||||
return
|
||||
}
|
||||
|
||||
@@ -362,15 +383,16 @@ section_reader_init :: proc(s: ^Section_Reader, r: Reader_At, off: i64, n: i64)
|
||||
return
|
||||
}
|
||||
section_reader_to_stream :: proc(s: ^Section_Reader) -> (out: Stream) {
|
||||
out.stream_data = s
|
||||
out.stream_vtable = _section_reader_vtable
|
||||
out.data = s
|
||||
out.procedure = _section_reader_proc
|
||||
return
|
||||
}
|
||||
|
||||
@(private)
|
||||
_section_reader_vtable := &Stream_VTable{
|
||||
impl_read = proc(stream: Stream, p: []byte) -> (n: int, err: Error) {
|
||||
s := (^Section_Reader)(stream.stream_data)
|
||||
_section_reader_proc :: proc(stream_data: rawptr, mode: Stream_Mode, p: []byte, offset: i64, whence: Seek_From) -> (n: i64, err: Error) {
|
||||
s := (^Section_Reader)(stream_data)
|
||||
#partial switch mode {
|
||||
case .Read:
|
||||
if s.off >= s.limit {
|
||||
return 0, .EOF
|
||||
}
|
||||
@@ -378,13 +400,11 @@ _section_reader_vtable := &Stream_VTable{
|
||||
if max := s.limit - s.off; i64(len(p)) > max {
|
||||
p = p[0:max]
|
||||
}
|
||||
n, err = read_at(s.r, p, s.off)
|
||||
n, err = _i64_err(read_at(s.r, p, s.off))
|
||||
s.off += i64(n)
|
||||
return
|
||||
},
|
||||
impl_read_at = proc(stream: Stream, p: []byte, off: i64) -> (n: int, err: Error) {
|
||||
s := (^Section_Reader)(stream.stream_data)
|
||||
p, off := p, off
|
||||
case .Read_At:
|
||||
p, off := p, offset
|
||||
|
||||
if off < 0 || off >= s.limit - s.base {
|
||||
return 0, .EOF
|
||||
@@ -392,17 +412,15 @@ _section_reader_vtable := &Stream_VTable{
|
||||
off += s.base
|
||||
if max := s.limit - off; i64(len(p)) > max {
|
||||
p = p[0:max]
|
||||
n, err = read_at(s.r, p, off)
|
||||
n, err = _i64_err(read_at(s.r, p, off))
|
||||
if err == nil {
|
||||
err = .EOF
|
||||
}
|
||||
return
|
||||
}
|
||||
return read_at(s.r, p, off)
|
||||
},
|
||||
impl_seek = proc(stream: Stream, offset: i64, whence: Seek_From) -> (n: i64, err: Error) {
|
||||
s := (^Section_Reader)(stream.stream_data)
|
||||
return _i64_err(read_at(s.r, p, off))
|
||||
|
||||
case .Seek:
|
||||
offset := offset
|
||||
switch whence {
|
||||
case:
|
||||
@@ -420,10 +438,12 @@ _section_reader_vtable := &Stream_VTable{
|
||||
s.off = offset
|
||||
n = offset - s.base
|
||||
return
|
||||
},
|
||||
impl_size = proc(stream: Stream) -> i64 {
|
||||
s := (^Section_Reader)(stream.stream_data)
|
||||
return s.limit - s.base
|
||||
},
|
||||
}
|
||||
case .Size:
|
||||
n = s.limit - s.base
|
||||
return
|
||||
case .Query:
|
||||
return query_utility({.Read, .Read_At, .Seek, .Size, .Query})
|
||||
}
|
||||
return 0, nil
|
||||
|
||||
}
|
||||
|
||||
+13
-13
@@ -76,43 +76,43 @@ nil_logger :: proc() -> Logger {
|
||||
}
|
||||
|
||||
debugf :: proc(fmt_str: string, args: ..any, location := #caller_location) {
|
||||
logf(level=.Debug, fmt_str=fmt_str, args=args, location=location)
|
||||
logf(.Debug, fmt_str, ..args, location=location)
|
||||
}
|
||||
infof :: proc(fmt_str: string, args: ..any, location := #caller_location) {
|
||||
logf(level=.Info, fmt_str=fmt_str, args=args, location=location)
|
||||
logf(.Info, fmt_str, ..args, location=location)
|
||||
}
|
||||
warnf :: proc(fmt_str: string, args: ..any, location := #caller_location) {
|
||||
logf(level=.Warning, fmt_str=fmt_str, args=args, location=location)
|
||||
logf(.Warning, fmt_str, ..args, location=location)
|
||||
}
|
||||
errorf :: proc(fmt_str: string, args: ..any, location := #caller_location) {
|
||||
logf(level=.Error, fmt_str=fmt_str, args=args, location=location)
|
||||
logf(.Error, fmt_str, ..args, location=location)
|
||||
}
|
||||
fatalf :: proc(fmt_str: string, args: ..any, location := #caller_location) {
|
||||
logf(level=.Fatal, fmt_str=fmt_str, args=args, location=location)
|
||||
logf(.Fatal, fmt_str, ..args, location=location)
|
||||
}
|
||||
|
||||
debug :: proc(args: ..any, sep := " ", location := #caller_location) {
|
||||
log(level=.Debug, args=args, sep=sep, location=location)
|
||||
log(.Debug, ..args, sep=sep, location=location)
|
||||
}
|
||||
info :: proc(args: ..any, sep := " ", location := #caller_location) {
|
||||
log(level=.Info, args=args, sep=sep, location=location)
|
||||
log(.Info, ..args, sep=sep, location=location)
|
||||
}
|
||||
warn :: proc(args: ..any, sep := " ", location := #caller_location) {
|
||||
log(level=.Warning, args=args, sep=sep, location=location)
|
||||
log(.Warning, ..args, sep=sep, location=location)
|
||||
}
|
||||
error :: proc(args: ..any, sep := " ", location := #caller_location) {
|
||||
log(level=.Error, args=args, sep=sep, location=location)
|
||||
log(.Error, ..args, sep=sep, location=location)
|
||||
}
|
||||
fatal :: proc(args: ..any, sep := " ", location := #caller_location) {
|
||||
log(level=.Fatal, args=args, sep=sep, location=location)
|
||||
log(.Fatal, ..args, sep=sep, location=location)
|
||||
}
|
||||
|
||||
panic :: proc(args: ..any, location := #caller_location) -> ! {
|
||||
log(level=.Fatal, args=args, location=location)
|
||||
log(.Fatal, ..args, location=location)
|
||||
runtime.panic("log.panic", location)
|
||||
}
|
||||
panicf :: proc(fmt_str: string, args: ..any, location := #caller_location) -> ! {
|
||||
logf(level=.Fatal, fmt_str=fmt_str, args=args, location=location)
|
||||
logf(.Fatal, fmt_str, ..args, location=location)
|
||||
runtime.panic("log.panicf", location)
|
||||
}
|
||||
|
||||
@@ -127,7 +127,7 @@ log :: proc(level: Level, args: ..any, sep := " ", location := #caller_location)
|
||||
if level < logger.lowest_level {
|
||||
return
|
||||
}
|
||||
str := fmt.tprint(args=args, sep=sep) //NOTE(Hoej): While tprint isn't thread-safe, no logging is.
|
||||
str := fmt.tprint(..args, sep=sep) //NOTE(Hoej): While tprint isn't thread-safe, no logging is.
|
||||
logger.procedure(logger.data, level, str, logger.options, location)
|
||||
}
|
||||
|
||||
|
||||
+27
-27
@@ -38,60 +38,60 @@ log_allocator_proc :: proc(allocator_data: rawptr, mode: runtime.Allocator_Mode,
|
||||
switch mode {
|
||||
case .Alloc:
|
||||
logf(
|
||||
level=la.level,
|
||||
fmt_str = "%s%s>>> ALLOCATOR(mode=.Alloc, size=%d, alignment=%d)",
|
||||
args = {la.prefix, padding, size, alignment},
|
||||
la.level,
|
||||
"%s%s>>> ALLOCATOR(mode=.Alloc, size=%d, alignment=%d)",
|
||||
la.prefix, padding, size, alignment,
|
||||
location = location,
|
||||
)
|
||||
case .Alloc_Non_Zeroed:
|
||||
logf(
|
||||
level=la.level,
|
||||
fmt_str = "%s%s>>> ALLOCATOR(mode=.Alloc_Non_Zeroed, size=%d, alignment=%d)",
|
||||
args = {la.prefix, padding, size, alignment},
|
||||
la.level,
|
||||
"%s%s>>> ALLOCATOR(mode=.Alloc_Non_Zeroed, size=%d, alignment=%d)",
|
||||
la.prefix, padding, size, alignment,
|
||||
location = location,
|
||||
)
|
||||
case .Free:
|
||||
if old_size != 0 {
|
||||
logf(
|
||||
level=la.level,
|
||||
fmt_str = "%s%s<<< ALLOCATOR(mode=.Free, ptr=%p, size=%d)",
|
||||
args = {la.prefix, padding, old_memory, old_size},
|
||||
la.level,
|
||||
"%s%s<<< ALLOCATOR(mode=.Free, ptr=%p, size=%d)",
|
||||
la.prefix, padding, old_memory, old_size,
|
||||
location = location,
|
||||
)
|
||||
} else {
|
||||
logf(
|
||||
level=la.level,
|
||||
fmt_str = "%s%s<<< ALLOCATOR(mode=.Free, ptr=%p)",
|
||||
args = {la.prefix, padding, old_memory},
|
||||
la.level,
|
||||
"%s%s<<< ALLOCATOR(mode=.Free, ptr=%p)",
|
||||
la.prefix, padding, old_memory,
|
||||
location = location,
|
||||
)
|
||||
}
|
||||
case .Free_All:
|
||||
logf(
|
||||
level=la.level,
|
||||
fmt_str = "%s%s<<< ALLOCATOR(mode=.Free_All)",
|
||||
args = {la.prefix, padding},
|
||||
la.level,
|
||||
"%s%s<<< ALLOCATOR(mode=.Free_All)",
|
||||
la.prefix, padding,
|
||||
location = location,
|
||||
)
|
||||
case .Resize:
|
||||
logf(
|
||||
level=la.level,
|
||||
fmt_str = "%s%s>>> ALLOCATOR(mode=.Resize, ptr=%p, old_size=%d, size=%d, alignment=%d)",
|
||||
args = {la.prefix, padding, old_memory, old_size, size, alignment},
|
||||
la.level,
|
||||
"%s%s>>> ALLOCATOR(mode=.Resize, ptr=%p, old_size=%d, size=%d, alignment=%d)",
|
||||
la.prefix, padding, old_memory, old_size, size, alignment,
|
||||
location = location,
|
||||
)
|
||||
case .Query_Features:
|
||||
logf(
|
||||
level=la.level,
|
||||
fmt_str = "%s%ALLOCATOR(mode=.Query_Features)",
|
||||
args = {la.prefix, padding},
|
||||
la.level,
|
||||
"%s%ALLOCATOR(mode=.Query_Features)",
|
||||
la.prefix, padding,
|
||||
location = location,
|
||||
)
|
||||
case .Query_Info:
|
||||
logf(
|
||||
level=la.level,
|
||||
fmt_str = "%s%ALLOCATOR(mode=.Query_Info)",
|
||||
args = {la.prefix, padding},
|
||||
la.level,
|
||||
"%s%ALLOCATOR(mode=.Query_Info)",
|
||||
la.prefix, padding,
|
||||
location = location,
|
||||
)
|
||||
}
|
||||
@@ -103,9 +103,9 @@ log_allocator_proc :: proc(allocator_data: rawptr, mode: runtime.Allocator_Mode,
|
||||
defer la.locked = false
|
||||
if err != nil {
|
||||
logf(
|
||||
level=la.level,
|
||||
fmt_str = "%s%ALLOCATOR ERROR=%v",
|
||||
args = {la.prefix, padding, error},
|
||||
la.level,
|
||||
"%s%ALLOCATOR ERROR=%v",
|
||||
la.prefix, padding, error,
|
||||
location = location,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ import rnd "core:math/rand"
|
||||
int_destroy :: proc(integers: ..^Int) {
|
||||
integers := integers
|
||||
|
||||
for a in &integers {
|
||||
for a in integers {
|
||||
assert_if_nil(a)
|
||||
}
|
||||
#force_inline internal_int_destroy(..integers)
|
||||
@@ -408,7 +408,7 @@ clear_if_uninitialized_multi :: proc(args: ..^Int, allocator := context.allocato
|
||||
args := args
|
||||
assert_if_nil(..args)
|
||||
|
||||
for i in &args {
|
||||
for i in args {
|
||||
#force_inline internal_clear_if_uninitialized_single(i, allocator) or_return
|
||||
}
|
||||
return err
|
||||
@@ -435,7 +435,7 @@ int_init_multi :: proc(integers: ..^Int, allocator := context.allocator) -> (err
|
||||
assert_if_nil(..integers)
|
||||
|
||||
integers := integers
|
||||
for a in &integers {
|
||||
for a in integers {
|
||||
#force_inline internal_clear(a, true, allocator) or_return
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -1857,7 +1857,7 @@ internal_root_n :: proc { internal_int_root_n, }
|
||||
internal_int_destroy :: proc(integers: ..^Int) {
|
||||
integers := integers
|
||||
|
||||
for a in &integers {
|
||||
for &a in integers {
|
||||
if internal_int_allocated_cap(a) > 0 {
|
||||
mem.zero_slice(a.digit[:])
|
||||
free(&a.digit[0])
|
||||
@@ -2909,7 +2909,7 @@ internal_int_init_multi :: proc(integers: ..^Int, allocator := context.allocator
|
||||
context.allocator = allocator
|
||||
|
||||
integers := integers
|
||||
for a in &integers {
|
||||
for a in integers {
|
||||
internal_clear(a) or_return
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -429,7 +429,7 @@ internal_int_write_to_ascii_file :: proc(a: ^Int, filename: string, radix := i8(
|
||||
len = l,
|
||||
}
|
||||
|
||||
ok := os.write_entire_file(name=filename, data=data, truncate=true)
|
||||
ok := os.write_entire_file(filename, data, truncate=true)
|
||||
return nil if ok else .Cannot_Write_File
|
||||
}
|
||||
|
||||
|
||||
@@ -137,7 +137,7 @@ rat_copy :: proc(dst, src: ^Rat, minimize := false, allocator := context.allocat
|
||||
internal_rat_destroy :: proc(rationals: ..^Rat) {
|
||||
rationals := rationals
|
||||
|
||||
for z in &rationals {
|
||||
for &z in rationals {
|
||||
internal_int_destroy(&z.a, &z.b)
|
||||
}
|
||||
}
|
||||
|
||||
+154
-77
@@ -37,68 +37,96 @@ overflowing_sub :: intrinsics.overflow_sub
|
||||
overflowing_mul :: intrinsics.overflow_mul
|
||||
|
||||
|
||||
log2 :: proc(x: $T) -> T where intrinsics.type_is_integer(T), intrinsics.type_is_unsigned(T) {
|
||||
@(require_results)
|
||||
log2 :: proc "contextless" (x: $T) -> T where intrinsics.type_is_integer(T), intrinsics.type_is_unsigned(T) {
|
||||
return (8*size_of(T)-1) - count_leading_zeros(x)
|
||||
}
|
||||
|
||||
rotate_left8 :: proc(x: u8, k: int) -> u8 {
|
||||
@(require_results)
|
||||
rotate_left8 :: proc "contextless" (x: u8, k: int) -> u8 {
|
||||
n :: 8
|
||||
s := uint(k) & (n-1)
|
||||
return x <<s | x>>(n-s)
|
||||
}
|
||||
rotate_left16 :: proc(x: u16, k: int) -> u16 {
|
||||
@(require_results)
|
||||
rotate_left16 :: proc "contextless" (x: u16, k: int) -> u16 {
|
||||
n :: 16
|
||||
s := uint(k) & (n-1)
|
||||
return x <<s | x>>(n-s)
|
||||
}
|
||||
rotate_left32 :: proc(x: u32, k: int) -> u32 {
|
||||
@(require_results)
|
||||
rotate_left32 :: proc "contextless" (x: u32, k: int) -> u32 {
|
||||
n :: 32
|
||||
s := uint(k) & (n-1)
|
||||
return x <<s | x>>(n-s)
|
||||
}
|
||||
rotate_left64 :: proc(x: u64, k: int) -> u64 {
|
||||
@(require_results)
|
||||
rotate_left64 :: proc "contextless" (x: u64, k: int) -> u64 {
|
||||
n :: 64
|
||||
s := uint(k) & (n-1)
|
||||
return x <<s | x>>(n-s)
|
||||
}
|
||||
|
||||
rotate_left :: proc(x: uint, k: int) -> uint {
|
||||
@(require_results)
|
||||
rotate_left :: proc "contextless" (x: uint, k: int) -> uint {
|
||||
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 }
|
||||
from_be_u16 :: proc(i: u16) -> u16 { when ODIN_ENDIAN == .Big { return i } else { return byte_swap(i) } }
|
||||
from_be_u32 :: proc(i: u32) -> u32 { when ODIN_ENDIAN == .Big { return i } else { return byte_swap(i) } }
|
||||
from_be_u64 :: proc(i: u64) -> u64 { when ODIN_ENDIAN == .Big { return i } else { return byte_swap(i) } }
|
||||
from_be_uint :: proc(i: uint) -> uint { when ODIN_ENDIAN == .Big { return i } else { return byte_swap(i) } }
|
||||
@(require_results)
|
||||
from_be_u8 :: proc "contextless" (i: u8) -> u8 { return i }
|
||||
@(require_results)
|
||||
from_be_u16 :: proc "contextless" (i: u16) -> u16 { when ODIN_ENDIAN == .Big { return i } else { return byte_swap(i) } }
|
||||
@(require_results)
|
||||
from_be_u32 :: proc "contextless" (i: u32) -> u32 { when ODIN_ENDIAN == .Big { return i } else { return byte_swap(i) } }
|
||||
@(require_results)
|
||||
from_be_u64 :: proc "contextless" (i: u64) -> u64 { when ODIN_ENDIAN == .Big { return i } else { return byte_swap(i) } }
|
||||
@(require_results)
|
||||
from_be_uint :: proc "contextless" (i: uint) -> uint { when ODIN_ENDIAN == .Big { return i } else { return byte_swap(i) } }
|
||||
|
||||
from_le_u8 :: proc(i: u8) -> u8 { return i }
|
||||
from_le_u16 :: proc(i: u16) -> u16 { when ODIN_ENDIAN == .Little { return i } else { return byte_swap(i) } }
|
||||
from_le_u32 :: proc(i: u32) -> u32 { when ODIN_ENDIAN == .Little { return i } else { return byte_swap(i) } }
|
||||
from_le_u64 :: proc(i: u64) -> u64 { when ODIN_ENDIAN == .Little { return i } else { return byte_swap(i) } }
|
||||
from_le_uint :: proc(i: uint) -> uint { when ODIN_ENDIAN == .Little { return i } else { return byte_swap(i) } }
|
||||
@(require_results)
|
||||
from_le_u8 :: proc "contextless" (i: u8) -> u8 { return i }
|
||||
@(require_results)
|
||||
from_le_u16 :: proc "contextless" (i: u16) -> u16 { when ODIN_ENDIAN == .Little { return i } else { return byte_swap(i) } }
|
||||
@(require_results)
|
||||
from_le_u32 :: proc "contextless" (i: u32) -> u32 { when ODIN_ENDIAN == .Little { return i } else { return byte_swap(i) } }
|
||||
@(require_results)
|
||||
from_le_u64 :: proc "contextless" (i: u64) -> u64 { when ODIN_ENDIAN == .Little { return i } else { return byte_swap(i) } }
|
||||
@(require_results)
|
||||
from_le_uint :: proc "contextless" (i: uint) -> uint { when ODIN_ENDIAN == .Little { return i } else { return byte_swap(i) } }
|
||||
|
||||
to_be_u8 :: proc(i: u8) -> u8 { return i }
|
||||
to_be_u16 :: proc(i: u16) -> u16 { when ODIN_ENDIAN == .Big { return i } else { return byte_swap(i) } }
|
||||
to_be_u32 :: proc(i: u32) -> u32 { when ODIN_ENDIAN == .Big { return i } else { return byte_swap(i) } }
|
||||
to_be_u64 :: proc(i: u64) -> u64 { when ODIN_ENDIAN == .Big { return i } else { return byte_swap(i) } }
|
||||
to_be_uint :: proc(i: uint) -> uint { when ODIN_ENDIAN == .Big { return i } else { return byte_swap(i) } }
|
||||
@(require_results)
|
||||
to_be_u8 :: proc "contextless" (i: u8) -> u8 { return i }
|
||||
@(require_results)
|
||||
to_be_u16 :: proc "contextless" (i: u16) -> u16 { when ODIN_ENDIAN == .Big { return i } else { return byte_swap(i) } }
|
||||
@(require_results)
|
||||
to_be_u32 :: proc "contextless" (i: u32) -> u32 { when ODIN_ENDIAN == .Big { return i } else { return byte_swap(i) } }
|
||||
@(require_results)
|
||||
to_be_u64 :: proc "contextless" (i: u64) -> u64 { when ODIN_ENDIAN == .Big { return i } else { return byte_swap(i) } }
|
||||
@(require_results)
|
||||
to_be_uint :: proc "contextless" (i: uint) -> uint { when ODIN_ENDIAN == .Big { return i } else { return byte_swap(i) } }
|
||||
|
||||
|
||||
to_le_u8 :: proc(i: u8) -> u8 { return i }
|
||||
to_le_u16 :: proc(i: u16) -> u16 { when ODIN_ENDIAN == .Little { return i } else { return byte_swap(i) } }
|
||||
to_le_u32 :: proc(i: u32) -> u32 { when ODIN_ENDIAN == .Little { return i } else { return byte_swap(i) } }
|
||||
to_le_u64 :: proc(i: u64) -> u64 { when ODIN_ENDIAN == .Little { return i } else { return byte_swap(i) } }
|
||||
to_le_uint :: proc(i: uint) -> uint { when ODIN_ENDIAN == .Little { return i } else { return byte_swap(i) } }
|
||||
@(require_results)
|
||||
to_le_u8 :: proc "contextless" (i: u8) -> u8 { return i }
|
||||
@(require_results)
|
||||
to_le_u16 :: proc "contextless" (i: u16) -> u16 { when ODIN_ENDIAN == .Little { return i } else { return byte_swap(i) } }
|
||||
@(require_results)
|
||||
to_le_u32 :: proc "contextless" (i: u32) -> u32 { when ODIN_ENDIAN == .Little { return i } else { return byte_swap(i) } }
|
||||
@(require_results)
|
||||
to_le_u64 :: proc "contextless" (i: u64) -> u64 { when ODIN_ENDIAN == .Little { return i } else { return byte_swap(i) } }
|
||||
@(require_results)
|
||||
to_le_uint :: proc "contextless" (i: uint) -> uint { when ODIN_ENDIAN == .Little { return i } else { return byte_swap(i) } }
|
||||
|
||||
|
||||
|
||||
len_u8 :: proc(x: u8) -> int {
|
||||
@(require_results)
|
||||
len_u8 :: proc "contextless" (x: u8) -> int {
|
||||
return int(len_u8_table[x])
|
||||
}
|
||||
len_u16 :: proc(x: u16) -> (n: int) {
|
||||
@(require_results)
|
||||
len_u16 :: proc "contextless" (x: u16) -> (n: int) {
|
||||
x := x
|
||||
if x >= 1<<8 {
|
||||
x >>= 8
|
||||
@@ -106,7 +134,8 @@ len_u16 :: proc(x: u16) -> (n: int) {
|
||||
}
|
||||
return n + int(len_u8_table[x])
|
||||
}
|
||||
len_u32 :: proc(x: u32) -> (n: int) {
|
||||
@(require_results)
|
||||
len_u32 :: proc "contextless" (x: u32) -> (n: int) {
|
||||
x := x
|
||||
if x >= 1<<16 {
|
||||
x >>= 16
|
||||
@@ -118,7 +147,8 @@ len_u32 :: proc(x: u32) -> (n: int) {
|
||||
}
|
||||
return n + int(len_u8_table[x])
|
||||
}
|
||||
len_u64 :: proc(x: u64) -> (n: int) {
|
||||
@(require_results)
|
||||
len_u64 :: proc "contextless" (x: u64) -> (n: int) {
|
||||
x := x
|
||||
if x >= 1<<32 {
|
||||
x >>= 32
|
||||
@@ -134,7 +164,8 @@ len_u64 :: proc(x: u64) -> (n: int) {
|
||||
}
|
||||
return n + int(len_u8_table[x])
|
||||
}
|
||||
len_uint :: proc(x: uint) -> (n: int) {
|
||||
@(require_results)
|
||||
len_uint :: proc "contextless" (x: uint) -> (n: int) {
|
||||
when size_of(uint) == size_of(u64) {
|
||||
return len_u64(u64(x))
|
||||
} else {
|
||||
@@ -146,21 +177,24 @@ len_uint :: proc(x: uint) -> (n: int) {
|
||||
len :: proc{len_u8, len_u16, len_u32, len_u64, len_uint}
|
||||
|
||||
|
||||
add_u32 :: proc(x, y, carry: u32) -> (sum, carry_out: u32) {
|
||||
@(require_results)
|
||||
add_u32 :: proc "contextless" (x, y, carry: u32) -> (sum, carry_out: u32) {
|
||||
tmp_carry, tmp_carry2: bool
|
||||
sum, tmp_carry = intrinsics.overflow_add(x, y)
|
||||
sum, tmp_carry2 = intrinsics.overflow_add(sum, carry)
|
||||
carry_out = u32(tmp_carry | tmp_carry2)
|
||||
return
|
||||
}
|
||||
add_u64 :: proc(x, y, carry: u64) -> (sum, carry_out: u64) {
|
||||
@(require_results)
|
||||
add_u64 :: proc "contextless" (x, y, carry: u64) -> (sum, carry_out: u64) {
|
||||
tmp_carry, tmp_carry2: bool
|
||||
sum, tmp_carry = intrinsics.overflow_add(x, y)
|
||||
sum, tmp_carry2 = intrinsics.overflow_add(sum, carry)
|
||||
carry_out = u64(tmp_carry | tmp_carry2)
|
||||
return
|
||||
}
|
||||
add_uint :: proc(x, y, carry: uint) -> (sum, carry_out: uint) {
|
||||
@(require_results)
|
||||
add_uint :: proc "contextless" (x, y, carry: uint) -> (sum, carry_out: uint) {
|
||||
when size_of(uint) == size_of(u64) {
|
||||
a, b := add_u64(u64(x), u64(y), u64(carry))
|
||||
} else {
|
||||
@@ -172,21 +206,24 @@ add_uint :: proc(x, y, carry: uint) -> (sum, carry_out: uint) {
|
||||
add :: proc{add_u32, add_u64, add_uint}
|
||||
|
||||
|
||||
sub_u32 :: proc(x, y, borrow: u32) -> (diff, borrow_out: u32) {
|
||||
@(require_results)
|
||||
sub_u32 :: proc "contextless" (x, y, borrow: u32) -> (diff, borrow_out: u32) {
|
||||
tmp_borrow, tmp_borrow2: bool
|
||||
diff, tmp_borrow = intrinsics.overflow_sub(x, y)
|
||||
diff, tmp_borrow2 = intrinsics.overflow_sub(diff, borrow)
|
||||
borrow_out = u32(tmp_borrow | tmp_borrow2)
|
||||
return
|
||||
}
|
||||
sub_u64 :: proc(x, y, borrow: u64) -> (diff, borrow_out: u64) {
|
||||
@(require_results)
|
||||
sub_u64 :: proc "contextless" (x, y, borrow: u64) -> (diff, borrow_out: u64) {
|
||||
tmp_borrow, tmp_borrow2: bool
|
||||
diff, tmp_borrow = intrinsics.overflow_sub(x, y)
|
||||
diff, tmp_borrow2 = intrinsics.overflow_sub(diff, borrow)
|
||||
borrow_out = u64(tmp_borrow | tmp_borrow2)
|
||||
return
|
||||
}
|
||||
sub_uint :: proc(x, y, borrow: uint) -> (diff, borrow_out: uint) {
|
||||
@(require_results)
|
||||
sub_uint :: proc "contextless" (x, y, borrow: uint) -> (diff, borrow_out: uint) {
|
||||
when size_of(uint) == size_of(u64) {
|
||||
a, b := sub_u64(u64(x), u64(y), u64(borrow))
|
||||
} else {
|
||||
@@ -198,18 +235,21 @@ sub_uint :: proc(x, y, borrow: uint) -> (diff, borrow_out: uint) {
|
||||
sub :: proc{sub_u32, sub_u64, sub_uint}
|
||||
|
||||
|
||||
mul_u32 :: proc(x, y: u32) -> (hi, lo: u32) {
|
||||
@(require_results)
|
||||
mul_u32 :: proc "contextless" (x, y: u32) -> (hi, lo: u32) {
|
||||
z := u64(x) * u64(y)
|
||||
hi, lo = u32(z>>32), u32(z)
|
||||
return
|
||||
}
|
||||
mul_u64 :: proc(x, y: u64) -> (hi, lo: u64) {
|
||||
@(require_results)
|
||||
mul_u64 :: proc "contextless" (x, y: u64) -> (hi, lo: u64) {
|
||||
prod_wide := u128(x) * u128(y)
|
||||
hi, lo = u64(prod_wide>>64), u64(prod_wide)
|
||||
return
|
||||
}
|
||||
|
||||
mul_uint :: proc(x, y: uint) -> (hi, lo: uint) {
|
||||
@(require_results)
|
||||
mul_uint :: proc "contextless" (x, y: uint) -> (hi, lo: uint) {
|
||||
when size_of(uint) == size_of(u32) {
|
||||
a, b := mul_u32(u32(x), u32(y))
|
||||
} else {
|
||||
@@ -222,13 +262,15 @@ mul_uint :: proc(x, y: uint) -> (hi, lo: uint) {
|
||||
mul :: proc{mul_u32, mul_u64, mul_uint}
|
||||
|
||||
|
||||
div_u32 :: proc(hi, lo, y: u32) -> (quo, rem: u32) {
|
||||
@(require_results)
|
||||
div_u32 :: proc "odin" (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
|
||||
}
|
||||
div_u64 :: proc(hi, lo, y: u64) -> (quo, rem: u64) {
|
||||
@(require_results)
|
||||
div_u64 :: proc "odin" (hi, lo, y: u64) -> (quo, rem: u64) {
|
||||
y := y
|
||||
two32 :: 1 << 32
|
||||
mask32 :: two32 - 1
|
||||
@@ -273,7 +315,8 @@ div_u64 :: proc(hi, lo, y: u64) -> (quo, rem: u64) {
|
||||
|
||||
return q1*two32 + q0, (un21*two32 + un0 - q0*y) >> s
|
||||
}
|
||||
div_uint :: proc(hi, lo, y: uint) -> (quo, rem: uint) {
|
||||
@(require_results)
|
||||
div_uint :: proc "odin" (hi, lo, y: uint) -> (quo, rem: uint) {
|
||||
when size_of(uint) == size_of(u32) {
|
||||
a, b := div_u32(u32(hi), u32(lo), u32(y))
|
||||
} else {
|
||||
@@ -286,16 +329,26 @@ div :: proc{div_u32, div_u64, div_uint}
|
||||
|
||||
|
||||
|
||||
is_power_of_two_u8 :: proc(i: u8) -> bool { return i > 0 && (i & (i-1)) == 0 }
|
||||
is_power_of_two_i8 :: proc(i: i8) -> bool { return i > 0 && (i & (i-1)) == 0 }
|
||||
is_power_of_two_u16 :: proc(i: u16) -> bool { return i > 0 && (i & (i-1)) == 0 }
|
||||
is_power_of_two_i16 :: proc(i: i16) -> bool { return i > 0 && (i & (i-1)) == 0 }
|
||||
is_power_of_two_u32 :: proc(i: u32) -> bool { return i > 0 && (i & (i-1)) == 0 }
|
||||
is_power_of_two_i32 :: proc(i: i32) -> bool { return i > 0 && (i & (i-1)) == 0 }
|
||||
is_power_of_two_u64 :: proc(i: u64) -> bool { return i > 0 && (i & (i-1)) == 0 }
|
||||
is_power_of_two_i64 :: proc(i: i64) -> bool { return i > 0 && (i & (i-1)) == 0 }
|
||||
is_power_of_two_uint :: proc(i: uint) -> bool { return i > 0 && (i & (i-1)) == 0 }
|
||||
is_power_of_two_int :: proc(i: int) -> bool { return i > 0 && (i & (i-1)) == 0 }
|
||||
@(require_results)
|
||||
is_power_of_two_u8 :: proc "contextless" (i: u8) -> bool { return i > 0 && (i & (i-1)) == 0 }
|
||||
@(require_results)
|
||||
is_power_of_two_i8 :: proc "contextless" (i: i8) -> bool { return i > 0 && (i & (i-1)) == 0 }
|
||||
@(require_results)
|
||||
is_power_of_two_u16 :: proc "contextless" (i: u16) -> bool { return i > 0 && (i & (i-1)) == 0 }
|
||||
@(require_results)
|
||||
is_power_of_two_i16 :: proc "contextless" (i: i16) -> bool { return i > 0 && (i & (i-1)) == 0 }
|
||||
@(require_results)
|
||||
is_power_of_two_u32 :: proc "contextless" (i: u32) -> bool { return i > 0 && (i & (i-1)) == 0 }
|
||||
@(require_results)
|
||||
is_power_of_two_i32 :: proc "contextless" (i: i32) -> bool { return i > 0 && (i & (i-1)) == 0 }
|
||||
@(require_results)
|
||||
is_power_of_two_u64 :: proc "contextless" (i: u64) -> bool { return i > 0 && (i & (i-1)) == 0 }
|
||||
@(require_results)
|
||||
is_power_of_two_i64 :: proc "contextless" (i: i64) -> bool { return i > 0 && (i & (i-1)) == 0 }
|
||||
@(require_results)
|
||||
is_power_of_two_uint :: proc "contextless" (i: uint) -> bool { return i > 0 && (i & (i-1)) == 0 }
|
||||
@(require_results)
|
||||
is_power_of_two_int :: proc "contextless" (i: int) -> bool { return i > 0 && (i & (i-1)) == 0 }
|
||||
|
||||
is_power_of_two :: proc{
|
||||
is_power_of_two_u8, is_power_of_two_i8,
|
||||
@@ -320,44 +373,56 @@ len_u8_table := [256]u8{
|
||||
}
|
||||
|
||||
|
||||
bitfield_extract_u8 :: proc(value: u8, offset, bits: uint) -> u8 { return (value >> offset) & u8(1<<bits - 1) }
|
||||
bitfield_extract_u16 :: proc(value: u16, offset, bits: uint) -> u16 { return (value >> offset) & u16(1<<bits - 1) }
|
||||
bitfield_extract_u32 :: proc(value: u32, offset, bits: uint) -> u32 { return (value >> offset) & u32(1<<bits - 1) }
|
||||
bitfield_extract_u64 :: proc(value: u64, offset, bits: uint) -> u64 { return (value >> offset) & u64(1<<bits - 1) }
|
||||
bitfield_extract_u128 :: proc(value: u128, offset, bits: uint) -> u128 { return (value >> offset) & u128(1<<bits - 1) }
|
||||
bitfield_extract_uint :: proc(value: uint, offset, bits: uint) -> uint { return (value >> offset) & uint(1<<bits - 1) }
|
||||
@(require_results)
|
||||
bitfield_extract_u8 :: proc "contextless" (value: u8, offset, bits: uint) -> u8 { return (value >> offset) & u8(1<<bits - 1) }
|
||||
@(require_results)
|
||||
bitfield_extract_u16 :: proc "contextless" (value: u16, offset, bits: uint) -> u16 { return (value >> offset) & u16(1<<bits - 1) }
|
||||
@(require_results)
|
||||
bitfield_extract_u32 :: proc "contextless" (value: u32, offset, bits: uint) -> u32 { return (value >> offset) & u32(1<<bits - 1) }
|
||||
@(require_results)
|
||||
bitfield_extract_u64 :: proc "contextless" (value: u64, offset, bits: uint) -> u64 { return (value >> offset) & u64(1<<bits - 1) }
|
||||
@(require_results)
|
||||
bitfield_extract_u128 :: proc "contextless" (value: u128, offset, bits: uint) -> u128 { return (value >> offset) & u128(1<<bits - 1) }
|
||||
@(require_results)
|
||||
bitfield_extract_uint :: proc "contextless" (value: uint, offset, bits: uint) -> uint { return (value >> offset) & uint(1<<bits - 1) }
|
||||
|
||||
bitfield_extract_i8 :: proc(value: i8, offset, bits: uint) -> i8 {
|
||||
@(require_results)
|
||||
bitfield_extract_i8 :: proc "contextless" (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)
|
||||
}
|
||||
bitfield_extract_i16 :: proc(value: i16, offset, bits: uint) -> i16 {
|
||||
@(require_results)
|
||||
bitfield_extract_i16 :: proc "contextless" (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)
|
||||
}
|
||||
bitfield_extract_i32 :: proc(value: i32, offset, bits: uint) -> i32 {
|
||||
@(require_results)
|
||||
bitfield_extract_i32 :: proc "contextless" (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)
|
||||
}
|
||||
bitfield_extract_i64 :: proc(value: i64, offset, bits: uint) -> i64 {
|
||||
@(require_results)
|
||||
bitfield_extract_i64 :: proc "contextless" (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)
|
||||
}
|
||||
bitfield_extract_i128 :: proc(value: i128, offset, bits: uint) -> i128 {
|
||||
@(require_results)
|
||||
bitfield_extract_i128 :: proc "contextless" (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)
|
||||
}
|
||||
bitfield_extract_int :: proc(value: int, offset, bits: uint) -> int {
|
||||
@(require_results)
|
||||
bitfield_extract_int :: proc "contextless" (value: int, offset, bits: uint) -> int {
|
||||
v := (uint(value) >> offset) & uint(1<<bits - 1)
|
||||
m := uint(1<<(bits-1))
|
||||
r := (v~m) - m
|
||||
@@ -381,52 +446,64 @@ bitfield_extract :: proc{
|
||||
}
|
||||
|
||||
|
||||
bitfield_insert_u8 :: proc(base, insert: u8, offset, bits: uint) -> u8 {
|
||||
@(require_results)
|
||||
bitfield_insert_u8 :: proc "contextless" (base, insert: u8, offset, bits: uint) -> u8 {
|
||||
mask := u8(1<<bits - 1)
|
||||
return (base &~ (mask<<offset)) | ((insert&mask) << offset)
|
||||
}
|
||||
bitfield_insert_u16 :: proc(base, insert: u16, offset, bits: uint) -> u16 {
|
||||
@(require_results)
|
||||
bitfield_insert_u16 :: proc "contextless" (base, insert: u16, offset, bits: uint) -> u16 {
|
||||
mask := u16(1<<bits - 1)
|
||||
return (base &~ (mask<<offset)) | ((insert&mask) << offset)
|
||||
}
|
||||
bitfield_insert_u32 :: proc(base, insert: u32, offset, bits: uint) -> u32 {
|
||||
@(require_results)
|
||||
bitfield_insert_u32 :: proc "contextless" (base, insert: u32, offset, bits: uint) -> u32 {
|
||||
mask := u32(1<<bits - 1)
|
||||
return (base &~ (mask<<offset)) | ((insert&mask) << offset)
|
||||
}
|
||||
bitfield_insert_u64 :: proc(base, insert: u64, offset, bits: uint) -> u64 {
|
||||
@(require_results)
|
||||
bitfield_insert_u64 :: proc "contextless" (base, insert: u64, offset, bits: uint) -> u64 {
|
||||
mask := u64(1<<bits - 1)
|
||||
return (base &~ (mask<<offset)) | ((insert&mask) << offset)
|
||||
}
|
||||
bitfield_insert_u128 :: proc(base, insert: u128, offset, bits: uint) -> u128 {
|
||||
@(require_results)
|
||||
bitfield_insert_u128 :: proc "contextless" (base, insert: u128, offset, bits: uint) -> u128 {
|
||||
mask := u128(1<<bits - 1)
|
||||
return (base &~ (mask<<offset)) | ((insert&mask) << offset)
|
||||
}
|
||||
bitfield_insert_uint :: proc(base, insert: uint, offset, bits: uint) -> uint {
|
||||
@(require_results)
|
||||
bitfield_insert_uint :: proc "contextless" (base, insert: uint, offset, bits: uint) -> uint {
|
||||
mask := uint(1<<bits - 1)
|
||||
return (base &~ (mask<<offset)) | ((insert&mask) << offset)
|
||||
}
|
||||
|
||||
bitfield_insert_i8 :: proc(base, insert: i8, offset, bits: uint) -> i8 {
|
||||
@(require_results)
|
||||
bitfield_insert_i8 :: proc "contextless" (base, insert: i8, offset, bits: uint) -> i8 {
|
||||
mask := i8(1<<bits - 1)
|
||||
return (base &~ (mask<<offset)) | ((insert&mask) << offset)
|
||||
}
|
||||
bitfield_insert_i16 :: proc(base, insert: i16, offset, bits: uint) -> i16 {
|
||||
@(require_results)
|
||||
bitfield_insert_i16 :: proc "contextless" (base, insert: i16, offset, bits: uint) -> i16 {
|
||||
mask := i16(1<<bits - 1)
|
||||
return (base &~ (mask<<offset)) | ((insert&mask) << offset)
|
||||
}
|
||||
bitfield_insert_i32 :: proc(base, insert: i32, offset, bits: uint) -> i32 {
|
||||
@(require_results)
|
||||
bitfield_insert_i32 :: proc "contextless" (base, insert: i32, offset, bits: uint) -> i32 {
|
||||
mask := i32(1<<bits - 1)
|
||||
return (base &~ (mask<<offset)) | ((insert&mask) << offset)
|
||||
}
|
||||
bitfield_insert_i64 :: proc(base, insert: i64, offset, bits: uint) -> i64 {
|
||||
@(require_results)
|
||||
bitfield_insert_i64 :: proc "contextless" (base, insert: i64, offset, bits: uint) -> i64 {
|
||||
mask := i64(1<<bits - 1)
|
||||
return (base &~ (mask<<offset)) | ((insert&mask) << offset)
|
||||
}
|
||||
bitfield_insert_i128 :: proc(base, insert: i128, offset, bits: uint) -> i128 {
|
||||
@(require_results)
|
||||
bitfield_insert_i128 :: proc "contextless" (base, insert: i128, offset, bits: uint) -> i128 {
|
||||
mask := i128(1<<bits - 1)
|
||||
return (base &~ (mask<<offset)) | ((insert&mask) << offset)
|
||||
}
|
||||
bitfield_insert_int :: proc(base, insert: int, offset, bits: uint) -> int {
|
||||
@(require_results)
|
||||
bitfield_insert_int :: proc "contextless" (base, insert: int, offset, bits: uint) -> int {
|
||||
mask := int(1<<bits - 1)
|
||||
return (base &~ (mask<<offset)) | ((insert&mask) << offset)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,513 @@
|
||||
package math_cmplx
|
||||
|
||||
import "core:builtin"
|
||||
import "core:math"
|
||||
|
||||
// The original C code, the long comment, and the constants
|
||||
// below are from http://netlib.sandia.gov/cephes/c9x-complex/clog.c.
|
||||
// The go code is a simplified version of the original C.
|
||||
//
|
||||
// Cephes Math Library Release 2.8: June, 2000
|
||||
// Copyright 1984, 1987, 1989, 1992, 2000 by Stephen L. Moshier
|
||||
//
|
||||
// The readme file at http://netlib.sandia.gov/cephes/ says:
|
||||
// Some software in this archive may be from the book _Methods and
|
||||
// Programs for Mathematical Functions_ (Prentice-Hall or Simon & Schuster
|
||||
// International, 1989) or from the Cephes Mathematical Library, a
|
||||
// commercial product. In either event, it is copyrighted by the author.
|
||||
// What you see here may be used freely but it comes with no support or
|
||||
// guarantee.
|
||||
//
|
||||
// The two known misprints in the book are repaired here in the
|
||||
// source listings for the gamma function and the incomplete beta
|
||||
// integral.
|
||||
//
|
||||
// Stephen L. Moshier
|
||||
// moshier@na-net.ornl.gov
|
||||
|
||||
abs :: builtin.abs
|
||||
conj :: builtin.conj
|
||||
real :: builtin.real
|
||||
imag :: builtin.imag
|
||||
jmag :: builtin.jmag
|
||||
kmag :: builtin.kmag
|
||||
|
||||
|
||||
sin :: proc{
|
||||
sin_complex128,
|
||||
}
|
||||
cos :: proc{
|
||||
cos_complex128,
|
||||
}
|
||||
tan :: proc{
|
||||
tan_complex128,
|
||||
}
|
||||
cot :: proc{
|
||||
cot_complex128,
|
||||
}
|
||||
|
||||
|
||||
sinh :: proc{
|
||||
sinh_complex128,
|
||||
}
|
||||
cosh :: proc{
|
||||
cosh_complex128,
|
||||
}
|
||||
tanh :: proc{
|
||||
tanh_complex128,
|
||||
}
|
||||
|
||||
|
||||
|
||||
// sqrt returns the square root of x.
|
||||
// The result r is chosen so that real(r) ≥ 0 and imag(r) has the same sign as imag(x).
|
||||
sqrt :: proc{
|
||||
sqrt_complex32,
|
||||
sqrt_complex64,
|
||||
sqrt_complex128,
|
||||
}
|
||||
ln :: proc{
|
||||
ln_complex32,
|
||||
ln_complex64,
|
||||
ln_complex128,
|
||||
}
|
||||
log10 :: proc{
|
||||
log10_complex32,
|
||||
log10_complex64,
|
||||
log10_complex128,
|
||||
}
|
||||
|
||||
exp :: proc{
|
||||
exp_complex32,
|
||||
exp_complex64,
|
||||
exp_complex128,
|
||||
}
|
||||
|
||||
pow :: proc{
|
||||
pow_complex32,
|
||||
pow_complex64,
|
||||
pow_complex128,
|
||||
}
|
||||
|
||||
phase :: proc{
|
||||
phase_complex32,
|
||||
phase_complex64,
|
||||
phase_complex128,
|
||||
}
|
||||
|
||||
polar :: proc{
|
||||
polar_complex32,
|
||||
polar_complex64,
|
||||
polar_complex128,
|
||||
}
|
||||
|
||||
is_inf :: proc{
|
||||
is_inf_complex32,
|
||||
is_inf_complex64,
|
||||
is_inf_complex128,
|
||||
}
|
||||
|
||||
is_nan :: proc{
|
||||
is_nan_complex32,
|
||||
is_nan_complex64,
|
||||
is_nan_complex128,
|
||||
}
|
||||
|
||||
|
||||
|
||||
// sqrt_complex32 returns the square root of x.
|
||||
// The result r is chosen so that real(r) ≥ 0 and imag(r) has the same sign as imag(x).
|
||||
sqrt_complex32 :: proc "contextless" (x: complex32) -> complex32 {
|
||||
return complex32(sqrt_complex128(complex128(x)))
|
||||
}
|
||||
|
||||
// sqrt_complex64 returns the square root of x.
|
||||
// The result r is chosen so that real(r) ≥ 0 and imag(r) has the same sign as imag(x).
|
||||
sqrt_complex64 :: proc "contextless" (x: complex64) -> complex64 {
|
||||
return complex64(sqrt_complex128(complex128(x)))
|
||||
}
|
||||
|
||||
|
||||
// sqrt_complex128 returns the square root of x.
|
||||
// The result r is chosen so that real(r) ≥ 0 and imag(r) has the same sign as imag(x).
|
||||
sqrt_complex128 :: proc "contextless" (x: complex128) -> complex128 {
|
||||
// The original C code, the long comment, and the constants
|
||||
// below are from http://netlib.sandia.gov/cephes/c9x-complex/clog.c.
|
||||
// The go code is a simplified version of the original C.
|
||||
//
|
||||
// Cephes Math Library Release 2.8: June, 2000
|
||||
// Copyright 1984, 1987, 1989, 1992, 2000 by Stephen L. Moshier
|
||||
//
|
||||
// The readme file at http://netlib.sandia.gov/cephes/ says:
|
||||
// Some software in this archive may be from the book _Methods and
|
||||
// Programs for Mathematical Functions_ (Prentice-Hall or Simon & Schuster
|
||||
// International, 1989) or from the Cephes Mathematical Library, a
|
||||
// commercial product. In either event, it is copyrighted by the author.
|
||||
// What you see here may be used freely but it comes with no support or
|
||||
// guarantee.
|
||||
//
|
||||
// The two known misprints in the book are repaired here in the
|
||||
// source listings for the gamma function and the incomplete beta
|
||||
// integral.
|
||||
//
|
||||
// Stephen L. Moshier
|
||||
// moshier@na-net.ornl.gov
|
||||
|
||||
// Complex square root
|
||||
//
|
||||
// DESCRIPTION:
|
||||
//
|
||||
// If z = x + iy, r = |z|, then
|
||||
//
|
||||
// 1/2
|
||||
// Re w = [ (r + x)/2 ] ,
|
||||
//
|
||||
// 1/2
|
||||
// Im w = [ (r - x)/2 ] .
|
||||
//
|
||||
// Cancellation error in r-x or r+x is avoided by using the
|
||||
// identity 2 Re w Im w = y.
|
||||
//
|
||||
// Note that -w is also a square root of z. The root chosen
|
||||
// is always in the right half plane and Im w has the same sign as y.
|
||||
//
|
||||
// ACCURACY:
|
||||
//
|
||||
// Relative error:
|
||||
// arithmetic domain # trials peak rms
|
||||
// DEC -10,+10 25000 3.2e-17 9.6e-18
|
||||
// IEEE -10,+10 1,000,000 2.9e-16 6.1e-17
|
||||
|
||||
if imag(x) == 0 {
|
||||
// Ensure that imag(r) has the same sign as imag(x) for imag(x) == signed zero.
|
||||
if real(x) == 0 {
|
||||
return complex(0, imag(x))
|
||||
}
|
||||
if real(x) < 0 {
|
||||
return complex(0, math.copy_sign(math.sqrt(-real(x)), imag(x)))
|
||||
}
|
||||
return complex(math.sqrt(real(x)), imag(x))
|
||||
} else if math.is_inf(imag(x), 0) {
|
||||
return complex(math.inf_f64(1.0), imag(x))
|
||||
}
|
||||
if real(x) == 0 {
|
||||
if imag(x) < 0 {
|
||||
r := math.sqrt(-0.5 * imag(x))
|
||||
return complex(r, -r)
|
||||
}
|
||||
r := math.sqrt(0.5 * imag(x))
|
||||
return complex(r, r)
|
||||
}
|
||||
a := real(x)
|
||||
b := imag(x)
|
||||
scale: f64
|
||||
// Rescale to avoid internal overflow or underflow.
|
||||
if abs(a) > 4 || abs(b) > 4 {
|
||||
a *= 0.25
|
||||
b *= 0.25
|
||||
scale = 2
|
||||
} else {
|
||||
a *= 1.8014398509481984e16 // 2**54
|
||||
b *= 1.8014398509481984e16
|
||||
scale = 7.450580596923828125e-9 // 2**-27
|
||||
}
|
||||
r := math.hypot(a, b)
|
||||
t: f64
|
||||
if a > 0 {
|
||||
t = math.sqrt(0.5*r + 0.5*a)
|
||||
r = scale * abs((0.5*b)/t)
|
||||
t *= scale
|
||||
} else {
|
||||
r = math.sqrt(0.5*r - 0.5*a)
|
||||
t = scale * abs((0.5*b)/r)
|
||||
r *= scale
|
||||
}
|
||||
if b < 0 {
|
||||
return complex(t, -r)
|
||||
}
|
||||
return complex(t, r)
|
||||
}
|
||||
|
||||
ln_complex32 :: proc "contextless" (x: complex32) -> complex32 {
|
||||
return complex(math.ln(abs(x)), phase(x))
|
||||
}
|
||||
ln_complex64 :: proc "contextless" (x: complex64) -> complex64 {
|
||||
return complex(math.ln(abs(x)), phase(x))
|
||||
}
|
||||
ln_complex128 :: proc "contextless" (x: complex128) -> complex128 {
|
||||
return complex(math.ln(abs(x)), phase(x))
|
||||
}
|
||||
|
||||
|
||||
exp_complex32 :: proc "contextless" (x: complex32) -> complex32 {
|
||||
switch re, im := real(x), imag(x); {
|
||||
case math.is_inf(re, 0):
|
||||
switch {
|
||||
case re > 0 && im == 0:
|
||||
return x
|
||||
case math.is_inf(im, 0) || math.is_nan(im):
|
||||
if re < 0 {
|
||||
return complex(0, math.copy_sign(0, im))
|
||||
} else {
|
||||
return complex(math.inf_f64(1.0), math.nan_f64())
|
||||
}
|
||||
}
|
||||
case math.is_nan(re):
|
||||
if im == 0 {
|
||||
return complex(math.nan_f16(), im)
|
||||
}
|
||||
}
|
||||
r := math.exp(real(x))
|
||||
s, c := math.sincos(imag(x))
|
||||
return complex(r*c, r*s)
|
||||
}
|
||||
exp_complex64 :: proc "contextless" (x: complex64) -> complex64 {
|
||||
switch re, im := real(x), imag(x); {
|
||||
case math.is_inf(re, 0):
|
||||
switch {
|
||||
case re > 0 && im == 0:
|
||||
return x
|
||||
case math.is_inf(im, 0) || math.is_nan(im):
|
||||
if re < 0 {
|
||||
return complex(0, math.copy_sign(0, im))
|
||||
} else {
|
||||
return complex(math.inf_f64(1.0), math.nan_f64())
|
||||
}
|
||||
}
|
||||
case math.is_nan(re):
|
||||
if im == 0 {
|
||||
return complex(math.nan_f32(), im)
|
||||
}
|
||||
}
|
||||
r := math.exp(real(x))
|
||||
s, c := math.sincos(imag(x))
|
||||
return complex(r*c, r*s)
|
||||
}
|
||||
exp_complex128 :: proc "contextless" (x: complex128) -> complex128 {
|
||||
switch re, im := real(x), imag(x); {
|
||||
case math.is_inf(re, 0):
|
||||
switch {
|
||||
case re > 0 && im == 0:
|
||||
return x
|
||||
case math.is_inf(im, 0) || math.is_nan(im):
|
||||
if re < 0 {
|
||||
return complex(0, math.copy_sign(0, im))
|
||||
} else {
|
||||
return complex(math.inf_f64(1.0), math.nan_f64())
|
||||
}
|
||||
}
|
||||
case math.is_nan(re):
|
||||
if im == 0 {
|
||||
return complex(math.nan_f64(), im)
|
||||
}
|
||||
}
|
||||
r := math.exp(real(x))
|
||||
s, c := math.sincos(imag(x))
|
||||
return complex(r*c, r*s)
|
||||
}
|
||||
|
||||
|
||||
pow_complex32 :: proc "contextless" (x, y: complex32) -> complex32 {
|
||||
if x == 0 { // Guaranteed also true for x == -0.
|
||||
if is_nan(y) {
|
||||
return nan_complex32()
|
||||
}
|
||||
r, i := real(y), imag(y)
|
||||
switch {
|
||||
case r == 0:
|
||||
return 1
|
||||
case r < 0:
|
||||
if i == 0 {
|
||||
return complex(math.inf_f16(1), 0)
|
||||
}
|
||||
return inf_complex32()
|
||||
case r > 0:
|
||||
return 0
|
||||
}
|
||||
unreachable()
|
||||
}
|
||||
modulus := abs(x)
|
||||
if modulus == 0 {
|
||||
return complex(0, 0)
|
||||
}
|
||||
r := math.pow(modulus, real(y))
|
||||
arg := phase(x)
|
||||
theta := real(y) * arg
|
||||
if imag(y) != 0 {
|
||||
r *= math.exp(-imag(y) * arg)
|
||||
theta += imag(y) * math.ln(modulus)
|
||||
}
|
||||
s, c := math.sincos(theta)
|
||||
return complex(r*c, r*s)
|
||||
}
|
||||
pow_complex64 :: proc "contextless" (x, y: complex64) -> complex64 {
|
||||
if x == 0 { // Guaranteed also true for x == -0.
|
||||
if is_nan(y) {
|
||||
return nan_complex64()
|
||||
}
|
||||
r, i := real(y), imag(y)
|
||||
switch {
|
||||
case r == 0:
|
||||
return 1
|
||||
case r < 0:
|
||||
if i == 0 {
|
||||
return complex(math.inf_f32(1), 0)
|
||||
}
|
||||
return inf_complex64()
|
||||
case r > 0:
|
||||
return 0
|
||||
}
|
||||
unreachable()
|
||||
}
|
||||
modulus := abs(x)
|
||||
if modulus == 0 {
|
||||
return complex(0, 0)
|
||||
}
|
||||
r := math.pow(modulus, real(y))
|
||||
arg := phase(x)
|
||||
theta := real(y) * arg
|
||||
if imag(y) != 0 {
|
||||
r *= math.exp(-imag(y) * arg)
|
||||
theta += imag(y) * math.ln(modulus)
|
||||
}
|
||||
s, c := math.sincos(theta)
|
||||
return complex(r*c, r*s)
|
||||
}
|
||||
pow_complex128 :: proc "contextless" (x, y: complex128) -> complex128 {
|
||||
if x == 0 { // Guaranteed also true for x == -0.
|
||||
if is_nan(y) {
|
||||
return nan_complex128()
|
||||
}
|
||||
r, i := real(y), imag(y)
|
||||
switch {
|
||||
case r == 0:
|
||||
return 1
|
||||
case r < 0:
|
||||
if i == 0 {
|
||||
return complex(math.inf_f64(1), 0)
|
||||
}
|
||||
return inf_complex128()
|
||||
case r > 0:
|
||||
return 0
|
||||
}
|
||||
unreachable()
|
||||
}
|
||||
modulus := abs(x)
|
||||
if modulus == 0 {
|
||||
return complex(0, 0)
|
||||
}
|
||||
r := math.pow(modulus, real(y))
|
||||
arg := phase(x)
|
||||
theta := real(y) * arg
|
||||
if imag(y) != 0 {
|
||||
r *= math.exp(-imag(y) * arg)
|
||||
theta += imag(y) * math.ln(modulus)
|
||||
}
|
||||
s, c := math.sincos(theta)
|
||||
return complex(r*c, r*s)
|
||||
}
|
||||
|
||||
|
||||
|
||||
log10_complex32 :: proc "contextless" (x: complex32) -> complex32 {
|
||||
return math.LN10*ln(x)
|
||||
}
|
||||
log10_complex64 :: proc "contextless" (x: complex64) -> complex64 {
|
||||
return math.LN10*ln(x)
|
||||
}
|
||||
log10_complex128 :: proc "contextless" (x: complex128) -> complex128 {
|
||||
return math.LN10*ln(x)
|
||||
}
|
||||
|
||||
|
||||
phase_complex32 :: proc "contextless" (x: complex32) -> f16 {
|
||||
return math.atan2(imag(x), real(x))
|
||||
}
|
||||
phase_complex64 :: proc "contextless" (x: complex64) -> f32 {
|
||||
return math.atan2(imag(x), real(x))
|
||||
}
|
||||
phase_complex128 :: proc "contextless" (x: complex128) -> f64 {
|
||||
return math.atan2(imag(x), real(x))
|
||||
}
|
||||
|
||||
|
||||
rect_complex32 :: proc "contextless" (r, θ: f16) -> complex32 {
|
||||
s, c := math.sincos(θ)
|
||||
return complex(r*c, r*s)
|
||||
}
|
||||
rect_complex64 :: proc "contextless" (r, θ: f32) -> complex64 {
|
||||
s, c := math.sincos(θ)
|
||||
return complex(r*c, r*s)
|
||||
}
|
||||
rect_complex128 :: proc "contextless" (r, θ: f64) -> complex128 {
|
||||
s, c := math.sincos(θ)
|
||||
return complex(r*c, r*s)
|
||||
}
|
||||
|
||||
polar_complex32 :: proc "contextless" (x: complex32) -> (r, θ: f16) {
|
||||
return abs(x), phase(x)
|
||||
}
|
||||
polar_complex64 :: proc "contextless" (x: complex64) -> (r, θ: f32) {
|
||||
return abs(x), phase(x)
|
||||
}
|
||||
polar_complex128 :: proc "contextless" (x: complex128) -> (r, θ: f64) {
|
||||
return abs(x), phase(x)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
nan_complex32 :: proc "contextless" () -> complex32 {
|
||||
return complex(math.nan_f16(), math.nan_f16())
|
||||
}
|
||||
nan_complex64 :: proc "contextless" () -> complex64 {
|
||||
return complex(math.nan_f32(), math.nan_f32())
|
||||
}
|
||||
nan_complex128 :: proc "contextless" () -> complex128 {
|
||||
return complex(math.nan_f64(), math.nan_f64())
|
||||
}
|
||||
|
||||
|
||||
inf_complex32 :: proc "contextless" () -> complex32 {
|
||||
inf := math.inf_f16(1)
|
||||
return complex(inf, inf)
|
||||
}
|
||||
inf_complex64 :: proc "contextless" () -> complex64 {
|
||||
inf := math.inf_f32(1)
|
||||
return complex(inf, inf)
|
||||
}
|
||||
inf_complex128 :: proc "contextless" () -> complex128 {
|
||||
inf := math.inf_f64(1)
|
||||
return complex(inf, inf)
|
||||
}
|
||||
|
||||
|
||||
is_inf_complex32 :: proc "contextless" (x: complex32) -> bool {
|
||||
return math.is_inf(real(x), 0) || math.is_inf(imag(x), 0)
|
||||
}
|
||||
is_inf_complex64 :: proc "contextless" (x: complex64) -> bool {
|
||||
return math.is_inf(real(x), 0) || math.is_inf(imag(x), 0)
|
||||
}
|
||||
is_inf_complex128 :: proc "contextless" (x: complex128) -> bool {
|
||||
return math.is_inf(real(x), 0) || math.is_inf(imag(x), 0)
|
||||
}
|
||||
|
||||
|
||||
is_nan_complex32 :: proc "contextless" (x: complex32) -> bool {
|
||||
if math.is_inf(real(x), 0) || math.is_inf(imag(x), 0) {
|
||||
return false
|
||||
}
|
||||
return math.is_nan(real(x)) || math.is_nan(imag(x))
|
||||
}
|
||||
is_nan_complex64 :: proc "contextless" (x: complex64) -> bool {
|
||||
if math.is_inf(real(x), 0) || math.is_inf(imag(x), 0) {
|
||||
return false
|
||||
}
|
||||
return math.is_nan(real(x)) || math.is_nan(imag(x))
|
||||
}
|
||||
is_nan_complex128 :: proc "contextless" (x: complex128) -> bool {
|
||||
if math.is_inf(real(x), 0) || math.is_inf(imag(x), 0) {
|
||||
return false
|
||||
}
|
||||
return math.is_nan(real(x)) || math.is_nan(imag(x))
|
||||
}
|
||||
@@ -0,0 +1,273 @@
|
||||
package math_cmplx
|
||||
|
||||
import "core:builtin"
|
||||
import "core:math"
|
||||
|
||||
// The original C code, the long comment, and the constants
|
||||
// below are from http://netlib.sandia.gov/cephes/c9x-complex/clog.c.
|
||||
// The go code is a simplified version of the original C.
|
||||
//
|
||||
// Cephes Math Library Release 2.8: June, 2000
|
||||
// Copyright 1984, 1987, 1989, 1992, 2000 by Stephen L. Moshier
|
||||
//
|
||||
// The readme file at http://netlib.sandia.gov/cephes/ says:
|
||||
// Some software in this archive may be from the book _Methods and
|
||||
// Programs for Mathematical Functions_ (Prentice-Hall or Simon & Schuster
|
||||
// International, 1989) or from the Cephes Mathematical Library, a
|
||||
// commercial product. In either event, it is copyrighted by the author.
|
||||
// What you see here may be used freely but it comes with no support or
|
||||
// guarantee.
|
||||
//
|
||||
// The two known misprints in the book are repaired here in the
|
||||
// source listings for the gamma function and the incomplete beta
|
||||
// integral.
|
||||
//
|
||||
// Stephen L. Moshier
|
||||
// moshier@na-net.ornl.gov
|
||||
|
||||
acos :: proc{
|
||||
acos_complex32,
|
||||
acos_complex64,
|
||||
acos_complex128,
|
||||
}
|
||||
acosh :: proc{
|
||||
acosh_complex32,
|
||||
acosh_complex64,
|
||||
acosh_complex128,
|
||||
}
|
||||
|
||||
asin :: proc{
|
||||
asin_complex32,
|
||||
asin_complex64,
|
||||
asin_complex128,
|
||||
}
|
||||
asinh :: proc{
|
||||
asinh_complex32,
|
||||
asinh_complex64,
|
||||
asinh_complex128,
|
||||
}
|
||||
|
||||
atan :: proc{
|
||||
atan_complex32,
|
||||
atan_complex64,
|
||||
atan_complex128,
|
||||
}
|
||||
|
||||
atanh :: proc{
|
||||
atanh_complex32,
|
||||
atanh_complex64,
|
||||
atanh_complex128,
|
||||
}
|
||||
|
||||
|
||||
acos_complex32 :: proc "contextless" (x: complex32) -> complex32 {
|
||||
w := asin(x)
|
||||
return complex(math.PI/2 - real(w), -imag(w))
|
||||
}
|
||||
acos_complex64 :: proc "contextless" (x: complex64) -> complex64 {
|
||||
w := asin(x)
|
||||
return complex(math.PI/2 - real(w), -imag(w))
|
||||
}
|
||||
acos_complex128 :: proc "contextless" (x: complex128) -> complex128 {
|
||||
w := asin(x)
|
||||
return complex(math.PI/2 - real(w), -imag(w))
|
||||
}
|
||||
|
||||
|
||||
acosh_complex32 :: proc "contextless" (x: complex32) -> complex32 {
|
||||
if x == 0 {
|
||||
return complex(0, math.copy_sign(math.PI/2, imag(x)))
|
||||
}
|
||||
w := acos(x)
|
||||
if imag(w) <= 0 {
|
||||
return complex(-imag(w), real(w))
|
||||
}
|
||||
return complex(imag(w), -real(w))
|
||||
}
|
||||
acosh_complex64 :: proc "contextless" (x: complex64) -> complex64 {
|
||||
if x == 0 {
|
||||
return complex(0, math.copy_sign(math.PI/2, imag(x)))
|
||||
}
|
||||
w := acos(x)
|
||||
if imag(w) <= 0 {
|
||||
return complex(-imag(w), real(w))
|
||||
}
|
||||
return complex(imag(w), -real(w))
|
||||
}
|
||||
acosh_complex128 :: proc "contextless" (x: complex128) -> complex128 {
|
||||
if x == 0 {
|
||||
return complex(0, math.copy_sign(math.PI/2, imag(x)))
|
||||
}
|
||||
w := acos(x)
|
||||
if imag(w) <= 0 {
|
||||
return complex(-imag(w), real(w))
|
||||
}
|
||||
return complex(imag(w), -real(w))
|
||||
}
|
||||
|
||||
asin_complex32 :: proc "contextless" (x: complex32) -> complex32 {
|
||||
return complex32(asin_complex128(complex128(x)))
|
||||
}
|
||||
asin_complex64 :: proc "contextless" (x: complex64) -> complex64 {
|
||||
return complex64(asin_complex128(complex128(x)))
|
||||
}
|
||||
asin_complex128 :: proc "contextless" (x: complex128) -> complex128 {
|
||||
switch re, im := real(x), imag(x); {
|
||||
case im == 0 && abs(re) <= 1:
|
||||
return complex(math.asin(re), im)
|
||||
case re == 0 && abs(im) <= 1:
|
||||
return complex(re, math.asinh(im))
|
||||
case math.is_nan(im):
|
||||
switch {
|
||||
case re == 0:
|
||||
return complex(re, math.nan_f64())
|
||||
case math.is_inf(re, 0):
|
||||
return complex(math.nan_f64(), re)
|
||||
case:
|
||||
return nan_complex128()
|
||||
}
|
||||
case math.is_inf(im, 0):
|
||||
switch {
|
||||
case math.is_nan(re):
|
||||
return x
|
||||
case math.is_inf(re, 0):
|
||||
return complex(math.copy_sign(math.PI/4, re), im)
|
||||
case:
|
||||
return complex(math.copy_sign(0, re), im)
|
||||
}
|
||||
case math.is_inf(re, 0):
|
||||
return complex(math.copy_sign(math.PI/2, re), math.copy_sign(re, im))
|
||||
}
|
||||
ct := complex(-imag(x), real(x)) // i * x
|
||||
xx := x * x
|
||||
x1 := complex(1-real(xx), -imag(xx)) // 1 - x*x
|
||||
x2 := sqrt(x1) // x2 = sqrt(1 - x*x)
|
||||
w := ln(ct + x2)
|
||||
return complex(imag(w), -real(w)) // -i * w
|
||||
}
|
||||
|
||||
asinh_complex32 :: proc "contextless" (x: complex32) -> complex32 {
|
||||
return complex32(asinh_complex128(complex128(x)))
|
||||
}
|
||||
asinh_complex64 :: proc "contextless" (x: complex64) -> complex64 {
|
||||
return complex64(asinh_complex128(complex128(x)))
|
||||
}
|
||||
asinh_complex128 :: proc "contextless" (x: complex128) -> complex128 {
|
||||
switch re, im := real(x), imag(x); {
|
||||
case im == 0 && abs(re) <= 1:
|
||||
return complex(math.asinh(re), im)
|
||||
case re == 0 && abs(im) <= 1:
|
||||
return complex(re, math.asin(im))
|
||||
case math.is_inf(re, 0):
|
||||
switch {
|
||||
case math.is_inf(im, 0):
|
||||
return complex(re, math.copy_sign(math.PI/4, im))
|
||||
case math.is_nan(im):
|
||||
return x
|
||||
case:
|
||||
return complex(re, math.copy_sign(0.0, im))
|
||||
}
|
||||
case math.is_nan(re):
|
||||
switch {
|
||||
case im == 0:
|
||||
return x
|
||||
case math.is_inf(im, 0):
|
||||
return complex(im, re)
|
||||
case:
|
||||
return nan_complex128()
|
||||
}
|
||||
case math.is_inf(im, 0):
|
||||
return complex(math.copy_sign(im, re), math.copy_sign(math.PI/2, im))
|
||||
}
|
||||
xx := x * x
|
||||
x1 := complex(1+real(xx), imag(xx)) // 1 + x*x
|
||||
return ln(x + sqrt(x1)) // log(x + sqrt(1 + x*x))
|
||||
}
|
||||
|
||||
|
||||
atan_complex32 :: proc "contextless" (x: complex32) -> complex32 {
|
||||
return complex32(atan_complex128(complex128(x)))
|
||||
}
|
||||
atan_complex64 :: proc "contextless" (x: complex64) -> complex64 {
|
||||
return complex64(atan_complex128(complex128(x)))
|
||||
}
|
||||
atan_complex128 :: proc "contextless" (x: complex128) -> complex128 {
|
||||
// Complex circular arc tangent
|
||||
//
|
||||
// DESCRIPTION:
|
||||
//
|
||||
// If
|
||||
// z = x + iy,
|
||||
//
|
||||
// then
|
||||
// 1 ( 2x )
|
||||
// Re w = - arctan(-----------) + k PI
|
||||
// 2 ( 2 2)
|
||||
// (1 - x - y )
|
||||
//
|
||||
// ( 2 2)
|
||||
// 1 (x + (y+1) )
|
||||
// Im w = - log(------------)
|
||||
// 4 ( 2 2)
|
||||
// (x + (y-1) )
|
||||
//
|
||||
// Where k is an arbitrary integer.
|
||||
//
|
||||
// catan(z) = -i catanh(iz).
|
||||
//
|
||||
// ACCURACY:
|
||||
//
|
||||
// Relative error:
|
||||
// arithmetic domain # trials peak rms
|
||||
// DEC -10,+10 5900 1.3e-16 7.8e-18
|
||||
// IEEE -10,+10 30000 2.3e-15 8.5e-17
|
||||
// The check catan( ctan(z) ) = z, with |x| and |y| < PI/2,
|
||||
// had peak relative error 1.5e-16, rms relative error
|
||||
// 2.9e-17. See also clog().
|
||||
|
||||
switch re, im := real(x), imag(x); {
|
||||
case im == 0:
|
||||
return complex(math.atan(re), im)
|
||||
case re == 0 && abs(im) <= 1:
|
||||
return complex(re, math.atanh(im))
|
||||
case math.is_inf(im, 0) || math.is_inf(re, 0):
|
||||
if math.is_nan(re) {
|
||||
return complex(math.nan_f64(), math.copy_sign(0, im))
|
||||
}
|
||||
return complex(math.copy_sign(math.PI/2, re), math.copy_sign(0, im))
|
||||
case math.is_nan(re) || math.is_nan(im):
|
||||
return nan_complex128()
|
||||
}
|
||||
x2 := real(x) * real(x)
|
||||
a := 1 - x2 - imag(x)*imag(x)
|
||||
if a == 0 {
|
||||
return nan_complex128()
|
||||
}
|
||||
t := 0.5 * math.atan2(2*real(x), a)
|
||||
w := _reduce_pi_f64(t)
|
||||
|
||||
t = imag(x) - 1
|
||||
b := x2 + t*t
|
||||
if b == 0 {
|
||||
return nan_complex128()
|
||||
}
|
||||
t = imag(x) + 1
|
||||
c := (x2 + t*t) / b
|
||||
return complex(w, 0.25*math.ln(c))
|
||||
}
|
||||
|
||||
atanh_complex32 :: proc "contextless" (x: complex32) -> complex32 {
|
||||
z := complex(-imag(x), real(x)) // z = i * x
|
||||
z = atan(z)
|
||||
return complex(imag(z), -real(z)) // z = -i * z
|
||||
}
|
||||
atanh_complex64 :: proc "contextless" (x: complex64) -> complex64 {
|
||||
z := complex(-imag(x), real(x)) // z = i * x
|
||||
z = atan(z)
|
||||
return complex(imag(z), -real(z)) // z = -i * z
|
||||
}
|
||||
atanh_complex128 :: proc "contextless" (x: complex128) -> complex128 {
|
||||
z := complex(-imag(x), real(x)) // z = i * x
|
||||
z = atan(z)
|
||||
return complex(imag(z), -real(z)) // z = -i * z
|
||||
}
|
||||
@@ -0,0 +1,409 @@
|
||||
package math_cmplx
|
||||
|
||||
import "core:math"
|
||||
import "core:math/bits"
|
||||
|
||||
// The original C code, the long comment, and the constants
|
||||
// below are from http://netlib.sandia.gov/cephes/c9x-complex/clog.c.
|
||||
// The go code is a simplified version of the original C.
|
||||
//
|
||||
// Cephes Math Library Release 2.8: June, 2000
|
||||
// Copyright 1984, 1987, 1989, 1992, 2000 by Stephen L. Moshier
|
||||
//
|
||||
// The readme file at http://netlib.sandia.gov/cephes/ says:
|
||||
// Some software in this archive may be from the book _Methods and
|
||||
// Programs for Mathematical Functions_ (Prentice-Hall or Simon & Schuster
|
||||
// International, 1989) or from the Cephes Mathematical Library, a
|
||||
// commercial product. In either event, it is copyrighted by the author.
|
||||
// What you see here may be used freely but it comes with no support or
|
||||
// guarantee.
|
||||
//
|
||||
// The two known misprints in the book are repaired here in the
|
||||
// source listings for the gamma function and the incomplete beta
|
||||
// integral.
|
||||
//
|
||||
// Stephen L. Moshier
|
||||
// moshier@na-net.ornl.gov
|
||||
|
||||
sin_complex128 :: proc "contextless" (x: complex128) -> complex128 {
|
||||
// Complex circular sine
|
||||
//
|
||||
// DESCRIPTION:
|
||||
//
|
||||
// If
|
||||
// z = x + iy,
|
||||
//
|
||||
// then
|
||||
//
|
||||
// w = sin x cosh y + i cos x sinh y.
|
||||
//
|
||||
// csin(z) = -i csinh(iz).
|
||||
//
|
||||
// ACCURACY:
|
||||
//
|
||||
// Relative error:
|
||||
// arithmetic domain # trials peak rms
|
||||
// DEC -10,+10 8400 5.3e-17 1.3e-17
|
||||
// IEEE -10,+10 30000 3.8e-16 1.0e-16
|
||||
// Also tested by csin(casin(z)) = z.
|
||||
|
||||
switch re, im := real(x), imag(x); {
|
||||
case im == 0 && (math.is_inf(re, 0) || math.is_nan(re)):
|
||||
return complex(math.nan_f64(), im)
|
||||
case math.is_inf(im, 0):
|
||||
switch {
|
||||
case re == 0:
|
||||
return x
|
||||
case math.is_inf(re, 0) || math.is_nan(re):
|
||||
return complex(math.nan_f64(), im)
|
||||
}
|
||||
case re == 0 && math.is_nan(im):
|
||||
return x
|
||||
}
|
||||
s, c := math.sincos(real(x))
|
||||
sh, ch := _sinhcosh_f64(imag(x))
|
||||
return complex(s*ch, c*sh)
|
||||
}
|
||||
|
||||
cos_complex128 :: proc "contextless" (x: complex128) -> complex128 {
|
||||
// Complex circular cosine
|
||||
//
|
||||
// DESCRIPTION:
|
||||
//
|
||||
// If
|
||||
// z = x + iy,
|
||||
//
|
||||
// then
|
||||
//
|
||||
// w = cos x cosh y - i sin x sinh y.
|
||||
//
|
||||
// ACCURACY:
|
||||
//
|
||||
// Relative error:
|
||||
// arithmetic domain # trials peak rms
|
||||
// DEC -10,+10 8400 4.5e-17 1.3e-17
|
||||
// IEEE -10,+10 30000 3.8e-16 1.0e-16
|
||||
|
||||
switch re, im := real(x), imag(x); {
|
||||
case im == 0 && (math.is_inf(re, 0) || math.is_nan(re)):
|
||||
return complex(math.nan_f64(), -im*math.copy_sign(0, re))
|
||||
case math.is_inf(im, 0):
|
||||
switch {
|
||||
case re == 0:
|
||||
return complex(math.inf_f64(1), -re*math.copy_sign(0, im))
|
||||
case math.is_inf(re, 0) || math.is_nan(re):
|
||||
return complex(math.inf_f64(1), math.nan_f64())
|
||||
}
|
||||
case re == 0 && math.is_nan(im):
|
||||
return complex(math.nan_f64(), 0)
|
||||
}
|
||||
s, c := math.sincos(real(x))
|
||||
sh, ch := _sinhcosh_f64(imag(x))
|
||||
return complex(c*ch, -s*sh)
|
||||
}
|
||||
|
||||
sinh_complex128 :: proc "contextless" (x: complex128) -> complex128 {
|
||||
// Complex hyperbolic sine
|
||||
//
|
||||
// DESCRIPTION:
|
||||
//
|
||||
// csinh z = (cexp(z) - cexp(-z))/2
|
||||
// = sinh x * cos y + i cosh x * sin y .
|
||||
//
|
||||
// ACCURACY:
|
||||
//
|
||||
// Relative error:
|
||||
// arithmetic domain # trials peak rms
|
||||
// IEEE -10,+10 30000 3.1e-16 8.2e-17
|
||||
|
||||
switch re, im := real(x), imag(x); {
|
||||
case re == 0 && (math.is_inf(im, 0) || math.is_nan(im)):
|
||||
return complex(re, math.nan_f64())
|
||||
case math.is_inf(re, 0):
|
||||
switch {
|
||||
case im == 0:
|
||||
return complex(re, im)
|
||||
case math.is_inf(im, 0) || math.is_nan(im):
|
||||
return complex(re, math.nan_f64())
|
||||
}
|
||||
case im == 0 && math.is_nan(re):
|
||||
return complex(math.nan_f64(), im)
|
||||
}
|
||||
s, c := math.sincos(imag(x))
|
||||
sh, ch := _sinhcosh_f64(real(x))
|
||||
return complex(c*sh, s*ch)
|
||||
}
|
||||
|
||||
cosh_complex128 :: proc "contextless" (x: complex128) -> complex128 {
|
||||
// Complex hyperbolic cosine
|
||||
//
|
||||
// DESCRIPTION:
|
||||
//
|
||||
// ccosh(z) = cosh x cos y + i sinh x sin y .
|
||||
//
|
||||
// ACCURACY:
|
||||
//
|
||||
// Relative error:
|
||||
// arithmetic domain # trials peak rms
|
||||
// IEEE -10,+10 30000 2.9e-16 8.1e-17
|
||||
|
||||
switch re, im := real(x), imag(x); {
|
||||
case re == 0 && (math.is_inf(im, 0) || math.is_nan(im)):
|
||||
return complex(math.nan_f64(), re*math.copy_sign(0, im))
|
||||
case math.is_inf(re, 0):
|
||||
switch {
|
||||
case im == 0:
|
||||
return complex(math.inf_f64(1), im*math.copy_sign(0, re))
|
||||
case math.is_inf(im, 0) || math.is_nan(im):
|
||||
return complex(math.inf_f64(1), math.nan_f64())
|
||||
}
|
||||
case im == 0 && math.is_nan(re):
|
||||
return complex(math.nan_f64(), im)
|
||||
}
|
||||
s, c := math.sincos(imag(x))
|
||||
sh, ch := _sinhcosh_f64(real(x))
|
||||
return complex(c*ch, s*sh)
|
||||
}
|
||||
|
||||
tan_complex128 :: proc "contextless" (x: complex128) -> complex128 {
|
||||
// Complex circular tangent
|
||||
//
|
||||
// DESCRIPTION:
|
||||
//
|
||||
// If
|
||||
// z = x + iy,
|
||||
//
|
||||
// then
|
||||
//
|
||||
// sin 2x + i sinh 2y
|
||||
// w = --------------------.
|
||||
// cos 2x + cosh 2y
|
||||
//
|
||||
// On the real axis the denominator is zero at odd multiples
|
||||
// of PI/2. The denominator is evaluated by its Taylor
|
||||
// series near these points.
|
||||
//
|
||||
// ctan(z) = -i ctanh(iz).
|
||||
//
|
||||
// ACCURACY:
|
||||
//
|
||||
// Relative error:
|
||||
// arithmetic domain # trials peak rms
|
||||
// DEC -10,+10 5200 7.1e-17 1.6e-17
|
||||
// IEEE -10,+10 30000 7.2e-16 1.2e-16
|
||||
// Also tested by ctan * ccot = 1 and catan(ctan(z)) = z.
|
||||
|
||||
switch re, im := real(x), imag(x); {
|
||||
case math.is_inf(im, 0):
|
||||
switch {
|
||||
case math.is_inf(re, 0) || math.is_nan(re):
|
||||
return complex(math.copy_sign(0, re), math.copy_sign(1, im))
|
||||
}
|
||||
return complex(math.copy_sign(0, math.sin(2*re)), math.copy_sign(1, im))
|
||||
case re == 0 && math.is_nan(im):
|
||||
return x
|
||||
}
|
||||
d := math.cos(2*real(x)) + math.cosh(2*imag(x))
|
||||
if abs(d) < 0.25 {
|
||||
d = _tan_series_f64(x)
|
||||
}
|
||||
if d == 0 {
|
||||
return inf_complex128()
|
||||
}
|
||||
return complex(math.sin(2*real(x))/d, math.sinh(2*imag(x))/d)
|
||||
}
|
||||
|
||||
tanh_complex128 :: proc "contextless" (x: complex128) -> complex128 {
|
||||
switch re, im := real(x), imag(x); {
|
||||
case math.is_inf(re, 0):
|
||||
switch {
|
||||
case math.is_inf(im, 0) || math.is_nan(im):
|
||||
return complex(math.copy_sign(1, re), math.copy_sign(0, im))
|
||||
}
|
||||
return complex(math.copy_sign(1, re), math.copy_sign(0, math.sin(2*im)))
|
||||
case im == 0 && math.is_nan(re):
|
||||
return x
|
||||
}
|
||||
d := math.cosh(2*real(x)) + math.cos(2*imag(x))
|
||||
if d == 0 {
|
||||
return inf_complex128()
|
||||
}
|
||||
return complex(math.sinh(2*real(x))/d, math.sin(2*imag(x))/d)
|
||||
}
|
||||
|
||||
cot_complex128 :: proc "contextless" (x: complex128) -> complex128 {
|
||||
d := math.cosh(2*imag(x)) - math.cos(2*real(x))
|
||||
if abs(d) < 0.25 {
|
||||
d = _tan_series_f64(x)
|
||||
}
|
||||
if d == 0 {
|
||||
return inf_complex128()
|
||||
}
|
||||
return complex(math.sin(2*real(x))/d, -math.sinh(2*imag(x))/d)
|
||||
}
|
||||
|
||||
|
||||
@(private="file")
|
||||
_sinhcosh_f64 :: proc "contextless" (x: f64) -> (sh, ch: f64) {
|
||||
if abs(x) <= 0.5 {
|
||||
return math.sinh(x), math.cosh(x)
|
||||
}
|
||||
e := math.exp(x)
|
||||
ei := 0.5 / e
|
||||
e *= 0.5
|
||||
return e - ei, e + ei
|
||||
}
|
||||
|
||||
|
||||
// taylor series of cosh(2y) - cos(2x)
|
||||
@(private)
|
||||
_tan_series_f64 :: proc "contextless" (z: complex128) -> f64 {
|
||||
MACH_EPSILON :: 1.0 / (1 << 53)
|
||||
|
||||
x := abs(2 * real(z))
|
||||
y := abs(2 * imag(z))
|
||||
x = _reduce_pi_f64(x)
|
||||
x, y = x * x, y * y
|
||||
x2, y2 := 1.0, 1.0
|
||||
f, rn, d := 1.0, 0.0, 0.0
|
||||
|
||||
for {
|
||||
rn += 1
|
||||
f *= rn
|
||||
rn += 1
|
||||
f *= rn
|
||||
x2 *= x
|
||||
y2 *= y
|
||||
t := y2 + x2
|
||||
t /= f
|
||||
d += t
|
||||
|
||||
rn += 1
|
||||
f *= rn
|
||||
rn += 1
|
||||
f *= rn
|
||||
x2 *= x
|
||||
y2 *= y
|
||||
t = y2 - x2
|
||||
t /= f
|
||||
d += t
|
||||
if !(abs(t/d) > MACH_EPSILON) { // don't use <=, because of floating point nonsense and NaN
|
||||
break
|
||||
}
|
||||
}
|
||||
return d
|
||||
}
|
||||
|
||||
// _reduce_pi_f64 reduces the input argument x to the range (-PI/2, PI/2].
|
||||
// x must be greater than or equal to 0. For small arguments it
|
||||
// uses Cody-Waite reduction in 3 f64 parts based on:
|
||||
// "Elementary Function Evaluation: Algorithms and Implementation"
|
||||
// Jean-Michel Muller, 1997.
|
||||
// For very large arguments it uses Payne-Hanek range reduction based on:
|
||||
// "ARGUMENT REDUCTION FOR HUGE ARGUMENTS: Good to the Last Bit"
|
||||
@(private)
|
||||
_reduce_pi_f64 :: proc "contextless" (x: f64) -> f64 #no_bounds_check {
|
||||
x := x
|
||||
|
||||
// REDUCE_THRESHOLD is the maximum value of x where the reduction using
|
||||
// Cody-Waite reduction still gives accurate results. This threshold
|
||||
// is set by t*PIn being representable as a f64 without error
|
||||
// where t is given by t = floor(x * (1 / PI)) and PIn are the leading partial
|
||||
// terms of PI. Since the leading terms, PI1 and PI2 below, have 30 and 32
|
||||
// trailing zero bits respectively, t should have less than 30 significant bits.
|
||||
// t < 1<<30 -> floor(x*(1/PI)+0.5) < 1<<30 -> x < (1<<30-1) * PI - 0.5
|
||||
// So, conservatively we can take x < 1<<30.
|
||||
REDUCE_THRESHOLD :: f64(1 << 30)
|
||||
|
||||
if abs(x) < REDUCE_THRESHOLD {
|
||||
// Use Cody-Waite reduction in three parts.
|
||||
// PI1, PI2 and PI3 comprise an extended precision value of PI
|
||||
// such that PI ~= PI1 + PI2 + PI3. The parts are chosen so
|
||||
// that PI1 and PI2 have an approximately equal number of trailing
|
||||
// zero bits. This ensures that t*PI1 and t*PI2 are exact for
|
||||
// large integer values of t. The full precision PI3 ensures the
|
||||
// approximation of PI is accurate to 102 bits to handle cancellation
|
||||
// during subtraction.
|
||||
PI1 :: 0h400921fb40000000 // 3.141592502593994
|
||||
PI2 :: 0h3e84442d00000000 // 1.5099578831723193e-07
|
||||
PI3 :: 0h3d08469898cc5170 // 1.0780605716316238e-14
|
||||
|
||||
t := x / math.PI
|
||||
t += 0.5
|
||||
t = f64(i64(t)) // i64(t) = the multiple
|
||||
return ((x - t*PI1) - t*PI2) - t*PI3
|
||||
}
|
||||
// Must apply Payne-Hanek range reduction
|
||||
MASK :: 0x7FF
|
||||
SHIFT :: 64 - 11 - 1
|
||||
BIAS :: 1023
|
||||
FRAC_MASK :: 1<<SHIFT - 1
|
||||
|
||||
// Extract out the integer and exponent such that,
|
||||
// x = ix * 2 ** exp.
|
||||
ix := transmute(u64)(x)
|
||||
exp := int(ix>>SHIFT&MASK) - BIAS - SHIFT
|
||||
ix &= FRAC_MASK
|
||||
ix |= 1 << SHIFT
|
||||
|
||||
// bdpi is the binary digits of 1/PI as a u64 array,
|
||||
// that is, 1/PI = SUM bdpi[i]*2^(-64*i).
|
||||
// 19 64-bit digits give 1216 bits of precision
|
||||
// to handle the largest possible f64 exponent.
|
||||
@static bdpi := [?]u64{
|
||||
0x0000000000000000,
|
||||
0x517cc1b727220a94,
|
||||
0xfe13abe8fa9a6ee0,
|
||||
0x6db14acc9e21c820,
|
||||
0xff28b1d5ef5de2b0,
|
||||
0xdb92371d2126e970,
|
||||
0x0324977504e8c90e,
|
||||
0x7f0ef58e5894d39f,
|
||||
0x74411afa975da242,
|
||||
0x74ce38135a2fbf20,
|
||||
0x9cc8eb1cc1a99cfa,
|
||||
0x4e422fc5defc941d,
|
||||
0x8ffc4bffef02cc07,
|
||||
0xf79788c5ad05368f,
|
||||
0xb69b3f6793e584db,
|
||||
0xa7a31fb34f2ff516,
|
||||
0xba93dd63f5f2f8bd,
|
||||
0x9e839cfbc5294975,
|
||||
0x35fdafd88fc6ae84,
|
||||
0x2b0198237e3db5d5,
|
||||
}
|
||||
|
||||
// Use the exponent to extract the 3 appropriate u64 digits from bdpi,
|
||||
// B ~ (z0, z1, z2), such that the product leading digit has the exponent -64.
|
||||
// Note, exp >= 50 since x >= REDUCE_THRESHOLD and exp < 971 for maximum f64.
|
||||
digit, bitshift := uint(exp+64)/64, uint(exp+64)%64
|
||||
z0 := (bdpi[digit] << bitshift) | (bdpi[digit+1] >> (64 - bitshift))
|
||||
z1 := (bdpi[digit+1] << bitshift) | (bdpi[digit+2] >> (64 - bitshift))
|
||||
z2 := (bdpi[digit+2] << bitshift) | (bdpi[digit+3] >> (64 - bitshift))
|
||||
|
||||
// Multiply mantissa by the digits and extract the upper two digits (hi, lo).
|
||||
z2hi, _ := bits.mul(z2, ix)
|
||||
z1hi, z1lo := bits.mul(z1, ix)
|
||||
z0lo := z0 * ix
|
||||
lo, c := bits.add(z1lo, z2hi, 0)
|
||||
hi, _ := bits.add(z0lo, z1hi, c)
|
||||
|
||||
// Find the magnitude of the fraction.
|
||||
lz := uint(bits.leading_zeros(hi))
|
||||
e := u64(BIAS - (lz + 1))
|
||||
|
||||
// Clear implicit mantissa bit and shift into place.
|
||||
hi = (hi << (lz + 1)) | (lo >> (64 - (lz + 1)))
|
||||
hi >>= 64 - SHIFT
|
||||
|
||||
// Include the exponent and convert to a float.
|
||||
hi |= e << SHIFT
|
||||
x = transmute(f64)(hi)
|
||||
|
||||
// map to (-PI/2, PI/2]
|
||||
if x > 0.5 {
|
||||
x -= 1
|
||||
}
|
||||
return math.PI * x
|
||||
}
|
||||
|
||||
+68
-33
@@ -11,11 +11,13 @@ import "core:time"
|
||||
// with additional enum based call
|
||||
|
||||
// Modeled after the parabola y = x^2
|
||||
@(require_results)
|
||||
quadratic_in :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) {
|
||||
return p * p
|
||||
}
|
||||
|
||||
// Modeled after the parabola y = -x^2 + 2x
|
||||
@(require_results)
|
||||
quadratic_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) {
|
||||
return -(p * (p - 2))
|
||||
}
|
||||
@@ -23,6 +25,7 @@ quadratic_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(
|
||||
// Modeled after the piecewise quadratic
|
||||
// y = (1/2)((2x)^2) ; [0, 0.5)
|
||||
// y = -(1/2)((2x-1)*(2x-3) - 1) ; [0.5, 1]
|
||||
@(require_results)
|
||||
quadratic_in_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) {
|
||||
if p < 0.5 {
|
||||
return 2 * p * p
|
||||
@@ -32,11 +35,13 @@ quadratic_in_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_flo
|
||||
}
|
||||
|
||||
// Modeled after the cubic y = x^3
|
||||
@(require_results)
|
||||
cubic_in :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) {
|
||||
return p * p * p
|
||||
}
|
||||
|
||||
// Modeled after the cubic y = (x - 1)^3 + 1
|
||||
@(require_results)
|
||||
cubic_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) {
|
||||
f := p - 1
|
||||
return f * f * f + 1
|
||||
@@ -45,6 +50,7 @@ cubic_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) {
|
||||
// Modeled after the piecewise cubic
|
||||
// y = (1/2)((2x)^3) ; [0, 0.5)
|
||||
// y = (1/2)((2x-2)^3 + 2) ; [0.5, 1]
|
||||
@(require_results)
|
||||
cubic_in_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) {
|
||||
if p < 0.5 {
|
||||
return 4 * p * p * p
|
||||
@@ -55,11 +61,13 @@ cubic_in_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T
|
||||
}
|
||||
|
||||
// Modeled after the quartic x^4
|
||||
@(require_results)
|
||||
quartic_in :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) {
|
||||
return p * p * p * p
|
||||
}
|
||||
|
||||
// Modeled after the quartic y = 1 - (x - 1)^4
|
||||
@(require_results)
|
||||
quartic_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) {
|
||||
f := p - 1
|
||||
return f * f * f * (1 - p) + 1
|
||||
@@ -68,6 +76,7 @@ quartic_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T)
|
||||
// Modeled after the piecewise quartic
|
||||
// y = (1/2)((2x)^4) ; [0, 0.5)
|
||||
// y = -(1/2)((2x-2)^4 - 2) ; [0.5, 1]
|
||||
@(require_results)
|
||||
quartic_in_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) {
|
||||
if p < 0.5 {
|
||||
return 8 * p * p * p * p
|
||||
@@ -78,11 +87,13 @@ quartic_in_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float
|
||||
}
|
||||
|
||||
// Modeled after the quintic y = x^5
|
||||
@(require_results)
|
||||
quintic_in :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) {
|
||||
return p * p * p * p * p
|
||||
}
|
||||
|
||||
// Modeled after the quintic y = (x - 1)^5 + 1
|
||||
@(require_results)
|
||||
quintic_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) {
|
||||
f := p - 1
|
||||
return f * f * f * f * f + 1
|
||||
@@ -91,6 +102,7 @@ quintic_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T)
|
||||
// Modeled after the piecewise quintic
|
||||
// y = (1/2)((2x)^5) ; [0, 0.5)
|
||||
// y = (1/2)((2x-2)^5 + 2) ; [0.5, 1]
|
||||
@(require_results)
|
||||
quintic_in_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) {
|
||||
if p < 0.5 {
|
||||
return 16 * p * p * p * p * p
|
||||
@@ -101,26 +113,31 @@ quintic_in_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float
|
||||
}
|
||||
|
||||
// Modeled after quarter-cycle of sine wave
|
||||
@(require_results)
|
||||
sine_in :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) {
|
||||
return math.sin((p - 1) * PI_2) + 1
|
||||
}
|
||||
|
||||
// Modeled after quarter-cycle of sine wave (different phase)
|
||||
@(require_results)
|
||||
sine_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) {
|
||||
return math.sin(p * PI_2)
|
||||
}
|
||||
|
||||
// Modeled after half sine wave
|
||||
@(require_results)
|
||||
sine_in_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) {
|
||||
return 0.5 * (1 - math.cos(p * math.PI))
|
||||
}
|
||||
|
||||
// Modeled after shifted quadrant IV of unit circle
|
||||
@(require_results)
|
||||
circular_in :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) {
|
||||
return 1 - math.sqrt(1 - (p * p))
|
||||
}
|
||||
|
||||
// Modeled after shifted quadrant II of unit circle
|
||||
@(require_results)
|
||||
circular_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) {
|
||||
return math.sqrt((2 - p) * p)
|
||||
}
|
||||
@@ -128,6 +145,7 @@ circular_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T
|
||||
// Modeled after the piecewise circular function
|
||||
// y = (1/2)(1 - sqrt(1 - 4x^2)) ; [0, 0.5)
|
||||
// y = (1/2)(sqrt(-(2x - 3)*(2x - 1)) + 1) ; [0.5, 1]
|
||||
@(require_results)
|
||||
circular_in_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) {
|
||||
if p < 0.5 {
|
||||
return 0.5 * (1 - math.sqrt(1 - 4 * (p * p)))
|
||||
@@ -137,11 +155,13 @@ circular_in_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_floa
|
||||
}
|
||||
|
||||
// Modeled after the exponential function y = 2^(10(x - 1))
|
||||
@(require_results)
|
||||
exponential_in :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) {
|
||||
return p == 0.0 ? p : math.pow(2, 10 * (p - 1))
|
||||
}
|
||||
|
||||
// Modeled after the exponential function y = -2^(-10x) + 1
|
||||
@(require_results)
|
||||
exponential_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) {
|
||||
return p == 1.0 ? p : 1 - math.pow(2, -10 * p)
|
||||
}
|
||||
@@ -149,6 +169,7 @@ exponential_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_floa
|
||||
// Modeled after the piecewise exponential
|
||||
// y = (1/2)2^(10(2x - 1)) ; [0,0.5)
|
||||
// y = -(1/2)*2^(-10(2x - 1))) + 1 ; [0.5,1]
|
||||
@(require_results)
|
||||
exponential_in_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) {
|
||||
if p == 0.0 || p == 1.0 {
|
||||
return p
|
||||
@@ -162,11 +183,13 @@ exponential_in_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_f
|
||||
}
|
||||
|
||||
// Modeled after the damped sine wave y = sin(13pi/2*x)*pow(2, 10 * (x - 1))
|
||||
@(require_results)
|
||||
elastic_in :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) {
|
||||
return math.sin(13 * PI_2 * p) * math.pow(2, 10 * (p - 1))
|
||||
}
|
||||
|
||||
// Modeled after the damped sine wave y = sin(-13pi/2*(x + 1))*pow(2, -10x) + 1
|
||||
@(require_results)
|
||||
elastic_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) {
|
||||
return math.sin(-13 * PI_2 * (p + 1)) * math.pow(2, -10 * p) + 1
|
||||
}
|
||||
@@ -174,6 +197,7 @@ elastic_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T)
|
||||
// Modeled after the piecewise exponentially-damped sine wave:
|
||||
// y = (1/2)*sin(13pi/2*(2*x))*pow(2, 10 * ((2*x) - 1)) ; [0,0.5)
|
||||
// y = (1/2)*(sin(-13pi/2*((2x-1)+1))*pow(2,-10(2*x-1)) + 2) ; [0.5, 1]
|
||||
@(require_results)
|
||||
elastic_in_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) {
|
||||
if p < 0.5 {
|
||||
return 0.5 * math.sin(13 * PI_2 * (2 * p)) * math.pow(2, 10 * ((2 * p) - 1))
|
||||
@@ -183,11 +207,13 @@ elastic_in_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float
|
||||
}
|
||||
|
||||
// Modeled after the overshooting cubic y = x^3-x*sin(x*pi)
|
||||
@(require_results)
|
||||
back_in :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) {
|
||||
return p * p * p - p * math.sin(p * math.PI)
|
||||
}
|
||||
|
||||
// Modeled after overshooting cubic y = 1-((1-x)^3-(1-x)*sin((1-x)*pi))
|
||||
@(require_results)
|
||||
back_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) {
|
||||
f := 1 - p
|
||||
return 1 - (f * f * f - f * math.sin(f * math.PI))
|
||||
@@ -196,6 +222,7 @@ back_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) {
|
||||
// Modeled after the piecewise overshooting cubic function:
|
||||
// y = (1/2)*((2x)^3-(2x)*sin(2*x*pi)) ; [0, 0.5)
|
||||
// y = (1/2)*(1-((1-x)^3-(1-x)*sin((1-x)*pi))+1) ; [0.5, 1]
|
||||
@(require_results)
|
||||
back_in_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) {
|
||||
if p < 0.5 {
|
||||
f := 2 * p
|
||||
@@ -206,10 +233,12 @@ back_in_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T)
|
||||
}
|
||||
}
|
||||
|
||||
@(require_results)
|
||||
bounce_in :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) {
|
||||
return 1 - bounce_out(1 - p)
|
||||
}
|
||||
|
||||
@(require_results)
|
||||
bounce_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) {
|
||||
if p < 4/11.0 {
|
||||
return (121 * p * p)/16.0
|
||||
@@ -222,6 +251,7 @@ bounce_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T)
|
||||
}
|
||||
}
|
||||
|
||||
@(require_results)
|
||||
bounce_in_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) {
|
||||
if p < 0.5 {
|
||||
return 0.5 * bounce_in(p*2)
|
||||
@@ -276,50 +306,51 @@ Ease :: enum {
|
||||
Bounce_In_Out,
|
||||
}
|
||||
|
||||
@(require_results)
|
||||
ease :: proc "contextless" (type: Ease, p: $T) -> T
|
||||
where intrinsics.type_is_float(T) {
|
||||
switch type {
|
||||
case .Linear: return p
|
||||
|
||||
case .Quadratic_In: return quadratic_in(p)
|
||||
case .Quadratic_Out: return quadratic_out(p)
|
||||
case .Quadratic_In_Out: return quadratic_in_out(p)
|
||||
case .Linear: return p
|
||||
|
||||
case .Cubic_In: return cubic_in(p)
|
||||
case .Cubic_Out: return cubic_out(p)
|
||||
case .Cubic_In_Out: return cubic_in_out(p)
|
||||
case .Quadratic_In: return quadratic_in(p)
|
||||
case .Quadratic_Out: return quadratic_out(p)
|
||||
case .Quadratic_In_Out: return quadratic_in_out(p)
|
||||
|
||||
case .Quartic_In: return quartic_in(p)
|
||||
case .Quartic_Out: return quartic_out(p)
|
||||
case .Quartic_In_Out: return quartic_in_out(p)
|
||||
case .Cubic_In: return cubic_in(p)
|
||||
case .Cubic_Out: return cubic_out(p)
|
||||
case .Cubic_In_Out: return cubic_in_out(p)
|
||||
|
||||
case .Quintic_In: return quintic_in(p)
|
||||
case .Quintic_Out: return quintic_out(p)
|
||||
case .Quintic_In_Out: return quintic_in_out(p)
|
||||
case .Quartic_In: return quartic_in(p)
|
||||
case .Quartic_Out: return quartic_out(p)
|
||||
case .Quartic_In_Out: return quartic_in_out(p)
|
||||
|
||||
case .Sine_In: return sine_in(p)
|
||||
case .Sine_Out: return sine_out(p)
|
||||
case .Sine_In_Out: return sine_in_out(p)
|
||||
case .Quintic_In: return quintic_in(p)
|
||||
case .Quintic_Out: return quintic_out(p)
|
||||
case .Quintic_In_Out: return quintic_in_out(p)
|
||||
|
||||
case .Circular_In: return circular_in(p)
|
||||
case .Circular_Out: return circular_out(p)
|
||||
case .Circular_In_Out: return circular_in_out(p)
|
||||
case .Sine_In: return sine_in(p)
|
||||
case .Sine_Out: return sine_out(p)
|
||||
case .Sine_In_Out: return sine_in_out(p)
|
||||
|
||||
case .Exponential_In: return exponential_in(p)
|
||||
case .Exponential_Out: return exponential_out(p)
|
||||
case .Exponential_In_Out: return exponential_in_out(p)
|
||||
case .Circular_In: return circular_in(p)
|
||||
case .Circular_Out: return circular_out(p)
|
||||
case .Circular_In_Out: return circular_in_out(p)
|
||||
|
||||
case .Elastic_In: return elastic_in(p)
|
||||
case .Elastic_Out: return elastic_out(p)
|
||||
case .Elastic_In_Out: return elastic_in_out(p)
|
||||
case .Exponential_In: return exponential_in(p)
|
||||
case .Exponential_Out: return exponential_out(p)
|
||||
case .Exponential_In_Out: return exponential_in_out(p)
|
||||
|
||||
case .Back_In: return back_in(p)
|
||||
case .Back_Out: return back_out(p)
|
||||
case .Back_In_Out: return back_in_out(p)
|
||||
case .Elastic_In: return elastic_in(p)
|
||||
case .Elastic_Out: return elastic_out(p)
|
||||
case .Elastic_In_Out: return elastic_in_out(p)
|
||||
|
||||
case .Bounce_In: return bounce_in(p)
|
||||
case .Bounce_Out: return bounce_out(p)
|
||||
case .Bounce_In_Out: return bounce_in_out(p)
|
||||
case .Back_In: return back_in(p)
|
||||
case .Back_Out: return back_out(p)
|
||||
case .Back_In_Out: return back_in_out(p)
|
||||
|
||||
case .Bounce_In: return bounce_in(p)
|
||||
case .Bounce_Out: return bounce_out(p)
|
||||
case .Bounce_In_Out: return bounce_in_out(p)
|
||||
}
|
||||
|
||||
// in case type was invalid
|
||||
@@ -353,6 +384,7 @@ Flux_Tween :: struct($T: typeid) {
|
||||
}
|
||||
|
||||
// init flux map to a float type and a wanted cap
|
||||
@(require_results)
|
||||
flux_init :: proc($T: typeid, value_capacity := 8) -> Flux_Map(T) where intrinsics.type_is_float(T) {
|
||||
return {
|
||||
values = make(map[^T]Flux_Tween(T), value_capacity),
|
||||
@@ -374,6 +406,7 @@ flux_clear :: proc(flux: ^Flux_Map($T)) where intrinsics.type_is_float(T) {
|
||||
// append / overwrite existing tween value to parameters
|
||||
// rest is initialized in flux_tween_init, inside update
|
||||
// return value can be used to set callbacks
|
||||
@(require_results)
|
||||
flux_to :: proc(
|
||||
flux: ^Flux_Map($T),
|
||||
value: ^T,
|
||||
@@ -417,7 +450,7 @@ flux_tween_init :: proc(tween: ^Flux_Tween($T), duration: time.Duration) where i
|
||||
flux_update :: proc(flux: ^Flux_Map($T), dt: f64) where intrinsics.type_is_float(T) {
|
||||
clear(&flux.keys_to_be_deleted)
|
||||
|
||||
for key, tween in &flux.values {
|
||||
for key, &tween in flux.values {
|
||||
delay_remainder := f64(0)
|
||||
|
||||
// Update delay if necessary.
|
||||
@@ -475,6 +508,7 @@ flux_update :: proc(flux: ^Flux_Map($T), dt: f64) where intrinsics.type_is_float
|
||||
|
||||
// stop a specific key inside the map
|
||||
// returns true when it successfully removed the key
|
||||
@(require_results)
|
||||
flux_stop :: proc(flux: ^Flux_Map($T), key: ^T) -> bool where intrinsics.type_is_float(T) {
|
||||
if key in flux.values {
|
||||
delete_key(&flux.values, key)
|
||||
@@ -486,6 +520,7 @@ flux_stop :: proc(flux: ^Flux_Map($T), key: ^T) -> bool where intrinsics.type_is
|
||||
|
||||
// returns the amount of time left for the tween animation, if the key exists in the map
|
||||
// returns 0 if the tween doesnt exist on the map
|
||||
@(require_results)
|
||||
flux_tween_time_left :: proc(flux: Flux_Map($T), key: ^T) -> f64 {
|
||||
if tween, ok := flux.values[key]; ok {
|
||||
return ((1 - tween.progress) * tween.rate) + tween.delay
|
||||
|
||||
@@ -50,39 +50,48 @@ to_f64 :: proc(x: $T/Fixed($Backing, $Fraction_Width)) -> f64 {
|
||||
}
|
||||
|
||||
|
||||
@(require_results)
|
||||
add :: proc(x, y: $T/Fixed) -> T {
|
||||
return {x.i + y.i}
|
||||
}
|
||||
@(require_results)
|
||||
sub :: proc(x, y: $T/Fixed) -> T {
|
||||
return {x.i - y.i}
|
||||
}
|
||||
|
||||
@(require_results)
|
||||
mul :: proc(x, y: $T/Fixed($Backing, $Fraction_Width)) -> (z: T) {
|
||||
z.i = intrinsics.fixed_point_mul(x.i, y.i, Fraction_Width)
|
||||
return
|
||||
}
|
||||
@(require_results)
|
||||
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
|
||||
}
|
||||
|
||||
@(require_results)
|
||||
div :: proc(x, y: $T/Fixed($Backing, $Fraction_Width)) -> (z: T) {
|
||||
z.i = intrinsics.fixed_point_div(x.i, y.i, Fraction_Width)
|
||||
return
|
||||
}
|
||||
@(require_results)
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
@(require_results)
|
||||
floor :: proc(x: $T/Fixed($Backing, $Fraction_Width)) -> Backing {
|
||||
return x.i >> Fraction_Width
|
||||
}
|
||||
@(require_results)
|
||||
ceil :: proc(x: $T/Fixed($Backing, $Fraction_Width)) -> Backing {
|
||||
Integer :: 8*size_of(Backing) - Fraction_Width
|
||||
return (x.i + (1 << Integer-1)) >> Fraction_Width
|
||||
}
|
||||
@(require_results)
|
||||
round :: proc(x: $T/Fixed($Backing, $Fraction_Width)) -> Backing {
|
||||
Integer :: 8*size_of(Backing) - Fraction_Width
|
||||
return (x.i + (1 << (Integer - 1))) >> Fraction_Width
|
||||
@@ -90,6 +99,7 @@ round :: proc(x: $T/Fixed($Backing, $Fraction_Width)) -> Backing {
|
||||
|
||||
|
||||
|
||||
@(require_results)
|
||||
append :: proc(dst: []byte, x: $T/Fixed($Backing, $Fraction_Width)) -> string {
|
||||
x := x
|
||||
buf: [48]byte
|
||||
@@ -123,6 +133,7 @@ append :: proc(dst: []byte, x: $T/Fixed($Backing, $Fraction_Width)) -> string {
|
||||
}
|
||||
|
||||
|
||||
@(require_results)
|
||||
to_string :: proc(x: $T/Fixed($Backing, $Fraction_Width), allocator := context.allocator) -> string {
|
||||
buf: [48]byte
|
||||
s := append(buf[:], x)
|
||||
|
||||
+124
-65
@@ -3,7 +3,8 @@ package linalg
|
||||
import "core:builtin"
|
||||
import "core:math"
|
||||
|
||||
to_radians :: proc(degrees: $T) -> (out: T) where IS_NUMERIC(ELEM_TYPE(T)) {
|
||||
@(require_results)
|
||||
to_radians :: proc "contextless" (degrees: $T) -> (out: T) where IS_NUMERIC(ELEM_TYPE(T)) {
|
||||
when IS_ARRAY(T) {
|
||||
for i in 0..<len(T) {
|
||||
out[i] = degrees[i] * RAD_PER_DEG
|
||||
@@ -14,7 +15,8 @@ to_radians :: proc(degrees: $T) -> (out: T) where IS_NUMERIC(ELEM_TYPE(T)) {
|
||||
return
|
||||
}
|
||||
|
||||
to_degrees :: proc(radians: $T) -> (out: T) where IS_NUMERIC(ELEM_TYPE(T)) {
|
||||
@(require_results)
|
||||
to_degrees :: proc "contextless" (radians: $T) -> (out: T) where IS_NUMERIC(ELEM_TYPE(T)) {
|
||||
when IS_ARRAY(T) {
|
||||
for i in 0..<len(T) {
|
||||
out[i] = radians[i] * DEG_PER_RAD
|
||||
@@ -25,7 +27,8 @@ to_degrees :: proc(radians: $T) -> (out: T) where IS_NUMERIC(ELEM_TYPE(T)) {
|
||||
return
|
||||
}
|
||||
|
||||
min_double :: proc(a, b: $T) -> (out: T) where IS_NUMERIC(ELEM_TYPE(T)) {
|
||||
@(require_results)
|
||||
min_double :: proc "contextless" (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])
|
||||
@@ -36,7 +39,8 @@ min_double :: proc(a, b: $T) -> (out: T) where IS_NUMERIC(ELEM_TYPE(T)) {
|
||||
return
|
||||
}
|
||||
|
||||
min_single :: proc(a: $T) -> (out: ELEM_TYPE(T)) where IS_NUMERIC(ELEM_TYPE(T)) {
|
||||
@(require_results)
|
||||
min_single :: proc "contextless" (a: $T) -> (out: ELEM_TYPE(T)) where IS_NUMERIC(ELEM_TYPE(T)) {
|
||||
when IS_ARRAY(T) {
|
||||
N :: len(T)
|
||||
|
||||
@@ -56,13 +60,15 @@ min_single :: proc(a: $T) -> (out: ELEM_TYPE(T)) where IS_NUMERIC(ELEM_TYPE(T))
|
||||
return
|
||||
}
|
||||
|
||||
min_triple :: proc(a, b, c: $T) -> T where IS_NUMERIC(ELEM_TYPE(T)) {
|
||||
@(require_results)
|
||||
min_triple :: proc "contextless" (a, b, c: $T) -> T where IS_NUMERIC(ELEM_TYPE(T)) {
|
||||
return min_double(a, min_double(b, c))
|
||||
}
|
||||
|
||||
min :: proc{min_single, min_double, min_triple}
|
||||
|
||||
max_double :: proc(a, b: $T) -> (out: T) where IS_NUMERIC(ELEM_TYPE(T)) {
|
||||
@(require_results)
|
||||
max_double :: proc "contextless" (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])
|
||||
@@ -73,7 +79,8 @@ max_double :: proc(a, b: $T) -> (out: T) where IS_NUMERIC(ELEM_TYPE(T)) {
|
||||
return
|
||||
}
|
||||
|
||||
max_single :: proc(a: $T) -> (out: ELEM_TYPE(T)) where IS_NUMERIC(ELEM_TYPE(T)) {
|
||||
@(require_results)
|
||||
max_single :: proc "contextless" (a: $T) -> (out: ELEM_TYPE(T)) where IS_NUMERIC(ELEM_TYPE(T)) {
|
||||
when IS_ARRAY(T) {
|
||||
N :: len(T)
|
||||
|
||||
@@ -95,13 +102,15 @@ max_single :: proc(a: $T) -> (out: ELEM_TYPE(T)) where IS_NUMERIC(ELEM_TYPE(T))
|
||||
return
|
||||
}
|
||||
|
||||
max_triple :: proc(a, b, c: $T) -> T where IS_NUMERIC(ELEM_TYPE(T)) {
|
||||
@(require_results)
|
||||
max_triple :: proc "contextless" (a, b, c: $T) -> T where IS_NUMERIC(ELEM_TYPE(T)) {
|
||||
return max_double(a, max_double(b, c))
|
||||
}
|
||||
|
||||
max :: proc{max_single, max_double, max_triple}
|
||||
|
||||
abs :: proc(a: $T) -> (out: T) where IS_NUMERIC(ELEM_TYPE(T)) {
|
||||
@(require_results)
|
||||
abs :: proc "contextless" (a: $T) -> (out: T) where IS_NUMERIC(ELEM_TYPE(T)) {
|
||||
when IS_ARRAY(T) {
|
||||
for i in 0..<len(T) {
|
||||
out[i] = auto_cast builtin.abs(a[i])
|
||||
@@ -112,7 +121,8 @@ abs :: proc(a: $T) -> (out: T) where IS_NUMERIC(ELEM_TYPE(T)) {
|
||||
return
|
||||
}
|
||||
|
||||
sign :: proc(a: $T) -> (out: T) where IS_NUMERIC(ELEM_TYPE(T)) {
|
||||
@(require_results)
|
||||
sign :: proc "contextless" (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])
|
||||
@@ -123,7 +133,8 @@ sign :: proc(a: $T) -> (out: T) where IS_NUMERIC(ELEM_TYPE(T)) {
|
||||
return
|
||||
}
|
||||
|
||||
clamp :: proc(x, a, b: $T) -> (out: T) where IS_NUMERIC(ELEM_TYPE(T)) {
|
||||
@(require_results)
|
||||
clamp :: proc "contextless" (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])
|
||||
@@ -135,11 +146,13 @@ clamp :: proc(x, a, b: $T) -> (out: T) where IS_NUMERIC(ELEM_TYPE(T)) {
|
||||
}
|
||||
|
||||
|
||||
saturate :: proc(x: $T) -> T where IS_FLOAT(ELEM_TYPE(T)) {
|
||||
@(require_results)
|
||||
saturate :: proc "contextless" (x: $T) -> T where IS_FLOAT(ELEM_TYPE(T)) {
|
||||
return clamp(x, 0.0, 1.0)
|
||||
}
|
||||
|
||||
lerp :: proc(a, b, t: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
|
||||
@(require_results)
|
||||
lerp :: proc "contextless" (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]
|
||||
@@ -149,7 +162,8 @@ lerp :: proc(a, b, t: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
|
||||
}
|
||||
return
|
||||
}
|
||||
mix :: proc(a, b, t: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
|
||||
@(require_results)
|
||||
mix :: proc "contextless" (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]
|
||||
@@ -160,11 +174,13 @@ mix :: proc(a, b, t: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
|
||||
return
|
||||
}
|
||||
|
||||
unlerp :: proc(a, b, x: $T) -> T where IS_FLOAT(ELEM_TYPE(T)) {
|
||||
@(require_results)
|
||||
unlerp :: proc "contextless" (a, b, x: $T) -> T where IS_FLOAT(ELEM_TYPE(T)) {
|
||||
return (x - a) / (b - a)
|
||||
}
|
||||
|
||||
step :: proc(e, x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
|
||||
@(require_results)
|
||||
step :: proc "contextless" (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
|
||||
@@ -175,18 +191,21 @@ step :: proc(e, x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
|
||||
return
|
||||
}
|
||||
|
||||
smoothstep :: proc(e0, e1, x: $T) -> T where IS_FLOAT(ELEM_TYPE(T)) {
|
||||
@(require_results)
|
||||
smoothstep :: proc "contextless" (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)
|
||||
}
|
||||
|
||||
smootherstep :: proc(e0, e1, x: $T) -> T where IS_FLOAT(ELEM_TYPE(T)) {
|
||||
@(require_results)
|
||||
smootherstep :: proc "contextless" (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)
|
||||
}
|
||||
|
||||
|
||||
sqrt :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
|
||||
@(require_results)
|
||||
sqrt :: proc "contextless" (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])
|
||||
@@ -197,7 +216,8 @@ sqrt :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
|
||||
return
|
||||
}
|
||||
|
||||
inverse_sqrt :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
|
||||
@(require_results)
|
||||
inverse_sqrt :: proc "contextless" (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])
|
||||
@@ -208,7 +228,8 @@ inverse_sqrt :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
|
||||
return
|
||||
}
|
||||
|
||||
cos :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
|
||||
@(require_results)
|
||||
cos :: proc "contextless" (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])
|
||||
@@ -219,7 +240,8 @@ cos :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
|
||||
return
|
||||
}
|
||||
|
||||
sin :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
|
||||
@(require_results)
|
||||
sin :: proc "contextless" (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])
|
||||
@@ -230,7 +252,8 @@ sin :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
|
||||
return
|
||||
}
|
||||
|
||||
tan :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
|
||||
@(require_results)
|
||||
tan :: proc "contextless" (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])
|
||||
@@ -241,7 +264,8 @@ tan :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
|
||||
return
|
||||
}
|
||||
|
||||
acos :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
|
||||
@(require_results)
|
||||
acos :: proc "contextless" (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])
|
||||
@@ -252,7 +276,8 @@ acos :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
|
||||
return
|
||||
}
|
||||
|
||||
asin :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
|
||||
@(require_results)
|
||||
asin :: proc "contextless" (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])
|
||||
@@ -263,7 +288,8 @@ asin :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
|
||||
return
|
||||
}
|
||||
|
||||
atan :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
|
||||
@(require_results)
|
||||
atan :: proc "contextless" (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])
|
||||
@@ -273,7 +299,8 @@ atan :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
|
||||
}
|
||||
return
|
||||
}
|
||||
atan2 :: proc(y, x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
|
||||
@(require_results)
|
||||
atan2 :: proc "contextless" (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])
|
||||
@@ -285,7 +312,8 @@ atan2 :: proc(y, x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
|
||||
}
|
||||
|
||||
|
||||
ln :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
|
||||
@(require_results)
|
||||
ln :: proc "contextless" (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])
|
||||
@@ -296,7 +324,8 @@ ln :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
|
||||
return
|
||||
}
|
||||
|
||||
log2 :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
|
||||
@(require_results)
|
||||
log2 :: proc "contextless" (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])
|
||||
@@ -307,7 +336,8 @@ log2 :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
|
||||
return
|
||||
}
|
||||
|
||||
log10 :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
|
||||
@(require_results)
|
||||
log10 :: proc "contextless" (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])
|
||||
@@ -318,7 +348,8 @@ log10 :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
|
||||
return
|
||||
}
|
||||
|
||||
log :: proc(x, b: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
|
||||
@(require_results)
|
||||
log :: proc "contextless" (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])
|
||||
@@ -329,7 +360,8 @@ log :: proc(x, b: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
|
||||
return
|
||||
}
|
||||
|
||||
exp :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
|
||||
@(require_results)
|
||||
exp :: proc "contextless" (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])
|
||||
@@ -340,7 +372,8 @@ exp :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
|
||||
return
|
||||
}
|
||||
|
||||
exp2 :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
|
||||
@(require_results)
|
||||
exp2 :: proc "contextless" (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])
|
||||
@@ -351,7 +384,8 @@ exp2 :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
|
||||
return
|
||||
}
|
||||
|
||||
exp10 :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
|
||||
@(require_results)
|
||||
exp10 :: proc "contextless" (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])
|
||||
@@ -362,7 +396,8 @@ exp10 :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
|
||||
return
|
||||
}
|
||||
|
||||
pow :: proc(x, e: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
|
||||
@(require_results)
|
||||
pow :: proc "contextless" (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])
|
||||
@@ -374,7 +409,8 @@ pow :: proc(x, e: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
|
||||
}
|
||||
|
||||
|
||||
ceil :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
|
||||
@(require_results)
|
||||
ceil :: proc "contextless" (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])
|
||||
@@ -385,7 +421,8 @@ ceil :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
|
||||
return
|
||||
}
|
||||
|
||||
floor :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
|
||||
@(require_results)
|
||||
floor :: proc "contextless" (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])
|
||||
@@ -396,7 +433,8 @@ floor :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
|
||||
return
|
||||
}
|
||||
|
||||
round :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
|
||||
@(require_results)
|
||||
round :: proc "contextless" (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])
|
||||
@@ -407,30 +445,36 @@ round :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
|
||||
return
|
||||
}
|
||||
|
||||
fract :: proc(x: $T) -> T where IS_FLOAT(ELEM_TYPE(T)) {
|
||||
@(require_results)
|
||||
fract :: proc "contextless" (x: $T) -> T where IS_FLOAT(ELEM_TYPE(T)) {
|
||||
f := #force_inline floor(x)
|
||||
return x - f
|
||||
}
|
||||
|
||||
mod :: proc(x, m: $T) -> T where IS_FLOAT(ELEM_TYPE(T)) {
|
||||
@(require_results)
|
||||
mod :: proc "contextless" (x, m: $T) -> T where IS_FLOAT(ELEM_TYPE(T)) {
|
||||
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)) {
|
||||
@(require_results)
|
||||
face_forward :: proc "contextless" (N, I, N_ref: $T) -> (out: T) where IS_ARRAY(T), IS_FLOAT(ELEM_TYPE(T)) {
|
||||
return dot(N_ref, I) < 0 ? N : -N
|
||||
}
|
||||
|
||||
distance :: proc(p0, p1: $V/[$N]$E) -> E where IS_NUMERIC(E) {
|
||||
@(require_results)
|
||||
distance :: proc "contextless" (p0, p1: $V/[$N]$E) -> E where IS_NUMERIC(E) {
|
||||
return length(p1 - p0)
|
||||
}
|
||||
|
||||
reflect :: proc(I, N: $T) -> (out: T) where IS_ARRAY(T), IS_FLOAT(ELEM_TYPE(T)) {
|
||||
@(require_results)
|
||||
reflect :: proc "contextless" (I, N: $T) -> (out: T) where IS_ARRAY(T), IS_FLOAT(ELEM_TYPE(T)) {
|
||||
b := N * (2 * dot(N, I))
|
||||
return I - b
|
||||
}
|
||||
refract :: proc(I, Normal: $V/[$N]$E, eta: E) -> (out: V) where IS_ARRAY(V), IS_FLOAT(ELEM_TYPE(V)) {
|
||||
@(require_results)
|
||||
refract :: proc "contextless" (I, Normal: $V/[$N]$E, eta: E) -> (out: V) where IS_ARRAY(V), IS_FLOAT(ELEM_TYPE(V)) {
|
||||
dv := dot(Normal, I)
|
||||
k := 1 - eta*eta * (1 - dv*dv)
|
||||
a := I * eta
|
||||
@@ -441,33 +485,39 @@ refract :: proc(I, Normal: $V/[$N]$E, eta: E) -> (out: V) where IS_ARRAY(V), IS_
|
||||
|
||||
|
||||
|
||||
is_nan_single :: proc(x: $T) -> bool where IS_FLOAT(T) {
|
||||
@(require_results)
|
||||
is_nan_single :: proc "contextless" (x: $T) -> bool where IS_FLOAT(T) {
|
||||
return #force_inline math.is_nan(x)
|
||||
}
|
||||
|
||||
is_nan_array :: proc(x: $A/[$N]$T) -> (out: [N]bool) where IS_FLOAT(T) {
|
||||
@(require_results)
|
||||
is_nan_array :: proc "contextless" (x: $A/[$N]$T) -> (out: [N]bool) where IS_FLOAT(T) {
|
||||
for i in 0..<N {
|
||||
out[i] = #force_inline is_nan(x[i])
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
is_inf_single :: proc(x: $T) -> bool where IS_FLOAT(T) {
|
||||
@(require_results)
|
||||
is_inf_single :: proc "contextless" (x: $T) -> bool where IS_FLOAT(T) {
|
||||
return #force_inline math.is_inf(x)
|
||||
}
|
||||
|
||||
is_inf_array :: proc(x: $A/[$N]$T) -> (out: [N]bool) where IS_FLOAT(T) {
|
||||
@(require_results)
|
||||
is_inf_array :: proc "contextless" (x: $A/[$N]$T) -> (out: [N]bool) where IS_FLOAT(T) {
|
||||
for i in 0..<N {
|
||||
out[i] = #force_inline is_inf(x[i])
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
classify_single :: proc(x: $T) -> math.Float_Class where IS_FLOAT(T) {
|
||||
@(require_results)
|
||||
classify_single :: proc "contextless" (x: $T) -> math.Float_Class where IS_FLOAT(T) {
|
||||
return #force_inline math.classify(x)
|
||||
}
|
||||
|
||||
classify_array :: proc(x: $A/[$N]$T) -> (out: [N]math.Float_Class) where IS_FLOAT(T) {
|
||||
@(require_results)
|
||||
classify_array :: proc "contextless" (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])
|
||||
}
|
||||
@@ -479,44 +529,50 @@ 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 }
|
||||
less_than_equal_single :: proc(x, y: $T) -> (out: bool) where !IS_ARRAY(T), IS_FLOAT(T) { return x <= y }
|
||||
greater_than_single :: proc(x, y: $T) -> (out: bool) where !IS_ARRAY(T), IS_FLOAT(T) { return x > y }
|
||||
greater_than_equal_single :: proc(x, y: $T) -> (out: bool) where !IS_ARRAY(T), IS_FLOAT(T) { return x >= y }
|
||||
equal_single :: proc(x, y: $T) -> (out: bool) where !IS_ARRAY(T), IS_FLOAT(T) { return x == y }
|
||||
not_equal_single :: proc(x, y: $T) -> (out: bool) where !IS_ARRAY(T), IS_FLOAT(T) { return x != y }
|
||||
@(require_results) less_than_single :: proc "contextless" (x, y: $T) -> (out: bool) where !IS_ARRAY(T), IS_FLOAT(T) { return x < y }
|
||||
@(require_results) less_than_equal_single :: proc "contextless" (x, y: $T) -> (out: bool) where !IS_ARRAY(T), IS_FLOAT(T) { return x <= y }
|
||||
@(require_results) greater_than_single :: proc "contextless" (x, y: $T) -> (out: bool) where !IS_ARRAY(T), IS_FLOAT(T) { return x > y }
|
||||
@(require_results) greater_than_equal_single :: proc "contextless" (x, y: $T) -> (out: bool) where !IS_ARRAY(T), IS_FLOAT(T) { return x >= y }
|
||||
@(require_results) equal_single :: proc "contextless" (x, y: $T) -> (out: bool) where !IS_ARRAY(T), IS_FLOAT(T) { return x == y }
|
||||
@(require_results) not_equal_single :: proc "contextless" (x, y: $T) -> (out: bool) where !IS_ARRAY(T), IS_FLOAT(T) { return x != y }
|
||||
|
||||
less_than_array :: proc(x, y: $A/[$N]$T) -> (out: [N]bool) where IS_ARRAY(A), IS_FLOAT(ELEM_TYPE(A)) {
|
||||
@(require_results)
|
||||
less_than_array :: proc "contextless" (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]
|
||||
}
|
||||
return
|
||||
}
|
||||
less_than_equal_array :: proc(x, y: $A/[$N]$T) -> (out: [N]bool) where IS_ARRAY(A), IS_FLOAT(ELEM_TYPE(A)) {
|
||||
@(require_results)
|
||||
less_than_equal_array :: proc "contextless" (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]
|
||||
}
|
||||
return
|
||||
}
|
||||
greater_than_array :: proc(x, y: $A/[$N]$T) -> (out: [N]bool) where IS_ARRAY(A), IS_FLOAT(ELEM_TYPE(A)) {
|
||||
@(require_results)
|
||||
greater_than_array :: proc "contextless" (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]
|
||||
}
|
||||
return
|
||||
}
|
||||
greater_than_equal_array :: proc(x, y: $A/[$N]$T) -> (out: [N]bool) where IS_ARRAY(A), IS_FLOAT(ELEM_TYPE(A)) {
|
||||
@(require_results)
|
||||
greater_than_equal_array :: proc "contextless" (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]
|
||||
}
|
||||
return
|
||||
}
|
||||
equal_array :: proc(x, y: $A/[$N]$T) -> (out: [N]bool) where IS_ARRAY(A), IS_FLOAT(ELEM_TYPE(A)) {
|
||||
@(require_results)
|
||||
equal_array :: proc "contextless" (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]
|
||||
}
|
||||
return
|
||||
}
|
||||
not_equal_array :: proc(x, y: $A/[$N]$T) -> (out: [N]bool) where IS_ARRAY(A), IS_FLOAT(ELEM_TYPE(A)) {
|
||||
@(require_results)
|
||||
not_equal_array :: proc "contextless" (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]
|
||||
}
|
||||
@@ -530,7 +586,8 @@ 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) {
|
||||
@(require_results)
|
||||
any :: proc "contextless" (x: $A/[$N]bool) -> (out: bool) {
|
||||
for e in x {
|
||||
if e {
|
||||
return true
|
||||
@@ -538,7 +595,8 @@ any :: proc(x: $A/[$N]bool) -> (out: bool) {
|
||||
}
|
||||
return false
|
||||
}
|
||||
all :: proc(x: $A/[$N]bool) -> (out: bool) {
|
||||
@(require_results)
|
||||
all :: proc "contextless" (x: $A/[$N]bool) -> (out: bool) {
|
||||
for e in x {
|
||||
if !e {
|
||||
return false
|
||||
@@ -546,7 +604,8 @@ all :: proc(x: $A/[$N]bool) -> (out: bool) {
|
||||
}
|
||||
return true
|
||||
}
|
||||
not :: proc(x: $A/[$N]bool) -> (out: A) {
|
||||
@(require_results)
|
||||
not :: proc "contextless" (x: $A/[$N]bool) -> (out: A) {
|
||||
for e, i in x {
|
||||
out[i] = !e
|
||||
}
|
||||
|
||||
@@ -38,23 +38,28 @@ DEG_PER_RAD :: 360.0/TAU
|
||||
@private ELEM_TYPE :: intrinsics.type_elem_type
|
||||
|
||||
|
||||
scalar_dot :: proc(a, b: $T) -> T where IS_FLOAT(T), !IS_ARRAY(T) {
|
||||
@(require_results)
|
||||
scalar_dot :: proc "contextless" (a, b: $T) -> T where IS_FLOAT(T), !IS_ARRAY(T) {
|
||||
return a * b
|
||||
}
|
||||
|
||||
vector_dot :: proc(a, b: $T/[$N]$E) -> (c: E) where IS_NUMERIC(E) #no_bounds_check {
|
||||
@(require_results)
|
||||
vector_dot :: proc "contextless" (a, b: $T/[$N]$E) -> (c: E) where IS_NUMERIC(E) #no_bounds_check {
|
||||
for i in 0..<N {
|
||||
c += a[i] * b[i]
|
||||
}
|
||||
return
|
||||
}
|
||||
quaternion64_dot :: proc(a, b: $T/quaternion64) -> (c: f16) {
|
||||
@(require_results)
|
||||
quaternion64_dot :: proc "contextless" (a, b: $T/quaternion64) -> (c: f16) {
|
||||
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) {
|
||||
@(require_results)
|
||||
quaternion128_dot :: proc "contextless" (a, b: $T/quaternion128) -> (c: f32) {
|
||||
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) {
|
||||
@(require_results)
|
||||
quaternion256_dot :: proc "contextless" (a, b: $T/quaternion256) -> (c: f64) {
|
||||
return a.w*a.w + a.x*b.x + a.y*b.y + a.z*b.z
|
||||
}
|
||||
|
||||
@@ -63,27 +68,32 @@ dot :: proc{scalar_dot, vector_dot, quaternion64_dot, quaternion128_dot, quatern
|
||||
inner_product :: dot
|
||||
outer_product :: builtin.outer_product
|
||||
|
||||
quaternion_inverse :: proc(q: $Q) -> Q where IS_QUATERNION(Q) {
|
||||
@(require_results)
|
||||
quaternion_inverse :: proc "contextless" (q: $Q) -> Q where IS_QUATERNION(Q) {
|
||||
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) {
|
||||
@(require_results)
|
||||
scalar_cross :: proc "contextless" (a, b: $T) -> T where IS_FLOAT(T), !IS_ARRAY(T) {
|
||||
return a * b
|
||||
}
|
||||
|
||||
vector_cross2 :: proc(a, b: $T/[2]$E) -> E where IS_NUMERIC(E) {
|
||||
@(require_results)
|
||||
vector_cross2 :: proc "contextless" (a, b: $T/[2]$E) -> E where IS_NUMERIC(E) {
|
||||
return a[0]*b[1] - b[0]*a[1]
|
||||
}
|
||||
|
||||
vector_cross3 :: proc(a, b: $T/[3]$E) -> (c: T) where IS_NUMERIC(E) {
|
||||
@(require_results)
|
||||
vector_cross3 :: proc "contextless" (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
|
||||
}
|
||||
|
||||
quaternion_cross :: proc(q1, q2: $Q) -> (q3: Q) where IS_QUATERNION(Q) {
|
||||
@(require_results)
|
||||
quaternion_cross :: proc "contextless" (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
|
||||
@@ -94,49 +104,59 @@ quaternion_cross :: proc(q1, q2: $Q) -> (q3: Q) where IS_QUATERNION(Q) {
|
||||
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_FLOAT(E) {
|
||||
@(require_results)
|
||||
vector_normalize :: proc "contextless" (v: $T/[$N]$E) -> T where IS_FLOAT(E) {
|
||||
return v / length(v)
|
||||
}
|
||||
quaternion_normalize :: proc(q: $Q) -> Q where IS_QUATERNION(Q) {
|
||||
@(require_results)
|
||||
quaternion_normalize :: proc "contextless" (q: $Q) -> Q where IS_QUATERNION(Q) {
|
||||
return q/abs(q)
|
||||
}
|
||||
normalize :: proc{vector_normalize, quaternion_normalize}
|
||||
|
||||
vector_normalize0 :: proc(v: $T/[$N]$E) -> T where IS_FLOAT(E) {
|
||||
@(require_results)
|
||||
vector_normalize0 :: proc "contextless" (v: $T/[$N]$E) -> T where IS_FLOAT(E) {
|
||||
m := length(v)
|
||||
return 0 if m == 0 else v/m
|
||||
}
|
||||
quaternion_normalize0 :: proc(q: $Q) -> Q where IS_QUATERNION(Q) {
|
||||
@(require_results)
|
||||
quaternion_normalize0 :: proc "contextless" (q: $Q) -> Q where IS_QUATERNION(Q) {
|
||||
m := abs(q)
|
||||
return 0 if m == 0 else q/m
|
||||
}
|
||||
normalize0 :: proc{vector_normalize0, quaternion_normalize0}
|
||||
|
||||
|
||||
vector_length :: proc(v: $T/[$N]$E) -> E where IS_FLOAT(E) {
|
||||
@(require_results)
|
||||
vector_length :: proc "contextless" (v: $T/[$N]$E) -> E where IS_FLOAT(E) {
|
||||
return math.sqrt(dot(v, v))
|
||||
}
|
||||
|
||||
vector_length2 :: proc(v: $T/[$N]$E) -> E where IS_NUMERIC(E) {
|
||||
@(require_results)
|
||||
vector_length2 :: proc "contextless" (v: $T/[$N]$E) -> E where IS_NUMERIC(E) {
|
||||
return dot(v, v)
|
||||
}
|
||||
|
||||
quaternion_length :: proc(q: $Q) -> Q where IS_QUATERNION(Q) {
|
||||
@(require_results)
|
||||
quaternion_length :: proc "contextless" (q: $Q) -> Q where IS_QUATERNION(Q) {
|
||||
return abs(q)
|
||||
}
|
||||
|
||||
quaternion_length2 :: proc(q: $Q) -> Q where IS_QUATERNION(Q) {
|
||||
@(require_results)
|
||||
quaternion_length2 :: proc "contextless" (q: $Q) -> Q where IS_QUATERNION(Q) {
|
||||
return dot(q, q)
|
||||
}
|
||||
|
||||
scalar_triple_product :: proc(a, b, c: $T/[$N]$E) -> E where IS_NUMERIC(E) {
|
||||
@(require_results)
|
||||
scalar_triple_product :: proc "contextless" (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))
|
||||
}
|
||||
|
||||
vector_triple_product :: proc(a, b, c: $T/[$N]$E) -> T where IS_NUMERIC(E) {
|
||||
@(require_results)
|
||||
vector_triple_product :: proc "contextless" (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))
|
||||
@@ -146,11 +166,13 @@ vector_triple_product :: proc(a, b, c: $T/[$N]$E) -> T where IS_NUMERIC(E) {
|
||||
length :: proc{vector_length, quaternion_length}
|
||||
length2 :: proc{vector_length2, quaternion_length2}
|
||||
|
||||
projection :: proc(x, normal: $T/[$N]$E) -> T where IS_NUMERIC(E) {
|
||||
@(require_results)
|
||||
projection :: proc "contextless" (x, normal: $T/[$N]$E) -> T where IS_NUMERIC(E) {
|
||||
return dot(x, normal) / dot(normal, normal) * normal
|
||||
}
|
||||
|
||||
identity :: proc($T: typeid/[$N][N]$E) -> (m: T) #no_bounds_check {
|
||||
@(require_results)
|
||||
identity :: proc "contextless" ($T: typeid/[$N][N]$E) -> (m: T) #no_bounds_check {
|
||||
for i in 0..<N {
|
||||
m[i][i] = E(1)
|
||||
}
|
||||
@@ -160,32 +182,38 @@ identity :: proc($T: typeid/[$N][N]$E) -> (m: T) #no_bounds_check {
|
||||
trace :: builtin.matrix_trace
|
||||
transpose :: builtin.transpose
|
||||
|
||||
matrix_mul :: proc(a, b: $M/matrix[$N, N]$E) -> (c: M)
|
||||
@(require_results)
|
||||
matrix_mul :: proc "contextless" (a, b: $M/matrix[$N, N]$E) -> (c: M)
|
||||
where !IS_ARRAY(E), IS_NUMERIC(E) #no_bounds_check {
|
||||
return a * b
|
||||
}
|
||||
|
||||
matrix_comp_mul :: proc(a, b: $M/matrix[$I, $J]$E) -> (c: M)
|
||||
@(require_results)
|
||||
matrix_comp_mul :: proc "contextless" (a, b: $M/matrix[$I, $J]$E) -> (c: M)
|
||||
where !IS_ARRAY(E), IS_NUMERIC(E) #no_bounds_check {
|
||||
return hadamard_product(a, b)
|
||||
}
|
||||
|
||||
matrix_mul_differ :: proc(a: $A/matrix[$I, $J]$E, b: $B/matrix[J, $K]E) -> (c: matrix[I, K]E)
|
||||
@(require_results)
|
||||
matrix_mul_differ :: proc "contextless" (a: $A/matrix[$I, $J]$E, b: $B/matrix[J, $K]E) -> (c: matrix[I, K]E)
|
||||
where !IS_ARRAY(E), IS_NUMERIC(E), I != K #no_bounds_check {
|
||||
return a * b
|
||||
}
|
||||
|
||||
|
||||
matrix_mul_vector :: proc(a: $A/matrix[$I, $J]$E, b: $B/[J]E) -> (c: B)
|
||||
@(require_results)
|
||||
matrix_mul_vector :: proc "contextless" (a: $A/matrix[$I, $J]$E, b: $B/[J]E) -> (c: B)
|
||||
where !IS_ARRAY(E), IS_NUMERIC(E) #no_bounds_check {
|
||||
return a * b
|
||||
}
|
||||
|
||||
quaternion_mul_quaternion :: proc(q1, q2: $Q) -> Q where IS_QUATERNION(Q) {
|
||||
@(require_results)
|
||||
quaternion_mul_quaternion :: proc "contextless" (q1, q2: $Q) -> Q where IS_QUATERNION(Q) {
|
||||
return q1 * q2
|
||||
}
|
||||
|
||||
quaternion64_mul_vector3 :: proc(q: $Q/quaternion64, v: $V/[3]$F/f16) -> V {
|
||||
@(require_results)
|
||||
quaternion64_mul_vector3 :: proc "contextless" (q: $Q/quaternion64, v: $V/[3]$F/f16) -> V {
|
||||
Raw_Quaternion :: struct {xyz: [3]f16, r: f16}
|
||||
|
||||
q := transmute(Raw_Quaternion)q
|
||||
@@ -194,7 +222,8 @@ quaternion64_mul_vector3 :: proc(q: $Q/quaternion64, v: $V/[3]$F/f16) -> V {
|
||||
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 {
|
||||
@(require_results)
|
||||
quaternion128_mul_vector3 :: proc "contextless" (q: $Q/quaternion128, v: $V/[3]$F/f32) -> V {
|
||||
Raw_Quaternion :: struct {xyz: [3]f32, r: f32}
|
||||
|
||||
q := transmute(Raw_Quaternion)q
|
||||
@@ -203,7 +232,8 @@ quaternion128_mul_vector3 :: proc(q: $Q/quaternion128, v: $V/[3]$F/f32) -> V {
|
||||
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 {
|
||||
@(require_results)
|
||||
quaternion256_mul_vector3 :: proc "contextless" (q: $Q/quaternion256, v: $V/[3]$F/f64) -> V {
|
||||
Raw_Quaternion :: struct {xyz: [3]f64, r: f64}
|
||||
|
||||
q := transmute(Raw_Quaternion)q
|
||||
@@ -224,10 +254,12 @@ mul :: proc{
|
||||
quaternion_mul_quaternion,
|
||||
}
|
||||
|
||||
vector_to_ptr :: proc(v: ^$V/[$N]$E) -> ^E where IS_NUMERIC(E), N > 0 #no_bounds_check {
|
||||
@(require_results)
|
||||
vector_to_ptr :: proc "contextless" (v: ^$V/[$N]$E) -> ^E where IS_NUMERIC(E), N > 0 #no_bounds_check {
|
||||
return &v[0]
|
||||
}
|
||||
matrix_to_ptr :: proc(m: ^$A/matrix[$I, $J]$E) -> ^E where IS_NUMERIC(E), I > 0, J > 0 #no_bounds_check {
|
||||
@(require_results)
|
||||
matrix_to_ptr :: proc "contextless" (m: ^$A/matrix[$I, $J]$E) -> ^E where IS_NUMERIC(E), I > 0, J > 0 #no_bounds_check {
|
||||
return &m[0, 0]
|
||||
}
|
||||
|
||||
@@ -239,7 +271,8 @@ to_ptr :: proc{vector_to_ptr, matrix_to_ptr}
|
||||
|
||||
// Splines
|
||||
|
||||
vector_slerp :: proc(x, y: $T/[$N]$E, a: E) -> T {
|
||||
@(require_results)
|
||||
vector_slerp :: proc "contextless" (x, y: $T/[$N]$E, a: E) -> T {
|
||||
cos_alpha := dot(x, y)
|
||||
alpha := math.acos(cos_alpha)
|
||||
sin_alpha := math.sin(alpha)
|
||||
@@ -250,7 +283,8 @@ vector_slerp :: proc(x, y: $T/[$N]$E, a: E) -> T {
|
||||
return x * t1 + y * t2
|
||||
}
|
||||
|
||||
catmull_rom :: proc(v1, v2, v3, v4: $T/[$N]$E, s: E) -> T {
|
||||
@(require_results)
|
||||
catmull_rom :: proc "contextless" (v1, v2, v3, v4: $T/[$N]$E, s: E) -> T {
|
||||
s2 := s*s
|
||||
s3 := s2*s
|
||||
|
||||
@@ -262,7 +296,8 @@ catmull_rom :: proc(v1, v2, v3, v4: $T/[$N]$E, s: E) -> T {
|
||||
return (f1 * v1 + f2 * v2 + f3 * v3 + f4 * v4) * 0.5
|
||||
}
|
||||
|
||||
hermite :: proc(v1, t1, v2, t2: $T/[$N]$E, s: E) -> T {
|
||||
@(require_results)
|
||||
hermite :: proc "contextless" (v1, t1, v2, t2: $T/[$N]$E, s: E) -> T {
|
||||
s2 := s*s
|
||||
s3 := s2*s
|
||||
|
||||
@@ -274,20 +309,23 @@ hermite :: proc(v1, t1, v2, t2: $T/[$N]$E, s: E) -> T {
|
||||
return f1 * v1 + f2 * v2 + f3 * t1 + f4 * t2
|
||||
}
|
||||
|
||||
cubic :: proc(v1, v2, v3, v4: $T/[$N]$E, s: E) -> T {
|
||||
@(require_results)
|
||||
cubic :: proc "contextless" (v1, v2, v3, v4: $T/[$N]$E, s: E) -> T {
|
||||
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 {
|
||||
@(require_results)
|
||||
array_cast :: proc "contextless" (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])
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
matrix_cast :: proc(v: $A/matrix[$M, $N]$T, $Elem_Type: typeid) -> (w: matrix[M, N]Elem_Type) #no_bounds_check {
|
||||
@(require_results)
|
||||
matrix_cast :: proc "contextless" (v: $A/matrix[$M, $N]$T, $Elem_Type: typeid) -> (w: matrix[M, N]Elem_Type) #no_bounds_check {
|
||||
for j in 0..<N {
|
||||
for i in 0..<M {
|
||||
w[i, j] = Elem_Type(v[i, j])
|
||||
@@ -296,24 +334,24 @@ matrix_cast :: proc(v: $A/matrix[$M, $N]$T, $Elem_Type: typeid) -> (w: matrix[M,
|
||||
return
|
||||
}
|
||||
|
||||
to_f32 :: #force_inline proc(v: $A/[$N]$T) -> [N]f32 { return array_cast(v, f32) }
|
||||
to_f64 :: #force_inline proc(v: $A/[$N]$T) -> [N]f64 { return array_cast(v, f64) }
|
||||
@(require_results) to_f32 :: #force_inline proc(v: $A/[$N]$T) -> [N]f32 { return array_cast(v, f32) }
|
||||
@(require_results) to_f64 :: #force_inline proc(v: $A/[$N]$T) -> [N]f64 { return array_cast(v, f64) }
|
||||
|
||||
to_i8 :: #force_inline proc(v: $A/[$N]$T) -> [N]i8 { return array_cast(v, i8) }
|
||||
to_i16 :: #force_inline proc(v: $A/[$N]$T) -> [N]i16 { return array_cast(v, i16) }
|
||||
to_i32 :: #force_inline proc(v: $A/[$N]$T) -> [N]i32 { return array_cast(v, i32) }
|
||||
to_i64 :: #force_inline proc(v: $A/[$N]$T) -> [N]i64 { return array_cast(v, i64) }
|
||||
to_int :: #force_inline proc(v: $A/[$N]$T) -> [N]int { return array_cast(v, int) }
|
||||
@(require_results) to_i8 :: #force_inline proc(v: $A/[$N]$T) -> [N]i8 { return array_cast(v, i8) }
|
||||
@(require_results) to_i16 :: #force_inline proc(v: $A/[$N]$T) -> [N]i16 { return array_cast(v, i16) }
|
||||
@(require_results) to_i32 :: #force_inline proc(v: $A/[$N]$T) -> [N]i32 { return array_cast(v, i32) }
|
||||
@(require_results) to_i64 :: #force_inline proc(v: $A/[$N]$T) -> [N]i64 { return array_cast(v, i64) }
|
||||
@(require_results) to_int :: #force_inline proc(v: $A/[$N]$T) -> [N]int { return array_cast(v, int) }
|
||||
|
||||
to_u8 :: #force_inline proc(v: $A/[$N]$T) -> [N]u8 { return array_cast(v, u8) }
|
||||
to_u16 :: #force_inline proc(v: $A/[$N]$T) -> [N]u16 { return array_cast(v, u16) }
|
||||
to_u32 :: #force_inline proc(v: $A/[$N]$T) -> [N]u32 { return array_cast(v, u32) }
|
||||
to_u64 :: #force_inline proc(v: $A/[$N]$T) -> [N]u64 { return array_cast(v, u64) }
|
||||
to_uint :: #force_inline proc(v: $A/[$N]$T) -> [N]uint { return array_cast(v, uint) }
|
||||
@(require_results) to_u8 :: #force_inline proc(v: $A/[$N]$T) -> [N]u8 { return array_cast(v, u8) }
|
||||
@(require_results) to_u16 :: #force_inline proc(v: $A/[$N]$T) -> [N]u16 { return array_cast(v, u16) }
|
||||
@(require_results) to_u32 :: #force_inline proc(v: $A/[$N]$T) -> [N]u32 { return array_cast(v, u32) }
|
||||
@(require_results) to_u64 :: #force_inline proc(v: $A/[$N]$T) -> [N]u64 { return array_cast(v, u64) }
|
||||
@(require_results) to_uint :: #force_inline proc(v: $A/[$N]$T) -> [N]uint { return array_cast(v, uint) }
|
||||
|
||||
to_complex32 :: #force_inline proc(v: $A/[$N]$T) -> [N]complex32 { return array_cast(v, complex32) }
|
||||
to_complex64 :: #force_inline proc(v: $A/[$N]$T) -> [N]complex64 { return array_cast(v, complex64) }
|
||||
to_complex128 :: #force_inline proc(v: $A/[$N]$T) -> [N]complex128 { return array_cast(v, complex128) }
|
||||
to_quaternion64 :: #force_inline proc(v: $A/[$N]$T) -> [N]quaternion64 { return array_cast(v, quaternion64) }
|
||||
to_quaternion128 :: #force_inline proc(v: $A/[$N]$T) -> [N]quaternion128 { return array_cast(v, quaternion128) }
|
||||
to_quaternion256 :: #force_inline proc(v: $A/[$N]$T) -> [N]quaternion256 { return array_cast(v, quaternion256) }
|
||||
@(require_results) to_complex32 :: #force_inline proc(v: $A/[$N]$T) -> [N]complex32 { return array_cast(v, complex32) }
|
||||
@(require_results) to_complex64 :: #force_inline proc(v: $A/[$N]$T) -> [N]complex64 { return array_cast(v, complex64) }
|
||||
@(require_results) to_complex128 :: #force_inline proc(v: $A/[$N]$T) -> [N]complex128 { return array_cast(v, complex128) }
|
||||
@(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_quaternion256 :: #force_inline proc(v: $A/[$N]$T) -> [N]quaternion256 { return array_cast(v, quaternion256) }
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,30 +2,31 @@ package math_linalg_glsl
|
||||
|
||||
import "core:math"
|
||||
|
||||
cos_f32 :: proc "c" (x: f32) -> f32 { return math.cos(x) }
|
||||
sin_f32 :: proc "c" (x: f32) -> f32 { return math.sin(x) }
|
||||
tan_f32 :: proc "c" (x: f32) -> f32 { return math.tan(x) }
|
||||
acos_f32 :: proc "c" (x: f32) -> f32 { return math.acos(x) }
|
||||
asin_f32 :: proc "c" (x: f32) -> f32 { return math.asin(x) }
|
||||
atan_f32 :: proc "c" (x: f32) -> f32 { return math.atan(x) }
|
||||
atan2_f32 :: proc "c" (y, x: f32) -> f32 { return math.atan2(y, x) }
|
||||
cosh_f32 :: proc "c" (x: f32) -> f32 { return math.cosh(x) }
|
||||
sinh_f32 :: proc "c" (x: f32) -> f32 { return math.sinh(x) }
|
||||
tanh_f32 :: proc "c" (x: f32) -> f32 { return math.tanh(x) }
|
||||
acosh_f32 :: proc "c" (x: f32) -> f32 { return math.acosh(x) }
|
||||
asinh_f32 :: proc "c" (x: f32) -> f32 { return math.asinh(x) }
|
||||
atanh_f32 :: proc "c" (x: f32) -> f32 { return math.atanh(x) }
|
||||
sqrt_f32 :: proc "c" (x: f32) -> f32 { return math.sqrt(x) }
|
||||
inversesqrt_f32 :: proc "c" (x: f32) -> f32 { return 1.0/math.sqrt(x) }
|
||||
pow_f32 :: proc "c" (x, y: f32) -> f32 { return math.pow(x, y) }
|
||||
exp_f32 :: proc "c" (x: f32) -> f32 { return math.exp(x) }
|
||||
log_f32 :: proc "c" (x: f32) -> f32 { return math.ln(x) }
|
||||
exp2_f32 :: proc "c" (x: f32) -> f32 { return math.pow(f32(2), x) }
|
||||
sign_f32 :: proc "c" (x: f32) -> f32 { return math.sign(x) }
|
||||
floor_f32 :: proc "c" (x: f32) -> f32 { return math.floor(x) }
|
||||
round_f32 :: proc "c" (x: f32) -> f32 { return math.round(x) }
|
||||
ceil_f32 :: proc "c" (x: f32) -> f32 { return math.ceil(x) }
|
||||
mod_f32 :: proc "c" (x, y: f32) -> f32 { return math.mod(x, y) }
|
||||
@(require_results) cos_f32 :: proc "c" (x: f32) -> f32 { return math.cos(x) }
|
||||
@(require_results) sin_f32 :: proc "c" (x: f32) -> f32 { return math.sin(x) }
|
||||
@(require_results) tan_f32 :: proc "c" (x: f32) -> f32 { return math.tan(x) }
|
||||
@(require_results) acos_f32 :: proc "c" (x: f32) -> f32 { return math.acos(x) }
|
||||
@(require_results) asin_f32 :: proc "c" (x: f32) -> f32 { return math.asin(x) }
|
||||
@(require_results) atan_f32 :: proc "c" (x: f32) -> f32 { return math.atan(x) }
|
||||
@(require_results) atan2_f32 :: proc "c" (y, x: f32) -> f32 { return math.atan2(y, x) }
|
||||
@(require_results) cosh_f32 :: proc "c" (x: f32) -> f32 { return math.cosh(x) }
|
||||
@(require_results) sinh_f32 :: proc "c" (x: f32) -> f32 { return math.sinh(x) }
|
||||
@(require_results) tanh_f32 :: proc "c" (x: f32) -> f32 { return math.tanh(x) }
|
||||
@(require_results) acosh_f32 :: proc "c" (x: f32) -> f32 { return math.acosh(x) }
|
||||
@(require_results) asinh_f32 :: proc "c" (x: f32) -> f32 { return math.asinh(x) }
|
||||
@(require_results) atanh_f32 :: proc "c" (x: f32) -> f32 { return math.atanh(x) }
|
||||
@(require_results) sqrt_f32 :: proc "c" (x: f32) -> f32 { return math.sqrt(x) }
|
||||
@(require_results) inversesqrt_f32 :: proc "c" (x: f32) -> f32 { return 1.0/math.sqrt(x) }
|
||||
@(require_results) pow_f32 :: proc "c" (x, y: f32) -> f32 { return math.pow(x, y) }
|
||||
@(require_results) exp_f32 :: proc "c" (x: f32) -> f32 { return math.exp(x) }
|
||||
@(require_results) log_f32 :: proc "c" (x: f32) -> f32 { return math.ln(x) }
|
||||
@(require_results) exp2_f32 :: proc "c" (x: f32) -> f32 { return math.pow(f32(2), x) }
|
||||
@(require_results) sign_f32 :: proc "c" (x: f32) -> f32 { return math.sign(x) }
|
||||
@(require_results) floor_f32 :: proc "c" (x: f32) -> f32 { return math.floor(x) }
|
||||
@(require_results) round_f32 :: proc "c" (x: f32) -> f32 { return math.round(x) }
|
||||
@(require_results) ceil_f32 :: proc "c" (x: f32) -> f32 { return math.ceil(x) }
|
||||
@(require_results) mod_f32 :: proc "c" (x, y: f32) -> f32 { return math.mod(x, y) }
|
||||
@(require_results)
|
||||
fract_f32 :: proc "c" (x: f32) -> f32 {
|
||||
if x >= 0 {
|
||||
return x - math.trunc(x)
|
||||
@@ -33,30 +34,31 @@ fract_f32 :: proc "c" (x: f32) -> f32 {
|
||||
return math.trunc(-x) + x
|
||||
}
|
||||
|
||||
cos_f64 :: proc "c" (x: f64) -> f64 { return math.cos(x) }
|
||||
sin_f64 :: proc "c" (x: f64) -> f64 { return math.sin(x) }
|
||||
tan_f64 :: proc "c" (x: f64) -> f64 { return math.tan(x) }
|
||||
acos_f64 :: proc "c" (x: f64) -> f64 { return math.acos(x) }
|
||||
asin_f64 :: proc "c" (x: f64) -> f64 { return math.asin(x) }
|
||||
atan_f64 :: proc "c" (x: f64) -> f64 { return math.atan(x) }
|
||||
atan2_f64 :: proc "c" (y, x: f64) -> f64 { return math.atan2(y, x) }
|
||||
cosh_f64 :: proc "c" (x: f64) -> f64 { return math.cosh(x) }
|
||||
sinh_f64 :: proc "c" (x: f64) -> f64 { return math.sinh(x) }
|
||||
tanh_f64 :: proc "c" (x: f64) -> f64 { return math.tanh(x) }
|
||||
acosh_f64 :: proc "c" (x: f64) -> f64 { return math.acosh(x) }
|
||||
asinh_f64 :: proc "c" (x: f64) -> f64 { return math.asinh(x) }
|
||||
atanh_f64 :: proc "c" (x: f64) -> f64 { return math.atanh(x) }
|
||||
sqrt_f64 :: proc "c" (x: f64) -> f64 { return math.sqrt(x) }
|
||||
inversesqrt_f64 :: proc "c" (x: f64) -> f64 { return 1.0/math.sqrt(x) }
|
||||
pow_f64 :: proc "c" (x, y: f64) -> f64 { return math.pow(x, y) }
|
||||
exp_f64 :: proc "c" (x: f64) -> f64 { return math.exp(x) }
|
||||
log_f64 :: proc "c" (x: f64) -> f64 { return math.ln(x) }
|
||||
exp2_f64 :: proc "c" (x: f64) -> f64 { return math.pow(f64(2), x) }
|
||||
sign_f64 :: proc "c" (x: f64) -> f64 { return math.sign(x) }
|
||||
floor_f64 :: proc "c" (x: f64) -> f64 { return math.floor(x) }
|
||||
round_f64 :: proc "c" (x: f64) -> f64 { return math.round(x) }
|
||||
ceil_f64 :: proc "c" (x: f64) -> f64 { return math.ceil(x) }
|
||||
mod_f64 :: proc "c" (x, y: f64) -> f64 { return math.mod(x, y) }
|
||||
@(require_results) cos_f64 :: proc "c" (x: f64) -> f64 { return math.cos(x) }
|
||||
@(require_results) sin_f64 :: proc "c" (x: f64) -> f64 { return math.sin(x) }
|
||||
@(require_results) tan_f64 :: proc "c" (x: f64) -> f64 { return math.tan(x) }
|
||||
@(require_results) acos_f64 :: proc "c" (x: f64) -> f64 { return math.acos(x) }
|
||||
@(require_results) asin_f64 :: proc "c" (x: f64) -> f64 { return math.asin(x) }
|
||||
@(require_results) atan_f64 :: proc "c" (x: f64) -> f64 { return math.atan(x) }
|
||||
@(require_results) atan2_f64 :: proc "c" (y, x: f64) -> f64 { return math.atan2(y, x) }
|
||||
@(require_results) cosh_f64 :: proc "c" (x: f64) -> f64 { return math.cosh(x) }
|
||||
@(require_results) sinh_f64 :: proc "c" (x: f64) -> f64 { return math.sinh(x) }
|
||||
@(require_results) tanh_f64 :: proc "c" (x: f64) -> f64 { return math.tanh(x) }
|
||||
@(require_results) acosh_f64 :: proc "c" (x: f64) -> f64 { return math.acosh(x) }
|
||||
@(require_results) asinh_f64 :: proc "c" (x: f64) -> f64 { return math.asinh(x) }
|
||||
@(require_results) atanh_f64 :: proc "c" (x: f64) -> f64 { return math.atanh(x) }
|
||||
@(require_results) sqrt_f64 :: proc "c" (x: f64) -> f64 { return math.sqrt(x) }
|
||||
@(require_results) inversesqrt_f64 :: proc "c" (x: f64) -> f64 { return 1.0/math.sqrt(x) }
|
||||
@(require_results) pow_f64 :: proc "c" (x, y: f64) -> f64 { return math.pow(x, y) }
|
||||
@(require_results) exp_f64 :: proc "c" (x: f64) -> f64 { return math.exp(x) }
|
||||
@(require_results) log_f64 :: proc "c" (x: f64) -> f64 { return math.ln(x) }
|
||||
@(require_results) exp2_f64 :: proc "c" (x: f64) -> f64 { return math.pow(f64(2), x) }
|
||||
@(require_results) sign_f64 :: proc "c" (x: f64) -> f64 { return math.sign(x) }
|
||||
@(require_results) floor_f64 :: proc "c" (x: f64) -> f64 { return math.floor(x) }
|
||||
@(require_results) round_f64 :: proc "c" (x: f64) -> f64 { return math.round(x) }
|
||||
@(require_results) ceil_f64 :: proc "c" (x: f64) -> f64 { return math.ceil(x) }
|
||||
@(require_results) mod_f64 :: proc "c" (x, y: f64) -> f64 { return math.mod(x, y) }
|
||||
@(require_results)
|
||||
fract_f64 :: proc "c" (x: f64) -> f64 {
|
||||
if x >= 0 {
|
||||
return x - math.trunc(x)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,34 +2,35 @@ package math_linalg_hlsl
|
||||
|
||||
import "core:math"
|
||||
|
||||
cos_float :: proc "c" (x: float) -> float { return math.cos(x) }
|
||||
sin_float :: proc "c" (x: float) -> float { return math.sin(x) }
|
||||
tan_float :: proc "c" (x: float) -> float { return math.tan(x) }
|
||||
acos_float :: proc "c" (x: float) -> float { return math.acos(x) }
|
||||
asin_float :: proc "c" (x: float) -> float { return math.asin(x) }
|
||||
atan_float :: proc "c" (x: float) -> float { return math.atan(x) }
|
||||
atan2_float :: proc "c" (y, x: float) -> float { return math.atan2(y, x) }
|
||||
cosh_float :: proc "c" (x: float) -> float { return math.cosh(x) }
|
||||
sinh_float :: proc "c" (x: float) -> float { return math.sinh(x) }
|
||||
tanh_float :: proc "c" (x: float) -> float { return math.tanh(x) }
|
||||
acosh_float :: proc "c" (x: float) -> float { return math.acosh(x) }
|
||||
asinh_float :: proc "c" (x: float) -> float { return math.asinh(x) }
|
||||
atanh_float :: proc "c" (x: float) -> float { return math.atanh(x) }
|
||||
sqrt_float :: proc "c" (x: float) -> float { return math.sqrt(x) }
|
||||
rsqrt_float :: proc "c" (x: float) -> float { return 1.0/math.sqrt(x) }
|
||||
rcp_float :: proc "c" (x: float) -> float { return 1.0/x }
|
||||
pow_float :: proc "c" (x, y: float) -> float { return math.pow(x, y) }
|
||||
exp_float :: proc "c" (x: float) -> float { return math.exp(x) }
|
||||
log_float :: proc "c" (x: float) -> float { return math.ln(x) }
|
||||
log2_float :: proc "c" (x: float) -> float { return math.log(x, 2) }
|
||||
log10_float :: proc "c" (x: float) -> float { return math.log(x, 10) }
|
||||
exp2_float :: proc "c" (x: float) -> float { return math.pow(float(2), x) }
|
||||
sign_float :: proc "c" (x: float) -> float { return math.sign(x) }
|
||||
floor_float :: proc "c" (x: float) -> float { return math.floor(x) }
|
||||
round_float :: proc "c" (x: float) -> float { return math.round(x) }
|
||||
ceil_float :: proc "c" (x: float) -> float { return math.ceil(x) }
|
||||
isnan_float :: proc "c" (x: float) -> bool { return math.classify(x) == .NaN}
|
||||
fmod_float :: proc "c" (x, y: float) -> float { return math.mod(x, y) }
|
||||
@(require_results) cos_float :: proc "c" (x: float) -> float { return math.cos(x) }
|
||||
@(require_results) sin_float :: proc "c" (x: float) -> float { return math.sin(x) }
|
||||
@(require_results) tan_float :: proc "c" (x: float) -> float { return math.tan(x) }
|
||||
@(require_results) acos_float :: proc "c" (x: float) -> float { return math.acos(x) }
|
||||
@(require_results) asin_float :: proc "c" (x: float) -> float { return math.asin(x) }
|
||||
@(require_results) atan_float :: proc "c" (x: float) -> float { return math.atan(x) }
|
||||
@(require_results) atan2_float :: proc "c" (y, x: float) -> float { return math.atan2(y, x) }
|
||||
@(require_results) cosh_float :: proc "c" (x: float) -> float { return math.cosh(x) }
|
||||
@(require_results) sinh_float :: proc "c" (x: float) -> float { return math.sinh(x) }
|
||||
@(require_results) tanh_float :: proc "c" (x: float) -> float { return math.tanh(x) }
|
||||
@(require_results) acosh_float :: proc "c" (x: float) -> float { return math.acosh(x) }
|
||||
@(require_results) asinh_float :: proc "c" (x: float) -> float { return math.asinh(x) }
|
||||
@(require_results) atanh_float :: proc "c" (x: float) -> float { return math.atanh(x) }
|
||||
@(require_results) sqrt_float :: proc "c" (x: float) -> float { return math.sqrt(x) }
|
||||
@(require_results) rsqrt_float :: proc "c" (x: float) -> float { return 1.0/math.sqrt(x) }
|
||||
@(require_results) rcp_float :: proc "c" (x: float) -> float { return 1.0/x }
|
||||
@(require_results) pow_float :: proc "c" (x, y: float) -> float { return math.pow(x, y) }
|
||||
@(require_results) exp_float :: proc "c" (x: float) -> float { return math.exp(x) }
|
||||
@(require_results) log_float :: proc "c" (x: float) -> float { return math.ln(x) }
|
||||
@(require_results) log2_float :: proc "c" (x: float) -> float { return math.log(x, 2) }
|
||||
@(require_results) log10_float :: proc "c" (x: float) -> float { return math.log(x, 10) }
|
||||
@(require_results) exp2_float :: proc "c" (x: float) -> float { return math.pow(float(2), x) }
|
||||
@(require_results) sign_float :: proc "c" (x: float) -> float { return math.sign(x) }
|
||||
@(require_results) floor_float :: proc "c" (x: float) -> float { return math.floor(x) }
|
||||
@(require_results) round_float :: proc "c" (x: float) -> float { return math.round(x) }
|
||||
@(require_results) ceil_float :: proc "c" (x: float) -> float { return math.ceil(x) }
|
||||
@(require_results) isnan_float :: proc "c" (x: float) -> bool { return math.classify(x) == .NaN}
|
||||
@(require_results) fmod_float :: proc "c" (x, y: float) -> float { return math.mod(x, y) }
|
||||
@(require_results)
|
||||
frac_float :: proc "c" (x: float) -> float {
|
||||
if x >= 0 {
|
||||
return x - math.trunc(x)
|
||||
@@ -38,34 +39,35 @@ frac_float :: proc "c" (x: float) -> float {
|
||||
}
|
||||
|
||||
|
||||
cos_double :: proc "c" (x: double) -> double { return math.cos(x) }
|
||||
sin_double :: proc "c" (x: double) -> double { return math.sin(x) }
|
||||
tan_double :: proc "c" (x: double) -> double { return math.tan(x) }
|
||||
acos_double :: proc "c" (x: double) -> double { return math.acos(x) }
|
||||
asin_double :: proc "c" (x: double) -> double { return math.asin(x) }
|
||||
atan_double :: proc "c" (x: double) -> double { return math.atan(x) }
|
||||
atan2_double :: proc "c" (y, x: double) -> double { return math.atan2(y, x) }
|
||||
cosh_double :: proc "c" (x: double) -> double { return math.cosh(x) }
|
||||
sinh_double :: proc "c" (x: double) -> double { return math.sinh(x) }
|
||||
tanh_double :: proc "c" (x: double) -> double { return math.tanh(x) }
|
||||
acosh_double :: proc "c" (x: double) -> double { return math.acosh(x) }
|
||||
asinh_double :: proc "c" (x: double) -> double { return math.asinh(x) }
|
||||
atanh_double :: proc "c" (x: double) -> double { return math.atanh(x) }
|
||||
sqrt_double :: proc "c" (x: double) -> double { return math.sqrt(x) }
|
||||
rsqrt_double :: proc "c" (x: double) -> double { return 1.0/math.sqrt(x) }
|
||||
rcp_double :: proc "c" (x: double) -> double { return 1.0/x }
|
||||
pow_double :: proc "c" (x, y: double) -> double { return math.pow(x, y) }
|
||||
exp_double :: proc "c" (x: double) -> double { return math.exp(x) }
|
||||
log_double :: proc "c" (x: double) -> double { return math.ln(x) }
|
||||
log2_double :: proc "c" (x: double) -> double { return math.log(x, 2) }
|
||||
log10_double :: proc "c" (x: double) -> double { return math.log(x, 10) }
|
||||
exp2_double :: proc "c" (x: double) -> double { return math.pow(double(2), x) }
|
||||
sign_double :: proc "c" (x: double) -> double { return math.sign(x) }
|
||||
floor_double :: proc "c" (x: double) -> double { return math.floor(x) }
|
||||
round_double :: proc "c" (x: double) -> double { return math.round(x) }
|
||||
ceil_double :: proc "c" (x: double) -> double { return math.ceil(x) }
|
||||
isnan_double :: proc "c" (x: double) -> bool { return math.classify(x) == .NaN}
|
||||
fmod_double :: proc "c" (x, y: double) -> double { return math.mod(x, y) }
|
||||
@(require_results) cos_double :: proc "c" (x: double) -> double { return math.cos(x) }
|
||||
@(require_results) sin_double :: proc "c" (x: double) -> double { return math.sin(x) }
|
||||
@(require_results) tan_double :: proc "c" (x: double) -> double { return math.tan(x) }
|
||||
@(require_results) acos_double :: proc "c" (x: double) -> double { return math.acos(x) }
|
||||
@(require_results) asin_double :: proc "c" (x: double) -> double { return math.asin(x) }
|
||||
@(require_results) atan_double :: proc "c" (x: double) -> double { return math.atan(x) }
|
||||
@(require_results) atan2_double :: proc "c" (y, x: double) -> double { return math.atan2(y, x) }
|
||||
@(require_results) cosh_double :: proc "c" (x: double) -> double { return math.cosh(x) }
|
||||
@(require_results) sinh_double :: proc "c" (x: double) -> double { return math.sinh(x) }
|
||||
@(require_results) tanh_double :: proc "c" (x: double) -> double { return math.tanh(x) }
|
||||
@(require_results) acosh_double :: proc "c" (x: double) -> double { return math.acosh(x) }
|
||||
@(require_results) asinh_double :: proc "c" (x: double) -> double { return math.asinh(x) }
|
||||
@(require_results) atanh_double :: proc "c" (x: double) -> double { return math.atanh(x) }
|
||||
@(require_results) sqrt_double :: proc "c" (x: double) -> double { return math.sqrt(x) }
|
||||
@(require_results) rsqrt_double :: proc "c" (x: double) -> double { return 1.0/math.sqrt(x) }
|
||||
@(require_results) rcp_double :: proc "c" (x: double) -> double { return 1.0/x }
|
||||
@(require_results) pow_double :: proc "c" (x, y: double) -> double { return math.pow(x, y) }
|
||||
@(require_results) exp_double :: proc "c" (x: double) -> double { return math.exp(x) }
|
||||
@(require_results) log_double :: proc "c" (x: double) -> double { return math.ln(x) }
|
||||
@(require_results) log2_double :: proc "c" (x: double) -> double { return math.log(x, 2) }
|
||||
@(require_results) log10_double :: proc "c" (x: double) -> double { return math.log(x, 10) }
|
||||
@(require_results) exp2_double :: proc "c" (x: double) -> double { return math.pow(double(2), x) }
|
||||
@(require_results) sign_double :: proc "c" (x: double) -> double { return math.sign(x) }
|
||||
@(require_results) floor_double :: proc "c" (x: double) -> double { return math.floor(x) }
|
||||
@(require_results) round_double :: proc "c" (x: double) -> double { return math.round(x) }
|
||||
@(require_results) ceil_double :: proc "c" (x: double) -> double { return math.ceil(x) }
|
||||
@(require_results) isnan_double :: proc "c" (x: double) -> bool { return math.classify(x) == .NaN}
|
||||
@(require_results) fmod_double :: proc "c" (x, y: double) -> double { return math.mod(x, y) }
|
||||
@(require_results)
|
||||
frac_double :: proc "c" (x: double) -> double {
|
||||
if x >= 0 {
|
||||
return x - math.trunc(x)
|
||||
|
||||
+370
-185
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,8 @@ package linalg
|
||||
|
||||
import "core:math"
|
||||
|
||||
euler_angles_from_matrix3_f16 :: proc(m: Matrix3f16, order: Euler_Angle_Order) -> (t1, t2, t3: f16) {
|
||||
@(require_results)
|
||||
euler_angles_from_matrix3_f16 :: proc "contextless" (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)
|
||||
@@ -19,7 +20,8 @@ euler_angles_from_matrix3_f16 :: proc(m: Matrix3f16, order: Euler_Angle_Order) -
|
||||
}
|
||||
return
|
||||
}
|
||||
euler_angles_from_matrix4_f16 :: proc(m: Matrix4f16, order: Euler_Angle_Order) -> (t1, t2, t3: f16) {
|
||||
@(require_results)
|
||||
euler_angles_from_matrix4_f16 :: proc "contextless" (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)
|
||||
@@ -36,7 +38,8 @@ euler_angles_from_matrix4_f16 :: proc(m: Matrix4f16, order: Euler_Angle_Order) -
|
||||
}
|
||||
return
|
||||
}
|
||||
euler_angles_from_quaternion_f16 :: proc(m: Quaternionf16, order: Euler_Angle_Order) -> (t1, t2, t3: f16) {
|
||||
@(require_results)
|
||||
euler_angles_from_quaternion_f16 :: proc "contextless" (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)
|
||||
@@ -54,7 +57,8 @@ euler_angles_from_quaternion_f16 :: proc(m: Quaternionf16, order: Euler_Angle_Or
|
||||
return
|
||||
}
|
||||
|
||||
matrix3_from_euler_angles_f16 :: proc(t1, t2, t3: f16, order: Euler_Angle_Order) -> (m: Matrix3f16) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angles_f16 :: proc "contextless" (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);
|
||||
@@ -71,7 +75,8 @@ matrix3_from_euler_angles_f16 :: proc(t1, t2, t3: f16, order: Euler_Angle_Order)
|
||||
}
|
||||
return
|
||||
}
|
||||
matrix4_from_euler_angles_f16 :: proc(t1, t2, t3: f16, order: Euler_Angle_Order) -> (m: Matrix4f16) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angles_f16 :: proc "contextless" (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);
|
||||
@@ -89,7 +94,8 @@ matrix4_from_euler_angles_f16 :: proc(t1, t2, t3: f16, order: Euler_Angle_Order)
|
||||
return
|
||||
}
|
||||
|
||||
quaternion_from_euler_angles_f16 :: proc(t1, t2, t3: f16, order: Euler_Angle_Order) -> Quaternionf16 {
|
||||
@(require_results)
|
||||
quaternion_from_euler_angles_f16 :: proc "contextless" (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
|
||||
@@ -117,17 +123,21 @@ quaternion_from_euler_angles_f16 :: proc(t1, t2, t3: f16, order: Euler_Angle_Ord
|
||||
|
||||
// Quaternionf16s
|
||||
|
||||
quaternion_from_euler_angle_x_f16 :: proc(angle_x: f16) -> (q: Quaternionf16) {
|
||||
@(require_results)
|
||||
quaternion_from_euler_angle_x_f16 :: proc "contextless" (angle_x: f16) -> (q: Quaternionf16) {
|
||||
return quaternion_angle_axis_f16(angle_x, {1, 0, 0})
|
||||
}
|
||||
quaternion_from_euler_angle_y_f16 :: proc(angle_y: f16) -> (q: Quaternionf16) {
|
||||
@(require_results)
|
||||
quaternion_from_euler_angle_y_f16 :: proc "contextless" (angle_y: f16) -> (q: Quaternionf16) {
|
||||
return quaternion_angle_axis_f16(angle_y, {0, 1, 0})
|
||||
}
|
||||
quaternion_from_euler_angle_z_f16 :: proc(angle_z: f16) -> (q: Quaternionf16) {
|
||||
@(require_results)
|
||||
quaternion_from_euler_angle_z_f16 :: proc "contextless" (angle_z: f16) -> (q: Quaternionf16) {
|
||||
return quaternion_angle_axis_f16(angle_z, {0, 0, 1})
|
||||
}
|
||||
|
||||
quaternion_from_pitch_yaw_roll_f16 :: proc(pitch, yaw, roll: f16) -> Quaternionf16 {
|
||||
@(require_results)
|
||||
quaternion_from_pitch_yaw_roll_f16 :: proc "contextless" (pitch, yaw, roll: f16) -> Quaternionf16 {
|
||||
a, b, c := pitch, yaw, roll
|
||||
|
||||
ca, sa := math.cos(a*0.5), math.sin(a*0.5)
|
||||
@@ -142,11 +152,13 @@ quaternion_from_pitch_yaw_roll_f16 :: proc(pitch, yaw, roll: f16) -> Quaternionf
|
||||
return q
|
||||
}
|
||||
|
||||
roll_from_quaternion_f16 :: proc(q: Quaternionf16) -> f16 {
|
||||
@(require_results)
|
||||
roll_from_quaternion_f16 :: proc "contextless" (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)
|
||||
}
|
||||
|
||||
pitch_from_quaternion_f16 :: proc(q: Quaternionf16) -> f16 {
|
||||
@(require_results)
|
||||
pitch_from_quaternion_f16 :: proc "contextless" (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
|
||||
|
||||
@@ -157,52 +169,66 @@ pitch_from_quaternion_f16 :: proc(q: Quaternionf16) -> f16 {
|
||||
return math.atan2(y, x)
|
||||
}
|
||||
|
||||
yaw_from_quaternion_f16 :: proc(q: Quaternionf16) -> f16 {
|
||||
@(require_results)
|
||||
yaw_from_quaternion_f16 :: proc "contextless" (q: Quaternionf16) -> f16 {
|
||||
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) {
|
||||
@(require_results)
|
||||
pitch_yaw_roll_from_quaternion_f16 :: proc "contextless" (q: Quaternionf16) -> (pitch, yaw, roll: f16) {
|
||||
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) {
|
||||
@(require_results)
|
||||
euler_angles_xyz_from_quaternion_f16 :: proc "contextless" (q: Quaternionf16) -> (t1, t2, t3: f16) {
|
||||
return euler_angles_xyz_from_matrix4(matrix4_from_quaternion(q))
|
||||
}
|
||||
euler_angles_yxz_from_quaternion_f16 :: proc(q: Quaternionf16) -> (t1, t2, t3: f16) {
|
||||
@(require_results)
|
||||
euler_angles_yxz_from_quaternion_f16 :: proc "contextless" (q: Quaternionf16) -> (t1, t2, t3: f16) {
|
||||
return euler_angles_yxz_from_matrix4(matrix4_from_quaternion(q))
|
||||
}
|
||||
euler_angles_xzx_from_quaternion_f16 :: proc(q: Quaternionf16) -> (t1, t2, t3: f16) {
|
||||
@(require_results)
|
||||
euler_angles_xzx_from_quaternion_f16 :: proc "contextless" (q: Quaternionf16) -> (t1, t2, t3: f16) {
|
||||
return euler_angles_xzx_from_matrix4(matrix4_from_quaternion(q))
|
||||
}
|
||||
euler_angles_xyx_from_quaternion_f16 :: proc(q: Quaternionf16) -> (t1, t2, t3: f16) {
|
||||
@(require_results)
|
||||
euler_angles_xyx_from_quaternion_f16 :: proc "contextless" (q: Quaternionf16) -> (t1, t2, t3: f16) {
|
||||
return euler_angles_xyx_from_matrix4(matrix4_from_quaternion(q))
|
||||
}
|
||||
euler_angles_yxy_from_quaternion_f16 :: proc(q: Quaternionf16) -> (t1, t2, t3: f16) {
|
||||
@(require_results)
|
||||
euler_angles_yxy_from_quaternion_f16 :: proc "contextless" (q: Quaternionf16) -> (t1, t2, t3: f16) {
|
||||
return euler_angles_yxy_from_matrix4(matrix4_from_quaternion(q))
|
||||
}
|
||||
euler_angles_yzy_from_quaternion_f16 :: proc(q: Quaternionf16) -> (t1, t2, t3: f16) {
|
||||
@(require_results)
|
||||
euler_angles_yzy_from_quaternion_f16 :: proc "contextless" (q: Quaternionf16) -> (t1, t2, t3: f16) {
|
||||
return euler_angles_yzy_from_matrix4(matrix4_from_quaternion(q))
|
||||
}
|
||||
euler_angles_zyz_from_quaternion_f16 :: proc(q: Quaternionf16) -> (t1, t2, t3: f16) {
|
||||
@(require_results)
|
||||
euler_angles_zyz_from_quaternion_f16 :: proc "contextless" (q: Quaternionf16) -> (t1, t2, t3: f16) {
|
||||
return euler_angles_zyz_from_matrix4(matrix4_from_quaternion(q))
|
||||
}
|
||||
euler_angles_zxz_from_quaternion_f16 :: proc(q: Quaternionf16) -> (t1, t2, t3: f16) {
|
||||
@(require_results)
|
||||
euler_angles_zxz_from_quaternion_f16 :: proc "contextless" (q: Quaternionf16) -> (t1, t2, t3: f16) {
|
||||
return euler_angles_zxz_from_matrix4(matrix4_from_quaternion(q))
|
||||
}
|
||||
euler_angles_xzy_from_quaternion_f16 :: proc(q: Quaternionf16) -> (t1, t2, t3: f16) {
|
||||
@(require_results)
|
||||
euler_angles_xzy_from_quaternion_f16 :: proc "contextless" (q: Quaternionf16) -> (t1, t2, t3: f16) {
|
||||
return euler_angles_xzy_from_matrix4(matrix4_from_quaternion(q))
|
||||
}
|
||||
euler_angles_yzx_from_quaternion_f16 :: proc(q: Quaternionf16) -> (t1, t2, t3: f16) {
|
||||
@(require_results)
|
||||
euler_angles_yzx_from_quaternion_f16 :: proc "contextless" (q: Quaternionf16) -> (t1, t2, t3: f16) {
|
||||
return euler_angles_yzx_from_matrix4(matrix4_from_quaternion(q))
|
||||
}
|
||||
euler_angles_zyx_from_quaternion_f16 :: proc(q: Quaternionf16) -> (t1, t2, t3: f16) {
|
||||
@(require_results)
|
||||
euler_angles_zyx_from_quaternion_f16 :: proc "contextless" (q: Quaternionf16) -> (t1, t2, t3: f16) {
|
||||
return euler_angles_zyx_from_matrix4(matrix4_from_quaternion(q))
|
||||
}
|
||||
euler_angles_zxy_from_quaternion_f16 :: proc(q: Quaternionf16) -> (t1, t2, t3: f16) {
|
||||
@(require_results)
|
||||
euler_angles_zxy_from_quaternion_f16 :: proc "contextless" (q: Quaternionf16) -> (t1, t2, t3: f16) {
|
||||
return euler_angles_zxy_from_matrix4(matrix4_from_quaternion(q))
|
||||
}
|
||||
|
||||
@@ -210,7 +236,8 @@ euler_angles_zxy_from_quaternion_f16 :: proc(q: Quaternionf16) -> (t1, t2, t3: f
|
||||
// Matrix3
|
||||
|
||||
|
||||
matrix3_from_euler_angle_x_f16 :: proc(angle_x: f16) -> (m: Matrix3f16) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angle_x_f16 :: proc "contextless" (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
|
||||
@@ -219,7 +246,8 @@ matrix3_from_euler_angle_x_f16 :: proc(angle_x: f16) -> (m: Matrix3f16) {
|
||||
m[2, 2] = +cos_x
|
||||
return
|
||||
}
|
||||
matrix3_from_euler_angle_y_f16 :: proc(angle_y: f16) -> (m: Matrix3f16) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angle_y_f16 :: proc "contextless" (angle_y: f16) -> (m: Matrix3f16) {
|
||||
cos_y, sin_y := math.cos(angle_y), math.sin(angle_y)
|
||||
m[0, 0] = +cos_y
|
||||
m[0, 2] = -sin_y
|
||||
@@ -228,7 +256,8 @@ matrix3_from_euler_angle_y_f16 :: proc(angle_y: f16) -> (m: Matrix3f16) {
|
||||
m[2, 2] = +cos_y
|
||||
return
|
||||
}
|
||||
matrix3_from_euler_angle_z_f16 :: proc(angle_z: f16) -> (m: Matrix3f16) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angle_z_f16 :: proc "contextless" (angle_z: f16) -> (m: Matrix3f16) {
|
||||
cos_z, sin_z := math.cos(angle_z), math.sin(angle_z)
|
||||
m[0, 0] = +cos_z
|
||||
m[0, 1] = +sin_z
|
||||
@@ -239,7 +268,8 @@ matrix3_from_euler_angle_z_f16 :: proc(angle_z: f16) -> (m: Matrix3f16) {
|
||||
}
|
||||
|
||||
|
||||
matrix3_from_derived_euler_angle_x_f16 :: proc(angle_x: f16, angular_velocity_x: f16) -> (m: Matrix3f16) {
|
||||
@(require_results)
|
||||
matrix3_from_derived_euler_angle_x_f16 :: proc "contextless" (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
|
||||
@@ -249,7 +279,8 @@ matrix3_from_derived_euler_angle_x_f16 :: proc(angle_x: f16, angular_velocity_x:
|
||||
m[2, 2] = +cos_x
|
||||
return
|
||||
}
|
||||
matrix3_from_derived_euler_angle_y_f16 :: proc(angle_y: f16, angular_velocity_y: f16) -> (m: Matrix3f16) {
|
||||
@(require_results)
|
||||
matrix3_from_derived_euler_angle_y_f16 :: proc "contextless" (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
|
||||
@@ -259,7 +290,8 @@ matrix3_from_derived_euler_angle_y_f16 :: proc(angle_y: f16, angular_velocity_y:
|
||||
m[2, 2] = +cos_y
|
||||
return
|
||||
}
|
||||
matrix3_from_derived_euler_angle_z_f16 :: proc(angle_z: f16, angular_velocity_z: f16) -> (m: Matrix3f16) {
|
||||
@(require_results)
|
||||
matrix3_from_derived_euler_angle_z_f16 :: proc "contextless" (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
|
||||
@@ -271,7 +303,8 @@ matrix3_from_derived_euler_angle_z_f16 :: proc(angle_z: f16, angular_velocity_z:
|
||||
}
|
||||
|
||||
|
||||
matrix3_from_euler_angles_xy_f16 :: proc(angle_x, angle_y: f16) -> (m: Matrix3f16) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angles_xy_f16 :: proc "contextless" (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
|
||||
@@ -286,7 +319,8 @@ matrix3_from_euler_angles_xy_f16 :: proc(angle_x, angle_y: f16) -> (m: Matrix3f1
|
||||
}
|
||||
|
||||
|
||||
matrix3_from_euler_angles_yx_f16 :: proc(angle_y, angle_x: f16) -> (m: Matrix3f16) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angles_yx_f16 :: proc "contextless" (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
|
||||
@@ -300,21 +334,26 @@ matrix3_from_euler_angles_yx_f16 :: proc(angle_y, angle_x: f16) -> (m: Matrix3f1
|
||||
return
|
||||
}
|
||||
|
||||
matrix3_from_euler_angles_xz_f16 :: proc(angle_x, angle_z: f16) -> (m: Matrix3f16) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angles_xz_f16 :: proc "contextless" (angle_x, angle_z: f16) -> (m: Matrix3f16) {
|
||||
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) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angles_zx_f16 :: proc "contextless" (angle_z, angle_x: f16) -> (m: Matrix3f16) {
|
||||
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) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angles_yz_f16 :: proc "contextless" (angle_y, angle_z: f16) -> (m: Matrix3f16) {
|
||||
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) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angles_zy_f16 :: proc "contextless" (angle_z, angle_y: f16) -> (m: Matrix3f16) {
|
||||
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) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angles_xyz_f16 :: proc "contextless" (t1, t2, t3: f16) -> (m: Matrix3f16) {
|
||||
c1 := math.cos(-t1)
|
||||
c2 := math.cos(-t2)
|
||||
c3 := math.cos(-t3)
|
||||
@@ -334,7 +373,8 @@ matrix3_from_euler_angles_xyz_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) {
|
||||
return
|
||||
}
|
||||
|
||||
matrix3_from_euler_angles_yxz_f16 :: proc(yaw, pitch, roll: f16) -> (m: Matrix3f16) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angles_yxz_f16 :: proc "contextless" (yaw, pitch, roll: f16) -> (m: Matrix3f16) {
|
||||
ch := math.cos(yaw)
|
||||
sh := math.sin(yaw)
|
||||
cp := math.cos(pitch)
|
||||
@@ -354,7 +394,8 @@ matrix3_from_euler_angles_yxz_f16 :: proc(yaw, pitch, roll: f16) -> (m: Matrix3f
|
||||
return
|
||||
}
|
||||
|
||||
matrix3_from_euler_angles_xzx_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angles_xzx_f16 :: proc "contextless" (t1, t2, t3: f16) -> (m: Matrix3f16) {
|
||||
c1 := math.cos(t1)
|
||||
s1 := math.sin(t1)
|
||||
c2 := math.cos(t2)
|
||||
@@ -374,7 +415,8 @@ matrix3_from_euler_angles_xzx_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) {
|
||||
return
|
||||
}
|
||||
|
||||
matrix3_from_euler_angles_xyx_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angles_xyx_f16 :: proc "contextless" (t1, t2, t3: f16) -> (m: Matrix3f16) {
|
||||
c1 := math.cos(t1)
|
||||
s1 := math.sin(t1)
|
||||
c2 := math.cos(t2)
|
||||
@@ -394,7 +436,8 @@ matrix3_from_euler_angles_xyx_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) {
|
||||
return
|
||||
}
|
||||
|
||||
matrix3_from_euler_angles_yxy_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angles_yxy_f16 :: proc "contextless" (t1, t2, t3: f16) -> (m: Matrix3f16) {
|
||||
c1 := math.cos(t1)
|
||||
s1 := math.sin(t1)
|
||||
c2 := math.cos(t2)
|
||||
@@ -414,7 +457,8 @@ matrix3_from_euler_angles_yxy_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) {
|
||||
return
|
||||
}
|
||||
|
||||
matrix3_from_euler_angles_yzy_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angles_yzy_f16 :: proc "contextless" (t1, t2, t3: f16) -> (m: Matrix3f16) {
|
||||
c1 := math.cos(t1)
|
||||
s1 := math.sin(t1)
|
||||
c2 := math.cos(t2)
|
||||
@@ -434,7 +478,8 @@ matrix3_from_euler_angles_yzy_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) {
|
||||
return
|
||||
}
|
||||
|
||||
matrix3_from_euler_angles_zyz_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angles_zyz_f16 :: proc "contextless" (t1, t2, t3: f16) -> (m: Matrix3f16) {
|
||||
c1 := math.cos(t1)
|
||||
s1 := math.sin(t1)
|
||||
c2 := math.cos(t2)
|
||||
@@ -454,7 +499,8 @@ matrix3_from_euler_angles_zyz_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) {
|
||||
return
|
||||
}
|
||||
|
||||
matrix3_from_euler_angles_zxz_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angles_zxz_f16 :: proc "contextless" (t1, t2, t3: f16) -> (m: Matrix3f16) {
|
||||
c1 := math.cos(t1)
|
||||
s1 := math.sin(t1)
|
||||
c2 := math.cos(t2)
|
||||
@@ -475,7 +521,8 @@ matrix3_from_euler_angles_zxz_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) {
|
||||
}
|
||||
|
||||
|
||||
matrix3_from_euler_angles_xzy_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angles_xzy_f16 :: proc "contextless" (t1, t2, t3: f16) -> (m: Matrix3f16) {
|
||||
c1 := math.cos(t1)
|
||||
s1 := math.sin(t1)
|
||||
c2 := math.cos(t2)
|
||||
@@ -495,7 +542,8 @@ matrix3_from_euler_angles_xzy_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) {
|
||||
return
|
||||
}
|
||||
|
||||
matrix3_from_euler_angles_yzx_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angles_yzx_f16 :: proc "contextless" (t1, t2, t3: f16) -> (m: Matrix3f16) {
|
||||
c1 := math.cos(t1)
|
||||
s1 := math.sin(t1)
|
||||
c2 := math.cos(t2)
|
||||
@@ -515,7 +563,8 @@ matrix3_from_euler_angles_yzx_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) {
|
||||
return
|
||||
}
|
||||
|
||||
matrix3_from_euler_angles_zyx_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angles_zyx_f16 :: proc "contextless" (t1, t2, t3: f16) -> (m: Matrix3f16) {
|
||||
c1 := math.cos(t1)
|
||||
s1 := math.sin(t1)
|
||||
c2 := math.cos(t2)
|
||||
@@ -535,7 +584,8 @@ matrix3_from_euler_angles_zyx_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) {
|
||||
return
|
||||
}
|
||||
|
||||
matrix3_from_euler_angles_zxy_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angles_zxy_f16 :: proc "contextless" (t1, t2, t3: f16) -> (m: Matrix3f16) {
|
||||
c1 := math.cos(t1)
|
||||
s1 := math.sin(t1)
|
||||
c2 := math.cos(t2)
|
||||
@@ -556,7 +606,8 @@ matrix3_from_euler_angles_zxy_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) {
|
||||
}
|
||||
|
||||
|
||||
matrix3_from_yaw_pitch_roll_f16 :: proc(yaw, pitch, roll: f16) -> (m: Matrix3f16) {
|
||||
@(require_results)
|
||||
matrix3_from_yaw_pitch_roll_f16 :: proc "contextless" (yaw, pitch, roll: f16) -> (m: Matrix3f16) {
|
||||
ch := math.cos(yaw)
|
||||
sh := math.sin(yaw)
|
||||
cp := math.cos(pitch)
|
||||
@@ -576,7 +627,8 @@ matrix3_from_yaw_pitch_roll_f16 :: proc(yaw, pitch, roll: f16) -> (m: Matrix3f16
|
||||
return m
|
||||
}
|
||||
|
||||
euler_angles_xyz_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) {
|
||||
@(require_results)
|
||||
euler_angles_xyz_from_matrix3_f16 :: proc "contextless" (m: Matrix3f16) -> (t1, t2, t3: f16) {
|
||||
T1 := math.atan2(m[1, 2], m[2, 2])
|
||||
C2 := math.sqrt(m[0, 0]*m[0, 0] + m[0, 1]*m[0, 1])
|
||||
T2 := math.atan2(-m[0, 2], C2)
|
||||
@@ -589,7 +641,8 @@ euler_angles_xyz_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) {
|
||||
return
|
||||
}
|
||||
|
||||
euler_angles_yxz_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) {
|
||||
@(require_results)
|
||||
euler_angles_yxz_from_matrix3_f16 :: proc "contextless" (m: Matrix3f16) -> (t1, t2, t3: f16) {
|
||||
T1 := math.atan2(m[0, 2], m[2, 2])
|
||||
C2 := math.sqrt(m[1, 0]*m[1, 0] + m[1, 1]*m[1, 1])
|
||||
T2 := math.atan2(-m[1, 2], C2)
|
||||
@@ -602,7 +655,8 @@ euler_angles_yxz_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) {
|
||||
return
|
||||
}
|
||||
|
||||
euler_angles_xzx_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) {
|
||||
@(require_results)
|
||||
euler_angles_xzx_from_matrix3_f16 :: proc "contextless" (m: Matrix3f16) -> (t1, t2, t3: f16) {
|
||||
T1 := math.atan2(m[2, 0], m[1, 0])
|
||||
S2 := math.sqrt(m[0, 1]*m[0, 1] + m[0, 2]*m[0, 2])
|
||||
T2 := math.atan2(S2, m[0, 0])
|
||||
@@ -615,7 +669,8 @@ euler_angles_xzx_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) {
|
||||
return
|
||||
}
|
||||
|
||||
euler_angles_xyx_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) {
|
||||
@(require_results)
|
||||
euler_angles_xyx_from_matrix3_f16 :: proc "contextless" (m: Matrix3f16) -> (t1, t2, t3: f16) {
|
||||
T1 := math.atan2(m[1, 0], -m[2, 0])
|
||||
S2 := math.sqrt(m[0, 1]*m[0, 1] + m[0, 2]*m[0, 2])
|
||||
T2 := math.atan2(S2, m[0, 0])
|
||||
@@ -628,7 +683,8 @@ euler_angles_xyx_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) {
|
||||
return
|
||||
}
|
||||
|
||||
euler_angles_yxy_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) {
|
||||
@(require_results)
|
||||
euler_angles_yxy_from_matrix3_f16 :: proc "contextless" (m: Matrix3f16) -> (t1, t2, t3: f16) {
|
||||
T1 := math.atan2(m[0, 1], m[2, 1])
|
||||
S2 := math.sqrt(m[1, 0]*m[1, 0] + m[1, 2]*m[1, 2])
|
||||
T2 := math.atan2(S2, m[1, 1])
|
||||
@@ -641,7 +697,8 @@ euler_angles_yxy_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) {
|
||||
return
|
||||
}
|
||||
|
||||
euler_angles_yzy_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) {
|
||||
@(require_results)
|
||||
euler_angles_yzy_from_matrix3_f16 :: proc "contextless" (m: Matrix3f16) -> (t1, t2, t3: f16) {
|
||||
T1 := math.atan2(m[2, 1], -m[0, 1])
|
||||
S2 := math.sqrt(m[1, 0]*m[1, 0] + m[1, 2]*m[1, 2])
|
||||
T2 := math.atan2(S2, m[1, 1])
|
||||
@@ -653,7 +710,8 @@ euler_angles_yzy_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) {
|
||||
t3 = T3
|
||||
return
|
||||
}
|
||||
euler_angles_zyz_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) {
|
||||
@(require_results)
|
||||
euler_angles_zyz_from_matrix3_f16 :: proc "contextless" (m: Matrix3f16) -> (t1, t2, t3: f16) {
|
||||
T1 := math.atan2(m[1, 2], m[0, 2])
|
||||
S2 := math.sqrt(m[2, 0]*m[2, 0] + m[2, 1]*m[2, 1])
|
||||
T2 := math.atan2(S2, m[2, 2])
|
||||
@@ -666,7 +724,8 @@ euler_angles_zyz_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) {
|
||||
return
|
||||
}
|
||||
|
||||
euler_angles_zxz_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) {
|
||||
@(require_results)
|
||||
euler_angles_zxz_from_matrix3_f16 :: proc "contextless" (m: Matrix3f16) -> (t1, t2, t3: f16) {
|
||||
T1 := math.atan2(m[0, 2], -m[1, 2])
|
||||
S2 := math.sqrt(m[2, 0]*m[2, 0] + m[2, 1]*m[2, 1])
|
||||
T2 := math.atan2(S2, m[2, 2])
|
||||
@@ -679,7 +738,8 @@ euler_angles_zxz_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) {
|
||||
return
|
||||
}
|
||||
|
||||
euler_angles_xzy_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) {
|
||||
@(require_results)
|
||||
euler_angles_xzy_from_matrix3_f16 :: proc "contextless" (m: Matrix3f16) -> (t1, t2, t3: f16) {
|
||||
T1 := math.atan2(m[2, 1], m[1, 1])
|
||||
C2 := math.sqrt(m[0, 0]*m[0, 0] + m[0, 2]*m[0, 2])
|
||||
T2 := math.atan2(-m[0, 1], C2)
|
||||
@@ -692,7 +752,8 @@ euler_angles_xzy_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) {
|
||||
return
|
||||
}
|
||||
|
||||
euler_angles_yzx_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) {
|
||||
@(require_results)
|
||||
euler_angles_yzx_from_matrix3_f16 :: proc "contextless" (m: Matrix3f16) -> (t1, t2, t3: f16) {
|
||||
T1 := math.atan2(-m[2, 0], m[0, 0])
|
||||
C2 := math.sqrt(m[1, 1]*m[1, 1] + m[1, 2]*m[1, 2])
|
||||
T2 := math.atan2(m[1, 0], C2)
|
||||
@@ -705,7 +766,8 @@ euler_angles_yzx_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) {
|
||||
return
|
||||
}
|
||||
|
||||
euler_angles_zyx_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) {
|
||||
@(require_results)
|
||||
euler_angles_zyx_from_matrix3_f16 :: proc "contextless" (m: Matrix3f16) -> (t1, t2, t3: f16) {
|
||||
T1 := math.atan2(m[1, 0], m[0, 0])
|
||||
C2 := math.sqrt(m[2, 1]*m[2, 1] + m[2, 2]*m[2, 2])
|
||||
T2 := math.atan2(-m[2, 0], C2)
|
||||
@@ -718,7 +780,8 @@ euler_angles_zyx_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) {
|
||||
return
|
||||
}
|
||||
|
||||
euler_angles_zxy_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) {
|
||||
@(require_results)
|
||||
euler_angles_zxy_from_matrix3_f16 :: proc "contextless" (m: Matrix3f16) -> (t1, t2, t3: f16) {
|
||||
T1 := math.atan2(-m[0, 1], m[1, 1])
|
||||
C2 := math.sqrt(m[2, 0]*m[2, 0] + m[2, 2]*m[2, 2])
|
||||
T2 := math.atan2(m[2, 1], C2)
|
||||
@@ -735,7 +798,8 @@ euler_angles_zxy_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) {
|
||||
// Matrix4
|
||||
|
||||
|
||||
matrix4_from_euler_angle_x_f16 :: proc(angle_x: f16) -> (m: Matrix4f16) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angle_x_f16 :: proc "contextless" (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
|
||||
@@ -745,7 +809,8 @@ matrix4_from_euler_angle_x_f16 :: proc(angle_x: f16) -> (m: Matrix4f16) {
|
||||
m[3, 3] = 1
|
||||
return
|
||||
}
|
||||
matrix4_from_euler_angle_y_f16 :: proc(angle_y: f16) -> (m: Matrix4f16) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angle_y_f16 :: proc "contextless" (angle_y: f16) -> (m: Matrix4f16) {
|
||||
cos_y, sin_y := math.cos(angle_y), math.sin(angle_y)
|
||||
m[0, 0] = +cos_y
|
||||
m[0, 2] = -sin_y
|
||||
@@ -755,7 +820,8 @@ matrix4_from_euler_angle_y_f16 :: proc(angle_y: f16) -> (m: Matrix4f16) {
|
||||
m[3, 3] = 1
|
||||
return
|
||||
}
|
||||
matrix4_from_euler_angle_z_f16 :: proc(angle_z: f16) -> (m: Matrix4f16) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angle_z_f16 :: proc "contextless" (angle_z: f16) -> (m: Matrix4f16) {
|
||||
cos_z, sin_z := math.cos(angle_z), math.sin(angle_z)
|
||||
m[0, 0] = +cos_z
|
||||
m[0, 1] = +sin_z
|
||||
@@ -767,7 +833,8 @@ matrix4_from_euler_angle_z_f16 :: proc(angle_z: f16) -> (m: Matrix4f16) {
|
||||
}
|
||||
|
||||
|
||||
matrix4_from_derived_euler_angle_x_f16 :: proc(angle_x: f16, angular_velocity_x: f16) -> (m: Matrix4f16) {
|
||||
@(require_results)
|
||||
matrix4_from_derived_euler_angle_x_f16 :: proc "contextless" (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
|
||||
@@ -778,7 +845,8 @@ matrix4_from_derived_euler_angle_x_f16 :: proc(angle_x: f16, angular_velocity_x:
|
||||
m[3, 3] = 1
|
||||
return
|
||||
}
|
||||
matrix4_from_derived_euler_angle_y_f16 :: proc(angle_y: f16, angular_velocity_y: f16) -> (m: Matrix4f16) {
|
||||
@(require_results)
|
||||
matrix4_from_derived_euler_angle_y_f16 :: proc "contextless" (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
|
||||
@@ -789,7 +857,8 @@ matrix4_from_derived_euler_angle_y_f16 :: proc(angle_y: f16, angular_velocity_y:
|
||||
m[3, 3] = 1
|
||||
return
|
||||
}
|
||||
matrix4_from_derived_euler_angle_z_f16 :: proc(angle_z: f16, angular_velocity_z: f16) -> (m: Matrix4f16) {
|
||||
@(require_results)
|
||||
matrix4_from_derived_euler_angle_z_f16 :: proc "contextless" (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
|
||||
@@ -802,7 +871,8 @@ matrix4_from_derived_euler_angle_z_f16 :: proc(angle_z: f16, angular_velocity_z:
|
||||
}
|
||||
|
||||
|
||||
matrix4_from_euler_angles_xy_f16 :: proc(angle_x, angle_y: f16) -> (m: Matrix4f16) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angles_xy_f16 :: proc "contextless" (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
|
||||
@@ -818,7 +888,8 @@ matrix4_from_euler_angles_xy_f16 :: proc(angle_x, angle_y: f16) -> (m: Matrix4f1
|
||||
}
|
||||
|
||||
|
||||
matrix4_from_euler_angles_yx_f16 :: proc(angle_y, angle_x: f16) -> (m: Matrix4f16) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angles_yx_f16 :: proc "contextless" (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
|
||||
@@ -833,21 +904,26 @@ matrix4_from_euler_angles_yx_f16 :: proc(angle_y, angle_x: f16) -> (m: Matrix4f1
|
||||
return
|
||||
}
|
||||
|
||||
matrix4_from_euler_angles_xz_f16 :: proc(angle_x, angle_z: f16) -> (m: Matrix4f16) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angles_xz_f16 :: proc "contextless" (angle_x, angle_z: f16) -> (m: Matrix4f16) {
|
||||
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) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angles_zx_f16 :: proc "contextless" (angle_z, angle_x: f16) -> (m: Matrix4f16) {
|
||||
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) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angles_yz_f16 :: proc "contextless" (angle_y, angle_z: f16) -> (m: Matrix4f16) {
|
||||
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) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angles_zy_f16 :: proc "contextless" (angle_z, angle_y: f16) -> (m: Matrix4f16) {
|
||||
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) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angles_xyz_f16 :: proc "contextless" (t1, t2, t3: f16) -> (m: Matrix4f16) {
|
||||
c1 := math.cos(-t1)
|
||||
c2 := math.cos(-t2)
|
||||
c3 := math.cos(-t3)
|
||||
@@ -874,7 +950,8 @@ matrix4_from_euler_angles_xyz_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) {
|
||||
return
|
||||
}
|
||||
|
||||
matrix4_from_euler_angles_yxz_f16 :: proc(yaw, pitch, roll: f16) -> (m: Matrix4f16) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angles_yxz_f16 :: proc "contextless" (yaw, pitch, roll: f16) -> (m: Matrix4f16) {
|
||||
ch := math.cos(yaw)
|
||||
sh := math.sin(yaw)
|
||||
cp := math.cos(pitch)
|
||||
@@ -901,7 +978,8 @@ matrix4_from_euler_angles_yxz_f16 :: proc(yaw, pitch, roll: f16) -> (m: Matrix4f
|
||||
return
|
||||
}
|
||||
|
||||
matrix4_from_euler_angles_xzx_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angles_xzx_f16 :: proc "contextless" (t1, t2, t3: f16) -> (m: Matrix4f16) {
|
||||
c1 := math.cos(t1)
|
||||
s1 := math.sin(t1)
|
||||
c2 := math.cos(t2)
|
||||
@@ -928,7 +1006,8 @@ matrix4_from_euler_angles_xzx_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) {
|
||||
return
|
||||
}
|
||||
|
||||
matrix4_from_euler_angles_xyx_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angles_xyx_f16 :: proc "contextless" (t1, t2, t3: f16) -> (m: Matrix4f16) {
|
||||
c1 := math.cos(t1)
|
||||
s1 := math.sin(t1)
|
||||
c2 := math.cos(t2)
|
||||
@@ -955,7 +1034,8 @@ matrix4_from_euler_angles_xyx_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) {
|
||||
return
|
||||
}
|
||||
|
||||
matrix4_from_euler_angles_yxy_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angles_yxy_f16 :: proc "contextless" (t1, t2, t3: f16) -> (m: Matrix4f16) {
|
||||
c1 := math.cos(t1)
|
||||
s1 := math.sin(t1)
|
||||
c2 := math.cos(t2)
|
||||
@@ -982,7 +1062,8 @@ matrix4_from_euler_angles_yxy_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) {
|
||||
return
|
||||
}
|
||||
|
||||
matrix4_from_euler_angles_yzy_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angles_yzy_f16 :: proc "contextless" (t1, t2, t3: f16) -> (m: Matrix4f16) {
|
||||
c1 := math.cos(t1)
|
||||
s1 := math.sin(t1)
|
||||
c2 := math.cos(t2)
|
||||
@@ -1009,7 +1090,8 @@ matrix4_from_euler_angles_yzy_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) {
|
||||
return
|
||||
}
|
||||
|
||||
matrix4_from_euler_angles_zyz_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angles_zyz_f16 :: proc "contextless" (t1, t2, t3: f16) -> (m: Matrix4f16) {
|
||||
c1 := math.cos(t1)
|
||||
s1 := math.sin(t1)
|
||||
c2 := math.cos(t2)
|
||||
@@ -1036,7 +1118,8 @@ matrix4_from_euler_angles_zyz_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) {
|
||||
return
|
||||
}
|
||||
|
||||
matrix4_from_euler_angles_zxz_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angles_zxz_f16 :: proc "contextless" (t1, t2, t3: f16) -> (m: Matrix4f16) {
|
||||
c1 := math.cos(t1)
|
||||
s1 := math.sin(t1)
|
||||
c2 := math.cos(t2)
|
||||
@@ -1064,7 +1147,8 @@ matrix4_from_euler_angles_zxz_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) {
|
||||
}
|
||||
|
||||
|
||||
matrix4_from_euler_angles_xzy_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angles_xzy_f16 :: proc "contextless" (t1, t2, t3: f16) -> (m: Matrix4f16) {
|
||||
c1 := math.cos(t1)
|
||||
s1 := math.sin(t1)
|
||||
c2 := math.cos(t2)
|
||||
@@ -1091,7 +1175,8 @@ matrix4_from_euler_angles_xzy_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) {
|
||||
return
|
||||
}
|
||||
|
||||
matrix4_from_euler_angles_yzx_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angles_yzx_f16 :: proc "contextless" (t1, t2, t3: f16) -> (m: Matrix4f16) {
|
||||
c1 := math.cos(t1)
|
||||
s1 := math.sin(t1)
|
||||
c2 := math.cos(t2)
|
||||
@@ -1118,7 +1203,8 @@ matrix4_from_euler_angles_yzx_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) {
|
||||
return
|
||||
}
|
||||
|
||||
matrix4_from_euler_angles_zyx_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angles_zyx_f16 :: proc "contextless" (t1, t2, t3: f16) -> (m: Matrix4f16) {
|
||||
c1 := math.cos(t1)
|
||||
s1 := math.sin(t1)
|
||||
c2 := math.cos(t2)
|
||||
@@ -1145,7 +1231,8 @@ matrix4_from_euler_angles_zyx_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) {
|
||||
return
|
||||
}
|
||||
|
||||
matrix4_from_euler_angles_zxy_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angles_zxy_f16 :: proc "contextless" (t1, t2, t3: f16) -> (m: Matrix4f16) {
|
||||
c1 := math.cos(t1)
|
||||
s1 := math.sin(t1)
|
||||
c2 := math.cos(t2)
|
||||
@@ -1173,7 +1260,8 @@ matrix4_from_euler_angles_zxy_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) {
|
||||
}
|
||||
|
||||
|
||||
matrix4_from_yaw_pitch_roll_f16 :: proc(yaw, pitch, roll: f16) -> (m: Matrix4f16) {
|
||||
@(require_results)
|
||||
matrix4_from_yaw_pitch_roll_f16 :: proc "contextless" (yaw, pitch, roll: f16) -> (m: Matrix4f16) {
|
||||
ch := math.cos(yaw)
|
||||
sh := math.sin(yaw)
|
||||
cp := math.cos(pitch)
|
||||
@@ -1200,7 +1288,8 @@ matrix4_from_yaw_pitch_roll_f16 :: proc(yaw, pitch, roll: f16) -> (m: Matrix4f16
|
||||
return m
|
||||
}
|
||||
|
||||
euler_angles_xyz_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) {
|
||||
@(require_results)
|
||||
euler_angles_xyz_from_matrix4_f16 :: proc "contextless" (m: Matrix4f16) -> (t1, t2, t3: f16) {
|
||||
T1 := math.atan2(m[1, 2], m[2, 2])
|
||||
C2 := math.sqrt(m[0, 0]*m[0, 0] + m[0, 1]*m[0, 1])
|
||||
T2 := math.atan2(-m[0, 2], C2)
|
||||
@@ -1213,7 +1302,8 @@ euler_angles_xyz_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) {
|
||||
return
|
||||
}
|
||||
|
||||
euler_angles_yxz_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) {
|
||||
@(require_results)
|
||||
euler_angles_yxz_from_matrix4_f16 :: proc "contextless" (m: Matrix4f16) -> (t1, t2, t3: f16) {
|
||||
T1 := math.atan2(m[0, 2], m[2, 2])
|
||||
C2 := math.sqrt(m[1, 0]*m[1, 0] + m[1, 1]*m[1, 1])
|
||||
T2 := math.atan2(-m[1, 2], C2)
|
||||
@@ -1226,7 +1316,8 @@ euler_angles_yxz_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) {
|
||||
return
|
||||
}
|
||||
|
||||
euler_angles_xzx_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) {
|
||||
@(require_results)
|
||||
euler_angles_xzx_from_matrix4_f16 :: proc "contextless" (m: Matrix4f16) -> (t1, t2, t3: f16) {
|
||||
T1 := math.atan2(m[2, 0], m[1, 0])
|
||||
S2 := math.sqrt(m[0, 1]*m[0, 1] + m[0, 2]*m[0, 2])
|
||||
T2 := math.atan2(S2, m[0, 0])
|
||||
@@ -1239,7 +1330,8 @@ euler_angles_xzx_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) {
|
||||
return
|
||||
}
|
||||
|
||||
euler_angles_xyx_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) {
|
||||
@(require_results)
|
||||
euler_angles_xyx_from_matrix4_f16 :: proc "contextless" (m: Matrix4f16) -> (t1, t2, t3: f16) {
|
||||
T1 := math.atan2(m[1, 0], -m[2, 0])
|
||||
S2 := math.sqrt(m[0, 1]*m[0, 1] + m[0, 2]*m[0, 2])
|
||||
T2 := math.atan2(S2, m[0, 0])
|
||||
@@ -1252,7 +1344,8 @@ euler_angles_xyx_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) {
|
||||
return
|
||||
}
|
||||
|
||||
euler_angles_yxy_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) {
|
||||
@(require_results)
|
||||
euler_angles_yxy_from_matrix4_f16 :: proc "contextless" (m: Matrix4f16) -> (t1, t2, t3: f16) {
|
||||
T1 := math.atan2(m[0, 1], m[2, 1])
|
||||
S2 := math.sqrt(m[1, 0]*m[1, 0] + m[1, 2]*m[1, 2])
|
||||
T2 := math.atan2(S2, m[1, 1])
|
||||
@@ -1265,7 +1358,8 @@ euler_angles_yxy_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) {
|
||||
return
|
||||
}
|
||||
|
||||
euler_angles_yzy_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) {
|
||||
@(require_results)
|
||||
euler_angles_yzy_from_matrix4_f16 :: proc "contextless" (m: Matrix4f16) -> (t1, t2, t3: f16) {
|
||||
T1 := math.atan2(m[2, 1], -m[0, 1])
|
||||
S2 := math.sqrt(m[1, 0]*m[1, 0] + m[1, 2]*m[1, 2])
|
||||
T2 := math.atan2(S2, m[1, 1])
|
||||
@@ -1277,7 +1371,8 @@ euler_angles_yzy_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) {
|
||||
t3 = T3
|
||||
return
|
||||
}
|
||||
euler_angles_zyz_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) {
|
||||
@(require_results)
|
||||
euler_angles_zyz_from_matrix4_f16 :: proc "contextless" (m: Matrix4f16) -> (t1, t2, t3: f16) {
|
||||
T1 := math.atan2(m[1, 2], m[0, 2])
|
||||
S2 := math.sqrt(m[2, 0]*m[2, 0] + m[2, 1]*m[2, 1])
|
||||
T2 := math.atan2(S2, m[2, 2])
|
||||
@@ -1290,7 +1385,8 @@ euler_angles_zyz_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) {
|
||||
return
|
||||
}
|
||||
|
||||
euler_angles_zxz_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) {
|
||||
@(require_results)
|
||||
euler_angles_zxz_from_matrix4_f16 :: proc "contextless" (m: Matrix4f16) -> (t1, t2, t3: f16) {
|
||||
T1 := math.atan2(m[0, 2], -m[1, 2])
|
||||
S2 := math.sqrt(m[2, 0]*m[2, 0] + m[2, 1]*m[2, 1])
|
||||
T2 := math.atan2(S2, m[2, 2])
|
||||
@@ -1303,7 +1399,8 @@ euler_angles_zxz_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) {
|
||||
return
|
||||
}
|
||||
|
||||
euler_angles_xzy_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) {
|
||||
@(require_results)
|
||||
euler_angles_xzy_from_matrix4_f16 :: proc "contextless" (m: Matrix4f16) -> (t1, t2, t3: f16) {
|
||||
T1 := math.atan2(m[2, 1], m[1, 1])
|
||||
C2 := math.sqrt(m[0, 0]*m[0, 0] + m[0, 2]*m[0, 2])
|
||||
T2 := math.atan2(-m[0, 1], C2)
|
||||
@@ -1316,7 +1413,8 @@ euler_angles_xzy_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) {
|
||||
return
|
||||
}
|
||||
|
||||
euler_angles_yzx_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) {
|
||||
@(require_results)
|
||||
euler_angles_yzx_from_matrix4_f16 :: proc "contextless" (m: Matrix4f16) -> (t1, t2, t3: f16) {
|
||||
T1 := math.atan2(-m[2, 0], m[0, 0])
|
||||
C2 := math.sqrt(m[1, 1]*m[1, 1] + m[1, 2]*m[1, 2])
|
||||
T2 := math.atan2(m[1, 0], C2)
|
||||
@@ -1329,7 +1427,8 @@ euler_angles_yzx_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) {
|
||||
return
|
||||
}
|
||||
|
||||
euler_angles_zyx_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) {
|
||||
@(require_results)
|
||||
euler_angles_zyx_from_matrix4_f16 :: proc "contextless" (m: Matrix4f16) -> (t1, t2, t3: f16) {
|
||||
T1 := math.atan2(m[1, 0], m[0, 0])
|
||||
C2 := math.sqrt(m[2, 1]*m[2, 1] + m[2, 2]*m[2, 2])
|
||||
T2 := math.atan2(-m[2, 0], C2)
|
||||
@@ -1342,7 +1441,8 @@ euler_angles_zyx_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) {
|
||||
return
|
||||
}
|
||||
|
||||
euler_angles_zxy_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) {
|
||||
@(require_results)
|
||||
euler_angles_zxy_from_matrix4_f16 :: proc "contextless" (m: Matrix4f16) -> (t1, t2, t3: f16) {
|
||||
T1 := math.atan2(-m[0, 1], m[1, 1])
|
||||
C2 := math.sqrt(m[2, 0]*m[2, 0] + m[2, 2]*m[2, 2])
|
||||
T2 := math.atan2(m[2, 1], C2)
|
||||
|
||||
@@ -2,7 +2,8 @@ package linalg
|
||||
|
||||
import "core:math"
|
||||
|
||||
euler_angles_from_matrix3_f32 :: proc(m: Matrix3f32, order: Euler_Angle_Order) -> (t1, t2, t3: f32) {
|
||||
@(require_results)
|
||||
euler_angles_from_matrix3_f32 :: proc "contextless" (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)
|
||||
@@ -19,7 +20,8 @@ euler_angles_from_matrix3_f32 :: proc(m: Matrix3f32, order: Euler_Angle_Order) -
|
||||
}
|
||||
return
|
||||
}
|
||||
euler_angles_from_matrix4_f32 :: proc(m: Matrix4f32, order: Euler_Angle_Order) -> (t1, t2, t3: f32) {
|
||||
@(require_results)
|
||||
euler_angles_from_matrix4_f32 :: proc "contextless" (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)
|
||||
@@ -36,7 +38,8 @@ euler_angles_from_matrix4_f32 :: proc(m: Matrix4f32, order: Euler_Angle_Order) -
|
||||
}
|
||||
return
|
||||
}
|
||||
euler_angles_from_quaternion_f32 :: proc(m: Quaternionf32, order: Euler_Angle_Order) -> (t1, t2, t3: f32) {
|
||||
@(require_results)
|
||||
euler_angles_from_quaternion_f32 :: proc "contextless" (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)
|
||||
@@ -54,7 +57,8 @@ euler_angles_from_quaternion_f32 :: proc(m: Quaternionf32, order: Euler_Angle_Or
|
||||
return
|
||||
}
|
||||
|
||||
matrix3_from_euler_angles_f32 :: proc(t1, t2, t3: f32, order: Euler_Angle_Order) -> (m: Matrix3f32) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angles_f32 :: proc "contextless" (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);
|
||||
@@ -71,7 +75,8 @@ matrix3_from_euler_angles_f32 :: proc(t1, t2, t3: f32, order: Euler_Angle_Order)
|
||||
}
|
||||
return
|
||||
}
|
||||
matrix4_from_euler_angles_f32 :: proc(t1, t2, t3: f32, order: Euler_Angle_Order) -> (m: Matrix4f32) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angles_f32 :: proc "contextless" (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);
|
||||
@@ -89,7 +94,8 @@ matrix4_from_euler_angles_f32 :: proc(t1, t2, t3: f32, order: Euler_Angle_Order)
|
||||
return
|
||||
}
|
||||
|
||||
quaternion_from_euler_angles_f32 :: proc(t1, t2, t3: f32, order: Euler_Angle_Order) -> Quaternionf32 {
|
||||
@(require_results)
|
||||
quaternion_from_euler_angles_f32 :: proc "contextless" (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
|
||||
@@ -117,17 +123,21 @@ quaternion_from_euler_angles_f32 :: proc(t1, t2, t3: f32, order: Euler_Angle_Ord
|
||||
|
||||
// Quaternionf32s
|
||||
|
||||
quaternion_from_euler_angle_x_f32 :: proc(angle_x: f32) -> (q: Quaternionf32) {
|
||||
@(require_results)
|
||||
quaternion_from_euler_angle_x_f32 :: proc "contextless" (angle_x: f32) -> (q: Quaternionf32) {
|
||||
return quaternion_angle_axis_f32(angle_x, {1, 0, 0})
|
||||
}
|
||||
quaternion_from_euler_angle_y_f32 :: proc(angle_y: f32) -> (q: Quaternionf32) {
|
||||
@(require_results)
|
||||
quaternion_from_euler_angle_y_f32 :: proc "contextless" (angle_y: f32) -> (q: Quaternionf32) {
|
||||
return quaternion_angle_axis_f32(angle_y, {0, 1, 0})
|
||||
}
|
||||
quaternion_from_euler_angle_z_f32 :: proc(angle_z: f32) -> (q: Quaternionf32) {
|
||||
@(require_results)
|
||||
quaternion_from_euler_angle_z_f32 :: proc "contextless" (angle_z: f32) -> (q: Quaternionf32) {
|
||||
return quaternion_angle_axis_f32(angle_z, {0, 0, 1})
|
||||
}
|
||||
|
||||
quaternion_from_pitch_yaw_roll_f32 :: proc(pitch, yaw, roll: f32) -> Quaternionf32 {
|
||||
@(require_results)
|
||||
quaternion_from_pitch_yaw_roll_f32 :: proc "contextless" (pitch, yaw, roll: f32) -> Quaternionf32 {
|
||||
a, b, c := pitch, yaw, roll
|
||||
|
||||
ca, sa := math.cos(a*0.5), math.sin(a*0.5)
|
||||
@@ -142,11 +152,13 @@ quaternion_from_pitch_yaw_roll_f32 :: proc(pitch, yaw, roll: f32) -> Quaternionf
|
||||
return q
|
||||
}
|
||||
|
||||
roll_from_quaternion_f32 :: proc(q: Quaternionf32) -> f32 {
|
||||
@(require_results)
|
||||
roll_from_quaternion_f32 :: proc "contextless" (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)
|
||||
}
|
||||
|
||||
pitch_from_quaternion_f32 :: proc(q: Quaternionf32) -> f32 {
|
||||
@(require_results)
|
||||
pitch_from_quaternion_f32 :: proc "contextless" (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
|
||||
|
||||
@@ -157,52 +169,66 @@ pitch_from_quaternion_f32 :: proc(q: Quaternionf32) -> f32 {
|
||||
return math.atan2(y, x)
|
||||
}
|
||||
|
||||
yaw_from_quaternion_f32 :: proc(q: Quaternionf32) -> f32 {
|
||||
@(require_results)
|
||||
yaw_from_quaternion_f32 :: proc "contextless" (q: Quaternionf32) -> f32 {
|
||||
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) {
|
||||
@(require_results)
|
||||
pitch_yaw_roll_from_quaternion_f32 :: proc "contextless" (q: Quaternionf32) -> (pitch, yaw, roll: f32) {
|
||||
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) {
|
||||
@(require_results)
|
||||
euler_angles_xyz_from_quaternion_f32 :: proc "contextless" (q: Quaternionf32) -> (t1, t2, t3: f32) {
|
||||
return euler_angles_xyz_from_matrix4(matrix4_from_quaternion(q))
|
||||
}
|
||||
euler_angles_yxz_from_quaternion_f32 :: proc(q: Quaternionf32) -> (t1, t2, t3: f32) {
|
||||
@(require_results)
|
||||
euler_angles_yxz_from_quaternion_f32 :: proc "contextless" (q: Quaternionf32) -> (t1, t2, t3: f32) {
|
||||
return euler_angles_yxz_from_matrix4(matrix4_from_quaternion(q))
|
||||
}
|
||||
euler_angles_xzx_from_quaternion_f32 :: proc(q: Quaternionf32) -> (t1, t2, t3: f32) {
|
||||
@(require_results)
|
||||
euler_angles_xzx_from_quaternion_f32 :: proc "contextless" (q: Quaternionf32) -> (t1, t2, t3: f32) {
|
||||
return euler_angles_xzx_from_matrix4(matrix4_from_quaternion(q))
|
||||
}
|
||||
euler_angles_xyx_from_quaternion_f32 :: proc(q: Quaternionf32) -> (t1, t2, t3: f32) {
|
||||
@(require_results)
|
||||
euler_angles_xyx_from_quaternion_f32 :: proc "contextless" (q: Quaternionf32) -> (t1, t2, t3: f32) {
|
||||
return euler_angles_xyx_from_matrix4(matrix4_from_quaternion(q))
|
||||
}
|
||||
euler_angles_yxy_from_quaternion_f32 :: proc(q: Quaternionf32) -> (t1, t2, t3: f32) {
|
||||
@(require_results)
|
||||
euler_angles_yxy_from_quaternion_f32 :: proc "contextless" (q: Quaternionf32) -> (t1, t2, t3: f32) {
|
||||
return euler_angles_yxy_from_matrix4(matrix4_from_quaternion(q))
|
||||
}
|
||||
euler_angles_yzy_from_quaternion_f32 :: proc(q: Quaternionf32) -> (t1, t2, t3: f32) {
|
||||
@(require_results)
|
||||
euler_angles_yzy_from_quaternion_f32 :: proc "contextless" (q: Quaternionf32) -> (t1, t2, t3: f32) {
|
||||
return euler_angles_yzy_from_matrix4(matrix4_from_quaternion(q))
|
||||
}
|
||||
euler_angles_zyz_from_quaternion_f32 :: proc(q: Quaternionf32) -> (t1, t2, t3: f32) {
|
||||
@(require_results)
|
||||
euler_angles_zyz_from_quaternion_f32 :: proc "contextless" (q: Quaternionf32) -> (t1, t2, t3: f32) {
|
||||
return euler_angles_zyz_from_matrix4(matrix4_from_quaternion(q))
|
||||
}
|
||||
euler_angles_zxz_from_quaternion_f32 :: proc(q: Quaternionf32) -> (t1, t2, t3: f32) {
|
||||
@(require_results)
|
||||
euler_angles_zxz_from_quaternion_f32 :: proc "contextless" (q: Quaternionf32) -> (t1, t2, t3: f32) {
|
||||
return euler_angles_zxz_from_matrix4(matrix4_from_quaternion(q))
|
||||
}
|
||||
euler_angles_xzy_from_quaternion_f32 :: proc(q: Quaternionf32) -> (t1, t2, t3: f32) {
|
||||
@(require_results)
|
||||
euler_angles_xzy_from_quaternion_f32 :: proc "contextless" (q: Quaternionf32) -> (t1, t2, t3: f32) {
|
||||
return euler_angles_xzy_from_matrix4(matrix4_from_quaternion(q))
|
||||
}
|
||||
euler_angles_yzx_from_quaternion_f32 :: proc(q: Quaternionf32) -> (t1, t2, t3: f32) {
|
||||
@(require_results)
|
||||
euler_angles_yzx_from_quaternion_f32 :: proc "contextless" (q: Quaternionf32) -> (t1, t2, t3: f32) {
|
||||
return euler_angles_yzx_from_matrix4(matrix4_from_quaternion(q))
|
||||
}
|
||||
euler_angles_zyx_from_quaternion_f32 :: proc(q: Quaternionf32) -> (t1, t2, t3: f32) {
|
||||
@(require_results)
|
||||
euler_angles_zyx_from_quaternion_f32 :: proc "contextless" (q: Quaternionf32) -> (t1, t2, t3: f32) {
|
||||
return euler_angles_zyx_from_matrix4(matrix4_from_quaternion(q))
|
||||
}
|
||||
euler_angles_zxy_from_quaternion_f32 :: proc(q: Quaternionf32) -> (t1, t2, t3: f32) {
|
||||
@(require_results)
|
||||
euler_angles_zxy_from_quaternion_f32 :: proc "contextless" (q: Quaternionf32) -> (t1, t2, t3: f32) {
|
||||
return euler_angles_zxy_from_matrix4(matrix4_from_quaternion(q))
|
||||
}
|
||||
|
||||
@@ -210,7 +236,8 @@ euler_angles_zxy_from_quaternion_f32 :: proc(q: Quaternionf32) -> (t1, t2, t3: f
|
||||
// Matrix3
|
||||
|
||||
|
||||
matrix3_from_euler_angle_x_f32 :: proc(angle_x: f32) -> (m: Matrix3f32) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angle_x_f32 :: proc "contextless" (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
|
||||
@@ -219,7 +246,8 @@ matrix3_from_euler_angle_x_f32 :: proc(angle_x: f32) -> (m: Matrix3f32) {
|
||||
m[2, 2] = +cos_x
|
||||
return
|
||||
}
|
||||
matrix3_from_euler_angle_y_f32 :: proc(angle_y: f32) -> (m: Matrix3f32) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angle_y_f32 :: proc "contextless" (angle_y: f32) -> (m: Matrix3f32) {
|
||||
cos_y, sin_y := math.cos(angle_y), math.sin(angle_y)
|
||||
m[0, 0] = +cos_y
|
||||
m[0, 2] = -sin_y
|
||||
@@ -228,7 +256,8 @@ matrix3_from_euler_angle_y_f32 :: proc(angle_y: f32) -> (m: Matrix3f32) {
|
||||
m[2, 2] = +cos_y
|
||||
return
|
||||
}
|
||||
matrix3_from_euler_angle_z_f32 :: proc(angle_z: f32) -> (m: Matrix3f32) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angle_z_f32 :: proc "contextless" (angle_z: f32) -> (m: Matrix3f32) {
|
||||
cos_z, sin_z := math.cos(angle_z), math.sin(angle_z)
|
||||
m[0, 0] = +cos_z
|
||||
m[0, 1] = +sin_z
|
||||
@@ -239,7 +268,8 @@ matrix3_from_euler_angle_z_f32 :: proc(angle_z: f32) -> (m: Matrix3f32) {
|
||||
}
|
||||
|
||||
|
||||
matrix3_from_derived_euler_angle_x_f32 :: proc(angle_x: f32, angular_velocity_x: f32) -> (m: Matrix3f32) {
|
||||
@(require_results)
|
||||
matrix3_from_derived_euler_angle_x_f32 :: proc "contextless" (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
|
||||
@@ -249,7 +279,8 @@ matrix3_from_derived_euler_angle_x_f32 :: proc(angle_x: f32, angular_velocity_x:
|
||||
m[2, 2] = +cos_x
|
||||
return
|
||||
}
|
||||
matrix3_from_derived_euler_angle_y_f32 :: proc(angle_y: f32, angular_velocity_y: f32) -> (m: Matrix3f32) {
|
||||
@(require_results)
|
||||
matrix3_from_derived_euler_angle_y_f32 :: proc "contextless" (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
|
||||
@@ -259,7 +290,8 @@ matrix3_from_derived_euler_angle_y_f32 :: proc(angle_y: f32, angular_velocity_y:
|
||||
m[2, 2] = +cos_y
|
||||
return
|
||||
}
|
||||
matrix3_from_derived_euler_angle_z_f32 :: proc(angle_z: f32, angular_velocity_z: f32) -> (m: Matrix3f32) {
|
||||
@(require_results)
|
||||
matrix3_from_derived_euler_angle_z_f32 :: proc "contextless" (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
|
||||
@@ -271,7 +303,8 @@ matrix3_from_derived_euler_angle_z_f32 :: proc(angle_z: f32, angular_velocity_z:
|
||||
}
|
||||
|
||||
|
||||
matrix3_from_euler_angles_xy_f32 :: proc(angle_x, angle_y: f32) -> (m: Matrix3f32) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angles_xy_f32 :: proc "contextless" (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
|
||||
@@ -286,7 +319,8 @@ matrix3_from_euler_angles_xy_f32 :: proc(angle_x, angle_y: f32) -> (m: Matrix3f3
|
||||
}
|
||||
|
||||
|
||||
matrix3_from_euler_angles_yx_f32 :: proc(angle_y, angle_x: f32) -> (m: Matrix3f32) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angles_yx_f32 :: proc "contextless" (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
|
||||
@@ -300,21 +334,26 @@ matrix3_from_euler_angles_yx_f32 :: proc(angle_y, angle_x: f32) -> (m: Matrix3f3
|
||||
return
|
||||
}
|
||||
|
||||
matrix3_from_euler_angles_xz_f32 :: proc(angle_x, angle_z: f32) -> (m: Matrix3f32) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angles_xz_f32 :: proc "contextless" (angle_x, angle_z: f32) -> (m: Matrix3f32) {
|
||||
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) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angles_zx_f32 :: proc "contextless" (angle_z, angle_x: f32) -> (m: Matrix3f32) {
|
||||
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) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angles_yz_f32 :: proc "contextless" (angle_y, angle_z: f32) -> (m: Matrix3f32) {
|
||||
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) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angles_zy_f32 :: proc "contextless" (angle_z, angle_y: f32) -> (m: Matrix3f32) {
|
||||
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) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angles_xyz_f32 :: proc "contextless" (t1, t2, t3: f32) -> (m: Matrix3f32) {
|
||||
c1 := math.cos(-t1)
|
||||
c2 := math.cos(-t2)
|
||||
c3 := math.cos(-t3)
|
||||
@@ -334,7 +373,8 @@ matrix3_from_euler_angles_xyz_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) {
|
||||
return
|
||||
}
|
||||
|
||||
matrix3_from_euler_angles_yxz_f32 :: proc(yaw, pitch, roll: f32) -> (m: Matrix3f32) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angles_yxz_f32 :: proc "contextless" (yaw, pitch, roll: f32) -> (m: Matrix3f32) {
|
||||
ch := math.cos(yaw)
|
||||
sh := math.sin(yaw)
|
||||
cp := math.cos(pitch)
|
||||
@@ -354,7 +394,8 @@ matrix3_from_euler_angles_yxz_f32 :: proc(yaw, pitch, roll: f32) -> (m: Matrix3f
|
||||
return
|
||||
}
|
||||
|
||||
matrix3_from_euler_angles_xzx_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angles_xzx_f32 :: proc "contextless" (t1, t2, t3: f32) -> (m: Matrix3f32) {
|
||||
c1 := math.cos(t1)
|
||||
s1 := math.sin(t1)
|
||||
c2 := math.cos(t2)
|
||||
@@ -374,7 +415,8 @@ matrix3_from_euler_angles_xzx_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) {
|
||||
return
|
||||
}
|
||||
|
||||
matrix3_from_euler_angles_xyx_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angles_xyx_f32 :: proc "contextless" (t1, t2, t3: f32) -> (m: Matrix3f32) {
|
||||
c1 := math.cos(t1)
|
||||
s1 := math.sin(t1)
|
||||
c2 := math.cos(t2)
|
||||
@@ -394,7 +436,8 @@ matrix3_from_euler_angles_xyx_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) {
|
||||
return
|
||||
}
|
||||
|
||||
matrix3_from_euler_angles_yxy_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angles_yxy_f32 :: proc "contextless" (t1, t2, t3: f32) -> (m: Matrix3f32) {
|
||||
c1 := math.cos(t1)
|
||||
s1 := math.sin(t1)
|
||||
c2 := math.cos(t2)
|
||||
@@ -414,7 +457,8 @@ matrix3_from_euler_angles_yxy_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) {
|
||||
return
|
||||
}
|
||||
|
||||
matrix3_from_euler_angles_yzy_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angles_yzy_f32 :: proc "contextless" (t1, t2, t3: f32) -> (m: Matrix3f32) {
|
||||
c1 := math.cos(t1)
|
||||
s1 := math.sin(t1)
|
||||
c2 := math.cos(t2)
|
||||
@@ -434,7 +478,8 @@ matrix3_from_euler_angles_yzy_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) {
|
||||
return
|
||||
}
|
||||
|
||||
matrix3_from_euler_angles_zyz_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angles_zyz_f32 :: proc "contextless" (t1, t2, t3: f32) -> (m: Matrix3f32) {
|
||||
c1 := math.cos(t1)
|
||||
s1 := math.sin(t1)
|
||||
c2 := math.cos(t2)
|
||||
@@ -454,7 +499,8 @@ matrix3_from_euler_angles_zyz_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) {
|
||||
return
|
||||
}
|
||||
|
||||
matrix3_from_euler_angles_zxz_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angles_zxz_f32 :: proc "contextless" (t1, t2, t3: f32) -> (m: Matrix3f32) {
|
||||
c1 := math.cos(t1)
|
||||
s1 := math.sin(t1)
|
||||
c2 := math.cos(t2)
|
||||
@@ -475,7 +521,8 @@ matrix3_from_euler_angles_zxz_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) {
|
||||
}
|
||||
|
||||
|
||||
matrix3_from_euler_angles_xzy_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angles_xzy_f32 :: proc "contextless" (t1, t2, t3: f32) -> (m: Matrix3f32) {
|
||||
c1 := math.cos(t1)
|
||||
s1 := math.sin(t1)
|
||||
c2 := math.cos(t2)
|
||||
@@ -495,7 +542,8 @@ matrix3_from_euler_angles_xzy_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) {
|
||||
return
|
||||
}
|
||||
|
||||
matrix3_from_euler_angles_yzx_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angles_yzx_f32 :: proc "contextless" (t1, t2, t3: f32) -> (m: Matrix3f32) {
|
||||
c1 := math.cos(t1)
|
||||
s1 := math.sin(t1)
|
||||
c2 := math.cos(t2)
|
||||
@@ -515,7 +563,8 @@ matrix3_from_euler_angles_yzx_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) {
|
||||
return
|
||||
}
|
||||
|
||||
matrix3_from_euler_angles_zyx_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angles_zyx_f32 :: proc "contextless" (t1, t2, t3: f32) -> (m: Matrix3f32) {
|
||||
c1 := math.cos(t1)
|
||||
s1 := math.sin(t1)
|
||||
c2 := math.cos(t2)
|
||||
@@ -535,7 +584,8 @@ matrix3_from_euler_angles_zyx_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) {
|
||||
return
|
||||
}
|
||||
|
||||
matrix3_from_euler_angles_zxy_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angles_zxy_f32 :: proc "contextless" (t1, t2, t3: f32) -> (m: Matrix3f32) {
|
||||
c1 := math.cos(t1)
|
||||
s1 := math.sin(t1)
|
||||
c2 := math.cos(t2)
|
||||
@@ -556,7 +606,8 @@ matrix3_from_euler_angles_zxy_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) {
|
||||
}
|
||||
|
||||
|
||||
matrix3_from_yaw_pitch_roll_f32 :: proc(yaw, pitch, roll: f32) -> (m: Matrix3f32) {
|
||||
@(require_results)
|
||||
matrix3_from_yaw_pitch_roll_f32 :: proc "contextless" (yaw, pitch, roll: f32) -> (m: Matrix3f32) {
|
||||
ch := math.cos(yaw)
|
||||
sh := math.sin(yaw)
|
||||
cp := math.cos(pitch)
|
||||
@@ -576,7 +627,8 @@ matrix3_from_yaw_pitch_roll_f32 :: proc(yaw, pitch, roll: f32) -> (m: Matrix3f32
|
||||
return m
|
||||
}
|
||||
|
||||
euler_angles_xyz_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) {
|
||||
@(require_results)
|
||||
euler_angles_xyz_from_matrix3_f32 :: proc "contextless" (m: Matrix3f32) -> (t1, t2, t3: f32) {
|
||||
T1 := math.atan2(m[1, 2], m[2, 2])
|
||||
C2 := math.sqrt(m[0, 0]*m[0, 0] + m[0, 1]*m[0, 1])
|
||||
T2 := math.atan2(-m[0, 2], C2)
|
||||
@@ -589,7 +641,8 @@ euler_angles_xyz_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) {
|
||||
return
|
||||
}
|
||||
|
||||
euler_angles_yxz_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) {
|
||||
@(require_results)
|
||||
euler_angles_yxz_from_matrix3_f32 :: proc "contextless" (m: Matrix3f32) -> (t1, t2, t3: f32) {
|
||||
T1 := math.atan2(m[0, 2], m[2, 2])
|
||||
C2 := math.sqrt(m[1, 0]*m[1, 0] + m[1, 1]*m[1, 1])
|
||||
T2 := math.atan2(-m[1, 2], C2)
|
||||
@@ -602,7 +655,8 @@ euler_angles_yxz_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) {
|
||||
return
|
||||
}
|
||||
|
||||
euler_angles_xzx_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) {
|
||||
@(require_results)
|
||||
euler_angles_xzx_from_matrix3_f32 :: proc "contextless" (m: Matrix3f32) -> (t1, t2, t3: f32) {
|
||||
T1 := math.atan2(m[2, 0], m[1, 0])
|
||||
S2 := math.sqrt(m[0, 1]*m[0, 1] + m[0, 2]*m[0, 2])
|
||||
T2 := math.atan2(S2, m[0, 0])
|
||||
@@ -615,7 +669,8 @@ euler_angles_xzx_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) {
|
||||
return
|
||||
}
|
||||
|
||||
euler_angles_xyx_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) {
|
||||
@(require_results)
|
||||
euler_angles_xyx_from_matrix3_f32 :: proc "contextless" (m: Matrix3f32) -> (t1, t2, t3: f32) {
|
||||
T1 := math.atan2(m[1, 0], -m[2, 0])
|
||||
S2 := math.sqrt(m[0, 1]*m[0, 1] + m[0, 2]*m[0, 2])
|
||||
T2 := math.atan2(S2, m[0, 0])
|
||||
@@ -628,7 +683,8 @@ euler_angles_xyx_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) {
|
||||
return
|
||||
}
|
||||
|
||||
euler_angles_yxy_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) {
|
||||
@(require_results)
|
||||
euler_angles_yxy_from_matrix3_f32 :: proc "contextless" (m: Matrix3f32) -> (t1, t2, t3: f32) {
|
||||
T1 := math.atan2(m[0, 1], m[2, 1])
|
||||
S2 := math.sqrt(m[1, 0]*m[1, 0] + m[1, 2]*m[1, 2])
|
||||
T2 := math.atan2(S2, m[1, 1])
|
||||
@@ -641,7 +697,8 @@ euler_angles_yxy_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) {
|
||||
return
|
||||
}
|
||||
|
||||
euler_angles_yzy_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) {
|
||||
@(require_results)
|
||||
euler_angles_yzy_from_matrix3_f32 :: proc "contextless" (m: Matrix3f32) -> (t1, t2, t3: f32) {
|
||||
T1 := math.atan2(m[2, 1], -m[0, 1])
|
||||
S2 := math.sqrt(m[1, 0]*m[1, 0] + m[1, 2]*m[1, 2])
|
||||
T2 := math.atan2(S2, m[1, 1])
|
||||
@@ -653,7 +710,8 @@ euler_angles_yzy_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) {
|
||||
t3 = T3
|
||||
return
|
||||
}
|
||||
euler_angles_zyz_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) {
|
||||
@(require_results)
|
||||
euler_angles_zyz_from_matrix3_f32 :: proc "contextless" (m: Matrix3f32) -> (t1, t2, t3: f32) {
|
||||
T1 := math.atan2(m[1, 2], m[0, 2])
|
||||
S2 := math.sqrt(m[2, 0]*m[2, 0] + m[2, 1]*m[2, 1])
|
||||
T2 := math.atan2(S2, m[2, 2])
|
||||
@@ -666,7 +724,8 @@ euler_angles_zyz_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) {
|
||||
return
|
||||
}
|
||||
|
||||
euler_angles_zxz_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) {
|
||||
@(require_results)
|
||||
euler_angles_zxz_from_matrix3_f32 :: proc "contextless" (m: Matrix3f32) -> (t1, t2, t3: f32) {
|
||||
T1 := math.atan2(m[0, 2], -m[1, 2])
|
||||
S2 := math.sqrt(m[2, 0]*m[2, 0] + m[2, 1]*m[2, 1])
|
||||
T2 := math.atan2(S2, m[2, 2])
|
||||
@@ -679,7 +738,8 @@ euler_angles_zxz_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) {
|
||||
return
|
||||
}
|
||||
|
||||
euler_angles_xzy_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) {
|
||||
@(require_results)
|
||||
euler_angles_xzy_from_matrix3_f32 :: proc "contextless" (m: Matrix3f32) -> (t1, t2, t3: f32) {
|
||||
T1 := math.atan2(m[2, 1], m[1, 1])
|
||||
C2 := math.sqrt(m[0, 0]*m[0, 0] + m[0, 2]*m[0, 2])
|
||||
T2 := math.atan2(-m[0, 1], C2)
|
||||
@@ -692,7 +752,8 @@ euler_angles_xzy_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) {
|
||||
return
|
||||
}
|
||||
|
||||
euler_angles_yzx_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) {
|
||||
@(require_results)
|
||||
euler_angles_yzx_from_matrix3_f32 :: proc "contextless" (m: Matrix3f32) -> (t1, t2, t3: f32) {
|
||||
T1 := math.atan2(-m[2, 0], m[0, 0])
|
||||
C2 := math.sqrt(m[1, 1]*m[1, 1] + m[1, 2]*m[1, 2])
|
||||
T2 := math.atan2(m[1, 0], C2)
|
||||
@@ -705,7 +766,8 @@ euler_angles_yzx_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) {
|
||||
return
|
||||
}
|
||||
|
||||
euler_angles_zyx_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) {
|
||||
@(require_results)
|
||||
euler_angles_zyx_from_matrix3_f32 :: proc "contextless" (m: Matrix3f32) -> (t1, t2, t3: f32) {
|
||||
T1 := math.atan2(m[1, 0], m[0, 0])
|
||||
C2 := math.sqrt(m[2, 1]*m[2, 1] + m[2, 2]*m[2, 2])
|
||||
T2 := math.atan2(-m[2, 0], C2)
|
||||
@@ -718,7 +780,8 @@ euler_angles_zyx_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) {
|
||||
return
|
||||
}
|
||||
|
||||
euler_angles_zxy_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) {
|
||||
@(require_results)
|
||||
euler_angles_zxy_from_matrix3_f32 :: proc "contextless" (m: Matrix3f32) -> (t1, t2, t3: f32) {
|
||||
T1 := math.atan2(-m[0, 1], m[1, 1])
|
||||
C2 := math.sqrt(m[2, 0]*m[2, 0] + m[2, 2]*m[2, 2])
|
||||
T2 := math.atan2(m[2, 1], C2)
|
||||
@@ -735,7 +798,8 @@ euler_angles_zxy_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) {
|
||||
// Matrix4
|
||||
|
||||
|
||||
matrix4_from_euler_angle_x_f32 :: proc(angle_x: f32) -> (m: Matrix4f32) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angle_x_f32 :: proc "contextless" (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
|
||||
@@ -745,7 +809,8 @@ matrix4_from_euler_angle_x_f32 :: proc(angle_x: f32) -> (m: Matrix4f32) {
|
||||
m[3, 3] = 1
|
||||
return
|
||||
}
|
||||
matrix4_from_euler_angle_y_f32 :: proc(angle_y: f32) -> (m: Matrix4f32) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angle_y_f32 :: proc "contextless" (angle_y: f32) -> (m: Matrix4f32) {
|
||||
cos_y, sin_y := math.cos(angle_y), math.sin(angle_y)
|
||||
m[0, 0] = +cos_y
|
||||
m[0, 2] = -sin_y
|
||||
@@ -755,7 +820,8 @@ matrix4_from_euler_angle_y_f32 :: proc(angle_y: f32) -> (m: Matrix4f32) {
|
||||
m[3, 3] = 1
|
||||
return
|
||||
}
|
||||
matrix4_from_euler_angle_z_f32 :: proc(angle_z: f32) -> (m: Matrix4f32) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angle_z_f32 :: proc "contextless" (angle_z: f32) -> (m: Matrix4f32) {
|
||||
cos_z, sin_z := math.cos(angle_z), math.sin(angle_z)
|
||||
m[0, 0] = +cos_z
|
||||
m[0, 1] = +sin_z
|
||||
@@ -767,7 +833,8 @@ matrix4_from_euler_angle_z_f32 :: proc(angle_z: f32) -> (m: Matrix4f32) {
|
||||
}
|
||||
|
||||
|
||||
matrix4_from_derived_euler_angle_x_f32 :: proc(angle_x: f32, angular_velocity_x: f32) -> (m: Matrix4f32) {
|
||||
@(require_results)
|
||||
matrix4_from_derived_euler_angle_x_f32 :: proc "contextless" (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
|
||||
@@ -778,7 +845,8 @@ matrix4_from_derived_euler_angle_x_f32 :: proc(angle_x: f32, angular_velocity_x:
|
||||
m[3, 3] = 1
|
||||
return
|
||||
}
|
||||
matrix4_from_derived_euler_angle_y_f32 :: proc(angle_y: f32, angular_velocity_y: f32) -> (m: Matrix4f32) {
|
||||
@(require_results)
|
||||
matrix4_from_derived_euler_angle_y_f32 :: proc "contextless" (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
|
||||
@@ -789,7 +857,8 @@ matrix4_from_derived_euler_angle_y_f32 :: proc(angle_y: f32, angular_velocity_y:
|
||||
m[3, 3] = 1
|
||||
return
|
||||
}
|
||||
matrix4_from_derived_euler_angle_z_f32 :: proc(angle_z: f32, angular_velocity_z: f32) -> (m: Matrix4f32) {
|
||||
@(require_results)
|
||||
matrix4_from_derived_euler_angle_z_f32 :: proc "contextless" (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
|
||||
@@ -802,7 +871,8 @@ matrix4_from_derived_euler_angle_z_f32 :: proc(angle_z: f32, angular_velocity_z:
|
||||
}
|
||||
|
||||
|
||||
matrix4_from_euler_angles_xy_f32 :: proc(angle_x, angle_y: f32) -> (m: Matrix4f32) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angles_xy_f32 :: proc "contextless" (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
|
||||
@@ -818,7 +888,8 @@ matrix4_from_euler_angles_xy_f32 :: proc(angle_x, angle_y: f32) -> (m: Matrix4f3
|
||||
}
|
||||
|
||||
|
||||
matrix4_from_euler_angles_yx_f32 :: proc(angle_y, angle_x: f32) -> (m: Matrix4f32) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angles_yx_f32 :: proc "contextless" (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
|
||||
@@ -833,21 +904,26 @@ matrix4_from_euler_angles_yx_f32 :: proc(angle_y, angle_x: f32) -> (m: Matrix4f3
|
||||
return
|
||||
}
|
||||
|
||||
matrix4_from_euler_angles_xz_f32 :: proc(angle_x, angle_z: f32) -> (m: Matrix4f32) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angles_xz_f32 :: proc "contextless" (angle_x, angle_z: f32) -> (m: Matrix4f32) {
|
||||
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) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angles_zx_f32 :: proc "contextless" (angle_z, angle_x: f32) -> (m: Matrix4f32) {
|
||||
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) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angles_yz_f32 :: proc "contextless" (angle_y, angle_z: f32) -> (m: Matrix4f32) {
|
||||
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) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angles_zy_f32 :: proc "contextless" (angle_z, angle_y: f32) -> (m: Matrix4f32) {
|
||||
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) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angles_xyz_f32 :: proc "contextless" (t1, t2, t3: f32) -> (m: Matrix4f32) {
|
||||
c1 := math.cos(-t1)
|
||||
c2 := math.cos(-t2)
|
||||
c3 := math.cos(-t3)
|
||||
@@ -874,7 +950,8 @@ matrix4_from_euler_angles_xyz_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) {
|
||||
return
|
||||
}
|
||||
|
||||
matrix4_from_euler_angles_yxz_f32 :: proc(yaw, pitch, roll: f32) -> (m: Matrix4f32) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angles_yxz_f32 :: proc "contextless" (yaw, pitch, roll: f32) -> (m: Matrix4f32) {
|
||||
ch := math.cos(yaw)
|
||||
sh := math.sin(yaw)
|
||||
cp := math.cos(pitch)
|
||||
@@ -901,7 +978,8 @@ matrix4_from_euler_angles_yxz_f32 :: proc(yaw, pitch, roll: f32) -> (m: Matrix4f
|
||||
return
|
||||
}
|
||||
|
||||
matrix4_from_euler_angles_xzx_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angles_xzx_f32 :: proc "contextless" (t1, t2, t3: f32) -> (m: Matrix4f32) {
|
||||
c1 := math.cos(t1)
|
||||
s1 := math.sin(t1)
|
||||
c2 := math.cos(t2)
|
||||
@@ -928,7 +1006,8 @@ matrix4_from_euler_angles_xzx_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) {
|
||||
return
|
||||
}
|
||||
|
||||
matrix4_from_euler_angles_xyx_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angles_xyx_f32 :: proc "contextless" (t1, t2, t3: f32) -> (m: Matrix4f32) {
|
||||
c1 := math.cos(t1)
|
||||
s1 := math.sin(t1)
|
||||
c2 := math.cos(t2)
|
||||
@@ -955,7 +1034,8 @@ matrix4_from_euler_angles_xyx_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) {
|
||||
return
|
||||
}
|
||||
|
||||
matrix4_from_euler_angles_yxy_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angles_yxy_f32 :: proc "contextless" (t1, t2, t3: f32) -> (m: Matrix4f32) {
|
||||
c1 := math.cos(t1)
|
||||
s1 := math.sin(t1)
|
||||
c2 := math.cos(t2)
|
||||
@@ -982,7 +1062,8 @@ matrix4_from_euler_angles_yxy_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) {
|
||||
return
|
||||
}
|
||||
|
||||
matrix4_from_euler_angles_yzy_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angles_yzy_f32 :: proc "contextless" (t1, t2, t3: f32) -> (m: Matrix4f32) {
|
||||
c1 := math.cos(t1)
|
||||
s1 := math.sin(t1)
|
||||
c2 := math.cos(t2)
|
||||
@@ -1009,7 +1090,8 @@ matrix4_from_euler_angles_yzy_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) {
|
||||
return
|
||||
}
|
||||
|
||||
matrix4_from_euler_angles_zyz_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angles_zyz_f32 :: proc "contextless" (t1, t2, t3: f32) -> (m: Matrix4f32) {
|
||||
c1 := math.cos(t1)
|
||||
s1 := math.sin(t1)
|
||||
c2 := math.cos(t2)
|
||||
@@ -1036,7 +1118,8 @@ matrix4_from_euler_angles_zyz_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) {
|
||||
return
|
||||
}
|
||||
|
||||
matrix4_from_euler_angles_zxz_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angles_zxz_f32 :: proc "contextless" (t1, t2, t3: f32) -> (m: Matrix4f32) {
|
||||
c1 := math.cos(t1)
|
||||
s1 := math.sin(t1)
|
||||
c2 := math.cos(t2)
|
||||
@@ -1064,7 +1147,8 @@ matrix4_from_euler_angles_zxz_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) {
|
||||
}
|
||||
|
||||
|
||||
matrix4_from_euler_angles_xzy_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angles_xzy_f32 :: proc "contextless" (t1, t2, t3: f32) -> (m: Matrix4f32) {
|
||||
c1 := math.cos(t1)
|
||||
s1 := math.sin(t1)
|
||||
c2 := math.cos(t2)
|
||||
@@ -1091,7 +1175,8 @@ matrix4_from_euler_angles_xzy_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) {
|
||||
return
|
||||
}
|
||||
|
||||
matrix4_from_euler_angles_yzx_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angles_yzx_f32 :: proc "contextless" (t1, t2, t3: f32) -> (m: Matrix4f32) {
|
||||
c1 := math.cos(t1)
|
||||
s1 := math.sin(t1)
|
||||
c2 := math.cos(t2)
|
||||
@@ -1118,7 +1203,8 @@ matrix4_from_euler_angles_yzx_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) {
|
||||
return
|
||||
}
|
||||
|
||||
matrix4_from_euler_angles_zyx_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angles_zyx_f32 :: proc "contextless" (t1, t2, t3: f32) -> (m: Matrix4f32) {
|
||||
c1 := math.cos(t1)
|
||||
s1 := math.sin(t1)
|
||||
c2 := math.cos(t2)
|
||||
@@ -1145,7 +1231,8 @@ matrix4_from_euler_angles_zyx_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) {
|
||||
return
|
||||
}
|
||||
|
||||
matrix4_from_euler_angles_zxy_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angles_zxy_f32 :: proc "contextless" (t1, t2, t3: f32) -> (m: Matrix4f32) {
|
||||
c1 := math.cos(t1)
|
||||
s1 := math.sin(t1)
|
||||
c2 := math.cos(t2)
|
||||
@@ -1173,7 +1260,8 @@ matrix4_from_euler_angles_zxy_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) {
|
||||
}
|
||||
|
||||
|
||||
matrix4_from_yaw_pitch_roll_f32 :: proc(yaw, pitch, roll: f32) -> (m: Matrix4f32) {
|
||||
@(require_results)
|
||||
matrix4_from_yaw_pitch_roll_f32 :: proc "contextless" (yaw, pitch, roll: f32) -> (m: Matrix4f32) {
|
||||
ch := math.cos(yaw)
|
||||
sh := math.sin(yaw)
|
||||
cp := math.cos(pitch)
|
||||
@@ -1200,7 +1288,8 @@ matrix4_from_yaw_pitch_roll_f32 :: proc(yaw, pitch, roll: f32) -> (m: Matrix4f32
|
||||
return m
|
||||
}
|
||||
|
||||
euler_angles_xyz_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) {
|
||||
@(require_results)
|
||||
euler_angles_xyz_from_matrix4_f32 :: proc "contextless" (m: Matrix4f32) -> (t1, t2, t3: f32) {
|
||||
T1 := math.atan2(m[1, 2], m[2, 2])
|
||||
C2 := math.sqrt(m[0, 0]*m[0, 0] + m[0, 1]*m[0, 1])
|
||||
T2 := math.atan2(-m[0, 2], C2)
|
||||
@@ -1213,7 +1302,8 @@ euler_angles_xyz_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) {
|
||||
return
|
||||
}
|
||||
|
||||
euler_angles_yxz_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) {
|
||||
@(require_results)
|
||||
euler_angles_yxz_from_matrix4_f32 :: proc "contextless" (m: Matrix4f32) -> (t1, t2, t3: f32) {
|
||||
T1 := math.atan2(m[0, 2], m[2, 2])
|
||||
C2 := math.sqrt(m[1, 0]*m[1, 0] + m[1, 1]*m[1, 1])
|
||||
T2 := math.atan2(-m[1, 2], C2)
|
||||
@@ -1226,7 +1316,8 @@ euler_angles_yxz_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) {
|
||||
return
|
||||
}
|
||||
|
||||
euler_angles_xzx_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) {
|
||||
@(require_results)
|
||||
euler_angles_xzx_from_matrix4_f32 :: proc "contextless" (m: Matrix4f32) -> (t1, t2, t3: f32) {
|
||||
T1 := math.atan2(m[2, 0], m[1, 0])
|
||||
S2 := math.sqrt(m[0, 1]*m[0, 1] + m[0, 2]*m[0, 2])
|
||||
T2 := math.atan2(S2, m[0, 0])
|
||||
@@ -1239,7 +1330,8 @@ euler_angles_xzx_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) {
|
||||
return
|
||||
}
|
||||
|
||||
euler_angles_xyx_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) {
|
||||
@(require_results)
|
||||
euler_angles_xyx_from_matrix4_f32 :: proc "contextless" (m: Matrix4f32) -> (t1, t2, t3: f32) {
|
||||
T1 := math.atan2(m[1, 0], -m[2, 0])
|
||||
S2 := math.sqrt(m[0, 1]*m[0, 1] + m[0, 2]*m[0, 2])
|
||||
T2 := math.atan2(S2, m[0, 0])
|
||||
@@ -1252,7 +1344,8 @@ euler_angles_xyx_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) {
|
||||
return
|
||||
}
|
||||
|
||||
euler_angles_yxy_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) {
|
||||
@(require_results)
|
||||
euler_angles_yxy_from_matrix4_f32 :: proc "contextless" (m: Matrix4f32) -> (t1, t2, t3: f32) {
|
||||
T1 := math.atan2(m[0, 1], m[2, 1])
|
||||
S2 := math.sqrt(m[1, 0]*m[1, 0] + m[1, 2]*m[1, 2])
|
||||
T2 := math.atan2(S2, m[1, 1])
|
||||
@@ -1265,7 +1358,8 @@ euler_angles_yxy_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) {
|
||||
return
|
||||
}
|
||||
|
||||
euler_angles_yzy_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) {
|
||||
@(require_results)
|
||||
euler_angles_yzy_from_matrix4_f32 :: proc "contextless" (m: Matrix4f32) -> (t1, t2, t3: f32) {
|
||||
T1 := math.atan2(m[2, 1], -m[0, 1])
|
||||
S2 := math.sqrt(m[1, 0]*m[1, 0] + m[1, 2]*m[1, 2])
|
||||
T2 := math.atan2(S2, m[1, 1])
|
||||
@@ -1277,7 +1371,8 @@ euler_angles_yzy_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) {
|
||||
t3 = T3
|
||||
return
|
||||
}
|
||||
euler_angles_zyz_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) {
|
||||
@(require_results)
|
||||
euler_angles_zyz_from_matrix4_f32 :: proc "contextless" (m: Matrix4f32) -> (t1, t2, t3: f32) {
|
||||
T1 := math.atan2(m[1, 2], m[0, 2])
|
||||
S2 := math.sqrt(m[2, 0]*m[2, 0] + m[2, 1]*m[2, 1])
|
||||
T2 := math.atan2(S2, m[2, 2])
|
||||
@@ -1290,7 +1385,8 @@ euler_angles_zyz_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) {
|
||||
return
|
||||
}
|
||||
|
||||
euler_angles_zxz_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) {
|
||||
@(require_results)
|
||||
euler_angles_zxz_from_matrix4_f32 :: proc "contextless" (m: Matrix4f32) -> (t1, t2, t3: f32) {
|
||||
T1 := math.atan2(m[0, 2], -m[1, 2])
|
||||
S2 := math.sqrt(m[2, 0]*m[2, 0] + m[2, 1]*m[2, 1])
|
||||
T2 := math.atan2(S2, m[2, 2])
|
||||
@@ -1303,7 +1399,8 @@ euler_angles_zxz_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) {
|
||||
return
|
||||
}
|
||||
|
||||
euler_angles_xzy_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) {
|
||||
@(require_results)
|
||||
euler_angles_xzy_from_matrix4_f32 :: proc "contextless" (m: Matrix4f32) -> (t1, t2, t3: f32) {
|
||||
T1 := math.atan2(m[2, 1], m[1, 1])
|
||||
C2 := math.sqrt(m[0, 0]*m[0, 0] + m[0, 2]*m[0, 2])
|
||||
T2 := math.atan2(-m[0, 1], C2)
|
||||
@@ -1316,7 +1413,8 @@ euler_angles_xzy_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) {
|
||||
return
|
||||
}
|
||||
|
||||
euler_angles_yzx_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) {
|
||||
@(require_results)
|
||||
euler_angles_yzx_from_matrix4_f32 :: proc "contextless" (m: Matrix4f32) -> (t1, t2, t3: f32) {
|
||||
T1 := math.atan2(-m[2, 0], m[0, 0])
|
||||
C2 := math.sqrt(m[1, 1]*m[1, 1] + m[1, 2]*m[1, 2])
|
||||
T2 := math.atan2(m[1, 0], C2)
|
||||
@@ -1329,7 +1427,8 @@ euler_angles_yzx_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) {
|
||||
return
|
||||
}
|
||||
|
||||
euler_angles_zyx_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) {
|
||||
@(require_results)
|
||||
euler_angles_zyx_from_matrix4_f32 :: proc "contextless" (m: Matrix4f32) -> (t1, t2, t3: f32) {
|
||||
T1 := math.atan2(m[1, 0], m[0, 0])
|
||||
C2 := math.sqrt(m[2, 1]*m[2, 1] + m[2, 2]*m[2, 2])
|
||||
T2 := math.atan2(-m[2, 0], C2)
|
||||
@@ -1342,7 +1441,8 @@ euler_angles_zyx_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) {
|
||||
return
|
||||
}
|
||||
|
||||
euler_angles_zxy_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) {
|
||||
@(require_results)
|
||||
euler_angles_zxy_from_matrix4_f32 :: proc "contextless" (m: Matrix4f32) -> (t1, t2, t3: f32) {
|
||||
T1 := math.atan2(-m[0, 1], m[1, 1])
|
||||
C2 := math.sqrt(m[2, 0]*m[2, 0] + m[2, 2]*m[2, 2])
|
||||
T2 := math.atan2(m[2, 1], C2)
|
||||
|
||||
@@ -2,7 +2,8 @@ package linalg
|
||||
|
||||
import "core:math"
|
||||
|
||||
euler_angles_from_matrix3_f64 :: proc(m: Matrix3f64, order: Euler_Angle_Order) -> (t1, t2, t3: f64) {
|
||||
@(require_results)
|
||||
euler_angles_from_matrix3_f64 :: proc "contextless" (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)
|
||||
@@ -19,7 +20,8 @@ euler_angles_from_matrix3_f64 :: proc(m: Matrix3f64, order: Euler_Angle_Order) -
|
||||
}
|
||||
return
|
||||
}
|
||||
euler_angles_from_matrix4_f64 :: proc(m: Matrix4f64, order: Euler_Angle_Order) -> (t1, t2, t3: f64) {
|
||||
@(require_results)
|
||||
euler_angles_from_matrix4_f64 :: proc "contextless" (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)
|
||||
@@ -36,7 +38,8 @@ euler_angles_from_matrix4_f64 :: proc(m: Matrix4f64, order: Euler_Angle_Order) -
|
||||
}
|
||||
return
|
||||
}
|
||||
euler_angles_from_quaternion_f64 :: proc(m: Quaternionf64, order: Euler_Angle_Order) -> (t1, t2, t3: f64) {
|
||||
@(require_results)
|
||||
euler_angles_from_quaternion_f64 :: proc "contextless" (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)
|
||||
@@ -54,7 +57,8 @@ euler_angles_from_quaternion_f64 :: proc(m: Quaternionf64, order: Euler_Angle_Or
|
||||
return
|
||||
}
|
||||
|
||||
matrix3_from_euler_angles_f64 :: proc(t1, t2, t3: f64, order: Euler_Angle_Order) -> (m: Matrix3f64) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angles_f64 :: proc "contextless" (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);
|
||||
@@ -71,7 +75,8 @@ matrix3_from_euler_angles_f64 :: proc(t1, t2, t3: f64, order: Euler_Angle_Order)
|
||||
}
|
||||
return
|
||||
}
|
||||
matrix4_from_euler_angles_f64 :: proc(t1, t2, t3: f64, order: Euler_Angle_Order) -> (m: Matrix4f64) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angles_f64 :: proc "contextless" (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);
|
||||
@@ -89,7 +94,8 @@ matrix4_from_euler_angles_f64 :: proc(t1, t2, t3: f64, order: Euler_Angle_Order)
|
||||
return
|
||||
}
|
||||
|
||||
quaternion_from_euler_angles_f64 :: proc(t1, t2, t3: f64, order: Euler_Angle_Order) -> Quaternionf64 {
|
||||
@(require_results)
|
||||
quaternion_from_euler_angles_f64 :: proc "contextless" (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
|
||||
@@ -117,17 +123,21 @@ quaternion_from_euler_angles_f64 :: proc(t1, t2, t3: f64, order: Euler_Angle_Ord
|
||||
|
||||
// Quaternionf64s
|
||||
|
||||
quaternion_from_euler_angle_x_f64 :: proc(angle_x: f64) -> (q: Quaternionf64) {
|
||||
@(require_results)
|
||||
quaternion_from_euler_angle_x_f64 :: proc "contextless" (angle_x: f64) -> (q: Quaternionf64) {
|
||||
return quaternion_angle_axis_f64(angle_x, {1, 0, 0})
|
||||
}
|
||||
quaternion_from_euler_angle_y_f64 :: proc(angle_y: f64) -> (q: Quaternionf64) {
|
||||
@(require_results)
|
||||
quaternion_from_euler_angle_y_f64 :: proc "contextless" (angle_y: f64) -> (q: Quaternionf64) {
|
||||
return quaternion_angle_axis_f64(angle_y, {0, 1, 0})
|
||||
}
|
||||
quaternion_from_euler_angle_z_f64 :: proc(angle_z: f64) -> (q: Quaternionf64) {
|
||||
@(require_results)
|
||||
quaternion_from_euler_angle_z_f64 :: proc "contextless" (angle_z: f64) -> (q: Quaternionf64) {
|
||||
return quaternion_angle_axis_f64(angle_z, {0, 0, 1})
|
||||
}
|
||||
|
||||
quaternion_from_pitch_yaw_roll_f64 :: proc(pitch, yaw, roll: f64) -> Quaternionf64 {
|
||||
@(require_results)
|
||||
quaternion_from_pitch_yaw_roll_f64 :: proc "contextless" (pitch, yaw, roll: f64) -> Quaternionf64 {
|
||||
a, b, c := pitch, yaw, roll
|
||||
|
||||
ca, sa := math.cos(a*0.5), math.sin(a*0.5)
|
||||
@@ -142,11 +152,13 @@ quaternion_from_pitch_yaw_roll_f64 :: proc(pitch, yaw, roll: f64) -> Quaternionf
|
||||
return q
|
||||
}
|
||||
|
||||
roll_from_quaternion_f64 :: proc(q: Quaternionf64) -> f64 {
|
||||
@(require_results)
|
||||
roll_from_quaternion_f64 :: proc "contextless" (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)
|
||||
}
|
||||
|
||||
pitch_from_quaternion_f64 :: proc(q: Quaternionf64) -> f64 {
|
||||
@(require_results)
|
||||
pitch_from_quaternion_f64 :: proc "contextless" (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
|
||||
|
||||
@@ -157,52 +169,66 @@ pitch_from_quaternion_f64 :: proc(q: Quaternionf64) -> f64 {
|
||||
return math.atan2(y, x)
|
||||
}
|
||||
|
||||
yaw_from_quaternion_f64 :: proc(q: Quaternionf64) -> f64 {
|
||||
@(require_results)
|
||||
yaw_from_quaternion_f64 :: proc "contextless" (q: Quaternionf64) -> f64 {
|
||||
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) {
|
||||
@(require_results)
|
||||
pitch_yaw_roll_from_quaternion_f64 :: proc "contextless" (q: Quaternionf64) -> (pitch, yaw, roll: f64) {
|
||||
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) {
|
||||
@(require_results)
|
||||
euler_angles_xyz_from_quaternion_f64 :: proc "contextless" (q: Quaternionf64) -> (t1, t2, t3: f64) {
|
||||
return euler_angles_xyz_from_matrix4(matrix4_from_quaternion(q))
|
||||
}
|
||||
euler_angles_yxz_from_quaternion_f64 :: proc(q: Quaternionf64) -> (t1, t2, t3: f64) {
|
||||
@(require_results)
|
||||
euler_angles_yxz_from_quaternion_f64 :: proc "contextless" (q: Quaternionf64) -> (t1, t2, t3: f64) {
|
||||
return euler_angles_yxz_from_matrix4(matrix4_from_quaternion(q))
|
||||
}
|
||||
euler_angles_xzx_from_quaternion_f64 :: proc(q: Quaternionf64) -> (t1, t2, t3: f64) {
|
||||
@(require_results)
|
||||
euler_angles_xzx_from_quaternion_f64 :: proc "contextless" (q: Quaternionf64) -> (t1, t2, t3: f64) {
|
||||
return euler_angles_xzx_from_matrix4(matrix4_from_quaternion(q))
|
||||
}
|
||||
euler_angles_xyx_from_quaternion_f64 :: proc(q: Quaternionf64) -> (t1, t2, t3: f64) {
|
||||
@(require_results)
|
||||
euler_angles_xyx_from_quaternion_f64 :: proc "contextless" (q: Quaternionf64) -> (t1, t2, t3: f64) {
|
||||
return euler_angles_xyx_from_matrix4(matrix4_from_quaternion(q))
|
||||
}
|
||||
euler_angles_yxy_from_quaternion_f64 :: proc(q: Quaternionf64) -> (t1, t2, t3: f64) {
|
||||
@(require_results)
|
||||
euler_angles_yxy_from_quaternion_f64 :: proc "contextless" (q: Quaternionf64) -> (t1, t2, t3: f64) {
|
||||
return euler_angles_yxy_from_matrix4(matrix4_from_quaternion(q))
|
||||
}
|
||||
euler_angles_yzy_from_quaternion_f64 :: proc(q: Quaternionf64) -> (t1, t2, t3: f64) {
|
||||
@(require_results)
|
||||
euler_angles_yzy_from_quaternion_f64 :: proc "contextless" (q: Quaternionf64) -> (t1, t2, t3: f64) {
|
||||
return euler_angles_yzy_from_matrix4(matrix4_from_quaternion(q))
|
||||
}
|
||||
euler_angles_zyz_from_quaternion_f64 :: proc(q: Quaternionf64) -> (t1, t2, t3: f64) {
|
||||
@(require_results)
|
||||
euler_angles_zyz_from_quaternion_f64 :: proc "contextless" (q: Quaternionf64) -> (t1, t2, t3: f64) {
|
||||
return euler_angles_zyz_from_matrix4(matrix4_from_quaternion(q))
|
||||
}
|
||||
euler_angles_zxz_from_quaternion_f64 :: proc(q: Quaternionf64) -> (t1, t2, t3: f64) {
|
||||
@(require_results)
|
||||
euler_angles_zxz_from_quaternion_f64 :: proc "contextless" (q: Quaternionf64) -> (t1, t2, t3: f64) {
|
||||
return euler_angles_zxz_from_matrix4(matrix4_from_quaternion(q))
|
||||
}
|
||||
euler_angles_xzy_from_quaternion_f64 :: proc(q: Quaternionf64) -> (t1, t2, t3: f64) {
|
||||
@(require_results)
|
||||
euler_angles_xzy_from_quaternion_f64 :: proc "contextless" (q: Quaternionf64) -> (t1, t2, t3: f64) {
|
||||
return euler_angles_xzy_from_matrix4(matrix4_from_quaternion(q))
|
||||
}
|
||||
euler_angles_yzx_from_quaternion_f64 :: proc(q: Quaternionf64) -> (t1, t2, t3: f64) {
|
||||
@(require_results)
|
||||
euler_angles_yzx_from_quaternion_f64 :: proc "contextless" (q: Quaternionf64) -> (t1, t2, t3: f64) {
|
||||
return euler_angles_yzx_from_matrix4(matrix4_from_quaternion(q))
|
||||
}
|
||||
euler_angles_zyx_from_quaternion_f64 :: proc(q: Quaternionf64) -> (t1, t2, t3: f64) {
|
||||
@(require_results)
|
||||
euler_angles_zyx_from_quaternion_f64 :: proc "contextless" (q: Quaternionf64) -> (t1, t2, t3: f64) {
|
||||
return euler_angles_zyx_from_matrix4(matrix4_from_quaternion(q))
|
||||
}
|
||||
euler_angles_zxy_from_quaternion_f64 :: proc(q: Quaternionf64) -> (t1, t2, t3: f64) {
|
||||
@(require_results)
|
||||
euler_angles_zxy_from_quaternion_f64 :: proc "contextless" (q: Quaternionf64) -> (t1, t2, t3: f64) {
|
||||
return euler_angles_zxy_from_matrix4(matrix4_from_quaternion(q))
|
||||
}
|
||||
|
||||
@@ -210,7 +236,8 @@ euler_angles_zxy_from_quaternion_f64 :: proc(q: Quaternionf64) -> (t1, t2, t3: f
|
||||
// Matrix3
|
||||
|
||||
|
||||
matrix3_from_euler_angle_x_f64 :: proc(angle_x: f64) -> (m: Matrix3f64) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angle_x_f64 :: proc "contextless" (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
|
||||
@@ -219,7 +246,8 @@ matrix3_from_euler_angle_x_f64 :: proc(angle_x: f64) -> (m: Matrix3f64) {
|
||||
m[2, 2] = +cos_x
|
||||
return
|
||||
}
|
||||
matrix3_from_euler_angle_y_f64 :: proc(angle_y: f64) -> (m: Matrix3f64) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angle_y_f64 :: proc "contextless" (angle_y: f64) -> (m: Matrix3f64) {
|
||||
cos_y, sin_y := math.cos(angle_y), math.sin(angle_y)
|
||||
m[0, 0] = +cos_y
|
||||
m[0, 2] = -sin_y
|
||||
@@ -228,7 +256,8 @@ matrix3_from_euler_angle_y_f64 :: proc(angle_y: f64) -> (m: Matrix3f64) {
|
||||
m[2, 2] = +cos_y
|
||||
return
|
||||
}
|
||||
matrix3_from_euler_angle_z_f64 :: proc(angle_z: f64) -> (m: Matrix3f64) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angle_z_f64 :: proc "contextless" (angle_z: f64) -> (m: Matrix3f64) {
|
||||
cos_z, sin_z := math.cos(angle_z), math.sin(angle_z)
|
||||
m[0, 0] = +cos_z
|
||||
m[0, 1] = +sin_z
|
||||
@@ -239,7 +268,8 @@ matrix3_from_euler_angle_z_f64 :: proc(angle_z: f64) -> (m: Matrix3f64) {
|
||||
}
|
||||
|
||||
|
||||
matrix3_from_derived_euler_angle_x_f64 :: proc(angle_x: f64, angular_velocity_x: f64) -> (m: Matrix3f64) {
|
||||
@(require_results)
|
||||
matrix3_from_derived_euler_angle_x_f64 :: proc "contextless" (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
|
||||
@@ -249,7 +279,8 @@ matrix3_from_derived_euler_angle_x_f64 :: proc(angle_x: f64, angular_velocity_x:
|
||||
m[2, 2] = +cos_x
|
||||
return
|
||||
}
|
||||
matrix3_from_derived_euler_angle_y_f64 :: proc(angle_y: f64, angular_velocity_y: f64) -> (m: Matrix3f64) {
|
||||
@(require_results)
|
||||
matrix3_from_derived_euler_angle_y_f64 :: proc "contextless" (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
|
||||
@@ -259,7 +290,8 @@ matrix3_from_derived_euler_angle_y_f64 :: proc(angle_y: f64, angular_velocity_y:
|
||||
m[2, 2] = +cos_y
|
||||
return
|
||||
}
|
||||
matrix3_from_derived_euler_angle_z_f64 :: proc(angle_z: f64, angular_velocity_z: f64) -> (m: Matrix3f64) {
|
||||
@(require_results)
|
||||
matrix3_from_derived_euler_angle_z_f64 :: proc "contextless" (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
|
||||
@@ -271,7 +303,8 @@ matrix3_from_derived_euler_angle_z_f64 :: proc(angle_z: f64, angular_velocity_z:
|
||||
}
|
||||
|
||||
|
||||
matrix3_from_euler_angles_xy_f64 :: proc(angle_x, angle_y: f64) -> (m: Matrix3f64) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angles_xy_f64 :: proc "contextless" (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
|
||||
@@ -286,7 +319,8 @@ matrix3_from_euler_angles_xy_f64 :: proc(angle_x, angle_y: f64) -> (m: Matrix3f6
|
||||
}
|
||||
|
||||
|
||||
matrix3_from_euler_angles_yx_f64 :: proc(angle_y, angle_x: f64) -> (m: Matrix3f64) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angles_yx_f64 :: proc "contextless" (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
|
||||
@@ -300,21 +334,26 @@ matrix3_from_euler_angles_yx_f64 :: proc(angle_y, angle_x: f64) -> (m: Matrix3f6
|
||||
return
|
||||
}
|
||||
|
||||
matrix3_from_euler_angles_xz_f64 :: proc(angle_x, angle_z: f64) -> (m: Matrix3f64) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angles_xz_f64 :: proc "contextless" (angle_x, angle_z: f64) -> (m: Matrix3f64) {
|
||||
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) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angles_zx_f64 :: proc "contextless" (angle_z, angle_x: f64) -> (m: Matrix3f64) {
|
||||
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) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angles_yz_f64 :: proc "contextless" (angle_y, angle_z: f64) -> (m: Matrix3f64) {
|
||||
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) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angles_zy_f64 :: proc "contextless" (angle_z, angle_y: f64) -> (m: Matrix3f64) {
|
||||
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) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angles_xyz_f64 :: proc "contextless" (t1, t2, t3: f64) -> (m: Matrix3f64) {
|
||||
c1 := math.cos(-t1)
|
||||
c2 := math.cos(-t2)
|
||||
c3 := math.cos(-t3)
|
||||
@@ -334,7 +373,8 @@ matrix3_from_euler_angles_xyz_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) {
|
||||
return
|
||||
}
|
||||
|
||||
matrix3_from_euler_angles_yxz_f64 :: proc(yaw, pitch, roll: f64) -> (m: Matrix3f64) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angles_yxz_f64 :: proc "contextless" (yaw, pitch, roll: f64) -> (m: Matrix3f64) {
|
||||
ch := math.cos(yaw)
|
||||
sh := math.sin(yaw)
|
||||
cp := math.cos(pitch)
|
||||
@@ -354,7 +394,8 @@ matrix3_from_euler_angles_yxz_f64 :: proc(yaw, pitch, roll: f64) -> (m: Matrix3f
|
||||
return
|
||||
}
|
||||
|
||||
matrix3_from_euler_angles_xzx_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angles_xzx_f64 :: proc "contextless" (t1, t2, t3: f64) -> (m: Matrix3f64) {
|
||||
c1 := math.cos(t1)
|
||||
s1 := math.sin(t1)
|
||||
c2 := math.cos(t2)
|
||||
@@ -374,7 +415,8 @@ matrix3_from_euler_angles_xzx_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) {
|
||||
return
|
||||
}
|
||||
|
||||
matrix3_from_euler_angles_xyx_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angles_xyx_f64 :: proc "contextless" (t1, t2, t3: f64) -> (m: Matrix3f64) {
|
||||
c1 := math.cos(t1)
|
||||
s1 := math.sin(t1)
|
||||
c2 := math.cos(t2)
|
||||
@@ -394,7 +436,8 @@ matrix3_from_euler_angles_xyx_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) {
|
||||
return
|
||||
}
|
||||
|
||||
matrix3_from_euler_angles_yxy_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angles_yxy_f64 :: proc "contextless" (t1, t2, t3: f64) -> (m: Matrix3f64) {
|
||||
c1 := math.cos(t1)
|
||||
s1 := math.sin(t1)
|
||||
c2 := math.cos(t2)
|
||||
@@ -414,7 +457,8 @@ matrix3_from_euler_angles_yxy_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) {
|
||||
return
|
||||
}
|
||||
|
||||
matrix3_from_euler_angles_yzy_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angles_yzy_f64 :: proc "contextless" (t1, t2, t3: f64) -> (m: Matrix3f64) {
|
||||
c1 := math.cos(t1)
|
||||
s1 := math.sin(t1)
|
||||
c2 := math.cos(t2)
|
||||
@@ -434,7 +478,8 @@ matrix3_from_euler_angles_yzy_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) {
|
||||
return
|
||||
}
|
||||
|
||||
matrix3_from_euler_angles_zyz_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angles_zyz_f64 :: proc "contextless" (t1, t2, t3: f64) -> (m: Matrix3f64) {
|
||||
c1 := math.cos(t1)
|
||||
s1 := math.sin(t1)
|
||||
c2 := math.cos(t2)
|
||||
@@ -454,7 +499,8 @@ matrix3_from_euler_angles_zyz_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) {
|
||||
return
|
||||
}
|
||||
|
||||
matrix3_from_euler_angles_zxz_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angles_zxz_f64 :: proc "contextless" (t1, t2, t3: f64) -> (m: Matrix3f64) {
|
||||
c1 := math.cos(t1)
|
||||
s1 := math.sin(t1)
|
||||
c2 := math.cos(t2)
|
||||
@@ -475,7 +521,8 @@ matrix3_from_euler_angles_zxz_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) {
|
||||
}
|
||||
|
||||
|
||||
matrix3_from_euler_angles_xzy_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angles_xzy_f64 :: proc "contextless" (t1, t2, t3: f64) -> (m: Matrix3f64) {
|
||||
c1 := math.cos(t1)
|
||||
s1 := math.sin(t1)
|
||||
c2 := math.cos(t2)
|
||||
@@ -495,7 +542,8 @@ matrix3_from_euler_angles_xzy_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) {
|
||||
return
|
||||
}
|
||||
|
||||
matrix3_from_euler_angles_yzx_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angles_yzx_f64 :: proc "contextless" (t1, t2, t3: f64) -> (m: Matrix3f64) {
|
||||
c1 := math.cos(t1)
|
||||
s1 := math.sin(t1)
|
||||
c2 := math.cos(t2)
|
||||
@@ -515,7 +563,8 @@ matrix3_from_euler_angles_yzx_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) {
|
||||
return
|
||||
}
|
||||
|
||||
matrix3_from_euler_angles_zyx_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angles_zyx_f64 :: proc "contextless" (t1, t2, t3: f64) -> (m: Matrix3f64) {
|
||||
c1 := math.cos(t1)
|
||||
s1 := math.sin(t1)
|
||||
c2 := math.cos(t2)
|
||||
@@ -535,7 +584,8 @@ matrix3_from_euler_angles_zyx_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) {
|
||||
return
|
||||
}
|
||||
|
||||
matrix3_from_euler_angles_zxy_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) {
|
||||
@(require_results)
|
||||
matrix3_from_euler_angles_zxy_f64 :: proc "contextless" (t1, t2, t3: f64) -> (m: Matrix3f64) {
|
||||
c1 := math.cos(t1)
|
||||
s1 := math.sin(t1)
|
||||
c2 := math.cos(t2)
|
||||
@@ -556,7 +606,8 @@ matrix3_from_euler_angles_zxy_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) {
|
||||
}
|
||||
|
||||
|
||||
matrix3_from_yaw_pitch_roll_f64 :: proc(yaw, pitch, roll: f64) -> (m: Matrix3f64) {
|
||||
@(require_results)
|
||||
matrix3_from_yaw_pitch_roll_f64 :: proc "contextless" (yaw, pitch, roll: f64) -> (m: Matrix3f64) {
|
||||
ch := math.cos(yaw)
|
||||
sh := math.sin(yaw)
|
||||
cp := math.cos(pitch)
|
||||
@@ -576,7 +627,8 @@ matrix3_from_yaw_pitch_roll_f64 :: proc(yaw, pitch, roll: f64) -> (m: Matrix3f64
|
||||
return m
|
||||
}
|
||||
|
||||
euler_angles_xyz_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) {
|
||||
@(require_results)
|
||||
euler_angles_xyz_from_matrix3_f64 :: proc "contextless" (m: Matrix3f64) -> (t1, t2, t3: f64) {
|
||||
T1 := math.atan2(m[1, 2], m[2, 2])
|
||||
C2 := math.sqrt(m[0, 0]*m[0, 0] + m[0, 1]*m[0, 1])
|
||||
T2 := math.atan2(-m[0, 2], C2)
|
||||
@@ -589,7 +641,8 @@ euler_angles_xyz_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) {
|
||||
return
|
||||
}
|
||||
|
||||
euler_angles_yxz_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) {
|
||||
@(require_results)
|
||||
euler_angles_yxz_from_matrix3_f64 :: proc "contextless" (m: Matrix3f64) -> (t1, t2, t3: f64) {
|
||||
T1 := math.atan2(m[0, 2], m[2, 2])
|
||||
C2 := math.sqrt(m[1, 0]*m[1, 0] + m[1, 1]*m[1, 1])
|
||||
T2 := math.atan2(-m[1, 2], C2)
|
||||
@@ -602,7 +655,8 @@ euler_angles_yxz_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) {
|
||||
return
|
||||
}
|
||||
|
||||
euler_angles_xzx_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) {
|
||||
@(require_results)
|
||||
euler_angles_xzx_from_matrix3_f64 :: proc "contextless" (m: Matrix3f64) -> (t1, t2, t3: f64) {
|
||||
T1 := math.atan2(m[2, 0], m[1, 0])
|
||||
S2 := math.sqrt(m[0, 1]*m[0, 1] + m[0, 2]*m[0, 2])
|
||||
T2 := math.atan2(S2, m[0, 0])
|
||||
@@ -615,7 +669,8 @@ euler_angles_xzx_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) {
|
||||
return
|
||||
}
|
||||
|
||||
euler_angles_xyx_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) {
|
||||
@(require_results)
|
||||
euler_angles_xyx_from_matrix3_f64 :: proc "contextless" (m: Matrix3f64) -> (t1, t2, t3: f64) {
|
||||
T1 := math.atan2(m[1, 0], -m[2, 0])
|
||||
S2 := math.sqrt(m[0, 1]*m[0, 1] + m[0, 2]*m[0, 2])
|
||||
T2 := math.atan2(S2, m[0, 0])
|
||||
@@ -628,7 +683,8 @@ euler_angles_xyx_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) {
|
||||
return
|
||||
}
|
||||
|
||||
euler_angles_yxy_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) {
|
||||
@(require_results)
|
||||
euler_angles_yxy_from_matrix3_f64 :: proc "contextless" (m: Matrix3f64) -> (t1, t2, t3: f64) {
|
||||
T1 := math.atan2(m[0, 1], m[2, 1])
|
||||
S2 := math.sqrt(m[1, 0]*m[1, 0] + m[1, 2]*m[1, 2])
|
||||
T2 := math.atan2(S2, m[1, 1])
|
||||
@@ -641,7 +697,8 @@ euler_angles_yxy_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) {
|
||||
return
|
||||
}
|
||||
|
||||
euler_angles_yzy_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) {
|
||||
@(require_results)
|
||||
euler_angles_yzy_from_matrix3_f64 :: proc "contextless" (m: Matrix3f64) -> (t1, t2, t3: f64) {
|
||||
T1 := math.atan2(m[2, 1], -m[0, 1])
|
||||
S2 := math.sqrt(m[1, 0]*m[1, 0] + m[1, 2]*m[1, 2])
|
||||
T2 := math.atan2(S2, m[1, 1])
|
||||
@@ -653,7 +710,8 @@ euler_angles_yzy_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) {
|
||||
t3 = T3
|
||||
return
|
||||
}
|
||||
euler_angles_zyz_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) {
|
||||
@(require_results)
|
||||
euler_angles_zyz_from_matrix3_f64 :: proc "contextless" (m: Matrix3f64) -> (t1, t2, t3: f64) {
|
||||
T1 := math.atan2(m[1, 2], m[0, 2])
|
||||
S2 := math.sqrt(m[2, 0]*m[2, 0] + m[2, 1]*m[2, 1])
|
||||
T2 := math.atan2(S2, m[2, 2])
|
||||
@@ -666,7 +724,8 @@ euler_angles_zyz_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) {
|
||||
return
|
||||
}
|
||||
|
||||
euler_angles_zxz_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) {
|
||||
@(require_results)
|
||||
euler_angles_zxz_from_matrix3_f64 :: proc "contextless" (m: Matrix3f64) -> (t1, t2, t3: f64) {
|
||||
T1 := math.atan2(m[0, 2], -m[1, 2])
|
||||
S2 := math.sqrt(m[2, 0]*m[2, 0] + m[2, 1]*m[2, 1])
|
||||
T2 := math.atan2(S2, m[2, 2])
|
||||
@@ -679,7 +738,8 @@ euler_angles_zxz_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) {
|
||||
return
|
||||
}
|
||||
|
||||
euler_angles_xzy_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) {
|
||||
@(require_results)
|
||||
euler_angles_xzy_from_matrix3_f64 :: proc "contextless" (m: Matrix3f64) -> (t1, t2, t3: f64) {
|
||||
T1 := math.atan2(m[2, 1], m[1, 1])
|
||||
C2 := math.sqrt(m[0, 0]*m[0, 0] + m[0, 2]*m[0, 2])
|
||||
T2 := math.atan2(-m[0, 1], C2)
|
||||
@@ -692,7 +752,8 @@ euler_angles_xzy_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) {
|
||||
return
|
||||
}
|
||||
|
||||
euler_angles_yzx_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) {
|
||||
@(require_results)
|
||||
euler_angles_yzx_from_matrix3_f64 :: proc "contextless" (m: Matrix3f64) -> (t1, t2, t3: f64) {
|
||||
T1 := math.atan2(-m[2, 0], m[0, 0])
|
||||
C2 := math.sqrt(m[1, 1]*m[1, 1] + m[1, 2]*m[1, 2])
|
||||
T2 := math.atan2(m[1, 0], C2)
|
||||
@@ -705,7 +766,8 @@ euler_angles_yzx_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) {
|
||||
return
|
||||
}
|
||||
|
||||
euler_angles_zyx_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) {
|
||||
@(require_results)
|
||||
euler_angles_zyx_from_matrix3_f64 :: proc "contextless" (m: Matrix3f64) -> (t1, t2, t3: f64) {
|
||||
T1 := math.atan2(m[1, 0], m[0, 0])
|
||||
C2 := math.sqrt(m[2, 1]*m[2, 1] + m[2, 2]*m[2, 2])
|
||||
T2 := math.atan2(-m[2, 0], C2)
|
||||
@@ -718,7 +780,8 @@ euler_angles_zyx_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) {
|
||||
return
|
||||
}
|
||||
|
||||
euler_angles_zxy_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) {
|
||||
@(require_results)
|
||||
euler_angles_zxy_from_matrix3_f64 :: proc "contextless" (m: Matrix3f64) -> (t1, t2, t3: f64) {
|
||||
T1 := math.atan2(-m[0, 1], m[1, 1])
|
||||
C2 := math.sqrt(m[2, 0]*m[2, 0] + m[2, 2]*m[2, 2])
|
||||
T2 := math.atan2(m[2, 1], C2)
|
||||
@@ -735,7 +798,8 @@ euler_angles_zxy_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) {
|
||||
// Matrix4
|
||||
|
||||
|
||||
matrix4_from_euler_angle_x_f64 :: proc(angle_x: f64) -> (m: Matrix4f64) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angle_x_f64 :: proc "contextless" (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
|
||||
@@ -745,7 +809,8 @@ matrix4_from_euler_angle_x_f64 :: proc(angle_x: f64) -> (m: Matrix4f64) {
|
||||
m[3, 3] = 1
|
||||
return
|
||||
}
|
||||
matrix4_from_euler_angle_y_f64 :: proc(angle_y: f64) -> (m: Matrix4f64) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angle_y_f64 :: proc "contextless" (angle_y: f64) -> (m: Matrix4f64) {
|
||||
cos_y, sin_y := math.cos(angle_y), math.sin(angle_y)
|
||||
m[0, 0] = +cos_y
|
||||
m[0, 2] = -sin_y
|
||||
@@ -755,7 +820,8 @@ matrix4_from_euler_angle_y_f64 :: proc(angle_y: f64) -> (m: Matrix4f64) {
|
||||
m[3, 3] = 1
|
||||
return
|
||||
}
|
||||
matrix4_from_euler_angle_z_f64 :: proc(angle_z: f64) -> (m: Matrix4f64) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angle_z_f64 :: proc "contextless" (angle_z: f64) -> (m: Matrix4f64) {
|
||||
cos_z, sin_z := math.cos(angle_z), math.sin(angle_z)
|
||||
m[0, 0] = +cos_z
|
||||
m[0, 1] = +sin_z
|
||||
@@ -767,7 +833,8 @@ matrix4_from_euler_angle_z_f64 :: proc(angle_z: f64) -> (m: Matrix4f64) {
|
||||
}
|
||||
|
||||
|
||||
matrix4_from_derived_euler_angle_x_f64 :: proc(angle_x: f64, angular_velocity_x: f64) -> (m: Matrix4f64) {
|
||||
@(require_results)
|
||||
matrix4_from_derived_euler_angle_x_f64 :: proc "contextless" (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
|
||||
@@ -778,7 +845,8 @@ matrix4_from_derived_euler_angle_x_f64 :: proc(angle_x: f64, angular_velocity_x:
|
||||
m[3, 3] = 1
|
||||
return
|
||||
}
|
||||
matrix4_from_derived_euler_angle_y_f64 :: proc(angle_y: f64, angular_velocity_y: f64) -> (m: Matrix4f64) {
|
||||
@(require_results)
|
||||
matrix4_from_derived_euler_angle_y_f64 :: proc "contextless" (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
|
||||
@@ -789,7 +857,8 @@ matrix4_from_derived_euler_angle_y_f64 :: proc(angle_y: f64, angular_velocity_y:
|
||||
m[3, 3] = 1
|
||||
return
|
||||
}
|
||||
matrix4_from_derived_euler_angle_z_f64 :: proc(angle_z: f64, angular_velocity_z: f64) -> (m: Matrix4f64) {
|
||||
@(require_results)
|
||||
matrix4_from_derived_euler_angle_z_f64 :: proc "contextless" (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
|
||||
@@ -802,7 +871,8 @@ matrix4_from_derived_euler_angle_z_f64 :: proc(angle_z: f64, angular_velocity_z:
|
||||
}
|
||||
|
||||
|
||||
matrix4_from_euler_angles_xy_f64 :: proc(angle_x, angle_y: f64) -> (m: Matrix4f64) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angles_xy_f64 :: proc "contextless" (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
|
||||
@@ -818,7 +888,8 @@ matrix4_from_euler_angles_xy_f64 :: proc(angle_x, angle_y: f64) -> (m: Matrix4f6
|
||||
}
|
||||
|
||||
|
||||
matrix4_from_euler_angles_yx_f64 :: proc(angle_y, angle_x: f64) -> (m: Matrix4f64) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angles_yx_f64 :: proc "contextless" (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
|
||||
@@ -833,21 +904,26 @@ matrix4_from_euler_angles_yx_f64 :: proc(angle_y, angle_x: f64) -> (m: Matrix4f6
|
||||
return
|
||||
}
|
||||
|
||||
matrix4_from_euler_angles_xz_f64 :: proc(angle_x, angle_z: f64) -> (m: Matrix4f64) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angles_xz_f64 :: proc "contextless" (angle_x, angle_z: f64) -> (m: Matrix4f64) {
|
||||
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) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angles_zx_f64 :: proc "contextless" (angle_z, angle_x: f64) -> (m: Matrix4f64) {
|
||||
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) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angles_yz_f64 :: proc "contextless" (angle_y, angle_z: f64) -> (m: Matrix4f64) {
|
||||
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) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angles_zy_f64 :: proc "contextless" (angle_z, angle_y: f64) -> (m: Matrix4f64) {
|
||||
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) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angles_xyz_f64 :: proc "contextless" (t1, t2, t3: f64) -> (m: Matrix4f64) {
|
||||
c1 := math.cos(-t1)
|
||||
c2 := math.cos(-t2)
|
||||
c3 := math.cos(-t3)
|
||||
@@ -874,7 +950,8 @@ matrix4_from_euler_angles_xyz_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) {
|
||||
return
|
||||
}
|
||||
|
||||
matrix4_from_euler_angles_yxz_f64 :: proc(yaw, pitch, roll: f64) -> (m: Matrix4f64) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angles_yxz_f64 :: proc "contextless" (yaw, pitch, roll: f64) -> (m: Matrix4f64) {
|
||||
ch := math.cos(yaw)
|
||||
sh := math.sin(yaw)
|
||||
cp := math.cos(pitch)
|
||||
@@ -901,7 +978,8 @@ matrix4_from_euler_angles_yxz_f64 :: proc(yaw, pitch, roll: f64) -> (m: Matrix4f
|
||||
return
|
||||
}
|
||||
|
||||
matrix4_from_euler_angles_xzx_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angles_xzx_f64 :: proc "contextless" (t1, t2, t3: f64) -> (m: Matrix4f64) {
|
||||
c1 := math.cos(t1)
|
||||
s1 := math.sin(t1)
|
||||
c2 := math.cos(t2)
|
||||
@@ -928,7 +1006,8 @@ matrix4_from_euler_angles_xzx_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) {
|
||||
return
|
||||
}
|
||||
|
||||
matrix4_from_euler_angles_xyx_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angles_xyx_f64 :: proc "contextless" (t1, t2, t3: f64) -> (m: Matrix4f64) {
|
||||
c1 := math.cos(t1)
|
||||
s1 := math.sin(t1)
|
||||
c2 := math.cos(t2)
|
||||
@@ -955,7 +1034,8 @@ matrix4_from_euler_angles_xyx_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) {
|
||||
return
|
||||
}
|
||||
|
||||
matrix4_from_euler_angles_yxy_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angles_yxy_f64 :: proc "contextless" (t1, t2, t3: f64) -> (m: Matrix4f64) {
|
||||
c1 := math.cos(t1)
|
||||
s1 := math.sin(t1)
|
||||
c2 := math.cos(t2)
|
||||
@@ -982,7 +1062,8 @@ matrix4_from_euler_angles_yxy_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) {
|
||||
return
|
||||
}
|
||||
|
||||
matrix4_from_euler_angles_yzy_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angles_yzy_f64 :: proc "contextless" (t1, t2, t3: f64) -> (m: Matrix4f64) {
|
||||
c1 := math.cos(t1)
|
||||
s1 := math.sin(t1)
|
||||
c2 := math.cos(t2)
|
||||
@@ -1009,7 +1090,8 @@ matrix4_from_euler_angles_yzy_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) {
|
||||
return
|
||||
}
|
||||
|
||||
matrix4_from_euler_angles_zyz_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angles_zyz_f64 :: proc "contextless" (t1, t2, t3: f64) -> (m: Matrix4f64) {
|
||||
c1 := math.cos(t1)
|
||||
s1 := math.sin(t1)
|
||||
c2 := math.cos(t2)
|
||||
@@ -1036,7 +1118,8 @@ matrix4_from_euler_angles_zyz_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) {
|
||||
return
|
||||
}
|
||||
|
||||
matrix4_from_euler_angles_zxz_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angles_zxz_f64 :: proc "contextless" (t1, t2, t3: f64) -> (m: Matrix4f64) {
|
||||
c1 := math.cos(t1)
|
||||
s1 := math.sin(t1)
|
||||
c2 := math.cos(t2)
|
||||
@@ -1064,7 +1147,8 @@ matrix4_from_euler_angles_zxz_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) {
|
||||
}
|
||||
|
||||
|
||||
matrix4_from_euler_angles_xzy_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angles_xzy_f64 :: proc "contextless" (t1, t2, t3: f64) -> (m: Matrix4f64) {
|
||||
c1 := math.cos(t1)
|
||||
s1 := math.sin(t1)
|
||||
c2 := math.cos(t2)
|
||||
@@ -1091,7 +1175,8 @@ matrix4_from_euler_angles_xzy_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) {
|
||||
return
|
||||
}
|
||||
|
||||
matrix4_from_euler_angles_yzx_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angles_yzx_f64 :: proc "contextless" (t1, t2, t3: f64) -> (m: Matrix4f64) {
|
||||
c1 := math.cos(t1)
|
||||
s1 := math.sin(t1)
|
||||
c2 := math.cos(t2)
|
||||
@@ -1118,7 +1203,8 @@ matrix4_from_euler_angles_yzx_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) {
|
||||
return
|
||||
}
|
||||
|
||||
matrix4_from_euler_angles_zyx_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angles_zyx_f64 :: proc "contextless" (t1, t2, t3: f64) -> (m: Matrix4f64) {
|
||||
c1 := math.cos(t1)
|
||||
s1 := math.sin(t1)
|
||||
c2 := math.cos(t2)
|
||||
@@ -1145,7 +1231,8 @@ matrix4_from_euler_angles_zyx_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) {
|
||||
return
|
||||
}
|
||||
|
||||
matrix4_from_euler_angles_zxy_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) {
|
||||
@(require_results)
|
||||
matrix4_from_euler_angles_zxy_f64 :: proc "contextless" (t1, t2, t3: f64) -> (m: Matrix4f64) {
|
||||
c1 := math.cos(t1)
|
||||
s1 := math.sin(t1)
|
||||
c2 := math.cos(t2)
|
||||
@@ -1173,7 +1260,8 @@ matrix4_from_euler_angles_zxy_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) {
|
||||
}
|
||||
|
||||
|
||||
matrix4_from_yaw_pitch_roll_f64 :: proc(yaw, pitch, roll: f64) -> (m: Matrix4f64) {
|
||||
@(require_results)
|
||||
matrix4_from_yaw_pitch_roll_f64 :: proc "contextless" (yaw, pitch, roll: f64) -> (m: Matrix4f64) {
|
||||
ch := math.cos(yaw)
|
||||
sh := math.sin(yaw)
|
||||
cp := math.cos(pitch)
|
||||
@@ -1200,7 +1288,8 @@ matrix4_from_yaw_pitch_roll_f64 :: proc(yaw, pitch, roll: f64) -> (m: Matrix4f64
|
||||
return m
|
||||
}
|
||||
|
||||
euler_angles_xyz_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) {
|
||||
@(require_results)
|
||||
euler_angles_xyz_from_matrix4_f64 :: proc "contextless" (m: Matrix4f64) -> (t1, t2, t3: f64) {
|
||||
T1 := math.atan2(m[1, 2], m[2, 2])
|
||||
C2 := math.sqrt(m[0, 0]*m[0, 0] + m[0, 1]*m[0, 1])
|
||||
T2 := math.atan2(-m[0, 2], C2)
|
||||
@@ -1213,7 +1302,8 @@ euler_angles_xyz_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) {
|
||||
return
|
||||
}
|
||||
|
||||
euler_angles_yxz_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) {
|
||||
@(require_results)
|
||||
euler_angles_yxz_from_matrix4_f64 :: proc "contextless" (m: Matrix4f64) -> (t1, t2, t3: f64) {
|
||||
T1 := math.atan2(m[0, 2], m[2, 2])
|
||||
C2 := math.sqrt(m[1, 0]*m[1, 0] + m[1, 1]*m[1, 1])
|
||||
T2 := math.atan2(-m[1, 2], C2)
|
||||
@@ -1226,7 +1316,8 @@ euler_angles_yxz_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) {
|
||||
return
|
||||
}
|
||||
|
||||
euler_angles_xzx_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) {
|
||||
@(require_results)
|
||||
euler_angles_xzx_from_matrix4_f64 :: proc "contextless" (m: Matrix4f64) -> (t1, t2, t3: f64) {
|
||||
T1 := math.atan2(m[2, 0], m[1, 0])
|
||||
S2 := math.sqrt(m[0, 1]*m[0, 1] + m[0, 2]*m[0, 2])
|
||||
T2 := math.atan2(S2, m[0, 0])
|
||||
@@ -1239,7 +1330,8 @@ euler_angles_xzx_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) {
|
||||
return
|
||||
}
|
||||
|
||||
euler_angles_xyx_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) {
|
||||
@(require_results)
|
||||
euler_angles_xyx_from_matrix4_f64 :: proc "contextless" (m: Matrix4f64) -> (t1, t2, t3: f64) {
|
||||
T1 := math.atan2(m[1, 0], -m[2, 0])
|
||||
S2 := math.sqrt(m[0, 1]*m[0, 1] + m[0, 2]*m[0, 2])
|
||||
T2 := math.atan2(S2, m[0, 0])
|
||||
@@ -1252,7 +1344,8 @@ euler_angles_xyx_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) {
|
||||
return
|
||||
}
|
||||
|
||||
euler_angles_yxy_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) {
|
||||
@(require_results)
|
||||
euler_angles_yxy_from_matrix4_f64 :: proc "contextless" (m: Matrix4f64) -> (t1, t2, t3: f64) {
|
||||
T1 := math.atan2(m[0, 1], m[2, 1])
|
||||
S2 := math.sqrt(m[1, 0]*m[1, 0] + m[1, 2]*m[1, 2])
|
||||
T2 := math.atan2(S2, m[1, 1])
|
||||
@@ -1265,7 +1358,8 @@ euler_angles_yxy_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) {
|
||||
return
|
||||
}
|
||||
|
||||
euler_angles_yzy_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) {
|
||||
@(require_results)
|
||||
euler_angles_yzy_from_matrix4_f64 :: proc "contextless" (m: Matrix4f64) -> (t1, t2, t3: f64) {
|
||||
T1 := math.atan2(m[2, 1], -m[0, 1])
|
||||
S2 := math.sqrt(m[1, 0]*m[1, 0] + m[1, 2]*m[1, 2])
|
||||
T2 := math.atan2(S2, m[1, 1])
|
||||
@@ -1277,7 +1371,8 @@ euler_angles_yzy_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) {
|
||||
t3 = T3
|
||||
return
|
||||
}
|
||||
euler_angles_zyz_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) {
|
||||
@(require_results)
|
||||
euler_angles_zyz_from_matrix4_f64 :: proc "contextless" (m: Matrix4f64) -> (t1, t2, t3: f64) {
|
||||
T1 := math.atan2(m[1, 2], m[0, 2])
|
||||
S2 := math.sqrt(m[2, 0]*m[2, 0] + m[2, 1]*m[2, 1])
|
||||
T2 := math.atan2(S2, m[2, 2])
|
||||
@@ -1290,7 +1385,8 @@ euler_angles_zyz_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) {
|
||||
return
|
||||
}
|
||||
|
||||
euler_angles_zxz_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) {
|
||||
@(require_results)
|
||||
euler_angles_zxz_from_matrix4_f64 :: proc "contextless" (m: Matrix4f64) -> (t1, t2, t3: f64) {
|
||||
T1 := math.atan2(m[0, 2], -m[1, 2])
|
||||
S2 := math.sqrt(m[2, 0]*m[2, 0] + m[2, 1]*m[2, 1])
|
||||
T2 := math.atan2(S2, m[2, 2])
|
||||
@@ -1303,7 +1399,8 @@ euler_angles_zxz_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) {
|
||||
return
|
||||
}
|
||||
|
||||
euler_angles_xzy_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) {
|
||||
@(require_results)
|
||||
euler_angles_xzy_from_matrix4_f64 :: proc "contextless" (m: Matrix4f64) -> (t1, t2, t3: f64) {
|
||||
T1 := math.atan2(m[2, 1], m[1, 1])
|
||||
C2 := math.sqrt(m[0, 0]*m[0, 0] + m[0, 2]*m[0, 2])
|
||||
T2 := math.atan2(-m[0, 1], C2)
|
||||
@@ -1316,7 +1413,8 @@ euler_angles_xzy_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) {
|
||||
return
|
||||
}
|
||||
|
||||
euler_angles_yzx_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) {
|
||||
@(require_results)
|
||||
euler_angles_yzx_from_matrix4_f64 :: proc "contextless" (m: Matrix4f64) -> (t1, t2, t3: f64) {
|
||||
T1 := math.atan2(-m[2, 0], m[0, 0])
|
||||
C2 := math.sqrt(m[1, 1]*m[1, 1] + m[1, 2]*m[1, 2])
|
||||
T2 := math.atan2(m[1, 0], C2)
|
||||
@@ -1329,7 +1427,8 @@ euler_angles_yzx_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) {
|
||||
return
|
||||
}
|
||||
|
||||
euler_angles_zyx_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) {
|
||||
@(require_results)
|
||||
euler_angles_zyx_from_matrix4_f64 :: proc "contextless" (m: Matrix4f64) -> (t1, t2, t3: f64) {
|
||||
T1 := math.atan2(m[1, 0], m[0, 0])
|
||||
C2 := math.sqrt(m[2, 1]*m[2, 1] + m[2, 2]*m[2, 2])
|
||||
T2 := math.atan2(-m[2, 0], C2)
|
||||
@@ -1342,7 +1441,8 @@ euler_angles_zyx_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) {
|
||||
return
|
||||
}
|
||||
|
||||
euler_angles_zxy_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) {
|
||||
@(require_results)
|
||||
euler_angles_zxy_from_matrix4_f64 :: proc "contextless" (m: Matrix4f64) -> (t1, t2, t3: f64) {
|
||||
T1 := math.atan2(-m[0, 1], m[1, 1])
|
||||
C2 := math.sqrt(m[2, 0]*m[2, 0] + m[2, 2]*m[2, 2])
|
||||
T2 := math.atan2(m[2, 1], C2)
|
||||
|
||||
@@ -37,110 +37,142 @@ Vector4_Components :: enum u8 {
|
||||
a = 3,
|
||||
}
|
||||
|
||||
scalar_f32_swizzle1 :: proc(f: f32, c0: Scalar_Components) -> f32 {
|
||||
@(require_results)
|
||||
scalar_f32_swizzle1 :: proc "contextless" (f: f32, c0: Scalar_Components) -> f32 {
|
||||
return f
|
||||
}
|
||||
scalar_f32_swizzle2 :: proc(f: f32, c0, c1: Scalar_Components) -> Vector2f32 {
|
||||
@(require_results)
|
||||
scalar_f32_swizzle2 :: proc "contextless" (f: f32, c0, c1: Scalar_Components) -> Vector2f32 {
|
||||
return {f, f}
|
||||
}
|
||||
scalar_f32_swizzle3 :: proc(f: f32, c0, c1, c2: Scalar_Components) -> Vector3f32 {
|
||||
@(require_results)
|
||||
scalar_f32_swizzle3 :: proc "contextless" (f: f32, c0, c1, c2: Scalar_Components) -> Vector3f32 {
|
||||
return {f, f, f}
|
||||
}
|
||||
scalar_f32_swizzle4 :: proc(f: f32, c0, c1, c2, c3: Scalar_Components) -> Vector4f32 {
|
||||
@(require_results)
|
||||
scalar_f32_swizzle4 :: proc "contextless" (f: f32, c0, c1, c2, c3: Scalar_Components) -> Vector4f32 {
|
||||
return {f, f, f, f}
|
||||
}
|
||||
|
||||
vector2f32_swizzle1 :: proc(v: Vector2f32, c0: Vector2_Components) -> f32 {
|
||||
@(require_results)
|
||||
vector2f32_swizzle1 :: proc "contextless" (v: Vector2f32, c0: Vector2_Components) -> f32 {
|
||||
return v[c0]
|
||||
}
|
||||
vector2f32_swizzle2 :: proc(v: Vector2f32, c0, c1: Vector2_Components) -> Vector2f32 {
|
||||
@(require_results)
|
||||
vector2f32_swizzle2 :: proc "contextless" (v: Vector2f32, c0, c1: Vector2_Components) -> Vector2f32 {
|
||||
return {v[c0], v[c1]}
|
||||
}
|
||||
vector2f32_swizzle3 :: proc(v: Vector2f32, c0, c1, c2: Vector2_Components) -> Vector3f32 {
|
||||
@(require_results)
|
||||
vector2f32_swizzle3 :: proc "contextless" (v: Vector2f32, c0, c1, c2: Vector2_Components) -> Vector3f32 {
|
||||
return {v[c0], v[c1], v[c2]}
|
||||
}
|
||||
vector2f32_swizzle4 :: proc(v: Vector2f32, c0, c1, c2, c3: Vector2_Components) -> Vector4f32 {
|
||||
@(require_results)
|
||||
vector2f32_swizzle4 :: proc "contextless" (v: Vector2f32, c0, c1, c2, c3: Vector2_Components) -> Vector4f32 {
|
||||
return {v[c0], v[c1], v[c2], v[c3]}
|
||||
}
|
||||
|
||||
|
||||
vector3f32_swizzle1 :: proc(v: Vector3f32, c0: Vector3_Components) -> f32 {
|
||||
@(require_results)
|
||||
vector3f32_swizzle1 :: proc "contextless" (v: Vector3f32, c0: Vector3_Components) -> f32 {
|
||||
return v[c0]
|
||||
}
|
||||
vector3f32_swizzle2 :: proc(v: Vector3f32, c0, c1: Vector3_Components) -> Vector2f32 {
|
||||
@(require_results)
|
||||
vector3f32_swizzle2 :: proc "contextless" (v: Vector3f32, c0, c1: Vector3_Components) -> Vector2f32 {
|
||||
return {v[c0], v[c1]}
|
||||
}
|
||||
vector3f32_swizzle3 :: proc(v: Vector3f32, c0, c1, c2: Vector3_Components) -> Vector3f32 {
|
||||
@(require_results)
|
||||
vector3f32_swizzle3 :: proc "contextless" (v: Vector3f32, c0, c1, c2: Vector3_Components) -> Vector3f32 {
|
||||
return {v[c0], v[c1], v[c2]}
|
||||
}
|
||||
vector3f32_swizzle4 :: proc(v: Vector3f32, c0, c1, c2, c3: Vector3_Components) -> Vector4f32 {
|
||||
@(require_results)
|
||||
vector3f32_swizzle4 :: proc "contextless" (v: Vector3f32, c0, c1, c2, c3: Vector3_Components) -> Vector4f32 {
|
||||
return {v[c0], v[c1], v[c2], v[c3]}
|
||||
}
|
||||
|
||||
vector4f32_swizzle1 :: proc(v: Vector4f32, c0: Vector4_Components) -> f32 {
|
||||
@(require_results)
|
||||
vector4f32_swizzle1 :: proc "contextless" (v: Vector4f32, c0: Vector4_Components) -> f32 {
|
||||
return v[c0]
|
||||
}
|
||||
vector4f32_swizzle2 :: proc(v: Vector4f32, c0, c1: Vector4_Components) -> Vector2f32 {
|
||||
@(require_results)
|
||||
vector4f32_swizzle2 :: proc "contextless" (v: Vector4f32, c0, c1: Vector4_Components) -> Vector2f32 {
|
||||
return {v[c0], v[c1]}
|
||||
}
|
||||
vector4f32_swizzle3 :: proc(v: Vector4f32, c0, c1, c2: Vector4_Components) -> Vector3f32 {
|
||||
@(require_results)
|
||||
vector4f32_swizzle3 :: proc "contextless" (v: Vector4f32, c0, c1, c2: Vector4_Components) -> Vector3f32 {
|
||||
return {v[c0], v[c1], v[c2]}
|
||||
}
|
||||
vector4f32_swizzle4 :: proc(v: Vector4f32, c0, c1, c2, c3: Vector4_Components) -> Vector4f32 {
|
||||
@(require_results)
|
||||
vector4f32_swizzle4 :: proc "contextless" (v: Vector4f32, c0, c1, c2, c3: Vector4_Components) -> Vector4f32 {
|
||||
return {v[c0], v[c1], v[c2], v[c3]}
|
||||
}
|
||||
|
||||
|
||||
scalar_f64_swizzle1 :: proc(f: f64, c0: Scalar_Components) -> f64 {
|
||||
@(require_results)
|
||||
scalar_f64_swizzle1 :: proc "contextless" (f: f64, c0: Scalar_Components) -> f64 {
|
||||
return f
|
||||
}
|
||||
scalar_f64_swizzle2 :: proc(f: f64, c0, c1: Scalar_Components) -> Vector2f64 {
|
||||
@(require_results)
|
||||
scalar_f64_swizzle2 :: proc "contextless" (f: f64, c0, c1: Scalar_Components) -> Vector2f64 {
|
||||
return {f, f}
|
||||
}
|
||||
scalar_f64_swizzle3 :: proc(f: f64, c0, c1, c2: Scalar_Components) -> Vector3f64 {
|
||||
@(require_results)
|
||||
scalar_f64_swizzle3 :: proc "contextless" (f: f64, c0, c1, c2: Scalar_Components) -> Vector3f64 {
|
||||
return {f, f, f}
|
||||
}
|
||||
scalar_f64_swizzle4 :: proc(f: f64, c0, c1, c2, c3: Scalar_Components) -> Vector4f64 {
|
||||
@(require_results)
|
||||
scalar_f64_swizzle4 :: proc "contextless" (f: f64, c0, c1, c2, c3: Scalar_Components) -> Vector4f64 {
|
||||
return {f, f, f, f}
|
||||
}
|
||||
|
||||
vector2f64_swizzle1 :: proc(v: Vector2f64, c0: Vector2_Components) -> f64 {
|
||||
@(require_results)
|
||||
vector2f64_swizzle1 :: proc "contextless" (v: Vector2f64, c0: Vector2_Components) -> f64 {
|
||||
return v[c0]
|
||||
}
|
||||
vector2f64_swizzle2 :: proc(v: Vector2f64, c0, c1: Vector2_Components) -> Vector2f64 {
|
||||
@(require_results)
|
||||
vector2f64_swizzle2 :: proc "contextless" (v: Vector2f64, c0, c1: Vector2_Components) -> Vector2f64 {
|
||||
return {v[c0], v[c1]}
|
||||
}
|
||||
vector2f64_swizzle3 :: proc(v: Vector2f64, c0, c1, c2: Vector2_Components) -> Vector3f64 {
|
||||
@(require_results)
|
||||
vector2f64_swizzle3 :: proc "contextless" (v: Vector2f64, c0, c1, c2: Vector2_Components) -> Vector3f64 {
|
||||
return {v[c0], v[c1], v[c2]}
|
||||
}
|
||||
vector2f64_swizzle4 :: proc(v: Vector2f64, c0, c1, c2, c3: Vector2_Components) -> Vector4f64 {
|
||||
@(require_results)
|
||||
vector2f64_swizzle4 :: proc "contextless" (v: Vector2f64, c0, c1, c2, c3: Vector2_Components) -> Vector4f64 {
|
||||
return {v[c0], v[c1], v[c2], v[c3]}
|
||||
}
|
||||
|
||||
|
||||
vector3f64_swizzle1 :: proc(v: Vector3f64, c0: Vector3_Components) -> f64 {
|
||||
@(require_results)
|
||||
vector3f64_swizzle1 :: proc "contextless" (v: Vector3f64, c0: Vector3_Components) -> f64 {
|
||||
return v[c0]
|
||||
}
|
||||
vector3f64_swizzle2 :: proc(v: Vector3f64, c0, c1: Vector3_Components) -> Vector2f64 {
|
||||
@(require_results)
|
||||
vector3f64_swizzle2 :: proc "contextless" (v: Vector3f64, c0, c1: Vector3_Components) -> Vector2f64 {
|
||||
return {v[c0], v[c1]}
|
||||
}
|
||||
vector3f64_swizzle3 :: proc(v: Vector3f64, c0, c1, c2: Vector3_Components) -> Vector3f64 {
|
||||
@(require_results)
|
||||
vector3f64_swizzle3 :: proc "contextless" (v: Vector3f64, c0, c1, c2: Vector3_Components) -> Vector3f64 {
|
||||
return {v[c0], v[c1], v[c2]}
|
||||
}
|
||||
vector3f64_swizzle4 :: proc(v: Vector3f64, c0, c1, c2, c3: Vector3_Components) -> Vector4f64 {
|
||||
@(require_results)
|
||||
vector3f64_swizzle4 :: proc "contextless" (v: Vector3f64, c0, c1, c2, c3: Vector3_Components) -> Vector4f64 {
|
||||
return {v[c0], v[c1], v[c2], v[c3]}
|
||||
}
|
||||
|
||||
vector4f64_swizzle1 :: proc(v: Vector4f64, c0: Vector4_Components) -> f64 {
|
||||
@(require_results)
|
||||
vector4f64_swizzle1 :: proc "contextless" (v: Vector4f64, c0: Vector4_Components) -> f64 {
|
||||
return v[c0]
|
||||
}
|
||||
vector4f64_swizzle2 :: proc(v: Vector4f64, c0, c1: Vector4_Components) -> Vector2f64 {
|
||||
@(require_results)
|
||||
vector4f64_swizzle2 :: proc "contextless" (v: Vector4f64, c0, c1: Vector4_Components) -> Vector2f64 {
|
||||
return {v[c0], v[c1]}
|
||||
}
|
||||
vector4f64_swizzle3 :: proc(v: Vector4f64, c0, c1, c2: Vector4_Components) -> Vector3f64 {
|
||||
@(require_results)
|
||||
vector4f64_swizzle3 :: proc "contextless" (v: Vector4f64, c0, c1, c2: Vector4_Components) -> Vector3f64 {
|
||||
return {v[c0], v[c1], v[c2]}
|
||||
}
|
||||
vector4f64_swizzle4 :: proc(v: Vector4f64, c0, c1, c2, c3: Vector4_Components) -> Vector4f64 {
|
||||
@(require_results)
|
||||
vector4f64_swizzle4 :: proc "contextless" (v: Vector4f64, c0, c1, c2, c3: Vector4_Components) -> Vector4f64 {
|
||||
return {v[c0], v[c1], v[c2], v[c3]}
|
||||
}
|
||||
|
||||
|
||||
+477
-261
File diff suppressed because it is too large
Load Diff
+109
-39
@@ -3,56 +3,126 @@ package math
|
||||
|
||||
import "core:intrinsics"
|
||||
|
||||
@(default_calling_convention="none")
|
||||
@(default_calling_convention="none", private="file")
|
||||
foreign _ {
|
||||
@(link_name="llvm.sin.f16")
|
||||
sin_f16 :: proc(θ: f16) -> f16 ---
|
||||
@(link_name="llvm.sin.f32")
|
||||
sin_f32 :: proc(θ: f32) -> f32 ---
|
||||
@(link_name="llvm.sin.f64")
|
||||
sin_f64 :: proc(θ: f64) -> f64 ---
|
||||
@(link_name="llvm.sin.f16", require_results)
|
||||
_sin_f16 :: proc(θ: f16) -> f16 ---
|
||||
@(link_name="llvm.sin.f32", require_results)
|
||||
_sin_f32 :: proc(θ: f32) -> f32 ---
|
||||
@(link_name="llvm.sin.f64", require_results)
|
||||
_sin_f64 :: proc(θ: f64) -> f64 ---
|
||||
|
||||
@(link_name="llvm.cos.f16")
|
||||
cos_f16 :: proc(θ: f16) -> f16 ---
|
||||
@(link_name="llvm.cos.f32")
|
||||
cos_f32 :: proc(θ: f32) -> f32 ---
|
||||
@(link_name="llvm.cos.f64")
|
||||
cos_f64 :: proc(θ: f64) -> f64 ---
|
||||
@(link_name="llvm.cos.f16", require_results)
|
||||
_cos_f16 :: proc(θ: f16) -> f16 ---
|
||||
@(link_name="llvm.cos.f32", require_results)
|
||||
_cos_f32 :: proc(θ: f32) -> f32 ---
|
||||
@(link_name="llvm.cos.f64", require_results)
|
||||
_cos_f64 :: proc(θ: f64) -> f64 ---
|
||||
|
||||
@(link_name="llvm.pow.f16")
|
||||
pow_f16 :: proc(x, power: f16) -> f16 ---
|
||||
@(link_name="llvm.pow.f32")
|
||||
pow_f32 :: proc(x, power: f32) -> f32 ---
|
||||
@(link_name="llvm.pow.f64")
|
||||
pow_f64 :: proc(x, power: f64) -> f64 ---
|
||||
@(link_name="llvm.pow.f16", require_results)
|
||||
_pow_f16 :: proc(x, power: f16) -> f16 ---
|
||||
@(link_name="llvm.pow.f32", require_results)
|
||||
_pow_f32 :: proc(x, power: f32) -> f32 ---
|
||||
@(link_name="llvm.pow.f64", require_results)
|
||||
_pow_f64 :: proc(x, power: f64) -> f64 ---
|
||||
|
||||
@(link_name="llvm.fmuladd.f16")
|
||||
fmuladd_f16 :: proc(a, b, c: f16) -> f16 ---
|
||||
@(link_name="llvm.fmuladd.f32")
|
||||
fmuladd_f32 :: proc(a, b, c: f32) -> f32 ---
|
||||
@(link_name="llvm.fmuladd.f64")
|
||||
fmuladd_f64 :: proc(a, b, c: f64) -> f64 ---
|
||||
@(link_name="llvm.fmuladd.f16", require_results)
|
||||
_fmuladd_f16 :: proc(a, b, c: f16) -> f16 ---
|
||||
@(link_name="llvm.fmuladd.f32", require_results)
|
||||
_fmuladd_f32 :: proc(a, b, c: f32) -> f32 ---
|
||||
@(link_name="llvm.fmuladd.f64", require_results)
|
||||
_fmuladd_f64 :: proc(a, b, c: f64) -> f64 ---
|
||||
|
||||
@(link_name="llvm.exp.f16")
|
||||
exp_f16 :: proc(x: f16) -> f16 ---
|
||||
@(link_name="llvm.exp.f32")
|
||||
exp_f32 :: proc(x: f32) -> f32 ---
|
||||
@(link_name="llvm.exp.f64")
|
||||
exp_f64 :: proc(x: f64) -> f64 ---
|
||||
@(link_name="llvm.exp.f16", require_results)
|
||||
_exp_f16 :: proc(x: f16) -> f16 ---
|
||||
@(link_name="llvm.exp.f32", require_results)
|
||||
_exp_f32 :: proc(x: f32) -> f32 ---
|
||||
@(link_name="llvm.exp.f64", require_results)
|
||||
_exp_f64 :: proc(x: f64) -> f64 ---
|
||||
}
|
||||
|
||||
@(require_results)
|
||||
sin_f16 :: proc "contextless" (θ: f16) -> f16 {
|
||||
return _sin_f16(θ)
|
||||
}
|
||||
@(require_results)
|
||||
sin_f32 :: proc "contextless" (θ: f32) -> f32 {
|
||||
return _sin_f32(θ)
|
||||
}
|
||||
@(require_results)
|
||||
sin_f64 :: proc "contextless" (θ: f64) -> f64 {
|
||||
return _sin_f64(θ)
|
||||
}
|
||||
|
||||
@(require_results)
|
||||
cos_f16 :: proc "contextless" (θ: f16) -> f16 {
|
||||
return _cos_f16(θ)
|
||||
}
|
||||
@(require_results)
|
||||
cos_f32 :: proc "contextless" (θ: f32) -> f32 {
|
||||
return _cos_f32(θ)
|
||||
}
|
||||
@(require_results)
|
||||
cos_f64 :: proc "contextless" (θ: f64) -> f64 {
|
||||
return _cos_f64(θ)
|
||||
}
|
||||
|
||||
@(require_results)
|
||||
pow_f16 :: proc "contextless" (x, power: f16) -> f16 {
|
||||
return _pow_f16(x, power)
|
||||
}
|
||||
@(require_results)
|
||||
pow_f32 :: proc "contextless" (x, power: f32) -> f32 {
|
||||
return _pow_f32(x, power)
|
||||
}
|
||||
@(require_results)
|
||||
pow_f64 :: proc "contextless" (x, power: f64) -> f64 {
|
||||
return _pow_f64(x, power)
|
||||
}
|
||||
|
||||
@(require_results)
|
||||
fmuladd_f16 :: proc "contextless" (a, b, c: f16) -> f16 {
|
||||
return _fmuladd_f16(a, b, c)
|
||||
}
|
||||
@(require_results)
|
||||
fmuladd_f32 :: proc "contextless" (a, b, c: f32) -> f32 {
|
||||
return _fmuladd_f32(a, b, c)
|
||||
}
|
||||
@(require_results)
|
||||
fmuladd_f64 :: proc "contextless" (a, b, c: f64) -> f64 {
|
||||
return _fmuladd_f64(a, b, c)
|
||||
}
|
||||
|
||||
@(require_results)
|
||||
exp_f16 :: proc "contextless" (x: f16) -> f16 {
|
||||
return _exp_f16(x)
|
||||
}
|
||||
@(require_results)
|
||||
exp_f32 :: proc "contextless" (x: f32) -> f32 {
|
||||
return _exp_f32(x)
|
||||
}
|
||||
@(require_results)
|
||||
exp_f64 :: proc "contextless" (x: f64) -> f64 {
|
||||
return _exp_f64(x)
|
||||
}
|
||||
|
||||
|
||||
@(require_results)
|
||||
sqrt_f16 :: proc "contextless" (x: f16) -> f16 {
|
||||
return intrinsics.sqrt(x)
|
||||
}
|
||||
@(require_results)
|
||||
sqrt_f32 :: proc "contextless" (x: f32) -> f32 {
|
||||
return intrinsics.sqrt(x)
|
||||
}
|
||||
@(require_results)
|
||||
sqrt_f64 :: proc "contextless" (x: f64) -> f64 {
|
||||
return intrinsics.sqrt(x)
|
||||
}
|
||||
|
||||
|
||||
|
||||
@(require_results)
|
||||
ln_f64 :: proc "contextless" (x: f64) -> f64 {
|
||||
// The original C code, the long comment, and the constants
|
||||
// below are from FreeBSD's /usr/src/lib/msun/src/e_log.c
|
||||
@@ -154,14 +224,14 @@ ln_f64 :: proc "contextless" (x: f64) -> f64 {
|
||||
return k*LN2_HI - ((hfsq - (s*(hfsq+R) + k*LN2_LO)) - f)
|
||||
}
|
||||
|
||||
ln_f16 :: proc "contextless" (x: f16) -> f16 { return #force_inline f16(ln_f64(f64(x))) }
|
||||
ln_f32 :: proc "contextless" (x: f32) -> f32 { return #force_inline f32(ln_f64(f64(x))) }
|
||||
ln_f16le :: proc "contextless" (x: f16le) -> f16le { return #force_inline f16le(ln_f64(f64(x))) }
|
||||
ln_f16be :: proc "contextless" (x: f16be) -> f16be { return #force_inline f16be(ln_f64(f64(x))) }
|
||||
ln_f32le :: proc "contextless" (x: f32le) -> f32le { return #force_inline f32le(ln_f64(f64(x))) }
|
||||
ln_f32be :: proc "contextless" (x: f32be) -> f32be { return #force_inline f32be(ln_f64(f64(x))) }
|
||||
ln_f64le :: proc "contextless" (x: f64le) -> f64le { return #force_inline f64le(ln_f64(f64(x))) }
|
||||
ln_f64be :: proc "contextless" (x: f64be) -> f64be { return #force_inline f64be(ln_f64(f64(x))) }
|
||||
@(require_results) ln_f16 :: proc "contextless" (x: f16) -> f16 { return #force_inline f16(ln_f64(f64(x))) }
|
||||
@(require_results) ln_f32 :: proc "contextless" (x: f32) -> f32 { return #force_inline f32(ln_f64(f64(x))) }
|
||||
@(require_results) ln_f16le :: proc "contextless" (x: f16le) -> f16le { return #force_inline f16le(ln_f64(f64(x))) }
|
||||
@(require_results) ln_f16be :: proc "contextless" (x: f16be) -> f16be { return #force_inline f16be(ln_f64(f64(x))) }
|
||||
@(require_results) ln_f32le :: proc "contextless" (x: f32le) -> f32le { return #force_inline f32le(ln_f64(f64(x))) }
|
||||
@(require_results) ln_f32be :: proc "contextless" (x: f32be) -> f32be { return #force_inline f32be(ln_f64(f64(x))) }
|
||||
@(require_results) ln_f64le :: proc "contextless" (x: f64le) -> f64le { return #force_inline f64le(ln_f64(f64(x))) }
|
||||
@(require_results) ln_f64be :: proc "contextless" (x: f64be) -> f64be { return #force_inline f64be(ln_f64(f64(x))) }
|
||||
ln :: proc{
|
||||
ln_f16, ln_f16le, ln_f16be,
|
||||
ln_f32, ln_f32le, ln_f32be,
|
||||
|
||||
@@ -7,46 +7,47 @@ foreign import "odin_env"
|
||||
|
||||
@(default_calling_convention="c")
|
||||
foreign odin_env {
|
||||
@(link_name="sin")
|
||||
@(link_name="sin", require_results)
|
||||
sin_f64 :: proc(θ: f64) -> f64 ---
|
||||
@(link_name="cos")
|
||||
@(link_name="cos", require_results)
|
||||
cos_f64 :: proc(θ: f64) -> f64 ---
|
||||
@(link_name="pow")
|
||||
@(link_name="pow", require_results)
|
||||
pow_f64 :: proc(x, power: f64) -> f64 ---
|
||||
@(link_name="fmuladd")
|
||||
@(link_name="fmuladd", require_results)
|
||||
fmuladd_f64 :: proc(a, b, c: f64) -> f64 ---
|
||||
@(link_name="ln")
|
||||
@(link_name="ln", require_results)
|
||||
ln_f64 :: proc(x: f64) -> f64 ---
|
||||
@(link_name="exp")
|
||||
@(link_name="exp", require_results)
|
||||
exp_f64 :: proc(x: f64) -> f64 ---
|
||||
}
|
||||
|
||||
@(require_results)
|
||||
sqrt_f64 :: proc "contextless" (x: f64) -> f64 {
|
||||
return intrinsics.sqrt(x)
|
||||
}
|
||||
|
||||
sqrt_f16 :: proc "c" (x: f16) -> f16 { return f16(sqrt_f64(f64(x))) }
|
||||
sin_f16 :: proc "c" (θ: f16) -> f16 { return f16(sin_f64(f64(θ))) }
|
||||
cos_f16 :: proc "c" (θ: f16) -> f16 { return f16(cos_f64(f64(θ))) }
|
||||
pow_f16 :: proc "c" (x, power: f16) -> f16 { return f16(pow_f64(f64(x), f64(power))) }
|
||||
fmuladd_f16 :: proc "c" (a, b, c: f16) -> f16 { return f16(fmuladd_f64(f64(a), f64(a), f64(c))) }
|
||||
ln_f16 :: proc "c" (x: f16) -> f16 { return f16(ln_f64(f64(x))) }
|
||||
exp_f16 :: proc "c" (x: f16) -> f16 { return f16(exp_f64(f64(x))) }
|
||||
@(require_results) sqrt_f16 :: proc "c" (x: f16) -> f16 { return f16(sqrt_f64(f64(x))) }
|
||||
@(require_results) sin_f16 :: proc "c" (θ: f16) -> f16 { return f16(sin_f64(f64(θ))) }
|
||||
@(require_results) cos_f16 :: proc "c" (θ: f16) -> f16 { return f16(cos_f64(f64(θ))) }
|
||||
@(require_results) pow_f16 :: proc "c" (x, power: f16) -> f16 { return f16(pow_f64(f64(x), f64(power))) }
|
||||
@(require_results) fmuladd_f16 :: proc "c" (a, b, c: f16) -> f16 { return f16(fmuladd_f64(f64(a), f64(a), f64(c))) }
|
||||
@(require_results) ln_f16 :: proc "c" (x: f16) -> f16 { return f16(ln_f64(f64(x))) }
|
||||
@(require_results) exp_f16 :: proc "c" (x: f16) -> f16 { return f16(exp_f64(f64(x))) }
|
||||
|
||||
sqrt_f32 :: proc "c" (x: f32) -> f32 { return f32(sqrt_f64(f64(x))) }
|
||||
sin_f32 :: proc "c" (θ: f32) -> f32 { return f32(sin_f64(f64(θ))) }
|
||||
cos_f32 :: proc "c" (θ: f32) -> f32 { return f32(cos_f64(f64(θ))) }
|
||||
pow_f32 :: proc "c" (x, power: f32) -> f32 { return f32(pow_f64(f64(x), f64(power))) }
|
||||
fmuladd_f32 :: proc "c" (a, b, c: f32) -> f32 { return f32(fmuladd_f64(f64(a), f64(a), f64(c))) }
|
||||
ln_f32 :: proc "c" (x: f32) -> f32 { return f32(ln_f64(f64(x))) }
|
||||
exp_f32 :: proc "c" (x: f32) -> f32 { return f32(exp_f64(f64(x))) }
|
||||
@(require_results) sqrt_f32 :: proc "c" (x: f32) -> f32 { return f32(sqrt_f64(f64(x))) }
|
||||
@(require_results) sin_f32 :: proc "c" (θ: f32) -> f32 { return f32(sin_f64(f64(θ))) }
|
||||
@(require_results) cos_f32 :: proc "c" (θ: f32) -> f32 { return f32(cos_f64(f64(θ))) }
|
||||
@(require_results) pow_f32 :: proc "c" (x, power: f32) -> f32 { return f32(pow_f64(f64(x), f64(power))) }
|
||||
@(require_results) fmuladd_f32 :: proc "c" (a, b, c: f32) -> f32 { return f32(fmuladd_f64(f64(a), f64(a), f64(c))) }
|
||||
@(require_results) ln_f32 :: proc "c" (x: f32) -> f32 { return f32(ln_f64(f64(x))) }
|
||||
@(require_results) exp_f32 :: proc "c" (x: f32) -> f32 { return f32(exp_f64(f64(x))) }
|
||||
|
||||
ln_f16le :: proc "contextless" (x: f16le) -> f16le { return #force_inline f16le(ln_f64(f64(x))) }
|
||||
ln_f16be :: proc "contextless" (x: f16be) -> f16be { return #force_inline f16be(ln_f64(f64(x))) }
|
||||
ln_f32le :: proc "contextless" (x: f32le) -> f32le { return #force_inline f32le(ln_f64(f64(x))) }
|
||||
ln_f32be :: proc "contextless" (x: f32be) -> f32be { return #force_inline f32be(ln_f64(f64(x))) }
|
||||
ln_f64le :: proc "contextless" (x: f64le) -> f64le { return #force_inline f64le(ln_f64(f64(x))) }
|
||||
ln_f64be :: proc "contextless" (x: f64be) -> f64be { return #force_inline f64be(ln_f64(f64(x))) }
|
||||
@(require_results) ln_f16le :: proc "contextless" (x: f16le) -> f16le { return #force_inline f16le(ln_f64(f64(x))) }
|
||||
@(require_results) ln_f16be :: proc "contextless" (x: f16be) -> f16be { return #force_inline f16be(ln_f64(f64(x))) }
|
||||
@(require_results) ln_f32le :: proc "contextless" (x: f32le) -> f32le { return #force_inline f32le(ln_f64(f64(x))) }
|
||||
@(require_results) ln_f32be :: proc "contextless" (x: f32be) -> f32be { return #force_inline f32be(ln_f64(f64(x))) }
|
||||
@(require_results) ln_f64le :: proc "contextless" (x: f64le) -> f64le { return #force_inline f64le(ln_f64(f64(x))) }
|
||||
@(require_results) ln_f64be :: proc "contextless" (x: f64be) -> f64be { return #force_inline f64be(ln_f64(f64(x))) }
|
||||
ln :: proc{
|
||||
ln_f16, ln_f16le, ln_f16be,
|
||||
ln_f32, ln_f32le, ln_f32be,
|
||||
|
||||
+14
-12
@@ -117,13 +117,14 @@ erf :: proc{
|
||||
erf_f64,
|
||||
}
|
||||
|
||||
erf_f16 :: proc "contextless" (x: f16) -> f16 { return f16(erf_f64(f64(x))) }
|
||||
erf_f16le :: proc "contextless" (x: f16le) -> f16le { return f16le(erf_f64(f64(x))) }
|
||||
erf_f16be :: proc "contextless" (x: f16be) -> f16be { return f16be(erf_f64(f64(x))) }
|
||||
erf_f32 :: proc "contextless" (x: f32) -> f32 { return f32(erf_f64(f64(x))) }
|
||||
erf_f32le :: proc "contextless" (x: f32le) -> f32le { return f32le(erf_f64(f64(x))) }
|
||||
erf_f32be :: proc "contextless" (x: f32be) -> f32be { return f32be(erf_f64(f64(x))) }
|
||||
@(require_results) erf_f16 :: proc "contextless" (x: f16) -> f16 { return f16(erf_f64(f64(x))) }
|
||||
@(require_results) erf_f16le :: proc "contextless" (x: f16le) -> f16le { return f16le(erf_f64(f64(x))) }
|
||||
@(require_results) erf_f16be :: proc "contextless" (x: f16be) -> f16be { return f16be(erf_f64(f64(x))) }
|
||||
@(require_results) erf_f32 :: proc "contextless" (x: f32) -> f32 { return f32(erf_f64(f64(x))) }
|
||||
@(require_results) erf_f32le :: proc "contextless" (x: f32le) -> f32le { return f32le(erf_f64(f64(x))) }
|
||||
@(require_results) erf_f32be :: proc "contextless" (x: f32be) -> f32be { return f32be(erf_f64(f64(x))) }
|
||||
|
||||
@(require_results)
|
||||
erf_f64 :: proc "contextless" (x: f64) -> f64 {
|
||||
erx :: 0h3FEB0AC160000000
|
||||
// Coefficients for approximation to erf in [0, 0.84375]
|
||||
@@ -268,13 +269,14 @@ erfc :: proc{
|
||||
erfc_f64,
|
||||
}
|
||||
|
||||
erfc_f16 :: proc "contextless" (x: f16) -> f16 { return f16(erfc_f64(f64(x))) }
|
||||
erfc_f16le :: proc "contextless" (x: f16le) -> f16le { return f16le(erfc_f64(f64(x))) }
|
||||
erfc_f16be :: proc "contextless" (x: f16be) -> f16be { return f16be(erfc_f64(f64(x))) }
|
||||
erfc_f32 :: proc "contextless" (x: f32) -> f32 { return f32(erfc_f64(f64(x))) }
|
||||
erfc_f32le :: proc "contextless" (x: f32le) -> f32le { return f32le(erfc_f64(f64(x))) }
|
||||
erfc_f32be :: proc "contextless" (x: f32be) -> f32be { return f32be(erfc_f64(f64(x))) }
|
||||
@(require_results) erfc_f16 :: proc "contextless" (x: f16) -> f16 { return f16(erfc_f64(f64(x))) }
|
||||
@(require_results) erfc_f16le :: proc "contextless" (x: f16le) -> f16le { return f16le(erfc_f64(f64(x))) }
|
||||
@(require_results) erfc_f16be :: proc "contextless" (x: f16be) -> f16be { return f16be(erfc_f64(f64(x))) }
|
||||
@(require_results) erfc_f32 :: proc "contextless" (x: f32) -> f32 { return f32(erfc_f64(f64(x))) }
|
||||
@(require_results) erfc_f32le :: proc "contextless" (x: f32le) -> f32le { return f32le(erfc_f64(f64(x))) }
|
||||
@(require_results) erfc_f32be :: proc "contextless" (x: f32be) -> f32be { return f32be(erfc_f64(f64(x))) }
|
||||
|
||||
@(require_results)
|
||||
erfc_f64 :: proc "contextless" (x: f64) -> f64 {
|
||||
erx :: 0h3FEB0AC160000000
|
||||
// Coefficients for approximation to erf in [0, 0.84375]
|
||||
|
||||
@@ -65,7 +65,7 @@ package math
|
||||
// The polynomial is valid for 33 <= x <= 172; larger values are only used
|
||||
// in reciprocal and produce denormalized floats. The lower precision there
|
||||
// masks any imprecision in the polynomial.
|
||||
@(private="file")
|
||||
@(private="file", require_results)
|
||||
stirling :: proc "contextless" (x: f64) -> (f64, f64) {
|
||||
@(static) gamS := [?]f64{
|
||||
+7.87311395793093628397e-04,
|
||||
@@ -93,6 +93,7 @@ stirling :: proc "contextless" (x: f64) -> (f64, f64) {
|
||||
return y1, SQRT_TWO_PI * w * y2
|
||||
}
|
||||
|
||||
@(require_results)
|
||||
gamma_f64 :: proc "contextless" (x: f64) -> f64 {
|
||||
is_neg_int :: proc "contextless" (x: f64) -> bool {
|
||||
if x < 0 {
|
||||
@@ -210,14 +211,14 @@ gamma_f64 :: proc "contextless" (x: f64) -> f64 {
|
||||
}
|
||||
|
||||
|
||||
gamma_f16 :: proc "contextless" (x: f16) -> f16 { return f16(gamma_f64(f64(x))) }
|
||||
gamma_f16le :: proc "contextless" (x: f16le) -> f16le { return f16le(gamma_f64(f64(x))) }
|
||||
gamma_f16be :: proc "contextless" (x: f16be) -> f16be { return f16be(gamma_f64(f64(x))) }
|
||||
gamma_f32 :: proc "contextless" (x: f32) -> f32 { return f32(gamma_f64(f64(x))) }
|
||||
gamma_f32le :: proc "contextless" (x: f32le) -> f32le { return f32le(gamma_f64(f64(x))) }
|
||||
gamma_f32be :: proc "contextless" (x: f32be) -> f32be { return f32be(gamma_f64(f64(x))) }
|
||||
gamma_f64le :: proc "contextless" (x: f64le) -> f64le { return f64le(gamma_f64(f64(x))) }
|
||||
gamma_f64be :: proc "contextless" (x: f64be) -> f64be { return f64be(gamma_f64(f64(x))) }
|
||||
@(require_results) gamma_f16 :: proc "contextless" (x: f16) -> f16 { return f16(gamma_f64(f64(x))) }
|
||||
@(require_results) gamma_f16le :: proc "contextless" (x: f16le) -> f16le { return f16le(gamma_f64(f64(x))) }
|
||||
@(require_results) gamma_f16be :: proc "contextless" (x: f16be) -> f16be { return f16be(gamma_f64(f64(x))) }
|
||||
@(require_results) gamma_f32 :: proc "contextless" (x: f32) -> f32 { return f32(gamma_f64(f64(x))) }
|
||||
@(require_results) gamma_f32le :: proc "contextless" (x: f32le) -> f32le { return f32le(gamma_f64(f64(x))) }
|
||||
@(require_results) gamma_f32be :: proc "contextless" (x: f32be) -> f32be { return f32be(gamma_f64(f64(x))) }
|
||||
@(require_results) gamma_f64le :: proc "contextless" (x: f64le) -> f64le { return f64le(gamma_f64(f64(x))) }
|
||||
@(require_results) gamma_f64be :: proc "contextless" (x: f64be) -> f64be { return f64be(gamma_f64(f64(x))) }
|
||||
|
||||
gamma :: proc{
|
||||
gamma_f16, gamma_f16le, gamma_f16be,
|
||||
|
||||
@@ -80,7 +80,9 @@ package math
|
||||
//
|
||||
|
||||
|
||||
@(require_results)
|
||||
lgamma_f64 :: proc "contextless" (x: f64) -> (lgamma: f64, sign: int) {
|
||||
@(require_results)
|
||||
sin_pi :: proc "contextless" (x: f64) -> f64 {
|
||||
if x < 0.25 {
|
||||
return -sin(PI * x)
|
||||
@@ -345,14 +347,14 @@ lgamma_f64 :: proc "contextless" (x: f64) -> (lgamma: f64, sign: int) {
|
||||
}
|
||||
|
||||
|
||||
lgamma_f16 :: proc "contextless" (x: f16) -> (lgamma: f16, sign: int) { r, s := lgamma_f64(f64(x)); return f16(r), s }
|
||||
lgamma_f32 :: proc "contextless" (x: f32) -> (lgamma: f32, sign: int) { r, s := lgamma_f64(f64(x)); return f32(r), s }
|
||||
lgamma_f16le :: proc "contextless" (x: f16le) -> (lgamma: f16le, sign: int) { r, s := lgamma_f64(f64(x)); return f16le(r), s }
|
||||
lgamma_f16be :: proc "contextless" (x: f16be) -> (lgamma: f16be, sign: int) { r, s := lgamma_f64(f64(x)); return f16be(r), s }
|
||||
lgamma_f32le :: proc "contextless" (x: f32le) -> (lgamma: f32le, sign: int) { r, s := lgamma_f64(f64(x)); return f32le(r), s }
|
||||
lgamma_f32be :: proc "contextless" (x: f32be) -> (lgamma: f32be, sign: int) { r, s := lgamma_f64(f64(x)); return f32be(r), s }
|
||||
lgamma_f64le :: proc "contextless" (x: f64le) -> (lgamma: f64le, sign: int) { r, s := lgamma_f64(f64(x)); return f64le(r), s }
|
||||
lgamma_f64be :: proc "contextless" (x: f64be) -> (lgamma: f64be, sign: int) { r, s := lgamma_f64(f64(x)); return f64be(r), s }
|
||||
@(require_results) lgamma_f16 :: proc "contextless" (x: f16) -> (lgamma: f16, sign: int) { r, s := lgamma_f64(f64(x)); return f16(r), s }
|
||||
@(require_results) lgamma_f32 :: proc "contextless" (x: f32) -> (lgamma: f32, sign: int) { r, s := lgamma_f64(f64(x)); return f32(r), s }
|
||||
@(require_results) lgamma_f16le :: proc "contextless" (x: f16le) -> (lgamma: f16le, sign: int) { r, s := lgamma_f64(f64(x)); return f16le(r), s }
|
||||
@(require_results) lgamma_f16be :: proc "contextless" (x: f16be) -> (lgamma: f16be, sign: int) { r, s := lgamma_f64(f64(x)); return f16be(r), s }
|
||||
@(require_results) lgamma_f32le :: proc "contextless" (x: f32le) -> (lgamma: f32le, sign: int) { r, s := lgamma_f64(f64(x)); return f32le(r), s }
|
||||
@(require_results) lgamma_f32be :: proc "contextless" (x: f32be) -> (lgamma: f32be, sign: int) { r, s := lgamma_f64(f64(x)); return f32be(r), s }
|
||||
@(require_results) lgamma_f64le :: proc "contextless" (x: f64le) -> (lgamma: f64le, sign: int) { r, s := lgamma_f64(f64(x)); return f64le(r), s }
|
||||
@(require_results) lgamma_f64be :: proc "contextless" (x: f64be) -> (lgamma: f64be, sign: int) { r, s := lgamma_f64(f64(x)); return f64be(r), s }
|
||||
|
||||
lgamma :: proc{
|
||||
lgamma_f16, lgamma_f16le, lgamma_f16be,
|
||||
|
||||
@@ -90,15 +90,16 @@ log1p :: proc {
|
||||
log1p_f64le,
|
||||
log1p_f64be,
|
||||
}
|
||||
log1p_f16 :: proc "contextless" (x: f16) -> f16 { return f16(log1p_f64(f64(x))) }
|
||||
log1p_f32 :: proc "contextless" (x: f32) -> f32 { return f32(log1p_f64(f64(x))) }
|
||||
log1p_f16le :: proc "contextless" (x: f16le) -> f16le { return f16le(log1p_f64(f64(x))) }
|
||||
log1p_f16be :: proc "contextless" (x: f16be) -> f16be { return f16be(log1p_f64(f64(x))) }
|
||||
log1p_f32le :: proc "contextless" (x: f32le) -> f32le { return f32le(log1p_f64(f64(x))) }
|
||||
log1p_f32be :: proc "contextless" (x: f32be) -> f32be { return f32be(log1p_f64(f64(x))) }
|
||||
log1p_f64le :: proc "contextless" (x: f64le) -> f64le { return f64le(log1p_f64(f64(x))) }
|
||||
log1p_f64be :: proc "contextless" (x: f64be) -> f64be { return f64be(log1p_f64(f64(x))) }
|
||||
@(require_results) log1p_f16 :: proc "contextless" (x: f16) -> f16 { return f16(log1p_f64(f64(x))) }
|
||||
@(require_results) log1p_f32 :: proc "contextless" (x: f32) -> f32 { return f32(log1p_f64(f64(x))) }
|
||||
@(require_results) log1p_f16le :: proc "contextless" (x: f16le) -> f16le { return f16le(log1p_f64(f64(x))) }
|
||||
@(require_results) log1p_f16be :: proc "contextless" (x: f16be) -> f16be { return f16be(log1p_f64(f64(x))) }
|
||||
@(require_results) log1p_f32le :: proc "contextless" (x: f32le) -> f32le { return f32le(log1p_f64(f64(x))) }
|
||||
@(require_results) log1p_f32be :: proc "contextless" (x: f32be) -> f32be { return f32be(log1p_f64(f64(x))) }
|
||||
@(require_results) log1p_f64le :: proc "contextless" (x: f64le) -> f64le { return f64le(log1p_f64(f64(x))) }
|
||||
@(require_results) log1p_f64be :: proc "contextless" (x: f64be) -> f64be { return f64be(log1p_f64(f64(x))) }
|
||||
|
||||
@(require_results)
|
||||
log1p_f64 :: proc "contextless" (x: f64) -> f64 {
|
||||
SQRT2_M1 :: 0h3fda827999fcef34 // sqrt(2)-1
|
||||
SQRT2_HALF_M1 :: 0hbfd2bec333018866 // sqrt(2)/2-1
|
||||
|
||||
@@ -0,0 +1,308 @@
|
||||
package math
|
||||
|
||||
import "core:math/bits"
|
||||
|
||||
// The original C code, the long comment, and the constants
|
||||
// below were from http://netlib.sandia.gov/cephes/cmath/sin.c,
|
||||
// available from http://www.netlib.org/cephes/cmath.tgz.
|
||||
// The go code is a simplified version of the original C.
|
||||
//
|
||||
// sin.c
|
||||
//
|
||||
// Circular sine
|
||||
//
|
||||
// SYNOPSIS:
|
||||
//
|
||||
// double x, y, sin();
|
||||
// y = sin( x );
|
||||
//
|
||||
// DESCRIPTION:
|
||||
//
|
||||
// Range reduction is into intervals of pi/4. The reduction error is nearly
|
||||
// eliminated by contriving an extended precision modular arithmetic.
|
||||
//
|
||||
// Two polynomial approximating functions are employed.
|
||||
// Between 0 and pi/4 the sine is approximated by
|
||||
// x + x**3 P(x**2).
|
||||
// Between pi/4 and pi/2 the cosine is represented as
|
||||
// 1 - x**2 Q(x**2).
|
||||
//
|
||||
// ACCURACY:
|
||||
//
|
||||
// Relative error:
|
||||
// arithmetic domain # trials peak rms
|
||||
// DEC 0, 10 150000 3.0e-17 7.8e-18
|
||||
// IEEE -1.07e9,+1.07e9 130000 2.1e-16 5.4e-17
|
||||
//
|
||||
// Partial loss of accuracy begins to occur at x = 2**30 = 1.074e9. The loss
|
||||
// is not gradual, but jumps suddenly to about 1 part in 10e7. Results may
|
||||
// be meaningless for x > 2**49 = 5.6e14.
|
||||
//
|
||||
// cos.c
|
||||
//
|
||||
// Circular cosine
|
||||
//
|
||||
// SYNOPSIS:
|
||||
//
|
||||
// double x, y, cos();
|
||||
// y = cos( x );
|
||||
//
|
||||
// DESCRIPTION:
|
||||
//
|
||||
// Range reduction is into intervals of pi/4. The reduction error is nearly
|
||||
// eliminated by contriving an extended precision modular arithmetic.
|
||||
//
|
||||
// Two polynomial approximating functions are employed.
|
||||
// Between 0 and pi/4 the cosine is approximated by
|
||||
// 1 - x**2 Q(x**2).
|
||||
// Between pi/4 and pi/2 the sine is represented as
|
||||
// x + x**3 P(x**2).
|
||||
//
|
||||
// ACCURACY:
|
||||
//
|
||||
// Relative error:
|
||||
// arithmetic domain # trials peak rms
|
||||
// IEEE -1.07e9,+1.07e9 130000 2.1e-16 5.4e-17
|
||||
// DEC 0,+1.07e9 17000 3.0e-17 7.2e-18
|
||||
//
|
||||
// Cephes Math Library Release 2.8: June, 2000
|
||||
// Copyright 1984, 1987, 1989, 1992, 2000 by Stephen L. Moshier
|
||||
//
|
||||
// The readme file at http://netlib.sandia.gov/cephes/ says:
|
||||
// Some software in this archive may be from the book _Methods and
|
||||
// Programs for Mathematical Functions_ (Prentice-Hall or Simon & Schuster
|
||||
// International, 1989) or from the Cephes Mathematical Library, a
|
||||
// commercial product. In either event, it is copyrighted by the author.
|
||||
// What you see here may be used freely but it comes with no support or
|
||||
// guarantee.
|
||||
//
|
||||
// The two known misprints in the book are repaired here in the
|
||||
// source listings for the gamma function and the incomplete beta
|
||||
// integral.
|
||||
//
|
||||
// Stephen L. Moshier
|
||||
// moshier@na-net.ornl.gov
|
||||
|
||||
sincos :: proc{
|
||||
sincos_f16, sincos_f16le, sincos_f16be,
|
||||
sincos_f32, sincos_f32le, sincos_f32be,
|
||||
sincos_f64, sincos_f64le, sincos_f64be,
|
||||
}
|
||||
|
||||
sincos_f16 :: proc "contextless" (x: f16) -> (sin, cos: f16) #no_bounds_check {
|
||||
s, c := sincos_f64(f64(x))
|
||||
return f16(s), f16(c)
|
||||
}
|
||||
sincos_f16le :: proc "contextless" (x: f16le) -> (sin, cos: f16le) #no_bounds_check {
|
||||
s, c := sincos_f64(f64(x))
|
||||
return f16le(s), f16le(c)
|
||||
}
|
||||
sincos_f16be :: proc "contextless" (x: f16be) -> (sin, cos: f16be) #no_bounds_check {
|
||||
s, c := sincos_f64(f64(x))
|
||||
return f16be(s), f16be(c)
|
||||
}
|
||||
|
||||
sincos_f32 :: proc "contextless" (x: f32) -> (sin, cos: f32) #no_bounds_check {
|
||||
s, c := sincos_f64(f64(x))
|
||||
return f32(s), f32(c)
|
||||
}
|
||||
sincos_f32le :: proc "contextless" (x: f32le) -> (sin, cos: f32le) #no_bounds_check {
|
||||
s, c := sincos_f64(f64(x))
|
||||
return f32le(s), f32le(c)
|
||||
}
|
||||
sincos_f32be :: proc "contextless" (x: f32be) -> (sin, cos: f32be) #no_bounds_check {
|
||||
s, c := sincos_f64(f64(x))
|
||||
return f32be(s), f32be(c)
|
||||
}
|
||||
|
||||
sincos_f64le :: proc "contextless" (x: f64le) -> (sin, cos: f64le) #no_bounds_check {
|
||||
s, c := sincos_f64(f64(x))
|
||||
return f64le(s), f64le(c)
|
||||
}
|
||||
sincos_f64be :: proc "contextless" (x: f64be) -> (sin, cos: f64be) #no_bounds_check {
|
||||
s, c := sincos_f64(f64(x))
|
||||
return f64be(s), f64be(c)
|
||||
}
|
||||
|
||||
sincos_f64 :: proc "contextless" (x: f64) -> (sin, cos: f64) #no_bounds_check {
|
||||
x := x
|
||||
|
||||
PI4A :: 0h3fe921fb40000000 // 7.85398125648498535156e-1 PI/4 split into three parts
|
||||
PI4B :: 0h3e64442d00000000 // 3.77489470793079817668e-8
|
||||
PI4C :: 0h3ce8469898cc5170 // 2.69515142907905952645e-15
|
||||
|
||||
// special cases
|
||||
switch {
|
||||
case x == 0:
|
||||
return x, 1 // return ±0.0, 1.0
|
||||
case is_nan(x) || is_inf(x, 0):
|
||||
return nan_f64(), nan_f64()
|
||||
}
|
||||
|
||||
// make argument positive
|
||||
sin_sign, cos_sign := false, false
|
||||
if x < 0 {
|
||||
x = -x
|
||||
sin_sign = true
|
||||
}
|
||||
|
||||
j: u64
|
||||
y, z: f64
|
||||
if x >= REDUCE_THRESHOLD {
|
||||
j, z = _trig_reduce_f64(x)
|
||||
} else {
|
||||
j = u64(x * (4 / PI)) // integer part of x/(PI/4), as integer for tests on the phase angle
|
||||
y = f64(j) // integer part of x/(PI/4), as float
|
||||
|
||||
if j&1 == 1 { // map zeros to origin
|
||||
j += 1
|
||||
y += 1
|
||||
}
|
||||
j &= 7 // octant modulo TAU radians (360 degrees)
|
||||
z = ((x - y*PI4A) - y*PI4B) - y*PI4C // Extended precision modular arithmetic
|
||||
}
|
||||
if j > 3 { // reflect in x axis
|
||||
j -= 4
|
||||
sin_sign, cos_sign = !sin_sign, !cos_sign
|
||||
}
|
||||
if j > 1 {
|
||||
cos_sign = !cos_sign
|
||||
}
|
||||
|
||||
zz := z * z
|
||||
|
||||
cos = 1.0 - 0.5*zz + zz*zz*((((((_cos[0]*zz)+_cos[1])*zz+_cos[2])*zz+_cos[3])*zz+_cos[4])*zz+_cos[5])
|
||||
sin = z + z*zz*((((((_sin[0]*zz)+_sin[1])*zz+_sin[2])*zz+_sin[3])*zz+_sin[4])*zz+_sin[5])
|
||||
|
||||
if j == 1 || j == 2 {
|
||||
sin, cos = cos, sin
|
||||
}
|
||||
if cos_sign {
|
||||
cos = -cos
|
||||
}
|
||||
if sin_sign {
|
||||
sin = -sin
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// sin coefficients
|
||||
@(private="file")
|
||||
_sin := [?]f64{
|
||||
0h3de5d8fd1fd19ccd, // 1.58962301576546568060e-10
|
||||
0hbe5ae5e5a9291f5d, // -2.50507477628578072866e-8
|
||||
0h3ec71de3567d48a1, // 2.75573136213857245213e-6
|
||||
0hbf2a01a019bfdf03, // -1.98412698295895385996e-4
|
||||
0h3f8111111110f7d0, // 8.33333333332211858878e-3
|
||||
0hbfc5555555555548, // -1.66666666666666307295e-1
|
||||
}
|
||||
|
||||
// cos coefficients
|
||||
@(private="file")
|
||||
_cos := [?]f64{
|
||||
0hbda8fa49a0861a9b, // -1.13585365213876817300e-11,
|
||||
0h3e21ee9d7b4e3f05, // 2.08757008419747316778e-9,
|
||||
0hbe927e4f7eac4bc6, // -2.75573141792967388112e-7,
|
||||
0h3efa01a019c844f5, // 2.48015872888517045348e-5,
|
||||
0hbf56c16c16c14f91, // -1.38888888888730564116e-3,
|
||||
0h3fa555555555554b, // 4.16666666666665929218e-2,
|
||||
}
|
||||
|
||||
// REDUCE_THRESHOLD is the maximum value of x where the reduction using Pi/4
|
||||
// in 3 f64 parts still gives accurate results. This threshold
|
||||
// is set by y*C being representable as a f64 without error
|
||||
// where y is given by y = floor(x * (4 / Pi)) and C is the leading partial
|
||||
// terms of 4/Pi. Since the leading terms (PI4A and PI4B in sin.go) have 30
|
||||
// and 32 trailing zero bits, y should have less than 30 significant bits.
|
||||
//
|
||||
// y < 1<<30 -> floor(x*4/Pi) < 1<<30 -> x < (1<<30 - 1) * Pi/4
|
||||
//
|
||||
// So, conservatively we can take x < 1<<29.
|
||||
// Above this threshold Payne-Hanek range reduction must be used.
|
||||
@(private="file")
|
||||
REDUCE_THRESHOLD :: 1 << 29
|
||||
|
||||
// _trig_reduce_f64 implements Payne-Hanek range reduction by Pi/4
|
||||
// for x > 0. It returns the integer part mod 8 (j) and
|
||||
// the fractional part (z) of x / (Pi/4).
|
||||
// The implementation is based on:
|
||||
// "ARGUMENT REDUCTION FOR HUGE ARGUMENTS: Good to the Last Bit"
|
||||
// K. C. Ng et al, March 24, 1992
|
||||
// The simulated multi-precision calculation of x*B uses 64-bit integer arithmetic.
|
||||
_trig_reduce_f64 :: proc "contextless" (x: f64) -> (j: u64, z: f64) #no_bounds_check {
|
||||
// bd_pi4 is the binary digits of 4/pi as a u64 array,
|
||||
// that is, 4/pi = Sum bd_pi4[i]*2^(-64*i)
|
||||
// 19 64-bit digits and the leading one bit give 1217 bits
|
||||
// of precision to handle the largest possible f64 exponent.
|
||||
@static bd_pi4 := [?]u64{
|
||||
0x0000000000000001,
|
||||
0x45f306dc9c882a53,
|
||||
0xf84eafa3ea69bb81,
|
||||
0xb6c52b3278872083,
|
||||
0xfca2c757bd778ac3,
|
||||
0x6e48dc74849ba5c0,
|
||||
0x0c925dd413a32439,
|
||||
0xfc3bd63962534e7d,
|
||||
0xd1046bea5d768909,
|
||||
0xd338e04d68befc82,
|
||||
0x7323ac7306a673e9,
|
||||
0x3908bf177bf25076,
|
||||
0x3ff12fffbc0b301f,
|
||||
0xde5e2316b414da3e,
|
||||
0xda6cfd9e4f96136e,
|
||||
0x9e8c7ecd3cbfd45a,
|
||||
0xea4f758fd7cbe2f6,
|
||||
0x7a0e73ef14a525d4,
|
||||
0xd7f6bf623f1aba10,
|
||||
0xac06608df8f6d757,
|
||||
}
|
||||
|
||||
PI4 :: PI / 4
|
||||
if x < PI4 {
|
||||
return 0, x
|
||||
}
|
||||
|
||||
MASK :: 0x7FF
|
||||
SHIFT :: 64 - 11 - 1
|
||||
BIAS :: 1023
|
||||
|
||||
// Extract out the integer and exponent such that,
|
||||
// x = ix * 2 ** exp.
|
||||
ix := transmute(u64)x
|
||||
exp := int(ix>>SHIFT&MASK) - BIAS - SHIFT
|
||||
ix &~= MASK << SHIFT
|
||||
ix |= 1 << SHIFT
|
||||
// Use the exponent to extract the 3 appropriate u64 digits from bd_pi4,
|
||||
// B ~ (z0, z1, z2), such that the product leading digit has the exponent -61.
|
||||
// Note, exp >= -53 since x >= PI4 and exp < 971 for maximum f64.
|
||||
digit, bitshift := uint(exp+61)/64, uint(exp+61)%64
|
||||
z0 := (bd_pi4[digit] << bitshift) | (bd_pi4[digit+1] >> (64 - bitshift))
|
||||
z1 := (bd_pi4[digit+1] << bitshift) | (bd_pi4[digit+2] >> (64 - bitshift))
|
||||
z2 := (bd_pi4[digit+2] << bitshift) | (bd_pi4[digit+3] >> (64 - bitshift))
|
||||
// Multiply mantissa by the digits and extract the upper two digits (hi, lo).
|
||||
z2hi, _ := bits.mul(z2, ix)
|
||||
z1hi, z1lo := bits.mul(z1, ix)
|
||||
z0lo := z0 * ix
|
||||
lo, c := bits.add(z1lo, z2hi, 0)
|
||||
hi, _ := bits.add(z0lo, z1hi, c)
|
||||
// The top 3 bits are j.
|
||||
j = hi >> 61
|
||||
// Extract the fraction and find its magnitude.
|
||||
hi = hi<<3 | lo>>61
|
||||
lz := uint(bits.leading_zeros(hi))
|
||||
e := u64(BIAS - (lz + 1))
|
||||
// Clear implicit mantissa bit and shift into place.
|
||||
hi = (hi << (lz + 1)) | (lo >> (64 - (lz + 1)))
|
||||
hi >>= 64 - SHIFT
|
||||
// Include the exponent and convert to a float.
|
||||
hi |= e << SHIFT
|
||||
z = transmute(f64)hi
|
||||
// Map zeros to origin.
|
||||
if j&1 == 1 {
|
||||
j += 1
|
||||
j &= 7
|
||||
z -= 1
|
||||
}
|
||||
// Multiply the fractional part by pi/4.
|
||||
return j, z * PI4
|
||||
}
|
||||
@@ -20,6 +20,7 @@ Vec4 :: [4]f64
|
||||
/*
|
||||
2D Simplex noise, standard lattice orientation.
|
||||
*/
|
||||
@(require_results)
|
||||
noise_2d :: proc(seed: i64, coord: Vec2) -> (value: f32) {
|
||||
// Get points for A2* lattice
|
||||
skew := SKEW_2D * (coord.x + coord.y)
|
||||
@@ -35,6 +36,7 @@ noise_2d :: proc(seed: i64, coord: Vec2) -> (value: f32) {
|
||||
unless your map is centered around an equator. It's a subtle
|
||||
difference, but the option is here to make it an easy choice.
|
||||
*/
|
||||
@(require_results)
|
||||
noise_2d_improve_x :: proc(seed: i64, coord: Vec2) -> (value: f32) {
|
||||
// Skew transform and rotation baked into one.
|
||||
xx := coord.x * ROOT_2_OVER_2
|
||||
@@ -51,6 +53,7 @@ noise_2d_improve_x :: proc(seed: i64, coord: Vec2) -> (value: f32) {
|
||||
If Z is vertical in world coordinates, call `noise_3d_improve_xz(x, y, Z)`.
|
||||
For a time varied animation, call `noise_3d_improve_xz(x, y, T)`.
|
||||
*/
|
||||
@(require_results)
|
||||
noise_3d_improve_xy :: proc(seed: i64, coord: Vec3) -> (value: f32) {
|
||||
/*
|
||||
Re-orient the cubic lattices without skewing, so Z points up the main lattice diagonal,
|
||||
@@ -75,6 +78,7 @@ noise_3d_improve_xy :: proc(seed: i64, coord: Vec3) -> (value: f32) {
|
||||
If Z is vertical in world coordinates, call `noise_3d_improve_xz(x, Z, y)` or use `noise_3d_improve_xy`.
|
||||
For a time varied animation, call `noise_3d_improve_xz(x, T, y)` or use `noise_3d_improve_xy`.
|
||||
*/
|
||||
@(require_results)
|
||||
noise_3d_improve_xz :: proc(seed: i64, coord: Vec3) -> (value: f32) {
|
||||
/*
|
||||
Re-orient the cubic lattices without skewing, so Y points up the main lattice diagonal,
|
||||
@@ -96,6 +100,7 @@ noise_3d_improve_xz :: proc(seed: i64, coord: Vec3) -> (value: f32) {
|
||||
Use `noise_3d_improve_xy` or `noise_3d_improve_xz` instead, wherever appropriate.
|
||||
They have less diagonal bias. This function's best use is as a fallback.
|
||||
*/
|
||||
@(require_results)
|
||||
noise_3d_fallback :: proc(seed: i64, coord: Vec3) -> (value: f32) {
|
||||
/*
|
||||
Re-orient the cubic lattices via rotation, to produce a familiar look.
|
||||
@@ -114,6 +119,7 @@ noise_3d_fallback :: proc(seed: i64, coord: Vec3) -> (value: f32) {
|
||||
Recommended for time-varied animations which texture a 3D object (W=time)
|
||||
in a space where Z is vertical.
|
||||
*/
|
||||
@(require_results)
|
||||
noise_4d_improve_xyz_improve_xy :: proc(seed: i64, coord: Vec4) -> (value: f32) {
|
||||
xy := coord.x + coord.y
|
||||
s2 := xy * -0.21132486540518699998
|
||||
@@ -133,6 +139,7 @@ noise_4d_improve_xyz_improve_xy :: proc(seed: i64, coord: Vec4) -> (value: f32)
|
||||
Recommended for time-varied animations which texture a 3D object (W=time)
|
||||
in a space where Y is vertical.
|
||||
*/
|
||||
@(require_results)
|
||||
noise_4d_improve_xyz_improve_xz :: proc(seed: i64, coord: Vec4) -> (value: f32) {
|
||||
xz := coord.x + coord.z
|
||||
s2 := xz * -0.21132486540518699998
|
||||
@@ -152,6 +159,7 @@ noise_4d_improve_xyz_improve_xz :: proc(seed: i64, coord: Vec4) -> (value: f32)
|
||||
Recommended for time-varied animations which texture a 3D object (W=time)
|
||||
where there isn't a clear distinction between horizontal and vertical
|
||||
*/
|
||||
@(require_results)
|
||||
noise_4d_improve_xyz :: proc(seed: i64, coord: Vec4) -> (value: f32) {
|
||||
xyz := coord.x + coord.y + coord.z
|
||||
ww := coord.w * 0.2236067977499788
|
||||
@@ -164,6 +172,7 @@ noise_4d_improve_xyz :: proc(seed: i64, coord: Vec4) -> (value: f32) {
|
||||
/*
|
||||
4D OpenSimplex2 noise, fallback lattice orientation.
|
||||
*/
|
||||
@(require_results)
|
||||
noise_4d_fallback :: proc(seed: i64, coord: Vec4) -> (value: f32) {
|
||||
// Get points for A4 lattice
|
||||
skew := f64(SKEW_4D) * (coord.x + coord.y + coord.z + coord.w)
|
||||
|
||||
@@ -7,6 +7,7 @@ float32_uniform :: float32_range
|
||||
|
||||
// Triangular Distribution
|
||||
// See: http://wikipedia.org/wiki/Triangular_distribution
|
||||
@(require_results)
|
||||
float64_triangular :: proc(lo, hi: f64, mode: Maybe(f64), r: ^Rand = nil) -> f64 {
|
||||
if hi-lo == 0 {
|
||||
return lo
|
||||
@@ -24,6 +25,7 @@ float64_triangular :: proc(lo, hi: f64, mode: Maybe(f64), r: ^Rand = nil) -> f64
|
||||
}
|
||||
// Triangular Distribution
|
||||
// See: http://wikipedia.org/wiki/Triangular_distribution
|
||||
@(require_results)
|
||||
float32_triangular :: proc(lo, hi: f32, mode: Maybe(f32), r: ^Rand = nil) -> f32 {
|
||||
if hi-lo == 0 {
|
||||
return lo
|
||||
@@ -41,20 +43,24 @@ float32_triangular :: proc(lo, hi: f32, mode: Maybe(f32), r: ^Rand = nil) -> f32
|
||||
|
||||
|
||||
// Normal/Gaussian Distribution
|
||||
@(require_results)
|
||||
float64_normal :: proc(mean, stddev: f64, r: ^Rand = nil) -> f64 {
|
||||
return norm_float64(r) * stddev + mean
|
||||
}
|
||||
// Normal/Gaussian Distribution
|
||||
@(require_results)
|
||||
float32_normal :: proc(mean, stddev: f32, r: ^Rand = nil) -> f32 {
|
||||
return f32(float64_normal(f64(mean), f64(stddev), r))
|
||||
}
|
||||
|
||||
|
||||
// Log Normal Distribution
|
||||
@(require_results)
|
||||
float64_log_normal :: proc(mean, stddev: f64, r: ^Rand = nil) -> f64 {
|
||||
return math.exp(float64_normal(mean, stddev, r))
|
||||
}
|
||||
// Log Normal Distribution
|
||||
@(require_results)
|
||||
float32_log_normal :: proc(mean, stddev: f32, r: ^Rand = nil) -> f32 {
|
||||
return f32(float64_log_normal(f64(mean), f64(stddev), r))
|
||||
}
|
||||
@@ -65,6 +71,7 @@ float32_log_normal :: proc(mean, stddev: f32, r: ^Rand = nil) -> f32 {
|
||||
// Return values range from
|
||||
// 0 to positive infinity if lambda > 0
|
||||
// negative infinity to 0 if lambda <= 0
|
||||
@(require_results)
|
||||
float64_exponential :: proc(lambda: f64, r: ^Rand = nil) -> f64 {
|
||||
return - math.ln(1 - float64(r)) / lambda
|
||||
}
|
||||
@@ -73,6 +80,7 @@ float64_exponential :: proc(lambda: f64, r: ^Rand = nil) -> f64 {
|
||||
// Return values range from
|
||||
// 0 to positive infinity if lambda > 0
|
||||
// negative infinity to 0 if lambda <= 0
|
||||
@(require_results)
|
||||
float32_exponential :: proc(lambda: f32, r: ^Rand = nil) -> f32 {
|
||||
return f32(float64_exponential(f64(lambda), r))
|
||||
}
|
||||
@@ -87,6 +95,7 @@ float32_exponential :: proc(lambda: f32, r: ^Rand = nil) -> f32 {
|
||||
// math.gamma(alpha) * math.pow(beta, alpha)
|
||||
//
|
||||
// mean is alpha*beta, variance is math.pow(alpha*beta, 2)
|
||||
@(require_results)
|
||||
float64_gamma :: proc(alpha, beta: f64, r: ^Rand = nil) -> f64 {
|
||||
if alpha <= 0 || beta <= 0 {
|
||||
panic(#procedure + ": alpha and beta must be > 0.0")
|
||||
@@ -152,6 +161,7 @@ float64_gamma :: proc(alpha, beta: f64, r: ^Rand = nil) -> f64 {
|
||||
// math.gamma(alpha) * math.pow(beta, alpha)
|
||||
//
|
||||
// mean is alpha*beta, variance is math.pow(alpha*beta, 2)
|
||||
@(require_results)
|
||||
float32_gamma :: proc(alpha, beta: f32, r: ^Rand = nil) -> f32 {
|
||||
return f32(float64_gamma(f64(alpha), f64(beta), r))
|
||||
}
|
||||
@@ -162,6 +172,7 @@ float32_gamma :: proc(alpha, beta: f32, r: ^Rand = nil) -> f32 {
|
||||
// Required: alpha > 0 and beta > 0
|
||||
//
|
||||
// Return values range between 0 and 1
|
||||
@(require_results)
|
||||
float64_beta :: proc(alpha, beta: f64, r: ^Rand = nil) -> f64 {
|
||||
if alpha <= 0 || beta <= 0 {
|
||||
panic(#procedure + ": alpha and beta must be > 0.0")
|
||||
@@ -178,6 +189,7 @@ float64_beta :: proc(alpha, beta: f64, r: ^Rand = nil) -> f64 {
|
||||
// Required: alpha > 0 and beta > 0
|
||||
//
|
||||
// Return values range between 0 and 1
|
||||
@(require_results)
|
||||
float32_beta :: proc(alpha, beta: f32, r: ^Rand = nil) -> f32 {
|
||||
return f32(float64_beta(f64(alpha), f64(beta), r))
|
||||
}
|
||||
@@ -185,22 +197,26 @@ float32_beta :: proc(alpha, beta: f32, r: ^Rand = nil) -> f32 {
|
||||
|
||||
// Pareto distribution, `alpha` is the shape parameter.
|
||||
// https://wikipedia.org/wiki/Pareto_distribution
|
||||
@(require_results)
|
||||
float64_pareto :: proc(alpha: f64, r: ^Rand = nil) -> f64 {
|
||||
return math.pow(1 - float64(r), -1.0 / alpha)
|
||||
}
|
||||
// Pareto distribution, `alpha` is the shape parameter.
|
||||
// https://wikipedia.org/wiki/Pareto_distribution
|
||||
@(require_results)
|
||||
float32_pareto :: proc(alpha, beta: f32, r: ^Rand = nil) -> f32 {
|
||||
return f32(float64_pareto(f64(alpha), r))
|
||||
}
|
||||
|
||||
|
||||
// Weibull distribution, `alpha` is the scale parameter, `beta` is the shape parameter.
|
||||
@(require_results)
|
||||
float64_weibull :: proc(alpha, beta: f64, r: ^Rand = nil) -> f64 {
|
||||
u := 1 - float64(r)
|
||||
return alpha * math.pow(-math.ln(u), 1.0/beta)
|
||||
}
|
||||
// Weibull distribution, `alpha` is the scale parameter, `beta` is the shape parameter.
|
||||
@(require_results)
|
||||
float32_weibull :: proc(alpha, beta: f32, r: ^Rand = nil) -> f32 {
|
||||
return f32(float64_weibull(f64(alpha), f64(beta), r))
|
||||
}
|
||||
@@ -210,6 +226,7 @@ float32_weibull :: proc(alpha, beta: f32, r: ^Rand = nil) -> f32 {
|
||||
// `mean_angle` is the in mean angle between 0 and 2pi radians
|
||||
// `kappa` is the concentration parameter which must be >= 0
|
||||
// When `kappa` is zero, the Distribution is a uniform Distribution over the range 0 to 2pi
|
||||
@(require_results)
|
||||
float64_von_mises :: proc(mean_angle, kappa: f64, r: ^Rand = nil) -> f64 {
|
||||
// Fisher, N.I., "Statistical Analysis of Circular Data", Cambridge University Press, 1993.
|
||||
|
||||
@@ -245,6 +262,7 @@ float64_von_mises :: proc(mean_angle, kappa: f64, r: ^Rand = nil) -> f64 {
|
||||
// `mean_angle` is the in mean angle between 0 and 2pi radians
|
||||
// `kappa` is the concentration parameter which must be >= 0
|
||||
// When `kappa` is zero, the Distribution is a uniform Distribution over the range 0 to 2pi
|
||||
@(require_results)
|
||||
float32_von_mises :: proc(mean_angle, kappa: f32, r: ^Rand = nil) -> f32 {
|
||||
return f32(float64_von_mises(f64(mean_angle), f64(kappa), r))
|
||||
}
|
||||
@@ -252,6 +270,7 @@ float32_von_mises :: proc(mean_angle, kappa: f32, r: ^Rand = nil) -> f32 {
|
||||
|
||||
// Cauchy-Lorentz Distribution
|
||||
// `x_0` is the location, `gamma` is the scale where `gamma` > 0
|
||||
@(require_results)
|
||||
float64_cauchy_lorentz :: proc(x_0, gamma: f64, r: ^Rand = nil) -> f64 {
|
||||
assert(gamma > 0)
|
||||
|
||||
@@ -261,6 +280,7 @@ float64_cauchy_lorentz :: proc(x_0, gamma: f64, r: ^Rand = nil) -> f64 {
|
||||
}
|
||||
// Cauchy-Lorentz Distribution
|
||||
// `x_0` is the location, `gamma` is the scale where `gamma` > 0
|
||||
@(require_results)
|
||||
float32_cauchy_lorentz :: proc(x_0, gamma: f32, r: ^Rand = nil) -> f32 {
|
||||
return f32(float64_cauchy_lorentz(f64(x_0), f64(gamma), r))
|
||||
}
|
||||
@@ -268,12 +288,14 @@ float32_cauchy_lorentz :: proc(x_0, gamma: f32, r: ^Rand = nil) -> f32 {
|
||||
|
||||
// Log Cauchy-Lorentz Distribution
|
||||
// `x_0` is the location, `gamma` is the scale where `gamma` > 0
|
||||
@(require_results)
|
||||
float64_log_cauchy_lorentz :: proc(x_0, gamma: f64, r: ^Rand = nil) -> f64 {
|
||||
assert(gamma > 0)
|
||||
return math.exp(math.tan(math.PI * (float64(r) - 0.5))*gamma + x_0)
|
||||
}
|
||||
// Log Cauchy-Lorentz Distribution
|
||||
// `x_0` is the location, `gamma` is the scale where `gamma` > 0
|
||||
@(require_results)
|
||||
float32_log_cauchy_lorentz :: proc(x_0, gamma: f32, r: ^Rand = nil) -> f32 {
|
||||
return f32(float64_log_cauchy_lorentz(f64(x_0), f64(gamma), r))
|
||||
}
|
||||
@@ -281,6 +303,7 @@ float32_log_cauchy_lorentz :: proc(x_0, gamma: f32, r: ^Rand = nil) -> f32 {
|
||||
|
||||
// Laplace Distribution
|
||||
// `b` is the scale where `b` > 0
|
||||
@(require_results)
|
||||
float64_laplace :: proc(mean, b: f64, r: ^Rand = nil) -> f64 {
|
||||
assert(b > 0)
|
||||
p := float64(r)-0.5
|
||||
@@ -288,6 +311,7 @@ float64_laplace :: proc(mean, b: f64, r: ^Rand = nil) -> f64 {
|
||||
}
|
||||
// Laplace Distribution
|
||||
// `b` is the scale where `b` > 0
|
||||
@(require_results)
|
||||
float32_laplace :: proc(mean, b: f32, r: ^Rand = nil) -> f32 {
|
||||
return f32(float64_laplace(f64(mean), f64(b), r))
|
||||
}
|
||||
@@ -296,6 +320,7 @@ float32_laplace :: proc(mean, b: f32, r: ^Rand = nil) -> f32 {
|
||||
// Gompertz Distribution
|
||||
// `eta` is the shape, `b` is the scale
|
||||
// Both `eta` and `b` must be > 0
|
||||
@(require_results)
|
||||
float64_gompertz :: proc(eta, b: f64, r: ^Rand = nil) -> f64 {
|
||||
if eta <= 0 || b <= 0 {
|
||||
panic(#procedure + ": eta and b must be > 0.0")
|
||||
@@ -307,6 +332,7 @@ float64_gompertz :: proc(eta, b: f64, r: ^Rand = nil) -> f64 {
|
||||
// Gompertz Distribution
|
||||
// `eta` is the shape, `b` is the scale
|
||||
// Both `eta` and `b` must be > 0
|
||||
@(require_results)
|
||||
float32_gompertz :: proc(eta, b: f32, r: ^Rand = nil) -> f32 {
|
||||
return f32(float64_gompertz(f64(eta), f64(b), r))
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import "core:math"
|
||||
// https://www.jstatsoft.org/index.php/jss/article/view/v005i08/ziggurat.pdf [pdf]
|
||||
// https://www.jstatsoft.org/article/view/v005i08 [web page]
|
||||
//
|
||||
@(require_results)
|
||||
exp_float64 :: proc(r: ^Rand = nil) -> f64 {
|
||||
re :: 7.69711747013104972
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user