Compare commits
635 Commits
Author | SHA1 | Date |
---|---|---|
Rémi Verschelde | 488757bd00 | |
A Thousand Ships | eb296c7f9c | |
Yuri Sizov | 6c9f2f7109 | |
Rémi Verschelde | 1ef40f418e | |
bruvzg | 5685756576 | |
Rémi Verschelde | 845fb92b03 | |
Rémi Verschelde | dc3a97a2c6 | |
A Thousand Ships | 7d9c3520a4 | |
Rémi Verschelde | 891c609d2e | |
Rémi Verschelde | ddaafbe81f | |
Rémi Verschelde | fe0e8e5575 | |
Yorick de Wid | 943b394946 | |
Rémi Verschelde | bb5ea0d249 | |
Rémi Verschelde | e03ea704e2 | |
Rémi Verschelde | 71a0be2b35 | |
Rémi Verschelde | 7c502d449a | |
Ekaterina Vaartis | 13b0956538 | |
Aaron Franke | 7c02f5cd5c | |
smix8 | 611c435dab | |
kleonc | c93eb1ba91 | |
melquiadess | f0c8d2c536 | |
Rémi Verschelde | eb281cc342 | |
Fabio Alessandrelli | 16bc127e00 | |
Micky | 83e985b159 | |
Micky | e7da23b5dd | |
A Thousand Ships | e1826e7caf | |
A Thousand Ships | 30eb46b938 | |
A Thousand Ships | 0cf3f3582a | |
A Thousand Ships | 169059efeb | |
Rémi Verschelde | 0c51c5cb1c | |
Silc Lizard (Tokage) Renew | 3c779d37bf | |
AlexOtsuka | caf55eb072 | |
Brandtware | 6c898685c7 | |
Jordyfel | 14b4742940 | |
Enhex | 7b4ea00218 | |
K. S. Ernest (iFire) Lee | e25abb5760 | |
kleonc | 0177ddb144 | |
A Thousand Ships | 5318c0ae6b | |
Haoyu Qiu | 3d8fc90d84 | |
Chronos-W | 64093528cd | |
A Thousand Ships | 31fd129ba0 | |
MewPurPur | ecf7f3f349 | |
Haoyu Qiu | afc47f93d1 | |
Danil Alexeev | 527e1d12b0 | |
iltenahmet | 44211441f3 | |
Rémi Verschelde | fbc4a7e3a5 | |
Micky | dc2a52141a | |
Micky | 634c413791 | |
Max Hilbrunner | 3e908bfef3 | |
Aaron Franke | 49c95e7bbb | |
Fabio Alessandrelli | bc0c61a30b | |
Pedro J. Estébanez | 15ac760e4a | |
Thaddeus Crews | 00cfd6dcac | |
Paul Joannon | c1efc31f2b | |
bruvzg | 776696eb64 | |
Alexander Hartmann | 601afdf1d5 | |
Adam Scott | c8ae076c1a | |
Adam Scott | 00e3aa9b07 | |
A Thousand Ships | 59b0a8da4f | |
A Thousand Ships | aec956d7c6 | |
A Thousand Ships | c2ff91c418 | |
Micky | 962575ad73 | |
A Thousand Ships | 045c42f514 | |
A Thousand Ships | dd6eced096 | |
Rémi Verschelde | bbc06c7cc8 | |
A Thousand Ships | 201ccb7aeb | |
Zi Ye | b0ca5cdc12 | |
Markus Sauermann | e01bf42ca5 | |
A Thousand Ships | 3eee0c0563 | |
A Thousand Ships | e96c67d725 | |
SaNeOr | f518099f73 | |
Cariad Eccleston | f63b703f21 | |
A Thousand Ships | 10848d0e80 | |
Dalton | 846892d366 | |
Hugo Locurcio | 5afb5e3132 | |
Hugo Locurcio | 803e901e22 | |
Allen Pestaluky | cbe3bf7511 | |
Hugo Locurcio | 4d45daec12 | |
Florian Grabmeier | 5e483e5af4 | |
A Thousand Ships | 25e88dd552 | |
Micky | 848d93f144 | |
Micky | a0a44578aa | |
Micky | 185cfee96f | |
Micky | 503dc95d71 | |
Micky | ccc4f49c22 | |
Micky | 44fc5956aa | |
Micky | 6b734531a3 | |
20kdc | fd9f1a7c41 | |
Hugo Locurcio | 3e4519fc2f | |
Lucas Clemente Vella | cdf8e0e87c | |
kobewi | 3c76c89cc7 | |
clayjohn | a24347d041 | |
Markus Sauermann | 5dfaec5c29 | |
Rémi Verschelde | 1281517746 | |
Mikael Hermansson | 036c9715c2 | |
AlexOtsuka | 702be5e2f2 | |
Rémi Verschelde | 19673840fb | |
Jakub Marcowski | f464e5d3f5 | |
Jakub Mateusz Marcowski | ce72cd9651 | |
Rémi Verschelde | 5b493f7214 | |
Rémi Verschelde | 8db15d9dc8 | |
Rémi Verschelde | 3de73d0249 | |
Rémi Verschelde | a3e39e2f57 | |
LinuxUserGD | 5c10605295 | |
Fredia Huya-Kouadio | 10f49cb758 | |
Andreia Gaita | 4182f2435a | |
Adam Scott | b11c95dc98 | |
Rémi Verschelde | 193592d532 | |
Fabio Alessandrelli | 5b4c5c4118 | |
bruvzg | 8c54f7b6cd | |
Adam Scott | 0d75fc564b | |
A Thousand Ships | 49927fb64c | |
Pedro J. Estébanez | 2860ed6064 | |
Rémi Verschelde | 10da4db645 | |
bruvzg | ec0ddc4633 | |
Rémi Verschelde | 68154d8a71 | |
Pedro J. Estébanez | 664b2502d2 | |
Michael Wörner | e1421715e8 | |
Rémi Verschelde | 77598f0708 | |
Aaron Franke | 72f00333dd | |
Yuri Sizov | b9008f3d51 | |
Yuri Sizov | 51c0672b13 | |
Yuri Sizov | c39ad18bfa | |
kleonc | 5b05029b35 | |
ShirenY | 211dd2fb53 | |
Hugo Locurcio | e2c96dc711 | |
Micky | 1ec0e4fba1 | |
jsjtxietian | f5c7a0e832 | |
Micky | 45fc8a3b43 | |
Hugo Locurcio | ffed9d36b5 | |
Micky | c02fcb4ede | |
Rémi Verschelde | 329f2ce49b | |
Quincy Wofford | 57fe32f8da | |
Hugo Locurcio | c72c69379a | |
Fabio Alessandrelli | e11165d7f1 | |
Michael Macha | 0904f0affd | |
LunaticInAHat | afac25a3f8 | |
Ricardo Subtil | c8fabac8c7 | |
rsburke4 | c9924b11a4 | |
Pedro J. Estébanez | 62485a51fd | |
Pedro J. Estébanez | 4b71c38e47 | |
Fredia Huya-Kouadio | 307a6eba6b | |
A Thousand Ships | a8180680af | |
A Thousand Ships | ab7d9578b7 | |
clayjohn | dc6ae4a8f0 | |
Rémi Verschelde | 8d479e8389 | |
Raul Santos | f4e6063ed8 | |
Lyuma | a4cabd7497 | |
CardboardCarl | b3018d81c5 | |
A Thousand Ships | 3df6145361 | |
Bartłomiej T. Listwon | b113602ce5 | |
jsjtxietian | 5376aea688 | |
Occalepsus | a092b1aa38 | |
Erik Johnson | dfcd70c09f | |
31 | 2c062f1922 | |
Alessandro Famà | 1fa33b6072 | |
Micky | 5ffc22b06f | |
BlueCube3310 | bf2b98b801 | |
Yuri Sizov | b915d7d9f2 | |
ChibiDenDen | d75566167f | |
LRFLEW | 38037bae47 | |
Malcolm Nixon | 5115b119f8 | |
aXu-AP | e7db7b552d | |
Haoyu Qiu | 32a3b2bf9c | |
A Thousand Ships | 9598a32b7b | |
HolySkyMin | c51b59c1fc | |
Ellen Poe | 97b081b45f | |
jsjtxietian | 7180817900 | |
bruvzg | 9d1d916864 | |
Alex Drozd | 3daaaff330 | |
Yuri Sizov | cf97df236d | |
addmix | 87798576f0 | |
Hugo Locurcio | 4cec48f1ea | |
A Thousand Ships | d9af9dd682 | |
Hugo Locurcio | da200b99c9 | |
Roy Berube | d8b89badfd | |
aXu-AP | 8a395124e6 | |
Rémi Verschelde | 98cfa8bcf2 | |
Nico | 2ff7b6c830 | |
clayjohn | 9c82571dd6 | |
jsjtxietian | 126874bb38 | |
bruvzg | d3713220b8 | |
kobewi | 326314eaa9 | |
Gabor Koncz | 46bcfa82e1 | |
Bastiaan Olij | 140f5a6a5a | |
Andreia Gaita | d9d4a2bb1d | |
bruvzg | b62b3fc40b | |
smix8 | b0179bba74 | |
smix8 | 0cf4e79b48 | |
Fredia Huya-Kouadio | f6a9129219 | |
Fredia Huya-Kouadio | a3432848b2 | |
Guilherme | 2762ae69d4 | |
Rémi Verschelde | c3a6dd2c11 | |
Hugo Locurcio | b468496700 | |
Haoyu Qiu | c5e94ad9de | |
Anutrix | b3b9342bf1 | |
Fredia Huya-Kouadio | 2559d4b587 | |
coumcashier | 4619d34b91 | |
Rémi Verschelde | 1e460e37c3 | |
Stanislav Labzyuk | 4100743a62 | |
kobewi | 0a7af396c4 | |
jitspoe | ceb0602c16 | |
scgm0 | 561b843831 | |
jsjtxietian | a966068f09 | |
A Thousand Ships | 9c68648d72 | |
jsjtxietian | e63a7215bb | |
bitsawer | 28a44d7bbc | |
jsjtxietian | 98002e03d7 | |
Hugo Locurcio | 95ca8e0365 | |
Pedro J. Estébanez | 1aeff1a7a5 | |
kobewi | 1bd63576b8 | |
A Thousand Ships | 36c7a47b11 | |
Hugo Locurcio | 3d4f1ce21f | |
Raul Santos | 6d1401cb8d | |
jsjtxietian | cf61f5e938 | |
stoofin | 73b0984764 | |
Ege Yıldır | 06d8262b57 | |
A Thousand Ships | f563f8bfa6 | |
Hugo Locurcio | e33eb36231 | |
thfrwn | 204f3bd58d | |
A Thousand Ships | f247ffef54 | |
Thaddeus Crews | ce9eee097e | |
A Thousand Ships | f311b0557c | |
Hugo Locurcio | 0ca1957445 | |
bitsawer | d38b61d523 | |
A Thousand Ships | a33cf3b6bf | |
Haoyu Qiu | a4912b8a63 | |
RealMadvicius | 8ed4af259a | |
A Thousand Ships | 5470eb5894 | |
John Watson | 76d5a0e723 | |
Alfonso J. Ramos | a285553472 | |
Brian MacIntosh | 04bd9cc06c | |
crazyStewie | 222cba2aab | |
bruvzg | 8face42022 | |
Silc Lizard (Tokage) Renew | 37e6267c6b | |
A Thousand Ships | 222ceb7a82 | |
Ben Rog-Wilhelm | a71153d9bd | |
Rémi Verschelde | 44098e56c9 | |
Rindbee | 52d56d806d | |
MrBBBaiXue | 965ea011a0 | |
bruvzg | ba41f42c82 | |
Mikael Klasson | 39271362c3 | |
HolySkyMin | d4a406f4a5 | |
Rémi Verschelde | 2d3b2abcf6 | |
Rémi Verschelde | 1e1d91df6a | |
Yuri Sizov | 65f5865d11 | |
Yuri Sizov | fc79201851 | |
Yuri Sizov | b79961e3c0 | |
Fredia Huya-Kouadio | 74a1d8addd | |
Yuri Sizov | c5e3fcbeb6 | |
风青山 | 7c3ac4d170 | |
Yuri Sizov | f80c673cdf | |
Rémi Verschelde | 56feab3258 | |
Yuri Sizov | 4a4356dafc | |
David Snopek | 9a322737cc | |
warriormaster12 | 9e315e7c79 | |
ajreckof | 5abac84a9e | |
Alexander Hartmann | 3d8c77dc92 | |
Saif Kandil | d73b76da02 | |
CopyTIME | f2dd4086b7 | |
kobewi | 7f2ebc2389 | |
Rémi Verschelde | 93becd4d2e | |
David Snopek | 10eafe236c | |
Ninni Pipping | c148398735 | |
Ryan Roden-Corrent | c93d74aca0 | |
A Thousand Ships | 578fa8603d | |
Rémi Verschelde | 4c8ee43d08 | |
Rémi Verschelde | 0b3c182038 | |
Matthew Borkowski | 34811c1f1e | |
Max Hilbrunner | e37eb47144 | |
Lunarisnia | 471af30f7b | |
A Thousand Ships | d56a6ad461 | |
Haoyu Qiu | ac57043a34 | |
bitsawer | 27d47246b5 | |
floatingpointer | 82ad6a3dad | |
Yogendra Manawat | 2b8dbbccae | |
Daniel Castellanos | de6e7c070c | |
朱力 | 11f9e35c06 | |
bitsawer | dac7049e16 | |
Radiant | 15eaeddfbf | |
bruvzg | d7fc0805c8 | |
bitsawer | e65f98576b | |
clayjohn | 51fd44318f | |
Haoyu Qiu | 1ebfd2f510 | |
bitsawer | 27b0e5aebb | |
bitsawer | efe99e5479 | |
bitsawer | 75671b7937 | |
viksl | ee6bdce5a1 | |
viksl | c9e5f90813 | |
tomissj2 | ecd098341a | |
bruvzg | 426e5288a1 | |
Aitor Guevara | fdfa59ee6c | |
GrammAcc | 3c3fad858c | |
0x4448 | ced93eb2e5 | |
jsjtxietian | 2d82ab735c | |
BlueCube3310 | f220aaa54b | |
Eric Liu | 3bc614bb1c | |
Hugo Locurcio | 61374c7794 | |
kleonc | e5c8d1ec0b | |
Rémi Verschelde | aa05918971 | |
RedworkDE | fb73281519 | |
Fabio Alessandrelli | fbc4ed8d94 | |
Adam Scott | 21e1148cc5 | |
SysError99 | 55ae5b0a78 | |
Saracen | 314dac441b | |
Saracen | eb414422fe | |
bitsawer | 3d47a3662f | |
bruvzg | ff59871b86 | |
Mario Liebisch | 5bb54d3184 | |
bitsawer | 08bc3570ae | |
bitsawer | 4f04d3191e | |
Lyuma | 299413157a | |
chokomancarr | 78713a427c | |
Matias N. Goldberg | b7498aeb5d | |
Tom Coxon | ba27e16275 | |
Aaron Franke | 3518801deb | |
A Thousand Ships | b0c59de143 | |
Gilles Roudière | 89325e8f13 | |
ocean (they/them) | 2beec2b00f | |
Fredia Huya-Kouadio | e0221d1c09 | |
Chia-Hsiang Cheng | 48b92610ce | |
Haoyu Qiu | d69359fa92 | |
jsjtxietian | a8e67284a9 | |
Alexander Hartmann | e19f868e09 | |
A Thousand Ships | 74506ce901 | |
David Nikdel | 4d498e18ec | |
AttackButton | 90b8a2ae8c | |
Raul Santos | 3c84e5a947 | |
Chia-Hsiang Cheng | 9e7652c5db | |
A Thousand Ships | a9566c17fc | |
Hugo Locurcio | 8d6493fae4 | |
BlueCube3310 | 165c49066b | |
Pedro J. Estébanez | d3d5531658 | |
ARez | ca6fba87de | |
Mateus Elias | cfd8b3cd9b | |
bitsawer | daa44c778c | |
bitsawer | 7d76bcbac6 | |
Rakka Rage | 22560c5bf0 | |
Brecht Kuppens | 4944a07044 | |
Fabio Alessandrelli | 560c52cef2 | |
Marcus Elg | 035fece0e7 | |
Bastiaan Olij | 82846a7e6d | |
Markus Sauermann | 1c0ffdaa87 | |
vitormaduro | 60b432a1f0 | |
azuloo | 3de5e5d4d4 | |
Kirill Diduk | eaa2485a5d | |
Hugo Locurcio | 67e1849bd4 | |
Chia-Hsiang Cheng | 1588eae8fa | |
PorkrollPosadist | f5130502be | |
pidogs | 67f5ec2f2f | |
Rindbee | 00d5da2f09 | |
Danil Alexeev | d5a11e17b8 | |
jsjtxietian | efa82d5025 | |
Chia-Hsiang Cheng | 3e9751aca4 | |
Andrés Botero | 2e39550306 | |
Septian | 35d622b029 | |
Emmanuel Ferdman | 7773e1ed96 | |
mandryskowski | 666460448d | |
Septian | bede7fa0d8 | |
Bastiaan Olij | ed94e3eb79 | |
Haoyu Qiu | b027d000cb | |
samdevelopscode | 7fa44784f8 | |
Matias N. Goldberg | 1f4a5c2c15 | |
bruvzg | 02c6d985b8 | |
ajreckof | 3d0c29cc0a | |
Haoyu Qiu | 06f6ef8fca | |
smix8 | d0b652932e | |
bruvzg | eca105f075 | |
Raul Santos | 85ab269796 | |
Ninni Pipping | 5cc85fb119 | |
Haoyu Qiu | 06b777fe4a | |
LRFLEW | 3df5907c87 | |
Haoyu Qiu | 2192c717a4 | |
detomon | cf1674c423 | |
Haoyu Qiu | 188d9040d3 | |
smix8 | 8fab0ff848 | |
Pedro J. Estébanez | ff6229e794 | |
kobewi | f7d1f9e25b | |
Sathvik Mulukutla | 77f6d00ad8 | |
Hugo Locurcio | c8bd1259af | |
Rémi Verschelde | 399c9dc393 | |
Rémi Verschelde | 681efc5bc5 | |
Rémi Verschelde | aae20e5b10 | |
Rémi Verschelde | 78fe0e47b1 | |
Fabio Alessandrelli | 52e2bde16f | |
Nomad1 | 33b965367c | |
Rémi Verschelde | 6b37ad40d7 | |
Rémi Verschelde | df0ebc6dfc | |
bruvzg | 9308d20d1b | |
Rémi Verschelde | c966bdf358 | |
Yuri Sizov | d5fab0ec4c | |
Michael Alexsander | 9bf09194cc | |
Rémi Verschelde | 58f0cae4af | |
DeeJayLSP | 2edd2f0202 | |
Rémi Verschelde | 089ecc0a82 | |
Yuri Sizov | 71ff34eaee | |
A Thousand Ships | c941715850 | |
bruvzg | 140eb6886f | |
ajreckof | 265fe750a8 | |
Tyler | fed41ae520 | |
Ben Rog-Wilhelm | f8cf6eb567 | |
Fabio Alessandrelli | 4355bf9cf3 | |
Chia-Hsiang Cheng | e65172237c | |
Adam Scott | 6318354212 | |
Fabio Alessandrelli | dabd733c4c | |
Sami Kalliomäki | c26722badf | |
Haoyu Qiu | cdc26082aa | |
bitsawer | 8d22e58063 | |
kleonc | 3b3f7efadb | |
Silc Lizard (Tokage) Renew | bb4ad56e95 | |
Chia-Hsiang Cheng | bad5e93945 | |
Hugo Locurcio | 89dd2d066f | |
Hugo Locurcio | 9812dfd450 | |
Nikola Bunjevac | 3b4748f6b5 | |
trollodel | 5e8654decb | |
Ricardo Subtil | 788ee7938b | |
Dario | fc130b26f8 | |
bruvzg | 21da3f3847 | |
Spencer Chang | c339abe1aa | |
jsjtxietian | 1238554f05 | |
David Snopek | 113cfdfc69 | |
Ninni Pipping | 4734295fd1 | |
Markus Sauermann | 45718ef635 | |
jsjtxietian | 2e71f6a806 | |
Ninni Pipping | dfdb6e576c | |
ocean (they/them) | 0b38cf8a8d | |
Lyuma | 58e3dd6999 | |
Raul Santos | a07b83a2dc | |
bruvzg | 88afb1a8ba | |
Emmanouil Papadeas | 252d816459 | |
Chia-Hsiang Cheng | cdc0e00557 | |
Eoin O'Neill | 58ff96b8b7 | |
Hugo Locurcio | 2d480eb632 | |
Dario | 29bcc51734 | |
Dario | 1bcb77fb15 | |
Dario | 1f18125652 | |
Dario | b447e1baaf | |
Matias N. Goldberg | efbe9237cc | |
Yogendra Manawat | a90aac5415 | |
bitsawer | 904582b4a8 | |
bitsawer | bc95b36fbf | |
Haoyu Qiu | 9dfb3ddad5 | |
Hugo Locurcio | a972686972 | |
Haoyu Qiu | de5a7b3764 | |
Danil Alexeev | 102f93b8b8 | |
A Thousand Ships | c4be3487ca | |
A Thousand Ships | 485d53133d | |
clayjohn | 5261d12a66 | |
Yuri Sizov | 08bd6ba734 | |
kobewi | a5b59b596f | |
Adam Scott | 4f59255059 | |
Rémi Verschelde | daedd124ac | |
Rémi Verschelde | 269b115d9c | |
Rémi Verschelde | 8be838481d | |
bruvzg | a4c041b6b6 | |
Valery Zhuk | 94dfa4eaf9 | |
Dario | 5f7685c831 | |
Rémi Verschelde | 12aeb83043 | |
Rémi Verschelde | 6122cf3178 | |
Rémi Verschelde | 9fb23c4e56 | |
ocean (they/them) | cd2e003a05 | |
bruvzg | d3265cf518 | |
Rémi Verschelde | e30ff075ce | |
Rémi Verschelde | 21adf29b8e | |
Rémi Verschelde | cdce948473 | |
Rémi Verschelde | 32b7664371 | |
bruvzg | ee009d26da | |
Rémi Verschelde | 3076f2f9c9 | |
kobewi | ef1d0cda30 | |
William Edwards | 9332a2b387 | |
Dario | f6f2b0897a | |
jsjtxietian | f2b6eda210 | |
Danil Alexeev | 6d5127d34b | |
bitsawer | 3c5f715053 | |
A Thousand Ships | 4e539028fb | |
HolonProduction | 96b8861c9d | |
clayjohn | 2c9901af36 | |
Lyuma | 6fa4270d71 | |
Ninni Pipping | f54cbe6b76 | |
Hrvoje Varga | 8f32e968b8 | |
Rindbee | 5f46bca824 | |
Fabian Keller | 76f61b3960 | |
Ryan Hitchman | e7978fe277 | |
kleonc | bf15d20e56 | |
bitsawer | 3920b2db05 | |
bitsawer | a606b03fd7 | |
Danil Alexeev | c57d6c9371 | |
Markus Sauermann | dbae37cc50 | |
A Thousand Ships | d5c246bbd3 | |
Danil Alexeev | 18f69e9ee1 | |
Danil Alexeev | 676013ce96 | |
Danil Alexeev | 75db138533 | |
Fabio Alessandrelli | 5eabd5e04a | |
Rémi Verschelde | f2c8eea60e | |
Rémi Verschelde | f2644f0cb0 | |
A Thousand Ships | 8e9852fa43 | |
Rémi Verschelde | a43c625d4e | |
Malcolm Nixon | d7f7c92f61 | |
LRFLEW | e47abd790a | |
Markus Sauermann | 2d607d7c5c | |
MewPurPur | 2c154348fc | |
kleonc | 053538c125 | |
kleonc | e34241a809 | |
Septian | 5360058d1c | |
Adam Scott | f3302b8089 | |
LRFLEW | f8ffad873a | |
univeous | 7627337d63 | |
Fabio Alessandrelli | dc1c3d03da | |
Fabio Alessandrelli | f6e436c34c | |
Ninni Pipping | 5641ad49e9 | |
Geoffroy Warin | da5cf99a34 | |
Matt Diener | 88f5f815e6 | |
kleonc | c6c5b5bf78 | |
smix8 | 605f1c0936 | |
smix8 | 663f45ba4e | |
bruvzg | e67b6e0d0f | |
Bastiaan Olij | ed9216d1d8 | |
Haoyu Qiu | 5e7a5cd2b1 | |
Aaron Franke | 6ecf741b7a | |
kobewi | 56a0004478 | |
Ninni Pipping | a31b866793 | |
Haoyu Qiu | b0ceeb2341 | |
Haoyu Qiu | 71ba2aca63 | |
smix8 | cd7411c58d | |
bitsawer | 143963d122 | |
George Marques | 01511caaf1 | |
Michael Alexsander | 3bb05da45f | |
MineBill | 4ec566fae2 | |
Hayden Leete | a9a27c7ea5 | |
kobewi | 271e08e543 | |
bruvzg | f346b8133e | |
Rémi Verschelde | b47d786921 | |
Rémi Verschelde | af6e5b9f0d | |
Rémi Verschelde | fc63a8d349 | |
Rémi Verschelde | 8d30a9f2a5 | |
Rémi Verschelde | 4c354b4977 | |
Rémi Verschelde | 023e154cb4 | |
Rémi Verschelde | 894d4ca769 | |
bruvzg | c1ba321815 | |
Rémi Verschelde | 346d0bba07 | |
bruvzg | 9ed12c884a | |
Rémi Verschelde | 7a86ffc034 | |
Rémi Verschelde | caa8c82567 | |
Yuri Sizov | e1a12879e9 | |
Rémi Verschelde | e9cdd1bf08 | |
Yuri Sizov | 6884be6b17 | |
Yuri Sizov | bd6af8e0ea | |
Yuri Sizov | e94d355366 | |
Yuri Sizov | 80aef72ef3 | |
kobewi | b45e7f0f63 | |
Septian | a6b1c0edbb | |
WiseNoodle | 085b16b1bb | |
stmSi | 74efa063cc | |
Septian | c1ddd0485b | |
kobewi | 0a4067bdbf | |
Yuri Sizov | e709ad4d64 | |
Yuri Sizov | 92cf616f63 | |
kleonc | 2796b629e9 | |
Rémi Verschelde | 30ab0e2cf4 | |
Rémi Verschelde | 6ec2d6d7d0 | |
Aaron Franke | e3cfc023b4 | |
Ninni Pipping | 1e2bfdc9bb | |
Haoyu Qiu | 167b02d942 | |
HolonProduction | 438a598713 | |
Aaron Franke | 5729e40035 | |
Aaron Franke | ec6d258db0 | |
kobewi | a79160ebd2 | |
Pedro J. Estébanez | b3a56228b1 | |
Emmanouil Papadeas | 2f32a3454c | |
Rémi Verschelde | 29b4ee3d97 | |
Chinmay Awale | 4f4052581b | |
NiskashY | 36ce14a826 | |
Rindbee | 1c1d4f6264 | |
clayjohn | d6d8f6a637 | |
Chris Bradfield | 55ae2a3297 | |
smix8 | 0d51fec22b | |
smix8 | bbfdfab748 | |
Kamil Brzoskowski | 6becf94f49 | |
clayjohn | 7447946dd1 | |
Septian | 5576f5ab81 | |
RedworkDE | 3f334cb144 | |
Markus Sauermann | 42b8ae50d2 | |
Septian | add7c218d1 | |
Arman Elgudzhyan | 361c0d53f3 | |
Aaron Franke | c8b50871fe | |
MewPurPur | a4547db15b | |
Ninni Pipping | fb8e21bd6d | |
Ninni Pipping | 90b4a3fa75 | |
Yadnesh Kulkarni | 09c245fd74 | |
Joe Marshall | fa6fb0ac70 | |
Angad Kambli | cdeddffee7 | |
Rémi Verschelde | 4c1c26979b | |
bruvzg | fa45bb63c6 | |
bruvzg | 393076a4b3 | |
Ivan Shakhov | c9b1d99cae | |
Florian Kothmeier | 240701f95a | |
Hugo Locurcio | ac87b5df75 | |
Hugo Locurcio | fe8e7a0b22 | |
Hugo Locurcio | e32330473a | |
lewiji | a084f0568f | |
Dawid Marzec | 87b4143f3b | |
Rémi Verschelde | 1875ecb776 | |
jpcerrone | 2ba192e803 | |
MewPurPur | 8cefce591a | |
MewPurPur | ab14aa9f16 | |
Aaron Franke | 4cec4bd32f | |
kobewi | ffc87b2bb1 | |
Bauke Conijn | 3fd5fecfc1 | |
bruvzg | 221535c33c | |
Markus Sauermann | 4e84660b50 | |
RedworkDE | 69948f7489 | |
mb4c | 6018ff49d6 | |
Alfonso J. Ramos | 8cea540eba | |
Silc Lizard (Tokage) Renew | ed9c091a92 | |
bitsawer | f5addd583d | |
bitsawer | 0dec3d6485 | |
ocean (they/them) | a0366f1cea | |
kobewi | 705c1d6bdf | |
Rindbee | 836913ce7a | |
Raul Santos | 80105226c2 | |
nklbdev | 2bfeb29bc6 | |
nklbdev | 92040e85e2 | |
Haoyu Qiu | 545e37cf77 | |
Haoyu Qiu | a8bfdd8bea | |
Ben Rog-Wilhelm | 371b31c85f | |
Amir-Rasteg | 7a8ac69862 | |
RedworkDE | 03e82be503 | |
Bastiaan Olij | 89e64da028 | |
Rémi Verschelde | da1e511f11 | |
Yuri Roubinski | 6255a64e03 | |
clayjohn | bc9bc236c0 | |
Markus Sauermann | 0ec599473d | |
Daylily-Zeleen | 71d5827228 | |
RedworkDE | ce5c6151fc | |
Rémi Verschelde | 529a55bab2 |
|
@ -15,3 +15,39 @@
|
||||||
|
|
||||||
# Style: clang-format: Disable AllowShortIfStatementsOnASingleLine
|
# Style: clang-format: Disable AllowShortIfStatementsOnASingleLine
|
||||||
e956e80c1fa1cc8aefcb1533e5acf5cf3c8ffdd9
|
e956e80c1fa1cc8aefcb1533e5acf5cf3c8ffdd9
|
||||||
|
|
||||||
|
# One Copyright Update to rule them all
|
||||||
|
d95794ec8a7c362b06a9cf080e2554ef77adb667
|
||||||
|
|
||||||
|
# Update copyright statements to 2022
|
||||||
|
fe52458154c64fb1b741df4f7bd10106395f7cbd
|
||||||
|
|
||||||
|
# Update copyright statements to 2021
|
||||||
|
b5334d14f7a471f94bcbd64d5bae2ad853d0b7f1
|
||||||
|
|
||||||
|
# Update copyright statements to 2020
|
||||||
|
a7f49ac9a107820a62677ee3fb49d38982a25165
|
||||||
|
|
||||||
|
# Update copyright statements to 2019
|
||||||
|
b16c309f82c77d606472c3c721a1857e323a09e7
|
||||||
|
|
||||||
|
# Update copyright statements to 2018
|
||||||
|
b50a9114b105dafafdda8248a38653bca314a6f3
|
||||||
|
|
||||||
|
# Welcome in 2017, dear changelog reader!
|
||||||
|
c7bc44d5ad9aae4902280012f7654e2318cd910e
|
||||||
|
|
||||||
|
# Update copyright to 2016 in headers
|
||||||
|
5be9ff7b6715a661e85f99b108f96340de7ef435
|
||||||
|
|
||||||
|
# Updated copyright year in all headers
|
||||||
|
fdaa2920eb21fff3320a17e9239e04dfadecdb00
|
||||||
|
|
||||||
|
# Add missing copyright headers and fix formatting
|
||||||
|
e4213e66b2dd8f5a87d8cf5015ac83ba3143279d
|
||||||
|
|
||||||
|
# Use HTTPS URL for Godot's website in the headers
|
||||||
|
bd282ff43f23fe845f29a3e25c8efc01bd65ffb0
|
||||||
|
|
||||||
|
# Add "Godot Engine contributors" copyright line
|
||||||
|
df61dc4b2bd54a5a40c515493c76f5a458e5b541
|
||||||
|
|
|
@ -139,10 +139,9 @@ doc_classes/* @godotengine/documentation
|
||||||
|
|
||||||
/platform/android/ @godotengine/android
|
/platform/android/ @godotengine/android
|
||||||
/platform/ios/ @godotengine/ios
|
/platform/ios/ @godotengine/ios
|
||||||
/platform/javascript/ @godotengine/html5
|
|
||||||
/platform/linuxbsd/ @godotengine/linux-bsd
|
/platform/linuxbsd/ @godotengine/linux-bsd
|
||||||
/platform/macos/ @godotengine/macos
|
/platform/macos/ @godotengine/macos
|
||||||
/platform/uwp/ @godotengine/uwp
|
/platform/web/ @godotengine/web
|
||||||
/platform/windows/ @godotengine/windows
|
/platform/windows/ @godotengine/windows
|
||||||
|
|
||||||
# Scene
|
# Scene
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
name: Download Godot artifact
|
||||||
|
description: Download the Godot artifact.
|
||||||
|
inputs:
|
||||||
|
name:
|
||||||
|
description: The artifact name.
|
||||||
|
default: "${{ github.job }}"
|
||||||
|
path:
|
||||||
|
description: The path to download and extract to.
|
||||||
|
required: true
|
||||||
|
default: "./"
|
||||||
|
runs:
|
||||||
|
using: "composite"
|
||||||
|
steps:
|
||||||
|
- name: Download Godot Artifact
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
name: ${{ inputs.name }}
|
||||||
|
path: ${{ inputs.path }}
|
|
@ -0,0 +1,24 @@
|
||||||
|
name: Dump Godot API
|
||||||
|
description: Dump Godot API for GDExtension
|
||||||
|
inputs:
|
||||||
|
bin:
|
||||||
|
description: The path to the Godot executable
|
||||||
|
required: true
|
||||||
|
runs:
|
||||||
|
using: "composite"
|
||||||
|
steps:
|
||||||
|
# Dump GDExtension interface and API
|
||||||
|
- name: Dump GDExtension interface and API for godot-cpp build
|
||||||
|
shell: sh
|
||||||
|
run: |
|
||||||
|
${{ inputs.bin }} --headless --dump-gdextension-interface --dump-extension-api
|
||||||
|
mkdir godot-api
|
||||||
|
cp -f gdextension_interface.h godot-api/
|
||||||
|
cp -f extension_api.json godot-api/
|
||||||
|
|
||||||
|
- name: Upload API dump
|
||||||
|
uses: ./.github/actions/upload-artifact
|
||||||
|
with:
|
||||||
|
name: 'godot-api-dump'
|
||||||
|
path: './godot-api/*'
|
||||||
|
|
|
@ -12,11 +12,24 @@ runs:
|
||||||
steps:
|
steps:
|
||||||
# Upload cache on completion and check it out now
|
# Upload cache on completion and check it out now
|
||||||
- name: Load .scons_cache directory
|
- name: Load .scons_cache directory
|
||||||
uses: actions/cache@v3
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: ${{inputs.scons-cache}}
|
path: ${{inputs.scons-cache}}
|
||||||
key: ${{inputs.cache-name}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
|
key: ${{inputs.cache-name}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
|
||||||
|
|
||||||
|
# We try to match an existing cache to restore from it. Each potential key is checked against
|
||||||
|
# all existing caches as a prefix. E.g. 'linux-template-minimal' would match any cache that
|
||||||
|
# starts with "linux-template-minimal", such as "linux-template-minimal-master-refs/heads/master-6588a4a29af1621086feac0117d5d4d37af957fd".
|
||||||
|
#
|
||||||
|
# We check these prefixes in this order:
|
||||||
|
#
|
||||||
|
# 1. The exact match, including the base branch, the commit reference, and the SHA hash of the commit.
|
||||||
|
# 2. A partial match for the same base branch and the same commit reference.
|
||||||
|
# 3. A partial match for the same base branch and the base branch commit reference.
|
||||||
|
# 4. A partial match for the same base branch only (not ideal, matches any PR with the same base branch).
|
||||||
|
|
||||||
restore-keys: |
|
restore-keys: |
|
||||||
${{inputs.cache-name}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
|
${{inputs.cache-name}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
|
||||||
${{inputs.cache-name}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}
|
${{inputs.cache-name}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}
|
||||||
|
${{inputs.cache-name}}-${{env.GODOT_BASE_BRANCH}}-refs/heads/${{env.GODOT_BASE_BRANCH}}
|
||||||
${{inputs.cache-name}}-${{env.GODOT_BASE_BRANCH}}
|
${{inputs.cache-name}}-${{env.GODOT_BASE_BRANCH}}
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
name: Test Godot project converter
|
||||||
|
description: Test the Godot project converter.
|
||||||
|
inputs:
|
||||||
|
bin:
|
||||||
|
description: The path to the Godot executable
|
||||||
|
required: true
|
||||||
|
runs:
|
||||||
|
using: "composite"
|
||||||
|
steps:
|
||||||
|
- name: Test 3-to-4 conversion
|
||||||
|
shell: sh
|
||||||
|
run: |
|
||||||
|
mkdir converter_test
|
||||||
|
cd converter_test
|
||||||
|
touch project.godot
|
||||||
|
../${{ inputs.bin }} --headless --validate-conversion-3to4
|
||||||
|
cd ..
|
||||||
|
rm converter_test -rf
|
|
@ -12,7 +12,7 @@ runs:
|
||||||
steps:
|
steps:
|
||||||
# Use python 3.x release (works cross platform)
|
# Use python 3.x release (works cross platform)
|
||||||
- name: Set up Python 3.x
|
- name: Set up Python 3.x
|
||||||
uses: actions/setup-python@v4
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
# Semantic version range syntax or exact version of a Python version
|
# Semantic version range syntax or exact version of a Python version
|
||||||
python-version: ${{ inputs.python-version }}
|
python-version: ${{ inputs.python-version }}
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
name: Test Godot project
|
||||||
|
description: Run the test Godot project.
|
||||||
|
inputs:
|
||||||
|
bin:
|
||||||
|
description: The path to the Godot executable
|
||||||
|
required: true
|
||||||
|
runs:
|
||||||
|
using: "composite"
|
||||||
|
steps:
|
||||||
|
# Download and extract zip archive with project, folder is renamed to be able to easy change used project
|
||||||
|
- name: Download test project
|
||||||
|
shell: sh
|
||||||
|
run: |
|
||||||
|
wget https://github.com/godotengine/regression-test-project/archive/4.0.zip
|
||||||
|
unzip 4.0.zip
|
||||||
|
mv "regression-test-project-4.0" "test_project"
|
||||||
|
|
||||||
|
# Editor is quite complicated piece of software, so it is easy to introduce bug here.
|
||||||
|
|
||||||
|
- name: Open and close editor (Vulkan)
|
||||||
|
shell: sh
|
||||||
|
run: |
|
||||||
|
xvfb-run ${{ inputs.bin }} --audio-driver Dummy --editor --quit --path test_project 2>&1 | tee sanitizers_log.txt || true
|
||||||
|
misc/scripts/check_ci_log.py sanitizers_log.txt
|
||||||
|
|
||||||
|
- name: Open and close editor (GLES3)
|
||||||
|
shell: sh
|
||||||
|
run: |
|
||||||
|
DRI_PRIME=0 xvfb-run ${{ inputs.bin }} --audio-driver Dummy --rendering-driver opengl3 --editor --quit --path test_project 2>&1 | tee sanitizers_log.txt || true
|
||||||
|
misc/scripts/check_ci_log.py sanitizers_log.txt
|
||||||
|
|
||||||
|
# Run test project
|
||||||
|
- name: Run project
|
||||||
|
shell: sh
|
||||||
|
run: |
|
||||||
|
xvfb-run ${{ inputs.bin }} 40 --audio-driver Dummy --path test_project 2>&1 | tee sanitizers_log.txt || true
|
||||||
|
misc/scripts/check_ci_log.py sanitizers_log.txt
|
|
@ -12,7 +12,7 @@ runs:
|
||||||
using: "composite"
|
using: "composite"
|
||||||
steps:
|
steps:
|
||||||
- name: Upload Godot Artifact
|
- name: Upload Godot Artifact
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: ${{ inputs.name }}
|
name: ${{ inputs.name }}
|
||||||
path: ${{ inputs.path }}
|
path: ${{ inputs.path }}
|
||||||
|
|
|
@ -5,7 +5,7 @@ on:
|
||||||
# Global Settings
|
# Global Settings
|
||||||
env:
|
env:
|
||||||
# Used for the cache key. Add version suffix to force clean build.
|
# Used for the cache key. Add version suffix to force clean build.
|
||||||
GODOT_BASE_BRANCH: master
|
GODOT_BASE_BRANCH: '4.1'
|
||||||
SCONSFLAGS: verbose=yes warnings=extra werror=yes debug_symbols=no module_text_server_fb_enabled=yes
|
SCONSFLAGS: verbose=yes warnings=extra werror=yes debug_symbols=no module_text_server_fb_enabled=yes
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
|
@ -18,10 +18,10 @@ jobs:
|
||||||
name: Template (target=template_release)
|
name: Template (target=template_release)
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Set up Java 11
|
- name: Set up Java 11
|
||||||
uses: actions/setup-java@v3
|
uses: actions/setup-java@v4
|
||||||
with:
|
with:
|
||||||
distribution: temurin
|
distribution: temurin
|
||||||
java-version: 11
|
java-version: 11
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
name: 🪲 Godot CPP
|
||||||
|
on:
|
||||||
|
workflow_call:
|
||||||
|
|
||||||
|
# Global Settings
|
||||||
|
env:
|
||||||
|
# Used for the cache key, and godot-cpp checkout. Add version suffix to force clean build.
|
||||||
|
GODOT_BASE_BRANCH: '4.1'
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: ci-${{github.actor}}-${{github.head_ref || github.run_number}}-${{github.ref}}-cpp-tests
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
godot-cpp-tests:
|
||||||
|
runs-on: "ubuntu-20.04"
|
||||||
|
name: "Build and test Godot CPP"
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup python and scons
|
||||||
|
uses: ./.github/actions/godot-deps
|
||||||
|
|
||||||
|
# Checkout godot-cpp
|
||||||
|
- name: Checkout godot-cpp
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
repository: godotengine/godot-cpp
|
||||||
|
ref: ${{ env.GODOT_BASE_BRANCH }}
|
||||||
|
submodules: 'recursive'
|
||||||
|
path: 'godot-cpp'
|
||||||
|
|
||||||
|
# Download generated API dump
|
||||||
|
- name: Download GDExtension interface and API dump
|
||||||
|
uses: ./.github/actions/download-artifact
|
||||||
|
with:
|
||||||
|
name: 'godot-api-dump'
|
||||||
|
path: './godot-api'
|
||||||
|
|
||||||
|
# Extract and override existing files with generated files
|
||||||
|
- name: Extract GDExtension interface and API dump
|
||||||
|
run: |
|
||||||
|
cp -f godot-api/gdextension_interface.h godot-cpp/gdextension/
|
||||||
|
cp -f godot-api/extension_api.json godot-cpp/gdextension/
|
||||||
|
|
||||||
|
# TODO: Add caching to the scons build and store it for CI via the godot-cache
|
||||||
|
# action.
|
||||||
|
|
||||||
|
# Build godot-cpp test extension
|
||||||
|
- name: Build godot-cpp test extension
|
||||||
|
run: |
|
||||||
|
cd godot-cpp/test
|
||||||
|
scons target=template_debug dev_build=yes
|
||||||
|
cd ../..
|
|
@ -5,7 +5,7 @@ on:
|
||||||
# Global Settings
|
# Global Settings
|
||||||
env:
|
env:
|
||||||
# Used for the cache key. Add version suffix to force clean build.
|
# Used for the cache key. Add version suffix to force clean build.
|
||||||
GODOT_BASE_BRANCH: master
|
GODOT_BASE_BRANCH: '4.1'
|
||||||
SCONSFLAGS: verbose=yes warnings=extra werror=yes debug_symbols=no module_text_server_fb_enabled=yes
|
SCONSFLAGS: verbose=yes warnings=extra werror=yes debug_symbols=no module_text_server_fb_enabled=yes
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
|
@ -18,7 +18,7 @@ jobs:
|
||||||
name: Template (target=template_release)
|
name: Template (target=template_release)
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Setup Godot build cache
|
- name: Setup Godot build cache
|
||||||
uses: ./.github/actions/godot-cache
|
uses: ./.github/actions/godot-cache
|
||||||
|
|
|
@ -4,8 +4,8 @@ on:
|
||||||
|
|
||||||
# Global Settings
|
# Global Settings
|
||||||
env:
|
env:
|
||||||
# Used for the cache key, and godot-cpp checkout. Add version suffix to force clean build.
|
# Used for the cache key. Add version suffix to force clean build.
|
||||||
GODOT_BASE_BRANCH: master
|
GODOT_BASE_BRANCH: '4.1'
|
||||||
SCONSFLAGS: verbose=yes warnings=extra werror=yes module_text_server_fb_enabled=yes
|
SCONSFLAGS: verbose=yes warnings=extra werror=yes module_text_server_fb_enabled=yes
|
||||||
DOTNET_NOLOGO: true
|
DOTNET_NOLOGO: true
|
||||||
DOTNET_CLI_TELEMETRY_OPTOUT: true
|
DOTNET_CLI_TELEMETRY_OPTOUT: true
|
||||||
|
@ -25,57 +25,56 @@ jobs:
|
||||||
- name: Editor w/ Mono (target=editor)
|
- name: Editor w/ Mono (target=editor)
|
||||||
cache-name: linux-editor-mono
|
cache-name: linux-editor-mono
|
||||||
target: editor
|
target: editor
|
||||||
tests: false # Disabled due freeze caused by mix Mono build and CI
|
|
||||||
sconsflags: module_mono_enabled=yes
|
sconsflags: module_mono_enabled=yes
|
||||||
doc-test: true
|
|
||||||
bin: "./bin/godot.linuxbsd.editor.x86_64.mono"
|
bin: "./bin/godot.linuxbsd.editor.x86_64.mono"
|
||||||
build-mono: true
|
build-mono: true
|
||||||
|
tests: false # Disabled due freeze caused by mix Mono build and CI
|
||||||
|
doc-test: true
|
||||||
proj-conv: true
|
proj-conv: true
|
||||||
|
api-compat: true
|
||||||
artifact: true
|
artifact: true
|
||||||
compat: true
|
|
||||||
|
|
||||||
- name: Editor with doubles and GCC sanitizers (target=editor, tests=yes, dev_build=yes, scu_build=yes, precision=double, use_asan=yes, use_ubsan=yes, linker=gold)
|
- name: Editor with doubles and GCC sanitizers (target=editor, tests=yes, dev_build=yes, scu_build=yes, precision=double, use_asan=yes, use_ubsan=yes, linker=gold)
|
||||||
cache-name: linux-editor-double-sanitizers
|
cache-name: linux-editor-double-sanitizers
|
||||||
target: editor
|
target: editor
|
||||||
tests: true
|
|
||||||
# Debug symbols disabled as they're huge on this build and we hit the 14 GB limit for runners.
|
# Debug symbols disabled as they're huge on this build and we hit the 14 GB limit for runners.
|
||||||
sconsflags: dev_build=yes scu_build=yes debug_symbols=no precision=double use_asan=yes use_ubsan=yes linker=gold
|
sconsflags: dev_build=yes scu_build=yes debug_symbols=no precision=double use_asan=yes use_ubsan=yes linker=gold
|
||||||
proj-test: true
|
|
||||||
# Can be turned off for PRs that intentionally break compat with godot-cpp,
|
|
||||||
# until both the upstream PR and the matching godot-cpp changes are merged.
|
|
||||||
godot-cpp-test: true
|
|
||||||
bin: "./bin/godot.linuxbsd.editor.dev.double.x86_64.san"
|
bin: "./bin/godot.linuxbsd.editor.dev.double.x86_64.san"
|
||||||
build-mono: false
|
build-mono: false
|
||||||
|
tests: true
|
||||||
|
proj-test: true
|
||||||
|
# Generate an API dump for godot-cpp tests.
|
||||||
|
api-dump: true
|
||||||
# Skip 2GiB artifact speeding up action.
|
# Skip 2GiB artifact speeding up action.
|
||||||
artifact: false
|
artifact: false
|
||||||
|
|
||||||
- name: Editor with clang sanitizers (target=editor, tests=yes, dev_build=yes, use_asan=yes, use_ubsan=yes, use_llvm=yes, linker=lld)
|
- name: Editor with clang sanitizers (target=editor, tests=yes, dev_build=yes, use_asan=yes, use_ubsan=yes, use_llvm=yes, linker=lld)
|
||||||
cache-name: linux-editor-llvm-sanitizers
|
cache-name: linux-editor-llvm-sanitizers
|
||||||
target: editor
|
target: editor
|
||||||
tests: true
|
|
||||||
sconsflags: dev_build=yes use_asan=yes use_ubsan=yes use_llvm=yes linker=lld
|
sconsflags: dev_build=yes use_asan=yes use_ubsan=yes use_llvm=yes linker=lld
|
||||||
bin: "./bin/godot.linuxbsd.editor.dev.x86_64.llvm.san"
|
bin: "./bin/godot.linuxbsd.editor.dev.x86_64.llvm.san"
|
||||||
build-mono: false
|
build-mono: false
|
||||||
|
tests: true
|
||||||
# Skip 2GiB artifact speeding up action.
|
# Skip 2GiB artifact speeding up action.
|
||||||
artifact: false
|
artifact: false
|
||||||
|
|
||||||
- name: Template w/ Mono (target=template_release)
|
- name: Template w/ Mono (target=template_release)
|
||||||
cache-name: linux-template-mono
|
cache-name: linux-template-mono
|
||||||
target: template_release
|
target: template_release
|
||||||
tests: false
|
|
||||||
sconsflags: module_mono_enabled=yes
|
sconsflags: module_mono_enabled=yes
|
||||||
build-mono: false
|
build-mono: false
|
||||||
|
tests: false
|
||||||
artifact: true
|
artifact: true
|
||||||
|
|
||||||
- name: Minimal template (target=template_release, everything disabled)
|
- name: Minimal template (target=template_release, everything disabled)
|
||||||
cache-name: linux-template-minimal
|
cache-name: linux-template-minimal
|
||||||
target: template_release
|
target: template_release
|
||||||
tests: false
|
|
||||||
sconsflags: modules_enabled_by_default=no disable_3d=yes disable_advanced_gui=yes deprecated=no minizip=no
|
sconsflags: modules_enabled_by_default=no disable_3d=yes disable_advanced_gui=yes deprecated=no minizip=no
|
||||||
|
tests: false
|
||||||
artifact: true
|
artifact: true
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
# Need newer mesa for lavapipe to work properly.
|
# Need newer mesa for lavapipe to work properly.
|
||||||
- name: Linux dependencies for tests
|
- name: Linux dependencies for tests
|
||||||
|
@ -85,6 +84,12 @@ jobs:
|
||||||
sudo add-apt-repository ppa:kisak/kisak-mesa
|
sudo add-apt-repository ppa:kisak/kisak-mesa
|
||||||
sudo apt-get install -qq mesa-vulkan-drivers
|
sudo apt-get install -qq mesa-vulkan-drivers
|
||||||
|
|
||||||
|
- name: Free disk space on runner
|
||||||
|
run: |
|
||||||
|
echo "Disk usage before:" && df -h
|
||||||
|
sudo rm -rf /usr/local/lib/android
|
||||||
|
echo "Disk usage after:" && df -h
|
||||||
|
|
||||||
- name: Setup Godot build cache
|
- name: Setup Godot build cache
|
||||||
uses: ./.github/actions/godot-cache
|
uses: ./.github/actions/godot-cache
|
||||||
with:
|
with:
|
||||||
|
@ -95,7 +100,7 @@ jobs:
|
||||||
uses: ./.github/actions/godot-deps
|
uses: ./.github/actions/godot-deps
|
||||||
|
|
||||||
- name: Set up .NET Sdk
|
- name: Set up .NET Sdk
|
||||||
uses: actions/setup-dotnet@v2
|
uses: actions/setup-dotnet@v3
|
||||||
if: ${{ matrix.build-mono }}
|
if: ${{ matrix.build-mono }}
|
||||||
with:
|
with:
|
||||||
dotnet-version: '6.0.x'
|
dotnet-version: '6.0.x'
|
||||||
|
@ -114,100 +119,13 @@ jobs:
|
||||||
- name: Generate C# glue
|
- name: Generate C# glue
|
||||||
if: ${{ matrix.build-mono }}
|
if: ${{ matrix.build-mono }}
|
||||||
run: |
|
run: |
|
||||||
${{ matrix.bin }} --headless --generate-mono-glue ./modules/mono/glue || true
|
${{ matrix.bin }} --headless --generate-mono-glue ./modules/mono/glue
|
||||||
|
|
||||||
- name: Build .NET solutions
|
- name: Build .NET solutions
|
||||||
if: ${{ matrix.build-mono }}
|
if: ${{ matrix.build-mono }}
|
||||||
run: |
|
run: |
|
||||||
./modules/mono/build_scripts/build_assemblies.py --godot-output-dir=./bin --godot-platform=linuxbsd
|
./modules/mono/build_scripts/build_assemblies.py --godot-output-dir=./bin --godot-platform=linuxbsd
|
||||||
|
|
||||||
# Execute unit tests for the editor
|
|
||||||
- name: Unit tests
|
|
||||||
if: ${{ matrix.tests }}
|
|
||||||
run: |
|
|
||||||
${{ matrix.bin }} --version
|
|
||||||
${{ matrix.bin }} --help
|
|
||||||
${{ matrix.bin }} --test --headless
|
|
||||||
|
|
||||||
# Check class reference
|
|
||||||
- name: Check for class reference updates
|
|
||||||
if: ${{ matrix.doc-test }}
|
|
||||||
run: |
|
|
||||||
echo "Running --doctool to see if this changes the public API without updating the documentation."
|
|
||||||
echo -e "If a diff is shown, it means that your code/doc changes are incomplete and you should update the class reference with --doctool.\n\n"
|
|
||||||
${{ matrix.bin }} --doctool --headless 2>&1 > /dev/null || true
|
|
||||||
git diff --color --exit-code && ! git ls-files --others --exclude-standard | sed -e 's/^/New doc file missing in PR: /' | grep 'xml$'
|
|
||||||
|
|
||||||
# Test 3.x -> 4.x project converter
|
|
||||||
- name: Test project converter
|
|
||||||
if: ${{ matrix.proj-conv }}
|
|
||||||
run: |
|
|
||||||
mkdir converter_test
|
|
||||||
cd converter_test
|
|
||||||
touch project.godot
|
|
||||||
../${{ matrix.bin }} --headless --validate-conversion-3to4
|
|
||||||
cd ..
|
|
||||||
rm converter_test -rf
|
|
||||||
|
|
||||||
# Download and extract zip archive with project, folder is renamed to be able to easy change used project
|
|
||||||
- name: Download test project
|
|
||||||
if: ${{ matrix.proj-test }}
|
|
||||||
run: |
|
|
||||||
wget https://github.com/godotengine/regression-test-project/archive/4.0.zip
|
|
||||||
unzip 4.0.zip
|
|
||||||
mv "regression-test-project-4.0" "test_project"
|
|
||||||
|
|
||||||
# Editor is quite complicated piece of software, so it is easy to introduce bug here
|
|
||||||
- name: Open and close editor (Vulkan)
|
|
||||||
if: ${{ matrix.proj-test }}
|
|
||||||
run: |
|
|
||||||
xvfb-run ${{ matrix.bin }} --audio-driver Dummy --editor --quit --path test_project 2>&1 | tee sanitizers_log.txt || true
|
|
||||||
misc/scripts/check_ci_log.py sanitizers_log.txt
|
|
||||||
|
|
||||||
- name: Open and close editor (GLES3)
|
|
||||||
if: ${{ matrix.proj-test }}
|
|
||||||
run: |
|
|
||||||
DRI_PRIME=0 xvfb-run ${{ matrix.bin }} --audio-driver Dummy --rendering-driver opengl3 --editor --quit --path test_project 2>&1 | tee sanitizers_log.txt || true
|
|
||||||
misc/scripts/check_ci_log.py sanitizers_log.txt
|
|
||||||
|
|
||||||
# Run test project
|
|
||||||
- name: Run project
|
|
||||||
if: ${{ matrix.proj-test }}
|
|
||||||
run: |
|
|
||||||
xvfb-run ${{ matrix.bin }} 40 --audio-driver Dummy --path test_project 2>&1 | tee sanitizers_log.txt || true
|
|
||||||
misc/scripts/check_ci_log.py sanitizers_log.txt
|
|
||||||
|
|
||||||
# Checkout godot-cpp
|
|
||||||
- name: Checkout godot-cpp
|
|
||||||
if: ${{ matrix.godot-cpp-test }}
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
with:
|
|
||||||
repository: godotengine/godot-cpp
|
|
||||||
ref: ${{ env.GODOT_BASE_BRANCH }}
|
|
||||||
submodules: 'recursive'
|
|
||||||
path: 'godot-cpp'
|
|
||||||
|
|
||||||
# Dump GDExtension interface and API
|
|
||||||
- name: Dump GDExtension interface and API for godot-cpp build
|
|
||||||
if: ${{ matrix.godot-cpp-test }}
|
|
||||||
run: |
|
|
||||||
${{ matrix.bin }} --headless --dump-gdextension-interface --dump-extension-api
|
|
||||||
cp -f gdextension_interface.h godot-cpp/gdextension/
|
|
||||||
cp -f extension_api.json godot-cpp/gdextension/
|
|
||||||
|
|
||||||
# Build godot-cpp test extension
|
|
||||||
- name: Build godot-cpp test extension
|
|
||||||
if: ${{ matrix.godot-cpp-test }}
|
|
||||||
run: |
|
|
||||||
cd godot-cpp/test
|
|
||||||
scons target=template_debug dev_build=yes
|
|
||||||
cd ../..
|
|
||||||
|
|
||||||
- name: Check for GDExtension compatibility
|
|
||||||
if: ${{ matrix.compat }}
|
|
||||||
run: |
|
|
||||||
./misc/scripts/validate_extension_api.sh "${{ matrix.bin }}" || true # don't fail the CI for now
|
|
||||||
|
|
||||||
- name: Prepare artifact
|
- name: Prepare artifact
|
||||||
if: ${{ matrix.artifact }}
|
if: ${{ matrix.artifact }}
|
||||||
run: |
|
run: |
|
||||||
|
@ -219,3 +137,46 @@ jobs:
|
||||||
if: ${{ matrix.artifact }}
|
if: ${{ matrix.artifact }}
|
||||||
with:
|
with:
|
||||||
name: ${{ matrix.cache-name }}
|
name: ${{ matrix.cache-name }}
|
||||||
|
|
||||||
|
- name: Dump Godot API
|
||||||
|
uses: ./.github/actions/godot-api-dump
|
||||||
|
if: ${{ matrix.api-dump }}
|
||||||
|
with:
|
||||||
|
bin: ${{ matrix.bin }}
|
||||||
|
|
||||||
|
# Execute unit tests for the editor
|
||||||
|
- name: Unit tests
|
||||||
|
if: ${{ matrix.tests }}
|
||||||
|
run: |
|
||||||
|
${{ matrix.bin }} --version
|
||||||
|
${{ matrix.bin }} --help
|
||||||
|
${{ matrix.bin }} --headless --test --force-colors
|
||||||
|
|
||||||
|
# Check class reference
|
||||||
|
- name: Check for class reference updates
|
||||||
|
if: ${{ matrix.doc-test }}
|
||||||
|
run: |
|
||||||
|
echo "Running --doctool to see if this changes the public API without updating the documentation."
|
||||||
|
echo -e "If a diff is shown, it means that your code/doc changes are incomplete and you should update the class reference with --doctool.\n\n"
|
||||||
|
${{ matrix.bin }} --doctool --headless 2>&1 > /dev/null || true
|
||||||
|
git diff --color --exit-code && ! git ls-files --others --exclude-standard | sed -e 's/^/New doc file missing in PR: /' | grep 'xml$'
|
||||||
|
|
||||||
|
# Check API backwards compatibility
|
||||||
|
- name: Check for GDExtension compatibility
|
||||||
|
if: ${{ matrix.api-compat }}
|
||||||
|
run: |
|
||||||
|
./misc/scripts/validate_extension_api.sh "${{ matrix.bin }}"
|
||||||
|
|
||||||
|
# Download and run the test project
|
||||||
|
- name: Test Godot project
|
||||||
|
uses: ./.github/actions/godot-project-test
|
||||||
|
if: ${{ matrix.proj-test }}
|
||||||
|
with:
|
||||||
|
bin: ${{ matrix.bin }}
|
||||||
|
|
||||||
|
# Test the project converter
|
||||||
|
- name: Test project converter
|
||||||
|
uses: ./.github/actions/godot-converter-test
|
||||||
|
if: ${{ matrix.proj-conv }}
|
||||||
|
with:
|
||||||
|
bin: ${{ matrix.bin }}
|
||||||
|
|
|
@ -5,7 +5,7 @@ on:
|
||||||
# Global Settings
|
# Global Settings
|
||||||
env:
|
env:
|
||||||
# Used for the cache key. Add version suffix to force clean build.
|
# Used for the cache key. Add version suffix to force clean build.
|
||||||
GODOT_BASE_BRANCH: master
|
GODOT_BASE_BRANCH: '4.1'
|
||||||
SCONSFLAGS: verbose=yes warnings=extra werror=yes module_text_server_fb_enabled=yes
|
SCONSFLAGS: verbose=yes warnings=extra werror=yes module_text_server_fb_enabled=yes
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
|
@ -24,7 +24,7 @@ jobs:
|
||||||
cache-name: macos-editor
|
cache-name: macos-editor
|
||||||
target: editor
|
target: editor
|
||||||
tests: true
|
tests: true
|
||||||
bin: "./bin/godot.macos.editor.x86_64"
|
bin: "./bin/godot.macos.editor.universal"
|
||||||
|
|
||||||
- name: Template (target=template_release)
|
- name: Template (target=template_release)
|
||||||
cache-name: macos-template
|
cache-name: macos-template
|
||||||
|
@ -33,7 +33,7 @@ jobs:
|
||||||
sconsflags: debug_symbols=no
|
sconsflags: debug_symbols=no
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Setup Godot build cache
|
- name: Setup Godot build cache
|
||||||
uses: ./.github/actions/godot-cache
|
uses: ./.github/actions/godot-cache
|
||||||
|
@ -48,24 +48,26 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
sh misc/scripts/install_vulkan_sdk_macos.sh
|
sh misc/scripts/install_vulkan_sdk_macos.sh
|
||||||
|
|
||||||
- name: Compilation
|
- name: Compilation (x86_64)
|
||||||
uses: ./.github/actions/godot-build
|
uses: ./.github/actions/godot-build
|
||||||
with:
|
with:
|
||||||
sconsflags: ${{ env.SCONSFLAGS }}
|
sconsflags: ${{ env.SCONSFLAGS }} arch=x86_64
|
||||||
platform: macos
|
platform: macos
|
||||||
target: ${{ matrix.target }}
|
target: ${{ matrix.target }}
|
||||||
tests: ${{ matrix.tests }}
|
tests: ${{ matrix.tests }}
|
||||||
|
|
||||||
# Execute unit tests for the editor
|
- name: Compilation (arm64)
|
||||||
- name: Unit tests
|
uses: ./.github/actions/godot-build
|
||||||
if: ${{ matrix.tests }}
|
with:
|
||||||
run: |
|
sconsflags: ${{ env.SCONSFLAGS }} arch=arm64
|
||||||
${{ matrix.bin }} --version
|
platform: macos
|
||||||
${{ matrix.bin }} --help
|
target: ${{ matrix.target }}
|
||||||
${{ matrix.bin }} --test
|
tests: ${{ matrix.tests }}
|
||||||
|
|
||||||
- name: Prepare artifact
|
- name: Prepare artifact
|
||||||
run: |
|
run: |
|
||||||
|
lipo -create ./bin/godot.macos.${{ matrix.target }}.x86_64 ./bin/godot.macos.${{ matrix.target }}.arm64 -output ./bin/godot.macos.${{ matrix.target }}.universal
|
||||||
|
rm ./bin/godot.macos.${{ matrix.target }}.x86_64 ./bin/godot.macos.${{ matrix.target }}.arm64
|
||||||
strip bin/godot.*
|
strip bin/godot.*
|
||||||
chmod +x bin/godot.*
|
chmod +x bin/godot.*
|
||||||
|
|
||||||
|
@ -73,3 +75,11 @@ jobs:
|
||||||
uses: ./.github/actions/upload-artifact
|
uses: ./.github/actions/upload-artifact
|
||||||
with:
|
with:
|
||||||
name: ${{ matrix.cache-name }}
|
name: ${{ matrix.cache-name }}
|
||||||
|
|
||||||
|
# Execute unit tests for the editor
|
||||||
|
- name: Unit tests
|
||||||
|
if: ${{ matrix.tests }}
|
||||||
|
run: |
|
||||||
|
${{ matrix.bin }} --version
|
||||||
|
${{ matrix.bin }} --help
|
||||||
|
${{ matrix.bin }} --test --force-colors
|
||||||
|
|
|
@ -6,36 +6,60 @@ concurrency:
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
# First stage: Only static checks, fast and prevent expensive builds from running.
|
||||||
|
|
||||||
static-checks:
|
static-checks:
|
||||||
|
if: ${{ vars.DISABLE_GODOT_CI == '' }}
|
||||||
name: 📊 Static checks
|
name: 📊 Static checks
|
||||||
uses: ./.github/workflows/static_checks.yml
|
uses: ./.github/workflows/static_checks.yml
|
||||||
|
|
||||||
|
# Second stage: Run all the builds and some of the tests.
|
||||||
|
|
||||||
android-build:
|
android-build:
|
||||||
|
if: ${{ vars.DISABLE_GODOT_CI == '' }}
|
||||||
name: 🤖 Android
|
name: 🤖 Android
|
||||||
needs: static-checks
|
needs: static-checks
|
||||||
uses: ./.github/workflows/android_builds.yml
|
uses: ./.github/workflows/android_builds.yml
|
||||||
|
|
||||||
ios-build:
|
ios-build:
|
||||||
|
if: ${{ vars.DISABLE_GODOT_CI == '' }}
|
||||||
name: 🍏 iOS
|
name: 🍏 iOS
|
||||||
needs: static-checks
|
needs: static-checks
|
||||||
uses: ./.github/workflows/ios_builds.yml
|
uses: ./.github/workflows/ios_builds.yml
|
||||||
|
|
||||||
linux-build:
|
linux-build:
|
||||||
|
if: ${{ vars.DISABLE_GODOT_CI == '' }}
|
||||||
name: 🐧 Linux
|
name: 🐧 Linux
|
||||||
needs: static-checks
|
needs: static-checks
|
||||||
uses: ./.github/workflows/linux_builds.yml
|
uses: ./.github/workflows/linux_builds.yml
|
||||||
|
|
||||||
macos-build:
|
macos-build:
|
||||||
|
if: ${{ vars.DISABLE_GODOT_CI == '' }}
|
||||||
name: 🍎 macOS
|
name: 🍎 macOS
|
||||||
needs: static-checks
|
needs: static-checks
|
||||||
uses: ./.github/workflows/macos_builds.yml
|
uses: ./.github/workflows/macos_builds.yml
|
||||||
|
|
||||||
windows-build:
|
windows-build:
|
||||||
|
if: ${{ vars.DISABLE_GODOT_CI == '' }}
|
||||||
name: 🏁 Windows
|
name: 🏁 Windows
|
||||||
needs: static-checks
|
needs: static-checks
|
||||||
uses: ./.github/workflows/windows_builds.yml
|
uses: ./.github/workflows/windows_builds.yml
|
||||||
|
|
||||||
web-build:
|
web-build:
|
||||||
|
if: ${{ vars.DISABLE_GODOT_CI == '' }}
|
||||||
name: 🌐 Web
|
name: 🌐 Web
|
||||||
needs: static-checks
|
needs: static-checks
|
||||||
uses: ./.github/workflows/web_builds.yml
|
uses: ./.github/workflows/web_builds.yml
|
||||||
|
|
||||||
|
# Third stage: Run auxiliary tests using build artifacts from previous jobs.
|
||||||
|
|
||||||
|
# Can be turned off for PRs that intentionally break compat with godot-cpp,
|
||||||
|
# until both the upstream PR and the matching godot-cpp changes are merged.
|
||||||
|
godot-cpp-test:
|
||||||
|
if: ${{ vars.DISABLE_GODOT_CI == '' }}
|
||||||
|
name: 🪲 Godot CPP
|
||||||
|
# This can be changed to depend on another platform, if we decide to use it for
|
||||||
|
# godot-cpp instead. Make sure to move the .github/actions/godot-api-dump step
|
||||||
|
# appropriately.
|
||||||
|
needs: linux-build
|
||||||
|
uses: ./.github/workflows/godot_cpp_test.yml
|
||||||
|
|
|
@ -12,7 +12,7 @@ jobs:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 2
|
fetch-depth: 2
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ jobs:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
run: |
|
run: |
|
||||||
if [ "${{ github.event_name }}" == "pull_request" ]; then
|
if [ "${{ github.event_name }}" == "pull_request" ]; then
|
||||||
files=$(gh pr diff ${{ github.event.pull_request.number }} --name-only)
|
files=$(git diff-tree --no-commit-id --name-only -r HEAD^1..HEAD 2> /dev/null || true)
|
||||||
elif [ "${{ github.event_name }}" == "push" -a "${{ github.event.forced }}" == "false" -a "${{ github.event.created }}" == "false" ]; then
|
elif [ "${{ github.event_name }}" == "push" -a "${{ github.event.forced }}" == "false" -a "${{ github.event.created }}" == "false" ]; then
|
||||||
files=$(git diff-tree --no-commit-id --name-only -r ${{ github.event.before }}..${{ github.event.after }} 2> /dev/null || true)
|
files=$(git diff-tree --no-commit-id --name-only -r ${{ github.event.before }}..${{ github.event.after }} 2> /dev/null || true)
|
||||||
fi
|
fi
|
||||||
|
@ -106,5 +106,5 @@ jobs:
|
||||||
uses: codespell-project/actions-codespell@v2
|
uses: codespell-project/actions-codespell@v2
|
||||||
with:
|
with:
|
||||||
skip: "./bin,./thirdparty,*.desktop,*.gen.*,*.po,*.pot,*.rc,./AUTHORS.md,./COPYRIGHT.txt,./DONORS.md,./core/input/gamecontrollerdb.txt,./core/string/locales.h,./editor/project_converter_3_to_4.cpp,./misc/scripts/codespell.sh,./platform/android/java/lib/src/com,./platform/web/node_modules,./platform/web/package-lock.json"
|
skip: "./bin,./thirdparty,*.desktop,*.gen.*,*.po,*.pot,*.rc,./AUTHORS.md,./COPYRIGHT.txt,./DONORS.md,./core/input/gamecontrollerdb.txt,./core/string/locales.h,./editor/project_converter_3_to_4.cpp,./misc/scripts/codespell.sh,./platform/android/java/lib/src/com,./platform/web/node_modules,./platform/web/package-lock.json"
|
||||||
ignore_words_list: "curvelinear,doubleclick,expct,findn,gird,hel,inout,lod,mis,nd,numer,ot,requestor,te,vai"
|
ignore_words_list: "breaked,checkin,curvelinear,doubleclick,expct,findn,gird,hel,inout,labelin,lod,mis,nd,numer,ot,pointin,requestor,te,textin,thirdparty,vai"
|
||||||
path: ${{ env.CHANGED_FILES }}
|
path: ${{ env.CHANGED_FILES }}
|
||||||
|
|
|
@ -5,9 +5,9 @@ on:
|
||||||
# Global Settings
|
# Global Settings
|
||||||
env:
|
env:
|
||||||
# Used for the cache key. Add version suffix to force clean build.
|
# Used for the cache key. Add version suffix to force clean build.
|
||||||
GODOT_BASE_BRANCH: master
|
GODOT_BASE_BRANCH: '4.1'
|
||||||
SCONSFLAGS: verbose=yes warnings=extra werror=yes debug_symbols=no
|
SCONSFLAGS: verbose=yes warnings=extra werror=yes debug_symbols=no
|
||||||
EM_VERSION: 3.1.18
|
EM_VERSION: 3.1.39
|
||||||
EM_CACHE_FOLDER: "emsdk-cache"
|
EM_CACHE_FOLDER: "emsdk-cache"
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
|
@ -16,17 +16,18 @@ concurrency:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
web-template:
|
web-template:
|
||||||
runs-on: "ubuntu-20.04"
|
runs-on: "ubuntu-22.04"
|
||||||
name: Template (target=template_release)
|
name: Template (target=template_release)
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Set up Emscripten latest
|
- name: Set up Emscripten latest
|
||||||
uses: mymindstorm/setup-emsdk@v12
|
uses: mymindstorm/setup-emsdk@v14
|
||||||
with:
|
with:
|
||||||
version: ${{env.EM_VERSION}}
|
version: ${{env.EM_VERSION}}
|
||||||
actions-cache-folder: ${{env.EM_CACHE_FOLDER}}
|
actions-cache-folder: ${{env.EM_CACHE_FOLDER}}
|
||||||
|
cache-key: emsdk-${{ matrix.cache-name }}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
|
||||||
|
|
||||||
- name: Verify Emscripten setup
|
- name: Verify Emscripten setup
|
||||||
run: |
|
run: |
|
||||||
|
|
|
@ -6,7 +6,7 @@ on:
|
||||||
# SCONS_CACHE for windows must be set in the build environment
|
# SCONS_CACHE for windows must be set in the build environment
|
||||||
env:
|
env:
|
||||||
# Used for the cache key. Add version suffix to force clean build.
|
# Used for the cache key. Add version suffix to force clean build.
|
||||||
GODOT_BASE_BRANCH: master
|
GODOT_BASE_BRANCH: '4.1'
|
||||||
SCONSFLAGS: verbose=yes warnings=extra werror=yes module_text_server_fb_enabled=yes
|
SCONSFLAGS: verbose=yes warnings=extra werror=yes module_text_server_fb_enabled=yes
|
||||||
SCONS_CACHE_MSVC_CONFIG: true
|
SCONS_CACHE_MSVC_CONFIG: true
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ jobs:
|
||||||
sconsflags: debug_symbols=no
|
sconsflags: debug_symbols=no
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Setup Godot build cache
|
- name: Setup Godot build cache
|
||||||
uses: ./.github/actions/godot-cache
|
uses: ./.github/actions/godot-cache
|
||||||
|
@ -60,14 +60,6 @@ jobs:
|
||||||
target: ${{ matrix.target }}
|
target: ${{ matrix.target }}
|
||||||
tests: ${{ matrix.tests }}
|
tests: ${{ matrix.tests }}
|
||||||
|
|
||||||
# Execute unit tests for the editor
|
|
||||||
- name: Unit tests
|
|
||||||
if: ${{ matrix.tests }}
|
|
||||||
run: |
|
|
||||||
${{ matrix.bin }} --version
|
|
||||||
${{ matrix.bin }} --help
|
|
||||||
${{ matrix.bin }} --test
|
|
||||||
|
|
||||||
- name: Prepare artifact
|
- name: Prepare artifact
|
||||||
run: |
|
run: |
|
||||||
Remove-Item bin/* -Include *.exp,*.lib,*.pdb -Force
|
Remove-Item bin/* -Include *.exp,*.lib,*.pdb -Force
|
||||||
|
@ -76,3 +68,11 @@ jobs:
|
||||||
uses: ./.github/actions/upload-artifact
|
uses: ./.github/actions/upload-artifact
|
||||||
with:
|
with:
|
||||||
name: ${{ matrix.cache-name }}
|
name: ${{ matrix.cache-name }}
|
||||||
|
|
||||||
|
# Execute unit tests for the editor
|
||||||
|
- name: Unit tests
|
||||||
|
if: ${{ matrix.tests }}
|
||||||
|
run: |
|
||||||
|
${{ matrix.bin }} --version
|
||||||
|
${{ matrix.bin }} --help
|
||||||
|
${{ matrix.bin }} --test --force-colors
|
||||||
|
|
|
@ -132,23 +132,13 @@ cppcheck-cppcheck-build-dir/
|
||||||
*.pydevproject
|
*.pydevproject
|
||||||
*.launch
|
*.launch
|
||||||
|
|
||||||
# Gcov and Lcov code coverage
|
# Emacs
|
||||||
*.gcno
|
\#*\#
|
||||||
|
.\#*
|
||||||
|
|
||||||
|
# GCOV code coverage
|
||||||
*.gcda
|
*.gcda
|
||||||
*.gcov.html
|
*.gcno
|
||||||
*.func.html
|
|
||||||
*.func-sort-c.html
|
|
||||||
*index-sort-f.html
|
|
||||||
*index-sort-l.html
|
|
||||||
*index.html
|
|
||||||
godot.info
|
|
||||||
amber.png
|
|
||||||
emerald.png
|
|
||||||
glass.png
|
|
||||||
ruby.png
|
|
||||||
snow.png
|
|
||||||
updown.png
|
|
||||||
gcov.css
|
|
||||||
|
|
||||||
# Geany
|
# Geany
|
||||||
*.geany
|
*.geany
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
extraction:
|
|
||||||
cpp:
|
|
||||||
after_prepare:
|
|
||||||
- pip3 install scons
|
|
||||||
- PATH="/opt/work/.local/bin:$PATH"
|
|
||||||
index:
|
|
||||||
build_command: scons -j2
|
|
841
CHANGELOG.md
841
CHANGELOG.md
|
@ -4,6 +4,843 @@ All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
|
|
||||||
|
## [4.1.4] - 2024-04-17
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
#### C#/.NET
|
||||||
|
|
||||||
|
- Implemented `{project}` placeholder for external dotnet editor ([GH-81847](https://github.com/godotengine/godot/pull/81847)).
|
||||||
|
|
||||||
|
#### Documentation
|
||||||
|
|
||||||
|
- Add an example for `Dictionary.merge()`, mention lack of recursion ([GH-81622](https://github.com/godotengine/godot/pull/81622)).
|
||||||
|
- Add docs for DRAW_ORDER_REVERSE_LIFETIME constant ([GH-82866](https://github.com/godotengine/godot/pull/82866)).
|
||||||
|
- Fill out Material documentation and clarify `render_priority` and `next_pass` sorting ([GH-83931](https://github.com/godotengine/godot/pull/83931)).
|
||||||
|
- Document changing the window's resizable status at runtime ([GH-84886](https://github.com/godotengine/godot/pull/84886)).
|
||||||
|
- Add description for rendering/limits/spatial_indexer/threaded_cull_minimum_instances ([GH-86246](https://github.com/godotengine/godot/pull/86246)).
|
||||||
|
- Add missing descriptions to TextServer's constants ([GH-86895](https://github.com/godotengine/godot/pull/86895)).
|
||||||
|
- Add missing descriptions for Image's documentation ([GH-86997](https://github.com/godotengine/godot/pull/86997)).
|
||||||
|
- Add missing descriptions to PrimitiveMesh and SoftBody3D ([GH-87011](https://github.com/godotengine/godot/pull/87011)).
|
||||||
|
|
||||||
|
#### Editor
|
||||||
|
|
||||||
|
- "Whole Words" search can detect word boundaries inside the search term ([GH-82694](https://github.com/godotengine/godot/pull/82694)).
|
||||||
|
|
||||||
|
#### GUI
|
||||||
|
|
||||||
|
- Translate TextEdit placeholder ([GH-83946](https://github.com/godotengine/godot/pull/83946)).
|
||||||
|
|
||||||
|
#### Import
|
||||||
|
|
||||||
|
- Support unspecified linear size in DDS files ([GH-86336](https://github.com/godotengine/godot/pull/86336)).
|
||||||
|
|
||||||
|
#### Porting
|
||||||
|
|
||||||
|
- Linux: Handle export preset forward compat with 4.3+ platform name ([GH-89047](https://github.com/godotengine/godot/pull/89047)).
|
||||||
|
- Android: Add `POST_NOTIFICATIONS` permission to the list of permissions available in the Export dialog ([GH-90377](https://github.com/godotengine/godot/pull/90377)).
|
||||||
|
|
||||||
|
#### XR
|
||||||
|
|
||||||
|
- Compile OpenXR into MacOS build ([GH-79614](https://github.com/godotengine/godot/pull/79614)).
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
#### 3D
|
||||||
|
|
||||||
|
- Hide CSGShape's `debug_collision_shape` when it is invisible ([GH-84174](https://github.com/godotengine/godot/pull/84174)).
|
||||||
|
|
||||||
|
#### Animation
|
||||||
|
|
||||||
|
- Improve retarget auto-mapping algorithm ([GH-81843](https://github.com/godotengine/godot/pull/81843)).
|
||||||
|
|
||||||
|
#### Audio
|
||||||
|
|
||||||
|
- Only warn once about OGG seeking issues ([GH-81704](https://github.com/godotengine/godot/pull/81704)).
|
||||||
|
|
||||||
|
#### Buildsystem
|
||||||
|
|
||||||
|
- SCons: Re-disable exceptions for Android, iOS, and Web ([GH-84328](https://github.com/godotengine/godot/pull/84328)).
|
||||||
|
- Use Python venv if detected when building VS project ([GH-84593](https://github.com/godotengine/godot/pull/84593)).
|
||||||
|
- Add unsigned char cast ifdef to work around `-Wtype-limits` warnings ([GH-85500](https://github.com/godotengine/godot/pull/85500)).
|
||||||
|
- Web: Pin Emscripten to 3.1.39 on CI ([GH-84717](https://github.com/godotengine/godot/pull/84717)).
|
||||||
|
|
||||||
|
#### Core
|
||||||
|
|
||||||
|
- Set language encoding flag when using `ZIPPacker` ([GH-78732](https://github.com/godotengine/godot/pull/78732)).
|
||||||
|
- Do not replace starting digit with underscore when making identifier ([GH-82786](https://github.com/godotengine/godot/pull/82786)).
|
||||||
|
|
||||||
|
#### Documentation
|
||||||
|
|
||||||
|
- Clarify `PackedByteArray.decompress*` limitations with external data ([GH-81689](https://github.com/godotengine/godot/pull/81689)).
|
||||||
|
- Specify the behavior of `get_tree()` when the node is not in the scene tree ([GH-82863](https://github.com/godotengine/godot/pull/82863)).
|
||||||
|
- Clarify `NOTIFICATION_SCROLL_BEGIN/END` behavior ([GH-83636](https://github.com/godotengine/godot/pull/83636)).
|
||||||
|
- Improve and clarify texture filtering documentation ([GH-83907](https://github.com/godotengine/godot/pull/83907)).
|
||||||
|
- Clarify behavior of RayCast when `get_collision_point()` is used inside a collision shape ([GH-84085](https://github.com/godotengine/godot/pull/84085)).
|
||||||
|
- Update `add_submenu_item` doc to mention that submenu should already exist ([GH-84283](https://github.com/godotengine/godot/pull/84283)).
|
||||||
|
- Improve documentation for `CameraAttributesPhysical.exposure_shutter_speed` ([GH-85599](https://github.com/godotengine/godot/pull/85599)).
|
||||||
|
- Remove pointer to deprecated class page from Skeleton3D ([GH-86326](https://github.com/godotengine/godot/pull/86326)).
|
||||||
|
- Improve RichTextLabel `install_effect()` documentation ([GH-86331](https://github.com/godotengine/godot/pull/86331)).
|
||||||
|
- Mention `CollisionPolygon2D.polygon` is local to the given CollisionPolygon2D ([GH-87024](https://github.com/godotengine/godot/pull/87024)).
|
||||||
|
- Include `animation.length` in Animation example ([GH-87180](https://github.com/godotengine/godot/pull/87180)).
|
||||||
|
|
||||||
|
#### Editor
|
||||||
|
|
||||||
|
- Ensure binds are duplicated with `Node` signals ([GH-75382](https://github.com/godotengine/godot/pull/75382)).
|
||||||
|
- Ignore directory entries in TPZ ([GH-79374](https://github.com/godotengine/godot/pull/79374)).
|
||||||
|
- Don't apply frame delay project setting to the editor ([GH-82929](https://github.com/godotengine/godot/pull/82929)).
|
||||||
|
- Enable new addon after hiding ProjectSettings ([GH-83576](https://github.com/godotengine/godot/pull/83576)).
|
||||||
|
- Remove margins from editor scrollbars ([GH-83868](https://github.com/godotengine/godot/pull/83868)).
|
||||||
|
- Provide more context when scene fails to load ([GH-85083](https://github.com/godotengine/godot/pull/85083)).
|
||||||
|
|
||||||
|
#### Export
|
||||||
|
|
||||||
|
- Improve headings for the export mode in the Export dialog ([GH-79725](https://github.com/godotengine/godot/pull/79725)).
|
||||||
|
- Update the validation logic for the package name ([GH-84676](https://github.com/godotengine/godot/pull/84676)).
|
||||||
|
- Preserve the output from the gradle build command ([GH-84779](https://github.com/godotengine/godot/pull/84779)).
|
||||||
|
|
||||||
|
#### GUI
|
||||||
|
|
||||||
|
- Enable scrolling of output with UI scale changes ([GH-82079](https://github.com/godotengine/godot/pull/82079)).
|
||||||
|
- SystemFont: Check name when selecting the best matching face from a collection ([GH-82712](https://github.com/godotengine/godot/pull/82712)).
|
||||||
|
- Redraw `TreeItem` on more changes ([GH-87415](https://github.com/godotengine/godot/pull/87415)).
|
||||||
|
|
||||||
|
#### Rendering
|
||||||
|
|
||||||
|
- Make the rendering method dropdown also affect mobile if compatible ([GH-72461](https://github.com/godotengine/godot/pull/72461)).
|
||||||
|
- Clamp ReflectionProbe Max Distance to 262,144 to fix rendering issues ([GH-82415](https://github.com/godotengine/godot/pull/82415)).
|
||||||
|
- Apply some low-hanging fruit optimizations to Vulkan RD ([GH-85532](https://github.com/godotengine/godot/pull/85532)).
|
||||||
|
|
||||||
|
#### Thirdparty
|
||||||
|
|
||||||
|
- Sync controller mappings DB with SDL2 community repo.
|
||||||
|
- CA root certificates updated to 2024-03-11 bundle from Mozilla.
|
||||||
|
- mbedTLS updated to version 2.28.8.
|
||||||
|
- r128: Update to include latest fix for intrinsics being incorrect included ([GH-84537](https://github.com/godotengine/godot/pull/84537)).
|
||||||
|
- zlib/minizip updated to version 1.3.1.
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
|
||||||
|
#### GDExtension
|
||||||
|
|
||||||
|
- Remove Android specific abis from the export preset feature list ([GH-84720](https://github.com/godotengine/godot/pull/84720)).
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
#### 2D
|
||||||
|
|
||||||
|
- Fix UV editor not using texture transform ([GH-84076](https://github.com/godotengine/godot/pull/84076)).
|
||||||
|
|
||||||
|
#### 3D
|
||||||
|
|
||||||
|
- Fix PlaneMesh tangents for 'Face X' orientation ([GH-84097](https://github.com/godotengine/godot/pull/84097)).
|
||||||
|
- Fix CSGShape `debug_collision_shape` crash ([GH-84338](https://github.com/godotengine/godot/pull/84338)).
|
||||||
|
|
||||||
|
#### Animation
|
||||||
|
|
||||||
|
- Fix rename animation in SpriteFramesEditor ([GH-79600](https://github.com/godotengine/godot/pull/79600)).
|
||||||
|
- Fix crash when clicking on "Interpolation Mode" with nonexistent node path ([GH-81779](https://github.com/godotengine/godot/pull/81779)).
|
||||||
|
- Fix invalid return from some more `_get/_set` ([GH-84060](https://github.com/godotengine/godot/pull/84060)).
|
||||||
|
- Fix invalid 3-to-4 renames of `add_animation` to `add_animation_library` ([GH-86647](https://github.com/godotengine/godot/pull/86647)).
|
||||||
|
- Fix spurious infinite loop warnings in AnimationStateMachine ([GH-89575](https://github.com/godotengine/godot/pull/89575)).
|
||||||
|
|
||||||
|
#### Audio
|
||||||
|
|
||||||
|
- Fix Dummy audio driver initialization issue on WASAPI output device initialization failure ([GH-87010](https://github.com/godotengine/godot/pull/87010)).
|
||||||
|
|
||||||
|
#### Buildsystem
|
||||||
|
|
||||||
|
- Fix invalid Python escape sequences ([GH-85818](https://github.com/godotengine/godot/pull/85818)).
|
||||||
|
- macOS: Fix MoltenVK SDK detection after file location changes in 1.3.275.0 ([GH-87305](https://github.com/godotengine/godot/pull/87305)).
|
||||||
|
|
||||||
|
#### C#/.NET
|
||||||
|
|
||||||
|
- Fix `Transform3D.InterpolateWith` applying rotation before scale ([GH-89843](https://github.com/godotengine/godot/pull/89843)).
|
||||||
|
|
||||||
|
#### Core
|
||||||
|
|
||||||
|
- Fix allocation size overflow check in `CowData` ([GH-81917](https://github.com/godotengine/godot/pull/81917)).
|
||||||
|
- Fix invalid return from some `_get/_set` ([GH-84054](https://github.com/godotengine/godot/pull/84054)).
|
||||||
|
- Prevent `encode_variant` doing `memcpy` from `nullptr` ([GH-84155](https://github.com/godotengine/godot/pull/84155)).
|
||||||
|
- Prevent crash on conversion of invalid data in `Image` ([GH-84782](https://github.com/godotengine/godot/pull/84782)).
|
||||||
|
- Fix translation remapping check for imported resources ([GH-84791](https://github.com/godotengine/godot/pull/84791)).
|
||||||
|
- Prevent read-after-free in the queued CallableCustomStaticMethodPointer, fixes `slot >= slot_max` errors in release templates ([GH-85280](https://github.com/godotengine/godot/pull/85280)).
|
||||||
|
- Fix crash when hashing empty `CharString` ([GH-85389](https://github.com/godotengine/godot/pull/85389)).
|
||||||
|
- Prevent infinite recursion when printing errors ([GH-85397](https://github.com/godotengine/godot/pull/85397)).
|
||||||
|
|
||||||
|
#### Documentation
|
||||||
|
|
||||||
|
- Fix description of `Animation::copy_track` ([GH-83441](https://github.com/godotengine/godot/pull/83441)).
|
||||||
|
- Fix typo in ConcavePolygonShape2D/3D description ([GH-84111](https://github.com/godotengine/godot/pull/84111)).
|
||||||
|
- Fix several reported issues in String's documentation ([GH-86639](https://github.com/godotengine/godot/pull/86639)).
|
||||||
|
- Fix incorrect VehicleWheel3D Roll Influence description ([GH-86672](https://github.com/godotengine/godot/pull/86672)).
|
||||||
|
|
||||||
|
#### Editor
|
||||||
|
|
||||||
|
- Fix missing arrows in integer vector properties ([GH-79021](https://github.com/godotengine/godot/pull/79021)).
|
||||||
|
- Fix undo methods for DELETE in EditorAutoloadSettings ([GH-79832](https://github.com/godotengine/godot/pull/79832)).
|
||||||
|
- Fix wrong shader rename in 3-to-4 project converter ([GH-83708](https://github.com/godotengine/godot/pull/83708)).
|
||||||
|
- Fix UV editor not showing polygon correctly ([GH-84116](https://github.com/godotengine/godot/pull/84116)).
|
||||||
|
- Fix texture region editor not selecting restored snap mode ([GH-84762](https://github.com/godotengine/godot/pull/84762)).
|
||||||
|
|
||||||
|
#### GDScript
|
||||||
|
|
||||||
|
- Fix `_get_debug_tooltip` crash if tooltip string is too large ([GH-81018](https://github.com/godotengine/godot/pull/81018)).
|
||||||
|
- Fix DAP breakpoints being cleared on closed scripts ([GH-84898](https://github.com/godotengine/godot/pull/84898)).
|
||||||
|
|
||||||
|
#### GUI
|
||||||
|
|
||||||
|
- Fix storing invalid item height values in `ItemList` ([GH-82660](https://github.com/godotengine/godot/pull/82660)).
|
||||||
|
- Ensure input event is valid in `PopupMenu::activate_item_by_event` ([GH-83952](https://github.com/godotengine/godot/pull/83952)).
|
||||||
|
- Fix remapped font reloading on locale change ([GH-84873](https://github.com/godotengine/godot/pull/84873)).
|
||||||
|
- VideoPlayer: Fix reloading translation remapped stream ([GH-84794](https://github.com/godotengine/godot/pull/84794)).
|
||||||
|
|
||||||
|
#### Import
|
||||||
|
|
||||||
|
- Fix memory corruption and assert failures in convex decomposition ([GH-85631](https://github.com/godotengine/godot/pull/85631)).
|
||||||
|
- Prevent overriding file info of another file when reimport creates extra files ([GH-85922](https://github.com/godotengine/godot/pull/85922)).
|
||||||
|
- Fix `BasisUniversal` ETC RA as RG transcoding ([GH-86916](https://github.com/godotengine/godot/pull/86916)).
|
||||||
|
- GLTF: Fix three bugs which prevented extracted textures from being refreshed ([GH-86504](https://github.com/godotengine/godot/pull/86504)).
|
||||||
|
- Fix crash when previewing a scene with a mesh as the root node ([GH-87781](https://github.com/godotengine/godot/pull/87781)).
|
||||||
|
- Fix setting animation save paths on import breaking on Windows ([GH-90003](https://github.com/godotengine/godot/pull/90003)).
|
||||||
|
|
||||||
|
#### Input
|
||||||
|
|
||||||
|
- Android: Fix joypad trigger value range ([GH-81322](https://github.com/godotengine/godot/pull/81322)).
|
||||||
|
|
||||||
|
#### Multiplayer
|
||||||
|
|
||||||
|
- Fix `complete_auth` notifying the wrong peer ([GH-86257](https://github.com/godotengine/godot/pull/86257)).
|
||||||
|
|
||||||
|
#### Navigation
|
||||||
|
|
||||||
|
- Fix NavigationObstacle elevation ([GH-84830](https://github.com/godotengine/godot/pull/84830)).
|
||||||
|
- Fix NavigationObstacle height ([GH-84857](https://github.com/godotengine/godot/pull/84857)).
|
||||||
|
|
||||||
|
#### Networking
|
||||||
|
|
||||||
|
- Fix missing return in `StreamPeerTCP::poll` when connection is `STATUS_CONNECTED` ([GH-90741](https://github.com/godotengine/godot/pull/90741)).
|
||||||
|
|
||||||
|
#### Particles
|
||||||
|
|
||||||
|
- Fix several Material texture parameter updates ([GH-84303](https://github.com/godotengine/godot/pull/84303)).
|
||||||
|
|
||||||
|
#### Physics
|
||||||
|
|
||||||
|
- Fix body leaving area gravity influence ([GH-82961](https://github.com/godotengine/godot/pull/82961)).
|
||||||
|
- Fix CollisionObject3D Gizmo not updated after calling `shape_owner_*` functions ([GH-84610](https://github.com/godotengine/godot/pull/84610)).
|
||||||
|
|
||||||
|
#### Porting
|
||||||
|
|
||||||
|
- Fix bug where maximized->fullscreen->windowed mode stays maximized ([GH-84504](https://github.com/godotengine/godot/pull/84504)).
|
||||||
|
- Android: Fix editor crash issue when pressing Back ([GH-84414](https://github.com/godotengine/godot/pull/84414)).
|
||||||
|
- Android: Fix disabling splash screen Show Image ([GH-84491](https://github.com/godotengine/godot/pull/84491)).
|
||||||
|
- Linux: Fix size_t template issue on OpenBSD by using int consistently ([GH-84017](https://github.com/godotengine/godot/pull/84017)).
|
||||||
|
|
||||||
|
#### Rendering
|
||||||
|
|
||||||
|
- Fix transparent viewport backgrounds with custom clear color ([GH-79876](https://github.com/godotengine/godot/pull/79876)).
|
||||||
|
- Fix clear color on mobile renderer ([GH-80933](https://github.com/godotengine/godot/pull/80933)).
|
||||||
|
- Fix VoxelGI MultiMesh and CSG mesh baking ([GH-81616](https://github.com/godotengine/godot/pull/81616)).
|
||||||
|
- Fix bad parameter for `rendering_method` crashes Godot ([GH-84241](https://github.com/godotengine/godot/pull/84241)).
|
||||||
|
- Transform mesh's AABB to skeleton's space when calculating mesh's bounds ([GH-84451](https://github.com/godotengine/godot/pull/84451)).
|
||||||
|
- Prevent crash in `_nvapi_disable_threaded_optimization` when attached to renderdoc ([GH-85121](https://github.com/godotengine/godot/pull/85121)).
|
||||||
|
- Fix typo in BaseMaterial3D conversion from 3.x SpatialMaterial ([GH-85269](https://github.com/godotengine/godot/pull/85269)).
|
||||||
|
- Fix Polygon2D to Skeleton2D transform calculation ([GH-86557](https://github.com/godotengine/godot/pull/86557)).
|
||||||
|
- Disable scissor test after rendering batches in compatibility renderer ([GH-87489](https://github.com/godotengine/godot/pull/87489)).
|
||||||
|
- GLES3: Avoid freeing proxy textures clearing owner's data ([GH-82430](https://github.com/godotengine/godot/pull/82430)).
|
||||||
|
- GLES3: Fix iOS Simulator by removing incorrect `system_fbo` overwrite ([GH-84955](https://github.com/godotengine/godot/pull/84955)).
|
||||||
|
- GLES3: Skip batches with zero instance count while rendering canvas ([GH-85778](https://github.com/godotengine/godot/pull/85778)).
|
||||||
|
|
||||||
|
#### Shaders
|
||||||
|
|
||||||
|
- Fix int to uint implicit cast error when use mat3 uniform in compatibility renderer ([GH-81494](https://github.com/godotengine/godot/pull/81494)).
|
||||||
|
|
||||||
|
|
||||||
|
## [4.1.3] - 2023-11-01
|
||||||
|
|
||||||
|
See the [release announcement](https://godotengine.org/article/maintenance-release-godot-4-1-3) for details.
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
#### Core
|
||||||
|
|
||||||
|
- Support loading of translations on threads ([GH-78747](https://github.com/godotengine/godot/pull/78747)).
|
||||||
|
|
||||||
|
#### Documentation
|
||||||
|
|
||||||
|
- Add missing RenderingDevice method descriptions ([GH-80716](https://github.com/godotengine/godot/pull/80716)).
|
||||||
|
|
||||||
|
#### GDScript
|
||||||
|
|
||||||
|
- Add check for `super()` methods not being implemented ([GH-81808](https://github.com/godotengine/godot/pull/81808)).
|
||||||
|
|
||||||
|
#### Input
|
||||||
|
|
||||||
|
- Add missing YEN, SECTION and OPENURL names to keycode mappings ([GH-81054](https://github.com/godotengine/godot/pull/81054)).
|
||||||
|
- Add XInput device ID for wireless Series 2 Elite controller ([GH-82508](https://github.com/godotengine/godot/pull/82508)).
|
||||||
|
|
||||||
|
#### Rendering
|
||||||
|
|
||||||
|
- Mobile: Uncomment code required for fog rendering on clear color ([GH-79776](https://github.com/godotengine/godot/pull/79776)).
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
#### 2D
|
||||||
|
|
||||||
|
- Allow using floating-point bone sizes and outline widths in the 2D editor ([GH-79434](https://github.com/godotengine/godot/pull/79434)).
|
||||||
|
- Convert TileSet Atlas Merge input images to RGBA8 to match output, if needed ([GH-80943](https://github.com/godotengine/godot/pull/80943)).
|
||||||
|
|
||||||
|
#### 3D
|
||||||
|
|
||||||
|
- Make CSGShape follow curve's tilt in Path mode ([GH-79355](https://github.com/godotengine/godot/pull/79355)).
|
||||||
|
- Initialize View Frame Time estimates to match 120 FPS ([GH-80124](https://github.com/godotengine/godot/pull/80124)).
|
||||||
|
|
||||||
|
#### Animation
|
||||||
|
|
||||||
|
- Improve and clarify paused Tweens ([GH-79879](https://github.com/godotengine/godot/pull/79879)).
|
||||||
|
- Avoid emitting signals if the animation is not ready to be processed ([GH-80367](https://github.com/godotengine/godot/pull/80367)).
|
||||||
|
- Ensure methods skipped by `AnimationPlayer::seek` are not called ([GH-80708](https://github.com/godotengine/godot/pull/80708)).
|
||||||
|
|
||||||
|
#### Buildsystem
|
||||||
|
|
||||||
|
- Updated compiler version detection ([GH-82325](https://github.com/godotengine/godot/pull/82325), [GH-82352](https://github.com/godotengine/godot/pull/82352)).
|
||||||
|
- SCons: Use CXXFLAGS to disable exceptions ([GH-83618](https://github.com/godotengine/godot/pull/83618)).
|
||||||
|
|
||||||
|
#### Editor
|
||||||
|
|
||||||
|
- Always double-quote path when launching Windows File Explorer ([GH-78963](https://github.com/godotengine/godot/pull/78963)).
|
||||||
|
|
||||||
|
#### Import
|
||||||
|
|
||||||
|
- Limit mesh complexity in LOD generation to prevent crashing ([GH-80467](https://github.com/godotengine/godot/pull/80467)).
|
||||||
|
- Update Blender export flags for 3.6 ([GH-81194](https://github.com/godotengine/godot/pull/81194)).
|
||||||
|
|
||||||
|
#### Thirdparty
|
||||||
|
|
||||||
|
- mbedTLS updated to version 2.18.5.
|
||||||
|
- zlib/minizip updated to version 1.3.
|
||||||
|
- Sync controller mappings DB with SDL2 community repo.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
#### 2D
|
||||||
|
|
||||||
|
- Fix "a number is required" error when printing RID ([GH-80122](https://github.com/godotengine/godot/pull/80122)).
|
||||||
|
- Fix TileMap editor so that pressing control deselects cells correctly ([GH-81925](https://github.com/godotengine/godot/pull/81925)).
|
||||||
|
- Fix animated tile time-slice calculation accumulating float errors ([GH-82360](https://github.com/godotengine/godot/pull/82360)).
|
||||||
|
|
||||||
|
#### 3D
|
||||||
|
|
||||||
|
- GridMap: Ensure the visibility is updated when entering the tree ([GH-81106](https://github.com/godotengine/godot/pull/81106)).
|
||||||
|
|
||||||
|
#### Animation
|
||||||
|
|
||||||
|
- Fix incorrect cast when animating `int` ([GH-81296](https://github.com/godotengine/godot/pull/81296)).
|
||||||
|
- Fix animation keyframes being skipped when played backwards ([GH-81452](https://github.com/godotengine/godot/pull/81452)).
|
||||||
|
- Fix BoneAttachment3D signal connection ([GH-81695](https://github.com/godotengine/godot/pull/81695)).
|
||||||
|
- Fix `SkeletonIK3D` editor preview when changing active node ([GH-82391](https://github.com/godotengine/godot/pull/82391)).
|
||||||
|
|
||||||
|
#### Audio
|
||||||
|
|
||||||
|
- Fix pausing stream on entering tree ([GH-83779](https://github.com/godotengine/godot/pull/83779)).
|
||||||
|
|
||||||
|
#### C#/.NET
|
||||||
|
|
||||||
|
- Fix line in OpenInExternalEditor ([GH-79404](https://github.com/godotengine/godot/pull/79404)).
|
||||||
|
- Fix an error in `Vector3.BezierDerivative` ([GH-82664](https://github.com/godotengine/godot/pull/82664)).
|
||||||
|
|
||||||
|
#### Core
|
||||||
|
|
||||||
|
- Clear the previously set state when configuring for a new scene root node ([GH-79201](https://github.com/godotengine/godot/pull/79201)).
|
||||||
|
- Fix example for `Object._set` documentation ([GH-80475](https://github.com/godotengine/godot/pull/80475)).
|
||||||
|
- Fix comparison of `Callable`s with binds ([GH-81131](https://github.com/godotengine/godot/pull/81131)).
|
||||||
|
- Fix for non-deterministic behavior in PCKPacker ([GH-81280](https://github.com/godotengine/godot/pull/81280)).
|
||||||
|
- Fix not being able to set Node process priority in certain cases ([GH-82358](https://github.com/godotengine/godot/pull/82358)).
|
||||||
|
|
||||||
|
#### Editor
|
||||||
|
|
||||||
|
- Fix conversion of hex color strings in project converter ([GH-74026](https://github.com/godotengine/godot/pull/74026)).
|
||||||
|
- Fix indentation in script templates ([GH-78675](https://github.com/godotengine/godot/pull/78675)).
|
||||||
|
- Fix "Go to parent folder" in `EditorFileDialog` ([GH-80821](https://github.com/godotengine/godot/pull/80821)).
|
||||||
|
- Fix paste value emptying an array on some right click location ([GH-80977](https://github.com/godotengine/godot/pull/80977)).
|
||||||
|
- Fix missing dependency warning popup ([GH-82244](https://github.com/godotengine/godot/pull/82244), [GH-83024](https://github.com/godotengine/godot/pull/83024)).
|
||||||
|
- Fix garbled text in editor toasters ([GH-82913](https://github.com/godotengine/godot/pull/82913)).
|
||||||
|
- AssetLib: Fix long plugin names breaking the UI ([GH-80555](https://github.com/godotengine/godot/pull/80555)).
|
||||||
|
|
||||||
|
#### Export
|
||||||
|
|
||||||
|
- iOS: Fix build on Xcode 14 and older ([GH-83088](https://github.com/godotengine/godot/pull/83088)).
|
||||||
|
|
||||||
|
#### GDExtension
|
||||||
|
|
||||||
|
- Fix incorrect virtual function in `VideoStream.set_paused` ([GH-79710](https://github.com/godotengine/godot/pull/79710)).
|
||||||
|
- Fix `variant_iter_get()` actually calling `iter_next()` ([GH-83681](https://github.com/godotengine/godot/pull/83681)).
|
||||||
|
|
||||||
|
#### GDScript
|
||||||
|
|
||||||
|
- Check `get_node()` shorthand in static functions ([GH-78552](https://github.com/godotengine/godot/pull/78552)).
|
||||||
|
- Fix completion option location not found ([GH-80283](https://github.com/godotengine/godot/pull/80283)).
|
||||||
|
- Fix `get_method` from named lambda ([GH-80506](https://github.com/godotengine/godot/pull/80506)).
|
||||||
|
- Fix `GDScriptCache::get_full_script` eating parsing errors because of early exit ([GH-83540](https://github.com/godotengine/godot/pull/83540)).
|
||||||
|
- LSP: Fix connection error when launched in a separate thread ([GH-80686](https://github.com/godotengine/godot/pull/80686)).
|
||||||
|
- LSP: Fix autocomplete quote handling ([GH-81833](https://github.com/godotengine/godot/pull/81833)).
|
||||||
|
|
||||||
|
#### GUI
|
||||||
|
|
||||||
|
- Fix native popups auto-closing when interacting with non-client area ([GH-79456](https://github.com/godotengine/godot/pull/79456)).
|
||||||
|
- Fix scrolling `PopupMenu` on keyboard/controller input ([GH-80271](https://github.com/godotengine/godot/pull/80271)).
|
||||||
|
- Fix `OptionButton` minimum size when "Fit Longest Item" is enabled ([GH-80366](https://github.com/godotengine/godot/pull/80366)).
|
||||||
|
- Fix 2D/3D viewport context switching issues when script editor is floating ([GH-80647](https://github.com/godotengine/godot/pull/80647)).
|
||||||
|
- Fix `TreeItem` range slider not working properly ([GH-81174](https://github.com/godotengine/godot/pull/81174)).
|
||||||
|
|
||||||
|
#### Import
|
||||||
|
|
||||||
|
- Fix reimporting scene with default values selected ([GH-79907](https://github.com/godotengine/godot/pull/79907)).
|
||||||
|
- Fix grayscale DDS loading ([GH-81134](https://github.com/godotengine/godot/pull/81134)).
|
||||||
|
- Fix ImporterMesh bone weight handling during lightmap unwrap ([GH-81854](https://github.com/godotengine/godot/pull/81854)).
|
||||||
|
- Avoid crash when generating LODs on meshes with non-finite vertices ([GH-82285](https://github.com/godotengine/godot/pull/82285)).
|
||||||
|
|
||||||
|
#### Multiplayer
|
||||||
|
|
||||||
|
- Fix watch properties not being correctly removed ([GH-81033](https://github.com/godotengine/godot/pull/81033)).
|
||||||
|
|
||||||
|
#### Navigation
|
||||||
|
|
||||||
|
- Fix pathfinding funnel adding unwanted point ([GH-79228](https://github.com/godotengine/godot/pull/79228)).
|
||||||
|
|
||||||
|
#### Particles
|
||||||
|
|
||||||
|
- Fix particle shader deterministic random values ([GH-80638](https://github.com/godotengine/godot/pull/80638)).
|
||||||
|
- Fix `GPUParticles2D` offset stutter ([GH-80984](https://github.com/godotengine/godot/pull/80984)).
|
||||||
|
- Fix errors when freeing GPUParticles ([GH-82431](https://github.com/godotengine/godot/pull/82431)).
|
||||||
|
|
||||||
|
#### Physics
|
||||||
|
|
||||||
|
- Fix missing clear for some `set_exclude*` query parameter methods ([GH-82043](https://github.com/godotengine/godot/pull/82043)).
|
||||||
|
|
||||||
|
#### Porting
|
||||||
|
|
||||||
|
- Android: Fix input routing logic when using a hardware keyboard ([GH-80932](https://github.com/godotengine/godot/pull/80932)).
|
||||||
|
- Android: Fix logic for deferred window input events being inverted ([GH-83301](https://github.com/godotengine/godot/pull/83301)).
|
||||||
|
- Android: Update the `launchMode` for the `GodotApp` activity ([GH-83954](https://github.com/godotengine/godot/pull/83954)).
|
||||||
|
- Linux: Use EWMH for `DisplayServerX11::_window_minimize_check()` implementation ([GH-80036](https://github.com/godotengine/godot/pull/80036)).
|
||||||
|
- macOS: Fix borderless mode on macOS 13.6+ ([GH-82357](https://github.com/godotengine/godot/pull/82357)).
|
||||||
|
- Web: Fix JavaScript callback memory leak issue ([GH-81105](https://github.com/godotengine/godot/pull/81105)).
|
||||||
|
- Windows: Do not force redraw window background on mouse pass-through region change ([GH-80153](https://github.com/godotengine/godot/pull/80153)).
|
||||||
|
- Windows: Fix not applying NVIDIA profile to new executables ([GH-81251](https://github.com/godotengine/godot/pull/81251)).
|
||||||
|
|
||||||
|
#### Rendering
|
||||||
|
|
||||||
|
- Initialize MSDF parameters in BaseMaterial3D with default ([GH-79983](https://github.com/godotengine/godot/pull/79983)).
|
||||||
|
- Fix validation error when enabling SSIL alone ([GH-80315](https://github.com/godotengine/godot/pull/80315)).
|
||||||
|
- Ensure `POINT_SIZE` takes effect in the canvas item shader ([GH-80323](https://github.com/godotengine/godot/pull/80323)).
|
||||||
|
- Fix volumetric fog NaN values in textures from starting at a zero Vector2 ([GH-80992](https://github.com/godotengine/godot/pull/80992)).
|
||||||
|
- Fix VoxelGI CameraAttributes exposure normalization handling ([GH-81067](https://github.com/godotengine/godot/pull/81067)).
|
||||||
|
- Fix special case of cluster render ([GH-81081](https://github.com/godotengine/godot/pull/81081)).
|
||||||
|
- Fix VoxelGI static light pairing ([GH-81124](https://github.com/godotengine/godot/pull/81124)).
|
||||||
|
- Fix LightmapGI baking with GridMap ([GH-81545](https://github.com/godotengine/godot/pull/81545)).
|
||||||
|
- Fix `SubViewport` with `UPDATE_WHEN_VISIBLE` not working properly in exported project ([GH-81607](https://github.com/godotengine/godot/pull/81607)).
|
||||||
|
- Fix massive validation errors when enabling TAA + MSAA ([GH-81775](https://github.com/godotengine/godot/pull/81775)).
|
||||||
|
- Fix LightmapGI shading sometimes being unlit or black ([GH-81951](https://github.com/godotengine/godot/pull/81951)).
|
||||||
|
- Fix ShaderGlobalsOverride property handling ([GH-82100](https://github.com/godotengine/godot/pull/82100)).
|
||||||
|
- Fix cluster artifacts and negative light ([GH-82546](https://github.com/godotengine/godot/pull/82546)).
|
||||||
|
- Fix undeclared identifier `global_variables` in the fog shader ([GH-82877](https://github.com/godotengine/godot/pull/82877)).
|
||||||
|
- Avoid default fallback material when using `world_vertex_coords` ([GH-82886](https://github.com/godotengine/godot/pull/82886)).
|
||||||
|
- Fix VoxelGI bake memory leak ([GH-83035](https://github.com/godotengine/godot/pull/83035)).
|
||||||
|
- Fix disabling depth prepass break opaque materials ([GH-83371](https://github.com/godotengine/godot/pull/83371)).
|
||||||
|
- GLES3: Fix clear color's alpha value will affects 2D editor ([GH-81395](https://github.com/godotengine/godot/pull/81395)).
|
||||||
|
- GLES3: Fix instanced rendering color and custom data defaults ([GH-81575](https://github.com/godotengine/godot/pull/81575)).
|
||||||
|
- Mobile: Fix issue with four subpasses always been requested ([GH-80368](https://github.com/godotengine/godot/pull/80368)).
|
||||||
|
- Mobile: Fix missing decal mask ([GH-80911](https://github.com/godotengine/godot/pull/80911)).
|
||||||
|
- Vulkan: Fix multithreaded compute list and GPU particle processing ([GH-79849](https://github.com/godotengine/godot/pull/79849)).
|
||||||
|
|
||||||
|
#### XR
|
||||||
|
|
||||||
|
- Properly skip frame render when the XR runtime is not yet ready ([GH-82752](https://github.com/godotengine/godot/pull/82752)).
|
||||||
|
- Fix `GPUParticles3D` on the Meta Quest 2 with OpenGL renderer ([GH-83756](https://github.com/godotengine/godot/pull/83756)).
|
||||||
|
|
||||||
|
|
||||||
|
## [4.1.2] - 2023-10-04
|
||||||
|
|
||||||
|
See the [release announcement](https://godotengine.org/article/maintenance-release-godot-4-1-2) for details.
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
#### Core
|
||||||
|
|
||||||
|
- Add check to ensure registered classes are declared ([GH-81020](https://github.com/godotengine/godot/pull/81020)).
|
||||||
|
|
||||||
|
#### Rendering
|
||||||
|
|
||||||
|
- Add motion vector support for GPU 3D Particles ([GH-80688](https://github.com/godotengine/godot/pull/80688)).
|
||||||
|
|
||||||
|
#### Shaders
|
||||||
|
|
||||||
|
- Allow more hint types for uniform arrays ([GH-79100](https://github.com/godotengine/godot/pull/79100)).
|
||||||
|
- Add autocomplete for filter/repeat hints on uniform arrays ([GH-79402](https://github.com/godotengine/godot/pull/79402)).
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
#### 3D
|
||||||
|
|
||||||
|
- Change property hint range for camera attributes exposure multiplier ([GH-79138](https://github.com/godotengine/godot/pull/79138)).
|
||||||
|
|
||||||
|
#### Buildsystem
|
||||||
|
|
||||||
|
- Disable C++ exception handling (off by default in 4.1) ([GH-80612](https://github.com/godotengine/godot/pull/80612)).
|
||||||
|
- libpng: Enable intrinsics on x86/SSE2, ppc64/VSX, and all arm/NEON ([GH-78325](https://github.com/godotengine/godot/pull/78325)).
|
||||||
|
- Linux: Allow unbundling OpenXR ([GH-73443](https://github.com/godotengine/godot/pull/73443)).
|
||||||
|
- MSVC: Pass build options configuration to Visual Studio projects ([GH-79238](https://github.com/godotengine/godot/pull/79238)).
|
||||||
|
- MSVC: Make incremental linking optional ([GH-80482](https://github.com/godotengine/godot/pull/80482), [GH-81144](https://github.com/godotengine/godot/pull/81144)).
|
||||||
|
- MSVC: Enable `/WX` on LINKFLAGS for MSVC with `werror=yes` ([GH-80711](https://github.com/godotengine/godot/pull/80711)).
|
||||||
|
|
||||||
|
#### C#/.NET
|
||||||
|
|
||||||
|
- Hide hostfxr not found error ([GH-81690](https://github.com/godotengine/godot/pull/81690)).
|
||||||
|
|
||||||
|
#### Editor
|
||||||
|
|
||||||
|
- Don't use splash minimum display time in editor ([GH-79388](https://github.com/godotengine/godot/pull/79388)).
|
||||||
|
- Automatically add path to built-in scripts ([GH-79920](https://github.com/godotengine/godot/pull/79920)).
|
||||||
|
- Uncollapse favorites by default in the editor FileSystem dock ([GH-79971](https://github.com/godotengine/godot/pull/79971)).
|
||||||
|
- Use `ui_text_submit` instead of `ui_accept` to confirm and close text prompts ([GH-81189](https://github.com/godotengine/godot/pull/81189)).
|
||||||
|
- Make editor camera speed indicator use `m/s` and `m` ([GH-81810](https://github.com/godotengine/godot/pull/81810)).
|
||||||
|
|
||||||
|
#### GUI
|
||||||
|
|
||||||
|
- Enable transparent background for GUI tooltips ([GH-81669](https://github.com/godotengine/godot/pull/81669)).
|
||||||
|
|
||||||
|
#### Input
|
||||||
|
|
||||||
|
- Prevent double input events on gamepad when running through steam input ([GH-76045](https://github.com/godotengine/godot/pull/76045)).
|
||||||
|
- Ensure `joy_connection_changed` is emitted on the main thread ([GH-80432](https://github.com/godotengine/godot/pull/80432)).
|
||||||
|
- Android: Set `echo` property for the physical keyboard events ([GH-79089](https://github.com/godotengine/godot/pull/79089)).
|
||||||
|
|
||||||
|
#### Networking
|
||||||
|
|
||||||
|
- Web: Always return -1 as body length in HTTPClientWeb ([GH-79846](https://github.com/godotengine/godot/pull/79846)).
|
||||||
|
|
||||||
|
#### Porting
|
||||||
|
|
||||||
|
- Web: Disable raycast module by default (no occlusion culling) ([GH-81716](https://github.com/godotengine/godot/pull/81716)).
|
||||||
|
- X11: Do not fail DisplayServer init if non-essential extensions are missing ([GH-80240](https://github.com/godotengine/godot/pull/80240)).
|
||||||
|
|
||||||
|
#### Rendering
|
||||||
|
|
||||||
|
- Enable depth writes during shadow pass and depth pass, disable during color pass ([GH-80070](https://github.com/godotengine/godot/pull/80070)).
|
||||||
|
- Remove GPU readback from `NoiseTexture3D.get_format()` ([GH-80407](https://github.com/godotengine/godot/pull/80407)).
|
||||||
|
- Clamp Volumetric Fog Length property to prevent rendering issues ([GH-80485](https://github.com/godotengine/godot/pull/80485)).
|
||||||
|
- Propagate error correctly when max texture size for lightmaps is too small ([GH-81543](https://github.com/godotengine/godot/pull/81543)).
|
||||||
|
- GLES3: Reset anisotropic filtering when changing texture filtering mode ([GH-79568](https://github.com/godotengine/godot/pull/79568)).
|
||||||
|
- GLES3: Don't call `glTexParameter*` for invalid filter and repeat modes ([GH-79685](https://github.com/godotengine/godot/pull/79685)).
|
||||||
|
|
||||||
|
#### Thirdparty
|
||||||
|
|
||||||
|
- FreeType updated to version 2.13.2.
|
||||||
|
- ICU4C updated to version 73.2.
|
||||||
|
- libpng updated to version 1.6.40.
|
||||||
|
- libwebp updated to version 1.3.2.
|
||||||
|
- mbedtls updated to version 2.28.4.
|
||||||
|
- miniupnpc updated to version 2.2.5.
|
||||||
|
- openxr updated to version 1.0.28.
|
||||||
|
- tinyexr updated to version 1.0.7.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
#### 2D
|
||||||
|
|
||||||
|
- Fix Camera2D crash when edited scene root is null ([GH-79645](https://github.com/godotengine/godot/pull/79645)).
|
||||||
|
- Fix `CanvasModulate` logic for modulating the canvas ([GH-79747](https://github.com/godotengine/godot/pull/79747)).
|
||||||
|
|
||||||
|
#### 3D
|
||||||
|
|
||||||
|
- Fix VoxelGI saving VoxelGIData as a built-in file, despite being prompted to save it to an external file ([GH-78772](https://github.com/godotengine/godot/pull/78772)).
|
||||||
|
- Fix Curve3D baking up vectors for nontrivial curves ([GH-81885](https://github.com/godotengine/godot/pull/81885)).
|
||||||
|
|
||||||
|
#### Animation
|
||||||
|
|
||||||
|
- Fix `Animation::subtract_variant` for affine transforms ([GH-79279](https://github.com/godotengine/godot/pull/79279)).
|
||||||
|
- Fix `AnimationNodeTransition` with negative time scale ([GH-79403](https://github.com/godotengine/godot/pull/79403)).
|
||||||
|
- Remove animation tracks with correct indices ([GH-81651](https://github.com/godotengine/godot/pull/81651)).
|
||||||
|
|
||||||
|
#### Audio
|
||||||
|
|
||||||
|
- Fix audio stream generators getting freed accidentally ([GH-81508](https://github.com/godotengine/godot/pull/81508)).
|
||||||
|
|
||||||
|
#### Buildsystem
|
||||||
|
|
||||||
|
- Fix Python 3.12 SyntaxError with regex escape sequences ([GH-82290](https://github.com/godotengine/godot/pull/82290)).
|
||||||
|
- macOS/iOS: Workaround build issue with new Xcode 15 linker ([GH-81968](https://github.com/godotengine/godot/pull/81968), [GH-82458](https://github.com/godotengine/godot/pull/82458)).
|
||||||
|
- Web: Workaround Emscripten 3.1.42+ LTO regression ([GH-81340](https://github.com/godotengine/godot/pull/81340)).
|
||||||
|
|
||||||
|
#### C#/.NET
|
||||||
|
|
||||||
|
- Fix deserialization of delegates that are 0-parameter overloads ([GH-78877](https://github.com/godotengine/godot/pull/78877)).
|
||||||
|
- Add missing `useModelFront` parameter to GodotSharp Basis and Transform ([GH-79082](https://github.com/godotengine/godot/pull/79082)).
|
||||||
|
- Fix double unregistration on dispose of Array ([GH-81230](https://github.com/godotengine/godot/pull/81230)).
|
||||||
|
- Fix Visual Studio 2022 for Mac compatibility ([GH-81802](https://github.com/godotengine/godot/pull/81802)).
|
||||||
|
|
||||||
|
#### Core
|
||||||
|
|
||||||
|
- Fix range error for `Array.slice` ([GH-79103](https://github.com/godotengine/godot/pull/79103)).
|
||||||
|
- Fix byte to float color conversion in `DisplayServerWindows::screen_get_pixel` ([GH-79350](https://github.com/godotengine/godot/pull/79350)).
|
||||||
|
- Fix recursion level check for array stringification ([GH-79370](https://github.com/godotengine/godot/pull/79370)).
|
||||||
|
- Fix global transform validity for `Node2D` and `Control` ([GH-80105](https://github.com/godotengine/godot/pull/80105)).
|
||||||
|
- Fix recursion level check for `VariantWriter::write()` with objects ([GH-81123](https://github.com/godotengine/godot/pull/81123)).
|
||||||
|
- Fix string conversion for -0.0 float values ([GH-81328](https://github.com/godotengine/godot/pull/81328)).
|
||||||
|
- Crypto: Fix `generate_random_bytes` for large chunks ([GH-81884](https://github.com/godotengine/godot/pull/81884)).
|
||||||
|
|
||||||
|
#### Editor
|
||||||
|
|
||||||
|
- Fix history mismatch ([GH-78827](https://github.com/godotengine/godot/pull/78827)).
|
||||||
|
- Improve resolution of script type icons ([GH-79203](https://github.com/godotengine/godot/pull/79203), [GH-81336](https://github.com/godotengine/godot/pull/81336)).
|
||||||
|
- Fix arg count checks in `SceneDebugger` ([GH-79655](https://github.com/godotengine/godot/pull/79655)).
|
||||||
|
- Make the single window mode check more strict ([GH-79793](https://github.com/godotengine/godot/pull/79793)).
|
||||||
|
- Fix crash when using "Close All Tabs" ([GH-79917](https://github.com/godotengine/godot/pull/79917)).
|
||||||
|
- Fix a crash when plugin tries to call `make_mesh_previews` on enable ([GH-81121](https://github.com/godotengine/godot/pull/81121)).
|
||||||
|
|
||||||
|
#### Export
|
||||||
|
|
||||||
|
- Fix Windows console wrapper and icon being swapped ([GH-80357](https://github.com/godotengine/godot/pull/80357)).
|
||||||
|
|
||||||
|
#### GDExtension
|
||||||
|
|
||||||
|
- Fix version check for GDExtension ([GH-80591](https://github.com/godotengine/godot/pull/80591)).
|
||||||
|
- Fix overriding `_export_begin`, `_export_file` and `_export_end` from GDExtension ([GH-80999](https://github.com/godotengine/godot/pull/80999)).
|
||||||
|
|
||||||
|
#### GDScript
|
||||||
|
|
||||||
|
- Fix conflict between property and group names ([GH-78254](https://github.com/godotengine/godot/pull/78254)).
|
||||||
|
- Properly track extents of constants ([GH-79301](https://github.com/godotengine/godot/pull/79301)).
|
||||||
|
- Fix dumping of signal API parameters ([GH-81599](https://github.com/godotengine/godot/pull/81599)).
|
||||||
|
|
||||||
|
#### GUI
|
||||||
|
|
||||||
|
- Fix RichTextLabel character line and paragraph index getters ([GH-76759](https://github.com/godotengine/godot/pull/76759)).
|
||||||
|
- Fix text overlapping icon in `Tree` ([GH-78756](https://github.com/godotengine/godot/pull/78756)).
|
||||||
|
- Fix delay on tab resizing when (un)hovering tabs ([GH-78777](https://github.com/godotengine/godot/pull/78777)).
|
||||||
|
- Fix `Tree` performance regression by using cache ([GH-79325](https://github.com/godotengine/godot/pull/79325)).
|
||||||
|
- Fix Button clipping when internal margins exist ([GH-79455](https://github.com/godotengine/godot/pull/79455)).
|
||||||
|
- Make `OptionButton`` resize when disabling "Fit to Longest Item" ([GH-79494](https://github.com/godotengine/godot/pull/79494)).
|
||||||
|
- Fix `root_node_layout_direction` project setting being incorrectly exposed as a range ([GH-79611](https://github.com/godotengine/godot/pull/79611)).
|
||||||
|
- Fix `Button` text when the overrun behavior is other than "No Trimming" ([GH-80402](https://github.com/godotengine/godot/pull/80402)).
|
||||||
|
- Fix `CodeEdit` completion being very slow in certain cases ([GH-80472](https://github.com/godotengine/godot/pull/80472)).
|
||||||
|
- Fix crash when hiding subwindow during popup of new subwindow ([GH-80780](https://github.com/godotengine/godot/pull/80780)).
|
||||||
|
- RTL: Improve performance by using list iterators for item/paragraph removal ([GH-80857](https://github.com/godotengine/godot/pull/80857)).
|
||||||
|
- Fix setting TabContainer's `font_hovered_color` theme property ([GH-81040](https://github.com/godotengine/godot/pull/81040)).
|
||||||
|
- Fix ItemList not updating when icon scale changes ([GH-81268](https://github.com/godotengine/godot/pull/81268)).
|
||||||
|
|
||||||
|
#### Import
|
||||||
|
|
||||||
|
- Use image index instead of texture index for `source_images` ([GH-80314](https://github.com/godotengine/godot/pull/80314)).
|
||||||
|
|
||||||
|
#### Navigation
|
||||||
|
|
||||||
|
- Fix NavigationObstacle2D debug position ([GH-79392](https://github.com/godotengine/godot/pull/79392)).
|
||||||
|
- Make NavigationRegion3D baking NavMesh on the main thread not finish deferred ([GH-79465](https://github.com/godotengine/godot/pull/79465)).
|
||||||
|
- Fix NavMesh `map_update_id` returning 0 results in errors ([GH-80189](https://github.com/godotengine/godot/pull/80189)).
|
||||||
|
|
||||||
|
#### Networking
|
||||||
|
|
||||||
|
- Prevent crash when accessing `Node` Multiplayer from thread ([GH-79332](https://github.com/godotengine/godot/pull/79332)).
|
||||||
|
- ENet: Better handle truncated socket messages ([GH-79699](https://github.com/godotengine/godot/pull/79699)).
|
||||||
|
- ENet: Properly set transfer flags when using custom channels ([GH-80293](https://github.com/godotengine/godot/pull/80293)).
|
||||||
|
|
||||||
|
#### Porting
|
||||||
|
|
||||||
|
- macOS: Fix uncapped frame rate for windows in the non-active workspaces ([GH-79572](https://github.com/godotengine/godot/pull/79572)).
|
||||||
|
- Web: Fix file permissions for the web platform (affects every Unix-like platform) ([GH-79866](https://github.com/godotengine/godot/pull/79866)).
|
||||||
|
- Web: Fix `JavaScriptBridge.eval()` never returning PackedByteArray ([GH-81015](https://github.com/godotengine/godot/pull/81015)).
|
||||||
|
|
||||||
|
#### Rendering
|
||||||
|
|
||||||
|
- Fix crash when calling `get_video_adapter_*` in a thread ([GH-79528](https://github.com/godotengine/godot/pull/79528)).
|
||||||
|
- Unbind the framebuffer when updating meshes ([GH-79772](https://github.com/godotengine/godot/pull/79772)).
|
||||||
|
- Fix motion vectors being corrupted when using `precision=double` ([GH-80257](https://github.com/godotengine/godot/pull/80257)).
|
||||||
|
- Fix integer underflow when rounding up in VoxelGI ([GH-80356](https://github.com/godotengine/godot/pull/80356)).
|
||||||
|
- Improve handling of motion vectors for multimesh instances ([GH-80414](https://github.com/godotengine/godot/pull/80414)).
|
||||||
|
- Clear SDFGI textures when created ([GH-80889](https://github.com/godotengine/godot/pull/80889)).
|
||||||
|
- Fix integer value for `GL_MAX_UNIFORM_BLOCK_SIZE` overflowing ([GH-80909](https://github.com/godotengine/godot/pull/80909)).
|
||||||
|
- Add half-pixel offset to lightmapper rasterization ([GH-81872](https://github.com/godotengine/godot/pull/81872)).
|
||||||
|
- GLES3: Fix multimesh rendering when using colors or custom data ([GH-79660](https://github.com/godotengine/godot/pull/79660)).
|
||||||
|
- GLES3: Fix memory access error for `MultiMesh` ([GH-80788](https://github.com/godotengine/godot/pull/80788)).
|
||||||
|
- GLES3: Fix `glMapBufferRange` return null when `r_index + last_item_index > max_instance` ([GH-81036](https://github.com/godotengine/godot/pull/81036)).
|
||||||
|
- Vulkan: Fix texture update ([GH-80781](https://github.com/godotengine/godot/pull/80781)).
|
||||||
|
- Vulkan: Fix crash with many Omni/SpotLights, Decals or ReflectionProbes ([GH-80845](https://github.com/godotengine/godot/pull/80845)).
|
||||||
|
|
||||||
|
#### Shaders
|
||||||
|
|
||||||
|
- Fix shader type detection ([GH-79287](https://github.com/godotengine/godot/pull/79287)).
|
||||||
|
- Fix Shader and ShaderInclude resource loading ([GH-80705](https://github.com/godotengine/godot/pull/80705)).
|
||||||
|
- Fix empty shader resource loading ([GH-81300](https://github.com/godotengine/godot/pull/81300)).
|
||||||
|
|
||||||
|
#### XR
|
||||||
|
|
||||||
|
- Fix issue with accessing hand tracking without timing info ([GH-78817](https://github.com/godotengine/godot/pull/78817)).
|
||||||
|
|
||||||
|
|
||||||
|
## [4.1.1] - 2023-07-17
|
||||||
|
|
||||||
|
See the [release announcement](https://godotengine.org/article/maintenance-release-godot-4-1-1) for details.
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
#### Animation
|
||||||
|
|
||||||
|
- Add 3.x compatibility for animation loop mode ([GH-79155](https://github.com/godotengine/godot/pull/79155)).
|
||||||
|
|
||||||
|
#### GUI
|
||||||
|
|
||||||
|
- Add compatibility properties to `TouchScreenButton` ([GH-78940](https://github.com/godotengine/godot/pull/78940)).
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
#### 2D
|
||||||
|
|
||||||
|
- Improve string drawing in the tiledata editor ([GH-78522](https://github.com/godotengine/godot/pull/78522)).
|
||||||
|
- Make sure the shortcut key respects the context in `TileSetAtlasSourceEditor` ([GH-78920](https://github.com/godotengine/godot/pull/78920)).
|
||||||
|
|
||||||
|
#### Buildsystem
|
||||||
|
|
||||||
|
- Linux: Allow unbundling brotli to use system library ([GH-79101](https://github.com/godotengine/godot/pull/79101)).
|
||||||
|
- Linux: Link libsquish directly when unbundling, .pc file unreliable ([GH-79105](https://github.com/godotengine/godot/pull/79105)).
|
||||||
|
|
||||||
|
#### C#/.NET
|
||||||
|
|
||||||
|
- Update the RiderPathLocator to support the JetBrains Toolbox 2.0 ([GH-78832](https://github.com/godotengine/godot/pull/78832)).
|
||||||
|
- Compare symbol names without null flow state ([GH-79094](https://github.com/godotengine/godot/pull/79094)).
|
||||||
|
- Add null check before calling `UnregisterGodotObject` ([GH-79151](https://github.com/godotengine/godot/pull/79151)).
|
||||||
|
|
||||||
|
#### Core
|
||||||
|
|
||||||
|
- Check parameter validity in `Object::set_script` ([GH-46125](https://github.com/godotengine/godot/pull/46125)).
|
||||||
|
- Improve error message for `Node.set_owner` ([GH-79000](https://github.com/godotengine/godot/pull/79000)).
|
||||||
|
|
||||||
|
#### Editor
|
||||||
|
|
||||||
|
- Focus current node after connecting ([GH-54071](https://github.com/godotengine/godot/pull/54071)).
|
||||||
|
- Fix tooltip of enum value without description ([GH-78524](https://github.com/godotengine/godot/pull/78524)).
|
||||||
|
- Use bullet points in shader editor creation dialog ([GH-78631](https://github.com/godotengine/godot/pull/78631)).
|
||||||
|
- Sort project tags before saving ([GH-78775](https://github.com/godotengine/godot/pull/78775)).
|
||||||
|
- Project converter: Use same rendering driver as Project Manager ([GH-78795](https://github.com/godotengine/godot/pull/78795)).
|
||||||
|
- Add tooltip description wrapping in scene tree and plugin settings ([GH-79090](https://github.com/godotengine/godot/pull/79090)).
|
||||||
|
- Improve user-friendliness of project version mismatch messages ([GH-79118](https://github.com/godotengine/godot/pull/79118), [GH-79299](https://github.com/godotengine/godot/pull/79299)).
|
||||||
|
|
||||||
|
#### GUI
|
||||||
|
|
||||||
|
- Ensure that `_drop_physics_mouseover` only happens when necessary ([GH-78078](https://github.com/godotengine/godot/pull/78078)).
|
||||||
|
- Update FileDialog button activity when `file_mode` is changed ([GH-79211](https://github.com/godotengine/godot/pull/79211)).
|
||||||
|
- Hide/show `AcceptDialog`'s button spacer on button visibility changed ([GH-79274](https://github.com/godotengine/godot/pull/79274)).
|
||||||
|
|
||||||
|
#### Porting
|
||||||
|
|
||||||
|
- macOS/iOS: Set MoltenVK logging level based on `--verbose` flag ([GH-79061](https://github.com/godotengine/godot/pull/79061)).
|
||||||
|
- Windows: Flash both the window caption and taskbar button on `request_attention` ([GH-78263](https://github.com/godotengine/godot/pull/78263)).
|
||||||
|
|
||||||
|
#### Rendering
|
||||||
|
|
||||||
|
- Clear specular buffer if sky mode is canvas and screen space effects are used ([GH-78624](https://github.com/godotengine/godot/pull/78624)).
|
||||||
|
- Take eye offset into account for depth in StandardMaterial3D ([GH-79049](https://github.com/godotengine/godot/pull/79049)).
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
#### 2D
|
||||||
|
|
||||||
|
- Fix `Camera2D.rotating` not being converted and reversed properly ([GH-79264](https://github.com/godotengine/godot/pull/79264)).
|
||||||
|
|
||||||
|
#### 3D
|
||||||
|
|
||||||
|
- Fix Camera3D `project_*` methods not accounting for frustum offset ([GH-75806](https://github.com/godotengine/godot/pull/75806)).
|
||||||
|
- Fix 3D viewport grid disappearing on scene tab changes ([GH-78694](https://github.com/godotengine/godot/pull/78694)).
|
||||||
|
|
||||||
|
#### Animation
|
||||||
|
|
||||||
|
- Fix infinite loop state check in `AnimationStateMachine` ([GH-79141](https://github.com/godotengine/godot/pull/79141)).
|
||||||
|
- Fix `tween_property` on `Basis` to properly update its value ([GH-79426](https://github.com/godotengine/godot/pull/79426)).
|
||||||
|
|
||||||
|
#### Buildsystem
|
||||||
|
|
||||||
|
- Linux: Fix build with `use_sowrap=no` and various warnings/errors ([GH-79097](https://github.com/godotengine/godot/pull/79097)).
|
||||||
|
|
||||||
|
#### C#/.NET
|
||||||
|
|
||||||
|
- Fix command line exporting ([GH-79173](https://github.com/godotengine/godot/pull/79173)).
|
||||||
|
|
||||||
|
#### Core
|
||||||
|
|
||||||
|
- Fix zero-sized WorkerThreadPool not processing group tasks ([GH-78845](https://github.com/godotengine/godot/pull/78845)).
|
||||||
|
- Fix `Node::add_sibling` parent check ([GH-78847](https://github.com/godotengine/godot/pull/78847)).
|
||||||
|
- Fix error when non-ASCII characters in resource pack path ([GH-78935](https://github.com/godotengine/godot/pull/78935)).
|
||||||
|
- Fix erroneous `pad_zeros()` warning ([GH-79202](https://github.com/godotengine/godot/pull/79202)).
|
||||||
|
- Fix `PackedScene::get_last_modified_time()` always returns `0` ([GH-79237](https://github.com/godotengine/godot/pull/79237)).
|
||||||
|
|
||||||
|
#### Editor
|
||||||
|
|
||||||
|
- Fix dropping files from `res://` to `res://` ([GH-78914](https://github.com/godotengine/godot/pull/78914)).
|
||||||
|
- Do not change a node unique name to the same name ([GH-78925](https://github.com/godotengine/godot/pull/78925)).
|
||||||
|
- Collapse bottom panel if there is no active tab ([GH-79078](https://github.com/godotengine/godot/pull/79078)).
|
||||||
|
- Fix `ui_cancel` action not closing `FindReplaceBar` ([GH-79079](https://github.com/godotengine/godot/pull/79079)).
|
||||||
|
- Emit `history_changed` on merged UndoRedo actions ([GH-79484](https://github.com/godotengine/godot/pull/79484)).
|
||||||
|
|
||||||
|
#### Export
|
||||||
|
|
||||||
|
- Fix export options of scripted `EditorExportPlugin`s ([GH-79025](https://github.com/godotengine/godot/pull/79025)).
|
||||||
|
|
||||||
|
#### GDScript
|
||||||
|
|
||||||
|
- Fix regression with GDScript enum descriptions now showing up in documentation ([GH-78953](https://github.com/godotengine/godot/pull/78953)).
|
||||||
|
|
||||||
|
#### GUI
|
||||||
|
|
||||||
|
- Fix cursor behavior for multiselect in Tree while holding CTRL ([GH-71024](https://github.com/godotengine/godot/pull/71024)).
|
||||||
|
- Fix disabled slider highlighting ([GH-78776](https://github.com/godotengine/godot/pull/78776)).
|
||||||
|
- Fix invalid minimum size for translated messages in option button ([GH-78835](https://github.com/godotengine/godot/pull/78835)).
|
||||||
|
- Fix incorrect property names in `FontFile::_get_property_list()` ([GH-78907](https://github.com/godotengine/godot/pull/78907)).
|
||||||
|
- Revert "Fix focusloss of non-exclusive `AcceptDialog` with `close_on_escape`" ([GH-79084](https://github.com/godotengine/godot/pull/79084)).
|
||||||
|
|
||||||
|
#### Import
|
||||||
|
|
||||||
|
- Fix property hint class name type string restriction and replace mode ([GH-79139](https://github.com/godotengine/godot/pull/79139)).
|
||||||
|
|
||||||
|
#### Navigation
|
||||||
|
|
||||||
|
- Fix closest possible navigation path position ([GH-79004](https://github.com/godotengine/godot/pull/79004)).
|
||||||
|
|
||||||
|
#### Networking
|
||||||
|
|
||||||
|
- Fix `rpc` calls with binds ([GH-78551](https://github.com/godotengine/godot/pull/78551)).
|
||||||
|
|
||||||
|
#### Particles
|
||||||
|
|
||||||
|
- Initialize particles instance buffer in case it is used before being updated ([GH-78852](https://github.com/godotengine/godot/pull/78852)).
|
||||||
|
- Unify error condition for particles trail lifetime ([GH-79270](https://github.com/godotengine/godot/pull/79270)).
|
||||||
|
|
||||||
|
#### Physics
|
||||||
|
|
||||||
|
- Fix rigid body `contact_monitor` property description ([GH-79250](https://github.com/godotengine/godot/pull/79250)).
|
||||||
|
|
||||||
|
#### Porting
|
||||||
|
|
||||||
|
- Fix formatting of `dlopen` error messages ([GH-78802](https://github.com/godotengine/godot/pull/78802)).
|
||||||
|
- Fix the fallback logic of `OS::shell_show_in_file_manager` ([GH-79087](https://github.com/godotengine/godot/pull/79087)).
|
||||||
|
- Linux/BSD: Avoid freeze when interacting with menus on Wayland ([GH-79143](https://github.com/godotengine/godot/pull/79143)).
|
||||||
|
- Linux/BSD: Fix `move_to_trash` wrongly reporting files as not found ([GH-79284](https://github.com/godotengine/godot/pull/79284)).
|
||||||
|
- Windows: Fix setting initial non-exclusive window mode ([GH-79016](https://github.com/godotengine/godot/pull/79016)).
|
||||||
|
|
||||||
|
#### Rendering
|
||||||
|
|
||||||
|
- Fix threading bug in Vulkan rendering device ([GH-78794](https://github.com/godotengine/godot/pull/78794)).
|
||||||
|
- Fix sanitizers reports about octahedral tangents in RenderingServer ([GH-78902](https://github.com/godotengine/godot/pull/78902)).
|
||||||
|
|
||||||
|
#### Shaders
|
||||||
|
|
||||||
|
- Fix invalid shader compilation when using `hint_normal_roughness_texture` in mobile backend ([GH-78839](https://github.com/godotengine/godot/pull/78839)).
|
||||||
|
- Fix using uint suffix at the hex number declaration in shaders ([GH-78906](https://github.com/godotengine/godot/pull/78906)).
|
||||||
|
- Fix shader language float literal precision truncation ([GH-78972](https://github.com/godotengine/godot/pull/78972)).
|
||||||
|
- Fix comments and indentation in `.gdshaderinc` files ([GH-79158](https://github.com/godotengine/godot/pull/79158)).
|
||||||
|
|
||||||
|
|
||||||
## [4.1] - 2023-07-06
|
## [4.1] - 2023-07-06
|
||||||
|
|
||||||
See the [release announcement](https://godotengine.org/article/godot-4-1-is-here) for details.
|
See the [release announcement](https://godotengine.org/article/godot-4-1-is-here) for details.
|
||||||
|
@ -161,6 +998,7 @@ See the [release announcement](https://godotengine.org/article/godot-4-1-is-here
|
||||||
|
|
||||||
#### Core
|
#### Core
|
||||||
|
|
||||||
|
- The strings returned by `ResourceLoader::get_dependencies()` now include paths in addition to UIDs ([GH-73131](https://github.com/godotengine/godot/pull/73131)).
|
||||||
- Optimize Node children management ([GH-75627](https://github.com/godotengine/godot/pull/75627)).
|
- Optimize Node children management ([GH-75627](https://github.com/godotengine/godot/pull/75627)).
|
||||||
- Deprecate `NOTIFICATION_MOVED_IN_PARENT` for `NOTIFICATION_CHILD_ORDER_CHANGED` ([GH-75701](https://github.com/godotengine/godot/pull/75701)).
|
- Deprecate `NOTIFICATION_MOVED_IN_PARENT` for `NOTIFICATION_CHILD_ORDER_CHANGED` ([GH-75701](https://github.com/godotengine/godot/pull/75701)).
|
||||||
- Optimize `Node::add_child` validation ([GH-75760](https://github.com/godotengine/godot/pull/75760)).
|
- Optimize `Node::add_child` validation ([GH-75760](https://github.com/godotengine/godot/pull/75760)).
|
||||||
|
@ -2876,6 +3714,9 @@ See the [release announcement](https://godotengine.org/article/godot-3-3-has-arr
|
||||||
- Only WebAssembly is supported now, since all browsers supporting WebGL 2.0 also support WebAssembly.
|
- Only WebAssembly is supported now, since all browsers supporting WebGL 2.0 also support WebAssembly.
|
||||||
|
|
||||||
|
|
||||||
|
[4.1.3]: https://github.com/godotengine/godot/compare/4.1.2-stable...4.1.3-stable
|
||||||
|
[4.1.2]: https://github.com/godotengine/godot/compare/4.1.1-stable...4.1.2-stable
|
||||||
|
[4.1.1]: https://github.com/godotengine/godot/compare/4.1-stable...4.1.1-stable
|
||||||
[4.1]: https://github.com/godotengine/godot/compare/4.0-stable...4.1-stable
|
[4.1]: https://github.com/godotengine/godot/compare/4.0-stable...4.1-stable
|
||||||
[4.0]: https://github.com/godotengine/godot/compare/3.2-stable...4.0-stable
|
[4.0]: https://github.com/godotengine/godot/compare/3.2-stable...4.0-stable
|
||||||
[3.5]: https://github.com/godotengine/godot/compare/3.4-stable...3.5-stable
|
[3.5]: https://github.com/godotengine/godot/compare/3.4-stable...3.5-stable
|
||||||
|
|
|
@ -204,7 +204,7 @@ License: OFL-1.1
|
||||||
|
|
||||||
Files: ./thirdparty/freetype/
|
Files: ./thirdparty/freetype/
|
||||||
Comment: The FreeType Project
|
Comment: The FreeType Project
|
||||||
Copyright: 1996-2022, David Turner, Robert Wilhelm, and Werner Lemberg.
|
Copyright: 1996-2023, David Turner, Robert Wilhelm, and Werner Lemberg.
|
||||||
License: FTL
|
License: FTL
|
||||||
|
|
||||||
Files: ./thirdparty/glad/
|
Files: ./thirdparty/glad/
|
||||||
|
@ -263,8 +263,8 @@ License: BSD-3-clause
|
||||||
|
|
||||||
Files: ./thirdparty/libpng/
|
Files: ./thirdparty/libpng/
|
||||||
Comment: libpng
|
Comment: libpng
|
||||||
Copyright: 1995-2019, The PNG Reference Library Authors.
|
Copyright: 1995-2024, The PNG Reference Library Authors.
|
||||||
2018-2019, Cosmin Truta.
|
2018-2024, Cosmin Truta.
|
||||||
2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson.
|
2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson.
|
||||||
1996-1997, Andreas Dilger.
|
1996-1997, Andreas Dilger.
|
||||||
1995-1996, Guy Eric Schalnat, Group 42, Inc.
|
1995-1996, Guy Eric Schalnat, Group 42, Inc.
|
||||||
|
@ -302,7 +302,7 @@ License: CC0-1.0
|
||||||
|
|
||||||
Files: ./thirdparty/miniupnpc/
|
Files: ./thirdparty/miniupnpc/
|
||||||
Comment: MiniUPnP Project
|
Comment: MiniUPnP Project
|
||||||
Copyright: 2005-2022, Thomas Bernard
|
Copyright: 2005-2023, Thomas Bernard
|
||||||
License: BSD-3-clause
|
License: BSD-3-clause
|
||||||
|
|
||||||
Files: ./thirdparty/minizip/
|
Files: ./thirdparty/minizip/
|
||||||
|
@ -409,7 +409,7 @@ License: Apache-2.0
|
||||||
|
|
||||||
Files: ./thirdparty/openxr/
|
Files: ./thirdparty/openxr/
|
||||||
Comment: OpenXR Loader
|
Comment: OpenXR Loader
|
||||||
Copyright: 2020-2022, The Khronos Group Inc.
|
Copyright: 2020-2023, The Khronos Group Inc.
|
||||||
License: Apache-2.0
|
License: Apache-2.0
|
||||||
|
|
||||||
Files: ./thirdparty/pcre2/
|
Files: ./thirdparty/pcre2/
|
||||||
|
@ -487,7 +487,7 @@ License: Expat
|
||||||
|
|
||||||
Files: ./thirdparty/zlib/
|
Files: ./thirdparty/zlib/
|
||||||
Comment: zlib
|
Comment: zlib
|
||||||
Copyright: 1995-2022, Jean-loup Gailly and Mark Adler
|
Copyright: 1995-2024, Jean-loup Gailly and Mark Adler
|
||||||
License: Zlib
|
License: Zlib
|
||||||
|
|
||||||
Files: ./thirdparty/zstd/
|
Files: ./thirdparty/zstd/
|
||||||
|
|
27
SConstruct
27
SConstruct
|
@ -152,7 +152,7 @@ env_base["x86_libtheora_opt_gcc"] = False
|
||||||
env_base["x86_libtheora_opt_vc"] = False
|
env_base["x86_libtheora_opt_vc"] = False
|
||||||
|
|
||||||
# avoid issues when building with different versions of python out of the same directory
|
# avoid issues when building with different versions of python out of the same directory
|
||||||
env_base.SConsignFile(".sconsign{0}.dblite".format(pickle.HIGHEST_PROTOCOL))
|
env_base.SConsignFile(File("#.sconsign{0}.dblite".format(pickle.HIGHEST_PROTOCOL)).abspath)
|
||||||
|
|
||||||
# Build options
|
# Build options
|
||||||
|
|
||||||
|
@ -193,6 +193,7 @@ opts.Add(BoolVariable("vulkan", "Enable the vulkan rendering driver", True))
|
||||||
opts.Add(BoolVariable("opengl3", "Enable the OpenGL/GLES3 rendering driver", True))
|
opts.Add(BoolVariable("opengl3", "Enable the OpenGL/GLES3 rendering driver", True))
|
||||||
opts.Add(BoolVariable("openxr", "Enable the OpenXR driver", True))
|
opts.Add(BoolVariable("openxr", "Enable the OpenXR driver", True))
|
||||||
opts.Add(BoolVariable("use_volk", "Use the volk library to load the Vulkan loader dynamically", True))
|
opts.Add(BoolVariable("use_volk", "Use the volk library to load the Vulkan loader dynamically", True))
|
||||||
|
opts.Add(BoolVariable("disable_exceptions", "Force disabling exception handling code", False))
|
||||||
opts.Add("custom_modules", "A list of comma-separated directory paths containing custom modules to build.", "")
|
opts.Add("custom_modules", "A list of comma-separated directory paths containing custom modules to build.", "")
|
||||||
opts.Add(BoolVariable("custom_modules_recursive", "Detect custom modules recursively for each specified path.", True))
|
opts.Add(BoolVariable("custom_modules_recursive", "Detect custom modules recursively for each specified path.", True))
|
||||||
|
|
||||||
|
@ -222,6 +223,7 @@ opts.Add(BoolVariable("use_precise_math_checks", "Math checks use very precise e
|
||||||
opts.Add(BoolVariable("scu_build", "Use single compilation unit build", False))
|
opts.Add(BoolVariable("scu_build", "Use single compilation unit build", False))
|
||||||
|
|
||||||
# Thirdparty libraries
|
# Thirdparty libraries
|
||||||
|
opts.Add(BoolVariable("builtin_brotli", "Use the built-in Brotli library", True))
|
||||||
opts.Add(BoolVariable("builtin_certs", "Use the built-in SSL certificates bundles", True))
|
opts.Add(BoolVariable("builtin_certs", "Use the built-in SSL certificates bundles", True))
|
||||||
opts.Add(BoolVariable("builtin_embree", "Use the built-in Embree library", True))
|
opts.Add(BoolVariable("builtin_embree", "Use the built-in Embree library", True))
|
||||||
opts.Add(BoolVariable("builtin_enet", "Use the built-in ENet library", True))
|
opts.Add(BoolVariable("builtin_enet", "Use the built-in ENet library", True))
|
||||||
|
@ -239,6 +241,7 @@ opts.Add(BoolVariable("builtin_libwebp", "Use the built-in libwebp library", Tru
|
||||||
opts.Add(BoolVariable("builtin_wslay", "Use the built-in wslay library", True))
|
opts.Add(BoolVariable("builtin_wslay", "Use the built-in wslay library", True))
|
||||||
opts.Add(BoolVariable("builtin_mbedtls", "Use the built-in mbedTLS library", True))
|
opts.Add(BoolVariable("builtin_mbedtls", "Use the built-in mbedTLS library", True))
|
||||||
opts.Add(BoolVariable("builtin_miniupnpc", "Use the built-in miniupnpc library", True))
|
opts.Add(BoolVariable("builtin_miniupnpc", "Use the built-in miniupnpc library", True))
|
||||||
|
opts.Add(BoolVariable("builtin_openxr", "Use the built-in OpenXR library", True))
|
||||||
opts.Add(BoolVariable("builtin_pcre2", "Use the built-in PCRE2 library", True))
|
opts.Add(BoolVariable("builtin_pcre2", "Use the built-in PCRE2 library", True))
|
||||||
opts.Add(BoolVariable("builtin_pcre2_with_jit", "Use JIT compiler for the built-in PCRE2 library", True))
|
opts.Add(BoolVariable("builtin_pcre2_with_jit", "Use JIT compiler for the built-in PCRE2 library", True))
|
||||||
opts.Add(BoolVariable("builtin_recastnavigation", "Use the built-in Recast navigation library", True))
|
opts.Add(BoolVariable("builtin_recastnavigation", "Use the built-in Recast navigation library", True))
|
||||||
|
@ -296,21 +299,21 @@ else:
|
||||||
if selected_platform in ["macos", "osx"]:
|
if selected_platform in ["macos", "osx"]:
|
||||||
if selected_platform == "osx":
|
if selected_platform == "osx":
|
||||||
# Deprecated alias kept for compatibility.
|
# Deprecated alias kept for compatibility.
|
||||||
print('Platform "osx" has been renamed to "macos" in Godot 4.0. Building for platform "macos".')
|
print('Platform "osx" has been renamed to "macos" in Godot 4. Building for platform "macos".')
|
||||||
# Alias for convenience.
|
# Alias for convenience.
|
||||||
selected_platform = "macos"
|
selected_platform = "macos"
|
||||||
|
|
||||||
if selected_platform in ["ios", "iphone"]:
|
if selected_platform in ["ios", "iphone"]:
|
||||||
if selected_platform == "iphone":
|
if selected_platform == "iphone":
|
||||||
# Deprecated alias kept for compatibility.
|
# Deprecated alias kept for compatibility.
|
||||||
print('Platform "iphone" has been renamed to "ios" in Godot 4.0. Building for platform "ios".')
|
print('Platform "iphone" has been renamed to "ios" in Godot 4. Building for platform "ios".')
|
||||||
# Alias for convenience.
|
# Alias for convenience.
|
||||||
selected_platform = "ios"
|
selected_platform = "ios"
|
||||||
|
|
||||||
if selected_platform in ["linux", "bsd", "x11"]:
|
if selected_platform in ["linux", "bsd", "x11"]:
|
||||||
if selected_platform == "x11":
|
if selected_platform == "x11":
|
||||||
# Deprecated alias kept for compatibility.
|
# Deprecated alias kept for compatibility.
|
||||||
print('Platform "x11" has been renamed to "linuxbsd" in Godot 4.0. Building for platform "linuxbsd".')
|
print('Platform "x11" has been renamed to "linuxbsd" in Godot 4. Building for platform "linuxbsd".')
|
||||||
# Alias for convenience.
|
# Alias for convenience.
|
||||||
selected_platform = "linuxbsd"
|
selected_platform = "linuxbsd"
|
||||||
|
|
||||||
|
@ -698,6 +701,16 @@ if selected_platform in platform_list:
|
||||||
)
|
)
|
||||||
Exit(255)
|
Exit(255)
|
||||||
|
|
||||||
|
# Disable exception handling. Godot doesn't use exceptions anywhere, and this
|
||||||
|
# saves around 20% of binary size and very significant build time (GH-80513).
|
||||||
|
if env["disable_exceptions"]:
|
||||||
|
if env.msvc:
|
||||||
|
env.Append(CPPDEFINES=[("_HAS_EXCEPTIONS", 0)])
|
||||||
|
else:
|
||||||
|
env.Append(CXXFLAGS=["-fno-exceptions"])
|
||||||
|
elif env.msvc:
|
||||||
|
env.Append(CXXFLAGS=["/EHsc"])
|
||||||
|
|
||||||
# Configure compiler warnings
|
# Configure compiler warnings
|
||||||
if env.msvc: # MSVC
|
if env.msvc: # MSVC
|
||||||
if env["warnings"] == "no":
|
if env["warnings"] == "no":
|
||||||
|
@ -727,11 +740,9 @@ if selected_platform in platform_list:
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
# Set exception handling model to avoid warnings caused by Windows system headers.
|
|
||||||
env.Append(CCFLAGS=["/EHsc"])
|
|
||||||
|
|
||||||
if env["werror"]:
|
if env["werror"]:
|
||||||
env.Append(CCFLAGS=["/WX"])
|
env.Append(CCFLAGS=["/WX"])
|
||||||
|
env.Append(LINKFLAGS=["/WX"])
|
||||||
else: # GCC, Clang
|
else: # GCC, Clang
|
||||||
common_warnings = []
|
common_warnings = []
|
||||||
|
|
||||||
|
@ -957,7 +968,7 @@ if selected_platform in platform_list:
|
||||||
print("Error: The `vsproj` option is only usable on Windows with Visual Studio.")
|
print("Error: The `vsproj` option is only usable on Windows with Visual Studio.")
|
||||||
Exit(255)
|
Exit(255)
|
||||||
env["CPPPATH"] = [Dir(path) for path in env["CPPPATH"]]
|
env["CPPPATH"] = [Dir(path) for path in env["CPPPATH"]]
|
||||||
methods.generate_vs_project(env, GetOption("num_jobs"), env["vsproj_name"])
|
methods.generate_vs_project(env, ARGUMENTS, env["vsproj_name"])
|
||||||
methods.generate_cpp_hint_file("cpp.hint")
|
methods.generate_cpp_hint_file("cpp.hint")
|
||||||
|
|
||||||
# Check for the existence of headers
|
# Check for the existence of headers
|
||||||
|
|
|
@ -65,7 +65,7 @@ thirdparty_misc_sources = [thirdparty_misc_dir + file for file in thirdparty_mis
|
||||||
env_thirdparty.add_source_files(thirdparty_obj, thirdparty_misc_sources)
|
env_thirdparty.add_source_files(thirdparty_obj, thirdparty_misc_sources)
|
||||||
|
|
||||||
# Brotli
|
# Brotli
|
||||||
if env["brotli"]:
|
if env["brotli"] and env["builtin_brotli"]:
|
||||||
thirdparty_brotli_dir = "#thirdparty/brotli/"
|
thirdparty_brotli_dir = "#thirdparty/brotli/"
|
||||||
thirdparty_brotli_sources = [
|
thirdparty_brotli_sources = [
|
||||||
"common/constants.c",
|
"common/constants.c",
|
||||||
|
@ -97,7 +97,6 @@ if env["builtin_zlib"]:
|
||||||
"compress.c",
|
"compress.c",
|
||||||
"crc32.c",
|
"crc32.c",
|
||||||
"deflate.c",
|
"deflate.c",
|
||||||
"infback.c",
|
|
||||||
"inffast.c",
|
"inffast.c",
|
||||||
"inflate.c",
|
"inflate.c",
|
||||||
"inftrees.c",
|
"inftrees.c",
|
||||||
|
|
|
@ -819,7 +819,7 @@ Error ProjectSettings::_save_settings_binary(const String &p_file, const RBMap<S
|
||||||
|
|
||||||
if (!p_custom_features.is_empty()) {
|
if (!p_custom_features.is_empty()) {
|
||||||
file->store_32(count + 1);
|
file->store_32(count + 1);
|
||||||
//store how many properties are saved, add one for custom featuers, which must always go first
|
// Store how many properties are saved, add one for custom features, which must always go first.
|
||||||
String key = CoreStringNames::get_singleton()->_custom_features;
|
String key = CoreStringNames::get_singleton()->_custom_features;
|
||||||
file->store_pascal_string(key);
|
file->store_pascal_string(key);
|
||||||
|
|
||||||
|
@ -1344,7 +1344,7 @@ ProjectSettings::ProjectSettings() {
|
||||||
GLOBAL_DEF_RST(PropertyInfo(Variant::INT, "rendering/occlusion_culling/bvh_build_quality", PROPERTY_HINT_ENUM, "Low,Medium,High"), 2);
|
GLOBAL_DEF_RST(PropertyInfo(Variant::INT, "rendering/occlusion_culling/bvh_build_quality", PROPERTY_HINT_ENUM, "Low,Medium,High"), 2);
|
||||||
GLOBAL_DEF(PropertyInfo(Variant::INT, "memory/limits/multithreaded_server/rid_pool_prealloc", PROPERTY_HINT_RANGE, "0,500,1"), 60); // No negative and limit to 500 due to crashes.
|
GLOBAL_DEF(PropertyInfo(Variant::INT, "memory/limits/multithreaded_server/rid_pool_prealloc", PROPERTY_HINT_RANGE, "0,500,1"), 60); // No negative and limit to 500 due to crashes.
|
||||||
GLOBAL_DEF_RST("internationalization/rendering/force_right_to_left_layout_direction", false);
|
GLOBAL_DEF_RST("internationalization/rendering/force_right_to_left_layout_direction", false);
|
||||||
GLOBAL_DEF_BASIC(PropertyInfo(Variant::INT, "internationalization/rendering/root_node_layout_direction", PROPERTY_HINT_RANGE, "Based on Locale,Left-to-Right,Right-to-Left"), 0);
|
GLOBAL_DEF_BASIC(PropertyInfo(Variant::INT, "internationalization/rendering/root_node_layout_direction", PROPERTY_HINT_ENUM, "Based on Locale,Left-to-Right,Right-to-Left"), 0);
|
||||||
|
|
||||||
GLOBAL_DEF(PropertyInfo(Variant::INT, "gui/timers/incremental_search_max_interval_msec", PROPERTY_HINT_RANGE, "0,10000,1,or_greater"), 2000);
|
GLOBAL_DEF(PropertyInfo(Variant::INT, "gui/timers/incremental_search_max_interval_msec", PROPERTY_HINT_RANGE, "0,10000,1,or_greater"), 2000);
|
||||||
|
|
||||||
|
|
|
@ -420,6 +420,10 @@ void register_global_constants() {
|
||||||
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, LAUNCHD);
|
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, LAUNCHD);
|
||||||
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, LAUNCHE);
|
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, LAUNCHE);
|
||||||
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, LAUNCHF);
|
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, LAUNCHF);
|
||||||
|
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, GLOBE);
|
||||||
|
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, KEYBOARD);
|
||||||
|
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, JIS_EISU);
|
||||||
|
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, JIS_KANA);
|
||||||
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, UNKNOWN);
|
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, UNKNOWN);
|
||||||
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, SPACE);
|
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, SPACE);
|
||||||
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, EXCLAM);
|
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, EXCLAM);
|
||||||
|
@ -492,10 +496,6 @@ void register_global_constants() {
|
||||||
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, ASCIITILDE);
|
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, ASCIITILDE);
|
||||||
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, YEN);
|
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, YEN);
|
||||||
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, SECTION);
|
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, SECTION);
|
||||||
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, GLOBE);
|
|
||||||
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, KEYBOARD);
|
|
||||||
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, JIS_EISU);
|
|
||||||
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, JIS_KANA);
|
|
||||||
|
|
||||||
BIND_CORE_BITFIELD_CLASS_FLAG_CUSTOM(KeyModifierMask, KEY_CODE_MASK, CODE_MASK);
|
BIND_CORE_BITFIELD_CLASS_FLAG_CUSTOM(KeyModifierMask, KEY_CODE_MASK, CODE_MASK);
|
||||||
BIND_CORE_BITFIELD_CLASS_FLAG_CUSTOM(KeyModifierMask, KEY_MODIFIER_MASK, MODIFIER_MASK);
|
BIND_CORE_BITFIELD_CLASS_FLAG_CUSTOM(KeyModifierMask, KEY_MODIFIER_MASK, MODIFIER_MASK);
|
||||||
|
|
|
@ -730,6 +730,16 @@ void _err_flush_stdout();
|
||||||
} else \
|
} else \
|
||||||
((void)0)
|
((void)0)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Warns about `m_msg` only when verbose mode is enabled.
|
||||||
|
*/
|
||||||
|
#define WARN_VERBOSE(m_msg) \
|
||||||
|
{ \
|
||||||
|
if (is_print_verbose_enabled()) { \
|
||||||
|
WARN_PRINT(m_msg); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
// Print deprecated warning message macros.
|
// Print deprecated warning message macros.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -603,12 +603,13 @@ Ref<Resource> GDExtensionResourceLoader::load(const String &p_path, const String
|
||||||
}
|
}
|
||||||
|
|
||||||
bool compatible = true;
|
bool compatible = true;
|
||||||
if (VERSION_MAJOR < compatibility_minimum[0]) {
|
// Check version lexicographically.
|
||||||
compatible = false;
|
if (VERSION_MAJOR != compatibility_minimum[0]) {
|
||||||
} else if (VERSION_MINOR < compatibility_minimum[1]) {
|
compatible = VERSION_MAJOR > compatibility_minimum[0];
|
||||||
compatible = false;
|
} else if (VERSION_MINOR != compatibility_minimum[1]) {
|
||||||
} else if (VERSION_PATCH < compatibility_minimum[2]) {
|
compatible = VERSION_MINOR > compatibility_minimum[1];
|
||||||
compatible = false;
|
} else {
|
||||||
|
compatible = VERSION_PATCH >= compatibility_minimum[2];
|
||||||
}
|
}
|
||||||
if (!compatible) {
|
if (!compatible) {
|
||||||
if (r_error) {
|
if (r_error) {
|
||||||
|
|
|
@ -253,7 +253,7 @@ static void gdextension_variant_iter_get(GDExtensionConstVariantPtr p_self, GDEx
|
||||||
Variant *iter = (Variant *)r_iter;
|
Variant *iter = (Variant *)r_iter;
|
||||||
|
|
||||||
bool valid;
|
bool valid;
|
||||||
memnew_placement(r_ret, Variant(self->iter_next(*iter, valid)));
|
memnew_placement(r_ret, Variant(self->iter_get(*iter, valid)));
|
||||||
*r_valid = valid;
|
*r_valid = valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -113,6 +113,7 @@ void Input::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("get_joy_axis", "device", "axis"), &Input::get_joy_axis);
|
ClassDB::bind_method(D_METHOD("get_joy_axis", "device", "axis"), &Input::get_joy_axis);
|
||||||
ClassDB::bind_method(D_METHOD("get_joy_name", "device"), &Input::get_joy_name);
|
ClassDB::bind_method(D_METHOD("get_joy_name", "device"), &Input::get_joy_name);
|
||||||
ClassDB::bind_method(D_METHOD("get_joy_guid", "device"), &Input::get_joy_guid);
|
ClassDB::bind_method(D_METHOD("get_joy_guid", "device"), &Input::get_joy_guid);
|
||||||
|
ClassDB::bind_method(D_METHOD("should_ignore_device", "vendor_id", "product_id"), &Input::should_ignore_device);
|
||||||
ClassDB::bind_method(D_METHOD("get_connected_joypads"), &Input::get_connected_joypads);
|
ClassDB::bind_method(D_METHOD("get_connected_joypads"), &Input::get_connected_joypads);
|
||||||
ClassDB::bind_method(D_METHOD("get_joy_vibration_strength", "device"), &Input::get_joy_vibration_strength);
|
ClassDB::bind_method(D_METHOD("get_joy_vibration_strength", "device"), &Input::get_joy_vibration_strength);
|
||||||
ClassDB::bind_method(D_METHOD("get_joy_vibration_duration", "device"), &Input::get_joy_vibration_duration);
|
ClassDB::bind_method(D_METHOD("get_joy_vibration_duration", "device"), &Input::get_joy_vibration_duration);
|
||||||
|
@ -472,7 +473,8 @@ void Input::joy_connection_changed(int p_idx, bool p_connected, String p_name, S
|
||||||
}
|
}
|
||||||
joy_names[p_idx] = js;
|
joy_names[p_idx] = js;
|
||||||
|
|
||||||
emit_signal(SNAME("joy_connection_changed"), p_idx, p_connected);
|
// Ensure this signal is emitted on the main thread, as some platforms (e.g. Linux) call this from a different thread.
|
||||||
|
call_deferred("emit_signal", SNAME("joy_connection_changed"), p_idx, p_connected);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3 Input::get_gravity() const {
|
Vector3 Input::get_gravity() const {
|
||||||
|
@ -1058,7 +1060,8 @@ void Input::joy_axis(int p_device, JoyAxis p_axis, float p_value) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
JoyEvent map = _get_mapped_axis_event(map_db[joy.mapping], p_axis, p_value);
|
JoyAxisRange range;
|
||||||
|
JoyEvent map = _get_mapped_axis_event(map_db[joy.mapping], p_axis, p_value, range);
|
||||||
|
|
||||||
if (map.type == TYPE_BUTTON) {
|
if (map.type == TYPE_BUTTON) {
|
||||||
bool pressed = map.value > 0.5;
|
bool pressed = map.value > 0.5;
|
||||||
|
@ -1098,7 +1101,7 @@ void Input::joy_axis(int p_device, JoyAxis p_axis, float p_value) {
|
||||||
if (map.type == TYPE_AXIS) {
|
if (map.type == TYPE_AXIS) {
|
||||||
JoyAxis axis = JoyAxis(map.index);
|
JoyAxis axis = JoyAxis(map.index);
|
||||||
float value = map.value;
|
float value = map.value;
|
||||||
if (axis == JoyAxis::TRIGGER_LEFT || axis == JoyAxis::TRIGGER_RIGHT) {
|
if (range == FULL_AXIS && (axis == JoyAxis::TRIGGER_LEFT || axis == JoyAxis::TRIGGER_RIGHT)) {
|
||||||
// Convert to a value between 0.0f and 1.0f.
|
// Convert to a value between 0.0f and 1.0f.
|
||||||
value = 0.5f + value / 2.0f;
|
value = 0.5f + value / 2.0f;
|
||||||
}
|
}
|
||||||
|
@ -1204,7 +1207,7 @@ Input::JoyEvent Input::_get_mapped_button_event(const JoyDeviceMapping &mapping,
|
||||||
return event;
|
return event;
|
||||||
}
|
}
|
||||||
|
|
||||||
Input::JoyEvent Input::_get_mapped_axis_event(const JoyDeviceMapping &mapping, JoyAxis p_axis, float p_value) {
|
Input::JoyEvent Input::_get_mapped_axis_event(const JoyDeviceMapping &mapping, JoyAxis p_axis, float p_value, JoyAxisRange &r_range) {
|
||||||
JoyEvent event;
|
JoyEvent event;
|
||||||
|
|
||||||
for (int i = 0; i < mapping.bindings.size(); i++) {
|
for (int i = 0; i < mapping.bindings.size(); i++) {
|
||||||
|
@ -1250,6 +1253,7 @@ Input::JoyEvent Input::_get_mapped_axis_event(const JoyDeviceMapping &mapping, J
|
||||||
case TYPE_AXIS:
|
case TYPE_AXIS:
|
||||||
event.index = (int)binding.output.axis.axis;
|
event.index = (int)binding.output.axis.axis;
|
||||||
event.value = value;
|
event.value = value;
|
||||||
|
r_range = binding.output.axis.range;
|
||||||
if (binding.output.axis.range != binding.input.axis.range) {
|
if (binding.output.axis.range != binding.input.axis.range) {
|
||||||
switch (binding.output.axis.range) {
|
switch (binding.output.axis.range) {
|
||||||
case POSITIVE_HALF_AXIS:
|
case POSITIVE_HALF_AXIS:
|
||||||
|
@ -1498,6 +1502,11 @@ String Input::get_joy_guid(int p_device) const {
|
||||||
return joy_names[p_device].uid;
|
return joy_names[p_device].uid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Input::should_ignore_device(int p_vendor_id, int p_product_id) const {
|
||||||
|
uint32_t full_id = (((uint32_t)p_vendor_id) << 16) | ((uint16_t)p_product_id);
|
||||||
|
return ignored_device_ids.has(full_id);
|
||||||
|
}
|
||||||
|
|
||||||
TypedArray<int> Input::get_connected_joypads() {
|
TypedArray<int> Input::get_connected_joypads() {
|
||||||
TypedArray<int> ret;
|
TypedArray<int> ret;
|
||||||
HashMap<int, Joypad>::Iterator elem = joy_names.begin();
|
HashMap<int, Joypad>::Iterator elem = joy_names.begin();
|
||||||
|
@ -1542,6 +1551,27 @@ Input::Input() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String env_ignore_devices = OS::get_singleton()->get_environment("SDL_GAMECONTROLLER_IGNORE_DEVICES");
|
||||||
|
if (!env_ignore_devices.is_empty()) {
|
||||||
|
Vector<String> entries = env_ignore_devices.split(",");
|
||||||
|
for (int i = 0; i < entries.size(); i++) {
|
||||||
|
Vector<String> vid_pid = entries[i].split("/");
|
||||||
|
|
||||||
|
if (vid_pid.size() < 2) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
print_verbose(vformat("Device Ignored -- Vendor: %s Product: %s", vid_pid[0], vid_pid[1]));
|
||||||
|
const uint16_t vid_unswapped = vid_pid[0].hex_to_int();
|
||||||
|
const uint16_t pid_unswapped = vid_pid[1].hex_to_int();
|
||||||
|
const uint16_t vid = BSWAP16(vid_unswapped);
|
||||||
|
const uint16_t pid = BSWAP16(pid_unswapped);
|
||||||
|
|
||||||
|
uint32_t full_id = (((uint32_t)vid) << 16) | ((uint16_t)pid);
|
||||||
|
ignored_device_ids.insert(full_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
legacy_just_pressed_behavior = GLOBAL_DEF("input_devices/compatibility/legacy_just_pressed_behavior", false);
|
legacy_just_pressed_behavior = GLOBAL_DEF("input_devices/compatibility/legacy_just_pressed_behavior", false);
|
||||||
if (Engine::get_singleton()->is_editor_hint()) {
|
if (Engine::get_singleton()->is_editor_hint()) {
|
||||||
// Always use standard behavior in the editor.
|
// Always use standard behavior in the editor.
|
||||||
|
|
|
@ -154,6 +154,9 @@ private:
|
||||||
VelocityTrack mouse_velocity_track;
|
VelocityTrack mouse_velocity_track;
|
||||||
HashMap<int, VelocityTrack> touch_velocity_track;
|
HashMap<int, VelocityTrack> touch_velocity_track;
|
||||||
HashMap<int, Joypad> joy_names;
|
HashMap<int, Joypad> joy_names;
|
||||||
|
|
||||||
|
HashSet<uint32_t> ignored_device_ids;
|
||||||
|
|
||||||
int fallback_mapping = -1;
|
int fallback_mapping = -1;
|
||||||
|
|
||||||
CursorShape default_shape = CURSOR_ARROW;
|
CursorShape default_shape = CURSOR_ARROW;
|
||||||
|
@ -216,7 +219,7 @@ private:
|
||||||
Vector<JoyDeviceMapping> map_db;
|
Vector<JoyDeviceMapping> map_db;
|
||||||
|
|
||||||
JoyEvent _get_mapped_button_event(const JoyDeviceMapping &mapping, JoyButton p_button);
|
JoyEvent _get_mapped_button_event(const JoyDeviceMapping &mapping, JoyButton p_button);
|
||||||
JoyEvent _get_mapped_axis_event(const JoyDeviceMapping &mapping, JoyAxis p_axis, float p_value);
|
JoyEvent _get_mapped_axis_event(const JoyDeviceMapping &mapping, JoyAxis p_axis, float p_value, JoyAxisRange &r_range);
|
||||||
void _get_mapped_hat_events(const JoyDeviceMapping &mapping, HatDir p_hat, JoyEvent r_events[(size_t)HatDir::MAX]);
|
void _get_mapped_hat_events(const JoyDeviceMapping &mapping, HatDir p_hat, JoyEvent r_events[(size_t)HatDir::MAX]);
|
||||||
JoyButton _get_output_button(String output);
|
JoyButton _get_output_button(String output);
|
||||||
JoyAxis _get_output_axis(String output);
|
JoyAxis _get_output_axis(String output);
|
||||||
|
@ -328,6 +331,7 @@ public:
|
||||||
|
|
||||||
bool is_joy_known(int p_device);
|
bool is_joy_known(int p_device);
|
||||||
String get_joy_guid(int p_device) const;
|
String get_joy_guid(int p_device) const;
|
||||||
|
bool should_ignore_device(int p_vendor_id, int p_product_id) const;
|
||||||
void set_fallback_mapping(String p_guid);
|
void set_fallback_mapping(String p_guid);
|
||||||
|
|
||||||
void flush_buffered_events();
|
void flush_buffered_events();
|
||||||
|
|
|
@ -1192,7 +1192,7 @@ static const char *_joy_button_descriptions[(size_t)JoyButton::SDL_MAX] = {
|
||||||
TTRC("Top Action, Sony Triangle, Xbox Y, Nintendo X"),
|
TTRC("Top Action, Sony Triangle, Xbox Y, Nintendo X"),
|
||||||
TTRC("Back, Sony Select, Xbox Back, Nintendo -"),
|
TTRC("Back, Sony Select, Xbox Back, Nintendo -"),
|
||||||
TTRC("Guide, Sony PS, Xbox Home"),
|
TTRC("Guide, Sony PS, Xbox Home"),
|
||||||
TTRC("Start, Nintendo +"),
|
TTRC("Start, Xbox Menu, Nintendo +"),
|
||||||
TTRC("Left Stick, Sony L3, Xbox L/LS"),
|
TTRC("Left Stick, Sony L3, Xbox L/LS"),
|
||||||
TTRC("Right Stick, Sony R3, Xbox R/RS"),
|
TTRC("Right Stick, Sony R3, Xbox R/RS"),
|
||||||
TTRC("Left Shoulder, Sony L1, Xbox LB"),
|
TTRC("Left Shoulder, Sony L1, Xbox LB"),
|
||||||
|
|
|
@ -35,13 +35,13 @@
|
||||||
|
|
||||||
#include "thirdparty/misc/fastlz.h"
|
#include "thirdparty/misc/fastlz.h"
|
||||||
|
|
||||||
#ifdef BROTLI_ENABLED
|
|
||||||
#include "thirdparty/brotli/include/brotli/decode.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
#include <zstd.h>
|
#include <zstd.h>
|
||||||
|
|
||||||
|
#ifdef BROTLI_ENABLED
|
||||||
|
#include <brotli/decode.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
int Compression::compress(uint8_t *p_dst, const uint8_t *p_src, int p_src_size, Mode p_mode) {
|
int Compression::compress(uint8_t *p_dst, const uint8_t *p_src, int p_src_size, Mode p_mode) {
|
||||||
switch (p_mode) {
|
switch (p_mode) {
|
||||||
case MODE_BROTLI: {
|
case MODE_BROTLI: {
|
||||||
|
|
|
@ -47,7 +47,7 @@ static void *godot_open(voidpf opaque, const char *p_fname, int mode) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<FileAccess> f = FileAccess::open(p_fname, FileAccess::READ);
|
Ref<FileAccess> f = FileAccess::open(String::utf8(p_fname), FileAccess::READ);
|
||||||
ERR_FAIL_COND_V(f.is_null(), nullptr);
|
ERR_FAIL_COND_V(f.is_null(), nullptr);
|
||||||
|
|
||||||
ZipData *zd = memnew(ZipData);
|
ZipData *zd = memnew(ZipData);
|
||||||
|
|
|
@ -509,6 +509,7 @@ static void _convert(int p_width, int p_height, const uint8_t *p_src, uint8_t *p
|
||||||
}
|
}
|
||||||
|
|
||||||
void Image::convert(Format p_new_format) {
|
void Image::convert(Format p_new_format) {
|
||||||
|
ERR_FAIL_INDEX_MSG(p_new_format, FORMAT_MAX, "The Image format specified (" + itos(p_new_format) + ") is out of range. See Image's Format enum.");
|
||||||
if (data.size() == 0) {
|
if (data.size() == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1619,9 +1619,11 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
|
||||||
encode_uint32(datalen, buf);
|
encode_uint32(datalen, buf);
|
||||||
buf += 4;
|
buf += 4;
|
||||||
const uint8_t *r = data.ptr();
|
const uint8_t *r = data.ptr();
|
||||||
|
if (r) {
|
||||||
memcpy(buf, &r[0], datalen * datasize);
|
memcpy(buf, &r[0], datalen * datasize);
|
||||||
buf += datalen * datasize;
|
buf += datalen * datasize;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
r_len += 4 + datalen * datasize;
|
r_len += 4 + datalen * datasize;
|
||||||
while (r_len % 4) {
|
while (r_len % 4) {
|
||||||
|
|
|
@ -205,7 +205,7 @@ Error PCKPacker::flush(bool p_verbose) {
|
||||||
|
|
||||||
int header_padding = _get_pad(alignment, file->get_position());
|
int header_padding = _get_pad(alignment, file->get_position());
|
||||||
for (int i = 0; i < header_padding; i++) {
|
for (int i = 0; i < header_padding; i++) {
|
||||||
file->store_8(Math::rand() % 256);
|
file->store_8(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t file_base = file->get_position();
|
int64_t file_base = file->get_position();
|
||||||
|
@ -244,7 +244,7 @@ Error PCKPacker::flush(bool p_verbose) {
|
||||||
|
|
||||||
int pad = _get_pad(alignment, file->get_position());
|
int pad = _get_pad(alignment, file->get_position());
|
||||||
for (int j = 0; j < pad; j++) {
|
for (int j = 0; j < pad; j++) {
|
||||||
file->store_8(Math::rand() % 256);
|
file->store_8(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
count += 1;
|
count += 1;
|
||||||
|
|
|
@ -270,7 +270,7 @@ Error RemoteFilesystemClient::_synchronize_with_server(const String &p_host, int
|
||||||
String file = temp_file_cache[i].path;
|
String file = temp_file_cache[i].path;
|
||||||
|
|
||||||
if (temp_file_cache[i].server_modified_time == 0 || server_disconnected) {
|
if (temp_file_cache[i].server_modified_time == 0 || server_disconnected) {
|
||||||
// File was removed, or server disconnected before tranferring it. Since it's no longer valid, remove anyway.
|
// File was removed, or server disconnected before transferring it. Since it's no longer valid, remove anyway.
|
||||||
_remove_file(file);
|
_remove_file(file);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,8 +44,8 @@ protected:
|
||||||
String _get_cache_path() { return cache_path; }
|
String _get_cache_path() { return cache_path; }
|
||||||
struct FileCache {
|
struct FileCache {
|
||||||
String path; // Local path (as in "folder/to/file.png")
|
String path; // Local path (as in "folder/to/file.png")
|
||||||
uint64_t server_modified_time; // MD5 checksum.
|
uint64_t server_modified_time = 0; // MD5 checksum.
|
||||||
uint64_t modified_time;
|
uint64_t modified_time = 0;
|
||||||
};
|
};
|
||||||
virtual bool _is_configured() { return !cache_path.is_empty(); }
|
virtual bool _is_configured() { return !cache_path.is_empty(); }
|
||||||
// Can be re-implemented per platform. If so, feel free to ignore get_cache_path()
|
// Can be re-implemented per platform. If so, feel free to ignore get_cache_path()
|
||||||
|
|
|
@ -226,6 +226,7 @@ void Resource::configure_for_local_scene(Node *p_for_scene, HashMap<Ref<Resource
|
||||||
List<PropertyInfo> plist;
|
List<PropertyInfo> plist;
|
||||||
get_property_list(&plist);
|
get_property_list(&plist);
|
||||||
|
|
||||||
|
reset_local_to_scene();
|
||||||
local_scene = p_for_scene;
|
local_scene = p_for_scene;
|
||||||
|
|
||||||
for (const PropertyInfo &E : plist) {
|
for (const PropertyInfo &E : plist) {
|
||||||
|
@ -386,6 +387,10 @@ void Resource::setup_local_to_scene() {
|
||||||
emit_signal(SNAME("setup_local_to_scene_requested"));
|
emit_signal(SNAME("setup_local_to_scene_requested"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Resource::reset_local_to_scene() {
|
||||||
|
// Restores the state as if setup_local_to_scene() hadn't been called.
|
||||||
|
}
|
||||||
|
|
||||||
Node *(*Resource::_get_local_scene_func)() = nullptr;
|
Node *(*Resource::_get_local_scene_func)() = nullptr;
|
||||||
void (*Resource::_update_configuration_warning)() = nullptr;
|
void (*Resource::_update_configuration_warning)() = nullptr;
|
||||||
|
|
||||||
|
|
|
@ -86,6 +86,8 @@ protected:
|
||||||
void _set_path(const String &p_path);
|
void _set_path(const String &p_path);
|
||||||
void _take_over_path(const String &p_path);
|
void _take_over_path(const String &p_path);
|
||||||
|
|
||||||
|
virtual void reset_local_to_scene();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static Node *(*_get_local_scene_func)(); //used by editor
|
static Node *(*_get_local_scene_func)(); //used by editor
|
||||||
static void (*_update_configuration_warning)(); //used by editor
|
static void (*_update_configuration_warning)(); //used by editor
|
||||||
|
|
|
@ -506,20 +506,20 @@ Ref<ResourceLoader::LoadToken> ResourceLoader::_load_start(const String &p_path,
|
||||||
float ResourceLoader::_dependency_get_progress(const String &p_path) {
|
float ResourceLoader::_dependency_get_progress(const String &p_path) {
|
||||||
if (thread_load_tasks.has(p_path)) {
|
if (thread_load_tasks.has(p_path)) {
|
||||||
ThreadLoadTask &load_task = thread_load_tasks[p_path];
|
ThreadLoadTask &load_task = thread_load_tasks[p_path];
|
||||||
|
float current_progress = 0.0;
|
||||||
int dep_count = load_task.sub_tasks.size();
|
int dep_count = load_task.sub_tasks.size();
|
||||||
if (dep_count > 0) {
|
if (dep_count > 0) {
|
||||||
float dep_progress = 0;
|
|
||||||
for (const String &E : load_task.sub_tasks) {
|
for (const String &E : load_task.sub_tasks) {
|
||||||
dep_progress += _dependency_get_progress(E);
|
current_progress += _dependency_get_progress(E);
|
||||||
}
|
}
|
||||||
dep_progress /= float(dep_count);
|
current_progress /= float(dep_count);
|
||||||
dep_progress *= 0.5;
|
current_progress *= 0.5;
|
||||||
dep_progress += load_task.progress * 0.5;
|
current_progress += load_task.progress * 0.5;
|
||||||
return dep_progress;
|
|
||||||
} else {
|
} else {
|
||||||
return load_task.progress;
|
current_progress = load_task.progress;
|
||||||
}
|
}
|
||||||
|
load_task.max_reported_progress = MAX(load_task.max_reported_progress, current_progress);
|
||||||
|
return load_task.max_reported_progress;
|
||||||
} else {
|
} else {
|
||||||
return 1.0; //assume finished loading it so it no longer exists
|
return 1.0; //assume finished loading it so it no longer exists
|
||||||
}
|
}
|
||||||
|
@ -917,7 +917,7 @@ String ResourceLoader::_path_remap(const String &p_path, bool *r_translation_rem
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fallback to p_path if new_path does not exist.
|
// Fallback to p_path if new_path does not exist.
|
||||||
if (!FileAccess::exists(new_path)) {
|
if (!FileAccess::exists(new_path + ".import") && !FileAccess::exists(new_path)) {
|
||||||
WARN_PRINT(vformat("Translation remap '%s' does not exist. Falling back to '%s'.", new_path, p_path));
|
WARN_PRINT(vformat("Translation remap '%s' does not exist. Falling back to '%s'.", new_path, p_path));
|
||||||
new_path = p_path;
|
new_path = p_path;
|
||||||
}
|
}
|
||||||
|
|
|
@ -168,7 +168,8 @@ private:
|
||||||
String remapped_path;
|
String remapped_path;
|
||||||
String dependent_path;
|
String dependent_path;
|
||||||
String type_hint;
|
String type_hint;
|
||||||
float progress = 0.0;
|
float progress = 0.0f;
|
||||||
|
float max_reported_progress = 0.0f;
|
||||||
ThreadLoadStatus status = THREAD_LOAD_IN_PROGRESS;
|
ThreadLoadStatus status = THREAD_LOAD_IN_PROGRESS;
|
||||||
ResourceFormatLoader::CacheMode cache_mode = ResourceFormatLoader::CACHE_MODE_REUSE;
|
ResourceFormatLoader::CacheMode cache_mode = ResourceFormatLoader::CACHE_MODE_REUSE;
|
||||||
Error error = OK;
|
Error error = OK;
|
||||||
|
@ -231,9 +232,13 @@ public:
|
||||||
// Loaders can safely use this regardless which thread they are running on.
|
// Loaders can safely use this regardless which thread they are running on.
|
||||||
static void notify_dependency_error(const String &p_path, const String &p_dependency, const String &p_type) {
|
static void notify_dependency_error(const String &p_path, const String &p_dependency, const String &p_type) {
|
||||||
if (dep_err_notify) {
|
if (dep_err_notify) {
|
||||||
|
if (Thread::get_caller_id() == Thread::get_main_id()) {
|
||||||
|
dep_err_notify(p_path, p_dependency, p_type);
|
||||||
|
} else {
|
||||||
callable_mp_static(dep_err_notify).bind(p_path, p_dependency, p_type).call_deferred();
|
callable_mp_static(dep_err_notify).bind(p_path, p_dependency, p_type).call_deferred();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
static void set_dependency_error_notify_func(DependencyErrorNotify p_err_notify) {
|
static void set_dependency_error_notify_func(DependencyErrorNotify p_err_notify) {
|
||||||
dep_err_notify = p_err_notify;
|
dep_err_notify = p_err_notify;
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,6 +51,7 @@ Error StreamPeerTCP::poll() {
|
||||||
status = STATUS_ERROR;
|
status = STATUS_ERROR;
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
return OK;
|
||||||
} else if (status != STATUS_CONNECTING) {
|
} else if (status != STATUS_CONNECTING) {
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -105,8 +105,8 @@ class Delaunay3D {
|
||||||
};
|
};
|
||||||
|
|
||||||
_FORCE_INLINE_ static void circum_sphere_compute(const Vector3 *p_points, Simplex *p_simplex) {
|
_FORCE_INLINE_ static void circum_sphere_compute(const Vector3 *p_points, Simplex *p_simplex) {
|
||||||
// the only part in the algorithm where there may be precision errors is this one, so ensure that
|
// The only part in the algorithm where there may be precision errors is this one,
|
||||||
// we do it as maximum precision as possible
|
// so ensure that we do it with the maximum precision possible.
|
||||||
|
|
||||||
R128 v0_x = p_points[p_simplex->points[0]].x;
|
R128 v0_x = p_points[p_simplex->points[0]].x;
|
||||||
R128 v0_y = p_points[p_simplex->points[0]].y;
|
R128 v0_y = p_points[p_simplex->points[0]].y;
|
||||||
|
@ -121,7 +121,7 @@ class Delaunay3D {
|
||||||
R128 v3_y = p_points[p_simplex->points[3]].y;
|
R128 v3_y = p_points[p_simplex->points[3]].y;
|
||||||
R128 v3_z = p_points[p_simplex->points[3]].z;
|
R128 v3_z = p_points[p_simplex->points[3]].z;
|
||||||
|
|
||||||
//Create the rows of our "unrolled" 3x3 matrix
|
// Create the rows of our "unrolled" 3x3 matrix.
|
||||||
R128 row1_x = v1_x - v0_x;
|
R128 row1_x = v1_x - v0_x;
|
||||||
R128 row1_y = v1_y - v0_y;
|
R128 row1_y = v1_y - v0_y;
|
||||||
R128 row1_z = v1_z - v0_z;
|
R128 row1_z = v1_z - v0_z;
|
||||||
|
@ -138,10 +138,10 @@ class Delaunay3D {
|
||||||
R128 sq_lenght2 = row2_x * row2_x + row2_y * row2_y + row2_z * row2_z;
|
R128 sq_lenght2 = row2_x * row2_x + row2_y * row2_y + row2_z * row2_z;
|
||||||
R128 sq_lenght3 = row3_x * row3_x + row3_y * row3_y + row3_z * row3_z;
|
R128 sq_lenght3 = row3_x * row3_x + row3_y * row3_y + row3_z * row3_z;
|
||||||
|
|
||||||
//Compute the determinant of said matrix
|
// Compute the determinant of said matrix.
|
||||||
R128 determinant = row1_x * (row2_y * row3_z - row3_y * row2_z) - row2_x * (row1_y * row3_z - row3_y * row1_z) + row3_x * (row1_y * row2_z - row2_y * row1_z);
|
R128 determinant = row1_x * (row2_y * row3_z - row3_y * row2_z) - row2_x * (row1_y * row3_z - row3_y * row1_z) + row3_x * (row1_y * row2_z - row2_y * row1_z);
|
||||||
|
|
||||||
// Compute the volume of the tetrahedron, and precompute a scalar quantity for re-use in the formula
|
// Compute the volume of the tetrahedron, and precompute a scalar quantity for reuse in the formula.
|
||||||
R128 volume = determinant / R128(6.f);
|
R128 volume = determinant / R128(6.f);
|
||||||
R128 i12volume = R128(1.f) / (volume * R128(12.f));
|
R128 i12volume = R128(1.f) / (volume * R128(12.f));
|
||||||
|
|
||||||
|
@ -149,8 +149,7 @@ class Delaunay3D {
|
||||||
R128 center_y = v0_y + i12volume * (-(row2_x * row3_z - row3_x * row2_z) * sq_lenght1 + (row1_x * row3_z - row3_x * row1_z) * sq_lenght2 - (row1_x * row2_z - row2_x * row1_z) * sq_lenght3);
|
R128 center_y = v0_y + i12volume * (-(row2_x * row3_z - row3_x * row2_z) * sq_lenght1 + (row1_x * row3_z - row3_x * row1_z) * sq_lenght2 - (row1_x * row2_z - row2_x * row1_z) * sq_lenght3);
|
||||||
R128 center_z = v0_z + i12volume * ((row2_x * row3_y - row3_x * row2_y) * sq_lenght1 - (row1_x * row3_y - row3_x * row1_y) * sq_lenght2 + (row1_x * row2_y - row2_x * row1_y) * sq_lenght3);
|
R128 center_z = v0_z + i12volume * ((row2_x * row3_y - row3_x * row2_y) * sq_lenght1 - (row1_x * row3_y - row3_x * row1_y) * sq_lenght2 + (row1_x * row2_y - row2_x * row1_y) * sq_lenght3);
|
||||||
|
|
||||||
//Once we know the center, the radius is clearly the distance to any vertex
|
// Once we know the center, the radius is clearly the distance to any vertex.
|
||||||
|
|
||||||
R128 rel1_x = center_x - v0_x;
|
R128 rel1_x = center_x - v0_x;
|
||||||
R128 rel1_y = center_y - v0_y;
|
R128 rel1_y = center_y - v0_y;
|
||||||
R128 rel1_z = center_z - v0_z;
|
R128 rel1_z = center_z - v0_z;
|
||||||
|
|
|
@ -81,35 +81,27 @@ template <class T, class... P>
|
||||||
class CallableCustomMethodPointer : public CallableCustomMethodPointerBase {
|
class CallableCustomMethodPointer : public CallableCustomMethodPointerBase {
|
||||||
struct Data {
|
struct Data {
|
||||||
T *instance;
|
T *instance;
|
||||||
#ifdef DEBUG_ENABLED
|
|
||||||
uint64_t object_id;
|
uint64_t object_id;
|
||||||
#endif
|
|
||||||
void (T::*method)(P...);
|
void (T::*method)(P...);
|
||||||
} data;
|
} data;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ObjectID get_object() const {
|
virtual ObjectID get_object() const {
|
||||||
#ifdef DEBUG_ENABLED
|
|
||||||
if (ObjectDB::get_instance(ObjectID(data.object_id)) == nullptr) {
|
if (ObjectDB::get_instance(ObjectID(data.object_id)) == nullptr) {
|
||||||
return ObjectID();
|
return ObjectID();
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
return data.instance->get_instance_id();
|
return data.instance->get_instance_id();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const {
|
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const {
|
||||||
#ifdef DEBUG_ENABLED
|
ERR_FAIL_NULL_MSG(ObjectDB::get_instance(ObjectID(data.object_id)), "Invalid Object id '" + uitos(data.object_id) + "', can't call method.");
|
||||||
ERR_FAIL_COND_MSG(ObjectDB::get_instance(ObjectID(data.object_id)) == nullptr, "Invalid Object id '" + uitos(data.object_id) + "', can't call method.");
|
|
||||||
#endif
|
|
||||||
call_with_variant_args(data.instance, data.method, p_arguments, p_argcount, r_call_error);
|
call_with_variant_args(data.instance, data.method, p_arguments, p_argcount, r_call_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
CallableCustomMethodPointer(T *p_instance, void (T::*p_method)(P...)) {
|
CallableCustomMethodPointer(T *p_instance, void (T::*p_method)(P...)) {
|
||||||
memset(&data, 0, sizeof(Data)); // Clear beforehand, may have padding bytes.
|
memset(&data, 0, sizeof(Data)); // Clear beforehand, may have padding bytes.
|
||||||
data.instance = p_instance;
|
data.instance = p_instance;
|
||||||
#ifdef DEBUG_ENABLED
|
|
||||||
data.object_id = p_instance->get_instance_id();
|
data.object_id = p_instance->get_instance_id();
|
||||||
#endif
|
|
||||||
data.method = p_method;
|
data.method = p_method;
|
||||||
_setup((uint32_t *)&data, sizeof(Data));
|
_setup((uint32_t *)&data, sizeof(Data));
|
||||||
}
|
}
|
||||||
|
@ -135,36 +127,28 @@ template <class T, class R, class... P>
|
||||||
class CallableCustomMethodPointerRet : public CallableCustomMethodPointerBase {
|
class CallableCustomMethodPointerRet : public CallableCustomMethodPointerBase {
|
||||||
struct Data {
|
struct Data {
|
||||||
T *instance;
|
T *instance;
|
||||||
#ifdef DEBUG_ENABLED
|
|
||||||
uint64_t object_id;
|
uint64_t object_id;
|
||||||
#endif
|
|
||||||
R(T::*method)
|
R(T::*method)
|
||||||
(P...);
|
(P...);
|
||||||
} data;
|
} data;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ObjectID get_object() const {
|
virtual ObjectID get_object() const {
|
||||||
#ifdef DEBUG_ENABLED
|
|
||||||
if (ObjectDB::get_instance(ObjectID(data.object_id)) == nullptr) {
|
if (ObjectDB::get_instance(ObjectID(data.object_id)) == nullptr) {
|
||||||
return ObjectID();
|
return ObjectID();
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
return data.instance->get_instance_id();
|
return data.instance->get_instance_id();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const {
|
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const {
|
||||||
#ifdef DEBUG_ENABLED
|
ERR_FAIL_NULL_MSG(ObjectDB::get_instance(ObjectID(data.object_id)), "Invalid Object id '" + uitos(data.object_id) + "', can't call method.");
|
||||||
ERR_FAIL_COND_MSG(ObjectDB::get_instance(ObjectID(data.object_id)) == nullptr, "Invalid Object id '" + uitos(data.object_id) + "', can't call method.");
|
|
||||||
#endif
|
|
||||||
call_with_variant_args_ret(data.instance, data.method, p_arguments, p_argcount, r_return_value, r_call_error);
|
call_with_variant_args_ret(data.instance, data.method, p_arguments, p_argcount, r_return_value, r_call_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
CallableCustomMethodPointerRet(T *p_instance, R (T::*p_method)(P...)) {
|
CallableCustomMethodPointerRet(T *p_instance, R (T::*p_method)(P...)) {
|
||||||
memset(&data, 0, sizeof(Data)); // Clear beforehand, may have padding bytes.
|
memset(&data, 0, sizeof(Data)); // Clear beforehand, may have padding bytes.
|
||||||
data.instance = p_instance;
|
data.instance = p_instance;
|
||||||
#ifdef DEBUG_ENABLED
|
|
||||||
data.object_id = p_instance->get_instance_id();
|
data.object_id = p_instance->get_instance_id();
|
||||||
#endif
|
|
||||||
data.method = p_method;
|
data.method = p_method;
|
||||||
_setup((uint32_t *)&data, sizeof(Data));
|
_setup((uint32_t *)&data, sizeof(Data));
|
||||||
}
|
}
|
||||||
|
@ -190,36 +174,28 @@ template <class T, class R, class... P>
|
||||||
class CallableCustomMethodPointerRetC : public CallableCustomMethodPointerBase {
|
class CallableCustomMethodPointerRetC : public CallableCustomMethodPointerBase {
|
||||||
struct Data {
|
struct Data {
|
||||||
T *instance;
|
T *instance;
|
||||||
#ifdef DEBUG_ENABLED
|
|
||||||
uint64_t object_id;
|
uint64_t object_id;
|
||||||
#endif
|
|
||||||
R(T::*method)
|
R(T::*method)
|
||||||
(P...) const;
|
(P...) const;
|
||||||
} data;
|
} data;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ObjectID get_object() const override {
|
virtual ObjectID get_object() const override {
|
||||||
#ifdef DEBUG_ENABLED
|
|
||||||
if (ObjectDB::get_instance(ObjectID(data.object_id)) == nullptr) {
|
if (ObjectDB::get_instance(ObjectID(data.object_id)) == nullptr) {
|
||||||
return ObjectID();
|
return ObjectID();
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
return data.instance->get_instance_id();
|
return data.instance->get_instance_id();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const override {
|
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const override {
|
||||||
#ifdef DEBUG_ENABLED
|
ERR_FAIL_NULL_MSG(ObjectDB::get_instance(ObjectID(data.object_id)), "Invalid Object id '" + uitos(data.object_id) + "', can't call method.");
|
||||||
ERR_FAIL_COND_MSG(ObjectDB::get_instance(ObjectID(data.object_id)) == nullptr, "Invalid Object id '" + uitos(data.object_id) + "', can't call method.");
|
|
||||||
#endif
|
|
||||||
call_with_variant_args_retc(data.instance, data.method, p_arguments, p_argcount, r_return_value, r_call_error);
|
call_with_variant_args_retc(data.instance, data.method, p_arguments, p_argcount, r_return_value, r_call_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
CallableCustomMethodPointerRetC(T *p_instance, R (T::*p_method)(P...) const) {
|
CallableCustomMethodPointerRetC(T *p_instance, R (T::*p_method)(P...) const) {
|
||||||
memset(&data, 0, sizeof(Data)); // Clear beforehand, may have padding bytes.
|
memset(&data, 0, sizeof(Data)); // Clear beforehand, may have padding bytes.
|
||||||
data.instance = p_instance;
|
data.instance = p_instance;
|
||||||
#ifdef DEBUG_ENABLED
|
|
||||||
data.object_id = p_instance->get_instance_id();
|
data.object_id = p_instance->get_instance_id();
|
||||||
#endif
|
|
||||||
data.method = p_method;
|
data.method = p_method;
|
||||||
_setup((uint32_t *)&data, sizeof(Data));
|
_setup((uint32_t *)&data, sizeof(Data));
|
||||||
}
|
}
|
||||||
|
|
|
@ -187,6 +187,7 @@ public:
|
||||||
template <class T>
|
template <class T>
|
||||||
static void register_class(bool p_virtual = false) {
|
static void register_class(bool p_virtual = false) {
|
||||||
GLOBAL_LOCK_FUNCTION;
|
GLOBAL_LOCK_FUNCTION;
|
||||||
|
static_assert(TypesAreSame<typename T::self_type, T>::value, "Class not declared properly, please use GDCLASS.");
|
||||||
T::initialize_class();
|
T::initialize_class();
|
||||||
ClassInfo *t = classes.getptr(T::get_class_static());
|
ClassInfo *t = classes.getptr(T::get_class_static());
|
||||||
ERR_FAIL_COND(!t);
|
ERR_FAIL_COND(!t);
|
||||||
|
@ -201,6 +202,7 @@ public:
|
||||||
template <class T>
|
template <class T>
|
||||||
static void register_abstract_class() {
|
static void register_abstract_class() {
|
||||||
GLOBAL_LOCK_FUNCTION;
|
GLOBAL_LOCK_FUNCTION;
|
||||||
|
static_assert(TypesAreSame<typename T::self_type, T>::value, "Class not declared properly, please use GDCLASS.");
|
||||||
T::initialize_class();
|
T::initialize_class();
|
||||||
ClassInfo *t = classes.getptr(T::get_class_static());
|
ClassInfo *t = classes.getptr(T::get_class_static());
|
||||||
ERR_FAIL_COND(!t);
|
ERR_FAIL_COND(!t);
|
||||||
|
@ -221,6 +223,7 @@ public:
|
||||||
template <class T>
|
template <class T>
|
||||||
static void register_custom_instance_class() {
|
static void register_custom_instance_class() {
|
||||||
GLOBAL_LOCK_FUNCTION;
|
GLOBAL_LOCK_FUNCTION;
|
||||||
|
static_assert(TypesAreSame<typename T::self_type, T>::value, "Class not declared properly, please use GDCLASS.");
|
||||||
T::initialize_class();
|
T::initialize_class();
|
||||||
ClassInfo *t = classes.getptr(T::get_class_static());
|
ClassInfo *t = classes.getptr(T::get_class_static());
|
||||||
ERR_FAIL_COND(!t);
|
ERR_FAIL_COND(!t);
|
||||||
|
|
|
@ -35,6 +35,8 @@
|
||||||
#include "core/object/class_db.h"
|
#include "core/object/class_db.h"
|
||||||
#include "core/object/script_language.h"
|
#include "core/object/script_language.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#ifdef DEV_ENABLED
|
#ifdef DEV_ENABLED
|
||||||
// Includes sanity checks to ensure that a queue set as a thread singleton override
|
// Includes sanity checks to ensure that a queue set as a thread singleton override
|
||||||
// is only ever called from the thread it was set for.
|
// is only ever called from the thread it was set for.
|
||||||
|
@ -93,7 +95,7 @@ Error CallQueue::push_callablep(const Callable &p_callable, const Variant **p_ar
|
||||||
|
|
||||||
if ((page_bytes[pages_used - 1] + room_needed) > uint32_t(PAGE_SIZE_BYTES)) {
|
if ((page_bytes[pages_used - 1] + room_needed) > uint32_t(PAGE_SIZE_BYTES)) {
|
||||||
if (pages_used == max_pages) {
|
if (pages_used == max_pages) {
|
||||||
ERR_PRINT("Failed method: " + p_callable + ". Message queue out of memory. " + error_text);
|
fprintf(stderr, "Failed method: %s. Message queue out of memory. %s\n", String(p_callable).utf8().get_data(), error_text.utf8().get_data());
|
||||||
statistics();
|
statistics();
|
||||||
UNLOCK_MUTEX;
|
UNLOCK_MUTEX;
|
||||||
return ERR_OUT_OF_MEMORY;
|
return ERR_OUT_OF_MEMORY;
|
||||||
|
@ -144,7 +146,7 @@ Error CallQueue::push_set(ObjectID p_id, const StringName &p_prop, const Variant
|
||||||
if (ObjectDB::get_instance(p_id)) {
|
if (ObjectDB::get_instance(p_id)) {
|
||||||
type = ObjectDB::get_instance(p_id)->get_class();
|
type = ObjectDB::get_instance(p_id)->get_class();
|
||||||
}
|
}
|
||||||
ERR_PRINT("Failed set: " + type + ":" + p_prop + " target ID: " + itos(p_id) + ". Message queue out of memory. " + error_text);
|
fprintf(stderr, "Failed set: %s: %s target ID: %s. Message queue out of memory. %s\n", type.utf8().get_data(), String(p_prop).utf8().get_data(), itos(p_id).utf8().get_data(), error_text.utf8().get_data());
|
||||||
statistics();
|
statistics();
|
||||||
|
|
||||||
UNLOCK_MUTEX;
|
UNLOCK_MUTEX;
|
||||||
|
@ -181,7 +183,7 @@ Error CallQueue::push_notification(ObjectID p_id, int p_notification) {
|
||||||
|
|
||||||
if ((page_bytes[pages_used - 1] + room_needed) > uint32_t(PAGE_SIZE_BYTES)) {
|
if ((page_bytes[pages_used - 1] + room_needed) > uint32_t(PAGE_SIZE_BYTES)) {
|
||||||
if (pages_used == max_pages) {
|
if (pages_used == max_pages) {
|
||||||
ERR_PRINT("Failed notification: " + itos(p_notification) + " target ID: " + itos(p_id) + ". Message queue out of memory. " + error_text);
|
fprintf(stderr, "Failed notification: %s target ID: %s. Message queue out of memory. %s\n", itos(p_notification).utf8().get_data(), itos(p_id).utf8().get_data(), error_text.utf8().get_data());
|
||||||
statistics();
|
statistics();
|
||||||
UNLOCK_MUTEX;
|
UNLOCK_MUTEX;
|
||||||
return ERR_OUT_OF_MEMORY;
|
return ERR_OUT_OF_MEMORY;
|
||||||
|
|
|
@ -836,14 +836,16 @@ void Object::set_script(const Variant &p_script) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ref<Script> s = p_script;
|
||||||
|
ERR_FAIL_COND_MSG(s.is_null() && !p_script.is_null(), "Invalid parameter, it should be a reference to a valid script (or null).");
|
||||||
|
|
||||||
|
script = p_script;
|
||||||
|
|
||||||
if (script_instance) {
|
if (script_instance) {
|
||||||
memdelete(script_instance);
|
memdelete(script_instance);
|
||||||
script_instance = nullptr;
|
script_instance = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
script = p_script;
|
|
||||||
Ref<Script> s = script;
|
|
||||||
|
|
||||||
if (!s.is_null()) {
|
if (!s.is_null()) {
|
||||||
if (s->can_instantiate()) {
|
if (s->can_instantiate()) {
|
||||||
OBJ_DEBUG_LOCK
|
OBJ_DEBUG_LOCK
|
||||||
|
|
|
@ -382,6 +382,7 @@ private:
|
||||||
friend class ::ClassDB; \
|
friend class ::ClassDB; \
|
||||||
\
|
\
|
||||||
public: \
|
public: \
|
||||||
|
typedef m_class self_type; \
|
||||||
static constexpr bool _class_is_enabled = !bool(GD_IS_DEFINED(ClassDB_Disable_##m_class)) && m_inherits::_class_is_enabled; \
|
static constexpr bool _class_is_enabled = !bool(GD_IS_DEFINED(ClassDB_Disable_##m_class)) && m_inherits::_class_is_enabled; \
|
||||||
virtual String get_class() const override { \
|
virtual String get_class() const override { \
|
||||||
if (_get_extension()) { \
|
if (_get_extension()) { \
|
||||||
|
@ -551,6 +552,8 @@ class ScriptInstance;
|
||||||
|
|
||||||
class Object {
|
class Object {
|
||||||
public:
|
public:
|
||||||
|
typedef Object self_type;
|
||||||
|
|
||||||
enum ConnectFlags {
|
enum ConnectFlags {
|
||||||
CONNECT_DEFERRED = 1,
|
CONNECT_DEFERRED = 1,
|
||||||
CONNECT_PERSIST = 2, // hint for scene to save this connection
|
CONNECT_PERSIST = 2, // hint for scene to save this connection
|
||||||
|
|
|
@ -416,7 +416,7 @@ Error WorkerThreadPool::wait_for_task_completion(TaskID p_task_id) {
|
||||||
WorkerThreadPool::GroupID WorkerThreadPool::_add_group_task(const Callable &p_callable, void (*p_func)(void *, uint32_t), void *p_userdata, BaseTemplateUserdata *p_template_userdata, int p_elements, int p_tasks, bool p_high_priority, const String &p_description) {
|
WorkerThreadPool::GroupID WorkerThreadPool::_add_group_task(const Callable &p_callable, void (*p_func)(void *, uint32_t), void *p_userdata, BaseTemplateUserdata *p_template_userdata, int p_elements, int p_tasks, bool p_high_priority, const String &p_description) {
|
||||||
ERR_FAIL_COND_V(p_elements < 0, INVALID_TASK_ID);
|
ERR_FAIL_COND_V(p_elements < 0, INVALID_TASK_ID);
|
||||||
if (p_tasks < 0) {
|
if (p_tasks < 0) {
|
||||||
p_tasks = threads.size();
|
p_tasks = MAX(1u, threads.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
task_mutex.lock();
|
task_mutex.lock();
|
||||||
|
|
|
@ -146,6 +146,7 @@ static const _KeyCodeText _keycodes[] = {
|
||||||
{Key::FAVORITES ,"Favorites"},
|
{Key::FAVORITES ,"Favorites"},
|
||||||
{Key::SEARCH ,"Search"},
|
{Key::SEARCH ,"Search"},
|
||||||
{Key::STANDBY ,"StandBy"},
|
{Key::STANDBY ,"StandBy"},
|
||||||
|
{Key::OPENURL ,"OpenURL"},
|
||||||
{Key::LAUNCHMAIL ,"LaunchMail"},
|
{Key::LAUNCHMAIL ,"LaunchMail"},
|
||||||
{Key::LAUNCHMEDIA ,"LaunchMedia"},
|
{Key::LAUNCHMEDIA ,"LaunchMedia"},
|
||||||
{Key::LAUNCH0 ,"Launch0"},
|
{Key::LAUNCH0 ,"Launch0"},
|
||||||
|
@ -238,6 +239,8 @@ static const _KeyCodeText _keycodes[] = {
|
||||||
{Key::BAR ,"Bar"},
|
{Key::BAR ,"Bar"},
|
||||||
{Key::BRACERIGHT ,"BraceRight"},
|
{Key::BRACERIGHT ,"BraceRight"},
|
||||||
{Key::ASCIITILDE ,"AsciiTilde"},
|
{Key::ASCIITILDE ,"AsciiTilde"},
|
||||||
|
{Key::YEN ,"Yen"},
|
||||||
|
{Key::SECTION ,"Section"},
|
||||||
{Key::NONE ,nullptr}
|
{Key::NONE ,nullptr}
|
||||||
/* clang-format on */
|
/* clang-format on */
|
||||||
};
|
};
|
||||||
|
|
|
@ -33,6 +33,8 @@
|
||||||
|
|
||||||
#include "core/string/ustring.h"
|
#include "core/string/ustring.h"
|
||||||
|
|
||||||
|
// Keep the values in this enum in sync with `_keycodes` in `keyboard.cpp`,
|
||||||
|
// and the bindings in `core_constants.cpp`.
|
||||||
enum class Key {
|
enum class Key {
|
||||||
NONE = 0,
|
NONE = 0,
|
||||||
// Special key: The strategy here is similar to the one used by toolkits,
|
// Special key: The strategy here is similar to the one used by toolkits,
|
||||||
|
|
|
@ -295,12 +295,14 @@ Error OS::shell_open(String p_uri) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Error OS::shell_show_in_file_manager(String p_path, bool p_open_folder) {
|
Error OS::shell_show_in_file_manager(String p_path, bool p_open_folder) {
|
||||||
if (!p_path.begins_with("file://")) {
|
p_path = p_path.trim_prefix("file://");
|
||||||
p_path = String("file://") + p_path;
|
|
||||||
}
|
if (!DirAccess::dir_exists_absolute(p_path)) {
|
||||||
if (!p_path.ends_with("/")) {
|
|
||||||
p_path = p_path.get_base_dir();
|
p_path = p_path.get_base_dir();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p_path = String("file://") + p_path;
|
||||||
|
|
||||||
return shell_open(p_path);
|
return shell_open(p_path);
|
||||||
}
|
}
|
||||||
// implement these with the canvas?
|
// implement these with the canvas?
|
||||||
|
|
|
@ -82,6 +82,15 @@ void Translation::_set_messages(const Dictionary &p_messages) {
|
||||||
void Translation::set_locale(const String &p_locale) {
|
void Translation::set_locale(const String &p_locale) {
|
||||||
locale = TranslationServer::get_singleton()->standardize_locale(p_locale);
|
locale = TranslationServer::get_singleton()->standardize_locale(p_locale);
|
||||||
|
|
||||||
|
if (Thread::is_main_thread()) {
|
||||||
|
_notify_translation_changed_if_applies();
|
||||||
|
} else {
|
||||||
|
// Avoid calling non-thread-safe functions here.
|
||||||
|
callable_mp(this, &Translation::_notify_translation_changed_if_applies).call_deferred();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Translation::_notify_translation_changed_if_applies() {
|
||||||
if (OS::get_singleton()->get_main_loop() && TranslationServer::get_singleton()->get_loaded_locales().has(get_locale())) {
|
if (OS::get_singleton()->get_main_loop() && TranslationServer::get_singleton()->get_loaded_locales().has(get_locale())) {
|
||||||
OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_TRANSLATION_CHANGED);
|
OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_TRANSLATION_CHANGED);
|
||||||
}
|
}
|
||||||
|
@ -511,11 +520,11 @@ String TranslationServer::get_country_name(const String &p_country) const {
|
||||||
void TranslationServer::set_locale(const String &p_locale) {
|
void TranslationServer::set_locale(const String &p_locale) {
|
||||||
locale = standardize_locale(p_locale);
|
locale = standardize_locale(p_locale);
|
||||||
|
|
||||||
|
ResourceLoader::reload_translation_remaps();
|
||||||
|
|
||||||
if (OS::get_singleton()->get_main_loop()) {
|
if (OS::get_singleton()->get_main_loop()) {
|
||||||
OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_TRANSLATION_CHANGED);
|
OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_TRANSLATION_CHANGED);
|
||||||
}
|
}
|
||||||
|
|
||||||
ResourceLoader::reload_translation_remaps();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String TranslationServer::get_locale() const {
|
String TranslationServer::get_locale() const {
|
||||||
|
@ -807,10 +816,11 @@ bool TranslationServer::is_pseudolocalization_enabled() const {
|
||||||
void TranslationServer::set_pseudolocalization_enabled(bool p_enabled) {
|
void TranslationServer::set_pseudolocalization_enabled(bool p_enabled) {
|
||||||
pseudolocalization_enabled = p_enabled;
|
pseudolocalization_enabled = p_enabled;
|
||||||
|
|
||||||
|
ResourceLoader::reload_translation_remaps();
|
||||||
|
|
||||||
if (OS::get_singleton()->get_main_loop()) {
|
if (OS::get_singleton()->get_main_loop()) {
|
||||||
OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_TRANSLATION_CHANGED);
|
OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_TRANSLATION_CHANGED);
|
||||||
}
|
}
|
||||||
ResourceLoader::reload_translation_remaps();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TranslationServer::set_editor_pseudolocalization(bool p_enabled) {
|
void TranslationServer::set_editor_pseudolocalization(bool p_enabled) {
|
||||||
|
@ -827,10 +837,11 @@ void TranslationServer::reload_pseudolocalization() {
|
||||||
pseudolocalization_suffix = GLOBAL_GET("internationalization/pseudolocalization/suffix");
|
pseudolocalization_suffix = GLOBAL_GET("internationalization/pseudolocalization/suffix");
|
||||||
pseudolocalization_skip_placeholders_enabled = GLOBAL_GET("internationalization/pseudolocalization/skip_placeholders");
|
pseudolocalization_skip_placeholders_enabled = GLOBAL_GET("internationalization/pseudolocalization/skip_placeholders");
|
||||||
|
|
||||||
|
ResourceLoader::reload_translation_remaps();
|
||||||
|
|
||||||
if (OS::get_singleton()->get_main_loop()) {
|
if (OS::get_singleton()->get_main_loop()) {
|
||||||
OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_TRANSLATION_CHANGED);
|
OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_TRANSLATION_CHANGED);
|
||||||
}
|
}
|
||||||
ResourceLoader::reload_translation_remaps();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StringName TranslationServer::pseudolocalize(const StringName &p_message) const {
|
StringName TranslationServer::pseudolocalize(const StringName &p_message) const {
|
||||||
|
|
|
@ -47,6 +47,8 @@ class Translation : public Resource {
|
||||||
virtual Dictionary _get_messages() const;
|
virtual Dictionary _get_messages() const;
|
||||||
virtual void _set_messages(const Dictionary &p_messages);
|
virtual void _set_messages(const Dictionary &p_messages);
|
||||||
|
|
||||||
|
void _notify_translation_changed_if_applies();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
|
|
||||||
|
|
|
@ -305,7 +305,11 @@ void String::copy_from(const char *p_cstr) {
|
||||||
char32_t *dst = this->ptrw();
|
char32_t *dst = this->ptrw();
|
||||||
|
|
||||||
for (size_t i = 0; i <= len; i++) {
|
for (size_t i = 0; i <= len; i++) {
|
||||||
|
#if CHAR_MIN == 0
|
||||||
|
uint8_t c = p_cstr[i];
|
||||||
|
#else
|
||||||
uint8_t c = p_cstr[i] >= 0 ? p_cstr[i] : uint8_t(256 + p_cstr[i]);
|
uint8_t c = p_cstr[i] >= 0 ? p_cstr[i] : uint8_t(256 + p_cstr[i]);
|
||||||
|
#endif
|
||||||
if (c == 0 && i < len) {
|
if (c == 0 && i < len) {
|
||||||
print_unicode_error("NUL character", true);
|
print_unicode_error("NUL character", true);
|
||||||
dst[i] = _replacement_char;
|
dst[i] = _replacement_char;
|
||||||
|
@ -338,7 +342,11 @@ void String::copy_from(const char *p_cstr, const int p_clip_to) {
|
||||||
char32_t *dst = this->ptrw();
|
char32_t *dst = this->ptrw();
|
||||||
|
|
||||||
for (int i = 0; i < len; i++) {
|
for (int i = 0; i < len; i++) {
|
||||||
|
#if CHAR_MIN == 0
|
||||||
|
uint8_t c = p_cstr[i];
|
||||||
|
#else
|
||||||
uint8_t c = p_cstr[i] >= 0 ? p_cstr[i] : uint8_t(256 + p_cstr[i]);
|
uint8_t c = p_cstr[i] >= 0 ? p_cstr[i] : uint8_t(256 + p_cstr[i]);
|
||||||
|
#endif
|
||||||
if (c == 0) {
|
if (c == 0) {
|
||||||
print_unicode_error("NUL character", true);
|
print_unicode_error("NUL character", true);
|
||||||
dst[i] = _replacement_char;
|
dst[i] = _replacement_char;
|
||||||
|
@ -544,7 +552,11 @@ String &String::operator+=(const char *p_str) {
|
||||||
char32_t *dst = ptrw() + lhs_len;
|
char32_t *dst = ptrw() + lhs_len;
|
||||||
|
|
||||||
for (size_t i = 0; i <= rhs_len; i++) {
|
for (size_t i = 0; i <= rhs_len; i++) {
|
||||||
|
#if CHAR_MIN == 0
|
||||||
|
uint8_t c = p_str[i];
|
||||||
|
#else
|
||||||
uint8_t c = p_str[i] >= 0 ? p_str[i] : uint8_t(256 + p_str[i]);
|
uint8_t c = p_str[i] >= 0 ? p_str[i] : uint8_t(256 + p_str[i]);
|
||||||
|
#endif
|
||||||
if (c == 0 && i < rhs_len) {
|
if (c == 0 && i < rhs_len) {
|
||||||
print_unicode_error("NUL character", true);
|
print_unicode_error("NUL character", true);
|
||||||
dst[i] = _replacement_char;
|
dst[i] = _replacement_char;
|
||||||
|
@ -1493,9 +1505,9 @@ String String::num(double p_num, int p_decimals) {
|
||||||
|
|
||||||
if (p_decimals < 0) {
|
if (p_decimals < 0) {
|
||||||
p_decimals = 14;
|
p_decimals = 14;
|
||||||
const double abs_num = ABS(p_num);
|
const double abs_num = Math::abs(p_num);
|
||||||
if (abs_num > 10) {
|
if (abs_num > 10) {
|
||||||
// We want to align the digits to the above sane default, so we only
|
// We want to align the digits to the above reasonable default, so we only
|
||||||
// need to subtract log10 for numbers with a positive power of ten.
|
// need to subtract log10 for numbers with a positive power of ten.
|
||||||
p_decimals -= (int)floor(log10(abs_num));
|
p_decimals -= (int)floor(log10(abs_num));
|
||||||
}
|
}
|
||||||
|
@ -1814,7 +1826,11 @@ Error String::parse_utf8(const char *p_utf8, int p_len, bool p_skip_cr) {
|
||||||
int skip = 0;
|
int skip = 0;
|
||||||
uint8_t c_start = 0;
|
uint8_t c_start = 0;
|
||||||
while (ptrtmp != ptrtmp_limit && *ptrtmp) {
|
while (ptrtmp != ptrtmp_limit && *ptrtmp) {
|
||||||
|
#if CHAR_MIN == 0
|
||||||
|
uint8_t c = *ptrtmp;
|
||||||
|
#else
|
||||||
uint8_t c = *ptrtmp >= 0 ? *ptrtmp : uint8_t(256 + *ptrtmp);
|
uint8_t c = *ptrtmp >= 0 ? *ptrtmp : uint8_t(256 + *ptrtmp);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (skip == 0) {
|
if (skip == 0) {
|
||||||
if (p_skip_cr && c == '\r') {
|
if (p_skip_cr && c == '\r') {
|
||||||
|
@ -1882,7 +1898,11 @@ Error String::parse_utf8(const char *p_utf8, int p_len, bool p_skip_cr) {
|
||||||
int skip = 0;
|
int skip = 0;
|
||||||
uint32_t unichar = 0;
|
uint32_t unichar = 0;
|
||||||
while (cstr_size) {
|
while (cstr_size) {
|
||||||
|
#if CHAR_MIN == 0
|
||||||
|
uint8_t c = *p_utf8;
|
||||||
|
#else
|
||||||
uint8_t c = *p_utf8 >= 0 ? *p_utf8 : uint8_t(256 + *p_utf8);
|
uint8_t c = *p_utf8 >= 0 ? *p_utf8 : uint8_t(256 + *p_utf8);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (skip == 0) {
|
if (skip == 0) {
|
||||||
if (p_skip_cr && c == '\r') {
|
if (p_skip_cr && c == '\r') {
|
||||||
|
@ -3945,24 +3965,22 @@ bool String::is_absolute_path() const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static _FORCE_INLINE_ bool _is_valid_identifier_bit(int p_index, char32_t p_char) {
|
|
||||||
if (p_index == 0 && is_digit(p_char)) {
|
|
||||||
return false; // No start with number plz.
|
|
||||||
}
|
|
||||||
return is_ascii_identifier_char(p_char);
|
|
||||||
}
|
|
||||||
|
|
||||||
String String::validate_identifier() const {
|
String String::validate_identifier() const {
|
||||||
if (is_empty()) {
|
if (is_empty()) {
|
||||||
return "_"; // Empty string is not a valid identifier;
|
return "_"; // Empty string is not a valid identifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
String result = *this;
|
String result;
|
||||||
|
if (is_digit(operator[](0))) {
|
||||||
|
result = "_" + *this;
|
||||||
|
} else {
|
||||||
|
result = *this;
|
||||||
|
}
|
||||||
|
|
||||||
int len = result.length();
|
int len = result.length();
|
||||||
char32_t *buffer = result.ptrw();
|
char32_t *buffer = result.ptrw();
|
||||||
|
|
||||||
for (int i = 0; i < len; i++) {
|
for (int i = 0; i < len; i++) {
|
||||||
if (!_is_valid_identifier_bit(i, buffer[i])) {
|
if (!is_ascii_identifier_char(buffer[i])) {
|
||||||
buffer[i] = '_';
|
buffer[i] = '_';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3977,10 +3995,14 @@ bool String::is_valid_identifier() const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_digit(operator[](0))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
const char32_t *str = &operator[](0);
|
const char32_t *str = &operator[](0);
|
||||||
|
|
||||||
for (int i = 0; i < len; i++) {
|
for (int i = 0; i < len; i++) {
|
||||||
if (!_is_valid_identifier_bit(i, str[i])) {
|
if (!is_ascii_identifier_char(str[i])) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4281,12 +4303,13 @@ String String::pad_zeros(int p_digits) const {
|
||||||
begin++;
|
begin++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (begin >= end) {
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
int zeros_to_add = p_digits - (end - begin);
|
int zeros_to_add = p_digits - (end - begin);
|
||||||
|
|
||||||
|
if (zeros_to_add <= 0) {
|
||||||
|
return s;
|
||||||
|
} else {
|
||||||
return s.insert(begin, String("0").repeat(zeros_to_add));
|
return s.insert(begin, String("0").repeat(zeros_to_add));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String String::trim_prefix(const String &p_prefix) const {
|
String String::trim_prefix(const String &p_prefix) const {
|
||||||
|
@ -4868,8 +4891,8 @@ String String::sprintf(const Array &values, bool *error) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
double value = values[value_index];
|
double value = values[value_index];
|
||||||
bool is_negative = (value < 0);
|
bool is_negative = signbit(value);
|
||||||
String str = String::num(ABS(value), min_decimals);
|
String str = String::num(Math::abs(value), min_decimals);
|
||||||
const bool is_finite = Math::is_finite(value);
|
const bool is_finite = Math::is_finite(value);
|
||||||
|
|
||||||
// Pad decimals out.
|
// Pad decimals out.
|
||||||
|
@ -4931,7 +4954,7 @@ String String::sprintf(const Array &values, bool *error) const {
|
||||||
String str = "(";
|
String str = "(";
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
double val = vec[i];
|
double val = vec[i];
|
||||||
String number_str = String::num(ABS(val), min_decimals);
|
String number_str = String::num(Math::abs(val), min_decimals);
|
||||||
const bool is_finite = Math::is_finite(val);
|
const bool is_finite = Math::is_finite(val);
|
||||||
|
|
||||||
// Pad decimals out.
|
// Pad decimals out.
|
||||||
|
|
|
@ -90,6 +90,10 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
_FORCE_INLINE_ bool _get_alloc_size_checked(size_t p_elements, size_t *out) const {
|
_FORCE_INLINE_ bool _get_alloc_size_checked(size_t p_elements, size_t *out) const {
|
||||||
|
if (unlikely(p_elements == 0)) {
|
||||||
|
*out = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
#if defined(__GNUC__)
|
#if defined(__GNUC__)
|
||||||
size_t o;
|
size_t o;
|
||||||
size_t p;
|
size_t p;
|
||||||
|
@ -101,13 +105,12 @@ private:
|
||||||
if (__builtin_add_overflow(o, static_cast<size_t>(32), &p)) {
|
if (__builtin_add_overflow(o, static_cast<size_t>(32), &p)) {
|
||||||
return false; // No longer allocated here.
|
return false; // No longer allocated here.
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
#else
|
#else
|
||||||
// Speed is more important than correctness here, do the operations unchecked
|
// Speed is more important than correctness here, do the operations unchecked
|
||||||
// and hope for the best.
|
// and hope for the best.
|
||||||
*out = _get_alloc_size(p_elements);
|
*out = _get_alloc_size(p_elements);
|
||||||
return true;
|
|
||||||
#endif
|
#endif
|
||||||
|
return *out;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _unref(void *p_data);
|
void _unref(void *p_data);
|
||||||
|
|
|
@ -310,7 +310,7 @@ struct HashMapHasherDefault {
|
||||||
static _FORCE_INLINE_ uint32_t hash(const char16_t p_uchar) { return hash_fmix32(p_uchar); }
|
static _FORCE_INLINE_ uint32_t hash(const char16_t p_uchar) { return hash_fmix32(p_uchar); }
|
||||||
static _FORCE_INLINE_ uint32_t hash(const char32_t p_uchar) { return hash_fmix32(p_uchar); }
|
static _FORCE_INLINE_ uint32_t hash(const char32_t p_uchar) { return hash_fmix32(p_uchar); }
|
||||||
static _FORCE_INLINE_ uint32_t hash(const RID &p_rid) { return hash_one_uint64(p_rid.get_id()); }
|
static _FORCE_INLINE_ uint32_t hash(const RID &p_rid) { return hash_one_uint64(p_rid.get_id()); }
|
||||||
static _FORCE_INLINE_ uint32_t hash(const CharString &p_char_string) { return hash_djb2(p_char_string.ptr()); }
|
static _FORCE_INLINE_ uint32_t hash(const CharString &p_char_string) { return hash_djb2(p_char_string.get_data()); }
|
||||||
static _FORCE_INLINE_ uint32_t hash(const StringName &p_string_name) { return p_string_name.hash(); }
|
static _FORCE_INLINE_ uint32_t hash(const StringName &p_string_name) { return p_string_name.hash(); }
|
||||||
static _FORCE_INLINE_ uint32_t hash(const NodePath &p_path) { return p_path.hash(); }
|
static _FORCE_INLINE_ uint32_t hash(const NodePath &p_path) { return p_path.hash(); }
|
||||||
static _FORCE_INLINE_ uint32_t hash(const ObjectID &p_id) { return hash_one_uint64(p_id); }
|
static _FORCE_INLINE_ uint32_t hash(const ObjectID &p_id) { return hash_one_uint64(p_id); }
|
||||||
|
|
|
@ -211,10 +211,10 @@ public:
|
||||||
size_mask = mask;
|
size_mask = mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
RingBuffer<T>(int p_power = 0) {
|
RingBuffer(int p_power = 0) {
|
||||||
resize(p_power);
|
resize(p_power);
|
||||||
}
|
}
|
||||||
~RingBuffer<T>() {}
|
~RingBuffer() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // RING_BUFFER_H
|
#endif // RING_BUFFER_H
|
||||||
|
|
|
@ -146,7 +146,7 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_ALWAYS_INLINE_ explicit SafeNumeric<T>(T p_value = static_cast<T>(0)) {
|
_ALWAYS_INLINE_ explicit SafeNumeric(T p_value = static_cast<T>(0)) {
|
||||||
set(p_value);
|
set(p_value);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -92,6 +92,7 @@
|
||||||
#undef Error
|
#undef Error
|
||||||
#undef OK
|
#undef OK
|
||||||
#undef CONNECT_DEFERRED // override from Windows SDK, clashes with Object enum
|
#undef CONNECT_DEFERRED // override from Windows SDK, clashes with Object enum
|
||||||
|
#undef MONO_FONT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Make room for our constexpr's below by overriding potential system-specific macros.
|
// Make room for our constexpr's below by overriding potential system-specific macros.
|
||||||
|
|
|
@ -454,17 +454,21 @@ Array Array::slice(int p_begin, int p_end, int p_step, bool p_deep) const {
|
||||||
|
|
||||||
const int s = size();
|
const int s = size();
|
||||||
|
|
||||||
int begin = CLAMP(p_begin, -s, s);
|
if (s == 0 || (p_begin < -s && p_step < 0) || (p_begin >= s && p_step > 0)) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int begin = CLAMP(p_begin, -s, s - 1);
|
||||||
if (begin < 0) {
|
if (begin < 0) {
|
||||||
begin += s;
|
begin += s;
|
||||||
}
|
}
|
||||||
int end = CLAMP(p_end, -s, s);
|
int end = CLAMP(p_end, -s - 1, s);
|
||||||
if (end < 0) {
|
if (end < 0) {
|
||||||
end += s;
|
end += s;
|
||||||
}
|
}
|
||||||
|
|
||||||
ERR_FAIL_COND_V_MSG(p_step > 0 && begin > end, result, "Slice is positive, but bounds is decreasing.");
|
ERR_FAIL_COND_V_MSG(p_step > 0 && begin > end, result, "Slice step is positive, but bounds are decreasing.");
|
||||||
ERR_FAIL_COND_V_MSG(p_step < 0 && begin < end, result, "Slice is negative, but bounds is increasing.");
|
ERR_FAIL_COND_V_MSG(p_step < 0 && begin < end, result, "Slice step is negative, but bounds are increasing.");
|
||||||
|
|
||||||
int result_size = (end - begin) / p_step + (((end - begin) % p_step != 0) ? 1 : 0);
|
int result_size = (end - begin) / p_step + (((end - begin) % p_step != 0) ? 1 : 0);
|
||||||
result.resize(result_size);
|
result.resize(result_size);
|
||||||
|
|
|
@ -88,7 +88,7 @@ ObjectID CallableCustomBind::get_object() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
const Callable *CallableCustomBind::get_base_comparator() const {
|
const Callable *CallableCustomBind::get_base_comparator() const {
|
||||||
return &callable;
|
return callable.get_base_comparator();
|
||||||
}
|
}
|
||||||
|
|
||||||
int CallableCustomBind::get_bound_arguments_count() const {
|
int CallableCustomBind::get_bound_arguments_count() const {
|
||||||
|
@ -144,6 +144,18 @@ void CallableCustomBind::call(const Variant **p_arguments, int p_argcount, Varia
|
||||||
callable.callp(args, p_argcount + binds.size(), r_return_value, r_call_error);
|
callable.callp(args, p_argcount + binds.size(), r_return_value, r_call_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Error CallableCustomBind::rpc(int p_peer_id, const Variant **p_arguments, int p_argcount, Callable::CallError &r_call_error) const {
|
||||||
|
const Variant **args = (const Variant **)alloca(sizeof(const Variant **) * (binds.size() + p_argcount));
|
||||||
|
for (int i = 0; i < p_argcount; i++) {
|
||||||
|
args[i] = (const Variant *)p_arguments[i];
|
||||||
|
}
|
||||||
|
for (int i = 0; i < binds.size(); i++) {
|
||||||
|
args[i + p_argcount] = (const Variant *)&binds[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return callable.rpcp(p_peer_id, args, p_argcount + binds.size(), r_call_error);
|
||||||
|
}
|
||||||
|
|
||||||
CallableCustomBind::CallableCustomBind(const Callable &p_callable, const Vector<Variant> &p_binds) {
|
CallableCustomBind::CallableCustomBind(const Callable &p_callable, const Vector<Variant> &p_binds) {
|
||||||
callable = p_callable;
|
callable = p_callable;
|
||||||
binds = p_binds;
|
binds = p_binds;
|
||||||
|
@ -210,7 +222,7 @@ ObjectID CallableCustomUnbind::get_object() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
const Callable *CallableCustomUnbind::get_base_comparator() const {
|
const Callable *CallableCustomUnbind::get_base_comparator() const {
|
||||||
return &callable;
|
return callable.get_base_comparator();
|
||||||
}
|
}
|
||||||
|
|
||||||
int CallableCustomUnbind::get_bound_arguments_count() const {
|
int CallableCustomUnbind::get_bound_arguments_count() const {
|
||||||
|
@ -242,6 +254,16 @@ void CallableCustomUnbind::call(const Variant **p_arguments, int p_argcount, Var
|
||||||
callable.callp(p_arguments, p_argcount - argcount, r_return_value, r_call_error);
|
callable.callp(p_arguments, p_argcount - argcount, r_return_value, r_call_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Error CallableCustomUnbind::rpc(int p_peer_id, const Variant **p_arguments, int p_argcount, Callable::CallError &r_call_error) const {
|
||||||
|
if (argcount > p_argcount) {
|
||||||
|
r_call_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
|
||||||
|
r_call_error.argument = 0;
|
||||||
|
r_call_error.expected = argcount;
|
||||||
|
return ERR_UNCONFIGURED;
|
||||||
|
}
|
||||||
|
return callable.rpcp(p_peer_id, p_arguments, p_argcount - argcount, r_call_error);
|
||||||
|
}
|
||||||
|
|
||||||
CallableCustomUnbind::CallableCustomUnbind(const Callable &p_callable, int p_argcount) {
|
CallableCustomUnbind::CallableCustomUnbind(const Callable &p_callable, int p_argcount) {
|
||||||
callable = p_callable;
|
callable = p_callable;
|
||||||
argcount = p_argcount;
|
argcount = p_argcount;
|
||||||
|
|
|
@ -51,6 +51,7 @@ public:
|
||||||
virtual StringName get_method() const override;
|
virtual StringName get_method() const override;
|
||||||
virtual ObjectID get_object() const override;
|
virtual ObjectID get_object() const override;
|
||||||
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const override;
|
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const override;
|
||||||
|
virtual Error rpc(int p_peer_id, const Variant **p_arguments, int p_argcount, Callable::CallError &r_call_error) const override;
|
||||||
virtual const Callable *get_base_comparator() const override;
|
virtual const Callable *get_base_comparator() const override;
|
||||||
virtual int get_bound_arguments_count() const override;
|
virtual int get_bound_arguments_count() const override;
|
||||||
virtual void get_bound_arguments(Vector<Variant> &r_arguments, int &r_argcount) const override;
|
virtual void get_bound_arguments(Vector<Variant> &r_arguments, int &r_argcount) const override;
|
||||||
|
@ -78,6 +79,7 @@ public:
|
||||||
virtual StringName get_method() const override;
|
virtual StringName get_method() const override;
|
||||||
virtual ObjectID get_object() const override;
|
virtual ObjectID get_object() const override;
|
||||||
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const override;
|
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const override;
|
||||||
|
virtual Error rpc(int p_peer_id, const Variant **p_arguments, int p_argcount, Callable::CallError &r_call_error) const override;
|
||||||
virtual const Callable *get_base_comparator() const override;
|
virtual const Callable *get_base_comparator() const override;
|
||||||
virtual int get_bound_arguments_count() const override;
|
virtual int get_bound_arguments_count() const override;
|
||||||
virtual void get_bound_arguments(Vector<Variant> &r_arguments, int &r_argcount) const override;
|
virtual void get_bound_arguments(Vector<Variant> &r_arguments, int &r_argcount) const override;
|
||||||
|
|
|
@ -1754,11 +1754,10 @@ String Variant::stringify(int recursion_count) const {
|
||||||
case COLOR:
|
case COLOR:
|
||||||
return operator Color();
|
return operator Color();
|
||||||
case DICTIONARY: {
|
case DICTIONARY: {
|
||||||
|
ERR_FAIL_COND_V_MSG(recursion_count > MAX_RECURSION, "{ ... }", "Maximum dictionary recursion reached!");
|
||||||
|
recursion_count++;
|
||||||
|
|
||||||
const Dictionary &d = *reinterpret_cast<const Dictionary *>(_data._mem);
|
const Dictionary &d = *reinterpret_cast<const Dictionary *>(_data._mem);
|
||||||
if (recursion_count > MAX_RECURSION) {
|
|
||||||
ERR_PRINT("Maximum dictionary recursion reached!");
|
|
||||||
return "{ ... }";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add leading and trailing space to Dictionary printing. This distinguishes it
|
// Add leading and trailing space to Dictionary printing. This distinguishes it
|
||||||
// from array printing on fonts that have similar-looking {} and [] characters.
|
// from array printing on fonts that have similar-looking {} and [] characters.
|
||||||
|
@ -1768,7 +1767,6 @@ String Variant::stringify(int recursion_count) const {
|
||||||
|
|
||||||
Vector<_VariantStrPair> pairs;
|
Vector<_VariantStrPair> pairs;
|
||||||
|
|
||||||
recursion_count++;
|
|
||||||
for (List<Variant>::Element *E = keys.front(); E; E = E->next()) {
|
for (List<Variant>::Element *E = keys.front(); E; E = E->next()) {
|
||||||
_VariantStrPair sp;
|
_VariantStrPair sp;
|
||||||
sp.key = stringify_variant_clean(E->get(), recursion_count);
|
sp.key = stringify_variant_clean(E->get(), recursion_count);
|
||||||
|
@ -1787,6 +1785,7 @@ String Variant::stringify(int recursion_count) const {
|
||||||
|
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
// Packed arrays cannot contain recursive structures, the recursion_count increment is not needed.
|
||||||
case PACKED_VECTOR2_ARRAY: {
|
case PACKED_VECTOR2_ARRAY: {
|
||||||
return stringify_vector(operator Vector<Vector2>(), recursion_count);
|
return stringify_vector(operator Vector<Vector2>(), recursion_count);
|
||||||
}
|
}
|
||||||
|
@ -1815,13 +1814,10 @@ String Variant::stringify(int recursion_count) const {
|
||||||
return stringify_vector(operator Vector<double>(), recursion_count);
|
return stringify_vector(operator Vector<double>(), recursion_count);
|
||||||
}
|
}
|
||||||
case ARRAY: {
|
case ARRAY: {
|
||||||
Array arr = operator Array();
|
ERR_FAIL_COND_V_MSG(recursion_count > MAX_RECURSION, "[...]", "Maximum array recursion reached!");
|
||||||
if (recursion_count > MAX_RECURSION) {
|
recursion_count++;
|
||||||
ERR_PRINT("Maximum array recursion reached!");
|
|
||||||
return "[...]";
|
|
||||||
}
|
|
||||||
|
|
||||||
return stringify_vector(arr, recursion_count);
|
return stringify_vector(operator Array(), recursion_count);
|
||||||
}
|
}
|
||||||
case OBJECT: {
|
case OBJECT: {
|
||||||
if (_get_obj().obj) {
|
if (_get_obj().obj) {
|
||||||
|
|
|
@ -1708,7 +1708,7 @@ static String rtos_fix(double p_value) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_string_func, void *p_store_string_ud, EncodeResourceFunc p_encode_res_func, void *p_encode_res_ud, int recursion_count) {
|
Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_string_func, void *p_store_string_ud, EncodeResourceFunc p_encode_res_func, void *p_encode_res_ud, int p_recursion_count) {
|
||||||
switch (p_variant.get_type()) {
|
switch (p_variant.get_type()) {
|
||||||
case Variant::NIL: {
|
case Variant::NIL: {
|
||||||
p_store_string_func(p_store_string_ud, "null");
|
p_store_string_func(p_store_string_ud, "null");
|
||||||
|
@ -1730,10 +1730,11 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
|
||||||
} break;
|
} break;
|
||||||
case Variant::STRING: {
|
case Variant::STRING: {
|
||||||
String str = p_variant;
|
String str = p_variant;
|
||||||
|
|
||||||
str = "\"" + str.c_escape_multiline() + "\"";
|
str = "\"" + str.c_escape_multiline() + "\"";
|
||||||
p_store_string_func(p_store_string_ud, str);
|
p_store_string_func(p_store_string_ud, str);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
// Math types.
|
||||||
case Variant::VECTOR2: {
|
case Variant::VECTOR2: {
|
||||||
Vector2 v = p_variant;
|
Vector2 v = p_variant;
|
||||||
p_store_string_func(p_store_string_ud, "Vector2(" + rtos_fix(v.x) + ", " + rtos_fix(v.y) + ")");
|
p_store_string_func(p_store_string_ud, "Vector2(" + rtos_fix(v.x) + ", " + rtos_fix(v.y) + ")");
|
||||||
|
@ -1745,12 +1746,10 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
|
||||||
case Variant::RECT2: {
|
case Variant::RECT2: {
|
||||||
Rect2 aabb = p_variant;
|
Rect2 aabb = p_variant;
|
||||||
p_store_string_func(p_store_string_ud, "Rect2(" + rtos_fix(aabb.position.x) + ", " + rtos_fix(aabb.position.y) + ", " + rtos_fix(aabb.size.x) + ", " + rtos_fix(aabb.size.y) + ")");
|
p_store_string_func(p_store_string_ud, "Rect2(" + rtos_fix(aabb.position.x) + ", " + rtos_fix(aabb.position.y) + ", " + rtos_fix(aabb.size.x) + ", " + rtos_fix(aabb.size.y) + ")");
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
case Variant::RECT2I: {
|
case Variant::RECT2I: {
|
||||||
Rect2i aabb = p_variant;
|
Rect2i aabb = p_variant;
|
||||||
p_store_string_func(p_store_string_ud, "Rect2i(" + itos(aabb.position.x) + ", " + itos(aabb.position.y) + ", " + itos(aabb.size.x) + ", " + itos(aabb.size.y) + ")");
|
p_store_string_func(p_store_string_ud, "Rect2i(" + itos(aabb.position.x) + ", " + itos(aabb.position.y) + ", " + itos(aabb.size.x) + ", " + itos(aabb.size.y) + ")");
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
case Variant::VECTOR3: {
|
case Variant::VECTOR3: {
|
||||||
Vector3 v = p_variant;
|
Vector3 v = p_variant;
|
||||||
|
@ -1771,17 +1770,14 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
|
||||||
case Variant::PLANE: {
|
case Variant::PLANE: {
|
||||||
Plane p = p_variant;
|
Plane p = p_variant;
|
||||||
p_store_string_func(p_store_string_ud, "Plane(" + rtos_fix(p.normal.x) + ", " + rtos_fix(p.normal.y) + ", " + rtos_fix(p.normal.z) + ", " + rtos_fix(p.d) + ")");
|
p_store_string_func(p_store_string_ud, "Plane(" + rtos_fix(p.normal.x) + ", " + rtos_fix(p.normal.y) + ", " + rtos_fix(p.normal.z) + ", " + rtos_fix(p.d) + ")");
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
case Variant::AABB: {
|
case Variant::AABB: {
|
||||||
AABB aabb = p_variant;
|
AABB aabb = p_variant;
|
||||||
p_store_string_func(p_store_string_ud, "AABB(" + rtos_fix(aabb.position.x) + ", " + rtos_fix(aabb.position.y) + ", " + rtos_fix(aabb.position.z) + ", " + rtos_fix(aabb.size.x) + ", " + rtos_fix(aabb.size.y) + ", " + rtos_fix(aabb.size.z) + ")");
|
p_store_string_func(p_store_string_ud, "AABB(" + rtos_fix(aabb.position.x) + ", " + rtos_fix(aabb.position.y) + ", " + rtos_fix(aabb.position.z) + ", " + rtos_fix(aabb.size.x) + ", " + rtos_fix(aabb.size.y) + ", " + rtos_fix(aabb.size.z) + ")");
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
case Variant::QUATERNION: {
|
case Variant::QUATERNION: {
|
||||||
Quaternion quaternion = p_variant;
|
Quaternion quaternion = p_variant;
|
||||||
p_store_string_func(p_store_string_ud, "Quaternion(" + rtos_fix(quaternion.x) + ", " + rtos_fix(quaternion.y) + ", " + rtos_fix(quaternion.z) + ", " + rtos_fix(quaternion.w) + ")");
|
p_store_string_func(p_store_string_ud, "Quaternion(" + rtos_fix(quaternion.x) + ", " + rtos_fix(quaternion.y) + ", " + rtos_fix(quaternion.z) + ", " + rtos_fix(quaternion.w) + ")");
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
case Variant::TRANSFORM2D: {
|
case Variant::TRANSFORM2D: {
|
||||||
String s = "Transform2D(";
|
String s = "Transform2D(";
|
||||||
|
@ -1796,7 +1792,6 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
|
||||||
}
|
}
|
||||||
|
|
||||||
p_store_string_func(p_store_string_ud, s + ")");
|
p_store_string_func(p_store_string_ud, s + ")");
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
case Variant::BASIS: {
|
case Variant::BASIS: {
|
||||||
String s = "Basis(";
|
String s = "Basis(";
|
||||||
|
@ -1811,7 +1806,6 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
|
||||||
}
|
}
|
||||||
|
|
||||||
p_store_string_func(p_store_string_ud, s + ")");
|
p_store_string_func(p_store_string_ud, s + ")");
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
case Variant::TRANSFORM3D: {
|
case Variant::TRANSFORM3D: {
|
||||||
String s = "Transform3D(";
|
String s = "Transform3D(";
|
||||||
|
@ -1845,30 +1839,23 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
|
||||||
p_store_string_func(p_store_string_ud, s + ")");
|
p_store_string_func(p_store_string_ud, s + ")");
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
// misc types
|
// Misc types.
|
||||||
case Variant::COLOR: {
|
case Variant::COLOR: {
|
||||||
Color c = p_variant;
|
Color c = p_variant;
|
||||||
p_store_string_func(p_store_string_ud, "Color(" + rtos_fix(c.r) + ", " + rtos_fix(c.g) + ", " + rtos_fix(c.b) + ", " + rtos_fix(c.a) + ")");
|
p_store_string_func(p_store_string_ud, "Color(" + rtos_fix(c.r) + ", " + rtos_fix(c.g) + ", " + rtos_fix(c.b) + ", " + rtos_fix(c.a) + ")");
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
case Variant::STRING_NAME: {
|
case Variant::STRING_NAME: {
|
||||||
String str = p_variant;
|
String str = p_variant;
|
||||||
|
|
||||||
str = "&\"" + str.c_escape() + "\"";
|
str = "&\"" + str.c_escape() + "\"";
|
||||||
p_store_string_func(p_store_string_ud, str);
|
p_store_string_func(p_store_string_ud, str);
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
case Variant::NODE_PATH: {
|
case Variant::NODE_PATH: {
|
||||||
String str = p_variant;
|
String str = p_variant;
|
||||||
|
|
||||||
str = "NodePath(\"" + str.c_escape() + "\")";
|
str = "NodePath(\"" + str.c_escape() + "\")";
|
||||||
p_store_string_func(p_store_string_ud, str);
|
p_store_string_func(p_store_string_ud, str);
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Variant::RID: {
|
case Variant::RID: {
|
||||||
RID rid = p_variant;
|
RID rid = p_variant;
|
||||||
|
|
||||||
if (rid == RID()) {
|
if (rid == RID()) {
|
||||||
p_store_string_func(p_store_string_ud, "RID()");
|
p_store_string_func(p_store_string_ud, "RID()");
|
||||||
} else {
|
} else {
|
||||||
|
@ -1885,6 +1872,13 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Variant::OBJECT: {
|
case Variant::OBJECT: {
|
||||||
|
if (unlikely(p_recursion_count > MAX_RECURSION)) {
|
||||||
|
ERR_PRINT("Max recursion reached");
|
||||||
|
p_store_string_func(p_store_string_ud, "null");
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
p_recursion_count++;
|
||||||
|
|
||||||
Object *obj = p_variant.get_validated_object();
|
Object *obj = p_variant.get_validated_object();
|
||||||
|
|
||||||
if (!obj) {
|
if (!obj) {
|
||||||
|
@ -1934,21 +1928,20 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
|
||||||
}
|
}
|
||||||
|
|
||||||
p_store_string_func(p_store_string_ud, "\"" + E.name + "\":");
|
p_store_string_func(p_store_string_ud, "\"" + E.name + "\":");
|
||||||
write(obj->get(E.name), p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud);
|
write(obj->get(E.name), p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud, p_recursion_count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
p_store_string_func(p_store_string_ud, ")\n");
|
p_store_string_func(p_store_string_ud, ")\n");
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Variant::DICTIONARY: {
|
case Variant::DICTIONARY: {
|
||||||
Dictionary dict = p_variant;
|
Dictionary dict = p_variant;
|
||||||
if (recursion_count > MAX_RECURSION) {
|
if (unlikely(p_recursion_count > MAX_RECURSION)) {
|
||||||
ERR_PRINT("Max recursion reached");
|
ERR_PRINT("Max recursion reached");
|
||||||
p_store_string_func(p_store_string_ud, "{}");
|
p_store_string_func(p_store_string_ud, "{}");
|
||||||
} else {
|
} else {
|
||||||
recursion_count++;
|
p_recursion_count++;
|
||||||
|
|
||||||
List<Variant> keys;
|
List<Variant> keys;
|
||||||
dict.get_key_list(&keys);
|
dict.get_key_list(&keys);
|
||||||
|
@ -1961,9 +1954,9 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
|
||||||
|
|
||||||
p_store_string_func(p_store_string_ud, "{\n");
|
p_store_string_func(p_store_string_ud, "{\n");
|
||||||
for (List<Variant>::Element *E = keys.front(); E; E = E->next()) {
|
for (List<Variant>::Element *E = keys.front(); E; E = E->next()) {
|
||||||
write(E->get(), p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud, recursion_count);
|
write(E->get(), p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud, p_recursion_count);
|
||||||
p_store_string_func(p_store_string_ud, ": ");
|
p_store_string_func(p_store_string_ud, ": ");
|
||||||
write(dict[E->get()], p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud, recursion_count);
|
write(dict[E->get()], p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud, p_recursion_count);
|
||||||
if (E->next()) {
|
if (E->next()) {
|
||||||
p_store_string_func(p_store_string_ud, ",\n");
|
p_store_string_func(p_store_string_ud, ",\n");
|
||||||
} else {
|
} else {
|
||||||
|
@ -1973,7 +1966,6 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
|
||||||
|
|
||||||
p_store_string_func(p_store_string_ud, "}");
|
p_store_string_func(p_store_string_ud, "}");
|
||||||
}
|
}
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Variant::ARRAY: {
|
case Variant::ARRAY: {
|
||||||
|
@ -2009,11 +2001,11 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
|
||||||
p_store_string_func(p_store_string_ud, "](");
|
p_store_string_func(p_store_string_ud, "](");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (recursion_count > MAX_RECURSION) {
|
if (unlikely(p_recursion_count > MAX_RECURSION)) {
|
||||||
ERR_PRINT("Max recursion reached");
|
ERR_PRINT("Max recursion reached");
|
||||||
p_store_string_func(p_store_string_ud, "[]");
|
p_store_string_func(p_store_string_ud, "[]");
|
||||||
} else {
|
} else {
|
||||||
recursion_count++;
|
p_recursion_count++;
|
||||||
|
|
||||||
p_store_string_func(p_store_string_ud, "[");
|
p_store_string_func(p_store_string_ud, "[");
|
||||||
int len = array.size();
|
int len = array.size();
|
||||||
|
@ -2021,7 +2013,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
p_store_string_func(p_store_string_ud, ", ");
|
p_store_string_func(p_store_string_ud, ", ");
|
||||||
}
|
}
|
||||||
write(array[i], p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud, recursion_count);
|
write(array[i], p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud, p_recursion_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
p_store_string_func(p_store_string_ud, "]");
|
p_store_string_func(p_store_string_ud, "]");
|
||||||
|
@ -2030,7 +2022,6 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
|
||||||
if (array.get_typed_builtin() != Variant::NIL) {
|
if (array.get_typed_builtin() != Variant::NIL) {
|
||||||
p_store_string_func(p_store_string_ud, ")");
|
p_store_string_func(p_store_string_ud, ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Variant::PACKED_BYTE_ARRAY: {
|
case Variant::PACKED_BYTE_ARRAY: {
|
||||||
|
@ -2048,7 +2039,6 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
|
||||||
}
|
}
|
||||||
|
|
||||||
p_store_string_func(p_store_string_ud, ")");
|
p_store_string_func(p_store_string_ud, ")");
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
case Variant::PACKED_INT32_ARRAY: {
|
case Variant::PACKED_INT32_ARRAY: {
|
||||||
p_store_string_func(p_store_string_ud, "PackedInt32Array(");
|
p_store_string_func(p_store_string_ud, "PackedInt32Array(");
|
||||||
|
@ -2065,7 +2055,6 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
|
||||||
}
|
}
|
||||||
|
|
||||||
p_store_string_func(p_store_string_ud, ")");
|
p_store_string_func(p_store_string_ud, ")");
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
case Variant::PACKED_INT64_ARRAY: {
|
case Variant::PACKED_INT64_ARRAY: {
|
||||||
p_store_string_func(p_store_string_ud, "PackedInt64Array(");
|
p_store_string_func(p_store_string_ud, "PackedInt64Array(");
|
||||||
|
@ -2082,7 +2071,6 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
|
||||||
}
|
}
|
||||||
|
|
||||||
p_store_string_func(p_store_string_ud, ")");
|
p_store_string_func(p_store_string_ud, ")");
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
case Variant::PACKED_FLOAT32_ARRAY: {
|
case Variant::PACKED_FLOAT32_ARRAY: {
|
||||||
p_store_string_func(p_store_string_ud, "PackedFloat32Array(");
|
p_store_string_func(p_store_string_ud, "PackedFloat32Array(");
|
||||||
|
@ -2098,7 +2086,6 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
|
||||||
}
|
}
|
||||||
|
|
||||||
p_store_string_func(p_store_string_ud, ")");
|
p_store_string_func(p_store_string_ud, ")");
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
case Variant::PACKED_FLOAT64_ARRAY: {
|
case Variant::PACKED_FLOAT64_ARRAY: {
|
||||||
p_store_string_func(p_store_string_ud, "PackedFloat64Array(");
|
p_store_string_func(p_store_string_ud, "PackedFloat64Array(");
|
||||||
|
@ -2114,7 +2101,6 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
|
||||||
}
|
}
|
||||||
|
|
||||||
p_store_string_func(p_store_string_ud, ")");
|
p_store_string_func(p_store_string_ud, ")");
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
case Variant::PACKED_STRING_ARRAY: {
|
case Variant::PACKED_STRING_ARRAY: {
|
||||||
p_store_string_func(p_store_string_ud, "PackedStringArray(");
|
p_store_string_func(p_store_string_ud, "PackedStringArray(");
|
||||||
|
@ -2130,7 +2116,6 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
|
||||||
}
|
}
|
||||||
|
|
||||||
p_store_string_func(p_store_string_ud, ")");
|
p_store_string_func(p_store_string_ud, ")");
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
case Variant::PACKED_VECTOR2_ARRAY: {
|
case Variant::PACKED_VECTOR2_ARRAY: {
|
||||||
p_store_string_func(p_store_string_ud, "PackedVector2Array(");
|
p_store_string_func(p_store_string_ud, "PackedVector2Array(");
|
||||||
|
@ -2146,7 +2131,6 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
|
||||||
}
|
}
|
||||||
|
|
||||||
p_store_string_func(p_store_string_ud, ")");
|
p_store_string_func(p_store_string_ud, ")");
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
case Variant::PACKED_VECTOR3_ARRAY: {
|
case Variant::PACKED_VECTOR3_ARRAY: {
|
||||||
p_store_string_func(p_store_string_ud, "PackedVector3Array(");
|
p_store_string_func(p_store_string_ud, "PackedVector3Array(");
|
||||||
|
@ -2162,7 +2146,6 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
|
||||||
}
|
}
|
||||||
|
|
||||||
p_store_string_func(p_store_string_ud, ")");
|
p_store_string_func(p_store_string_ud, ")");
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
case Variant::PACKED_COLOR_ARRAY: {
|
case Variant::PACKED_COLOR_ARRAY: {
|
||||||
p_store_string_func(p_store_string_ud, "PackedColorArray(");
|
p_store_string_func(p_store_string_ud, "PackedColorArray(");
|
||||||
|
@ -2178,8 +2161,8 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
|
||||||
}
|
}
|
||||||
|
|
||||||
p_store_string_func(p_store_string_ud, ")");
|
p_store_string_func(p_store_string_ud, ")");
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
ERR_PRINT("Unknown variant type");
|
ERR_PRINT("Unknown variant type");
|
||||||
return ERR_BUG;
|
return ERR_BUG;
|
||||||
|
|
|
@ -160,7 +160,7 @@ public:
|
||||||
typedef Error (*StoreStringFunc)(void *ud, const String &p_string);
|
typedef Error (*StoreStringFunc)(void *ud, const String &p_string);
|
||||||
typedef String (*EncodeResourceFunc)(void *ud, const Ref<Resource> &p_resource);
|
typedef String (*EncodeResourceFunc)(void *ud, const Ref<Resource> &p_resource);
|
||||||
|
|
||||||
static Error write(const Variant &p_variant, StoreStringFunc p_store_string_func, void *p_store_string_ud, EncodeResourceFunc p_encode_res_func, void *p_encode_res_ud, int recursion_count = 0);
|
static Error write(const Variant &p_variant, StoreStringFunc p_store_string_func, void *p_store_string_ud, EncodeResourceFunc p_encode_res_func, void *p_encode_res_ud, int p_recursion_count = 0);
|
||||||
static Error write_to_string(const Variant &p_variant, String &r_string, EncodeResourceFunc p_encode_res_func = nullptr, void *p_encode_res_ud = nullptr);
|
static Error write_to_string(const Variant &p_variant, String &r_string, EncodeResourceFunc p_encode_res_func = nullptr, void *p_encode_res_ud = nullptr);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -341,7 +341,7 @@
|
||||||
- 1.0: Linear
|
- 1.0: Linear
|
||||||
- Greater than 1.0 (exclusive): Ease in
|
- Greater than 1.0 (exclusive): Ease in
|
||||||
[/codeblock]
|
[/codeblock]
|
||||||
[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/ease_cheatsheet.png]ease() curve values cheatsheet[/url]
|
[url=https://raw.githubusercontent.com/godotengine/godot-docs/4.1/img/ease_cheatsheet.png]ease() curve values cheatsheet[/url]
|
||||||
See also [method smoothstep]. If you need to perform more advanced transitions, use [method Tween.interpolate_value].
|
See also [method smoothstep]. If you need to perform more advanced transitions, use [method Tween.interpolate_value].
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
|
@ -1203,7 +1203,7 @@
|
||||||
smoothstep(0, 2, 2.0) # Returns 1.0
|
smoothstep(0, 2, 2.0) # Returns 1.0
|
||||||
[/codeblock]
|
[/codeblock]
|
||||||
Compared to [method ease] with a curve value of [code]-1.6521[/code], [method smoothstep] returns the smoothest possible curve with no sudden changes in the derivative. If you need to perform more advanced transitions, use [Tween] or [AnimationPlayer].
|
Compared to [method ease] with a curve value of [code]-1.6521[/code], [method smoothstep] returns the smoothest possible curve with no sudden changes in the derivative. If you need to perform more advanced transitions, use [Tween] or [AnimationPlayer].
|
||||||
[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/smoothstep_ease_comparison.png]Comparison between smoothstep() and ease(x, -1.6521) return values[/url]
|
[url=https://raw.githubusercontent.com/godotengine/godot-docs/4.1/img/smoothstep_ease_comparison.png]Comparison between smoothstep() and ease(x, -1.6521) return values[/url]
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="snapped">
|
<method name="snapped">
|
||||||
|
@ -2032,6 +2032,18 @@
|
||||||
<constant name="KEY_LAUNCHF" value="4194415" enum="Key">
|
<constant name="KEY_LAUNCHF" value="4194415" enum="Key">
|
||||||
Launch Shortcut F key.
|
Launch Shortcut F key.
|
||||||
</constant>
|
</constant>
|
||||||
|
<constant name="KEY_GLOBE" value="4194416" enum="Key">
|
||||||
|
"Globe" key on Mac / iPad keyboard.
|
||||||
|
</constant>
|
||||||
|
<constant name="KEY_KEYBOARD" value="4194417" enum="Key">
|
||||||
|
"On-screen keyboard" key on iPad keyboard.
|
||||||
|
</constant>
|
||||||
|
<constant name="KEY_JIS_EISU" value="4194418" enum="Key">
|
||||||
|
英数 key on Mac keyboard.
|
||||||
|
</constant>
|
||||||
|
<constant name="KEY_JIS_KANA" value="4194419" enum="Key">
|
||||||
|
かな key on Mac keyboard.
|
||||||
|
</constant>
|
||||||
<constant name="KEY_UNKNOWN" value="8388607" enum="Key">
|
<constant name="KEY_UNKNOWN" value="8388607" enum="Key">
|
||||||
Unknown key.
|
Unknown key.
|
||||||
</constant>
|
</constant>
|
||||||
|
@ -2248,18 +2260,6 @@
|
||||||
<constant name="KEY_SECTION" value="167" enum="Key">
|
<constant name="KEY_SECTION" value="167" enum="Key">
|
||||||
§ key.
|
§ key.
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="KEY_GLOBE" value="4194416" enum="Key">
|
|
||||||
"Globe" key on Mac / iPad keyboard.
|
|
||||||
</constant>
|
|
||||||
<constant name="KEY_KEYBOARD" value="4194417" enum="Key">
|
|
||||||
"On-screen keyboard" key iPad keyboard.
|
|
||||||
</constant>
|
|
||||||
<constant name="KEY_JIS_EISU" value="4194418" enum="Key">
|
|
||||||
英数 key on Mac keyboard.
|
|
||||||
</constant>
|
|
||||||
<constant name="KEY_JIS_KANA" value="4194419" enum="Key">
|
|
||||||
かな key on Mac keyboard.
|
|
||||||
</constant>
|
|
||||||
<constant name="KEY_CODE_MASK" value="8388607" enum="KeyModifierMask" is_bitfield="true">
|
<constant name="KEY_CODE_MASK" value="8388607" enum="KeyModifierMask" is_bitfield="true">
|
||||||
Key Code mask.
|
Key Code mask.
|
||||||
</constant>
|
</constant>
|
||||||
|
@ -2435,61 +2435,66 @@
|
||||||
The maximum number of game controller axes: OpenVR supports up to 5 Joysticks making a total of 10 axes.
|
The maximum number of game controller axes: OpenVR supports up to 5 Joysticks making a total of 10 axes.
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="MIDI_MESSAGE_NONE" value="0" enum="MIDIMessage">
|
<constant name="MIDI_MESSAGE_NONE" value="0" enum="MIDIMessage">
|
||||||
Enum value which doesn't correspond to any MIDI message. This is used to initialize [enum MIDIMessage] properties with a generic state.
|
Does not correspond to any MIDI message. This is the default value of [member InputEventMIDI.message].
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="MIDI_MESSAGE_NOTE_OFF" value="8" enum="MIDIMessage">
|
<constant name="MIDI_MESSAGE_NOTE_OFF" value="8" enum="MIDIMessage">
|
||||||
MIDI note OFF message. Not all MIDI devices send this event; some send [constant MIDI_MESSAGE_NOTE_ON] with zero velocity instead. See the documentation of [InputEventMIDI] for information of how to use MIDI inputs.
|
MIDI message sent when a note is released.
|
||||||
|
[b]Note:[/b] Not all MIDI devices send this message; some may send [constant MIDI_MESSAGE_NOTE_ON] with [member InputEventMIDI.velocity] set to [code]0[/code].
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="MIDI_MESSAGE_NOTE_ON" value="9" enum="MIDIMessage">
|
<constant name="MIDI_MESSAGE_NOTE_ON" value="9" enum="MIDIMessage">
|
||||||
MIDI note ON message. Some MIDI devices send this event with velocity zero instead of [constant MIDI_MESSAGE_NOTE_OFF], but implementations vary. See the documentation of [InputEventMIDI] for information of how to use MIDI inputs.
|
MIDI message sent when a note is pressed.
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="MIDI_MESSAGE_AFTERTOUCH" value="10" enum="MIDIMessage">
|
<constant name="MIDI_MESSAGE_AFTERTOUCH" value="10" enum="MIDIMessage">
|
||||||
MIDI aftertouch message. This message is most often sent by pressing down on the key after it "bottoms out".
|
MIDI message sent to indicate a change in pressure while a note is being pressed down, also called aftertouch.
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="MIDI_MESSAGE_CONTROL_CHANGE" value="11" enum="MIDIMessage">
|
<constant name="MIDI_MESSAGE_CONTROL_CHANGE" value="11" enum="MIDIMessage">
|
||||||
MIDI control change message. This message is sent when a controller value changes. Controllers include devices such as pedals and levers.
|
MIDI message sent when a controller value changes. In a MIDI device, a controller is any input that doesn't play notes. These may include sliders for volume, balance, and panning, as well as switches and pedals. See the [url=https://en.wikipedia.org/wiki/General_MIDI#Controller_events]General MIDI specification[/url] for a small list.
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="MIDI_MESSAGE_PROGRAM_CHANGE" value="12" enum="MIDIMessage">
|
<constant name="MIDI_MESSAGE_PROGRAM_CHANGE" value="12" enum="MIDIMessage">
|
||||||
MIDI program change message. This message sent when the program patch number changes.
|
MIDI message sent when the MIDI device changes its current instrument (also called [i]program[/i] or [i]preset[/i]).
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="MIDI_MESSAGE_CHANNEL_PRESSURE" value="13" enum="MIDIMessage">
|
<constant name="MIDI_MESSAGE_CHANNEL_PRESSURE" value="13" enum="MIDIMessage">
|
||||||
MIDI channel pressure message. This message is most often sent by pressing down on the key after it "bottoms out". This message is different from polyphonic after-touch as it indicates the highest pressure across all keys.
|
MIDI message sent to indicate a change in pressure for the whole channel. Some MIDI devices may send this instead of [constant MIDI_MESSAGE_AFTERTOUCH].
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="MIDI_MESSAGE_PITCH_BEND" value="14" enum="MIDIMessage">
|
<constant name="MIDI_MESSAGE_PITCH_BEND" value="14" enum="MIDIMessage">
|
||||||
MIDI pitch bend message. This message is sent to indicate a change in the pitch bender (wheel or lever, typically).
|
MIDI message sent when the value of the pitch bender changes, usually a wheel on the MIDI device.
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="MIDI_MESSAGE_SYSTEM_EXCLUSIVE" value="240" enum="MIDIMessage">
|
<constant name="MIDI_MESSAGE_SYSTEM_EXCLUSIVE" value="240" enum="MIDIMessage">
|
||||||
MIDI system exclusive message. This has behavior exclusive to the device you're receiving input from. Getting this data is not implemented in Godot.
|
MIDI system exclusive (SysEx) message. This type of message is not standardized and it's highly dependent on the MIDI device sending it.
|
||||||
|
[b]Note:[/b] Getting this message's data from [InputEventMIDI] is not implemented.
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="MIDI_MESSAGE_QUARTER_FRAME" value="241" enum="MIDIMessage">
|
<constant name="MIDI_MESSAGE_QUARTER_FRAME" value="241" enum="MIDIMessage">
|
||||||
MIDI quarter frame message. Contains timing information that is used to synchronize MIDI devices. Getting this data is not implemented in Godot.
|
MIDI message sent every quarter frame to keep connected MIDI devices synchronized. Related to [constant MIDI_MESSAGE_TIMING_CLOCK].
|
||||||
|
[b]Note:[/b] Getting this message's data from [InputEventMIDI] is not implemented.
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="MIDI_MESSAGE_SONG_POSITION_POINTER" value="242" enum="MIDIMessage">
|
<constant name="MIDI_MESSAGE_SONG_POSITION_POINTER" value="242" enum="MIDIMessage">
|
||||||
MIDI song position pointer message. Gives the number of 16th notes since the start of the song. Getting this data is not implemented in Godot.
|
MIDI message sent to jump onto a new position in the current sequence or song.
|
||||||
|
[b]Note:[/b] Getting this message's data from [InputEventMIDI] is not implemented.
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="MIDI_MESSAGE_SONG_SELECT" value="243" enum="MIDIMessage">
|
<constant name="MIDI_MESSAGE_SONG_SELECT" value="243" enum="MIDIMessage">
|
||||||
MIDI song select message. Specifies which sequence or song is to be played. Getting this data is not implemented in Godot.
|
MIDI message sent to select a sequence or song to play.
|
||||||
|
[b]Note:[/b] Getting this message's data from [InputEventMIDI] is not implemented.
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="MIDI_MESSAGE_TUNE_REQUEST" value="246" enum="MIDIMessage">
|
<constant name="MIDI_MESSAGE_TUNE_REQUEST" value="246" enum="MIDIMessage">
|
||||||
MIDI tune request message. Upon receiving a tune request, all analog synthesizers should tune their oscillators.
|
MIDI message sent to request a tuning calibration. Used on analog synthesizers. Most modern MIDI devices do not need this message.
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="MIDI_MESSAGE_TIMING_CLOCK" value="248" enum="MIDIMessage">
|
<constant name="MIDI_MESSAGE_TIMING_CLOCK" value="248" enum="MIDIMessage">
|
||||||
MIDI timing clock message. Sent 24 times per quarter note when synchronization is required.
|
MIDI message sent 24 times after [constant MIDI_MESSAGE_QUARTER_FRAME], to keep connected MIDI devices synchronized.
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="MIDI_MESSAGE_START" value="250" enum="MIDIMessage">
|
<constant name="MIDI_MESSAGE_START" value="250" enum="MIDIMessage">
|
||||||
MIDI start message. Start the current sequence playing. This message will be followed with Timing Clocks.
|
MIDI message sent to start the current sequence or song from the beginning.
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="MIDI_MESSAGE_CONTINUE" value="251" enum="MIDIMessage">
|
<constant name="MIDI_MESSAGE_CONTINUE" value="251" enum="MIDIMessage">
|
||||||
MIDI continue message. Continue at the point the sequence was stopped.
|
MIDI message sent to resume from the point the current sequence or song was paused.
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="MIDI_MESSAGE_STOP" value="252" enum="MIDIMessage">
|
<constant name="MIDI_MESSAGE_STOP" value="252" enum="MIDIMessage">
|
||||||
MIDI stop message. Stop the current sequence.
|
MIDI message sent to pause the current sequence or song.
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="MIDI_MESSAGE_ACTIVE_SENSING" value="254" enum="MIDIMessage">
|
<constant name="MIDI_MESSAGE_ACTIVE_SENSING" value="254" enum="MIDIMessage">
|
||||||
MIDI active sensing message. This message is intended to be sent repeatedly to tell the receiver that a connection is alive.
|
MIDI message sent repeatedly while the MIDI device is idle, to tell the receiver that the connection is alive. Most MIDI devices do not send this message.
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="MIDI_MESSAGE_SYSTEM_RESET" value="255" enum="MIDIMessage">
|
<constant name="MIDI_MESSAGE_SYSTEM_RESET" value="255" enum="MIDIMessage">
|
||||||
MIDI system reset message. Reset all receivers in the system to power-up status. It should not be sent on power-up itself.
|
MIDI message sent to reset a MIDI device to its default state, as if it was just turned on. It should not be sent when the MIDI device is being turned on.
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="OK" value="0" enum="Error">
|
<constant name="OK" value="0" enum="Error">
|
||||||
Methods that return [enum Error] return [constant OK] when no error occurred.
|
Methods that return [enum Error] return [constant OK] when no error occurred.
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
[/gdscript]
|
[/gdscript]
|
||||||
[csharp]
|
[csharp]
|
||||||
AStarGrid2D astarGrid = new AStarGrid2D();
|
AStarGrid2D astarGrid = new AStarGrid2D();
|
||||||
astarGrid.Size = new Vector2I(32, 32);
|
astarGrid.Region = new Rect2I(0, 0, 32, 32);
|
||||||
astarGrid.CellSize = new Vector2I(16, 16);
|
astarGrid.CellSize = new Vector2I(16, 16);
|
||||||
astarGrid.Update();
|
astarGrid.Update();
|
||||||
GD.Print(astarGrid.GetIdPath(Vector2I.Zero, new Vector2I(3, 4))); // prints (0, 0), (1, 1), (2, 2), (3, 3), (3, 4)
|
GD.Print(astarGrid.GetIdPath(Vector2I.Zero, new Vector2I(3, 4))); // prints (0, 0), (1, 1), (2, 2), (3, 3), (3, 4)
|
||||||
|
@ -67,7 +67,7 @@
|
||||||
<param index="1" name="to_id" type="Vector2i" />
|
<param index="1" name="to_id" type="Vector2i" />
|
||||||
<description>
|
<description>
|
||||||
Returns an array with the points that are in the path found by AStarGrid2D between the given points. The array is ordered from the starting point to the ending point of the path.
|
Returns an array with the points that are in the path found by AStarGrid2D between the given points. The array is ordered from the starting point to the ending point of the path.
|
||||||
[b]Note:[/b] This method is not thread-safe. If called from a [Thread], it will return an empty [PackedVector3Array] and will print an error message.
|
[b]Note:[/b] This method is not thread-safe. If called from a [Thread], it will return an empty [PackedVector2Array] and will print an error message.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="get_point_position" qualifiers="const">
|
<method name="get_point_position" qualifiers="const">
|
||||||
|
|
|
@ -8,21 +8,23 @@
|
||||||
[codeblocks]
|
[codeblocks]
|
||||||
[gdscript]
|
[gdscript]
|
||||||
# This creates an animation that makes the node "Enemy" move to the right by
|
# This creates an animation that makes the node "Enemy" move to the right by
|
||||||
# 100 pixels in 0.5 seconds.
|
# 100 pixels in 2.0 seconds.
|
||||||
var animation = Animation.new()
|
var animation = Animation.new()
|
||||||
var track_index = animation.add_track(Animation.TYPE_VALUE)
|
var track_index = animation.add_track(Animation.TYPE_VALUE)
|
||||||
animation.track_set_path(track_index, "Enemy:position:x")
|
animation.track_set_path(track_index, "Enemy:position:x")
|
||||||
animation.track_insert_key(track_index, 0.0, 0)
|
animation.track_insert_key(track_index, 0.0, 0)
|
||||||
animation.track_insert_key(track_index, 0.5, 100)
|
animation.track_insert_key(track_index, 2.0, 100)
|
||||||
|
animation.length = 2.0
|
||||||
[/gdscript]
|
[/gdscript]
|
||||||
[csharp]
|
[csharp]
|
||||||
// This creates an animation that makes the node "Enemy" move to the right by
|
// This creates an animation that makes the node "Enemy" move to the right by
|
||||||
// 100 pixels in 0.5 seconds.
|
// 100 pixels in 2.0 seconds.
|
||||||
var animation = new Animation();
|
var animation = new Animation();
|
||||||
int trackIndex = animation.AddTrack(Animation.TrackType.Value);
|
int trackIndex = animation.AddTrack(Animation.TrackType.Value);
|
||||||
animation.TrackSetPath(trackIndex, "Enemy:position:x");
|
animation.TrackSetPath(trackIndex, "Enemy:position:x");
|
||||||
animation.TrackInsertKey(trackIndex, 0.0f, 0);
|
animation.TrackInsertKey(trackIndex, 0.0f, 0);
|
||||||
animation.TrackInsertKey(trackIndex, 0.5f, 100);
|
animation.TrackInsertKey(trackIndex, 2.0f, 100);
|
||||||
|
animation.Length = 2.0f;
|
||||||
[/csharp]
|
[/csharp]
|
||||||
[/codeblocks]
|
[/codeblocks]
|
||||||
Animations are just data containers, and must be added to nodes such as an [AnimationPlayer] to be played back. Animation tracks have different types, each with its own set of dedicated methods. Check [enum TrackType] to see available types.
|
Animations are just data containers, and must be added to nodes such as an [AnimationPlayer] to be played back. Animation tracks have different types, each with its own set of dedicated methods. Check [enum TrackType] to see available types.
|
||||||
|
@ -257,7 +259,7 @@
|
||||||
<param index="0" name="track_idx" type="int" />
|
<param index="0" name="track_idx" type="int" />
|
||||||
<param index="1" name="to_animation" type="Animation" />
|
<param index="1" name="to_animation" type="Animation" />
|
||||||
<description>
|
<description>
|
||||||
Adds a new track that is a copy of the given track from [param to_animation].
|
Adds a new track to [param to_animation] that is a copy of the given track from this animation.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="find_track" qualifiers="const">
|
<method name="find_track" qualifiers="const">
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
<method name="_get_child_nodes" qualifiers="virtual const">
|
<method name="_get_child_nodes" qualifiers="virtual const">
|
||||||
<return type="Dictionary" />
|
<return type="Dictionary" />
|
||||||
<description>
|
<description>
|
||||||
When inheriting from [AnimationRootNode], implement this virtual method to return all children animation nodes in order as a [code]name: node[/code] dictionary.
|
When inheriting from [AnimationRootNode], implement this virtual method to return all child animation nodes in order as a [code]name: node[/code] dictionary.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="_get_parameter_default_value" qualifiers="virtual const">
|
<method name="_get_parameter_default_value" qualifiers="virtual const">
|
||||||
|
@ -115,7 +115,7 @@
|
||||||
<param index="7" name="sync" type="bool" default="true" />
|
<param index="7" name="sync" type="bool" default="true" />
|
||||||
<param index="8" name="test_only" type="bool" default="false" />
|
<param index="8" name="test_only" type="bool" default="false" />
|
||||||
<description>
|
<description>
|
||||||
Blend another animation node (in case this animation node contains children animation nodes). This function is only useful if you inherit from [AnimationRootNode] instead, else editors will not display your animation node for addition.
|
Blend another animation node (in case this animation node contains child animation nodes). This function is only useful if you inherit from [AnimationRootNode] instead, otherwise editors will not display your animation node for addition.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="find_input" qualifiers="const">
|
<method name="find_input" qualifiers="const">
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
Blends two of three animations additively inside of an [AnimationNodeBlendTree].
|
Blends two of three animations additively inside of an [AnimationNodeBlendTree].
|
||||||
</brief_description>
|
</brief_description>
|
||||||
<description>
|
<description>
|
||||||
A resource to add to an [AnimationNodeBlendTree]. Blends two animations out of three additively out of three based on the amounmt value.
|
A resource to add to an [AnimationNodeBlendTree]. Blends two animations out of three additively out of three based on the amount value.
|
||||||
This animation node has three inputs:
|
This animation node has three inputs:
|
||||||
- The base animation to add to
|
- The base animation to add to
|
||||||
- A "-add" animation to blend with when the blend amount is negative
|
- A "-add" animation to blend with when the blend amount is negative
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
Blends two of three animations linearly inside of an [AnimationNodeBlendTree].
|
Blends two of three animations linearly inside of an [AnimationNodeBlendTree].
|
||||||
</brief_description>
|
</brief_description>
|
||||||
<description>
|
<description>
|
||||||
A resource to add to an [AnimationNodeBlendTree]. Blends two animations out of three linearly out of three based on the amounmt value.
|
A resource to add to an [AnimationNodeBlendTree]. Blends two animations out of three linearly out of three based on the amount value.
|
||||||
This animation node has three inputs:
|
This animation node has three inputs:
|
||||||
- The base animation to blend with
|
- The base animation to blend with
|
||||||
- A "-blend" animation to blend with when the blend amount is negative value
|
- A "-blend" animation to blend with when the blend amount is negative value
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
A time-scaling animation node used in [AnimationTree].
|
A time-scaling animation node used in [AnimationTree].
|
||||||
</brief_description>
|
</brief_description>
|
||||||
<description>
|
<description>
|
||||||
Allows to scale the speed of the animation (or reverse it) in any children [AnimationNode]s. Setting it to [code]0.0[/code] will pause the animation.
|
Allows to scale the speed of the animation (or reverse it) in any child [AnimationNode]s. Setting it to [code]0.0[/code] will pause the animation.
|
||||||
</description>
|
</description>
|
||||||
<tutorials>
|
<tutorials>
|
||||||
<link title="Using AnimationTree">$DOCS_URL/tutorials/animation/animation_tree.html</link>
|
<link title="Using AnimationTree">$DOCS_URL/tutorials/animation/animation_tree.html</link>
|
||||||
|
|
|
@ -218,6 +218,11 @@
|
||||||
<param index="1" name="before" type="bool" default="true" />
|
<param index="1" name="before" type="bool" default="true" />
|
||||||
<description>
|
<description>
|
||||||
Finds the index of an existing value (or the insertion index that maintains sorting order, if the value is not yet present in the array) using binary search. Optionally, a [param before] specifier can be passed. If [code]false[/code], the returned index comes after all existing entries of the value in the array.
|
Finds the index of an existing value (or the insertion index that maintains sorting order, if the value is not yet present in the array) using binary search. Optionally, a [param before] specifier can be passed. If [code]false[/code], the returned index comes after all existing entries of the value in the array.
|
||||||
|
[codeblock]
|
||||||
|
var array = ["a", "b", "c", "c", "d", "e"]
|
||||||
|
print(array.bsearch("c", true)) # Prints 2, at the first matching element.
|
||||||
|
print(array.bsearch("c", false)) # Prints 4, after the last matching element, pointing to "d".
|
||||||
|
[/codeblock]
|
||||||
[b]Note:[/b] Calling [method bsearch] on an unsorted array results in unexpected behavior.
|
[b]Note:[/b] Calling [method bsearch] on an unsorted array results in unexpected behavior.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
|
@ -228,6 +233,7 @@
|
||||||
<param index="2" name="before" type="bool" default="true" />
|
<param index="2" name="before" type="bool" default="true" />
|
||||||
<description>
|
<description>
|
||||||
Finds the index of an existing value (or the insertion index that maintains sorting order, if the value is not yet present in the array) using binary search and a custom comparison method. Optionally, a [param before] specifier can be passed. If [code]false[/code], the returned index comes after all existing entries of the value in the array. The custom method receives two arguments (an element from the array and the value searched for) and must return [code]true[/code] if the first argument is less than the second, and return [code]false[/code] otherwise.
|
Finds the index of an existing value (or the insertion index that maintains sorting order, if the value is not yet present in the array) using binary search and a custom comparison method. Optionally, a [param before] specifier can be passed. If [code]false[/code], the returned index comes after all existing entries of the value in the array. The custom method receives two arguments (an element from the array and the value searched for) and must return [code]true[/code] if the first argument is less than the second, and return [code]false[/code] otherwise.
|
||||||
|
[b]Note:[/b] The custom method must accept the two arguments in any order, you cannot rely on that the first argument will always be from the array.
|
||||||
[b]Note:[/b] Calling [method bsearch_custom] on an unsorted array results in unexpected behavior.
|
[b]Note:[/b] Calling [method bsearch_custom] on an unsorted array results in unexpected behavior.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
|
@ -584,6 +590,7 @@
|
||||||
If either [param begin] or [param end] are negative, they will be relative to the end of the array (i.e. [code]arr.slice(0, -2)[/code] is a shorthand for [code]arr.slice(0, arr.size() - 2)[/code]).
|
If either [param begin] or [param end] are negative, they will be relative to the end of the array (i.e. [code]arr.slice(0, -2)[/code] is a shorthand for [code]arr.slice(0, arr.size() - 2)[/code]).
|
||||||
If specified, [param step] is the relative index between source elements. It can be negative, then [param begin] must be higher than [param end]. For example, [code][0, 1, 2, 3, 4, 5].slice(5, 1, -2)[/code] returns [code][5, 3][/code].
|
If specified, [param step] is the relative index between source elements. It can be negative, then [param begin] must be higher than [param end]. For example, [code][0, 1, 2, 3, 4, 5].slice(5, 1, -2)[/code] returns [code][5, 3][/code].
|
||||||
If [param deep] is true, each element will be copied by value rather than by reference.
|
If [param deep] is true, each element will be copied by value rather than by reference.
|
||||||
|
[b]Note:[/b] To include the first element when [param step] is negative, use [code]arr.slice(begin, -arr.size() - 1, step)[/code] (i.e. [code][0, 1, 2].slice(1, -4, -1)[/code] returns [code][1, 0][/code]).
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="sort">
|
<method name="sort">
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
See [OccluderInstance3D]'s documentation for instructions on setting up occlusion culling.
|
See [OccluderInstance3D]'s documentation for instructions on setting up occlusion culling.
|
||||||
</description>
|
</description>
|
||||||
<tutorials>
|
<tutorials>
|
||||||
|
<link title="Occlusion culling">$DOCS_URL/tutorials/3d/occlusion_culling.html</link>
|
||||||
</tutorials>
|
</tutorials>
|
||||||
<methods>
|
<methods>
|
||||||
<method name="set_arrays">
|
<method name="set_arrays">
|
||||||
|
|
|
@ -280,6 +280,8 @@
|
||||||
<return type="void" />
|
<return type="void" />
|
||||||
<param index="0" name="enable" type="bool" />
|
<param index="0" name="enable" type="bool" />
|
||||||
<description>
|
<description>
|
||||||
|
If set to [code]true[/code], all instances of [AudioStreamPlayback] will call [method AudioStreamPlayback._tag_used_streams] every mix step.
|
||||||
|
[b]Note:[/b] This is enabled by default in the editor, as it is used by editor plugins for the audio stream previews.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="swap_bus_effects">
|
<method name="swap_bus_effects">
|
||||||
|
|
|
@ -16,31 +16,39 @@
|
||||||
<method name="_get_beat_count" qualifiers="virtual const">
|
<method name="_get_beat_count" qualifiers="virtual const">
|
||||||
<return type="int" />
|
<return type="int" />
|
||||||
<description>
|
<description>
|
||||||
|
Overridable method. Should return the total number of beats of this audio stream. Used by the engine to determine the position of every beat.
|
||||||
|
Ideally, the returned value should be based off the stream's sample rate ([member AudioStreamWAV.mix_rate], for example).
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="_get_bpm" qualifiers="virtual const">
|
<method name="_get_bpm" qualifiers="virtual const">
|
||||||
<return type="float" />
|
<return type="float" />
|
||||||
<description>
|
<description>
|
||||||
|
Overridable method. Should return the tempo of this audio stream, in beats per minute (BPM). Used by the engine to determine the position of every beat.
|
||||||
|
Ideally, the returned value should be based off the stream's sample rate ([member AudioStreamWAV.mix_rate], for example).
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="_get_length" qualifiers="virtual const">
|
<method name="_get_length" qualifiers="virtual const">
|
||||||
<return type="float" />
|
<return type="float" />
|
||||||
<description>
|
<description>
|
||||||
|
Override this method to customize the returned value of [method get_length]. Should return the length of this audio stream, in seconds.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="_get_stream_name" qualifiers="virtual const">
|
<method name="_get_stream_name" qualifiers="virtual const">
|
||||||
<return type="String" />
|
<return type="String" />
|
||||||
<description>
|
<description>
|
||||||
|
Override this method to customize the name assigned to this audio stream. Unused by the engine.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="_instantiate_playback" qualifiers="virtual const">
|
<method name="_instantiate_playback" qualifiers="virtual const">
|
||||||
<return type="AudioStreamPlayback" />
|
<return type="AudioStreamPlayback" />
|
||||||
<description>
|
<description>
|
||||||
|
Override this method to customize the returned value of [method instantiate_playback]. Should returned a new [AudioStreamPlayback] created when the stream is played (such as by an [AudioStreamPlayer])..
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="_is_monophonic" qualifiers="virtual const">
|
<method name="_is_monophonic" qualifiers="virtual const">
|
||||||
<return type="bool" />
|
<return type="bool" />
|
||||||
<description>
|
<description>
|
||||||
|
Override this method to customize the returned value of [method is_monophonic]. Should return [code]true[/code] if this audio stream only supports one channel.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="get_length" qualifiers="const">
|
<method name="get_length" qualifiers="const">
|
||||||
|
@ -52,13 +60,13 @@
|
||||||
<method name="instantiate_playback">
|
<method name="instantiate_playback">
|
||||||
<return type="AudioStreamPlayback" />
|
<return type="AudioStreamPlayback" />
|
||||||
<description>
|
<description>
|
||||||
Returns an AudioStreamPlayback. Useful for when you want to extend [method _instantiate_playback] but call [method instantiate_playback] from an internally held AudioStream subresource. An example of this can be found in the source files for [code]AudioStreamRandomPitch::instantiate_playback[/code].
|
Returns a newly created [AudioStreamPlayback] intended to play this audio stream. Useful for when you want to extend [method _instantiate_playback] but call [method instantiate_playback] from an internally held AudioStream subresource. An example of this can be found in the source code for [code]AudioStreamRandomPitch::instantiate_playback[/code].
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="is_monophonic" qualifiers="const">
|
<method name="is_monophonic" qualifiers="const">
|
||||||
<return type="bool" />
|
<return type="bool" />
|
||||||
<description>
|
<description>
|
||||||
Returns true if this audio stream only supports monophonic playback, or false if the audio stream supports polyphony.
|
Returns [code]true[/code] if this audio stream only supports one channel ([i]monophony[/i]), or [code]false[/code] if the audio stream supports two or more channels ([i]polyphony[/i]).
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
</methods>
|
</methods>
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
[b]Note:[/b] [member ProjectSettings.audio/driver/enable_input] must be [code]true[/code] for audio input to work. See also that setting's description for caveats related to permissions and operating system privacy settings.
|
[b]Note:[/b] [member ProjectSettings.audio/driver/enable_input] must be [code]true[/code] for audio input to work. See also that setting's description for caveats related to permissions and operating system privacy settings.
|
||||||
</description>
|
</description>
|
||||||
<tutorials>
|
<tutorials>
|
||||||
|
<link title="Recording with microphone">$DOCS_URL/tutorials/audio/recording_with_microphone.html</link>
|
||||||
<link title="Audio Mic Record Demo">https://github.com/godotengine/godot-demo-projects/tree/master/audio/mic_record</link>
|
<link title="Audio Mic Record Demo">https://github.com/godotengine/godot-demo-projects/tree/master/audio/mic_record</link>
|
||||||
</tutorials>
|
</tutorials>
|
||||||
</class>
|
</class>
|
||||||
|
|
|
@ -13,16 +13,19 @@
|
||||||
<method name="_get_loop_count" qualifiers="virtual const">
|
<method name="_get_loop_count" qualifiers="virtual const">
|
||||||
<return type="int" />
|
<return type="int" />
|
||||||
<description>
|
<description>
|
||||||
|
Overridable method. Should return how many times this audio stream has looped. Most built-in playbacks always return [code]0[/code].
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="_get_playback_position" qualifiers="virtual const">
|
<method name="_get_playback_position" qualifiers="virtual const">
|
||||||
<return type="float" />
|
<return type="float" />
|
||||||
<description>
|
<description>
|
||||||
|
Overridable method. Should return the current progress along the audio stream, in seconds.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="_is_playing" qualifiers="virtual const">
|
<method name="_is_playing" qualifiers="virtual const">
|
||||||
<return type="bool" />
|
<return type="bool" />
|
||||||
<description>
|
<description>
|
||||||
|
Overridable method. Should return [code]true[/code] if this playback is active and playing its audio stream.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="_mix" qualifiers="virtual">
|
<method name="_mix" qualifiers="virtual">
|
||||||
|
@ -31,28 +34,34 @@
|
||||||
<param index="1" name="rate_scale" type="float" />
|
<param index="1" name="rate_scale" type="float" />
|
||||||
<param index="2" name="frames" type="int" />
|
<param index="2" name="frames" type="int" />
|
||||||
<description>
|
<description>
|
||||||
|
Override this method to customize how the audio stream is mixed. This method is called even if the playback is not active.
|
||||||
|
[b]Note:[/b] It is not useful to override this method in GDScript or C#. Only GDExtension can take advantage of it.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="_seek" qualifiers="virtual">
|
<method name="_seek" qualifiers="virtual">
|
||||||
<return type="void" />
|
<return type="void" />
|
||||||
<param index="0" name="position" type="float" />
|
<param index="0" name="position" type="float" />
|
||||||
<description>
|
<description>
|
||||||
|
Override this method to customize what happens when seeking this audio stream at the given [param position], such as by calling [method AudioStreamPlayer.seek].
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="_start" qualifiers="virtual">
|
<method name="_start" qualifiers="virtual">
|
||||||
<return type="void" />
|
<return type="void" />
|
||||||
<param index="0" name="from_pos" type="float" />
|
<param index="0" name="from_pos" type="float" />
|
||||||
<description>
|
<description>
|
||||||
|
Override this method to customize what happens when the playback starts at the given position, such as by calling [method AudioStreamPlayer.play].
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="_stop" qualifiers="virtual">
|
<method name="_stop" qualifiers="virtual">
|
||||||
<return type="void" />
|
<return type="void" />
|
||||||
<description>
|
<description>
|
||||||
|
Override this method to customize what happens when the playback is stopped, such as by calling [method AudioStreamPlayer.stop].
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="_tag_used_streams" qualifiers="virtual">
|
<method name="_tag_used_streams" qualifiers="virtual">
|
||||||
<return type="void" />
|
<return type="void" />
|
||||||
<description>
|
<description>
|
||||||
|
Overridable method. Called whenever the audio stream is mixed if the playback is active and [method AudioServer.set_enable_tagging_used_audio_streams] has been set to [code]true[/code]. Editor plugins may use this method to "tag" the current position along the audio stream and display it in a preview.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
</methods>
|
</methods>
|
||||||
|
|
|
@ -85,7 +85,7 @@
|
||||||
Attenuation factor used if listener is outside of [member emission_angle_degrees] and [member emission_angle_enabled] is set, in decibels.
|
Attenuation factor used if listener is outside of [member emission_angle_degrees] and [member emission_angle_enabled] is set, in decibels.
|
||||||
</member>
|
</member>
|
||||||
<member name="max_db" type="float" setter="set_max_db" getter="get_max_db" default="3.0">
|
<member name="max_db" type="float" setter="set_max_db" getter="get_max_db" default="3.0">
|
||||||
Sets the absolute maximum of the soundlevel, in decibels.
|
Sets the absolute maximum of the sound level, in decibels.
|
||||||
</member>
|
</member>
|
||||||
<member name="max_distance" type="float" setter="set_max_distance" getter="get_max_distance" default="0.0">
|
<member name="max_distance" type="float" setter="set_max_distance" getter="get_max_distance" default="0.0">
|
||||||
The distance past which the sound can no longer be heard at all. Only has an effect if set to a value greater than [code]0.0[/code]. [member max_distance] works in tandem with [member unit_size]. However, unlike [member unit_size] whose behavior depends on the [member attenuation_model], [member max_distance] always works in a linear fashion. This can be used to prevent the [AudioStreamPlayer3D] from requiring audio mixing when the listener is far away, which saves CPU resources.
|
The distance past which the sound can no longer be heard at all. Only has an effect if set to a value greater than [code]0.0[/code]. [member max_distance] works in tandem with [member unit_size]. However, unlike [member unit_size] whose behavior depends on the [member attenuation_model], [member max_distance] always works in a linear fashion. This can be used to prevent the [AudioStreamPlayer3D] from requiring audio mixing when the listener is far away, which saves CPU resources.
|
||||||
|
|
|
@ -269,7 +269,7 @@
|
||||||
Specifies the channel of the [member metallic_texture] in which the metallic information is stored. This is useful when you store the information for multiple effects in a single texture. For example if you stored metallic in the red channel, roughness in the blue, and ambient occlusion in the green you could reduce the number of textures you use.
|
Specifies the channel of the [member metallic_texture] in which the metallic information is stored. This is useful when you store the information for multiple effects in a single texture. For example if you stored metallic in the red channel, roughness in the blue, and ambient occlusion in the green you could reduce the number of textures you use.
|
||||||
</member>
|
</member>
|
||||||
<member name="msdf_outline_size" type="float" setter="set_msdf_outline_size" getter="get_msdf_outline_size" default="0.0">
|
<member name="msdf_outline_size" type="float" setter="set_msdf_outline_size" getter="get_msdf_outline_size" default="0.0">
|
||||||
The width of the shape outine.
|
The width of the shape outline.
|
||||||
</member>
|
</member>
|
||||||
<member name="msdf_pixel_range" type="float" setter="set_msdf_pixel_range" getter="get_msdf_pixel_range" default="4.0">
|
<member name="msdf_pixel_range" type="float" setter="set_msdf_pixel_range" getter="get_msdf_pixel_range" default="4.0">
|
||||||
The width of the range around the shape between the minimum and maximum representable signed distance.
|
The width of the range around the shape between the minimum and maximum representable signed distance.
|
||||||
|
@ -498,22 +498,22 @@
|
||||||
Represents the size of the [enum TextureParam] enum.
|
Represents the size of the [enum TextureParam] enum.
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="TEXTURE_FILTER_NEAREST" value="0" enum="TextureFilter">
|
<constant name="TEXTURE_FILTER_NEAREST" value="0" enum="TextureFilter">
|
||||||
The texture filter reads from the nearest pixel only. The simplest and fastest method of filtering, but the texture will look pixelized.
|
The texture filter reads from the nearest pixel only. This makes the texture look pixelated from up close, and grainy from a distance (due to mipmaps not being sampled).
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="TEXTURE_FILTER_LINEAR" value="1" enum="TextureFilter">
|
<constant name="TEXTURE_FILTER_LINEAR" value="1" enum="TextureFilter">
|
||||||
The texture filter blends between the nearest 4 pixels. Use this when you want to avoid a pixelated style, but do not want mipmaps.
|
The texture filter blends between the nearest 4 pixels. This makes the texture look smooth from up close, and grainy from a distance (due to mipmaps not being sampled).
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="TEXTURE_FILTER_NEAREST_WITH_MIPMAPS" value="2" enum="TextureFilter">
|
<constant name="TEXTURE_FILTER_NEAREST_WITH_MIPMAPS" value="2" enum="TextureFilter">
|
||||||
The texture filter reads from the nearest pixel in the nearest mipmap. The fastest way to read from textures with mipmaps.
|
The texture filter reads from the nearest pixel and blends between the nearest 2 mipmaps (or uses the nearest mipmap if [member ProjectSettings.rendering/textures/default_filters/use_nearest_mipmap_filter] is [code]true[/code]). This makes the texture look pixelated from up close, and smooth from a distance.
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="TEXTURE_FILTER_LINEAR_WITH_MIPMAPS" value="3" enum="TextureFilter">
|
<constant name="TEXTURE_FILTER_LINEAR_WITH_MIPMAPS" value="3" enum="TextureFilter">
|
||||||
The texture filter blends between the nearest 4 pixels and between the nearest 2 mipmaps. Use this for most cases as mipmaps are important to smooth out pixels that are far from the camera.
|
The texture filter blends between the nearest 4 pixels and between the nearest 2 mipmaps (or uses the nearest mipmap if [member ProjectSettings.rendering/textures/default_filters/use_nearest_mipmap_filter] is [code]true[/code]). This makes the texture look smooth from up close, and smooth from a distance.
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC" value="4" enum="TextureFilter">
|
<constant name="TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC" value="4" enum="TextureFilter">
|
||||||
The texture filter reads from the nearest pixel, but selects a mipmap based on the angle between the surface and the camera view. This reduces artifacts on surfaces that are almost in line with the camera. The anisotropic filtering level can be changed by adjusting [member ProjectSettings.rendering/textures/default_filters/anisotropic_filtering_level].
|
The texture filter reads from the nearest pixel and blends between 2 mipmaps (or uses the nearest mipmap if [member ProjectSettings.rendering/textures/default_filters/use_nearest_mipmap_filter] is [code]true[/code]) based on the angle between the surface and the camera view. This makes the texture look pixelated from up close, and smooth from a distance. Anisotropic filtering improves texture quality on surfaces that are almost in line with the camera, but is slightly slower. The anisotropic filtering level can be changed by adjusting [member ProjectSettings.rendering/textures/default_filters/anisotropic_filtering_level].
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC" value="5" enum="TextureFilter">
|
<constant name="TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC" value="5" enum="TextureFilter">
|
||||||
The texture filter blends between the nearest 4 pixels and selects a mipmap based on the angle between the surface and the camera view. This reduces artifacts on surfaces that are almost in line with the camera. This is the slowest of the filtering options, but results in the highest quality texturing. The anisotropic filtering level can be changed by adjusting [member ProjectSettings.rendering/textures/default_filters/anisotropic_filtering_level].
|
The texture filter blends between the nearest 4 pixels and blends between 2 mipmaps (or uses the nearest mipmap if [member ProjectSettings.rendering/textures/default_filters/use_nearest_mipmap_filter] is [code]true[/code]) based on the angle between the surface and the camera view. This makes the texture look smooth from up close, and smooth from a distance. Anisotropic filtering improves texture quality on surfaces that are almost in line with the camera, but is slightly slower. The anisotropic filtering level can be changed by adjusting [member ProjectSettings.rendering/textures/default_filters/anisotropic_filtering_level].
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="TEXTURE_FILTER_MAX" value="6" enum="TextureFilter">
|
<constant name="TEXTURE_FILTER_MAX" value="6" enum="TextureFilter">
|
||||||
Represents the size of the [enum TextureFilter] enum.
|
Represents the size of the [enum TextureFilter] enum.
|
||||||
|
|
|
@ -4,10 +4,12 @@
|
||||||
A 3×3 matrix for representing 3D rotation and scale.
|
A 3×3 matrix for representing 3D rotation and scale.
|
||||||
</brief_description>
|
</brief_description>
|
||||||
<description>
|
<description>
|
||||||
A 3×3 matrix used for representing 3D rotation and scale. Usually used as an orthogonal basis for a [Transform3D].
|
The [Basis] built-in [Variant] type is a 3x3 [url=https://en.wikipedia.org/wiki/Matrix_(mathematics)]matrix[/url] used to represent 3D rotation, scale, and shear. It is frequently used within a [Transform3D].
|
||||||
Contains 3 vector fields X, Y and Z as its columns, which are typically interpreted as the local basis vectors of a transformation. For such use, it is composed of a scaling and a rotation matrix, in that order (M = R.S).
|
A [Basis] is composed by 3 axis vectors, each representing a column of the matrix: [member x], [member y], and [member z]. The length of each axis ([method Vector3.length]) influences the basis's scale, while the direction of all axes influence the rotation. Usually, these axes are perpendicular to one another. However, when you rotate any axis individually, the basis becomes sheared. Applying a sheared basis to a 3D model will make the model appear distorted.
|
||||||
Basis can also be accessed as an array of 3D vectors. These vectors are usually orthogonal to each other, but are not necessarily normalized (due to scaling).
|
A [Basis] is [b]orthogonal[/b] if its axes are perpendicular to each other. A basis is [b]normalized[/b] if the length of every axis is [code]1[/code]. A basis is [b]uniform[/b] if all axes share the same length (see [method get_scale]). A basis is [b]orthonormal[/b] if it is both orthogonal and normalized, which allows it to only represent rotations. A basis is [b]conformal[/b] if it is both orthogonal and uniform, which ensures it is not distorted.
|
||||||
For more information, read the "Matrices and transforms" documentation article.
|
For a general introduction, see the [url=$DOCS_URL/tutorials/math/matrices_and_transforms.html]Matrices and transforms[/url] tutorial.
|
||||||
|
[b]Note:[/b] Godot uses a [url=https://en.wikipedia.org/wiki/Right-hand_rule]right-handed coordinate system[/url], which is a common standard. For directions, the convention for built-in types like [Camera3D] is for -Z to point forward (+X is right, +Y is up, and +Z is back). Other objects may use different direction conventions. For more information, see the [url=$DOCS_URL/tutorials/assets_pipeline/importing_scenes.html#d-asset-direction-conventions]Importing 3D Scenes[/url] tutorial.
|
||||||
|
[b]Note:[/b] The basis matrices are exposed as [url=https://www.mindcontrol.org/~hplus/graphics/matrix-layout.html]column-major[/url] order, which is the same as OpenGL. However, they are stored internally in row-major order, which is the same as DirectX.
|
||||||
</description>
|
</description>
|
||||||
<tutorials>
|
<tutorials>
|
||||||
<link title="Math documentation index">$DOCS_URL/tutorials/math/index.html</link>
|
<link title="Math documentation index">$DOCS_URL/tutorials/math/index.html</link>
|
||||||
|
@ -22,7 +24,7 @@
|
||||||
<constructor name="Basis">
|
<constructor name="Basis">
|
||||||
<return type="Basis" />
|
<return type="Basis" />
|
||||||
<description>
|
<description>
|
||||||
Constructs a default-initialized [Basis] set to [constant IDENTITY].
|
Constructs a [Basis] identical to the [constant IDENTITY].
|
||||||
</description>
|
</description>
|
||||||
</constructor>
|
</constructor>
|
||||||
<constructor name="Basis">
|
<constructor name="Basis">
|
||||||
|
@ -37,14 +39,16 @@
|
||||||
<param index="0" name="axis" type="Vector3" />
|
<param index="0" name="axis" type="Vector3" />
|
||||||
<param index="1" name="angle" type="float" />
|
<param index="1" name="angle" type="float" />
|
||||||
<description>
|
<description>
|
||||||
Constructs a pure rotation basis matrix, rotated around the given [param axis] by [param angle] (in radians). The axis must be a normalized vector.
|
Constructs a [Basis] that only represents rotation, rotated around the [param axis] by the given [param angle], in radians. The axis must be a normalized vector.
|
||||||
|
[b]Note:[/b] This is the same as using [method rotated] on the [constant IDENTITY] basis. With more than one angle consider using [method from_euler], instead.
|
||||||
</description>
|
</description>
|
||||||
</constructor>
|
</constructor>
|
||||||
<constructor name="Basis">
|
<constructor name="Basis">
|
||||||
<return type="Basis" />
|
<return type="Basis" />
|
||||||
<param index="0" name="from" type="Quaternion" />
|
<param index="0" name="from" type="Quaternion" />
|
||||||
<description>
|
<description>
|
||||||
Constructs a pure rotation basis matrix from the given quaternion.
|
Constructs a [Basis] that only represents rotation from the given [Quaternion].
|
||||||
|
[b]Note:[/b] Quaternions [i]only[/i] store rotation, not scale. Because of this, conversions from [Basis] to [Quaternion] cannot always be reversed.
|
||||||
</description>
|
</description>
|
||||||
</constructor>
|
</constructor>
|
||||||
<constructor name="Basis">
|
<constructor name="Basis">
|
||||||
|
@ -53,7 +57,7 @@
|
||||||
<param index="1" name="y_axis" type="Vector3" />
|
<param index="1" name="y_axis" type="Vector3" />
|
||||||
<param index="2" name="z_axis" type="Vector3" />
|
<param index="2" name="z_axis" type="Vector3" />
|
||||||
<description>
|
<description>
|
||||||
Constructs a basis matrix from 3 axis vectors (matrix columns).
|
Constructs a [Basis] from 3 axis vectors. These are the columns of the basis matrix.
|
||||||
</description>
|
</description>
|
||||||
</constructor>
|
</constructor>
|
||||||
</constructors>
|
</constructors>
|
||||||
|
@ -61,8 +65,10 @@
|
||||||
<method name="determinant" qualifiers="const">
|
<method name="determinant" qualifiers="const">
|
||||||
<return type="float" />
|
<return type="float" />
|
||||||
<description>
|
<description>
|
||||||
Returns the determinant of the basis matrix. If the basis is uniformly scaled, its determinant is the square of the scale.
|
Returns the [url=https://en.wikipedia.org/wiki/Determinant]determinant[/url] of this basis's matrix. For advanced math, this number can be used to determine a few attributes:
|
||||||
A negative determinant means the basis has a negative scale. A zero determinant means the basis isn't invertible, and is usually considered invalid.
|
- If the determinant is exactly [code]0[/code], the basis is not invertible (see [method inverse]).
|
||||||
|
- If the determinant is a negative number, the basis represents a negative scale.
|
||||||
|
[b]Note:[/b] If the basis's scale is the same for every axis, its determinant is always that scale by the power of 2.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="from_euler" qualifiers="static">
|
<method name="from_euler" qualifiers="static">
|
||||||
|
@ -70,40 +76,108 @@
|
||||||
<param index="0" name="euler" type="Vector3" />
|
<param index="0" name="euler" type="Vector3" />
|
||||||
<param index="1" name="order" type="int" default="2" />
|
<param index="1" name="order" type="int" default="2" />
|
||||||
<description>
|
<description>
|
||||||
Constructs a pure rotation Basis matrix from Euler angles in the specified Euler rotation order. By default, use YXZ order (most common). See the [enum EulerOrder] enum for possible values.
|
Constructs a new [Basis] that only represents rotation from the given [Vector3] of [url=https://en.wikipedia.org/wiki/Euler_angles]Euler angles[/url], in radians.
|
||||||
|
- The [member Vector3.x] should contain the angle around the [member x] axis (pitch).
|
||||||
|
- The [member Vector3.y] should contain the angle around the [member y] axis (yaw).
|
||||||
|
- The [member Vector3.z] should contain the angle around the [member z] axis (roll).
|
||||||
|
[codeblocks]
|
||||||
|
[gdscript]
|
||||||
|
# Creates a Basis whose z axis points down.
|
||||||
|
var my_basis = Basis.from_euler(Vector3(TAU / 4, 0, 0))
|
||||||
|
|
||||||
|
print(my_basis.z) # Prints (0, -1, 0).
|
||||||
|
[/gdscript]
|
||||||
|
[csharp]
|
||||||
|
// Creates a Basis whose z axis points down.
|
||||||
|
var myBasis = Basis.FromEuler(new Vector3(Mathf.Tau / 4.0f, 0.0f, 0.0f));
|
||||||
|
|
||||||
|
GD.Print(myBasis.Z); // Prints (0, -1, 0).
|
||||||
|
[/csharp]
|
||||||
|
[/codeblocks]
|
||||||
|
The order of each consecutive rotation can be changed with [param order] (see [enum EulerOrder] constants). By default, the YXZ convention is used ([constant EULER_ORDER_YXZ]): the basis rotates first around the Y axis (yaw), then X (pitch), and lastly Z (roll). When using the opposite method [method get_euler], this order is reversed.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="from_scale" qualifiers="static">
|
<method name="from_scale" qualifiers="static">
|
||||||
<return type="Basis" />
|
<return type="Basis" />
|
||||||
<param index="0" name="scale" type="Vector3" />
|
<param index="0" name="scale" type="Vector3" />
|
||||||
<description>
|
<description>
|
||||||
Constructs a pure scale basis matrix with no rotation or shearing. The scale values are set as the diagonal of the matrix, and the other parts of the matrix are zero.
|
Constructs a new [Basis] that only represents scale, with no rotation or shear, from the given [param scale] vector.
|
||||||
|
[codeblocks]
|
||||||
|
[gdscript]
|
||||||
|
var my_basis = Basis.from_scale(Vector3(2, 4, 8))
|
||||||
|
|
||||||
|
print(my_basis.x) # Prints (2, 0, 0).
|
||||||
|
print(my_basis.y) # Prints (0, 4, 0).
|
||||||
|
print(my_basis.z) # Prints (0, 0, 8).
|
||||||
|
[/gdscript]
|
||||||
|
[csharp]
|
||||||
|
var myBasis = Basis.FromScale(new Vector3(2.0f, 4.0f, 8.0f));
|
||||||
|
|
||||||
|
GD.Print(myBasis.X); // Prints (2, 0, 0).
|
||||||
|
GD.Print(myBasis.Y); // Prints (0, 4, 0).
|
||||||
|
GD.Print(myBasis.Z); // Prints (0, 0, 8).
|
||||||
|
[/csharp]
|
||||||
|
[/codeblocks]
|
||||||
|
[b]Note:[/b] In linear algebra, the matrix of this basis is also known as a [url=https://en.wikipedia.org/wiki/Diagonal_matrix]diagonal matrix[/url].
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="get_euler" qualifiers="const">
|
<method name="get_euler" qualifiers="const">
|
||||||
<return type="Vector3" />
|
<return type="Vector3" />
|
||||||
<param index="0" name="order" type="int" default="2" />
|
<param index="0" name="order" type="int" default="2" />
|
||||||
<description>
|
<description>
|
||||||
Returns the basis's rotation in the form of Euler angles. The Euler order depends on the [param order] parameter, by default it uses the YXZ convention: when decomposing, first Z, then X, and Y last. The returned vector contains the rotation angles in the format (X angle, Y angle, Z angle).
|
Returns this basis's rotation as a [Vector3] of [url=https://en.wikipedia.org/wiki/Euler_angles]Euler angles[/url], in radians.
|
||||||
Consider using the [method get_rotation_quaternion] method instead, which returns a [Quaternion] quaternion instead of Euler angles.
|
- The [member Vector3.x] contains the angle around the [member x] axis (pitch);
|
||||||
|
- The [member Vector3.y] contains the angle around the [member y] axis (yaw);
|
||||||
|
- The [member Vector3.z] contains the angle around the [member z] axis (roll).
|
||||||
|
The order of each consecutive rotation can be changed with [param order] (see [enum EulerOrder] constants). By default, the YXZ convention is used ([constant EULER_ORDER_YXZ]): Z (roll) is calculated first, then X (pitch), and lastly Y (yaw). When using the opposite method [method from_euler], this order is reversed.
|
||||||
|
[b]Note:[/b] Euler angles are much more intuitive but are not suitable for 3D math. Because of this, consider using the [method get_rotation_quaternion] method instead, which returns a [Quaternion].
|
||||||
|
[b]Note:[/b] In the Inspector dock, a basis's rotation is often displayed in Euler angles (in degrees), as is the case with the [member Node3D.rotation] property.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="get_rotation_quaternion" qualifiers="const">
|
<method name="get_rotation_quaternion" qualifiers="const">
|
||||||
<return type="Quaternion" />
|
<return type="Quaternion" />
|
||||||
<description>
|
<description>
|
||||||
Returns the basis's rotation in the form of a quaternion. See [method get_euler] if you need Euler angles, but keep in mind quaternions should generally be preferred to Euler angles.
|
Returns this basis's rotation as a [Quaternion].
|
||||||
|
[b]Note:[/b] Quatenions are much more suitable for 3D math but are less intuitive. For user interfaces, consider using the [method get_euler] method, which returns Euler angles.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="get_scale" qualifiers="const">
|
<method name="get_scale" qualifiers="const">
|
||||||
<return type="Vector3" />
|
<return type="Vector3" />
|
||||||
<description>
|
<description>
|
||||||
Assuming that the matrix is the combination of a rotation and scaling, return the absolute value of scaling factors along each axis.
|
Returns the length of each axis of this basis, as a [Vector3]. If the basis is not sheared, this is the scaling factor. It is not affected by rotation.
|
||||||
|
[codeblocks]
|
||||||
|
[gdscript]
|
||||||
|
var my_basis = Basis(
|
||||||
|
Vector3(2, 0, 0),
|
||||||
|
Vector3(0, 4, 0),
|
||||||
|
Vector3(0, 0, 8)
|
||||||
|
)
|
||||||
|
# Rotating the Basis in any way preserves its scale.
|
||||||
|
my_basis = my_basis.rotated(Vector3.UP, TAU / 2)
|
||||||
|
my_basis = my_basis.rotated(Vector3.RIGHT, TAU / 4)
|
||||||
|
|
||||||
|
print(my_basis.get_scale()) # Prints (2, 4, 8).
|
||||||
|
[/gdscript]
|
||||||
|
[csharp]
|
||||||
|
var myBasis = new Basis(
|
||||||
|
Vector3(2.0f, 0.0f, 0.0f),
|
||||||
|
Vector3(0.0f, 4.0f, 0.0f),
|
||||||
|
Vector3(0.0f, 0.0f, 8.0f)
|
||||||
|
);
|
||||||
|
// Rotating the Basis in any way preserves its scale.
|
||||||
|
myBasis = myBasis.Rotated(Vector3.Up, Mathf.Tau / 2.0f);
|
||||||
|
myBasis = myBasis.Rotated(Vector3.Right, Mathf.Tau / 4.0f);
|
||||||
|
|
||||||
|
GD.Print(myBasis.Scale); // Prints (2, 4, 8).
|
||||||
|
[/csharp]
|
||||||
|
[/codeblocks]
|
||||||
|
[b]Note:[/b] If the value returned by [method determinant] is negative, the scale is also negative.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="inverse" qualifiers="const">
|
<method name="inverse" qualifiers="const">
|
||||||
<return type="Basis" />
|
<return type="Basis" />
|
||||||
<description>
|
<description>
|
||||||
Returns the inverse of the matrix.
|
Returns the [url=https://en.wikipedia.org/wiki/Invertible_matrix]inverse of this basis's matrix[/url].
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="is_equal_approx" qualifiers="const">
|
<method name="is_equal_approx" qualifiers="const">
|
||||||
|
@ -125,15 +199,35 @@
|
||||||
<param index="1" name="up" type="Vector3" default="Vector3(0, 1, 0)" />
|
<param index="1" name="up" type="Vector3" default="Vector3(0, 1, 0)" />
|
||||||
<param index="2" name="use_model_front" type="bool" default="false" />
|
<param index="2" name="use_model_front" type="bool" default="false" />
|
||||||
<description>
|
<description>
|
||||||
Creates a Basis with a rotation such that the forward axis (-Z) points towards the [param target] position.
|
Creates a new [Basis] with a rotation such that the forward axis (-Z) points towards the [param target] position.
|
||||||
The up axis (+Y) points as close to the [param up] vector as possible while staying perpendicular to the forward axis. The resulting Basis is orthonormalized. The [param target] and [param up] vectors cannot be zero, and cannot be parallel to each other.
|
By default, the -Z axis (camera forward) is treated as forward (implies +X is right). If [param use_model_front] is [code]true[/code], the +Z axis (asset front) is treated as forward (implies +X is left) and points toward the [param target] position.
|
||||||
If [param use_model_front] is [code]true[/code], the +Z axis (asset front) is treated as forward (implies +X is left) and points toward the [param target] position. By default, the -Z axis (camera forward) is treated as forward (implies +X is right).
|
The up axis (+Y) points as close to the [param up] vector as possible while staying perpendicular to the forward axis. The returned basis is orthonormalized (see [method orthonormalized]). The [param target] and [param up] vectors cannot be [constant Vector3.ZERO], and cannot be parallel to each other.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="orthonormalized" qualifiers="const">
|
<method name="orthonormalized" qualifiers="const">
|
||||||
<return type="Basis" />
|
<return type="Basis" />
|
||||||
<description>
|
<description>
|
||||||
Returns the orthonormalized version of the matrix (useful to call from time to time to avoid rounding error for orthogonal matrices). This performs a Gram-Schmidt orthonormalization on the basis of the matrix.
|
Returns the orthonormalized version of this basis. An orthonormal basis is both [i]orthogonal[/i] (the axes are perpendicular to each other) and [i]normalized[/i] (the axes have a length of [code]1[/code]), which also means it can only represent rotation.
|
||||||
|
It is often useful to call this method to avoid rounding errors on a rotating basis:
|
||||||
|
[codeblocks]
|
||||||
|
[gdscript]
|
||||||
|
# Rotate this Node3D every frame.
|
||||||
|
func _process(delta):
|
||||||
|
basis = basis.rotated(Vector3.UP, TAU * delta)
|
||||||
|
basis = basis.rotated(Vector3.RIGHT, TAU * delta)
|
||||||
|
|
||||||
|
basis = basis.orthonormalized()
|
||||||
|
[/gdscript]
|
||||||
|
[csharp]
|
||||||
|
// Rotate this Node3D every frame.
|
||||||
|
public override void _Process(double delta)
|
||||||
|
{
|
||||||
|
Basis = Basis.Rotated(Vector3.Up, Mathf.Tau * (float)delta)
|
||||||
|
.Rotated(Vector3.Right, Mathf.Tau * (float)delta)
|
||||||
|
.Orthonormalized();
|
||||||
|
}
|
||||||
|
[/csharp]
|
||||||
|
[/codeblocks]
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="rotated" qualifiers="const">
|
<method name="rotated" qualifiers="const">
|
||||||
|
@ -141,14 +235,60 @@
|
||||||
<param index="0" name="axis" type="Vector3" />
|
<param index="0" name="axis" type="Vector3" />
|
||||||
<param index="1" name="angle" type="float" />
|
<param index="1" name="angle" type="float" />
|
||||||
<description>
|
<description>
|
||||||
Introduce an additional rotation around the given axis by [param angle] (in radians). The axis must be a normalized vector.
|
Returns this basis rotated around the given [param axis] by [param angle] (in radians). The [param axis] must be a normalized vector (see [method Vector3.normalized]).
|
||||||
|
Positive values rotate this basis clockwise around the axis, while negative values rotate it counterclockwise.
|
||||||
|
[codeblocks]
|
||||||
|
[gdscript]
|
||||||
|
var my_basis = Basis.IDENTITY
|
||||||
|
var angle = TAU / 2
|
||||||
|
|
||||||
|
my_basis = my_basis.rotated(Vector3.UP, angle) # Rotate around the up axis (yaw).
|
||||||
|
my_basis = my_basis.rotated(Vector3.RIGHT, angle) # Rotate around the right axis (pitch).
|
||||||
|
my_basis = my_basis.rotated(Vector3.BACK, angle) # Rotate around the back axis (roll).
|
||||||
|
[/gdscript]
|
||||||
|
[csharp]
|
||||||
|
var myBasis = Basis.Identity;
|
||||||
|
var angle = Mathf.Tau / 2.0f;
|
||||||
|
|
||||||
|
myBasis = myBasis.Rotated(Vector3.Up, angle); // Rotate around the up axis (yaw).
|
||||||
|
myBasis = myBasis.Rotated(Vector3.Right, angle); // Rotate around the right axis (pitch).
|
||||||
|
myBasis = myBasis.Rotated(Vector3.Back, angle); // Rotate around the back axis (roll).
|
||||||
|
[/csharp]
|
||||||
|
[/codeblocks]
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="scaled" qualifiers="const">
|
<method name="scaled" qualifiers="const">
|
||||||
<return type="Basis" />
|
<return type="Basis" />
|
||||||
<param index="0" name="scale" type="Vector3" />
|
<param index="0" name="scale" type="Vector3" />
|
||||||
<description>
|
<description>
|
||||||
Introduce an additional scaling specified by the given 3D scaling factor.
|
Returns this basis with each axis's components scaled by the given [param scale]'s components.
|
||||||
|
The basis matrix's rows are multiplied by [param scale]'s components. This operation is a global scale (relative to the parent).
|
||||||
|
[codeblocks]
|
||||||
|
[gdscript]
|
||||||
|
var my_basis = Basis(
|
||||||
|
Vector3(1, 1, 1),
|
||||||
|
Vector3(2, 2, 2),
|
||||||
|
Vector3(3, 3, 3)
|
||||||
|
)
|
||||||
|
my_basis = my_basis.scaled(Vector3(0, 2, -2))
|
||||||
|
|
||||||
|
print(my_basis.x) # Prints (0, 2, -2).
|
||||||
|
print(my_basis.y) # Prints (0, 4, -4).
|
||||||
|
print(my_basis.z) # Prints (0, 6, -6).
|
||||||
|
[/gdscript]
|
||||||
|
[csharp]
|
||||||
|
var myBasis = new Basis(
|
||||||
|
new Vector3(1.0f, 1.0f, 1.0f),
|
||||||
|
new Vector3(2.0f, 2.0f, 2.0f),
|
||||||
|
new Vector3(3.0f, 3.0f, 3.0f)
|
||||||
|
);
|
||||||
|
myBasis = myBasis.Scaled(new Vector3(0.0f, 2.0f, -2.0f));
|
||||||
|
|
||||||
|
GD.Print(myBasis.X); // Prints (0, 2, -2).
|
||||||
|
GD.Print(myBasis.Y); // Prints (0, 4, -4).
|
||||||
|
GD.Print(myBasis.Z); // Prints (0, 6, -6).
|
||||||
|
[/csharp]
|
||||||
|
[/codeblocks]
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="slerp" qualifiers="const">
|
<method name="slerp" qualifiers="const">
|
||||||
|
@ -156,61 +296,122 @@
|
||||||
<param index="0" name="to" type="Basis" />
|
<param index="0" name="to" type="Basis" />
|
||||||
<param index="1" name="weight" type="float" />
|
<param index="1" name="weight" type="float" />
|
||||||
<description>
|
<description>
|
||||||
Assuming that the matrix is a proper rotation matrix, slerp performs a spherical-linear interpolation with another rotation matrix.
|
Performs a spherical-linear interpolation with the [param to] basis, given a [param weight]. Both this basis and [param to] should represent a rotation.
|
||||||
|
[b]Example:[/b] Smoothly rotate a [Node3D] to the target basis over time, with a [Tween].
|
||||||
|
[codeblock]
|
||||||
|
var start_basis = Basis.IDENTITY
|
||||||
|
var target_basis = Basis.IDENTITY.rotated(Vector3.UP, TAU / 2)
|
||||||
|
|
||||||
|
func _ready():
|
||||||
|
create_tween().tween_method(interpolate, 0.0, 1.0, 5.0).set_trans(Tween.TRANS_EXPO)
|
||||||
|
|
||||||
|
func interpolate(weight):
|
||||||
|
basis = start_basis.slerp(target_basis, weight)
|
||||||
|
[/codeblock]
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="tdotx" qualifiers="const">
|
<method name="tdotx" qualifiers="const">
|
||||||
<return type="float" />
|
<return type="float" />
|
||||||
<param index="0" name="with" type="Vector3" />
|
<param index="0" name="with" type="Vector3" />
|
||||||
<description>
|
<description>
|
||||||
Transposed dot product with the X axis of the matrix.
|
Returns the transposed dot product between [param with] and the [member x] axis (see [method transposed]).
|
||||||
|
This is equivalent to [code]basis.x.dot(vector)[/code].
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="tdoty" qualifiers="const">
|
<method name="tdoty" qualifiers="const">
|
||||||
<return type="float" />
|
<return type="float" />
|
||||||
<param index="0" name="with" type="Vector3" />
|
<param index="0" name="with" type="Vector3" />
|
||||||
<description>
|
<description>
|
||||||
Transposed dot product with the Y axis of the matrix.
|
Returns the transposed dot product between [param with] and the [member y] axis (see [method transposed]).
|
||||||
|
This is equivalent to [code]basis.y.dot(vector)[/code].
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="tdotz" qualifiers="const">
|
<method name="tdotz" qualifiers="const">
|
||||||
<return type="float" />
|
<return type="float" />
|
||||||
<param index="0" name="with" type="Vector3" />
|
<param index="0" name="with" type="Vector3" />
|
||||||
<description>
|
<description>
|
||||||
Transposed dot product with the Z axis of the matrix.
|
Returns the transposed dot product between [param with] and the [member z] axis (see [method transposed]).
|
||||||
|
This is equivalent to [code]basis.z.dot(vector)[/code].
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="transposed" qualifiers="const">
|
<method name="transposed" qualifiers="const">
|
||||||
<return type="Basis" />
|
<return type="Basis" />
|
||||||
<description>
|
<description>
|
||||||
Returns the transposed version of the matrix.
|
Returns the transposed version of this basis. This turns the basis matrix's columns into rows, and its rows into columns.
|
||||||
|
[codeblocks]
|
||||||
|
[gdscript]
|
||||||
|
var my_basis = Basis(
|
||||||
|
Vector3(1, 2, 3),
|
||||||
|
Vector3(4, 5, 6),
|
||||||
|
Vector3(7, 8, 9)
|
||||||
|
)
|
||||||
|
my_basis = my_basis.transposed()
|
||||||
|
|
||||||
|
print(my_basis.x) # Prints (1, 4, 7).
|
||||||
|
print(my_basis.y) # Prints (2, 5, 8).
|
||||||
|
print(my_basis.z) # Prints (3, 6, 9).
|
||||||
|
[/gdscript]
|
||||||
|
[csharp]
|
||||||
|
var myBasis = new Basis(
|
||||||
|
new Vector3(1.0f, 2.0f, 3.0f),
|
||||||
|
new Vector3(4.0f, 5.0f, 6.0f),
|
||||||
|
new Vector3(7.0f, 8.0f, 9.0f)
|
||||||
|
);
|
||||||
|
myBasis = myBasis.Transposed();
|
||||||
|
|
||||||
|
GD.Print(myBasis.X); // Prints (1, 4, 7).
|
||||||
|
GD.Print(myBasis.Y); // Prints (2, 5, 8).
|
||||||
|
GD.Print(myBasis.Z); // Prints (3, 6, 9).
|
||||||
|
[/csharp]
|
||||||
|
[/codeblocks]
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
</methods>
|
</methods>
|
||||||
<members>
|
<members>
|
||||||
<member name="x" type="Vector3" setter="" getter="" default="Vector3(1, 0, 0)">
|
<member name="x" type="Vector3" setter="" getter="" default="Vector3(1, 0, 0)">
|
||||||
The basis matrix's X vector (column 0). Equivalent to array index [code]0[/code].
|
The basis's X axis, and the column [code]0[/code] of the matrix.
|
||||||
|
On the identity basis, this vector points right ([constant Vector3.RIGHT]).
|
||||||
</member>
|
</member>
|
||||||
<member name="y" type="Vector3" setter="" getter="" default="Vector3(0, 1, 0)">
|
<member name="y" type="Vector3" setter="" getter="" default="Vector3(0, 1, 0)">
|
||||||
The basis matrix's Y vector (column 1). Equivalent to array index [code]1[/code].
|
The basis's Y axis, and the column [code]1[/code] of the matrix.
|
||||||
|
On the identity basis, this vector points up ([constant Vector3.UP]).
|
||||||
</member>
|
</member>
|
||||||
<member name="z" type="Vector3" setter="" getter="" default="Vector3(0, 0, 1)">
|
<member name="z" type="Vector3" setter="" getter="" default="Vector3(0, 0, 1)">
|
||||||
The basis matrix's Z vector (column 2). Equivalent to array index [code]2[/code].
|
The basis's Z axis, and the column [code]2[/code] of the matrix.
|
||||||
|
On the identity basis, this vector points back ([constant Vector3.BACK]).
|
||||||
</member>
|
</member>
|
||||||
</members>
|
</members>
|
||||||
<constants>
|
<constants>
|
||||||
<constant name="IDENTITY" value="Basis(1, 0, 0, 0, 1, 0, 0, 0, 1)">
|
<constant name="IDENTITY" value="Basis(1, 0, 0, 0, 1, 0, 0, 0, 1)">
|
||||||
The identity basis, with no rotation or scaling applied.
|
The identity basis. This is a basis with no rotation, no shear, and its scale being [code]1[/code]. This means that:
|
||||||
This is identical to calling [code]Basis()[/code] without any parameters. This constant can be used to make your code clearer, and for consistency with C#.
|
- The [member x] points right ([constant Vector3.RIGHT]);
|
||||||
|
- The [member y] points up ([constant Vector3.UP]);
|
||||||
|
- The [member z] points back ([constant Vector3.BACK]).
|
||||||
|
[codeblock]
|
||||||
|
var basis := Basis.IDENTITY
|
||||||
|
print("| X | Y | Z")
|
||||||
|
print("| %s | %s | %s" % [basis.x.x, basis.y.x, basis.z.x])
|
||||||
|
print("| %s | %s | %s" % [basis.x.y, basis.y.y, basis.z.y])
|
||||||
|
print("| %s | %s | %s" % [basis.x.z, basis.y.z, basis.z.z])
|
||||||
|
# Prints:
|
||||||
|
# | X | Y | Z
|
||||||
|
# | 1 | 0 | 0
|
||||||
|
# | 0 | 1 | 0
|
||||||
|
# | 0 | 0 | 1
|
||||||
|
[/codeblock]
|
||||||
|
This is identical to creating [code]Basis()[/code] without any parameters. This constant can be used to make your code clearer, and for consistency with C#.
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="FLIP_X" value="Basis(-1, 0, 0, 0, 1, 0, 0, 0, 1)">
|
<constant name="FLIP_X" value="Basis(-1, 0, 0, 0, 1, 0, 0, 0, 1)">
|
||||||
The basis that will flip something along the X axis when used in a transformation.
|
When any basis is multiplied by [constant FLIP_X], it negates all components of the [member x] axis (the X column).
|
||||||
|
When [constant FLIP_X] is multiplied by any basis, it negates the [member Vector3.x] component of all axes (the X row).
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="FLIP_Y" value="Basis(1, 0, 0, 0, -1, 0, 0, 0, 1)">
|
<constant name="FLIP_Y" value="Basis(1, 0, 0, 0, -1, 0, 0, 0, 1)">
|
||||||
The basis that will flip something along the Y axis when used in a transformation.
|
When any basis is multiplied by [constant FLIP_Y], it negates all components of the [member y] axis (the Y column).
|
||||||
|
When [constant FLIP_Y] is multiplied by any basis, it negates the [member Vector3.y] component of all axes (the Y row).
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="FLIP_Z" value="Basis(1, 0, 0, 0, 1, 0, 0, 0, -1)">
|
<constant name="FLIP_Z" value="Basis(1, 0, 0, 0, 1, 0, 0, 0, -1)">
|
||||||
The basis that will flip something along the Z axis when used in a transformation.
|
When any basis is multiplied by [constant FLIP_Z], it negates all components of the [member z] axis (the Z column).
|
||||||
|
When [constant FLIP_Z] is multiplied by any basis, it negates the [member Vector3.z] component of all axes (the Z row).
|
||||||
</constant>
|
</constant>
|
||||||
</constants>
|
</constants>
|
||||||
<operators>
|
<operators>
|
||||||
|
@ -218,7 +419,7 @@
|
||||||
<return type="bool" />
|
<return type="bool" />
|
||||||
<param index="0" name="right" type="Basis" />
|
<param index="0" name="right" type="Basis" />
|
||||||
<description>
|
<description>
|
||||||
Returns [code]true[/code] if the [Basis] matrices are not equal.
|
Returns [code]true[/code] if the components of both [Basis] matrices are not equal.
|
||||||
[b]Note:[/b] Due to floating-point precision errors, consider using [method is_equal_approx] instead, which is more reliable.
|
[b]Note:[/b] Due to floating-point precision errors, consider using [method is_equal_approx] instead, which is more reliable.
|
||||||
</description>
|
</description>
|
||||||
</operator>
|
</operator>
|
||||||
|
@ -226,35 +427,46 @@
|
||||||
<return type="Basis" />
|
<return type="Basis" />
|
||||||
<param index="0" name="right" type="Basis" />
|
<param index="0" name="right" type="Basis" />
|
||||||
<description>
|
<description>
|
||||||
Composes these two basis matrices by multiplying them together. This has the effect of transforming the second basis (the child) by the first basis (the parent).
|
Transforms (multiplies) the [param right] basis by this basis.
|
||||||
|
This is the operation performed between parent and child [Node3D]s.
|
||||||
</description>
|
</description>
|
||||||
</operator>
|
</operator>
|
||||||
<operator name="operator *">
|
<operator name="operator *">
|
||||||
<return type="Vector3" />
|
<return type="Vector3" />
|
||||||
<param index="0" name="right" type="Vector3" />
|
<param index="0" name="right" type="Vector3" />
|
||||||
<description>
|
<description>
|
||||||
Transforms (multiplies) the [Vector3] by the given [Basis] matrix.
|
Transforms (multiplies) the [param right] vector by this basis, returning a [Vector3].
|
||||||
|
[codeblocks]
|
||||||
|
[gdscript]
|
||||||
|
var my_basis = Basis(Vector3(1, 1, 1), Vector3(1, 1, 1), Vector3(0, 2, 5))
|
||||||
|
print(my_basis * Vector3(1, 2, 3)) # Prints (7, 3, 16)
|
||||||
|
[/gdscript]
|
||||||
|
[csharp]
|
||||||
|
var myBasis = new Basis(new Vector3(1, 1, 1), new Vector3(1, 1, 1), new Vector3(0, 2, 5));
|
||||||
|
GD.Print(my_basis * new Vector3(1, 2, 3)); // Prints (7, 3, 16)
|
||||||
|
[/csharp]
|
||||||
|
[/codeblocks]
|
||||||
</description>
|
</description>
|
||||||
</operator>
|
</operator>
|
||||||
<operator name="operator *">
|
<operator name="operator *">
|
||||||
<return type="Basis" />
|
<return type="Basis" />
|
||||||
<param index="0" name="right" type="float" />
|
<param index="0" name="right" type="float" />
|
||||||
<description>
|
<description>
|
||||||
This operator multiplies all components of the [Basis], which scales it uniformly.
|
Multiplies all components of the [Basis] by the given [float]. This affects the basis's scale uniformly, resizing all 3 axes by the [param right] value.
|
||||||
</description>
|
</description>
|
||||||
</operator>
|
</operator>
|
||||||
<operator name="operator *">
|
<operator name="operator *">
|
||||||
<return type="Basis" />
|
<return type="Basis" />
|
||||||
<param index="0" name="right" type="int" />
|
<param index="0" name="right" type="int" />
|
||||||
<description>
|
<description>
|
||||||
This operator multiplies all components of the [Basis], which scales it uniformly.
|
Multiplies all components of the [Basis] by the given [int]. This affects the basis's scale uniformly, resizing all 3 axes by the [param right] value.
|
||||||
</description>
|
</description>
|
||||||
</operator>
|
</operator>
|
||||||
<operator name="operator ==">
|
<operator name="operator ==">
|
||||||
<return type="bool" />
|
<return type="bool" />
|
||||||
<param index="0" name="right" type="Basis" />
|
<param index="0" name="right" type="Basis" />
|
||||||
<description>
|
<description>
|
||||||
Returns [code]true[/code] if the [Basis] matrices are exactly equal.
|
Returns [code]true[/code] if the components of both [Basis] matrices are exactly equal.
|
||||||
[b]Note:[/b] Due to floating-point precision errors, consider using [method is_equal_approx] instead, which is more reliable.
|
[b]Note:[/b] Due to floating-point precision errors, consider using [method is_equal_approx] instead, which is more reliable.
|
||||||
</description>
|
</description>
|
||||||
</operator>
|
</operator>
|
||||||
|
@ -262,7 +474,8 @@
|
||||||
<return type="Vector3" />
|
<return type="Vector3" />
|
||||||
<param index="0" name="index" type="int" />
|
<param index="0" name="index" type="int" />
|
||||||
<description>
|
<description>
|
||||||
Access basis components using their index. [code]b[0][/code] is equivalent to [code]b.x[/code], [code]b[1][/code] is equivalent to [code]b.y[/code], and [code]b[2][/code] is equivalent to [code]b.z[/code].
|
Accesses each axis (column) of this basis by their index. Index [code]0[/code] is the same as [member x], index [code]1[/code] is the same as [member y], and index [code]2[/code] is the same as [member z].
|
||||||
|
[b]Note:[/b] In C++, this operator accesses the rows of the basis matrix, [i]not[/i] the columns. For the same behavior as scripting languages, use the [code]set_column[/code] and [code]get_column[/code] methods.
|
||||||
</description>
|
</description>
|
||||||
</operator>
|
</operator>
|
||||||
</operators>
|
</operators>
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
<method name="apply_rest">
|
<method name="apply_rest">
|
||||||
<return type="void" />
|
<return type="void" />
|
||||||
<description>
|
<description>
|
||||||
Stores the node's current transforms in [member rest].
|
Resets the bone to the rest pose. This is equivalent to setting [member Node2D.transform] to [member rest].
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="get_autocalculate_length_and_angle" qualifiers="const">
|
<method name="get_autocalculate_length_and_angle" qualifiers="const">
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
<return type="void" />
|
<return type="void" />
|
||||||
<param index="0" name="use_external_skeleton" type="bool" />
|
<param index="0" name="use_external_skeleton" type="bool" />
|
||||||
<description>
|
<description>
|
||||||
Sets whether the BoneAttachment3D node will use an extenral [Skeleton3D] node rather than attenpting to use its parent node as the [Skeleton3D]. When set to [code]true[/code], the BoneAttachment3D node will use the external [Skeleton3D] node set in [method set_external_skeleton].
|
Sets whether the BoneAttachment3D node will use an external [Skeleton3D] node rather than attempting to use its parent node as the [Skeleton3D]. When set to [code]true[/code], the BoneAttachment3D node will use the external [Skeleton3D] node set in [method set_external_skeleton].
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
</methods>
|
</methods>
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
See [OccluderInstance3D]'s documentation for instructions on setting up occlusion culling.
|
See [OccluderInstance3D]'s documentation for instructions on setting up occlusion culling.
|
||||||
</description>
|
</description>
|
||||||
<tutorials>
|
<tutorials>
|
||||||
|
<link title="Occlusion culling">$DOCS_URL/tutorials/3d/occlusion_culling.html</link>
|
||||||
</tutorials>
|
</tutorials>
|
||||||
<members>
|
<members>
|
||||||
<member name="size" type="Vector3" setter="set_size" getter="get_size" default="Vector3(1, 1, 1)">
|
<member name="size" type="Vector3" setter="set_size" getter="get_size" default="Vector3(1, 1, 1)">
|
||||||
|
|
|
@ -290,7 +290,7 @@
|
||||||
Particles are drawn in the order emitted.
|
Particles are drawn in the order emitted.
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="DRAW_ORDER_LIFETIME" value="1" enum="DrawOrder">
|
<constant name="DRAW_ORDER_LIFETIME" value="1" enum="DrawOrder">
|
||||||
Particles are drawn in order of remaining lifetime.
|
Particles are drawn in order of remaining lifetime. In other words, the particle with the highest lifetime is drawn at the front.
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="PARAM_INITIAL_LINEAR_VELOCITY" value="0" enum="Parameter">
|
<constant name="PARAM_INITIAL_LINEAR_VELOCITY" value="0" enum="Parameter">
|
||||||
Use with [method set_param_min], [method set_param_max], and [method set_param_curve] to set initial velocity properties.
|
Use with [method set_param_min], [method set_param_max], and [method set_param_curve] to set initial velocity properties.
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
See also [GPUParticles3D], which provides the same functionality with hardware acceleration, but may not run on older devices.
|
See also [GPUParticles3D], which provides the same functionality with hardware acceleration, but may not run on older devices.
|
||||||
</description>
|
</description>
|
||||||
<tutorials>
|
<tutorials>
|
||||||
|
<link title="Particle systems (3D)">$DOCS_URL/tutorials/3d/particles/index.html</link>
|
||||||
</tutorials>
|
</tutorials>
|
||||||
<methods>
|
<methods>
|
||||||
<method name="convert_from_particles">
|
<method name="convert_from_particles">
|
||||||
|
@ -314,7 +315,7 @@
|
||||||
Particles are drawn in the order emitted.
|
Particles are drawn in the order emitted.
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="DRAW_ORDER_LIFETIME" value="1" enum="DrawOrder">
|
<constant name="DRAW_ORDER_LIFETIME" value="1" enum="DrawOrder">
|
||||||
Particles are drawn in order of remaining lifetime.
|
Particles are drawn in order of remaining lifetime. In other words, the particle with the highest lifetime is drawn at the front.
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="DRAW_ORDER_VIEW_DEPTH" value="2" enum="DrawOrder">
|
<constant name="DRAW_ORDER_VIEW_DEPTH" value="2" enum="DrawOrder">
|
||||||
Particles are drawn in order of depth.
|
Particles are drawn in order of depth.
|
||||||
|
|
|
@ -113,6 +113,7 @@
|
||||||
func _ready():
|
func _ready():
|
||||||
grab_focus.call_deferred()
|
grab_focus.call_deferred()
|
||||||
[/codeblock]
|
[/codeblock]
|
||||||
|
[b]Note:[/b] Deferred calls are processed at idle time. Idle time happens mainly at the end of process and physics frames. In it, deferred calls will be run until there are none left, which means you can defer calls from other deferred calls and they'll still be run in the current idle time cycle. This means you should not call a method deferred from itself (or from a method called by it), as this causes infinite recursion the same way as if you had called the method directly.
|
||||||
See also [method Object.call_deferred].
|
See also [method Object.call_deferred].
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
|
@ -138,7 +139,7 @@
|
||||||
<method name="get_method" qualifiers="const">
|
<method name="get_method" qualifiers="const">
|
||||||
<return type="StringName" />
|
<return type="StringName" />
|
||||||
<description>
|
<description>
|
||||||
Returns the name of the method represented by this [Callable]. If the callable is a lambda function, returns the function's name.
|
Returns the name of the method represented by this [Callable]. If the callable is a GDScript lambda function, returns the function's name or [code]"<anonymous lambda>"[/code].
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="get_object" qualifiers="const">
|
<method name="get_object" qualifiers="const">
|
||||||
|
|
|
@ -17,6 +17,12 @@
|
||||||
If this is the current camera, remove it from being current. If [param enable_next] is [code]true[/code], request to make the next camera current, if any.
|
If this is the current camera, remove it from being current. If [param enable_next] is [code]true[/code], request to make the next camera current, if any.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
|
<method name="get_camera_projection" qualifiers="const">
|
||||||
|
<return type="Projection" />
|
||||||
|
<description>
|
||||||
|
Returns the projection matrix that this camera uses to render to its associated viewport. The camera must be part of the scene tree to function.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
<method name="get_camera_rid" qualifiers="const">
|
<method name="get_camera_rid" qualifiers="const">
|
||||||
<return type="RID" />
|
<return type="RID" />
|
||||||
<description>
|
<description>
|
||||||
|
@ -52,7 +58,7 @@
|
||||||
<return type="bool" />
|
<return type="bool" />
|
||||||
<param index="0" name="world_point" type="Vector3" />
|
<param index="0" name="world_point" type="Vector3" />
|
||||||
<description>
|
<description>
|
||||||
Returns [code]true[/code] if the given position is behind the camera (the blue part of the linked diagram). [url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/camera3d_position_frustum.png]See this diagram[/url] for an overview of position query methods.
|
Returns [code]true[/code] if the given position is behind the camera (the blue part of the linked diagram). [url=https://raw.githubusercontent.com/godotengine/godot-docs/4.1/img/camera3d_position_frustum.png]See this diagram[/url] for an overview of position query methods.
|
||||||
[b]Note:[/b] A position which returns [code]false[/code] may still be outside the camera's field of view.
|
[b]Note:[/b] A position which returns [code]false[/code] may still be outside the camera's field of view.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
|
@ -60,7 +66,7 @@
|
||||||
<return type="bool" />
|
<return type="bool" />
|
||||||
<param index="0" name="world_point" type="Vector3" />
|
<param index="0" name="world_point" type="Vector3" />
|
||||||
<description>
|
<description>
|
||||||
Returns [code]true[/code] if the given position is inside the camera's frustum (the green part of the linked diagram). [url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/camera3d_position_frustum.png]See this diagram[/url] for an overview of position query methods.
|
Returns [code]true[/code] if the given position is inside the camera's frustum (the green part of the linked diagram). [url=https://raw.githubusercontent.com/godotengine/godot-docs/4.1/img/camera3d_position_frustum.png]See this diagram[/url] for an overview of position query methods.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="make_current">
|
<method name="make_current">
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
[b]Note:[/b] Depth of field blur is only supported in the Forward+ and Mobile rendering methods, not Compatibility.
|
[b]Note:[/b] Depth of field blur is only supported in the Forward+ and Mobile rendering methods, not Compatibility.
|
||||||
</description>
|
</description>
|
||||||
<tutorials>
|
<tutorials>
|
||||||
|
<link title="Physical light and camera units">$DOCS_URL/tutorials/3d/physical_light_and_camera_units.html</link>
|
||||||
</tutorials>
|
</tutorials>
|
||||||
<methods>
|
<methods>
|
||||||
<method name="get_fov" qualifiers="const">
|
<method name="get_fov" qualifiers="const">
|
||||||
|
@ -31,7 +32,7 @@
|
||||||
Only available when [member ProjectSettings.rendering/lights_and_shadows/use_physical_light_units] is enabled.
|
Only available when [member ProjectSettings.rendering/lights_and_shadows/use_physical_light_units] is enabled.
|
||||||
</member>
|
</member>
|
||||||
<member name="exposure_shutter_speed" type="float" setter="set_shutter_speed" getter="get_shutter_speed" default="100.0">
|
<member name="exposure_shutter_speed" type="float" setter="set_shutter_speed" getter="get_shutter_speed" default="100.0">
|
||||||
Time for shutter to open and close, measured in seconds. A higher value will let in more light leading to a brighter image, while a lower amount will let in less light leading to a darker image.
|
Time for shutter to open and close, evaluated as [code]1 / shutter_speed[/code] seconds. A higher value will allow less light (leading to a darker image), while a lower value will allow more light (leading to a brighter image).
|
||||||
Only available when [member ProjectSettings.rendering/lights_and_shadows/use_physical_light_units] is enabled.
|
Only available when [member ProjectSettings.rendering/lights_and_shadows/use_physical_light_units] is enabled.
|
||||||
</member>
|
</member>
|
||||||
<member name="frustum_far" type="float" setter="set_far" getter="get_far" default="4000.0">
|
<member name="frustum_far" type="float" setter="set_far" getter="get_far" default="4000.0">
|
||||||
|
|
|
@ -522,7 +522,7 @@
|
||||||
<return type="void" />
|
<return type="void" />
|
||||||
<description>
|
<description>
|
||||||
Moves this node to display on top of its siblings.
|
Moves this node to display on top of its siblings.
|
||||||
Internally, the node is moved to the bottom of parent's children list. The method has no effect on nodes without a parent.
|
Internally, the node is moved to the bottom of parent's child list. The method has no effect on nodes without a parent.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="queue_redraw">
|
<method name="queue_redraw">
|
||||||
|
@ -562,7 +562,7 @@
|
||||||
</methods>
|
</methods>
|
||||||
<members>
|
<members>
|
||||||
<member name="clip_children" type="int" setter="set_clip_children_mode" getter="get_clip_children_mode" enum="CanvasItem.ClipChildrenMode" default="0">
|
<member name="clip_children" type="int" setter="set_clip_children_mode" getter="get_clip_children_mode" enum="CanvasItem.ClipChildrenMode" default="0">
|
||||||
Allows the current node to clip children nodes, essentially acting as a mask.
|
Allows the current node to clip child nodes, essentially acting as a mask.
|
||||||
</member>
|
</member>
|
||||||
<member name="light_mask" type="int" setter="set_light_mask" getter="get_light_mask" default="1">
|
<member name="light_mask" type="int" setter="set_light_mask" getter="get_light_mask" default="1">
|
||||||
The rendering layers in which this [CanvasItem] responds to [Light2D] nodes.
|
The rendering layers in which this [CanvasItem] responds to [Light2D] nodes.
|
||||||
|
@ -660,24 +660,26 @@
|
||||||
The [CanvasItem] will inherit the filter from its parent.
|
The [CanvasItem] will inherit the filter from its parent.
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="TEXTURE_FILTER_NEAREST" value="1" enum="TextureFilter">
|
<constant name="TEXTURE_FILTER_NEAREST" value="1" enum="TextureFilter">
|
||||||
The texture filter reads from the nearest pixel only. The simplest and fastest method of filtering. Useful for pixel art.
|
The texture filter reads from the nearest pixel only. This makes the texture look pixelated from up close, and grainy from a distance (due to mipmaps not being sampled).
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="TEXTURE_FILTER_LINEAR" value="2" enum="TextureFilter">
|
<constant name="TEXTURE_FILTER_LINEAR" value="2" enum="TextureFilter">
|
||||||
The texture filter blends between the nearest four pixels. Use this for most cases where you want to avoid a pixelated style.
|
The texture filter blends between the nearest 4 pixels. This makes the texture look smooth from up close, and grainy from a distance (due to mipmaps not being sampled).
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="TEXTURE_FILTER_NEAREST_WITH_MIPMAPS" value="3" enum="TextureFilter">
|
<constant name="TEXTURE_FILTER_NEAREST_WITH_MIPMAPS" value="3" enum="TextureFilter">
|
||||||
The texture filter reads from the nearest pixel in the nearest mipmap. This is the fastest way to read from textures with mipmaps.
|
The texture filter reads from the nearest pixel and blends between the nearest 2 mipmaps (or uses the nearest mipmap if [member ProjectSettings.rendering/textures/default_filters/use_nearest_mipmap_filter] is [code]true[/code]). This makes the texture look pixelated from up close, and smooth from a distance.
|
||||||
|
Use this for non-pixel art textures that may be viewed at a low scale (e.g. due to [Camera2D] zoom or sprite scaling), as mipmaps are important to smooth out pixels that are smaller than on-screen pixels.
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="TEXTURE_FILTER_LINEAR_WITH_MIPMAPS" value="4" enum="TextureFilter">
|
<constant name="TEXTURE_FILTER_LINEAR_WITH_MIPMAPS" value="4" enum="TextureFilter">
|
||||||
The texture filter blends between the nearest 4 pixels and between the nearest 2 mipmaps. Use this for non-pixel art textures that may be viewed at a low scale (e.g. due to [Camera2D] zoom), as mipmaps are important to smooth out pixels that are smaller than on-screen pixels.
|
The texture filter blends between the nearest 4 pixels and between the nearest 2 mipmaps (or uses the nearest mipmap if [member ProjectSettings.rendering/textures/default_filters/use_nearest_mipmap_filter] is [code]true[/code]). This makes the texture look smooth from up close, and smooth from a distance.
|
||||||
|
Use this for non-pixel art textures that may be viewed at a low scale (e.g. due to [Camera2D] zoom or sprite scaling), as mipmaps are important to smooth out pixels that are smaller than on-screen pixels.
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC" value="5" enum="TextureFilter">
|
<constant name="TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC" value="5" enum="TextureFilter">
|
||||||
The texture filter reads from the nearest pixel, but selects a mipmap based on the angle between the surface and the camera view. This reduces artifacts on surfaces that are almost in line with the camera. The anisotropic filtering level can be changed by adjusting [member ProjectSettings.rendering/textures/default_filters/anisotropic_filtering_level].
|
The texture filter reads from the nearest pixel and blends between 2 mipmaps (or uses the nearest mipmap if [member ProjectSettings.rendering/textures/default_filters/use_nearest_mipmap_filter] is [code]true[/code]) based on the angle between the surface and the camera view. This makes the texture look pixelated from up close, and smooth from a distance. Anisotropic filtering improves texture quality on surfaces that are almost in line with the camera, but is slightly slower. The anisotropic filtering level can be changed by adjusting [member ProjectSettings.rendering/textures/default_filters/anisotropic_filtering_level].
|
||||||
[b]Note:[/b] This texture filter is rarely useful in 2D projects. [constant TEXTURE_FILTER_NEAREST_WITH_MIPMAPS] is usually more appropriate.
|
[b]Note:[/b] This texture filter is rarely useful in 2D projects. [constant TEXTURE_FILTER_NEAREST_WITH_MIPMAPS] is usually more appropriate in this case.
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC" value="6" enum="TextureFilter">
|
<constant name="TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC" value="6" enum="TextureFilter">
|
||||||
The texture filter blends between the nearest 4 pixels and selects a mipmap based on the angle between the surface and the camera view. This reduces artifacts on surfaces that are almost in line with the camera. This is the slowest of the filtering options, but results in the highest quality texturing. The anisotropic filtering level can be changed by adjusting [member ProjectSettings.rendering/textures/default_filters/anisotropic_filtering_level].
|
The texture filter blends between the nearest 4 pixels and blends between 2 mipmaps (or uses the nearest mipmap if [member ProjectSettings.rendering/textures/default_filters/use_nearest_mipmap_filter] is [code]true[/code]) based on the angle between the surface and the camera view. This makes the texture look smooth from up close, and smooth from a distance. Anisotropic filtering improves texture quality on surfaces that are almost in line with the camera, but is slightly slower. The anisotropic filtering level can be changed by adjusting [member ProjectSettings.rendering/textures/default_filters/anisotropic_filtering_level].
|
||||||
[b]Note:[/b] This texture filter is rarely useful in 2D projects. [constant TEXTURE_FILTER_LINEAR_WITH_MIPMAPS] is usually more appropriate.
|
[b]Note:[/b] This texture filter is rarely useful in 2D projects. [constant TEXTURE_FILTER_LINEAR_WITH_MIPMAPS] is usually more appropriate in this case.
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="TEXTURE_FILTER_MAX" value="7" enum="TextureFilter">
|
<constant name="TEXTURE_FILTER_MAX" value="7" enum="TextureFilter">
|
||||||
Represents the size of the [enum TextureFilter] enum.
|
Represents the size of the [enum TextureFilter] enum.
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
</brief_description>
|
</brief_description>
|
||||||
<description>
|
<description>
|
||||||
A node that provides a thickened polygon shape (a prism) to a [CollisionObject2D] parent and allows to edit it. The polygon can be concave or convex. This can give a detection shape to an [Area2D] or turn [PhysicsBody2D] into a solid object.
|
A node that provides a thickened polygon shape (a prism) to a [CollisionObject2D] parent and allows to edit it. The polygon can be concave or convex. This can give a detection shape to an [Area2D] or turn [PhysicsBody2D] into a solid object.
|
||||||
[b]Warning:[/b] A non-uniformly scaled [CollisionShape3D] will likely not behave as expected. Make sure to keep its scale the same on all axes and adjust its shape resource instead.
|
[b]Warning:[/b] A non-uniformly scaled [CollisionShape2D] will likely not behave as expected. Make sure to keep its scale the same on all axes and adjust its shape resource instead.
|
||||||
</description>
|
</description>
|
||||||
<tutorials>
|
<tutorials>
|
||||||
</tutorials>
|
</tutorials>
|
||||||
|
@ -25,6 +25,7 @@
|
||||||
</member>
|
</member>
|
||||||
<member name="polygon" type="PackedVector2Array" setter="set_polygon" getter="get_polygon" default="PackedVector2Array()">
|
<member name="polygon" type="PackedVector2Array" setter="set_polygon" getter="get_polygon" default="PackedVector2Array()">
|
||||||
The polygon's list of vertices. Each point will be connected to the next, and the final point will be connected to the first.
|
The polygon's list of vertices. Each point will be connected to the next, and the final point will be connected to the first.
|
||||||
|
[b]Note:[/b] The returned vertices are in the local coordinate space of the given [CollisionPolygon2D].
|
||||||
[b]Warning:[/b] The returned value is a clone of the [PackedVector2Array], not a reference.
|
[b]Warning:[/b] The returned value is a clone of the [PackedVector2Array], not a reference.
|
||||||
</member>
|
</member>
|
||||||
</members>
|
</members>
|
||||||
|
|
|
@ -4,10 +4,10 @@
|
||||||
A color represented in RGBA format.
|
A color represented in RGBA format.
|
||||||
</brief_description>
|
</brief_description>
|
||||||
<description>
|
<description>
|
||||||
A color represented in RGBA format by a red ([member r]), green ([member g]), blue ([member b]), and alpha ([member a]) component. Each component is a 16-bit floating-point value, usually ranging from [code]0.0[/code] to [code]1.0[/code]. Some properties (such as [member CanvasItem.modulate]) may support values greater than [code]1.0[/code], for overbright or HDR (High Dynamic Range) colors.
|
A color represented in RGBA format by a red ([member r]), green ([member g]), blue ([member b]), and alpha ([member a]) component. Each component is a 32-bit floating-point value, usually ranging from [code]0.0[/code] to [code]1.0[/code]. Some properties (such as [member CanvasItem.modulate]) may support values greater than [code]1.0[/code], for overbright or HDR (High Dynamic Range) colors.
|
||||||
Colors can be created in various ways: By the various [Color] constructors, by static methods such as [method from_hsv], and by using a name from the set of standardized colors based on [url=https://en.wikipedia.org/wiki/X11_color_names]X11 color names[/url] with the addition of [constant TRANSPARENT]. GDScript also provides [method @GDScript.Color8], which uses integers from [code]0[/code] to [code]255[/code] and doesn't support overbright colors.
|
Colors can be created in various ways: By the various [Color] constructors, by static methods such as [method from_hsv], and by using a name from the set of standardized colors based on [url=https://en.wikipedia.org/wiki/X11_color_names]X11 color names[/url] with the addition of [constant TRANSPARENT]. GDScript also provides [method @GDScript.Color8], which uses integers from [code]0[/code] to [code]255[/code] and doesn't support overbright colors.
|
||||||
[b]Note:[/b] In a boolean context, a Color will evaluate to [code]false[/code] if it is equal to [code]Color(0, 0, 0, 1)[/code] (opaque black). Otherwise, a Color will always evaluate to [code]true[/code].
|
[b]Note:[/b] In a boolean context, a Color will evaluate to [code]false[/code] if it is equal to [code]Color(0, 0, 0, 1)[/code] (opaque black). Otherwise, a Color will always evaluate to [code]true[/code].
|
||||||
[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/color_constants.png]Color constants cheatsheet[/url]
|
[url=https://raw.githubusercontent.com/godotengine/godot-docs/4.1/img/color_constants.png]Color constants cheatsheet[/url]
|
||||||
</description>
|
</description>
|
||||||
<tutorials>
|
<tutorials>
|
||||||
<link title="2D GD Paint Demo">https://godotengine.org/asset-library/asset/517</link>
|
<link title="2D GD Paint Demo">https://godotengine.org/asset-library/asset/517</link>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
</brief_description>
|
</brief_description>
|
||||||
<description>
|
<description>
|
||||||
A 2D polyline shape, intended for use in physics. Used internally in [CollisionPolygon2D] when it's in [code]BUILD_SEGMENTS[/code] mode.
|
A 2D polyline shape, intended for use in physics. Used internally in [CollisionPolygon2D] when it's in [code]BUILD_SEGMENTS[/code] mode.
|
||||||
Being just a collection of interconnected line segments, [ConcavePolygonShape2D] is the most freely configurable single 2D shape. It can be used to form polygons of any nature, or even shapes that don't enclose an area. However, [ConvexPolygonShape2D] is [i]hollow[/i] even if the interconnected line segments do enclose an area, which often makes it unsuitable for physics or detection.
|
Being just a collection of interconnected line segments, [ConcavePolygonShape2D] is the most freely configurable single 2D shape. It can be used to form polygons of any nature, or even shapes that don't enclose an area. However, [ConcavePolygonShape2D] is [i]hollow[/i] even if the interconnected line segments do enclose an area, which often makes it unsuitable for physics or detection.
|
||||||
[b]Note:[/b] When used for collision, [ConcavePolygonShape2D] is intended to work with static [CollisionShape2D] nodes like [StaticBody2D] and will likely not behave well for [CharacterBody2D]s or [RigidBody2D]s in a mode other than Static.
|
[b]Note:[/b] When used for collision, [ConcavePolygonShape2D] is intended to work with static [CollisionShape2D] nodes like [StaticBody2D] and will likely not behave well for [CharacterBody2D]s or [RigidBody2D]s in a mode other than Static.
|
||||||
[b]Warning:[/b] Physics bodies that are small have a chance to clip through this shape when moving fast. This happens because on one frame, the physics body may be on the "outside" of the shape, and on the next frame it may be "inside" it. [ConcavePolygonShape2D] is hollow, so it won't detect a collision.
|
[b]Warning:[/b] Physics bodies that are small have a chance to clip through this shape when moving fast. This happens because on one frame, the physics body may be on the "outside" of the shape, and on the next frame it may be "inside" it. [ConcavePolygonShape2D] is hollow, so it won't detect a collision.
|
||||||
[b]Performance:[/b] Due to its complexity, [ConcavePolygonShape2D] is the slowest 2D collision shape to check collisions against. Its use should generally be limited to level geometry. If the polyline is closed, [CollisionPolygon2D]'s [code]BUILD_SOLIDS[/code] mode can be used, which decomposes the polygon into convex ones; see [ConvexPolygonShape2D]'s documentation for instructions.
|
[b]Performance:[/b] Due to its complexity, [ConcavePolygonShape2D] is the slowest 2D collision shape to check collisions against. Its use should generally be limited to level geometry. If the polyline is closed, [CollisionPolygon2D]'s [code]BUILD_SOLIDS[/code] mode can be used, which decomposes the polygon into convex ones; see [ConvexPolygonShape2D]'s documentation for instructions.
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
</brief_description>
|
</brief_description>
|
||||||
<description>
|
<description>
|
||||||
A 3D trimesh shape, intended for use in physics. Usually used to provide a shape for a [CollisionShape3D].
|
A 3D trimesh shape, intended for use in physics. Usually used to provide a shape for a [CollisionShape3D].
|
||||||
Being just a collection of interconnected triangles, [ConcavePolygonShape3D] is the most freely configurable single 3D shape. It can be used to form polyhedra of any nature, or even shapes that don't enclose a volume. However, [ConvexPolygonShape3D] is [i]hollow[/i] even if the interconnected triangles do enclose a volume, which often makes it unsuitable for physics or detection.
|
Being just a collection of interconnected triangles, [ConcavePolygonShape3D] is the most freely configurable single 3D shape. It can be used to form polyhedra of any nature, or even shapes that don't enclose a volume. However, [ConcavePolygonShape3D] is [i]hollow[/i] even if the interconnected triangles do enclose a volume, which often makes it unsuitable for physics or detection.
|
||||||
[b]Note:[/b] When used for collision, [ConcavePolygonShape3D] is intended to work with static [CollisionShape3D] nodes like [StaticBody3D] and will likely not behave well for [CharacterBody3D]s or [RigidBody3D]s in a mode other than Static.
|
[b]Note:[/b] When used for collision, [ConcavePolygonShape3D] is intended to work with static [CollisionShape3D] nodes like [StaticBody3D] and will likely not behave well for [CharacterBody3D]s or [RigidBody3D]s in a mode other than Static.
|
||||||
[b]Warning:[/b] Physics bodies that are small have a chance to clip through this shape when moving fast. This happens because on one frame, the physics body may be on the "outside" of the shape, and on the next frame it may be "inside" it. [ConcavePolygonShape3D] is hollow, so it won't detect a collision.
|
[b]Warning:[/b] Physics bodies that are small have a chance to clip through this shape when moving fast. This happens because on one frame, the physics body may be on the "outside" of the shape, and on the next frame it may be "inside" it. [ConcavePolygonShape3D] is hollow, so it won't detect a collision.
|
||||||
[b]Performance:[/b] Due to its complexity, [ConcavePolygonShape3D] is the slowest 3D collision shape to check collisions against. Its use should generally be limited to level geometry. For convex geometry, [ConvexPolygonShape3D] should be used. For dynamic physics bodies that need concave collision, several [ConvexPolygonShape3D]s can be used to represent its collision by using convex decomposition; see [ConvexPolygonShape3D]'s documentation for instructions.
|
[b]Performance:[/b] Due to its complexity, [ConcavePolygonShape3D] is the slowest 3D collision shape to check collisions against. Its use should generally be limited to level geometry. For convex geometry, [ConvexPolygonShape3D] should be used. For dynamic physics bodies that need concave collision, several [ConvexPolygonShape3D]s can be used to represent its collision by using convex decomposition; see [ConvexPolygonShape3D]'s documentation for instructions.
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
<link title="GUI documentation index">$DOCS_URL/tutorials/ui/index.html</link>
|
<link title="GUI documentation index">$DOCS_URL/tutorials/ui/index.html</link>
|
||||||
<link title="Custom drawing in 2D">$DOCS_URL/tutorials/2d/custom_drawing_in_2d.html</link>
|
<link title="Custom drawing in 2D">$DOCS_URL/tutorials/2d/custom_drawing_in_2d.html</link>
|
||||||
<link title="Control node gallery">$DOCS_URL/tutorials/ui/control_node_gallery.html</link>
|
<link title="Control node gallery">$DOCS_URL/tutorials/ui/control_node_gallery.html</link>
|
||||||
|
<link title="Multiple resolutions">$DOCS_URL/tutorials/rendering/multiple_resolutions.html</link>
|
||||||
<link title="All GUI Demos">https://github.com/godotengine/godot-demo-projects/tree/master/gui</link>
|
<link title="All GUI Demos">https://github.com/godotengine/godot-demo-projects/tree/master/gui</link>
|
||||||
</tutorials>
|
</tutorials>
|
||||||
<methods>
|
<methods>
|
||||||
|
@ -1160,10 +1161,12 @@
|
||||||
[b]Note:[/b] As an optimization, this notification won't be sent from changes that occur while this node is outside of the scene tree. Instead, all of the theme item updates can be applied at once when the node enters the scene tree.
|
[b]Note:[/b] As an optimization, this notification won't be sent from changes that occur while this node is outside of the scene tree. Instead, all of the theme item updates can be applied at once when the node enters the scene tree.
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="NOTIFICATION_SCROLL_BEGIN" value="47">
|
<constant name="NOTIFICATION_SCROLL_BEGIN" value="47">
|
||||||
Sent when this node is inside a [ScrollContainer] which has begun being scrolled.
|
Sent when this node is inside a [ScrollContainer] which has begun being scrolled when dragging the scrollable area [i]with a touch event[/i]. This notification is [i]not[/i] sent when scrolling by dragging the scrollbar, scrolling with the mouse wheel or scrolling with keyboard/gamepad events.
|
||||||
|
[b]Note:[/b] This signal is only emitted on Android or iOS, or on desktop/web platforms when [member ProjectSettings.input_devices/pointing/emulate_touch_from_mouse] is enabled.
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="NOTIFICATION_SCROLL_END" value="48">
|
<constant name="NOTIFICATION_SCROLL_END" value="48">
|
||||||
Sent when this node is inside a [ScrollContainer] which has stopped being scrolled.
|
Sent when this node is inside a [ScrollContainer] which has stopped being scrolled when dragging the scrollable area [i]with a touch event[/i]. This notification is [i]not[/i] sent when scrolling by dragging the scrollbar, scrolling with the mouse wheel or scrolling with keyboard/gamepad events.
|
||||||
|
[b]Note:[/b] This signal is only emitted on Android or iOS, or on desktop/web platforms when [member ProjectSettings.input_devices/pointing/emulate_touch_from_mouse] is enabled.
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="NOTIFICATION_LAYOUT_DIRECTION_CHANGED" value="49">
|
<constant name="NOTIFICATION_LAYOUT_DIRECTION_CHANGED" value="49">
|
||||||
Sent when control layout direction is changed.
|
Sent when control layout direction is changed.
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<description>
|
<description>
|
||||||
A 2D convex polygon shape, intended for use in physics. Used internally in [CollisionPolygon2D] when it's in [code]BUILD_SOLIDS[/code] mode.
|
A 2D convex polygon shape, intended for use in physics. Used internally in [CollisionPolygon2D] when it's in [code]BUILD_SOLIDS[/code] mode.
|
||||||
[ConvexPolygonShape2D] is [i]solid[/i], which means it detects collisions from objects that are fully inside it, unlike [ConcavePolygonShape2D] which is hollow. This makes it more suitable for both detection and physics.
|
[ConvexPolygonShape2D] is [i]solid[/i], which means it detects collisions from objects that are fully inside it, unlike [ConcavePolygonShape2D] which is hollow. This makes it more suitable for both detection and physics.
|
||||||
[b]Convex decomposition:[/b] A concave polygon can be split up into several convex polygons. This allows dynamic physics bodies to have complex concave collisions (at a performance cost) and can be achieved by using several [ConvexPolygonShape3D] nodes or by using the [CollisionPolygon2D] node in [code]BUILD_SOLIDS[/code] mode. To generate a collision polygon from a sprite, select the [Sprite2D] node, go to the [b]Sprite2D[/b] menu that appears above the viewport, and choose [b]Create Polygon2D Sibling[/b].
|
[b]Convex decomposition:[/b] A concave polygon can be split up into several convex polygons. This allows dynamic physics bodies to have complex concave collisions (at a performance cost) and can be achieved by using several [ConvexPolygonShape2D] nodes or by using the [CollisionPolygon2D] node in [code]BUILD_SOLIDS[/code] mode. To generate a collision polygon from a sprite, select the [Sprite2D] node, go to the [b]Sprite2D[/b] menu that appears above the viewport, and choose [b]Create Polygon2D Sibling[/b].
|
||||||
[b]Performance:[/b] [ConvexPolygonShape2D] is faster to check collisions against compared to [ConcavePolygonShape2D], but it is slower than primitive collision shapes such as [CircleShape2D] and [RectangleShape2D]. Its use should generally be limited to medium-sized objects that cannot have their collision accurately represented by primitive shapes.
|
[b]Performance:[/b] [ConvexPolygonShape2D] is faster to check collisions against compared to [ConcavePolygonShape2D], but it is slower than primitive collision shapes such as [CircleShape2D] and [RectangleShape2D]. Its use should generally be limited to medium-sized objects that cannot have their collision accurately represented by primitive shapes.
|
||||||
</description>
|
</description>
|
||||||
<tutorials>
|
<tutorials>
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue