Compare commits
461 Commits
Author | SHA1 | Date |
---|---|---|
Rémi Verschelde | 820dd1d001 | |
George Marques | 78883ea57d | |
Juan Linietsky | 9cc9b45948 | |
eska | 828fa9af11 | |
SuperUserNameMan | 8a615b27ad | |
Rémi Verschelde | 5184b215a9 | |
Rémi Verschelde | 7ce99c23dd | |
Rémi Verschelde | af3cf7806e | |
Ariel Manzur | 687248bbf4 | |
Rémi Verschelde | 6d6b14d112 | |
Juan Linietsky | 75cc8dc6b4 | |
Rémi Verschelde | 106199dfa7 | |
Rémi Verschelde | 192688e7eb | |
eska | a9a8bb281d | |
Franklin Sobrinho | 90c8dbb890 | |
Juan Linietsky | 6e7db99614 | |
Juan Linietsky | 3963f89ebd | |
Juan Linietsky | f4a5963ca9 | |
Pawel Kowal | d4cb381ce0 | |
Rémi Verschelde | 2c3511a284 | |
George Marques | 9420a1b6c1 | |
volzhs | 8aeacd935c | |
Ignacio Etcheverry | f9b7baa546 | |
Andreas Haas | 7589307911 | |
Juan Linietsky | 6199efbc7e | |
Juan Linietsky | 801db4c708 | |
Juan Linietsky | 9b90d70ae7 | |
Juan Linietsky | 242ceb1869 | |
Juan Linietsky | de0b7b871b | |
Juan Linietsky | eaca35adfe | |
Juan Linietsky | dffa1da012 | |
Juan Linietsky | a2103bac7c | |
Juan Linietsky | a2d2eb9a63 | |
Rémi Verschelde | 3ce0380ba4 | |
Juan Linietsky | 34e6e284db | |
Juan Linietsky | 302abb1449 | |
Juan Linietsky | c5fd6a3b69 | |
Juan Linietsky | 6813c89021 | |
Ferdinand Thiessen | 406daa8f7f | |
George Marques | 694120210a | |
Juan Linietsky | 9a7c310134 | |
Juan Linietsky | ea7da3bf08 | |
Juan Linietsky | 9592dd3e3b | |
Paulb23 | 9d85bfa00a | |
Pedro J. Estébanez | 5083e18b89 | |
paper-pauper | 3ff466770a | |
volzhs | 584deb807e | |
volzhs | 6116174d49 | |
Rémi Verschelde | 8a451e49e5 | |
Saracen | b0aab53853 | |
Juan Linietsky | 10eedf62b8 | |
Rémi Verschelde | 673ef0cf88 | |
Andreas Haas | f7436c7d16 | |
George Marques | c015341221 | |
Juan Linietsky | 6e49bc8210 | |
volzhs | c2226d1199 | |
George Marques | 7fd9ff70f9 | |
George Marques | 1218d8f2a2 | |
Juan Linietsky | cf300ace96 | |
Rémi Verschelde | 4e1dcd3d0b | |
Paulb23 | 5907bddda5 | |
volzhs | 39cc2cbfb9 | |
Juan Linietsky | 140949e013 | |
Rémi Verschelde | 5b3551a91f | |
George Marques | 2389712638 | |
Rémi Verschelde | 1a3d408f52 | |
Bojidar Marinov | 0ce2f76d5a | |
George Marques | 35c64c1824 | |
George Marques | aa581a067d | |
sunnystormy | 418cd58d47 | |
Juan Linietsky | 0c71eb8a1e | |
Juan Linietsky | 3318860539 | |
Juan Linietsky | d1dbc7fe93 | |
Juan Linietsky | 299b0102f0 | |
Juan Linietsky | fb255a69b6 | |
Juan Linietsky | 1bfaea0d76 | |
Juan Linietsky | ad01fa2248 | |
Juan Linietsky | b457b8ac89 | |
volzhs | 5582d37af9 | |
Juan Linietsky | 8c5577e9e4 | |
Juan Linietsky | 7076e98f40 | |
Juan Linietsky | a71ea0abc6 | |
George Marques | edadb46bd4 | |
J08nY | 86c4bbc031 | |
J08nY | 8d9121f0b0 | |
Mehmet Durgel | c9716ebd00 | |
J08nY | a04be3e44b | |
Juan Linietsky | af41d7bffa | |
J08nY | 61b087dd66 | |
Juan Linietsky | 257d370677 | |
Juan Linietsky | beb2176399 | |
Ignacio Etcheverry | 18cb1f8e44 | |
Dennis Brakhane | a04a78c7f6 | |
Juan Linietsky | 8df46cddcb | |
Juan Linietsky | 775b089548 | |
Juan Linietsky | 7b36595641 | |
J08nY | f5d3d9cc5f | |
J08nY | be4babccba | |
volzhs | 6a1368d24d | |
J08nY | 109e58cf75 | |
George Marques | 0b8cf7946e | |
J08nY | c1e004ffca | |
Juan Linietsky | d662f5aa63 | |
Juan Linietsky | 85c6d1b37d | |
Juan Linietsky | fd4d666289 | |
George Marques | d8f9c95dbd | |
Juan Linietsky | 56c5da8565 | |
Andreas Haas | c2e09a21ac | |
J08nY | d8d926730c | |
Juan Linietsky | da45e32ef1 | |
Juan Linietsky | b075525e84 | |
Juan Linietsky | 6525e0017c | |
Ovnuniarchos | c54744ce4d | |
Juan Linietsky | acc552c447 | |
Juan Linietsky | d411cbe1d9 | |
Juan Linietsky | 2212cc827c | |
Juan Linietsky | cb37d1bb91 | |
Juan Linietsky | 7987147502 | |
Juan Linietsky | c22ac11afb | |
Juan Linietsky | d945dbdd0f | |
Juan Linietsky | b06cf23c1a | |
Juan Linietsky | 51330b29ae | |
Juan Linietsky | 8289760227 | |
Juan Linietsky | dd7e7c94c1 | |
Nuno Donato | 25244e9843 | |
Juan Linietsky | 6a83c87dda | |
Juan Linietsky | 64ac2272ce | |
volzhs | 2998b7c486 | |
Paulb23 | 13d3d217b1 | |
CowThing | a94f6108a9 | |
Paulb23 | 93616e41f9 | |
J08nY | 1475f8d318 | |
Rémi Verschelde | 9bb6a0852b | |
Rémi Verschelde | 66ce012ca6 | |
Rémi Verschelde | 64507f0085 | |
Pawel Kowal | 08c9e566bf | |
Paulb23 | afbc9d550f | |
J08nY | d16375d005 | |
J08nY | 74d0f8b65b | |
Rémi Verschelde | 9791d2ef6d | |
Juan Linietsky | cb94271e9f | |
Juan Linietsky | bb8b57cbae | |
TheoXD | 5a45b295ae | |
Roberto | a39eaf4c66 | |
Roberto | 9ac954e2a4 | |
Pedro J. Estébanez | 73e455c22f | |
Roberto | 840ad26069 | |
Roberto | b18000349e | |
Andreas Haas | 7bff33ea92 | |
Bojidar Marinov | aad9cd3e22 | |
Juan Linietsky | d5bed26e42 | |
volzhs | 356c35954a | |
Rémi Verschelde | ff91f409bf | |
Błażej Szczygieł | 763b29f34e | |
Rémi Verschelde | d412cb65be | |
Rémi Verschelde | da8fb5de7a | |
J08nY | 845a0e2566 | |
marcelofg55 | bed17e98c8 | |
Warlaan | c6ef223498 | |
J08nY | 8a7c4c017f | |
volzhs | f22e13d24e | |
George Marques | 47f8da5409 | |
J08nY | 8ea940e99b | |
Rémi Verschelde | f97cbdec8f | |
Warlaan | fc15a842af | |
George Marques | 6d45fc0717 | |
P-GLEZ | 298be3356f | |
P-GLEZ | 436e968b43 | |
Andreas Haas | 2b06d7e6f7 | |
P-GLEZ | 79e9917367 | |
jmintb | 3efe43fb8b | |
marcelofg55 | 331a0aed71 | |
J08nY | 39773b6b9a | |
CowThing | 566d751e39 | |
Paulb23 | 7928b5fef6 | |
Rémi Verschelde | 8b8a1a0cbb | |
Julian Murgia - StraToN | 5c52f4437a | |
Julian Murgia - StraToN | e8b1744325 | |
Aleksandar Danilovic | 24e5755e72 | |
Rémi Verschelde | 1787ec12be | |
MarianoGNU | c67b1888b5 | |
Paulb23 | 7029c96221 | |
Geequlim | 178168aa8a | |
Paulb23 | 71487793df | |
Paulb23 | 99c948ba56 | |
Ignacio Etcheverry | 211a6d01bc | |
marcelofg55 | 280899ee43 | |
Paulb23 | 652f82dae8 | |
Carter Anderson | 6844b580f6 | |
Daniel J. Ramirez | ef4ac86656 | |
Daniel J. Ramirez | f346733d80 | |
volzhs | bbf08a48df | |
volzhs | 4478f8cfbb | |
Hugo Locurcio | 5ad050be2b | |
anatoly techtonik | a5007d0e7a | |
est31 | 88e512547b | |
est31 | 85018e185a | |
Calinou | 9b03b9e989 | |
Ariel Manzur | 803438d448 | |
marcelofg55 | 4dc2d78d2e | |
Geequlim | c2f48421d1 | |
captainwasabi | 08fa7a0ff1 | |
Bojidar Marinov | bea5135518 | |
Paulb23 | e95eb4b1dc | |
Rémi Verschelde | 01bdfa4d22 | |
Wilhem Barbier | 16d38b199a | |
Rémi Verschelde | 1d85dcb1fa | |
CowThing | c6e2c0f01d | |
Paulb23 | 481c076feb | |
Paulb23 | 86c0438f9d | |
Bojidar Marinov | d7e4fb4365 | |
volzhs | a3979cc928 | |
Daniel J. Ramirez | 1864745e2a | |
Rémi Verschelde | 0a64059937 | |
Błażej Szczygieł | 9acb666320 | |
Rémi Verschelde | 3a1e69f45c | |
Daniel J. Ramirez | 6a85acdffb | |
volzhs | 094a9c3bcc | |
Rémi Verschelde | 5d2a23d99c | |
Rémi Verschelde | 9ed2084b42 | |
Rémi Verschelde | c0df7da2ca | |
Rémi Verschelde | 49bf494eac | |
eska | b8d8ec09ee | |
MattUV | f120514402 | |
Rémi Verschelde | 77573a76d1 | |
Rémi Verschelde | c734a508c3 | |
Rémi Verschelde | d66b04921f | |
Paulb23 | f61f515872 | |
Paulb23 | c5e17d553e | |
marcelofg55 | 2bd6e2402b | |
Mattias Cibien | c575f31d5d | |
Andreas Haas | 6d50ccfd32 | |
Paulb23 | bd51dea8f6 | |
Paulb23 | abc97d3bb4 | |
George Marques | a5e54b83ec | |
Paulb23 | 18782aec61 | |
Alexander Holland | f58cfaf585 | |
Paulb23 | 5d98718c28 | |
Paulb23 | 7ab1c1ea3b | |
Ariel Manzur | f8debd8152 | |
Ariel Manzur | ac06e3d4db | |
Rémi Verschelde | b6be2f503d | |
Daniel J. Ramirez | b224407770 | |
George Marques | 7556391d20 | |
Juan Linietsky | 23c659fc47 | |
George Marques | 4832731477 | |
Ignacio Etcheverry | 19f08eaa5b | |
Ignacio Etcheverry | 975b4d2927 | |
Hinsbart | 913818a246 | |
Daniel J. Ramirez | 4a4999451b | |
George Marques | 4f57e532b8 | |
Aleksandar Danilovic | 3449c81bdb | |
mrezai | 05857a5472 | |
Paulb23 | ec3b50fd65 | |
CowThing | f95918e05a | |
Mattias Cibien | b3404c8c44 | |
Daniel J. Ramirez | 7e077258c5 | |
Daniel J. Ramirez | fb3d10c579 | |
Daniel J. Ramirez | 0b75c39c2b | |
Daniel J. Ramirez | e0a13981fc | |
CowThing | bdbb831261 | |
Ignacio Etcheverry | 97e30f4cd7 | |
CowThing | 78dc8e79c4 | |
Rémi Verschelde | 40681d90e5 | |
Daniel J. Ramirez | fbb8a2170c | |
Daniel J. Ramirez | e8a972197c | |
Bojidar Marinov | 047767b824 | |
Rémi Verschelde | ef2f1ae811 | |
Rémi Verschelde | 7c419032c7 | |
Rémi Verschelde | 9bdcc97e56 | |
Rémi Verschelde | 7f80fce464 | |
Rémi Verschelde | ea9b552e27 | |
Juan Linietsky | 21ab3a030e | |
Juan Linietsky | a14ff27337 | |
Juan Linietsky | d6e30256ad | |
Ariel Manzur | 4bc494ae2e | |
Rémi Verschelde | d49fff6246 | |
Rémi Verschelde | d29087cc53 | |
Rémi Verschelde | 27461a79dc | |
Rémi Verschelde | a86cfc258e | |
Rémi Verschelde | 26c2e0d09d | |
Rémi Verschelde | 0b49d78a3f | |
volzhs | 40b546fb83 | |
Rémi Verschelde | 3c453b7bd2 | |
George Marques | f033763700 | |
Rémi Verschelde | 944ac2500a | |
Geequlim | b4adb0d338 | |
Ariel Manzur | 227604a566 | |
Bojidar Marinov | 70644301dd | |
Paulb23 | 4228505cf0 | |
Rémi Verschelde | 9086a929b2 | |
Geequlim | 5365ae9212 | |
Geequlim | a3fd381a4f | |
Daniel J. Ramirez | d81ffaf2ab | |
Paulb23 | c77a5f910e | |
eska | 91461b588d | |
Hinsbart | 3a3f56689e | |
Daniel Ramirez | 35e05b092c | |
Rémi Verschelde | 238bbb6539 | |
Daniel J. Ramirez | 946ef8d478 | |
Alexander Holland | d3ee8de754 | |
Paulb23 | 517518ae9a | |
Rémi Verschelde | 084ce221d7 | |
Jan Heemstra | e38666b76a | |
Jan Heemstra | 6f76eca883 | |
Julian Murgia - StraToN | d183a5361f | |
Rémi Verschelde | 11aa0d1405 | |
Julian Murgia | 6efe8818a7 | |
Rémi Verschelde | 9023a84a93 | |
Rémi Verschelde | 1bd2145e34 | |
Rémi Verschelde | 382a8250ba | |
Paulb23 | 73296a9a6d | |
Hinsbart | 93b1f60ca2 | |
Bojidar Marinov | 7f4387d21e | |
Bojidar Marinov | c0748bad06 | |
Hinsbart | 94b321822d | |
Bojidar Marinov | c523749662 | |
eska | 0f47311610 | |
Bojidar Marinov | 4c358b7043 | |
eska | 98b30e3aff | |
volzhs | 9f5c6cf950 | |
Zher Huei Lee | 07fc330241 | |
Alex | c712e54b63 | |
Ignacio Etcheverry | 6a2efc48c5 | |
Bojidar Marinov | ff1d370b9f | |
eska | e654184888 | |
mrezai | cabb80ecf4 | |
mrezai | 3efa0f130d | |
Saracen | 47c7b535d2 | |
Hearto Lazor | 5fac497aa2 | |
volzhs | 4bfcd14a6a | |
Ignacio Etcheverry | dbcf969fbf | |
Ignacio Etcheverry | 52bf4a76b2 | |
Marc Gilleron | f32a4dc516 | |
Marc Gilleron | a0b6645858 | |
mrezai | b24c3be564 | |
Saracen | b2b5c495e1 | |
Paulb23 | e367c6cdd8 | |
Paulb23 | b5a438413a | |
Zher Huei Lee | f4ebba513a | |
Ignacio Etcheverry | 40d21117f9 | |
Ignacio Etcheverry | e120e2265b | |
Rémi Verschelde | 8746966194 | |
sanikoyes | 76eeb457d3 | |
sanikoyes | 02afea1e4e | |
Bojidar Marinov | 692878b7f4 | |
Paulb23 | b7f5418f8d | |
Alexander Holland | d4d810faac | |
punto- | 3a390e9b44 | |
Rémi Verschelde | 5d63f4e758 | |
Rémi Verschelde | cbac9a2ca3 | |
Rémi Verschelde | 837d50714a | |
Paulb23 | bb6cfc130b | |
Paulb23 | b3891246e5 | |
Rémi Verschelde | 00566a8592 | |
Bojidar Marinov | 63e33cfdd2 | |
Bojidar Marinov | dea6671d58 | |
Paul Batty | 7c6d2e7062 | |
SaracenOne | eb927383f2 | |
sunnystormy | 5c98674a8b | |
Paulb23 | 4bde902de1 | |
Paulb23 | a5f07d18ec | |
Rémi Verschelde | 71da9a1a23 | |
Luiz Paulo de Vasconcellos | 44daccc861 | |
MSC | 4220ffbd8e | |
MSC | 43c74056b1 | |
Paulb23 | 48438e4f3b | |
Paulb23 | 5f901e2b27 | |
Paulb23 | 22ef9673dd | |
Zher Huei Lee | 5b1aa3a5cd | |
Rémi Verschelde | f06f574735 | |
blubee | aac3b9db5c | |
Rémi Verschelde | 9fdc1279cc | |
Paul Batty | 01471e4c09 | |
Rémi Verschelde | bac8248316 | |
Rémi Verschelde | 69e67d51c7 | |
Rémi Verschelde | c6ccd05fed | |
Paulb23 | 937a96b26b | |
Maxwell Huang-Hobbs | a52b1e866d | |
Josh Grams | fed11a662a | |
Paulb23 | 26f2b7415c | |
Paulb23 | 729dc5da83 | |
sanikoyes | 54625bb771 | |
Paulb23 | 523625a3d1 | |
Rémi Verschelde | 5caf6ad8b9 | |
Ignacio Etcheverry | 7ddc17b18e | |
Ignacio Etcheverry | cf0a586a3e | |
demolitions | 41cc4ffe98 | |
Bojidar Marinov | 0ea354c12a | |
demolitions | 2bc4049b9b | |
Paulb23 | 64a8fe6ad7 | |
sanikoyes | 05c620b7ad | |
Saracen | ca1ca6c7df | |
Paulb23 | 1369b38d85 | |
Paulb23 | 68b7f9d87a | |
Paulb23 | 8a78112e5b | |
Franklin Sobrinho | 41326781d2 | |
Ignacio Etcheverry | cacf7d136f | |
Ignacio Etcheverry | a701c6ff68 | |
Franklin Sobrinho | 812de22194 | |
Franklin Sobrinho | 8de0405032 | |
Franklin Sobrinho | e59c0610ca | |
Paulb23 | 8fd4c78caf | |
Brandon DeRosier | 85820434de | |
Saracen | d0151daa69 | |
Rémi Verschelde | 763b29ed18 | |
Rémi Verschelde | 1d096471dc | |
sanikoyes | 7c44cbee67 | |
Ignacio Etcheverry | d950a13c10 | |
Ignacio Etcheverry | 6ce273b329 | |
Josh Grams | 0635a639e9 | |
Hubert Jarosz | 424a104666 | |
Josh Grams | 830947feaf | |
Josh Grams | ee20365f7c | |
RegalMedia | 0a24f562fb | |
Josh Grams | 60e4cfbcb7 | |
hondres | 656aa0a501 | |
volzhs | 7ad50eaea8 | |
Hubert Jarosz | 83887ae16d | |
hondres | 827f4a895a | |
Paulb23 | da356eca0f | |
Rémi Verschelde | 53aa9cd51a | |
Rémi Verschelde | 706d576f7b | |
Franklin Sobrinho | 226e0a7f4f | |
hondres | c44060bb82 | |
Martin Chuckeles | 4fee5f3915 | |
Franklin Sobrinho | e69c9021b5 | |
Franklin Sobrinho | edb3716da7 | |
Franklin Sobrinho | 1bdd5d24cb | |
Franklin Sobrinho | a1a1c0b9f6 | |
Martin Chuckeles | 450a7a9120 | |
Zher Huei Lee | c850fa7331 | |
hondres | afd75013f9 | |
Martin Chuckeles | 848c7378fd | |
Martin Chuckeles | 4b2fcabb74 | |
Martin Chuckeles | cb7693c533 | |
Stabington | 7fea990b1b | |
volzhs | 95e46e6eac | |
Josh Grams | bea8e1654e | |
Josh Grams | cafcdb015d | |
Rémi Verschelde | 459b914d9c | |
Rémi Verschelde | 9ed3d21d5a | |
hinsbart | 82d06b0027 | |
Ariel Manzur | e0a66b6e56 | |
Bojidar Marinov | 186b82c350 | |
Rémi Verschelde | 1af2e1101d | |
Rémi Verschelde | a55f41e3d9 | |
Rémi Verschelde | 439e29ea95 | |
Rémi Verschelde | f5e8e89f50 | |
Ariel Manzur | f619b05751 | |
Juan Linietsky | aa94ff6dae | |
Krzysztof Jankowski | ee5c250b63 | |
Ariel Manzur | e4d367e7a1 | |
Ariel Manzur | 45a0bbe56e | |
Julian Murgia - StraToN | d86b12a397 | |
hinsbart | f0ba9c7e78 | |
David | 61f17fb1bb | |
Dana Olson | a43af20f31 | |
est31 | 7ba92ae9eb | |
est31 | b05c27a27f | |
Dana Olson | e30cbc3b36 |
|
@ -1,10 +1,9 @@
|
||||||
# GoDot auto generated files
|
# Godot auto generated files
|
||||||
platform/server/logo.h
|
platform/server/logo.h
|
||||||
platform/android/logo.h
|
platform/android/logo.h
|
||||||
platform/bb10/logo.h
|
platform/bb10/logo.h
|
||||||
platform/iphone/logo.h
|
platform/iphone/logo.h
|
||||||
platform/javascript/logo.h
|
platform/javascript/logo.h
|
||||||
platform/nacl/logo.h
|
|
||||||
platform/osx/logo.h
|
platform/osx/logo.h
|
||||||
platform/windows/logo.h
|
platform/windows/logo.h
|
||||||
platform/x11/logo.h
|
platform/x11/logo.h
|
||||||
|
@ -19,7 +18,9 @@ drivers/unix/os_unix_global_settings_path.cpp
|
||||||
tools/editor/register_exporters.cpp
|
tools/editor/register_exporters.cpp
|
||||||
tools/editor/doc_data_compressed.h
|
tools/editor/doc_data_compressed.h
|
||||||
tools/editor/editor_icons.cpp
|
tools/editor/editor_icons.cpp
|
||||||
-fpic
|
tools/editor/builtin_fonts.h
|
||||||
|
tools/editor/certs_compressed.h
|
||||||
|
tools/editor/translations.h
|
||||||
.fscache
|
.fscache
|
||||||
make.bat
|
make.bat
|
||||||
log.txt
|
log.txt
|
||||||
|
@ -31,6 +32,7 @@ doc/_build/
|
||||||
*.bc
|
*.bc
|
||||||
|
|
||||||
# Android specific
|
# Android specific
|
||||||
|
platform/android/java/build.gradle
|
||||||
platform/android/java/.gradle
|
platform/android/java/.gradle
|
||||||
platform/android/java/.gradletasknamecache
|
platform/android/java/.gradletasknamecache
|
||||||
platform/android/java/local.properties
|
platform/android/java/local.properties
|
||||||
|
@ -145,6 +147,8 @@ ipch/
|
||||||
*.opensdf
|
*.opensdf
|
||||||
*.sdf
|
*.sdf
|
||||||
*.cachefile
|
*.cachefile
|
||||||
|
*.VC.db
|
||||||
|
*.VC.VC.opendb
|
||||||
|
|
||||||
# Visual Studio profiler
|
# Visual Studio profiler
|
||||||
*.psess
|
*.psess
|
||||||
|
|
38
.travis.yml
38
.travis.yml
|
@ -1,7 +1,6 @@
|
||||||
language: cpp
|
language: cpp
|
||||||
|
|
||||||
sudo: required
|
sudo: false
|
||||||
dist: trusty
|
|
||||||
|
|
||||||
compiler:
|
compiler:
|
||||||
- gcc
|
- gcc
|
||||||
|
@ -41,12 +40,39 @@ matrix:
|
||||||
- compiler: clang
|
- compiler: clang
|
||||||
env: GODOT_TARGET=x11
|
env: GODOT_TARGET=x11
|
||||||
|
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
packages:
|
||||||
|
- build-essential
|
||||||
|
- scons
|
||||||
|
- pkg-config
|
||||||
|
- libx11-dev
|
||||||
|
- libxcursor-dev
|
||||||
|
- libasound2-dev
|
||||||
|
- libfreetype6-dev
|
||||||
|
- libgl1-mesa-dev
|
||||||
|
- libglu1-mesa-dev
|
||||||
|
- libssl-dev
|
||||||
|
- libxinerama-dev
|
||||||
|
- libudev-dev
|
||||||
|
|
||||||
|
# For cross-compiling to Windows.
|
||||||
|
- binutils-mingw-w64-i686
|
||||||
|
- binutils-mingw-w64-x86-64
|
||||||
|
- gcc-mingw-w64-i686
|
||||||
|
- gcc-mingw-w64-x86-64
|
||||||
|
- g++-mingw-w64-i686
|
||||||
|
- g++-mingw-w64-x86-64
|
||||||
|
- mingw-w64
|
||||||
|
|
||||||
|
|
||||||
before_script:
|
before_script:
|
||||||
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then sudo apt-get update -qq; sudo apt-get install -y scons pkg-config libx11-dev libxcursor-dev build-essential libasound2-dev libfreetype6-dev libgl1-mesa-dev libglu-dev libssl-dev libxinerama-dev libudev-dev; fi
|
|
||||||
- if [ "$TRAVIS_OS_NAME" = "linux" ] && [ "$GODOT_TARGET" = "windows" ]; then sudo apt-get update -qq; sudo apt-get install -y mingw32 mingw-w64; fi
|
|
||||||
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew update; brew install scons; fi
|
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew update; brew install scons; fi
|
||||||
- if [ "$TRAVIS_OS_NAME" = "osx" ] && [ "$GODOT_TARGET" = "android" ]; then brew update; brew install android-sdk android-ndk; export ANDROID_HOME=/usr/local/opt/android-sdk; export ANDROID_NDK_ROOT=/usr/local/opt/android-ndk; fi
|
- if [ "$TRAVIS_OS_NAME" = "osx" ] && [ "$GODOT_TARGET" = "android" ]; then
|
||||||
|
brew update; brew install -v android-sdk;
|
||||||
|
brew install -v android-ndk | grep -v "inflating:" | grep -v "creating:";
|
||||||
|
export ANDROID_HOME=/usr/local/opt/android-sdk; export ANDROID_NDK_ROOT=/usr/local/opt/android-ndk;
|
||||||
|
fi
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- scons platform=$GODOT_TARGET CXX=$CXX
|
- scons platform=$GODOT_TARGET CXX=$CXX openssl=builtin
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
![GODOT](/logo.png)
|
![GODOT](/logo.png)
|
||||||
|
|
||||||
http://www.godotengine.org
|
https://godotengine.org
|
||||||
|
|
||||||
### The Engine
|
### The Engine
|
||||||
|
|
||||||
|
@ -13,17 +13,17 @@ Godot has been developed by Juan Linietsky and Ariel Manzur for several years, a
|
||||||
|
|
||||||
### Documentation
|
### Documentation
|
||||||
|
|
||||||
Documentation has been moved to [ReadTheDocs](http://docs.godotengine.org).
|
Documentation is hosted on [ReadTheDocs](http://docs.godotengine.org).
|
||||||
|
|
||||||
### Binary Downloads, Community, etc.
|
### Binary Downloads, Community, etc.
|
||||||
|
|
||||||
Binary downloads, community, etc. can be found in Godot homepage:
|
Binary downloads, community, etc. can be found in Godot homepage:
|
||||||
|
|
||||||
http://www.godotengine.org
|
https://godotengine.org
|
||||||
|
|
||||||
### Compiling from Source
|
### Compiling from Source
|
||||||
|
|
||||||
Compilation instructions for every platform can be found in the Wiki:
|
See docs for compilation instructions for every platform:
|
||||||
http://docs.godotengine.org/en/latest/reference/_compiling.html
|
http://docs.godotengine.org/en/latest/reference/_compiling.html
|
||||||
|
|
||||||
[![Build Status](https://travis-ci.org/godotengine/godot.svg?branch=master)](https://travis-ci.org/godotengine/godot)
|
[![Build Status](https://travis-ci.org/godotengine/godot.svg?branch=master)](https://travis-ci.org/godotengine/godot)
|
||||||
|
|
52
SConstruct
52
SConstruct
|
@ -23,7 +23,7 @@ platform_exporters=[]
|
||||||
global_defaults=[]
|
global_defaults=[]
|
||||||
|
|
||||||
for x in glob.glob("platform/*"):
|
for x in glob.glob("platform/*"):
|
||||||
if (not os.path.isdir(x)):
|
if (not os.path.isdir(x) or not os.path.exists(x+"/detect.py")):
|
||||||
continue
|
continue
|
||||||
tmppath="./"+x
|
tmppath="./"+x
|
||||||
|
|
||||||
|
@ -63,9 +63,9 @@ elif (os.name=="nt"):
|
||||||
if (os.getenv("VSINSTALLDIR")==None or platform_arg=="android"):
|
if (os.getenv("VSINSTALLDIR")==None or platform_arg=="android"):
|
||||||
custom_tools=['mingw']
|
custom_tools=['mingw']
|
||||||
|
|
||||||
env_base=Environment(tools=custom_tools,ENV = {'PATH' : os.environ['PATH']});
|
env_base=Environment(tools=custom_tools);
|
||||||
|
env_base.AppendENVPath('PATH', os.getenv('PATH'))
|
||||||
#env_base=Environment(tools=custom_tools);
|
env_base.AppendENVPath('PKG_CONFIG_PATH', os.getenv('PKG_CONFIG_PATH'))
|
||||||
env_base.global_defaults=global_defaults
|
env_base.global_defaults=global_defaults
|
||||||
env_base.android_maven_repos=[]
|
env_base.android_maven_repos=[]
|
||||||
env_base.android_dependencies=[]
|
env_base.android_dependencies=[]
|
||||||
|
@ -112,7 +112,8 @@ if profile:
|
||||||
|
|
||||||
opts=Variables(customs, ARGUMENTS)
|
opts=Variables(customs, ARGUMENTS)
|
||||||
opts.Add('target', 'Compile Target (debug/release_debug/release).', "debug")
|
opts.Add('target', 'Compile Target (debug/release_debug/release).', "debug")
|
||||||
opts.Add('bits', 'Compile Target Bits (default/32/64).', "default")
|
opts.Add('arch', 'Platform dependent architecture (arm/arm64/x86/x64/mips/etc)', "")
|
||||||
|
opts.Add('bits', 'Compile Target Bits (default/32/64/fat).', "default")
|
||||||
opts.Add('platform','Platform: '+str(platform_list)+'.',"")
|
opts.Add('platform','Platform: '+str(platform_list)+'.',"")
|
||||||
opts.Add('p','Platform (same as platform=).',"")
|
opts.Add('p','Platform (same as platform=).',"")
|
||||||
opts.Add('tools','Build Tools (Including Editor): (yes/no)','yes')
|
opts.Add('tools','Build Tools (Including Editor): (yes/no)','yes')
|
||||||
|
@ -267,10 +268,14 @@ if selected_platform in platform_list:
|
||||||
else:
|
else:
|
||||||
suffix+=".debug"
|
suffix+=".debug"
|
||||||
|
|
||||||
if (env["bits"]=="32"):
|
if env["arch"] != "":
|
||||||
|
suffix += "."+env["arch"]
|
||||||
|
elif (env["bits"]=="32"):
|
||||||
suffix+=".32"
|
suffix+=".32"
|
||||||
elif (env["bits"]=="64"):
|
elif (env["bits"]=="64"):
|
||||||
suffix+=".64"
|
suffix+=".64"
|
||||||
|
elif (env["bits"]=="fat"):
|
||||||
|
suffix+=".fat"
|
||||||
|
|
||||||
suffix+=env.extra_suffix
|
suffix+=env.extra_suffix
|
||||||
|
|
||||||
|
@ -302,10 +307,10 @@ if selected_platform in platform_list:
|
||||||
if (env['musepack']=='yes'):
|
if (env['musepack']=='yes'):
|
||||||
env.Append(CPPFLAGS=['-DMUSEPACK_ENABLED']);
|
env.Append(CPPFLAGS=['-DMUSEPACK_ENABLED']);
|
||||||
|
|
||||||
if (env['openssl']!='no'):
|
#if (env['openssl']!='no'):
|
||||||
env.Append(CPPFLAGS=['-DOPENSSL_ENABLED']);
|
# env.Append(CPPFLAGS=['-DOPENSSL_ENABLED']);
|
||||||
if (env['openssl']=="builtin"):
|
# if (env['openssl']=="builtin"):
|
||||||
env.Append(CPPPATH=['#drivers/builtin_openssl2'])
|
# env.Append(CPPPATH=['#drivers/builtin_openssl2'])
|
||||||
|
|
||||||
if (env["builtin_zlib"]=='yes'):
|
if (env["builtin_zlib"]=='yes'):
|
||||||
env.Append(CPPPATH=['#drivers/builtin_zlib/zlib'])
|
env.Append(CPPPATH=['#drivers/builtin_zlib/zlib'])
|
||||||
|
@ -324,7 +329,7 @@ if selected_platform in platform_list:
|
||||||
|
|
||||||
if (env['theora']=='yes'):
|
if (env['theora']=='yes'):
|
||||||
env['theoralib']='yes'
|
env['theoralib']='yes'
|
||||||
env.Append(CPPFLAGS=['-DTHEORA_ENABLED']);
|
env.Append(CPPFLAGS=['-DTHEORA_ENABLED']);
|
||||||
if (env['theoralib']=='yes'):
|
if (env['theoralib']=='yes'):
|
||||||
env.Append(CPPFLAGS=['-DTHEORALIB_ENABLED']);
|
env.Append(CPPFLAGS=['-DTHEORALIB_ENABLED']);
|
||||||
|
|
||||||
|
@ -389,14 +394,25 @@ if selected_platform in platform_list:
|
||||||
AddToVSProject(env.servers_sources)
|
AddToVSProject(env.servers_sources)
|
||||||
AddToVSProject(env.tool_sources)
|
AddToVSProject(env.tool_sources)
|
||||||
|
|
||||||
|
# this env flag won't work, it needs to be set in env_base=Environment(MSVC_VERSION='9.0')
|
||||||
|
# Even then, SCons still seems to ignore it and builds with the latest MSVC...
|
||||||
|
# That said, it's not needed to be set so far but I'm leaving it here so that this comment
|
||||||
|
# has a purpose.
|
||||||
#env['MSVS_VERSION']='9.0'
|
#env['MSVS_VERSION']='9.0'
|
||||||
env['MSVSBUILDCOM'] = "scons platform=" + selected_platform + " target=" + env["target"] + " bits=" + env["bits"] + " tools=yes"
|
|
||||||
env['MSVSREBUILDCOM'] = "scons platform=" + selected_platform + " target=" + env["target"] + " bits=" + env["bits"] + " tools=yes vsproj=true"
|
|
||||||
env['MSVSCLEANCOM'] = "scons --clean platform=" + selected_platform + " target=" + env["target"] + " bits=" + env["bits"] + " tools=yes"
|
# Calls a CMD with /C(lose) and /V(delayed environment variable expansion) options.
|
||||||
|
# And runs vcvarsall bat for the propper arhitecture and scons for propper configuration
|
||||||
debug_variants = ['Debug|Win32']+['Debug|x64']
|
env['MSVSBUILDCOM'] = 'cmd /V /C set "plat=$(PlatformTarget)" ^& (if "$(PlatformTarget)"=="x64" (set "plat=x86_amd64")) ^& set "tools=yes" ^& (if "$(Configuration)"=="release" (set "tools=no")) ^& call "$(VCInstallDir)vcvarsall.bat" !plat! ^& scons platform=windows target=$(Configuration) tools=!tools! -j2'
|
||||||
release_variants = ['Release|Win32']+['Release|x64']
|
env['MSVSREBUILDCOM'] = 'cmd /V /C set "plat=$(PlatformTarget)" ^& (if "$(PlatformTarget)"=="x64" (set "plat=x86_amd64")) ^& set "tools=yes" ^& (if "$(Configuration)"=="release" (set "tools=no")) & call "$(VCInstallDir)vcvarsall.bat" !plat! ^& scons platform=windows target=$(Configuration) tools=!tools! vsproj=yes -j2'
|
||||||
release_debug_variants = ['Release_Debug|Win32']+['Release_Debug|x64']
|
env['MSVSCLEANCOM'] = 'cmd /V /C set "plat=$(PlatformTarget)" ^& (if "$(PlatformTarget)"=="x64" (set "plat=x86_amd64")) ^& set "tools=yes" ^& (if "$(Configuration)"=="release" (set "tools=no")) ^& call "$(VCInstallDir)vcvarsall.bat" !plat! ^& scons --clean platform=windows target=$(Configuration) tools=!tools! -j2'
|
||||||
|
|
||||||
|
# This version information (Win32, x64, Debug, Release, Release_Debug seems to be
|
||||||
|
# required for Visual Studio to understand that it needs to generate an NMAKE
|
||||||
|
# project. Do not modify without knowing what you are doing.
|
||||||
|
debug_variants = ['debug|Win32']+['debug|x64']
|
||||||
|
release_variants = ['release|Win32']+['release|x64']
|
||||||
|
release_debug_variants = ['release_debug|Win32']+['release_debug|x64']
|
||||||
variants = debug_variants + release_variants + release_debug_variants
|
variants = debug_variants + release_variants + release_debug_variants
|
||||||
debug_targets = ['Debug']+['Debug']
|
debug_targets = ['Debug']+['Debug']
|
||||||
release_targets = ['Release']+['Release']
|
release_targets = ['Release']+['Release']
|
||||||
|
|
|
@ -44,9 +44,9 @@ MainLoop * test() {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
HashMap<int,int> int_map;
|
HashMap<int,int> int_map;
|
||||||
|
|
||||||
for (int i=0;i<68000;i++) {
|
for (int i=0;i<68000;i++) {
|
||||||
|
|
||||||
int num=(int)Math::random(0,1024);
|
int num=(int)Math::random(0,1024);
|
||||||
int_map[i]=num;
|
int_map[i]=num;
|
||||||
}
|
}
|
||||||
|
@ -70,21 +70,21 @@ MainLoop * test() {
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
Set<int> set;
|
Set<int> set;
|
||||||
|
|
||||||
print_line("Begin Insert");
|
print_line("Begin Insert");
|
||||||
for (int i=0;i<1100;i++) {
|
for (int i=0;i<1100;i++) {
|
||||||
|
|
||||||
int num=i;//(int)Math::random(0,1024);
|
int num=i;//(int)Math::random(0,1024);
|
||||||
// print_line("inserting "+itos(num));
|
// print_line("inserting "+itos(num));
|
||||||
set.insert( num );
|
set.insert( num );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
for (int i=0;i<400;i++) {
|
for (int i=0;i<400;i++) {
|
||||||
|
|
||||||
int num=(int)Math::random(0,1024);
|
int num=(int)Math::random(0,1024);
|
||||||
set.erase(num);
|
set.erase(num);
|
||||||
}
|
}
|
||||||
|
@ -92,11 +92,11 @@ MainLoop * test() {
|
||||||
//set.print_tree();
|
//set.print_tree();
|
||||||
|
|
||||||
for(Set<int>::Element *I=set.front();I;I=I->next()) {
|
for(Set<int>::Element *I=set.front();I;I=I->next()) {
|
||||||
|
|
||||||
print_line("inserted "+itos(I->get())+" prev is "+itos(I->prev()?I->prev()->get():-100));
|
print_line("inserted "+itos(I->get())+" prev is "+itos(I->prev()?I->prev()->get():-100));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
print_line("depth is "+itos(set.calculate_depth()));
|
print_line("depth is "+itos(set.calculate_depth()));
|
||||||
print_line("Insert Success");
|
print_line("Insert Success");
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -44,7 +44,7 @@ class TestMainLoop : public MainLoop {
|
||||||
RID light;
|
RID light;
|
||||||
RID mesh;
|
RID mesh;
|
||||||
RID scenario;
|
RID scenario;
|
||||||
|
|
||||||
#define MULTIMESH_COUNT 1500
|
#define MULTIMESH_COUNT 1500
|
||||||
|
|
||||||
float ofs_x,ofs_y;
|
float ofs_x,ofs_y;
|
||||||
|
@ -122,9 +122,9 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void input_event(const InputEvent& p_event) {
|
virtual void input_event(const InputEvent& p_event) {
|
||||||
|
|
||||||
if (p_event.type==InputEvent::MOUSE_MOTION && p_event.mouse_motion.button_mask&4) {
|
if (p_event.type==InputEvent::MOUSE_MOTION && p_event.mouse_motion.button_mask&4) {
|
||||||
|
|
||||||
ofs_x+=p_event.mouse_motion.relative_y/200.0;
|
ofs_x+=p_event.mouse_motion.relative_y/200.0;
|
||||||
ofs_y+=p_event.mouse_motion.relative_x/200.0;
|
ofs_y+=p_event.mouse_motion.relative_x/200.0;
|
||||||
}
|
}
|
||||||
|
@ -142,16 +142,16 @@ public:
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void request_quit() {
|
virtual void request_quit() {
|
||||||
|
|
||||||
quit=true;
|
quit=true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
virtual void init() {
|
virtual void init() {
|
||||||
|
|
||||||
VisualServer *vs=VisualServer::get_singleton();
|
VisualServer *vs=VisualServer::get_singleton();
|
||||||
|
|
||||||
|
|
||||||
|
@ -163,13 +163,13 @@ public:
|
||||||
_update_qh();
|
_update_qh();
|
||||||
|
|
||||||
instance = vs->instance_create2(mesh,scenario);
|
instance = vs->instance_create2(mesh,scenario);
|
||||||
|
|
||||||
camera = vs->camera_create();
|
camera = vs->camera_create();
|
||||||
|
|
||||||
|
|
||||||
vs->camera_set_perspective( camera, 60.0,0.1, 100.0 );
|
vs->camera_set_perspective( camera, 60.0,0.1, 100.0 );
|
||||||
viewport = vs->viewport_create();
|
viewport = vs->viewport_create();
|
||||||
vs->viewport_attach_camera( viewport, camera );
|
vs->viewport_attach_camera( viewport, camera );
|
||||||
vs->viewport_attach_to_screen(viewport);
|
vs->viewport_attach_to_screen(viewport);
|
||||||
vs->viewport_set_scenario( viewport, scenario );
|
vs->viewport_set_scenario( viewport, scenario );
|
||||||
|
|
||||||
|
@ -179,7 +179,7 @@ public:
|
||||||
//vs->light_set_color( lightaux, VisualServer::LIGHT_COLOR_AMBIENT, Color(0.3,0.3,0.3) );
|
//vs->light_set_color( lightaux, VisualServer::LIGHT_COLOR_AMBIENT, Color(0.3,0.3,0.3) );
|
||||||
light = vs->instance_create2( lightaux,scenario );
|
light = vs->instance_create2( lightaux,scenario );
|
||||||
vs->instance_set_transform(light,Transform(Matrix3(Vector3(0.1,0.4,0.7).normalized(),0.9)));
|
vs->instance_set_transform(light,Transform(Matrix3(Vector3(0.1,0.4,0.7).normalized(),0.9)));
|
||||||
|
|
||||||
ofs_x=0;
|
ofs_x=0;
|
||||||
ofs_y=0;
|
ofs_y=0;
|
||||||
quit=false;
|
quit=false;
|
||||||
|
@ -190,20 +190,20 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool iteration(float p_time) {
|
virtual bool iteration(float p_time) {
|
||||||
|
|
||||||
VisualServer *vs=VisualServer::get_singleton();
|
VisualServer *vs=VisualServer::get_singleton();
|
||||||
|
|
||||||
Transform tr_camera;
|
Transform tr_camera;
|
||||||
tr_camera.rotate( Vector3(0,1,0), ofs_y );
|
tr_camera.rotate( Vector3(0,1,0), ofs_y );
|
||||||
tr_camera.rotate( Vector3(1,0,0),ofs_x );
|
tr_camera.rotate( Vector3(1,0,0),ofs_x );
|
||||||
tr_camera.translate(0,0,10);
|
tr_camera.translate(0,0,10);
|
||||||
|
|
||||||
vs->camera_set_transform( camera, tr_camera );
|
vs->camera_set_transform( camera, tr_camera );
|
||||||
|
|
||||||
return quit;
|
return quit;
|
||||||
}
|
}
|
||||||
virtual void finish() {
|
virtual void finish() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -81,7 +81,7 @@ static String _parser_expr(const GDParser::Node *p_expr) {
|
||||||
|
|
||||||
case GDParser::Node::TYPE_IDENTIFIER: {
|
case GDParser::Node::TYPE_IDENTIFIER: {
|
||||||
|
|
||||||
const GDParser::IdentifierNode *id_node = static_cast<const GDParser::IdentifierNode *>(p_expr);
|
const GDParser::IdentifierNode *id_node = static_cast<const GDParser::IdentifierNode *>(p_expr);
|
||||||
txt=id_node->name;
|
txt=id_node->name;
|
||||||
} break;
|
} break;
|
||||||
case GDParser::Node::TYPE_CONSTANT: {
|
case GDParser::Node::TYPE_CONSTANT: {
|
||||||
|
|
|
@ -62,16 +62,16 @@ class TestMainLoop : public SceneTree {
|
||||||
|
|
||||||
|
|
||||||
Control *control;
|
Control *control;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
virtual void request_quit() {
|
virtual void request_quit() {
|
||||||
|
|
||||||
quit();
|
quit();
|
||||||
|
|
||||||
}
|
}
|
||||||
virtual void init() {
|
virtual void init() {
|
||||||
|
|
||||||
SceneTree::init();
|
SceneTree::init();
|
||||||
|
|
||||||
|
|
||||||
|
@ -112,7 +112,7 @@ public:
|
||||||
|
|
||||||
Ref<Theme> t = memnew( Theme );
|
Ref<Theme> t = memnew( Theme );
|
||||||
frame->set_theme(t);
|
frame->set_theme(t);
|
||||||
|
|
||||||
get_root()->add_child( frame );
|
get_root()->add_child( frame );
|
||||||
|
|
||||||
Label *label = memnew( Label );
|
Label *label = memnew( Label );
|
||||||
|
@ -198,21 +198,21 @@ public:
|
||||||
//root->add_child( control );
|
//root->add_child( control );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
LineEdit *line_edit = memnew( LineEdit );
|
LineEdit *line_edit = memnew( LineEdit );
|
||||||
|
|
||||||
line_edit->set_pos( Point2( 30,190 ) );
|
line_edit->set_pos( Point2( 30,190 ) );
|
||||||
line_edit->set_size( Point2( 180,1 ) );
|
line_edit->set_size( Point2( 180,1 ) );
|
||||||
|
|
||||||
frame->add_child(line_edit);
|
frame->add_child(line_edit);
|
||||||
|
|
||||||
HScrollBar *hscroll = memnew( HScrollBar );
|
HScrollBar *hscroll = memnew( HScrollBar );
|
||||||
|
|
||||||
hscroll->set_pos( Point2( 30,290 ) );
|
hscroll->set_pos( Point2( 30,290 ) );
|
||||||
hscroll->set_size( Point2( 180,1 ) );
|
hscroll->set_size( Point2( 180,1 ) );
|
||||||
hscroll->set_max(10);
|
hscroll->set_max(10);
|
||||||
hscroll->set_page(4);
|
hscroll->set_page(4);
|
||||||
|
|
||||||
frame->add_child(hscroll);
|
frame->add_child(hscroll);
|
||||||
|
|
||||||
|
|
||||||
|
@ -234,36 +234,36 @@ public:
|
||||||
hscroll->share(progress);
|
hscroll->share(progress);
|
||||||
|
|
||||||
MenuButton *menu_button = memnew( MenuButton );
|
MenuButton *menu_button = memnew( MenuButton );
|
||||||
|
|
||||||
menu_button->set_text("I'm a menu!");
|
menu_button->set_text("I'm a menu!");
|
||||||
menu_button->set_pos( Point2( 30,380 ) );
|
menu_button->set_pos( Point2( 30,380 ) );
|
||||||
menu_button->set_size( Point2( 1,1 ) );
|
menu_button->set_size( Point2( 1,1 ) );
|
||||||
|
|
||||||
frame->add_child(menu_button);
|
frame->add_child(menu_button);
|
||||||
|
|
||||||
PopupMenu *popup = menu_button->get_popup();
|
PopupMenu *popup = menu_button->get_popup();
|
||||||
|
|
||||||
popup->add_item("Hello, testing");
|
popup->add_item("Hello, testing");
|
||||||
popup->add_item("My Dearest");
|
popup->add_item("My Dearest");
|
||||||
popup->add_separator();
|
popup->add_separator();
|
||||||
popup->add_item("Popup");
|
popup->add_item("Popup");
|
||||||
popup->add_check_item("Check Popup");
|
popup->add_check_item("Check Popup");
|
||||||
popup->set_item_checked(4,true);
|
popup->set_item_checked(4,true);
|
||||||
|
|
||||||
OptionButton *options = memnew( OptionButton );
|
OptionButton *options = memnew( OptionButton );
|
||||||
|
|
||||||
options->add_item("Hello, testing");
|
options->add_item("Hello, testing");
|
||||||
options->add_item("My Dearest");
|
options->add_item("My Dearest");
|
||||||
|
|
||||||
options->set_pos( Point2( 230,180 ) );
|
options->set_pos( Point2( 230,180 ) );
|
||||||
options->set_size( Point2( 1,1 ) );
|
options->set_size( Point2( 1,1 ) );
|
||||||
|
|
||||||
frame->add_child(options);
|
frame->add_child(options);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Tree * tree = memnew( Tree );
|
Tree * tree = memnew( Tree );
|
||||||
tree->set_columns(2);
|
tree->set_columns(2);
|
||||||
|
|
||||||
tree->set_pos( Point2( 230,210 ) );
|
tree->set_pos( Point2( 230,210 ) );
|
||||||
tree->set_size( Point2( 150,250 ) );
|
tree->set_size( Point2( 150,250 ) );
|
||||||
|
|
||||||
|
@ -286,7 +286,7 @@ public:
|
||||||
item->set_editable(0,true);
|
item->set_editable(0,true);
|
||||||
item->set_text(0,"Have,Many,Several,Options!");
|
item->set_text(0,"Have,Many,Several,Options!");
|
||||||
item->set_range(0,2);
|
item->set_range(0,2);
|
||||||
|
|
||||||
frame->add_child(tree);
|
frame->add_child(tree);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -365,11 +365,11 @@ public:
|
||||||
tabc->add_child(ctl);
|
tabc->add_child(ctl);
|
||||||
|
|
||||||
frame->add_child(tabc);
|
frame->add_child(tabc);
|
||||||
|
|
||||||
tabc->set_pos( Point2( 400,210 ) );
|
tabc->set_pos( Point2( 400,210 ) );
|
||||||
tabc->set_size( Point2( 180,250 ) );
|
tabc->set_size( Point2( 180,250 ) );
|
||||||
|
|
||||||
|
|
||||||
Ref<ImageTexture> text = memnew( ImageTexture );
|
Ref<ImageTexture> text = memnew( ImageTexture );
|
||||||
text->load("test_data/concave.png");
|
text->load("test_data/concave.png");
|
||||||
|
|
||||||
|
@ -387,13 +387,13 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
MainLoop* test() {
|
MainLoop* test() {
|
||||||
|
|
||||||
|
|
||||||
return memnew( TestMainLoop );
|
return memnew( TestMainLoop );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,37 +47,37 @@ namespace TestIO {
|
||||||
|
|
||||||
|
|
||||||
class TestMainLoop : public MainLoop {
|
class TestMainLoop : public MainLoop {
|
||||||
|
|
||||||
|
|
||||||
bool quit;
|
bool quit;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual void input_event(const InputEvent& p_event) {
|
virtual void input_event(const InputEvent& p_event) {
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
virtual bool idle(float p_time) {
|
virtual bool idle(float p_time) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void request_quit() {
|
virtual void request_quit() {
|
||||||
|
|
||||||
quit=true;
|
quit=true;
|
||||||
|
|
||||||
}
|
}
|
||||||
virtual void init() {
|
virtual void init() {
|
||||||
|
|
||||||
quit=true;
|
quit=true;
|
||||||
}
|
}
|
||||||
virtual bool iteration(float p_time) {
|
virtual bool iteration(float p_time) {
|
||||||
|
|
||||||
return quit;
|
return quit;
|
||||||
}
|
}
|
||||||
virtual void finish() {
|
virtual void finish() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -64,7 +64,7 @@ const char ** tests_get_names() {
|
||||||
"physics",
|
"physics",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
return test_names;
|
return test_names;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,22 +72,22 @@ MainLoop* test_main(String p_test,const List<String>& p_args) {
|
||||||
|
|
||||||
|
|
||||||
if (p_test=="string") {
|
if (p_test=="string") {
|
||||||
|
|
||||||
return TestString::test();
|
return TestString::test();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p_test=="containers") {
|
if (p_test=="containers") {
|
||||||
|
|
||||||
return TestContainers::test();
|
return TestContainers::test();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p_test=="math") {
|
if (p_test=="math") {
|
||||||
|
|
||||||
return TestMath::test();
|
return TestMath::test();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p_test=="physics") {
|
if (p_test=="physics") {
|
||||||
|
|
||||||
return TestPhysics::test();
|
return TestPhysics::test();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,15 +97,15 @@ MainLoop* test_main(String p_test,const List<String>& p_args) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p_test=="misc") {
|
if (p_test=="misc") {
|
||||||
|
|
||||||
return TestMisc::test();
|
return TestMisc::test();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p_test=="render") {
|
if (p_test=="render") {
|
||||||
|
|
||||||
return TestRender::test();
|
return TestRender::test();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef _3D_DISABLED
|
#ifndef _3D_DISABLED
|
||||||
if (p_test=="gui") {
|
if (p_test=="gui") {
|
||||||
|
|
||||||
|
@ -119,17 +119,17 @@ MainLoop* test_main(String p_test,const List<String>& p_args) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p_test=="io") {
|
if (p_test=="io") {
|
||||||
|
|
||||||
return TestIO::test();
|
return TestIO::test();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p_test=="particles") {
|
if (p_test=="particles") {
|
||||||
|
|
||||||
return TestParticles::test();
|
return TestParticles::test();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p_test=="multimesh") {
|
if (p_test=="multimesh") {
|
||||||
|
|
||||||
return TestMultiMesh::test();
|
return TestMultiMesh::test();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,7 +171,7 @@ MainLoop* test_main(String p_test,const List<String>& p_args) {
|
||||||
#ifdef PYTHON_ENABLED
|
#ifdef PYTHON_ENABLED
|
||||||
|
|
||||||
if (p_test=="python") {
|
if (p_test=="python") {
|
||||||
|
|
||||||
return TestPython::test();
|
return TestPython::test();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -70,7 +70,7 @@ fix: 0, 0, 49.949951, 50
|
||||||
v0: 0, 0, 100, 100
|
v0: 0, 0, 100, 100
|
||||||
v1: 0, 0, 100, 100
|
v1: 0, 0, 100, 100
|
||||||
fix: 0, 0, 100, 100
|
fix: 0, 0, 100, 100
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,38 +43,38 @@ class TestMainLoop : public MainLoop {
|
||||||
RID viewport;
|
RID viewport;
|
||||||
RID light;
|
RID light;
|
||||||
RID scenario;
|
RID scenario;
|
||||||
|
|
||||||
struct InstanceInfo {
|
struct InstanceInfo {
|
||||||
|
|
||||||
RID instance;
|
RID instance;
|
||||||
Transform base;
|
Transform base;
|
||||||
Vector3 rot_axis;
|
Vector3 rot_axis;
|
||||||
};
|
};
|
||||||
|
|
||||||
List<InstanceInfo> instances;
|
List<InstanceInfo> instances;
|
||||||
|
|
||||||
float ofs;
|
float ofs;
|
||||||
bool quit;
|
bool quit;
|
||||||
public:
|
public:
|
||||||
virtual void input_event(const InputEvent& p_event) {
|
virtual void input_event(const InputEvent& p_event) {
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
virtual void request_quit() {
|
virtual void request_quit() {
|
||||||
|
|
||||||
quit=true;
|
quit=true;
|
||||||
}
|
}
|
||||||
virtual void init() {
|
virtual void init() {
|
||||||
|
|
||||||
VisualServer *vs=VisualServer::get_singleton();
|
VisualServer *vs=VisualServer::get_singleton();
|
||||||
particles = vs->particles_create();
|
particles = vs->particles_create();
|
||||||
vs->particles_set_amount(particles,1000);
|
vs->particles_set_amount(particles,1000);
|
||||||
|
|
||||||
instance = vs->instance_create2(particles,scenario);
|
instance = vs->instance_create2(particles,scenario);
|
||||||
|
|
||||||
|
|
||||||
camera = vs->camera_create();
|
camera = vs->camera_create();
|
||||||
|
|
||||||
// vs->camera_set_perspective( camera, 60.0,0.1, 100.0 );
|
// vs->camera_set_perspective( camera, 60.0,0.1, 100.0 );
|
||||||
viewport = vs->viewport_create();
|
viewport = vs->viewport_create();
|
||||||
vs->viewport_attach_camera( viewport, camera );
|
vs->viewport_attach_camera( viewport, camera );
|
||||||
|
@ -89,7 +89,7 @@ public:
|
||||||
RID lightaux = vs->light_create( VisualServer::LIGHT_DIRECTIONAL );
|
RID lightaux = vs->light_create( VisualServer::LIGHT_DIRECTIONAL );
|
||||||
// vs->light_set_color( lightaux, VisualServer::LIGHT_COLOR_AMBIENT, Color(0.0,0.0,0.0) );
|
// vs->light_set_color( lightaux, VisualServer::LIGHT_COLOR_AMBIENT, Color(0.0,0.0,0.0) );
|
||||||
light = vs->instance_create2( lightaux, scenario );
|
light = vs->instance_create2( lightaux, scenario );
|
||||||
|
|
||||||
ofs=0;
|
ofs=0;
|
||||||
quit=false;
|
quit=false;
|
||||||
}
|
}
|
||||||
|
@ -99,14 +99,14 @@ public:
|
||||||
|
|
||||||
|
|
||||||
virtual bool iteration(float p_time) {
|
virtual bool iteration(float p_time) {
|
||||||
|
|
||||||
// VisualServer *vs=VisualServer::get_singleton();
|
// VisualServer *vs=VisualServer::get_singleton();
|
||||||
|
|
||||||
ofs+=p_time;
|
ofs+=p_time;
|
||||||
return quit;
|
return quit;
|
||||||
}
|
}
|
||||||
virtual void finish() {
|
virtual void finish() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -47,7 +47,7 @@ class TestPhysicsMainLoop : public MainLoop {
|
||||||
};
|
};
|
||||||
|
|
||||||
RID test_cube;
|
RID test_cube;
|
||||||
|
|
||||||
RID plane;
|
RID plane;
|
||||||
RID sphere;
|
RID sphere;
|
||||||
RID light;
|
RID light;
|
||||||
|
@ -74,13 +74,13 @@ class TestPhysicsMainLoop : public MainLoop {
|
||||||
//t.basis.scale( Vector3(1.0,0.5,0.2) );
|
//t.basis.scale( Vector3(1.0,0.5,0.2) );
|
||||||
vs->instance_set_transform(p_visual_instance,t);
|
vs->instance_set_transform(p_visual_instance,t);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool quit;
|
bool quit;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
static void _bind_methods() {
|
static void _bind_methods() {
|
||||||
|
|
||||||
ObjectTypeDB::bind_method("body_changed_transform",&TestPhysicsMainLoop::body_changed_transform);
|
ObjectTypeDB::bind_method("body_changed_transform",&TestPhysicsMainLoop::body_changed_transform);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,11 +90,11 @@ protected:
|
||||||
PhysicsServer * ps = PhysicsServer::get_singleton();
|
PhysicsServer * ps = PhysicsServer::get_singleton();
|
||||||
|
|
||||||
RID mesh_instance = vs->instance_create2(type_mesh_map[p_shape],scenario);
|
RID mesh_instance = vs->instance_create2(type_mesh_map[p_shape],scenario);
|
||||||
RID body = ps->body_create(p_body,!p_active_default);
|
RID body = ps->body_create(p_body,!p_active_default);
|
||||||
ps->body_set_space(body,space);
|
ps->body_set_space(body,space);
|
||||||
ps->body_set_param(body,PhysicsServer::BODY_PARAM_BOUNCE,0.0);
|
ps->body_set_param(body,PhysicsServer::BODY_PARAM_BOUNCE,0.0);
|
||||||
//todo set space
|
//todo set space
|
||||||
ps->body_add_shape(body,type_shape_map[p_shape]);
|
ps->body_add_shape(body,type_shape_map[p_shape]);
|
||||||
ps->body_set_force_integration_callback(body,this,"body_changed_transform",mesh_instance);
|
ps->body_set_force_integration_callback(body,this,"body_changed_transform",mesh_instance);
|
||||||
|
|
||||||
ps->body_set_state( body, PhysicsServer::BODY_STATE_TRANSFORM,p_location);
|
ps->body_set_state( body, PhysicsServer::BODY_STATE_TRANSFORM,p_location);
|
||||||
|
@ -289,7 +289,7 @@ protected:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual void input_event(const InputEvent& p_event) {
|
virtual void input_event(const InputEvent& p_event) {
|
||||||
|
|
||||||
if (p_event.type==InputEvent::MOUSE_MOTION && p_event.mouse_motion.button_mask&4) {
|
if (p_event.type==InputEvent::MOUSE_MOTION && p_event.mouse_motion.button_mask&4) {
|
||||||
|
|
||||||
ofs_y-=p_event.mouse_motion.relative_y/200.0;
|
ofs_y-=p_event.mouse_motion.relative_y/200.0;
|
||||||
|
@ -329,7 +329,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void request_quit() {
|
virtual void request_quit() {
|
||||||
|
|
||||||
quit=true;
|
quit=true;
|
||||||
}
|
}
|
||||||
virtual void init() {
|
virtual void init() {
|
||||||
|
@ -388,53 +388,53 @@ public:
|
||||||
/* Make Trimesh */
|
/* Make Trimesh */
|
||||||
quit=false;
|
quit=false;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
#define GRID_SIZE 5
|
#define GRID_SIZE 5
|
||||||
|
|
||||||
float grid[GRID_SIZE][GRID_SIZE];
|
float grid[GRID_SIZE][GRID_SIZE];
|
||||||
|
|
||||||
for (int i=0;i<GRID_SIZE;i++) {
|
for (int i=0;i<GRID_SIZE;i++) {
|
||||||
|
|
||||||
for (int j=0;j<GRID_SIZE;j++) {
|
for (int j=0;j<GRID_SIZE;j++) {
|
||||||
|
|
||||||
grid[j][i]=Math::random(0.0, 1.0 );
|
grid[j][i]=Math::random(0.0, 1.0 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector<Vector3> faces;
|
Vector<Vector3> faces;
|
||||||
|
|
||||||
for (int i=1;i<GRID_SIZE;i++) {
|
for (int i=1;i<GRID_SIZE;i++) {
|
||||||
|
|
||||||
for (int j=1;j<GRID_SIZE;j++) {
|
for (int j=1;j<GRID_SIZE;j++) {
|
||||||
|
|
||||||
|
|
||||||
#define MAKE_VERTEX(m_x,m_z)\
|
#define MAKE_VERTEX(m_x,m_z)\
|
||||||
faces.push_back( Vector3( m_x-GRID_SIZE/2.0, grid[m_x][m_z], m_z-GRID_SIZE/2.0 )*3.0 )
|
faces.push_back( Vector3( m_x-GRID_SIZE/2.0, grid[m_x][m_z], m_z-GRID_SIZE/2.0 )*3.0 )
|
||||||
|
|
||||||
MAKE_VERTEX(i,j-1);
|
MAKE_VERTEX(i,j-1);
|
||||||
MAKE_VERTEX(i,j);
|
MAKE_VERTEX(i,j);
|
||||||
MAKE_VERTEX(i-1,j);
|
MAKE_VERTEX(i-1,j);
|
||||||
|
|
||||||
MAKE_VERTEX(i-1,j-1);
|
MAKE_VERTEX(i-1,j-1);
|
||||||
MAKE_VERTEX(i,j-1);
|
MAKE_VERTEX(i,j-1);
|
||||||
MAKE_VERTEX(i-1,j);
|
MAKE_VERTEX(i-1,j);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
faces.clear();
|
faces.clear();
|
||||||
faces.push_back( Vector3(0,0,-5) );
|
faces.push_back( Vector3(0,0,-5) );
|
||||||
faces.push_back( Vector3(1,0,-1) );
|
faces.push_back( Vector3(1,0,-1) );
|
||||||
faces.push_back( Vector3(-1,-0,-1) );
|
faces.push_back( Vector3(-1,-0,-1) );
|
||||||
*/
|
*/
|
||||||
|
|
||||||
RID trimesh_shape = ps->shape_create();
|
RID trimesh_shape = ps->shape_create();
|
||||||
ps->shape_set_data(trimesh_shape, PhysicsServer::SHAPE_CONCAVE_POLYGON,faces);
|
ps->shape_set_data(trimesh_shape, PhysicsServer::SHAPE_CONCAVE_POLYGON,faces);
|
||||||
faces=ps->shape_get_shape(trimesh_shape, 0);
|
faces=ps->shape_get_shape(trimesh_shape, 0);
|
||||||
Vector<Vector3> normals; // for drawing
|
Vector<Vector3> normals; // for drawing
|
||||||
for (int i=0;i<faces.size()/3;i++) {
|
for (int i=0;i<faces.size()/3;i++) {
|
||||||
|
|
||||||
Plane p( faces[i*3+0],faces[i*3+1], faces[i*3+2] );
|
Plane p( faces[i*3+0],faces[i*3+1], faces[i*3+2] );
|
||||||
normals.push_back(p.normal);
|
normals.push_back(p.normal);
|
||||||
normals.push_back(p.normal);
|
normals.push_back(p.normal);
|
||||||
|
@ -448,11 +448,11 @@ public:
|
||||||
RID trimesh_mat = vs->fixed_material_create();
|
RID trimesh_mat = vs->fixed_material_create();
|
||||||
vs->material_generate( trimesh_mat, Color(1.0,0.5,0.3) );
|
vs->material_generate( trimesh_mat, Color(1.0,0.5,0.3) );
|
||||||
vs->mesh_surface_set_material( trimesh_mesh, 0, trimesh_mat );
|
vs->mesh_surface_set_material( trimesh_mesh, 0, trimesh_mat );
|
||||||
|
|
||||||
RID triins = vs->instance_create2(trimesh_mesh);
|
RID triins = vs->instance_create2(trimesh_mesh);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
RID tribody = ps->body_create( PhysicsServer::BODY_MODE_STATIC, trimesh_shape);
|
RID tribody = ps->body_create( PhysicsServer::BODY_MODE_STATIC, trimesh_shape);
|
||||||
Transform tritrans = Transform( Matrix3(), Vector3(0,0,-2) );
|
Transform tritrans = Transform( Matrix3(), Vector3(0,0,-2) );
|
||||||
ps->body_set_state( tribody, PhysicsServer::BODY_STATE_TRANSFORM, tritrans );
|
ps->body_set_state( tribody, PhysicsServer::BODY_STATE_TRANSFORM, tritrans );
|
||||||
|
@ -483,7 +483,7 @@ public:
|
||||||
return quit;
|
return quit;
|
||||||
}
|
}
|
||||||
virtual void finish() {
|
virtual void finish() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_joint() {
|
void test_joint() {
|
||||||
|
@ -599,7 +599,7 @@ public:
|
||||||
PhysicsServer::ShapeType type=shape_idx[i%4];
|
PhysicsServer::ShapeType type=shape_idx[i%4];
|
||||||
//type=PhysicsServer::SHAPE_CONVEX_POLYGON;
|
//type=PhysicsServer::SHAPE_CONVEX_POLYGON;
|
||||||
|
|
||||||
Transform t;
|
Transform t;
|
||||||
|
|
||||||
t.origin=Vector3(0.0*i,3.5+1.1*i,0.7+0.0*i);
|
t.origin=Vector3(0.0*i,3.5+1.1*i,0.7+0.0*i);
|
||||||
//t.origin=Vector3(-0.7+0.0*i,0.5+4.1*i,0);
|
//t.origin=Vector3(-0.7+0.0*i,0.5+4.1*i,0);
|
||||||
|
|
|
@ -47,7 +47,7 @@ void test() {
|
||||||
PyRun_SimpleString("b=Moch();\n");
|
PyRun_SimpleString("b=Moch();\n");
|
||||||
PyRun_SimpleString("b.mooch();\n");
|
PyRun_SimpleString("b.mooch();\n");
|
||||||
PyRun_SimpleString("b.meis();\n");
|
PyRun_SimpleString("b.meis();\n");
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,16 +49,16 @@ class TestMainLoop : public MainLoop {
|
||||||
RID viewport;
|
RID viewport;
|
||||||
RID light;
|
RID light;
|
||||||
RID scenario;
|
RID scenario;
|
||||||
|
|
||||||
struct InstanceInfo {
|
struct InstanceInfo {
|
||||||
|
|
||||||
RID instance;
|
RID instance;
|
||||||
Transform base;
|
Transform base;
|
||||||
Vector3 rot_axis;
|
Vector3 rot_axis;
|
||||||
};
|
};
|
||||||
|
|
||||||
List<InstanceInfo> instances;
|
List<InstanceInfo> instances;
|
||||||
|
|
||||||
float ofs;
|
float ofs;
|
||||||
bool quit;
|
bool quit;
|
||||||
protected:
|
protected:
|
||||||
|
@ -66,13 +66,13 @@ protected:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual void input_event(const InputEvent& p_event) {
|
virtual void input_event(const InputEvent& p_event) {
|
||||||
|
|
||||||
if (p_event.type==InputEvent::KEY && p_event.key.pressed)
|
if (p_event.type==InputEvent::KEY && p_event.key.pressed)
|
||||||
quit=true;
|
quit=true;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void init() {
|
virtual void init() {
|
||||||
|
|
||||||
|
|
||||||
print_line("INITIALIZING TEST RENDER");
|
print_line("INITIALIZING TEST RENDER");
|
||||||
VisualServer *vs=VisualServer::get_singleton();
|
VisualServer *vs=VisualServer::get_singleton();
|
||||||
|
@ -150,26 +150,26 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
for (int i=0;i<object_count;i++) {
|
for (int i=0;i<object_count;i++) {
|
||||||
|
|
||||||
InstanceInfo ii;
|
InstanceInfo ii;
|
||||||
|
|
||||||
|
|
||||||
ii.instance = vs->instance_create2( test_cube, scenario );
|
ii.instance = vs->instance_create2( test_cube, scenario );
|
||||||
|
|
||||||
|
|
||||||
ii.base.translate( Math::random(-20,20), Math::random(-20,20),Math::random(-20,18) );
|
ii.base.translate( Math::random(-20,20), Math::random(-20,20),Math::random(-20,18) );
|
||||||
ii.base.rotate( Vector3(0,1,0), Math::randf() * Math_PI );
|
ii.base.rotate( Vector3(0,1,0), Math::randf() * Math_PI );
|
||||||
ii.base.rotate( Vector3(1,0,0), Math::randf() * Math_PI );
|
ii.base.rotate( Vector3(1,0,0), Math::randf() * Math_PI );
|
||||||
vs->instance_set_transform( ii.instance, ii.base );
|
vs->instance_set_transform( ii.instance, ii.base );
|
||||||
|
|
||||||
ii.rot_axis = Vector3( Math::random(-1,1), Math::random(-1,1), Math::random(-1,1) ).normalized();
|
ii.rot_axis = Vector3( Math::random(-1,1), Math::random(-1,1), Math::random(-1,1) ).normalized();
|
||||||
|
|
||||||
instances.push_back(ii);
|
instances.push_back(ii);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
camera = vs->camera_create();
|
camera = vs->camera_create();
|
||||||
|
|
||||||
// vs->camera_set_perspective( camera, 60.0,0.1, 100.0 );
|
// vs->camera_set_perspective( camera, 60.0,0.1, 100.0 );
|
||||||
|
|
||||||
viewport = vs->viewport_create();
|
viewport = vs->viewport_create();
|
||||||
|
@ -226,9 +226,9 @@ public:
|
||||||
ofs+=p_time*0.05;
|
ofs+=p_time*0.05;
|
||||||
|
|
||||||
//return quit;
|
//return quit;
|
||||||
|
|
||||||
for(List<InstanceInfo>::Element *E=instances.front();E;E=E->next()) {
|
for(List<InstanceInfo>::Element *E=instances.front();E;E=E->next()) {
|
||||||
|
|
||||||
Transform pre( Matrix3(E->get().rot_axis, ofs), Vector3() );
|
Transform pre( Matrix3(E->get().rot_axis, ofs), Vector3() );
|
||||||
vs->instance_set_transform( E->get().instance, pre * E->get().base );
|
vs->instance_set_transform( E->get().instance, pre * E->get().base );
|
||||||
/*
|
/*
|
||||||
|
@ -238,7 +238,7 @@ public:
|
||||||
instances.erase(E );
|
instances.erase(E );
|
||||||
}*/
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
return quit;
|
return quit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -290,7 +290,7 @@ MainLoop* test() {
|
||||||
|
|
||||||
FileAccess *fa = FileAccess::open(test,FileAccess::READ);
|
FileAccess *fa = FileAccess::open(test,FileAccess::READ);
|
||||||
|
|
||||||
if (!fa) {
|
if (!fa) {
|
||||||
ERR_FAIL_V(NULL);
|
ERR_FAIL_V(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,145 +38,145 @@
|
||||||
namespace TestString {
|
namespace TestString {
|
||||||
|
|
||||||
bool test_1() {
|
bool test_1() {
|
||||||
|
|
||||||
OS::get_singleton()->print("\n\nTest 1: Assign from cstr\n");
|
OS::get_singleton()->print("\n\nTest 1: Assign from cstr\n");
|
||||||
|
|
||||||
String s = "Hello";
|
String s = "Hello";
|
||||||
|
|
||||||
OS::get_singleton()->print("\tExpected: Hello\n");
|
OS::get_singleton()->print("\tExpected: Hello\n");
|
||||||
OS::get_singleton()->print("\tResulted: %ls\n",s.c_str());
|
OS::get_singleton()->print("\tResulted: %ls\n",s.c_str());
|
||||||
|
|
||||||
return (wcscmp(s.c_str(),L"Hello")==0);
|
return (wcscmp(s.c_str(),L"Hello")==0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool test_2() {
|
bool test_2() {
|
||||||
|
|
||||||
OS::get_singleton()->print("\n\nTest 2: Assign from string (operator=)\n");
|
OS::get_singleton()->print("\n\nTest 2: Assign from string (operator=)\n");
|
||||||
|
|
||||||
String s = "Dolly";
|
String s = "Dolly";
|
||||||
String t = s;
|
String t = s;
|
||||||
|
|
||||||
OS::get_singleton()->print("\tExpected: Dolly\n");
|
OS::get_singleton()->print("\tExpected: Dolly\n");
|
||||||
OS::get_singleton()->print("\tResulted: %ls\n",t.c_str());
|
OS::get_singleton()->print("\tResulted: %ls\n",t.c_str());
|
||||||
|
|
||||||
return (wcscmp(t.c_str(),L"Dolly")==0);
|
return (wcscmp(t.c_str(),L"Dolly")==0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool test_3() {
|
bool test_3() {
|
||||||
|
|
||||||
OS::get_singleton()->print("\n\nTest 3: Assign from c-string (copycon)\n");
|
OS::get_singleton()->print("\n\nTest 3: Assign from c-string (copycon)\n");
|
||||||
|
|
||||||
String s("Sheep");
|
String s("Sheep");
|
||||||
String t(s);
|
String t(s);
|
||||||
|
|
||||||
OS::get_singleton()->print("\tExpected: Sheep\n");
|
OS::get_singleton()->print("\tExpected: Sheep\n");
|
||||||
OS::get_singleton()->print("\tResulted: %ls\n",t.c_str());
|
OS::get_singleton()->print("\tResulted: %ls\n",t.c_str());
|
||||||
|
|
||||||
return (wcscmp(t.c_str(),L"Sheep")==0);
|
return (wcscmp(t.c_str(),L"Sheep")==0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool test_4() {
|
bool test_4() {
|
||||||
|
|
||||||
OS::get_singleton()->print("\n\nTest 4: Assign from c-widechar (operator=)\n");
|
OS::get_singleton()->print("\n\nTest 4: Assign from c-widechar (operator=)\n");
|
||||||
|
|
||||||
String s(L"Give me");
|
String s(L"Give me");
|
||||||
|
|
||||||
OS::get_singleton()->print("\tExpected: Give me\n");
|
OS::get_singleton()->print("\tExpected: Give me\n");
|
||||||
OS::get_singleton()->print("\tResulted: %ls\n",s.c_str());
|
OS::get_singleton()->print("\tResulted: %ls\n",s.c_str());
|
||||||
|
|
||||||
return (wcscmp(s.c_str(),L"Give me")==0);
|
return (wcscmp(s.c_str(),L"Give me")==0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool test_5() {
|
bool test_5() {
|
||||||
|
|
||||||
OS::get_singleton()->print("\n\nTest 5: Assign from c-widechar (copycon)\n");
|
OS::get_singleton()->print("\n\nTest 5: Assign from c-widechar (copycon)\n");
|
||||||
|
|
||||||
String s(L"Wool");
|
String s(L"Wool");
|
||||||
|
|
||||||
OS::get_singleton()->print("\tExpected: Wool\n");
|
OS::get_singleton()->print("\tExpected: Wool\n");
|
||||||
OS::get_singleton()->print("\tResulted: %ls\n",s.c_str());
|
OS::get_singleton()->print("\tResulted: %ls\n",s.c_str());
|
||||||
|
|
||||||
return (wcscmp(s.c_str(),L"Wool")==0);
|
return (wcscmp(s.c_str(),L"Wool")==0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool test_6() {
|
bool test_6() {
|
||||||
|
|
||||||
OS::get_singleton()->print("\n\nTest 6: comparisons (equal)\n");
|
OS::get_singleton()->print("\n\nTest 6: comparisons (equal)\n");
|
||||||
|
|
||||||
|
|
||||||
String s="Test Compare";
|
String s="Test Compare";
|
||||||
|
|
||||||
OS::get_singleton()->print("\tComparing to \"Test Compare\"\n");
|
OS::get_singleton()->print("\tComparing to \"Test Compare\"\n");
|
||||||
|
|
||||||
if (! ( s=="Test Compare" ) )
|
if (! ( s=="Test Compare" ) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (! ( s==L"Test Compare" ) )
|
if (! ( s==L"Test Compare" ) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (! ( s==String("Test Compare") ) )
|
if (! ( s==String("Test Compare") ) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool test_7() {
|
bool test_7() {
|
||||||
|
|
||||||
OS::get_singleton()->print("\n\nTest 7: comparisons (unequal)\n");
|
OS::get_singleton()->print("\n\nTest 7: comparisons (unequal)\n");
|
||||||
|
|
||||||
|
|
||||||
String s="Test Compare";
|
String s="Test Compare";
|
||||||
|
|
||||||
OS::get_singleton()->print("\tComparing to \"Test Compare\"\n");
|
OS::get_singleton()->print("\tComparing to \"Test Compare\"\n");
|
||||||
|
|
||||||
if (! ( s!="Peanut" ) )
|
if (! ( s!="Peanut" ) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (! ( s!=L"Coconut" ) )
|
if (! ( s!=L"Coconut" ) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (! ( s!=String("Butter") ) )
|
if (! ( s!=String("Butter") ) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool test_8() {
|
bool test_8() {
|
||||||
|
|
||||||
OS::get_singleton()->print("\n\nTest 8: comparisons (operator<)\n");
|
OS::get_singleton()->print("\n\nTest 8: comparisons (operator<)\n");
|
||||||
|
|
||||||
|
|
||||||
String s="Bees";
|
String s="Bees";
|
||||||
|
|
||||||
OS::get_singleton()->print("\tComparing to \"Bees\"\n");
|
OS::get_singleton()->print("\tComparing to \"Bees\"\n");
|
||||||
|
|
||||||
if ( ! (s < "Elephant") )
|
if ( ! (s < "Elephant") )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if ( s < L"Amber" )
|
if ( s < L"Amber" )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if ( s < String("Beatrix") )
|
if ( s < String("Beatrix") )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool test_9() {
|
bool test_9() {
|
||||||
|
|
||||||
OS::get_singleton()->print("\n\nTest 9: Concatenation\n");
|
OS::get_singleton()->print("\n\nTest 9: Concatenation\n");
|
||||||
|
|
||||||
|
|
||||||
String s;
|
String s;
|
||||||
|
|
||||||
s+="Have";
|
s+="Have";
|
||||||
s+=' ';
|
s+=' ';
|
||||||
s+='a';
|
s+='a';
|
||||||
|
@ -184,279 +184,279 @@ bool test_9() {
|
||||||
s = s + L"Nice";
|
s = s + L"Nice";
|
||||||
s = s + " ";
|
s = s + " ";
|
||||||
s = s + String("Day");
|
s = s + String("Day");
|
||||||
|
|
||||||
OS::get_singleton()->print("\tComparing to \"Have a Nice Day\"\n");
|
OS::get_singleton()->print("\tComparing to \"Have a Nice Day\"\n");
|
||||||
|
|
||||||
return (s == "Have a Nice Day");
|
return (s == "Have a Nice Day");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool test_10() {
|
bool test_10() {
|
||||||
|
|
||||||
OS::get_singleton()->print("\n\nTest 10: Misc funcs (size/length/empty/etc)\n");
|
OS::get_singleton()->print("\n\nTest 10: Misc funcs (size/length/empty/etc)\n");
|
||||||
|
|
||||||
if (! String("").empty())
|
if (! String("").empty())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (String("Mellon").size() != 7)
|
if (String("Mellon").size() != 7)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (String("Oranges").length() != 7)
|
if (String("Oranges").length() != 7)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool test_11() {
|
bool test_11() {
|
||||||
|
|
||||||
OS::get_singleton()->print("\n\nTest 11: Operator[]\n");
|
OS::get_singleton()->print("\n\nTest 11: Operator[]\n");
|
||||||
|
|
||||||
String a="Kugar Sane";
|
String a="Kugar Sane";
|
||||||
|
|
||||||
a[0]='S';
|
a[0]='S';
|
||||||
a[6]='C';
|
a[6]='C';
|
||||||
|
|
||||||
if (a != "Sugar Cane")
|
if (a != "Sugar Cane")
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (a[1]!='u')
|
if (a[1]!='u')
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool test_12() {
|
bool test_12() {
|
||||||
|
|
||||||
OS::get_singleton()->print("\n\nTest 12: case functions\n");
|
OS::get_singleton()->print("\n\nTest 12: case functions\n");
|
||||||
|
|
||||||
|
|
||||||
String a="MoMoNgA";
|
String a="MoMoNgA";
|
||||||
|
|
||||||
if (a.to_upper() != "MOMONGA")
|
if (a.to_upper() != "MOMONGA")
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (a.nocasecmp_to("momonga")!=0)
|
if (a.nocasecmp_to("momonga")!=0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool test_13() {
|
bool test_13() {
|
||||||
|
|
||||||
OS::get_singleton()->print("\n\nTest 13: UTF8\n");
|
OS::get_singleton()->print("\n\nTest 13: UTF8\n");
|
||||||
|
|
||||||
/* how can i embed UTF in here? */
|
/* how can i embed UTF in here? */
|
||||||
|
|
||||||
static const CharType ustr[] = { 0x304A , 0x360F, 0x3088, 0x3046, 0 };
|
static const CharType ustr[] = { 0x304A , 0x360F, 0x3088, 0x3046, 0 };
|
||||||
// static const wchar_t ustr[] = { 'P', 0xCE, 'p',0xD3, 0 };
|
// static const wchar_t ustr[] = { 'P', 0xCE, 'p',0xD3, 0 };
|
||||||
String s=ustr;
|
String s=ustr;
|
||||||
|
|
||||||
OS::get_singleton()->print("\tUnicode: %ls\n",ustr);
|
OS::get_singleton()->print("\tUnicode: %ls\n",ustr);
|
||||||
s.parse_utf8( s.utf8().get_data() );
|
s.parse_utf8( s.utf8().get_data() );
|
||||||
OS::get_singleton()->print("\tConvert/Parse UTF8: %ls\n",s.c_str());
|
OS::get_singleton()->print("\tConvert/Parse UTF8: %ls\n",s.c_str());
|
||||||
|
|
||||||
return (s==ustr);
|
return (s==ustr);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool test_14() {
|
bool test_14() {
|
||||||
|
|
||||||
OS::get_singleton()->print("\n\nTest 14: ASCII\n");
|
OS::get_singleton()->print("\n\nTest 14: ASCII\n");
|
||||||
|
|
||||||
String s = L"Primero Leche";
|
String s = L"Primero Leche";
|
||||||
OS::get_singleton()->print("\tAscii: %s\n",s.ascii().get_data());
|
OS::get_singleton()->print("\tAscii: %s\n",s.ascii().get_data());
|
||||||
|
|
||||||
String t=s.ascii().get_data();
|
String t=s.ascii().get_data();
|
||||||
return (s==t);
|
return (s==t);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool test_15() {
|
bool test_15() {
|
||||||
|
|
||||||
OS::get_singleton()->print("\n\nTest 15: substr\n");
|
OS::get_singleton()->print("\n\nTest 15: substr\n");
|
||||||
|
|
||||||
String s="Killer Baby";
|
String s="Killer Baby";
|
||||||
OS::get_singleton()->print("\tsubstr(3,4) of \"%ls\" is \"%ls\"\n",s.c_str(),s.substr(3,4).c_str());
|
OS::get_singleton()->print("\tsubstr(3,4) of \"%ls\" is \"%ls\"\n",s.c_str(),s.substr(3,4).c_str());
|
||||||
|
|
||||||
return (s.substr(3,4)=="ler ");
|
return (s.substr(3,4)=="ler ");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool test_16() {
|
bool test_16() {
|
||||||
|
|
||||||
OS::get_singleton()->print("\n\nTest 16: find\n");
|
OS::get_singleton()->print("\n\nTest 16: find\n");
|
||||||
|
|
||||||
String s="Pretty Woman";
|
String s="Pretty Woman";
|
||||||
OS::get_singleton()->print("\tString: %ls\n",s.c_str());
|
OS::get_singleton()->print("\tString: %ls\n",s.c_str());
|
||||||
OS::get_singleton()->print("\t\"tty\" is at %i pos.\n",s.find("tty"));
|
OS::get_singleton()->print("\t\"tty\" is at %i pos.\n",s.find("tty"));
|
||||||
OS::get_singleton()->print("\t\"Revenge of the Monster Truck\" is at %i pos.\n",s.find("Revenge of the Monster Truck"));
|
OS::get_singleton()->print("\t\"Revenge of the Monster Truck\" is at %i pos.\n",s.find("Revenge of the Monster Truck"));
|
||||||
|
|
||||||
if (s.find("tty")!=3)
|
if (s.find("tty")!=3)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (s.find("Revenge of the Monster Truck")!=-1)
|
if (s.find("Revenge of the Monster Truck")!=-1)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool test_17() {
|
bool test_17() {
|
||||||
|
|
||||||
OS::get_singleton()->print("\n\nTest 17: find no case\n");
|
OS::get_singleton()->print("\n\nTest 17: find no case\n");
|
||||||
|
|
||||||
String s="Pretty Whale";
|
String s="Pretty Whale";
|
||||||
OS::get_singleton()->print("\tString: %ls\n",s.c_str());
|
OS::get_singleton()->print("\tString: %ls\n",s.c_str());
|
||||||
OS::get_singleton()->print("\t\"WHA\" is at %i pos.\n",s.findn("WHA"));
|
OS::get_singleton()->print("\t\"WHA\" is at %i pos.\n",s.findn("WHA"));
|
||||||
OS::get_singleton()->print("\t\"Revenge of the Monster SawFish\" is at %i pos.\n",s.findn("Revenge of the Monster Truck"));
|
OS::get_singleton()->print("\t\"Revenge of the Monster SawFish\" is at %i pos.\n",s.findn("Revenge of the Monster Truck"));
|
||||||
|
|
||||||
if (s.findn("WHA")!=7)
|
if (s.findn("WHA")!=7)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (s.findn("Revenge of the Monster SawFish")!=-1)
|
if (s.findn("Revenge of the Monster SawFish")!=-1)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool test_18() {
|
bool test_18() {
|
||||||
|
|
||||||
OS::get_singleton()->print("\n\nTest 18: find no case\n");
|
OS::get_singleton()->print("\n\nTest 18: find no case\n");
|
||||||
|
|
||||||
String s="Pretty Whale";
|
String s="Pretty Whale";
|
||||||
OS::get_singleton()->print("\tString: %ls\n",s.c_str());
|
OS::get_singleton()->print("\tString: %ls\n",s.c_str());
|
||||||
OS::get_singleton()->print("\t\"WHA\" is at %i pos.\n",s.findn("WHA"));
|
OS::get_singleton()->print("\t\"WHA\" is at %i pos.\n",s.findn("WHA"));
|
||||||
OS::get_singleton()->print("\t\"Revenge of the Monster SawFish\" is at %i pos.\n",s.findn("Revenge of the Monster Truck"));
|
OS::get_singleton()->print("\t\"Revenge of the Monster SawFish\" is at %i pos.\n",s.findn("Revenge of the Monster Truck"));
|
||||||
|
|
||||||
if (s.findn("WHA")!=7)
|
if (s.findn("WHA")!=7)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (s.findn("Revenge of the Monster SawFish")!=-1)
|
if (s.findn("Revenge of the Monster SawFish")!=-1)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool test_19() {
|
bool test_19() {
|
||||||
|
|
||||||
OS::get_singleton()->print("\n\nTest 19: Search & replace\n");
|
OS::get_singleton()->print("\n\nTest 19: Search & replace\n");
|
||||||
|
|
||||||
String s="Happy Birthday, Anna!";
|
String s="Happy Birthday, Anna!";
|
||||||
OS::get_singleton()->print("\tString: %ls\n",s.c_str());
|
OS::get_singleton()->print("\tString: %ls\n",s.c_str());
|
||||||
|
|
||||||
s=s.replace("Birthday","Halloween");
|
s=s.replace("Birthday","Halloween");
|
||||||
OS::get_singleton()->print("\tReplaced Birthday/Halloween: %ls.\n",s.c_str());
|
OS::get_singleton()->print("\tReplaced Birthday/Halloween: %ls.\n",s.c_str());
|
||||||
|
|
||||||
return (s=="Happy Halloween, Anna!");
|
return (s=="Happy Halloween, Anna!");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool test_20() {
|
bool test_20() {
|
||||||
|
|
||||||
OS::get_singleton()->print("\n\nTest 20: Insertion\n");
|
OS::get_singleton()->print("\n\nTest 20: Insertion\n");
|
||||||
|
|
||||||
String s="Who is Frederic?";
|
String s="Who is Frederic?";
|
||||||
|
|
||||||
OS::get_singleton()->print("\tString: %ls\n",s.c_str());
|
OS::get_singleton()->print("\tString: %ls\n",s.c_str());
|
||||||
s=s.insert( s.find("?")," Chopin" );
|
s=s.insert( s.find("?")," Chopin" );
|
||||||
OS::get_singleton()->print("\tInserted Chopin: %ls.\n",s.c_str());
|
OS::get_singleton()->print("\tInserted Chopin: %ls.\n",s.c_str());
|
||||||
|
|
||||||
return (s=="Who is Frederic Chopin?");
|
return (s=="Who is Frederic Chopin?");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool test_21() {
|
bool test_21() {
|
||||||
|
|
||||||
OS::get_singleton()->print("\n\nTest 21: Number -> String\n");
|
OS::get_singleton()->print("\n\nTest 21: Number -> String\n");
|
||||||
|
|
||||||
OS::get_singleton()->print("\tPi is %f\n",33.141593);
|
OS::get_singleton()->print("\tPi is %f\n",33.141593);
|
||||||
OS::get_singleton()->print("\tPi String is %ls\n",String::num(3.141593).c_str());
|
OS::get_singleton()->print("\tPi String is %ls\n",String::num(3.141593).c_str());
|
||||||
|
|
||||||
return String::num(3.141593)=="3.141593";
|
return String::num(3.141593)=="3.141593";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool test_22() {
|
bool test_22() {
|
||||||
|
|
||||||
OS::get_singleton()->print("\n\nTest 22: String -> Int\n");
|
OS::get_singleton()->print("\n\nTest 22: String -> Int\n");
|
||||||
|
|
||||||
static const char* nums[4]={ "1237461283", "- 22", "0", " - 1123412" };
|
static const char* nums[4]={ "1237461283", "- 22", "0", " - 1123412" };
|
||||||
static const int num[4]={ 1237461283, -22, 0, -1123412 };
|
static const int num[4]={ 1237461283, -22, 0, -1123412 };
|
||||||
|
|
||||||
for (int i=0;i<4;i++) {
|
for (int i=0;i<4;i++) {
|
||||||
OS::get_singleton()->print("\tString: \"%s\" as Int is %i\n",nums[i],String(nums[i]).to_int());
|
OS::get_singleton()->print("\tString: \"%s\" as Int is %i\n",nums[i],String(nums[i]).to_int());
|
||||||
|
|
||||||
if (String(nums[i]).to_int()!=num[i])
|
if (String(nums[i]).to_int()!=num[i])
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool test_23() {
|
bool test_23() {
|
||||||
|
|
||||||
OS::get_singleton()->print("\n\nTest 23: String -> Float\n");
|
OS::get_singleton()->print("\n\nTest 23: String -> Float\n");
|
||||||
|
|
||||||
static const char* nums[4]={ "-12348298412.2", "0.05", "2.0002", " -0.0001" };
|
static const char* nums[4]={ "-12348298412.2", "0.05", "2.0002", " -0.0001" };
|
||||||
static const double num[4]={ -12348298412.2, 0.05, 2.0002, -0.0001 };
|
static const double num[4]={ -12348298412.2, 0.05, 2.0002, -0.0001 };
|
||||||
|
|
||||||
for (int i=0;i<4;i++) {
|
for (int i=0;i<4;i++) {
|
||||||
OS::get_singleton()->print("\tString: \"%s\" as Float is %f\n",nums[i],String(nums[i]).to_double());
|
OS::get_singleton()->print("\tString: \"%s\" as Float is %f\n",nums[i],String(nums[i]).to_double());
|
||||||
|
|
||||||
if ( ABS(String(nums[i]).to_double()-num[i])>0.00001)
|
if ( ABS(String(nums[i]).to_double()-num[i])>0.00001)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool test_24() {
|
bool test_24() {
|
||||||
|
|
||||||
OS::get_singleton()->print("\n\nTest 24: Slicing\n");
|
OS::get_singleton()->print("\n\nTest 24: Slicing\n");
|
||||||
|
|
||||||
String s="Mars,Jupiter,Saturn,Uranus";
|
String s="Mars,Jupiter,Saturn,Uranus";
|
||||||
|
|
||||||
const char*slices[4]={"Mars","Jupiter","Saturn","Uranus"};
|
const char*slices[4]={"Mars","Jupiter","Saturn","Uranus"};
|
||||||
|
|
||||||
OS::get_singleton()->print("\tSlicing \"%ls\" by \"%s\"..\n",s.c_str(),",");
|
OS::get_singleton()->print("\tSlicing \"%ls\" by \"%s\"..\n",s.c_str(),",");
|
||||||
|
|
||||||
for (int i=0;i<s.get_slice_count(",");i++) {
|
for (int i=0;i<s.get_slice_count(",");i++) {
|
||||||
|
|
||||||
OS::get_singleton()->print("\t\t%i- %ls\n",i+1,s.get_slice(",",i).c_str());
|
OS::get_singleton()->print("\t\t%i- %ls\n",i+1,s.get_slice(",",i).c_str());
|
||||||
|
|
||||||
|
|
||||||
if (s.get_slice(",",i)!=slices[i])
|
if (s.get_slice(",",i)!=slices[i])
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool test_25() {
|
bool test_25() {
|
||||||
|
|
||||||
OS::get_singleton()->print("\n\nTest 25: Erasing\n");
|
OS::get_singleton()->print("\n\nTest 25: Erasing\n");
|
||||||
|
|
||||||
String s="Josephine is such a cute girl!";
|
String s="Josephine is such a cute girl!";
|
||||||
|
|
||||||
OS::get_singleton()->print("\tString: %ls\n",s.c_str());
|
OS::get_singleton()->print("\tString: %ls\n",s.c_str());
|
||||||
OS::get_singleton()->print("\tRemoving \"cute\"\n");
|
OS::get_singleton()->print("\tRemoving \"cute\"\n");
|
||||||
|
|
||||||
s.erase(s.find("cute "),String("cute ").length());
|
s.erase(s.find("cute "),String("cute ").length());
|
||||||
OS::get_singleton()->print("\tResult: %ls\n",s.c_str());
|
OS::get_singleton()->print("\tResult: %ls\n",s.c_str());
|
||||||
|
|
||||||
|
|
||||||
return (s=="Josephine is such a girl!");
|
return (s=="Josephine is such a girl!");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool test_26() {
|
bool test_26() {
|
||||||
|
@ -516,7 +516,7 @@ bool test_28() {
|
||||||
String format, output;
|
String format, output;
|
||||||
Array args;
|
Array args;
|
||||||
bool error;
|
bool error;
|
||||||
|
|
||||||
// %%
|
// %%
|
||||||
format = "fish %% frog";
|
format = "fish %% frog";
|
||||||
args.clear();
|
args.clear();
|
||||||
|
@ -846,7 +846,7 @@ bool test_28() {
|
||||||
typedef bool (*TestFunc)(void);
|
typedef bool (*TestFunc)(void);
|
||||||
|
|
||||||
TestFunc test_funcs[] = {
|
TestFunc test_funcs[] = {
|
||||||
|
|
||||||
test_1,
|
test_1,
|
||||||
test_2,
|
test_2,
|
||||||
test_3,
|
test_3,
|
||||||
|
@ -876,18 +876,18 @@ TestFunc test_funcs[] = {
|
||||||
test_27,
|
test_27,
|
||||||
test_28,
|
test_28,
|
||||||
0
|
0
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
MainLoop* test() {
|
MainLoop* test() {
|
||||||
|
|
||||||
/** A character length != wchar_t may be forced, so the tests wont work */
|
/** A character length != wchar_t may be forced, so the tests wont work */
|
||||||
|
|
||||||
ERR_FAIL_COND_V( sizeof(CharType) != sizeof(wchar_t), NULL );
|
ERR_FAIL_COND_V( sizeof(CharType) != sizeof(wchar_t), NULL );
|
||||||
|
|
||||||
int count=0;
|
int count=0;
|
||||||
int passed=0;
|
int passed=0;
|
||||||
|
|
||||||
while(true) {
|
while(true) {
|
||||||
if (!test_funcs[count])
|
if (!test_funcs[count])
|
||||||
break;
|
break;
|
||||||
|
@ -895,17 +895,17 @@ MainLoop* test() {
|
||||||
if (pass)
|
if (pass)
|
||||||
passed++;
|
passed++;
|
||||||
OS::get_singleton()->print("\t%s\n",pass?"PASS":"FAILED");
|
OS::get_singleton()->print("\t%s\n",pass?"PASS":"FAILED");
|
||||||
|
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
OS::get_singleton()->print("\n\n\n");
|
OS::get_singleton()->print("\n\n\n");
|
||||||
OS::get_singleton()->print("*************\n");
|
OS::get_singleton()->print("*************\n");
|
||||||
OS::get_singleton()->print("***TOTALS!***\n");
|
OS::get_singleton()->print("***TOTALS!***\n");
|
||||||
OS::get_singleton()->print("*************\n");
|
OS::get_singleton()->print("*************\n");
|
||||||
|
|
||||||
OS::get_singleton()->print("Passed %i of %i tests\n", passed, count);
|
OS::get_singleton()->print("Passed %i of %i tests\n", passed, count);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1307,7 +1307,12 @@ DVector<uint8_t> _File::get_buffer(int p_length) const{
|
||||||
|
|
||||||
String _File::get_as_text() const {
|
String _File::get_as_text() const {
|
||||||
|
|
||||||
|
ERR_FAIL_COND_V(!f, String());
|
||||||
|
|
||||||
String text;
|
String text;
|
||||||
|
size_t original_pos = f->get_pos();
|
||||||
|
f->seek(0);
|
||||||
|
|
||||||
String l = get_line();
|
String l = get_line();
|
||||||
while(!eof_reached()) {
|
while(!eof_reached()) {
|
||||||
text+=l+"\n";
|
text+=l+"\n";
|
||||||
|
@ -1315,6 +1320,8 @@ String _File::get_as_text() const {
|
||||||
}
|
}
|
||||||
text+=l;
|
text+=l;
|
||||||
|
|
||||||
|
f->seek(original_pos);
|
||||||
|
|
||||||
return text;
|
return text;
|
||||||
|
|
||||||
|
|
||||||
|
@ -1669,15 +1676,15 @@ void _Directory::_bind_methods() {
|
||||||
ObjectTypeDB::bind_method(_MD("get_drive","idx"),&_Directory::get_drive);
|
ObjectTypeDB::bind_method(_MD("get_drive","idx"),&_Directory::get_drive);
|
||||||
ObjectTypeDB::bind_method(_MD("change_dir:Error","todir"),&_Directory::change_dir);
|
ObjectTypeDB::bind_method(_MD("change_dir:Error","todir"),&_Directory::change_dir);
|
||||||
ObjectTypeDB::bind_method(_MD("get_current_dir"),&_Directory::get_current_dir);
|
ObjectTypeDB::bind_method(_MD("get_current_dir"),&_Directory::get_current_dir);
|
||||||
ObjectTypeDB::bind_method(_MD("make_dir:Error","name"),&_Directory::make_dir);
|
ObjectTypeDB::bind_method(_MD("make_dir:Error","path"),&_Directory::make_dir);
|
||||||
ObjectTypeDB::bind_method(_MD("make_dir_recursive:Error","name"),&_Directory::make_dir_recursive);
|
ObjectTypeDB::bind_method(_MD("make_dir_recursive:Error","path"),&_Directory::make_dir_recursive);
|
||||||
ObjectTypeDB::bind_method(_MD("file_exists","name"),&_Directory::file_exists);
|
ObjectTypeDB::bind_method(_MD("file_exists","path"),&_Directory::file_exists);
|
||||||
ObjectTypeDB::bind_method(_MD("dir_exists","name"),&_Directory::dir_exists);
|
ObjectTypeDB::bind_method(_MD("dir_exists","path"),&_Directory::dir_exists);
|
||||||
// ObjectTypeDB::bind_method(_MD("get_modified_time","file"),&_Directory::get_modified_time);
|
// ObjectTypeDB::bind_method(_MD("get_modified_time","file"),&_Directory::get_modified_time);
|
||||||
ObjectTypeDB::bind_method(_MD("get_space_left"),&_Directory::get_space_left);
|
ObjectTypeDB::bind_method(_MD("get_space_left"),&_Directory::get_space_left);
|
||||||
ObjectTypeDB::bind_method(_MD("copy:Error","from","to"),&_Directory::copy);
|
ObjectTypeDB::bind_method(_MD("copy:Error","from","to"),&_Directory::copy);
|
||||||
ObjectTypeDB::bind_method(_MD("rename:Error","from","to"),&_Directory::rename);
|
ObjectTypeDB::bind_method(_MD("rename:Error","from","to"),&_Directory::rename);
|
||||||
ObjectTypeDB::bind_method(_MD("remove:Error","file"),&_Directory::remove);
|
ObjectTypeDB::bind_method(_MD("remove:Error","path"),&_Directory::remove);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -75,11 +75,11 @@ float Color::get_h() const {
|
||||||
h = 2 + ( b - r ) / delta; // between cyan & yellow
|
h = 2 + ( b - r ) / delta; // between cyan & yellow
|
||||||
else
|
else
|
||||||
h = 4 + ( r - g ) / delta; // between magenta & cyan
|
h = 4 + ( r - g ) / delta; // between magenta & cyan
|
||||||
|
|
||||||
h/=6.0;
|
h/=6.0;
|
||||||
if (h<0)
|
if (h<0)
|
||||||
h+=1.0;
|
h+=1.0;
|
||||||
|
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,7 +119,7 @@ void Color::set_hsv(float p_h, float p_s, float p_v, float p_alpha) {
|
||||||
p_h *=6.0;
|
p_h *=6.0;
|
||||||
p_h = Math::fmod(p_h,6);
|
p_h = Math::fmod(p_h,6);
|
||||||
i = Math::floor( p_h );
|
i = Math::floor( p_h );
|
||||||
|
|
||||||
f = p_h - i;
|
f = p_h - i;
|
||||||
p = p_v * ( 1 - p_s );
|
p = p_v * ( 1 - p_s );
|
||||||
q = p_v * ( 1 - p_s * f );
|
q = p_v * ( 1 - p_s * f );
|
||||||
|
@ -136,7 +136,7 @@ void Color::set_hsv(float p_h, float p_s, float p_v, float p_alpha) {
|
||||||
g = p_v;
|
g = p_v;
|
||||||
b = p;
|
b = p;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
r = p;
|
r = p;
|
||||||
g = p_v;
|
g = p_v;
|
||||||
b = t;
|
b = t;
|
||||||
|
@ -162,8 +162,8 @@ void Color::set_hsv(float p_h, float p_s, float p_v, float p_alpha) {
|
||||||
void Color::invert() {
|
void Color::invert() {
|
||||||
|
|
||||||
r=1.0-r;
|
r=1.0-r;
|
||||||
g=1.0-g;
|
g=1.0-g;
|
||||||
b=1.0-b;
|
b=1.0-b;
|
||||||
}
|
}
|
||||||
void Color::contrast() {
|
void Color::contrast() {
|
||||||
|
|
||||||
|
@ -368,7 +368,7 @@ String Color::to_html(bool p_alpha) const {
|
||||||
|
|
||||||
float Color::gray() const {
|
float Color::gray() const {
|
||||||
|
|
||||||
return (r+g+b)/3.0;
|
return (r+g+b)/3.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Color::operator String() const {
|
Color::operator String() const {
|
||||||
|
|
18
core/color.h
18
core/color.h
|
@ -37,13 +37,13 @@
|
||||||
struct Color {
|
struct Color {
|
||||||
|
|
||||||
union {
|
union {
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
float r;
|
float r;
|
||||||
float g;
|
float g;
|
||||||
float b;
|
float b;
|
||||||
float a;
|
float a;
|
||||||
};
|
};
|
||||||
float components[4];
|
float components[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -58,28 +58,28 @@ struct Color {
|
||||||
float get_v() const;
|
float get_v() const;
|
||||||
void set_hsv(float p_h, float p_s, float p_v, float p_alpha=1.0);
|
void set_hsv(float p_h, float p_s, float p_v, float p_alpha=1.0);
|
||||||
|
|
||||||
_FORCE_INLINE_ float& operator[](int idx) {
|
_FORCE_INLINE_ float& operator[](int idx) {
|
||||||
return components[idx];
|
return components[idx];
|
||||||
}
|
}
|
||||||
_FORCE_INLINE_ const float& operator[](int idx) const {
|
_FORCE_INLINE_ const float& operator[](int idx) const {
|
||||||
return components[idx];
|
return components[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
void invert();
|
void invert();
|
||||||
void contrast();
|
void contrast();
|
||||||
Color inverted() const;
|
Color inverted() const;
|
||||||
Color contrasted() const;
|
Color contrasted() const;
|
||||||
|
|
||||||
_FORCE_INLINE_ Color linear_interpolate(const Color& p_b, float p_t) const {
|
_FORCE_INLINE_ Color linear_interpolate(const Color& p_b, float p_t) const {
|
||||||
|
|
||||||
Color res=*this;
|
Color res=*this;
|
||||||
|
|
||||||
res.r+= (p_t * (p_b.r-r));
|
res.r+= (p_t * (p_b.r-r));
|
||||||
res.g+= (p_t * (p_b.g-g));
|
res.g+= (p_t * (p_b.g-g));
|
||||||
res.b+= (p_t * (p_b.b-b));
|
res.b+= (p_t * (p_b.b-b));
|
||||||
res.a+= (p_t * (p_b.a-a));
|
res.a+= (p_t * (p_b.a-a));
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
_FORCE_INLINE_ Color blend(const Color& p_over) const {
|
_FORCE_INLINE_ Color blend(const Color& p_over) const {
|
||||||
|
|
|
@ -76,7 +76,7 @@ CommandQueueMT::SyncSemaphore* CommandQueueMT::_alloc_sync_sem() {
|
||||||
CommandQueueMT::CommandQueueMT(bool p_sync){
|
CommandQueueMT::CommandQueueMT(bool p_sync){
|
||||||
|
|
||||||
read_ptr=0;
|
read_ptr=0;
|
||||||
write_ptr=0;
|
write_ptr=0;
|
||||||
mutex = Mutex::create();
|
mutex = Mutex::create();
|
||||||
|
|
||||||
for(int i=0;i<SYNC_SEMAPHORES;i++) {
|
for(int i=0;i<SYNC_SEMAPHORES;i++) {
|
||||||
|
|
|
@ -47,69 +47,69 @@ class CommandQueueMT {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CommandBase {
|
struct CommandBase {
|
||||||
|
|
||||||
virtual void call()=0;
|
virtual void call()=0;
|
||||||
virtual ~CommandBase() {};
|
virtual ~CommandBase() {};
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class T,class M>
|
template<class T,class M>
|
||||||
struct Command0 : public CommandBase {
|
struct Command0 : public CommandBase {
|
||||||
|
|
||||||
T*instance;
|
T*instance;
|
||||||
M method;
|
M method;
|
||||||
|
|
||||||
virtual void call() { (instance->*method)(); }
|
virtual void call() { (instance->*method)(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class T,class M,class P1>
|
template<class T,class M,class P1>
|
||||||
struct Command1 : public CommandBase {
|
struct Command1 : public CommandBase {
|
||||||
|
|
||||||
T*instance;
|
T*instance;
|
||||||
M method;
|
M method;
|
||||||
typename GetSimpleTypeT<P1>::type_t p1;
|
typename GetSimpleTypeT<P1>::type_t p1;
|
||||||
|
|
||||||
virtual void call() { (instance->*method)(p1); }
|
virtual void call() { (instance->*method)(p1); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class T,class M,class P1,class P2>
|
template<class T,class M,class P1,class P2>
|
||||||
struct Command2 : public CommandBase {
|
struct Command2 : public CommandBase {
|
||||||
|
|
||||||
T*instance;
|
T*instance;
|
||||||
M method;
|
M method;
|
||||||
typename GetSimpleTypeT<P1>::type_t p1;
|
typename GetSimpleTypeT<P1>::type_t p1;
|
||||||
typename GetSimpleTypeT<P2>::type_t p2;
|
typename GetSimpleTypeT<P2>::type_t p2;
|
||||||
|
|
||||||
virtual void call() { (instance->*method)(p1,p2); }
|
virtual void call() { (instance->*method)(p1,p2); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class T,class M,class P1,class P2,class P3>
|
template<class T,class M,class P1,class P2,class P3>
|
||||||
struct Command3 : public CommandBase {
|
struct Command3 : public CommandBase {
|
||||||
|
|
||||||
T*instance;
|
T*instance;
|
||||||
M method;
|
M method;
|
||||||
typename GetSimpleTypeT<P1>::type_t p1;
|
typename GetSimpleTypeT<P1>::type_t p1;
|
||||||
typename GetSimpleTypeT<P2>::type_t p2;
|
typename GetSimpleTypeT<P2>::type_t p2;
|
||||||
typename GetSimpleTypeT<P3>::type_t p3;
|
typename GetSimpleTypeT<P3>::type_t p3;
|
||||||
|
|
||||||
virtual void call() { (instance->*method)(p1,p2,p3); }
|
virtual void call() { (instance->*method)(p1,p2,p3); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class T,class M,class P1,class P2,class P3,class P4>
|
template<class T,class M,class P1,class P2,class P3,class P4>
|
||||||
struct Command4 : public CommandBase {
|
struct Command4 : public CommandBase {
|
||||||
|
|
||||||
T*instance;
|
T*instance;
|
||||||
M method;
|
M method;
|
||||||
typename GetSimpleTypeT<P1>::type_t p1;
|
typename GetSimpleTypeT<P1>::type_t p1;
|
||||||
typename GetSimpleTypeT<P2>::type_t p2;
|
typename GetSimpleTypeT<P2>::type_t p2;
|
||||||
typename GetSimpleTypeT<P3>::type_t p3;
|
typename GetSimpleTypeT<P3>::type_t p3;
|
||||||
typename GetSimpleTypeT<P4>::type_t p4;
|
typename GetSimpleTypeT<P4>::type_t p4;
|
||||||
|
|
||||||
virtual void call() { (instance->*method)(p1,p2,p3,p4); }
|
virtual void call() { (instance->*method)(p1,p2,p3,p4); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class T,class M,class P1,class P2,class P3,class P4,class P5>
|
template<class T,class M,class P1,class P2,class P3,class P4,class P5>
|
||||||
struct Command5 : public CommandBase {
|
struct Command5 : public CommandBase {
|
||||||
|
|
||||||
T*instance;
|
T*instance;
|
||||||
M method;
|
M method;
|
||||||
typename GetSimpleTypeT<P1>::type_t p1;
|
typename GetSimpleTypeT<P1>::type_t p1;
|
||||||
|
@ -117,13 +117,13 @@ class CommandQueueMT {
|
||||||
typename GetSimpleTypeT<P3>::type_t p3;
|
typename GetSimpleTypeT<P3>::type_t p3;
|
||||||
typename GetSimpleTypeT<P4>::type_t p4;
|
typename GetSimpleTypeT<P4>::type_t p4;
|
||||||
typename GetSimpleTypeT<P5>::type_t p5;
|
typename GetSimpleTypeT<P5>::type_t p5;
|
||||||
|
|
||||||
virtual void call() { (instance->*method)(p1,p2,p3,p4,p5); }
|
virtual void call() { (instance->*method)(p1,p2,p3,p4,p5); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class T,class M,class P1,class P2,class P3,class P4,class P5,class P6>
|
template<class T,class M,class P1,class P2,class P3,class P4,class P5,class P6>
|
||||||
struct Command6 : public CommandBase {
|
struct Command6 : public CommandBase {
|
||||||
|
|
||||||
T*instance;
|
T*instance;
|
||||||
M method;
|
M method;
|
||||||
typename GetSimpleTypeT<P1>::type_t p1;
|
typename GetSimpleTypeT<P1>::type_t p1;
|
||||||
|
@ -132,13 +132,13 @@ class CommandQueueMT {
|
||||||
typename GetSimpleTypeT<P4>::type_t p4;
|
typename GetSimpleTypeT<P4>::type_t p4;
|
||||||
typename GetSimpleTypeT<P5>::type_t p5;
|
typename GetSimpleTypeT<P5>::type_t p5;
|
||||||
typename GetSimpleTypeT<P6>::type_t p6;
|
typename GetSimpleTypeT<P6>::type_t p6;
|
||||||
|
|
||||||
virtual void call() { (instance->*method)(p1,p2,p3,p4,p5,p6); }
|
virtual void call() { (instance->*method)(p1,p2,p3,p4,p5,p6); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class T,class M,class P1,class P2,class P3,class P4,class P5,class P6,class P7>
|
template<class T,class M,class P1,class P2,class P3,class P4,class P5,class P6,class P7>
|
||||||
struct Command7 : public CommandBase {
|
struct Command7 : public CommandBase {
|
||||||
|
|
||||||
T*instance;
|
T*instance;
|
||||||
M method;
|
M method;
|
||||||
typename GetSimpleTypeT<P1>::type_t p1;
|
typename GetSimpleTypeT<P1>::type_t p1;
|
||||||
|
@ -148,12 +148,12 @@ class CommandQueueMT {
|
||||||
typename GetSimpleTypeT<P5>::type_t p5;
|
typename GetSimpleTypeT<P5>::type_t p5;
|
||||||
typename GetSimpleTypeT<P6>::type_t p6;
|
typename GetSimpleTypeT<P6>::type_t p6;
|
||||||
typename GetSimpleTypeT<P7>::type_t p7;
|
typename GetSimpleTypeT<P7>::type_t p7;
|
||||||
|
|
||||||
virtual void call() { (instance->*method)(p1,p2,p3,p4,p5,p6,p7); }
|
virtual void call() { (instance->*method)(p1,p2,p3,p4,p5,p6,p7); }
|
||||||
};
|
};
|
||||||
|
|
||||||
/* comands that return */
|
/* comands that return */
|
||||||
|
|
||||||
template<class T,class M,class R>
|
template<class T,class M,class R>
|
||||||
struct CommandRet0 : public CommandBase {
|
struct CommandRet0 : public CommandBase {
|
||||||
|
|
||||||
|
@ -161,38 +161,38 @@ class CommandQueueMT {
|
||||||
M method;
|
M method;
|
||||||
R* ret;
|
R* ret;
|
||||||
SyncSemaphore *sync;
|
SyncSemaphore *sync;
|
||||||
|
|
||||||
virtual void call() { *ret = (instance->*method)(); sync->sem->post(); sync->in_use=false; ; }
|
virtual void call() { *ret = (instance->*method)(); sync->sem->post(); sync->in_use=false; ; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class T,class M,class P1,class R>
|
template<class T,class M,class P1,class R>
|
||||||
struct CommandRet1 : public CommandBase {
|
struct CommandRet1 : public CommandBase {
|
||||||
|
|
||||||
T*instance;
|
T*instance;
|
||||||
M method;
|
M method;
|
||||||
typename GetSimpleTypeT<P1>::type_t p1;
|
typename GetSimpleTypeT<P1>::type_t p1;
|
||||||
R* ret;
|
R* ret;
|
||||||
SyncSemaphore *sync;
|
SyncSemaphore *sync;
|
||||||
|
|
||||||
virtual void call() { *ret = (instance->*method)(p1); sync->sem->post(); sync->in_use=false; }
|
virtual void call() { *ret = (instance->*method)(p1); sync->sem->post(); sync->in_use=false; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class T,class M,class P1,class P2,class R>
|
template<class T,class M,class P1,class P2,class R>
|
||||||
struct CommandRet2 : public CommandBase {
|
struct CommandRet2 : public CommandBase {
|
||||||
|
|
||||||
T*instance;
|
T*instance;
|
||||||
M method;
|
M method;
|
||||||
typename GetSimpleTypeT<P1>::type_t p1;
|
typename GetSimpleTypeT<P1>::type_t p1;
|
||||||
typename GetSimpleTypeT<P2>::type_t p2;
|
typename GetSimpleTypeT<P2>::type_t p2;
|
||||||
R* ret;
|
R* ret;
|
||||||
SyncSemaphore *sync;
|
SyncSemaphore *sync;
|
||||||
|
|
||||||
virtual void call() { *ret = (instance->*method)(p1,p2); sync->sem->post(); sync->in_use=false; ; }
|
virtual void call() { *ret = (instance->*method)(p1,p2); sync->sem->post(); sync->in_use=false; ; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class T,class M,class P1,class P2,class P3,class R>
|
template<class T,class M,class P1,class P2,class P3,class R>
|
||||||
struct CommandRet3 : public CommandBase {
|
struct CommandRet3 : public CommandBase {
|
||||||
|
|
||||||
T*instance;
|
T*instance;
|
||||||
M method;
|
M method;
|
||||||
typename GetSimpleTypeT<P1>::type_t p1;
|
typename GetSimpleTypeT<P1>::type_t p1;
|
||||||
|
@ -200,13 +200,13 @@ class CommandQueueMT {
|
||||||
typename GetSimpleTypeT<P3>::type_t p3;
|
typename GetSimpleTypeT<P3>::type_t p3;
|
||||||
R* ret;
|
R* ret;
|
||||||
SyncSemaphore *sync;
|
SyncSemaphore *sync;
|
||||||
|
|
||||||
virtual void call() { *ret = (instance->*method)(p1,p2,p3); sync->sem->post(); sync->in_use=false; ; }
|
virtual void call() { *ret = (instance->*method)(p1,p2,p3); sync->sem->post(); sync->in_use=false; ; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class T,class M,class P1,class P2,class P3,class P4,class R>
|
template<class T,class M,class P1,class P2,class P3,class P4,class R>
|
||||||
struct CommandRet4 : public CommandBase {
|
struct CommandRet4 : public CommandBase {
|
||||||
|
|
||||||
T*instance;
|
T*instance;
|
||||||
M method;
|
M method;
|
||||||
typename GetSimpleTypeT<P1>::type_t p1;
|
typename GetSimpleTypeT<P1>::type_t p1;
|
||||||
|
@ -215,13 +215,13 @@ class CommandQueueMT {
|
||||||
typename GetSimpleTypeT<P4>::type_t p4;
|
typename GetSimpleTypeT<P4>::type_t p4;
|
||||||
R* ret;
|
R* ret;
|
||||||
SyncSemaphore *sync;
|
SyncSemaphore *sync;
|
||||||
|
|
||||||
virtual void call() { *ret = (instance->*method)(p1,p2,p3,p4); sync->sem->post(); sync->in_use=false; ; }
|
virtual void call() { *ret = (instance->*method)(p1,p2,p3,p4); sync->sem->post(); sync->in_use=false; ; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class T,class M,class P1,class P2,class P3,class P4,class P5,class R>
|
template<class T,class M,class P1,class P2,class P3,class P4,class P5,class R>
|
||||||
struct CommandRet5 : public CommandBase {
|
struct CommandRet5 : public CommandBase {
|
||||||
|
|
||||||
T*instance;
|
T*instance;
|
||||||
M method;
|
M method;
|
||||||
typename GetSimpleTypeT<P1>::type_t p1;
|
typename GetSimpleTypeT<P1>::type_t p1;
|
||||||
|
@ -231,13 +231,13 @@ class CommandQueueMT {
|
||||||
typename GetSimpleTypeT<P5>::type_t p5;
|
typename GetSimpleTypeT<P5>::type_t p5;
|
||||||
R* ret;
|
R* ret;
|
||||||
SyncSemaphore *sync;
|
SyncSemaphore *sync;
|
||||||
|
|
||||||
virtual void call() { *ret = (instance->*method)(p1,p2,p3,p4,p5); sync->sem->post(); sync->in_use=false; ; }
|
virtual void call() { *ret = (instance->*method)(p1,p2,p3,p4,p5); sync->sem->post(); sync->in_use=false; ; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class T,class M,class P1,class P2,class P3,class P4,class P5,class P6,class R>
|
template<class T,class M,class P1,class P2,class P3,class P4,class P5,class P6,class R>
|
||||||
struct CommandRet6 : public CommandBase {
|
struct CommandRet6 : public CommandBase {
|
||||||
|
|
||||||
T*instance;
|
T*instance;
|
||||||
M method;
|
M method;
|
||||||
typename GetSimpleTypeT<P1>::type_t p1;
|
typename GetSimpleTypeT<P1>::type_t p1;
|
||||||
|
@ -248,13 +248,13 @@ class CommandQueueMT {
|
||||||
typename GetSimpleTypeT<P6>::type_t p6;
|
typename GetSimpleTypeT<P6>::type_t p6;
|
||||||
R* ret;
|
R* ret;
|
||||||
SyncSemaphore *sync;
|
SyncSemaphore *sync;
|
||||||
|
|
||||||
virtual void call() { *ret = (instance->*method)(p1,p2,p3,p4,p5,p6); sync->sem->post(); sync->in_use=false; ; }
|
virtual void call() { *ret = (instance->*method)(p1,p2,p3,p4,p5,p6); sync->sem->post(); sync->in_use=false; ; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class T,class M,class P1,class P2,class P3,class P4,class P5,class P6,class P7,class R>
|
template<class T,class M,class P1,class P2,class P3,class P4,class P5,class P6,class P7,class R>
|
||||||
struct CommandRet7 : public CommandBase {
|
struct CommandRet7 : public CommandBase {
|
||||||
|
|
||||||
T*instance;
|
T*instance;
|
||||||
M method;
|
M method;
|
||||||
typename GetSimpleTypeT<P1>::type_t p1;
|
typename GetSimpleTypeT<P1>::type_t p1;
|
||||||
|
@ -266,9 +266,9 @@ class CommandQueueMT {
|
||||||
typename GetSimpleTypeT<P7>::type_t p7;
|
typename GetSimpleTypeT<P7>::type_t p7;
|
||||||
R* ret;
|
R* ret;
|
||||||
SyncSemaphore *sync;
|
SyncSemaphore *sync;
|
||||||
|
|
||||||
virtual void call() { *ret = (instance->*method)(p1,p2,p3,p4,p5,p6,p7); sync->sem->post(); sync->in_use=false; ; }
|
virtual void call() { *ret = (instance->*method)(p1,p2,p3,p4,p5,p6,p7); sync->sem->post(); sync->in_use=false; ; }
|
||||||
};
|
};
|
||||||
|
|
||||||
/** commands that don't return but sync */
|
/** commands that don't return but sync */
|
||||||
|
|
||||||
|
@ -392,7 +392,7 @@ class CommandQueueMT {
|
||||||
|
|
||||||
/***** BASE *******/
|
/***** BASE *******/
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
COMMAND_MEM_SIZE_KB=256,
|
COMMAND_MEM_SIZE_KB=256,
|
||||||
COMMAND_MEM_SIZE=COMMAND_MEM_SIZE_KB*1024,
|
COMMAND_MEM_SIZE=COMMAND_MEM_SIZE_KB*1024,
|
||||||
SYNC_SEMAPHORES=8
|
SYNC_SEMAPHORES=8
|
||||||
|
@ -405,30 +405,30 @@ class CommandQueueMT {
|
||||||
SyncSemaphore sync_sems[SYNC_SEMAPHORES];
|
SyncSemaphore sync_sems[SYNC_SEMAPHORES];
|
||||||
Mutex *mutex;
|
Mutex *mutex;
|
||||||
Semaphore *sync;
|
Semaphore *sync;
|
||||||
|
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
T* allocate() {
|
T* allocate() {
|
||||||
|
|
||||||
// alloc size is size+T+safeguard
|
// alloc size is size+T+safeguard
|
||||||
uint32_t alloc_size=sizeof(T)+sizeof(uint32_t);
|
uint32_t alloc_size=sizeof(T)+sizeof(uint32_t);
|
||||||
|
|
||||||
tryagain:
|
tryagain:
|
||||||
|
|
||||||
if (write_ptr < read_ptr) {
|
if (write_ptr < read_ptr) {
|
||||||
// behind read_ptr, check that there is room
|
// behind read_ptr, check that there is room
|
||||||
if ( (read_ptr-write_ptr) <= alloc_size )
|
if ( (read_ptr-write_ptr) <= alloc_size )
|
||||||
return NULL;
|
return NULL;
|
||||||
} else if (write_ptr >= read_ptr) {
|
} else if (write_ptr >= read_ptr) {
|
||||||
// ahead of read_ptr, check that there is room
|
// ahead of read_ptr, check that there is room
|
||||||
|
|
||||||
|
|
||||||
if ( (COMMAND_MEM_SIZE-write_ptr) < alloc_size+4 ) {
|
if ( (COMMAND_MEM_SIZE-write_ptr) < alloc_size+4 ) {
|
||||||
// no room at the end, wrap down;
|
// no room at the end, wrap down;
|
||||||
|
|
||||||
if (read_ptr==0) // dont want write_ptr to become read_ptr
|
if (read_ptr==0) // dont want write_ptr to become read_ptr
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
// if this happens, it's a bug
|
// if this happens, it's a bug
|
||||||
ERR_FAIL_COND_V( (COMMAND_MEM_SIZE-write_ptr) < sizeof(uint32_t), NULL );
|
ERR_FAIL_COND_V( (COMMAND_MEM_SIZE-write_ptr) < sizeof(uint32_t), NULL );
|
||||||
// zero means, wrap to begining
|
// zero means, wrap to begining
|
||||||
|
@ -447,147 +447,147 @@ class CommandQueueMT {
|
||||||
T* cmd = memnew_placement( &command_mem[write_ptr], T );
|
T* cmd = memnew_placement( &command_mem[write_ptr], T );
|
||||||
write_ptr+=sizeof(T);
|
write_ptr+=sizeof(T);
|
||||||
return cmd;
|
return cmd;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
T* allocate_and_lock() {
|
T* allocate_and_lock() {
|
||||||
|
|
||||||
lock();
|
lock();
|
||||||
T* ret;
|
T* ret;
|
||||||
|
|
||||||
while ( (ret=allocate<T>())==NULL ) {
|
while ( (ret=allocate<T>())==NULL ) {
|
||||||
|
|
||||||
unlock();
|
unlock();
|
||||||
// sleep a little until fetch happened and some room is made
|
// sleep a little until fetch happened and some room is made
|
||||||
wait_for_flush();
|
wait_for_flush();
|
||||||
lock();
|
lock();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool flush_one() {
|
bool flush_one() {
|
||||||
|
|
||||||
tryagain:
|
tryagain:
|
||||||
|
|
||||||
// tried to read an empty queue
|
// tried to read an empty queue
|
||||||
if (read_ptr == write_ptr )
|
if (read_ptr == write_ptr )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
uint32_t size = *(uint32_t*)( &command_mem[read_ptr] );
|
uint32_t size = *(uint32_t*)( &command_mem[read_ptr] );
|
||||||
|
|
||||||
if (size==0) {
|
if (size==0) {
|
||||||
//end of ringbuffer, wrap
|
//end of ringbuffer, wrap
|
||||||
read_ptr=0;
|
read_ptr=0;
|
||||||
goto tryagain;
|
goto tryagain;
|
||||||
}
|
}
|
||||||
|
|
||||||
read_ptr+=sizeof(uint32_t);
|
read_ptr+=sizeof(uint32_t);
|
||||||
|
|
||||||
CommandBase *cmd = reinterpret_cast<CommandBase*>( &command_mem[read_ptr] );
|
CommandBase *cmd = reinterpret_cast<CommandBase*>( &command_mem[read_ptr] );
|
||||||
|
|
||||||
cmd->call();
|
cmd->call();
|
||||||
cmd->~CommandBase();
|
cmd->~CommandBase();
|
||||||
|
|
||||||
read_ptr+=size;
|
read_ptr+=size;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void lock();
|
void lock();
|
||||||
void unlock();
|
void unlock();
|
||||||
void wait_for_flush();
|
void wait_for_flush();
|
||||||
SyncSemaphore* _alloc_sync_sem();
|
SyncSemaphore* _alloc_sync_sem();
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/* NORMAL PUSH COMMANDS */
|
/* NORMAL PUSH COMMANDS */
|
||||||
|
|
||||||
template<class T, class M>
|
template<class T, class M>
|
||||||
void push( T * p_instance, M p_method ) {
|
void push( T * p_instance, M p_method ) {
|
||||||
|
|
||||||
Command0<T,M> * cmd = allocate_and_lock< Command0<T,M> >();
|
Command0<T,M> * cmd = allocate_and_lock< Command0<T,M> >();
|
||||||
|
|
||||||
cmd->instance=p_instance;
|
cmd->instance=p_instance;
|
||||||
cmd->method=p_method;
|
cmd->method=p_method;
|
||||||
|
|
||||||
unlock();
|
unlock();
|
||||||
|
|
||||||
if (sync) sync->post();
|
if (sync) sync->post();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T, class M, class P1>
|
template<class T, class M, class P1>
|
||||||
void push( T * p_instance, M p_method, P1 p1 ) {
|
void push( T * p_instance, M p_method, P1 p1 ) {
|
||||||
|
|
||||||
Command1<T,M,P1> * cmd = allocate_and_lock< Command1<T,M,P1> >();
|
Command1<T,M,P1> * cmd = allocate_and_lock< Command1<T,M,P1> >();
|
||||||
|
|
||||||
cmd->instance=p_instance;
|
cmd->instance=p_instance;
|
||||||
cmd->method=p_method;
|
cmd->method=p_method;
|
||||||
cmd->p1=p1;
|
cmd->p1=p1;
|
||||||
|
|
||||||
unlock();
|
unlock();
|
||||||
|
|
||||||
if (sync) sync->post();
|
if (sync) sync->post();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T, class M, class P1, class P2>
|
template<class T, class M, class P1, class P2>
|
||||||
void push( T * p_instance, M p_method, P1 p1, P2 p2 ) {
|
void push( T * p_instance, M p_method, P1 p1, P2 p2 ) {
|
||||||
|
|
||||||
Command2<T,M,P1,P2> * cmd = allocate_and_lock< Command2<T,M,P1,P2> >();
|
Command2<T,M,P1,P2> * cmd = allocate_and_lock< Command2<T,M,P1,P2> >();
|
||||||
|
|
||||||
cmd->instance=p_instance;
|
cmd->instance=p_instance;
|
||||||
cmd->method=p_method;
|
cmd->method=p_method;
|
||||||
cmd->p1=p1;
|
cmd->p1=p1;
|
||||||
cmd->p2=p2;
|
cmd->p2=p2;
|
||||||
|
|
||||||
unlock();
|
unlock();
|
||||||
|
|
||||||
if (sync) sync->post();
|
if (sync) sync->post();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T, class M, class P1, class P2, class P3>
|
template<class T, class M, class P1, class P2, class P3>
|
||||||
void push( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3 ) {
|
void push( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3 ) {
|
||||||
|
|
||||||
Command3<T,M,P1,P2,P3> * cmd = allocate_and_lock< Command3<T,M,P1,P2,P3> >();
|
Command3<T,M,P1,P2,P3> * cmd = allocate_and_lock< Command3<T,M,P1,P2,P3> >();
|
||||||
|
|
||||||
cmd->instance=p_instance;
|
cmd->instance=p_instance;
|
||||||
cmd->method=p_method;
|
cmd->method=p_method;
|
||||||
cmd->p1=p1;
|
cmd->p1=p1;
|
||||||
cmd->p2=p2;
|
cmd->p2=p2;
|
||||||
cmd->p3=p3;
|
cmd->p3=p3;
|
||||||
|
|
||||||
unlock();
|
unlock();
|
||||||
|
|
||||||
if (sync) sync->post();
|
if (sync) sync->post();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T, class M, class P1, class P2, class P3, class P4>
|
template<class T, class M, class P1, class P2, class P3, class P4>
|
||||||
void push( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4 ) {
|
void push( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4 ) {
|
||||||
|
|
||||||
Command4<T,M,P1,P2,P3,P4> * cmd = allocate_and_lock< Command4<T,M,P1,P2,P3,P4> >();
|
Command4<T,M,P1,P2,P3,P4> * cmd = allocate_and_lock< Command4<T,M,P1,P2,P3,P4> >();
|
||||||
|
|
||||||
cmd->instance=p_instance;
|
cmd->instance=p_instance;
|
||||||
cmd->method=p_method;
|
cmd->method=p_method;
|
||||||
cmd->p1=p1;
|
cmd->p1=p1;
|
||||||
cmd->p2=p2;
|
cmd->p2=p2;
|
||||||
cmd->p3=p3;
|
cmd->p3=p3;
|
||||||
cmd->p4=p4;
|
cmd->p4=p4;
|
||||||
|
|
||||||
unlock();
|
unlock();
|
||||||
|
|
||||||
if (sync) sync->post();
|
if (sync) sync->post();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T, class M, class P1, class P2, class P3, class P4, class P5>
|
template<class T, class M, class P1, class P2, class P3, class P4, class P5>
|
||||||
void push( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5 ) {
|
void push( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5 ) {
|
||||||
|
|
||||||
Command5<T,M,P1,P2,P3,P4,P5> * cmd = allocate_and_lock< Command5<T,M,P1,P2,P3,P4,P5> >();
|
Command5<T,M,P1,P2,P3,P4,P5> * cmd = allocate_and_lock< Command5<T,M,P1,P2,P3,P4,P5> >();
|
||||||
|
|
||||||
cmd->instance=p_instance;
|
cmd->instance=p_instance;
|
||||||
cmd->method=p_method;
|
cmd->method=p_method;
|
||||||
cmd->p1=p1;
|
cmd->p1=p1;
|
||||||
|
@ -595,17 +595,17 @@ public:
|
||||||
cmd->p3=p3;
|
cmd->p3=p3;
|
||||||
cmd->p4=p4;
|
cmd->p4=p4;
|
||||||
cmd->p5=p5;
|
cmd->p5=p5;
|
||||||
|
|
||||||
unlock();
|
unlock();
|
||||||
|
|
||||||
if (sync) sync->post();
|
if (sync) sync->post();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T, class M, class P1, class P2, class P3, class P4, class P5, class P6>
|
template<class T, class M, class P1, class P2, class P3, class P4, class P5, class P6>
|
||||||
void push( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6 ) {
|
void push( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6 ) {
|
||||||
|
|
||||||
Command6<T,M,P1,P2,P3,P4,P5,P6> * cmd = allocate_and_lock< Command6<T,M,P1,P2,P3,P4,P5,P6> >();
|
Command6<T,M,P1,P2,P3,P4,P5,P6> * cmd = allocate_and_lock< Command6<T,M,P1,P2,P3,P4,P5,P6> >();
|
||||||
|
|
||||||
cmd->instance=p_instance;
|
cmd->instance=p_instance;
|
||||||
cmd->method=p_method;
|
cmd->method=p_method;
|
||||||
cmd->p1=p1;
|
cmd->p1=p1;
|
||||||
|
@ -614,17 +614,17 @@ public:
|
||||||
cmd->p4=p4;
|
cmd->p4=p4;
|
||||||
cmd->p5=p5;
|
cmd->p5=p5;
|
||||||
cmd->p6=p6;
|
cmd->p6=p6;
|
||||||
|
|
||||||
unlock();
|
unlock();
|
||||||
|
|
||||||
if (sync) sync->post();
|
if (sync) sync->post();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7>
|
template<class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7>
|
||||||
void push( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7 ) {
|
void push( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7 ) {
|
||||||
|
|
||||||
Command7<T,M,P1,P2,P3,P4,P5,P6,P7> * cmd = allocate_and_lock< Command7<T,M,P1,P2,P3,P4,P5,P6,P7> >();
|
Command7<T,M,P1,P2,P3,P4,P5,P6,P7> * cmd = allocate_and_lock< Command7<T,M,P1,P2,P3,P4,P5,P6,P7> >();
|
||||||
|
|
||||||
cmd->instance=p_instance;
|
cmd->instance=p_instance;
|
||||||
cmd->method=p_method;
|
cmd->method=p_method;
|
||||||
cmd->p1=p1;
|
cmd->p1=p1;
|
||||||
|
@ -634,19 +634,19 @@ public:
|
||||||
cmd->p5=p5;
|
cmd->p5=p5;
|
||||||
cmd->p6=p6;
|
cmd->p6=p6;
|
||||||
cmd->p7=p7;
|
cmd->p7=p7;
|
||||||
|
|
||||||
unlock();
|
unlock();
|
||||||
|
|
||||||
if (sync) sync->post();
|
if (sync) sync->post();
|
||||||
}
|
}
|
||||||
/*** PUSH AND RET COMMANDS ***/
|
/*** PUSH AND RET COMMANDS ***/
|
||||||
|
|
||||||
|
|
||||||
template<class T, class M,class R>
|
template<class T, class M,class R>
|
||||||
void push_and_ret( T * p_instance, M p_method, R* r_ret) {
|
void push_and_ret( T * p_instance, M p_method, R* r_ret) {
|
||||||
|
|
||||||
CommandRet0<T,M,R> * cmd = allocate_and_lock< CommandRet0<T,M,R> >();
|
CommandRet0<T,M,R> * cmd = allocate_and_lock< CommandRet0<T,M,R> >();
|
||||||
|
|
||||||
cmd->instance=p_instance;
|
cmd->instance=p_instance;
|
||||||
cmd->method=p_method;
|
cmd->method=p_method;
|
||||||
cmd->ret=r_ret;
|
cmd->ret=r_ret;
|
||||||
|
@ -654,34 +654,34 @@ public:
|
||||||
cmd->sync=ss;
|
cmd->sync=ss;
|
||||||
|
|
||||||
unlock();
|
unlock();
|
||||||
|
|
||||||
if (sync) sync->post();
|
if (sync) sync->post();
|
||||||
ss->sem->wait();
|
ss->sem->wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T, class M, class P1,class R>
|
template<class T, class M, class P1,class R>
|
||||||
void push_and_ret( T * p_instance, M p_method, P1 p1, R* r_ret) {
|
void push_and_ret( T * p_instance, M p_method, P1 p1, R* r_ret) {
|
||||||
|
|
||||||
CommandRet1<T,M,P1,R> * cmd = allocate_and_lock< CommandRet1<T,M,P1,R> >();
|
CommandRet1<T,M,P1,R> * cmd = allocate_and_lock< CommandRet1<T,M,P1,R> >();
|
||||||
|
|
||||||
cmd->instance=p_instance;
|
cmd->instance=p_instance;
|
||||||
cmd->method=p_method;
|
cmd->method=p_method;
|
||||||
cmd->p1=p1;
|
cmd->p1=p1;
|
||||||
cmd->ret=r_ret;
|
cmd->ret=r_ret;
|
||||||
SyncSemaphore *ss=_alloc_sync_sem();
|
SyncSemaphore *ss=_alloc_sync_sem();
|
||||||
cmd->sync=ss;
|
cmd->sync=ss;
|
||||||
|
|
||||||
unlock();
|
unlock();
|
||||||
|
|
||||||
if (sync) sync->post();
|
if (sync) sync->post();
|
||||||
ss->sem->wait();
|
ss->sem->wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T, class M, class P1, class P2,class R>
|
template<class T, class M, class P1, class P2,class R>
|
||||||
void push_and_ret( T * p_instance, M p_method, P1 p1, P2 p2, R* r_ret) {
|
void push_and_ret( T * p_instance, M p_method, P1 p1, P2 p2, R* r_ret) {
|
||||||
|
|
||||||
CommandRet2<T,M,P1,P2,R> * cmd = allocate_and_lock< CommandRet2<T,M,P1,P2,R> >();
|
CommandRet2<T,M,P1,P2,R> * cmd = allocate_and_lock< CommandRet2<T,M,P1,P2,R> >();
|
||||||
|
|
||||||
cmd->instance=p_instance;
|
cmd->instance=p_instance;
|
||||||
cmd->method=p_method;
|
cmd->method=p_method;
|
||||||
cmd->p1=p1;
|
cmd->p1=p1;
|
||||||
|
@ -691,16 +691,16 @@ public:
|
||||||
cmd->sync=ss;
|
cmd->sync=ss;
|
||||||
|
|
||||||
unlock();
|
unlock();
|
||||||
|
|
||||||
if (sync) sync->post();
|
if (sync) sync->post();
|
||||||
ss->sem->wait();
|
ss->sem->wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T, class M, class P1, class P2, class P3,class R>
|
template<class T, class M, class P1, class P2, class P3,class R>
|
||||||
void push_and_ret( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, R* r_ret ) {
|
void push_and_ret( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, R* r_ret ) {
|
||||||
|
|
||||||
CommandRet3<T,M,P1,P2,P3,R> * cmd = allocate_and_lock< CommandRet3<T,M,P1,P2,P3,R> >();
|
CommandRet3<T,M,P1,P2,P3,R> * cmd = allocate_and_lock< CommandRet3<T,M,P1,P2,P3,R> >();
|
||||||
|
|
||||||
cmd->instance=p_instance;
|
cmd->instance=p_instance;
|
||||||
cmd->method=p_method;
|
cmd->method=p_method;
|
||||||
cmd->p1=p1;
|
cmd->p1=p1;
|
||||||
|
@ -711,16 +711,16 @@ public:
|
||||||
cmd->sync=ss;
|
cmd->sync=ss;
|
||||||
|
|
||||||
unlock();
|
unlock();
|
||||||
|
|
||||||
if (sync) sync->post();
|
if (sync) sync->post();
|
||||||
ss->sem->wait();
|
ss->sem->wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T, class M, class P1, class P2, class P3, class P4,class R>
|
template<class T, class M, class P1, class P2, class P3, class P4,class R>
|
||||||
void push_and_ret( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, R* r_ret ) {
|
void push_and_ret( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, R* r_ret ) {
|
||||||
|
|
||||||
CommandRet4<T,M,P1,P2,P3,P4,R> * cmd = allocate_and_lock< CommandRet4<T,M,P1,P2,P3,P4,R> >();
|
CommandRet4<T,M,P1,P2,P3,P4,R> * cmd = allocate_and_lock< CommandRet4<T,M,P1,P2,P3,P4,R> >();
|
||||||
|
|
||||||
cmd->instance=p_instance;
|
cmd->instance=p_instance;
|
||||||
cmd->method=p_method;
|
cmd->method=p_method;
|
||||||
cmd->p1=p1;
|
cmd->p1=p1;
|
||||||
|
@ -732,16 +732,16 @@ public:
|
||||||
cmd->sync=ss;
|
cmd->sync=ss;
|
||||||
|
|
||||||
unlock();
|
unlock();
|
||||||
|
|
||||||
if (sync) sync->post();
|
if (sync) sync->post();
|
||||||
ss->sem->wait();
|
ss->sem->wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T, class M, class P1, class P2, class P3, class P4, class P5,class R>
|
template<class T, class M, class P1, class P2, class P3, class P4, class P5,class R>
|
||||||
void push_and_ret( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, R* r_ret ) {
|
void push_and_ret( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, R* r_ret ) {
|
||||||
|
|
||||||
CommandRet5<T,M,P1,P2,P3,P4,P5,R> * cmd = allocate_and_lock< CommandRet5<T,M,P1,P2,P3,P4,P5,R> >();
|
CommandRet5<T,M,P1,P2,P3,P4,P5,R> * cmd = allocate_and_lock< CommandRet5<T,M,P1,P2,P3,P4,P5,R> >();
|
||||||
|
|
||||||
cmd->instance=p_instance;
|
cmd->instance=p_instance;
|
||||||
cmd->method=p_method;
|
cmd->method=p_method;
|
||||||
cmd->p1=p1;
|
cmd->p1=p1;
|
||||||
|
@ -754,16 +754,16 @@ public:
|
||||||
cmd->sync=ss;
|
cmd->sync=ss;
|
||||||
|
|
||||||
unlock();
|
unlock();
|
||||||
|
|
||||||
if (sync) sync->post();
|
if (sync) sync->post();
|
||||||
ss->sem->wait();
|
ss->sem->wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T, class M, class P1, class P2, class P3, class P4, class P5, class P6,class R>
|
template<class T, class M, class P1, class P2, class P3, class P4, class P5, class P6,class R>
|
||||||
void push_and_ret( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, R* r_ret ) {
|
void push_and_ret( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, R* r_ret ) {
|
||||||
|
|
||||||
CommandRet6<T,M,P1,P2,P3,P4,P5,P6,R> * cmd = allocate_and_lock< CommandRet6<T,M,P1,P2,P3,P4,P5,P6,R> >();
|
CommandRet6<T,M,P1,P2,P3,P4,P5,P6,R> * cmd = allocate_and_lock< CommandRet6<T,M,P1,P2,P3,P4,P5,P6,R> >();
|
||||||
|
|
||||||
cmd->instance=p_instance;
|
cmd->instance=p_instance;
|
||||||
cmd->method=p_method;
|
cmd->method=p_method;
|
||||||
cmd->p1=p1;
|
cmd->p1=p1;
|
||||||
|
@ -777,16 +777,16 @@ public:
|
||||||
cmd->sync=ss;
|
cmd->sync=ss;
|
||||||
|
|
||||||
unlock();
|
unlock();
|
||||||
|
|
||||||
if (sync) sync->post();
|
if (sync) sync->post();
|
||||||
ss->sem->wait();
|
ss->sem->wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T, class M, class P1, class P2, class P3, class P4, class P5, class P6,class P7,class R>
|
template<class T, class M, class P1, class P2, class P3, class P4, class P5, class P6,class P7,class R>
|
||||||
void push_and_ret( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6,P7 p7, R* r_ret ) {
|
void push_and_ret( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6,P7 p7, R* r_ret ) {
|
||||||
|
|
||||||
CommandRet7<T,M,P1,P2,P3,P4,P5,P6,P7,R> * cmd = allocate_and_lock< CommandRet7<T,M,P1,P2,P3,P4,P5,P6,P7,R> >();
|
CommandRet7<T,M,P1,P2,P3,P4,P5,P6,P7,R> * cmd = allocate_and_lock< CommandRet7<T,M,P1,P2,P3,P4,P5,P6,P7,R> >();
|
||||||
|
|
||||||
cmd->instance=p_instance;
|
cmd->instance=p_instance;
|
||||||
cmd->method=p_method;
|
cmd->method=p_method;
|
||||||
cmd->p1=p1;
|
cmd->p1=p1;
|
||||||
|
@ -801,7 +801,7 @@ public:
|
||||||
cmd->sync=ss;
|
cmd->sync=ss;
|
||||||
|
|
||||||
unlock();
|
unlock();
|
||||||
|
|
||||||
if (sync) sync->post();
|
if (sync) sync->post();
|
||||||
ss->sem->wait();
|
ss->sem->wait();
|
||||||
}
|
}
|
||||||
|
@ -975,12 +975,12 @@ public:
|
||||||
ERR_FAIL_COND(!sync);
|
ERR_FAIL_COND(!sync);
|
||||||
sync->wait();
|
sync->wait();
|
||||||
lock();
|
lock();
|
||||||
flush_one();
|
flush_one();
|
||||||
unlock();
|
unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void flush_all() {
|
void flush_all() {
|
||||||
|
|
||||||
//ERR_FAIL_COND(sync);
|
//ERR_FAIL_COND(sync);
|
||||||
lock();
|
lock();
|
||||||
while (true) {
|
while (true) {
|
||||||
|
@ -990,10 +990,10 @@ public:
|
||||||
}
|
}
|
||||||
unlock();
|
unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
CommandQueueMT(bool p_sync);
|
CommandQueueMT(bool p_sync);
|
||||||
~CommandQueueMT();
|
~CommandQueueMT();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -110,6 +110,16 @@ bool Dictionary::has(const Variant& p_key) const {
|
||||||
|
|
||||||
return _p->variant_map.has(p_key);
|
return _p->variant_map.has(p_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Dictionary::has_all(const Array& p_keys) const {
|
||||||
|
for (int i=0;i<p_keys.size();i++) {
|
||||||
|
if( !has(p_keys[i]) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void Dictionary::erase(const Variant& p_key) {
|
void Dictionary::erase(const Variant& p_key) {
|
||||||
_copy_on_write();
|
_copy_on_write();
|
||||||
_p->variant_map.erase(p_key);
|
_p->variant_map.erase(p_key);
|
||||||
|
|
|
@ -69,6 +69,8 @@ public:
|
||||||
bool is_shared() const;
|
bool is_shared() const;
|
||||||
|
|
||||||
bool has(const Variant& p_key) const;
|
bool has(const Variant& p_key) const;
|
||||||
|
bool has_all(const Array& p_keys) const;
|
||||||
|
|
||||||
void erase(const Variant& p_key);
|
void erase(const Variant& p_key);
|
||||||
|
|
||||||
bool operator==(const Dictionary& p_dictionary) const;
|
bool operator==(const Dictionary& p_dictionary) const;
|
||||||
|
|
198
core/dvector.h
198
core/dvector.h
|
@ -43,18 +43,18 @@ template<class T>
|
||||||
class DVector {
|
class DVector {
|
||||||
|
|
||||||
mutable MID mem;
|
mutable MID mem;
|
||||||
|
|
||||||
|
|
||||||
void copy_on_write() {
|
void copy_on_write() {
|
||||||
|
|
||||||
if (!mem.is_valid())
|
if (!mem.is_valid())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (dvector_lock)
|
if (dvector_lock)
|
||||||
dvector_lock->lock();
|
dvector_lock->lock();
|
||||||
|
|
||||||
MID_Lock lock( mem );
|
MID_Lock lock( mem );
|
||||||
|
|
||||||
|
|
||||||
if ( *(int*)lock.data() == 1 ) {
|
if ( *(int*)lock.data() == 1 ) {
|
||||||
// one reference, means no refcount changes
|
// one reference, means no refcount changes
|
||||||
|
@ -62,114 +62,114 @@ class DVector {
|
||||||
dvector_lock->unlock();
|
dvector_lock->unlock();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
MID new_mem= dynalloc( mem.get_size() );
|
MID new_mem= dynalloc( mem.get_size() );
|
||||||
|
|
||||||
if (!new_mem.is_valid()) {
|
if (!new_mem.is_valid()) {
|
||||||
|
|
||||||
if (dvector_lock)
|
if (dvector_lock)
|
||||||
dvector_lock->unlock();
|
dvector_lock->unlock();
|
||||||
ERR_FAIL_COND( new_mem.is_valid() ); // out of memory
|
ERR_FAIL_COND( new_mem.is_valid() ); // out of memory
|
||||||
}
|
}
|
||||||
|
|
||||||
MID_Lock dst_lock( new_mem );
|
MID_Lock dst_lock( new_mem );
|
||||||
|
|
||||||
int *rc = (int*)dst_lock.data();
|
int *rc = (int*)dst_lock.data();
|
||||||
|
|
||||||
*rc=1;
|
*rc=1;
|
||||||
|
|
||||||
T * dst = (T*)(rc + 1 );
|
T * dst = (T*)(rc + 1 );
|
||||||
|
|
||||||
T * src =(T*) ((int*)lock.data() + 1 );
|
T * src =(T*) ((int*)lock.data() + 1 );
|
||||||
|
|
||||||
int count = (mem.get_size() - sizeof(int)) / sizeof(T);
|
int count = (mem.get_size() - sizeof(int)) / sizeof(T);
|
||||||
|
|
||||||
for (int i=0;i<count;i++) {
|
for (int i=0;i<count;i++) {
|
||||||
|
|
||||||
memnew_placement( &dst[i], T(src[i]) );
|
memnew_placement( &dst[i], T(src[i]) );
|
||||||
}
|
}
|
||||||
|
|
||||||
(*(int*)lock.data())--;
|
(*(int*)lock.data())--;
|
||||||
|
|
||||||
// unlock all
|
// unlock all
|
||||||
dst_lock=MID_Lock();
|
dst_lock=MID_Lock();
|
||||||
lock=MID_Lock();
|
lock=MID_Lock();
|
||||||
|
|
||||||
mem=new_mem;
|
mem=new_mem;
|
||||||
|
|
||||||
if (dvector_lock)
|
if (dvector_lock)
|
||||||
dvector_lock->unlock();
|
dvector_lock->unlock();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void reference( const DVector& p_dvector ) {
|
void reference( const DVector& p_dvector ) {
|
||||||
|
|
||||||
unreference();
|
unreference();
|
||||||
|
|
||||||
if (dvector_lock)
|
if (dvector_lock)
|
||||||
dvector_lock->lock();
|
dvector_lock->lock();
|
||||||
|
|
||||||
if (!p_dvector.mem.is_valid()) {
|
if (!p_dvector.mem.is_valid()) {
|
||||||
|
|
||||||
if (dvector_lock)
|
if (dvector_lock)
|
||||||
dvector_lock->unlock();
|
dvector_lock->unlock();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
MID_Lock lock(p_dvector.mem);
|
MID_Lock lock(p_dvector.mem);
|
||||||
|
|
||||||
int * rc = (int*)lock.data();
|
int * rc = (int*)lock.data();
|
||||||
(*rc)++;
|
(*rc)++;
|
||||||
|
|
||||||
lock = MID_Lock();
|
lock = MID_Lock();
|
||||||
mem=p_dvector.mem;
|
mem=p_dvector.mem;
|
||||||
|
|
||||||
if (dvector_lock)
|
if (dvector_lock)
|
||||||
dvector_lock->unlock();
|
dvector_lock->unlock();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void unreference() {
|
void unreference() {
|
||||||
|
|
||||||
if (dvector_lock)
|
if (dvector_lock)
|
||||||
dvector_lock->lock();
|
dvector_lock->lock();
|
||||||
|
|
||||||
if (!mem.is_valid()) {
|
if (!mem.is_valid()) {
|
||||||
|
|
||||||
if (dvector_lock)
|
if (dvector_lock)
|
||||||
dvector_lock->unlock();
|
dvector_lock->unlock();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
MID_Lock lock(mem);
|
MID_Lock lock(mem);
|
||||||
|
|
||||||
int * rc = (int*)lock.data();
|
int * rc = (int*)lock.data();
|
||||||
(*rc)--;
|
(*rc)--;
|
||||||
|
|
||||||
if (*rc==0) {
|
if (*rc==0) {
|
||||||
// no one else using it, destruct
|
// no one else using it, destruct
|
||||||
|
|
||||||
T * t= (T*)(rc+1);
|
T * t= (T*)(rc+1);
|
||||||
int count = (mem.get_size() - sizeof(int)) / sizeof(T);
|
int count = (mem.get_size() - sizeof(int)) / sizeof(T);
|
||||||
|
|
||||||
for (int i=0;i<count;i++) {
|
for (int i=0;i<count;i++) {
|
||||||
|
|
||||||
t[i].~T();
|
t[i].~T();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
lock = MID_Lock();
|
lock = MID_Lock();
|
||||||
|
|
||||||
mem = MID ();
|
mem = MID ();
|
||||||
|
|
||||||
if (dvector_lock)
|
if (dvector_lock)
|
||||||
dvector_lock->unlock();
|
dvector_lock->unlock();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
class Read {
|
class Read {
|
||||||
|
@ -177,10 +177,10 @@ public:
|
||||||
MID_Lock lock;
|
MID_Lock lock;
|
||||||
const T * mem;
|
const T * mem;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
_FORCE_INLINE_ const T& operator[](int p_index) const { return mem[p_index]; }
|
_FORCE_INLINE_ const T& operator[](int p_index) const { return mem[p_index]; }
|
||||||
_FORCE_INLINE_ const T *ptr() const { return mem; }
|
_FORCE_INLINE_ const T *ptr() const { return mem; }
|
||||||
|
|
||||||
Read() { mem=NULL; }
|
Read() { mem=NULL; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -189,32 +189,32 @@ public:
|
||||||
MID_Lock lock;
|
MID_Lock lock;
|
||||||
T * mem;
|
T * mem;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
_FORCE_INLINE_ T& operator[](int p_index) { return mem[p_index]; }
|
_FORCE_INLINE_ T& operator[](int p_index) { return mem[p_index]; }
|
||||||
_FORCE_INLINE_ T *ptr() { return mem; }
|
_FORCE_INLINE_ T *ptr() { return mem; }
|
||||||
|
|
||||||
Write() { mem=NULL; }
|
Write() { mem=NULL; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
Read read() const {
|
Read read() const {
|
||||||
|
|
||||||
Read r;
|
Read r;
|
||||||
if (mem.is_valid()) {
|
if (mem.is_valid()) {
|
||||||
r.lock = MID_Lock( mem );
|
r.lock = MID_Lock( mem );
|
||||||
r.mem = (const T*)((int*)r.lock.data()+1);
|
r.mem = (const T*)((int*)r.lock.data()+1);
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
Write write() {
|
Write write() {
|
||||||
|
|
||||||
Write w;
|
Write w;
|
||||||
if (mem.is_valid()) {
|
if (mem.is_valid()) {
|
||||||
copy_on_write();
|
copy_on_write();
|
||||||
w.lock = MID_Lock( mem );
|
w.lock = MID_Lock( mem );
|
||||||
w.mem = (T*)((int*)w.lock.data()+1);
|
w.mem = (T*)((int*)w.lock.data()+1);
|
||||||
}
|
}
|
||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class MC>
|
template<class MC>
|
||||||
|
@ -280,12 +280,12 @@ public:
|
||||||
|
|
||||||
|
|
||||||
bool is_locked() const { return mem.is_locked(); }
|
bool is_locked() const { return mem.is_locked(); }
|
||||||
|
|
||||||
inline const T operator[](int p_index) const;
|
inline const T operator[](int p_index) const;
|
||||||
|
|
||||||
Error resize(int p_size);
|
Error resize(int p_size);
|
||||||
|
|
||||||
|
|
||||||
void operator=(const DVector& p_dvector) { reference(p_dvector); }
|
void operator=(const DVector& p_dvector) { reference(p_dvector); }
|
||||||
DVector() {}
|
DVector() {}
|
||||||
DVector(const DVector& p_dvector) { reference(p_dvector); }
|
DVector(const DVector& p_dvector) { reference(p_dvector); }
|
||||||
|
@ -308,7 +308,7 @@ T DVector<T>::get(int p_index) const {
|
||||||
template<class T>
|
template<class T>
|
||||||
void DVector<T>::set(int p_index, const T& p_val) {
|
void DVector<T>::set(int p_index, const T& p_val) {
|
||||||
|
|
||||||
if (p_index<0 || p_index>=size()) {
|
if (p_index<0 || p_index>=size()) {
|
||||||
ERR_FAIL_COND(p_index<0 || p_index>=size());
|
ERR_FAIL_COND(p_index<0 || p_index>=size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -332,7 +332,7 @@ const T DVector<T>::operator[](int p_index) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
Read r = read();
|
Read r = read();
|
||||||
|
|
||||||
return r[p_index];
|
return r[p_index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -344,83 +344,83 @@ Error DVector<T>::resize(int p_size) {
|
||||||
dvector_lock->lock();
|
dvector_lock->lock();
|
||||||
|
|
||||||
bool same = p_size==size();
|
bool same = p_size==size();
|
||||||
|
|
||||||
if (dvector_lock)
|
if (dvector_lock)
|
||||||
dvector_lock->unlock();
|
dvector_lock->unlock();
|
||||||
// no further locking is necesary because we are supposed to own the only copy of this (using copy on write)
|
// no further locking is necesary because we are supposed to own the only copy of this (using copy on write)
|
||||||
|
|
||||||
if (same)
|
if (same)
|
||||||
return OK;
|
return OK;
|
||||||
|
|
||||||
if (p_size == 0 ) {
|
if (p_size == 0 ) {
|
||||||
|
|
||||||
unreference();
|
unreference();
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
copy_on_write(); // make it unique
|
copy_on_write(); // make it unique
|
||||||
|
|
||||||
ERR_FAIL_COND_V( mem.is_locked(), ERR_LOCKED ); // if after copy on write, memory is locked, fail.
|
ERR_FAIL_COND_V( mem.is_locked(), ERR_LOCKED ); // if after copy on write, memory is locked, fail.
|
||||||
|
|
||||||
if (p_size > size() ) {
|
if (p_size > size() ) {
|
||||||
|
|
||||||
int oldsize=size();
|
int oldsize=size();
|
||||||
|
|
||||||
MID_Lock lock;
|
MID_Lock lock;
|
||||||
|
|
||||||
if (oldsize==0) {
|
if (oldsize==0) {
|
||||||
|
|
||||||
mem = dynalloc( p_size * sizeof(T) + sizeof(int) );
|
mem = dynalloc( p_size * sizeof(T) + sizeof(int) );
|
||||||
lock=MID_Lock(mem);
|
lock=MID_Lock(mem);
|
||||||
int *rc = ((int*)lock.data());
|
int *rc = ((int*)lock.data());
|
||||||
*rc=1;
|
*rc=1;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if (dynrealloc( mem, p_size * sizeof(T) + sizeof(int) )!=OK ) {
|
if (dynrealloc( mem, p_size * sizeof(T) + sizeof(int) )!=OK ) {
|
||||||
|
|
||||||
ERR_FAIL_V(ERR_OUT_OF_MEMORY); // out of memory
|
ERR_FAIL_V(ERR_OUT_OF_MEMORY); // out of memory
|
||||||
}
|
}
|
||||||
|
|
||||||
lock=MID_Lock(mem);
|
lock=MID_Lock(mem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
T *t = (T*)((int*)lock.data() + 1);
|
T *t = (T*)((int*)lock.data() + 1);
|
||||||
|
|
||||||
for (int i=oldsize;i<p_size;i++) {
|
for (int i=oldsize;i<p_size;i++) {
|
||||||
|
|
||||||
memnew_placement(&t[i], T );
|
memnew_placement(&t[i], T );
|
||||||
}
|
}
|
||||||
|
|
||||||
lock = MID_Lock(); // clear
|
lock = MID_Lock(); // clear
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
int oldsize=size();
|
int oldsize=size();
|
||||||
|
|
||||||
MID_Lock lock(mem);
|
MID_Lock lock(mem);
|
||||||
|
|
||||||
|
|
||||||
T *t = (T*)((int*)lock.data() + 1);
|
T *t = (T*)((int*)lock.data() + 1);
|
||||||
|
|
||||||
for (int i=p_size;i<oldsize;i++) {
|
for (int i=p_size;i<oldsize;i++) {
|
||||||
|
|
||||||
t[i].~T();
|
t[i].~T();
|
||||||
}
|
}
|
||||||
|
|
||||||
lock = MID_Lock(); // clear
|
lock = MID_Lock(); // clear
|
||||||
|
|
||||||
if (dynrealloc( mem, p_size * sizeof(T) + sizeof(int) )!=OK ) {
|
if (dynrealloc( mem, p_size * sizeof(T) + sizeof(int) )!=OK ) {
|
||||||
|
|
||||||
ERR_FAIL_V(ERR_OUT_OF_MEMORY); // wtf error
|
ERR_FAIL_V(ERR_OUT_OF_MEMORY); // wtf error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,12 +33,12 @@
|
||||||
/**
|
/**
|
||||||
* Error macros. Unlike exceptions and asserts, these macros try to mantain consistency and stability
|
* Error macros. Unlike exceptions and asserts, these macros try to mantain consistency and stability
|
||||||
* inside the code. It is recommended to always return processable data, so in case of an error, the
|
* inside the code. It is recommended to always return processable data, so in case of an error, the
|
||||||
* engine can stay working well.
|
* engine can stay working well.
|
||||||
* In most cases, bugs and/or invalid data are not fatal and should never allow a perfectly running application
|
* In most cases, bugs and/or invalid data are not fatal and should never allow a perfectly running application
|
||||||
* to fail or crash.
|
* to fail or crash.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pointer to the error macro priting function. Reassign to any function to have errors printed
|
* Pointer to the error macro priting function. Reassign to any function to have errors printed
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -136,7 +136,7 @@ extern bool _err_error_exists;
|
||||||
return m_retval; \
|
return m_retval; \
|
||||||
}else _err_error_exists=false; } \
|
}else _err_error_exists=false; } \
|
||||||
|
|
||||||
/** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert().
|
/** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert().
|
||||||
* the function will exit.
|
* the function will exit.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -146,7 +146,7 @@ extern bool _err_error_exists;
|
||||||
return; \
|
return; \
|
||||||
}else _err_error_exists=false; } \
|
}else _err_error_exists=false; } \
|
||||||
|
|
||||||
/** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert().
|
/** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert().
|
||||||
* the function will exit.
|
* the function will exit.
|
||||||
* This function returns an error value, if returning Error, please select the most
|
* This function returns an error value, if returning Error, please select the most
|
||||||
* appropriate error condition from error_macros.h
|
* appropriate error condition from error_macros.h
|
||||||
|
@ -158,7 +158,7 @@ extern bool _err_error_exists;
|
||||||
return m_retval; \
|
return m_retval; \
|
||||||
}else _err_error_exists=false; } \
|
}else _err_error_exists=false; } \
|
||||||
|
|
||||||
/** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert().
|
/** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert().
|
||||||
* the loop will skip to the next iteration.
|
* the loop will skip to the next iteration.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -168,7 +168,7 @@ extern bool _err_error_exists;
|
||||||
continue;\
|
continue;\
|
||||||
} else _err_error_exists=false;} \
|
} else _err_error_exists=false;} \
|
||||||
|
|
||||||
/** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert().
|
/** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert().
|
||||||
* the loop will break
|
* the loop will break
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
|
@ -43,118 +43,118 @@ Error EventQueue::push_call(uint32_t p_instance_ID, const StringName& p_method,
|
||||||
args=2;
|
args=2;
|
||||||
else if (p_arg1.get_type()!=Variant::NIL)
|
else if (p_arg1.get_type()!=Variant::NIL)
|
||||||
args=1;
|
args=1;
|
||||||
else
|
else
|
||||||
args=0;
|
args=0;
|
||||||
|
|
||||||
room_needed+=sizeof(Variant)*args;
|
room_needed+=sizeof(Variant)*args;
|
||||||
|
|
||||||
ERR_FAIL_COND_V( (buffer_end+room_needed) >= buffer_size , ERR_OUT_OF_MEMORY );
|
ERR_FAIL_COND_V( (buffer_end+room_needed) >= buffer_size , ERR_OUT_OF_MEMORY );
|
||||||
Event * ev = memnew_placement( &event_buffer[ buffer_end ], Event );
|
Event * ev = memnew_placement( &event_buffer[ buffer_end ], Event );
|
||||||
ev->args=args;
|
ev->args=args;
|
||||||
ev->instance_ID=p_instance_ID;
|
ev->instance_ID=p_instance_ID;
|
||||||
ev->method=p_method;
|
ev->method=p_method;
|
||||||
|
|
||||||
buffer_end+=sizeof(Event);
|
buffer_end+=sizeof(Event);
|
||||||
|
|
||||||
if (args>=1) {
|
if (args>=1) {
|
||||||
|
|
||||||
Variant * v = memnew_placement( &event_buffer[ buffer_end ], Variant );
|
Variant * v = memnew_placement( &event_buffer[ buffer_end ], Variant );
|
||||||
buffer_end+=sizeof(Variant);
|
buffer_end+=sizeof(Variant);
|
||||||
*v=p_arg1;
|
*v=p_arg1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args>=2) {
|
if (args>=2) {
|
||||||
|
|
||||||
Variant * v = memnew_placement( &event_buffer[ buffer_end ], Variant );
|
Variant * v = memnew_placement( &event_buffer[ buffer_end ], Variant );
|
||||||
buffer_end+=sizeof(Variant);
|
buffer_end+=sizeof(Variant);
|
||||||
*v=p_arg2;
|
*v=p_arg2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args>=3) {
|
if (args>=3) {
|
||||||
|
|
||||||
Variant * v = memnew_placement( &event_buffer[ buffer_end ], Variant );
|
Variant * v = memnew_placement( &event_buffer[ buffer_end ], Variant );
|
||||||
buffer_end+=sizeof(Variant);
|
buffer_end+=sizeof(Variant);
|
||||||
*v=p_arg3;
|
*v=p_arg3;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args>=4) {
|
if (args>=4) {
|
||||||
|
|
||||||
Variant * v = memnew_placement( &event_buffer[ buffer_end ], Variant );
|
Variant * v = memnew_placement( &event_buffer[ buffer_end ], Variant );
|
||||||
buffer_end+=sizeof(Variant);
|
buffer_end+=sizeof(Variant);
|
||||||
*v=p_arg4;
|
*v=p_arg4;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args>=5) {
|
if (args>=5) {
|
||||||
|
|
||||||
Variant * v = memnew_placement( &event_buffer[ buffer_end ], Variant );
|
Variant * v = memnew_placement( &event_buffer[ buffer_end ], Variant );
|
||||||
buffer_end+=sizeof(Variant);
|
buffer_end+=sizeof(Variant);
|
||||||
*v=p_arg5;
|
*v=p_arg5;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buffer_max_used>buffer_end);
|
if (buffer_end > buffer_max_used)
|
||||||
buffer_max_used=buffer_end;
|
buffer_max_used=buffer_end;
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EventQueue::flush_events() {
|
void EventQueue::flush_events() {
|
||||||
|
|
||||||
uint32_t read_pos=0;
|
uint32_t read_pos=0;
|
||||||
|
|
||||||
while (read_pos < buffer_end ) {
|
while (read_pos < buffer_end ) {
|
||||||
|
|
||||||
Event *event = (Event*)&event_buffer[ read_pos ];
|
Event *event = (Event*)&event_buffer[ read_pos ];
|
||||||
Variant *args= (Variant*)(event+1);
|
Variant *args= (Variant*)(event+1);
|
||||||
Object *obj = ObjectDB::get_instance(event->instance_ID);
|
Object *obj = ObjectDB::get_instance(event->instance_ID);
|
||||||
|
|
||||||
if (obj) {
|
if (obj) {
|
||||||
// events don't expect a return value
|
// events don't expect a return value
|
||||||
obj->call( event->method,
|
obj->call( event->method,
|
||||||
(event->args>=1) ? args[0] : Variant(),
|
(event->args>=1) ? args[0] : Variant(),
|
||||||
(event->args>=2) ? args[1] : Variant(),
|
(event->args>=2) ? args[1] : Variant(),
|
||||||
(event->args>=3) ? args[2] : Variant(),
|
(event->args>=3) ? args[2] : Variant(),
|
||||||
(event->args>=4) ? args[3] : Variant(),
|
(event->args>=4) ? args[3] : Variant(),
|
||||||
(event->args>=5) ? args[4] : Variant() );
|
(event->args>=5) ? args[4] : Variant() );
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event->args>=1) args[0].~Variant();
|
if (event->args>=1) args[0].~Variant();
|
||||||
if (event->args>=2) args[1].~Variant();
|
if (event->args>=2) args[1].~Variant();
|
||||||
if (event->args>=3) args[2].~Variant();
|
if (event->args>=3) args[2].~Variant();
|
||||||
if (event->args>=4) args[3].~Variant();
|
if (event->args>=4) args[3].~Variant();
|
||||||
if (event->args>=5) args[4].~Variant();
|
if (event->args>=5) args[4].~Variant();
|
||||||
event->~Event();
|
event->~Event();
|
||||||
|
|
||||||
read_pos+=sizeof(Event)+sizeof(Variant)*event->args;
|
read_pos+=sizeof(Event)+sizeof(Variant)*event->args;
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer_end=0; // reset buffer
|
buffer_end=0; // reset buffer
|
||||||
}
|
}
|
||||||
|
|
||||||
EventQueue::EventQueue(uint32_t p_buffer_size) {
|
EventQueue::EventQueue(uint32_t p_buffer_size) {
|
||||||
|
|
||||||
|
|
||||||
buffer_end=0;
|
buffer_end=0;
|
||||||
buffer_max_used=0;
|
buffer_max_used=0;
|
||||||
buffer_size=p_buffer_size;
|
buffer_size=p_buffer_size;
|
||||||
event_buffer = memnew_arr( uint8_t, buffer_size );
|
event_buffer = memnew_arr( uint8_t, buffer_size );
|
||||||
|
|
||||||
}
|
}
|
||||||
EventQueue::~EventQueue() {
|
EventQueue::~EventQueue() {
|
||||||
|
|
||||||
uint32_t read_pos=0;
|
uint32_t read_pos=0;
|
||||||
|
|
||||||
while (read_pos < buffer_end ) {
|
while (read_pos < buffer_end ) {
|
||||||
|
|
||||||
Event *event = (Event*)&event_buffer[ read_pos ];
|
Event *event = (Event*)&event_buffer[ read_pos ];
|
||||||
Variant *args= (Variant*)(event+1);
|
Variant *args= (Variant*)(event+1);
|
||||||
for (int i=0;i<event->args;i++)
|
for (int i=0;i<event->args;i++)
|
||||||
args[i].~Variant();
|
args[i].~Variant();
|
||||||
event->~Event();
|
event->~Event();
|
||||||
|
|
||||||
read_pos+=sizeof(Event)+sizeof(Variant)*event->args;
|
read_pos+=sizeof(Event)+sizeof(Variant)*event->args;
|
||||||
}
|
}
|
||||||
|
|
||||||
memdelete_arr(event_buffer);
|
memdelete_arr(event_buffer);
|
||||||
event_buffer=NULL;
|
event_buffer=NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,18 +36,18 @@
|
||||||
class EventQueue {
|
class EventQueue {
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
|
||||||
DEFAULT_EVENT_QUEUE_SIZE_KB=256
|
DEFAULT_EVENT_QUEUE_SIZE_KB=256
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Event {
|
struct Event {
|
||||||
|
|
||||||
uint32_t instance_ID;
|
uint32_t instance_ID;
|
||||||
StringName method;
|
StringName method;
|
||||||
int args;
|
int args;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
uint8_t *event_buffer;
|
uint8_t *event_buffer;
|
||||||
uint32_t buffer_end;
|
uint32_t buffer_end;
|
||||||
uint32_t buffer_max_used;
|
uint32_t buffer_max_used;
|
||||||
|
@ -57,7 +57,7 @@ public:
|
||||||
|
|
||||||
Error push_call(uint32_t p_instance_ID, const StringName& p_method, VARIANT_ARG_LIST);
|
Error push_call(uint32_t p_instance_ID, const StringName& p_method, VARIANT_ARG_LIST);
|
||||||
void flush_events();
|
void flush_events();
|
||||||
|
|
||||||
EventQueue(uint32_t p_buffer_size=DEFAULT_EVENT_QUEUE_SIZE_KB*1024);
|
EventQueue(uint32_t p_buffer_size=DEFAULT_EVENT_QUEUE_SIZE_KB*1024);
|
||||||
~EventQueue();
|
~EventQueue();
|
||||||
|
|
||||||
|
|
|
@ -474,7 +474,6 @@ static _GlobalConstant _global_constants[]={
|
||||||
BIND_GLOBAL_CONSTANT( PROPERTY_HINT_IMAGE_COMPRESS_LOSSLESS ),
|
BIND_GLOBAL_CONSTANT( PROPERTY_HINT_IMAGE_COMPRESS_LOSSLESS ),
|
||||||
|
|
||||||
|
|
||||||
BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_STORAGE ),
|
|
||||||
BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_STORAGE ),
|
BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_STORAGE ),
|
||||||
BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_EDITOR ),
|
BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_EDITOR ),
|
||||||
BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_NETWORK ),
|
BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_NETWORK ),
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
Globals *Globals::singleton=NULL;
|
Globals *Globals::singleton=NULL;
|
||||||
|
|
||||||
Globals *Globals::get_singleton() {
|
Globals *Globals::get_singleton() {
|
||||||
|
|
||||||
return singleton;
|
return singleton;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,7 +108,7 @@ bool Globals::is_persisting(const String& p_name) const {
|
||||||
|
|
||||||
|
|
||||||
String Globals::globalize_path(const String& p_path) const {
|
String Globals::globalize_path(const String& p_path) const {
|
||||||
|
|
||||||
if (p_path.begins_with("res://")) {
|
if (p_path.begins_with("res://")) {
|
||||||
|
|
||||||
if (resource_path != "") {
|
if (resource_path != "") {
|
||||||
|
@ -125,7 +125,7 @@ String Globals::globalize_path(const String& p_path) const {
|
||||||
bool Globals::_set(const StringName& p_name, const Variant& p_value) {
|
bool Globals::_set(const StringName& p_name, const Variant& p_value) {
|
||||||
|
|
||||||
_THREAD_SAFE_METHOD_
|
_THREAD_SAFE_METHOD_
|
||||||
|
|
||||||
if (p_value.get_type()==Variant::NIL)
|
if (p_value.get_type()==Variant::NIL)
|
||||||
props.erase(p_name);
|
props.erase(p_name);
|
||||||
else {
|
else {
|
||||||
|
@ -174,7 +174,7 @@ bool Globals::_get(const StringName& p_name,Variant &r_ret) const {
|
||||||
return false;
|
return false;
|
||||||
r_ret=props[p_name].variant;
|
r_ret=props[p_name].variant;
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct _VCSort {
|
struct _VCSort {
|
||||||
|
@ -188,13 +188,13 @@ struct _VCSort {
|
||||||
};
|
};
|
||||||
|
|
||||||
void Globals::_get_property_list(List<PropertyInfo> *p_list) const {
|
void Globals::_get_property_list(List<PropertyInfo> *p_list) const {
|
||||||
|
|
||||||
_THREAD_SAFE_METHOD_
|
_THREAD_SAFE_METHOD_
|
||||||
|
|
||||||
Set<_VCSort> vclist;
|
Set<_VCSort> vclist;
|
||||||
|
|
||||||
for(Map<StringName,VariantContainer>::Element *E=props.front();E;E=E->next()) {
|
for(Map<StringName,VariantContainer>::Element *E=props.front();E;E=E->next()) {
|
||||||
|
|
||||||
const VariantContainer *v=&E->get();
|
const VariantContainer *v=&E->get();
|
||||||
|
|
||||||
if (v->hide_from_editor)
|
if (v->hide_from_editor)
|
||||||
|
@ -250,7 +250,7 @@ bool Globals::_load_resource_pack(const String& p_pack) {
|
||||||
Error Globals::setup(const String& p_path,const String & p_main_pack) {
|
Error Globals::setup(const String& p_path,const String & p_main_pack) {
|
||||||
|
|
||||||
//an absolute mess of a function, must be cleaned up and reorganized somehow at some point
|
//an absolute mess of a function, must be cleaned up and reorganized somehow at some point
|
||||||
|
|
||||||
//_load_settings(p_path+"/override.cfg");
|
//_load_settings(p_path+"/override.cfg");
|
||||||
|
|
||||||
if (p_main_pack!="") {
|
if (p_main_pack!="") {
|
||||||
|
@ -292,7 +292,7 @@ Error Globals::setup(const String& p_path,const String & p_main_pack) {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (FileAccessNetworkClient::get_singleton()) {
|
if (FileAccessNetworkClient::get_singleton()) {
|
||||||
|
|
||||||
|
@ -332,7 +332,7 @@ Error Globals::setup(const String& p_path,const String & p_main_pack) {
|
||||||
resource_path = p_path;
|
resource_path = p_path;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
d->change_dir(p_path);
|
d->change_dir(p_path);
|
||||||
|
|
||||||
String candidate = d->get_current_dir();
|
String candidate = d->get_current_dir();
|
||||||
|
@ -395,7 +395,7 @@ Error Globals::setup(const String& p_path,const String & p_main_pack) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Globals::has(String p_var) const {
|
bool Globals::has(String p_var) const {
|
||||||
|
|
||||||
_THREAD_SAFE_METHOD_
|
_THREAD_SAFE_METHOD_
|
||||||
|
|
||||||
return props.has(p_var);
|
return props.has(p_var);
|
||||||
|
@ -1410,7 +1410,7 @@ void Globals::_bind_methods() {
|
||||||
}
|
}
|
||||||
|
|
||||||
Globals::Globals() {
|
Globals::Globals() {
|
||||||
|
|
||||||
|
|
||||||
singleton=this;
|
singleton=this;
|
||||||
last_order=0;
|
last_order=0;
|
||||||
|
@ -1531,7 +1531,7 @@ Globals::Globals() {
|
||||||
|
|
||||||
|
|
||||||
Globals::~Globals() {
|
Globals::~Globals() {
|
||||||
|
|
||||||
singleton=NULL;
|
singleton=NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
|
|
||||||
|
|
||||||
class Globals : public Object {
|
class Globals : public Object {
|
||||||
|
|
||||||
OBJ_TYPE( Globals, Object );
|
OBJ_TYPE( Globals, Object );
|
||||||
_THREAD_SAFE_CLASS_
|
_THREAD_SAFE_CLASS_
|
||||||
|
|
||||||
|
@ -77,13 +77,13 @@ protected:
|
||||||
bool using_datapack;
|
bool using_datapack;
|
||||||
List<String> input_presets;
|
List<String> input_presets;
|
||||||
|
|
||||||
|
|
||||||
bool _set(const StringName& p_name, const Variant& p_value);
|
bool _set(const StringName& p_name, const Variant& p_value);
|
||||||
bool _get(const StringName& p_name,Variant &r_ret) const;
|
bool _get(const StringName& p_name,Variant &r_ret) const;
|
||||||
void _get_property_list(List<PropertyInfo> *p_list) const;
|
void _get_property_list(List<PropertyInfo> *p_list) const;
|
||||||
|
|
||||||
static Globals *singleton;
|
static Globals *singleton;
|
||||||
|
|
||||||
Error _load_settings(const String p_path);
|
Error _load_settings(const String p_path);
|
||||||
Error _load_settings_binary(const String p_path);
|
Error _load_settings_binary(const String p_path);
|
||||||
|
|
||||||
|
@ -101,7 +101,7 @@ protected:
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
||||||
bool has(String p_var) const;
|
bool has(String p_var) const;
|
||||||
String localize_path(const String& p_path) const;
|
String localize_path(const String& p_path) const;
|
||||||
String globalize_path(const String& p_path) const;
|
String globalize_path(const String& p_path) const;
|
||||||
|
@ -110,13 +110,13 @@ public:
|
||||||
bool is_persisting(const String& p_name) const;
|
bool is_persisting(const String& p_name) const;
|
||||||
|
|
||||||
String get_resource_path() const;
|
String get_resource_path() const;
|
||||||
|
|
||||||
static Globals *get_singleton();
|
static Globals *get_singleton();
|
||||||
|
|
||||||
void clear(const String& p_name);
|
void clear(const String& p_name);
|
||||||
int get_order(const String& p_name) const;
|
int get_order(const String& p_name) const;
|
||||||
void set_order(const String& p_name, int p_order);
|
void set_order(const String& p_name, int p_order);
|
||||||
|
|
||||||
Error setup(const String& p_path, const String &p_main_pack);
|
Error setup(const String& p_path, const String &p_main_pack);
|
||||||
|
|
||||||
Error save_custom(const String& p_path="",const CustomMap& p_custom=CustomMap(),const Set<String>& p_ignore_masks=Set<String>());
|
Error save_custom(const String& p_path="",const CustomMap& p_custom=CustomMap(),const Set<String>& p_ignore_masks=Set<String>());
|
||||||
|
@ -141,7 +141,7 @@ public:
|
||||||
|
|
||||||
void set_registering_order(bool p_registering);
|
void set_registering_order(bool p_registering);
|
||||||
|
|
||||||
Globals();
|
Globals();
|
||||||
~Globals();
|
~Globals();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
330
core/hash_map.h
330
core/hash_map.h
|
@ -38,7 +38,7 @@
|
||||||
|
|
||||||
class HashMapHahserDefault {
|
class HashMapHahserDefault {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
static _FORCE_INLINE_ uint32_t hash(const String &p_string) { return p_string.hash(); }
|
static _FORCE_INLINE_ uint32_t hash(const String &p_string) { return p_string.hash(); }
|
||||||
static _FORCE_INLINE_ uint32_t hash(const char *p_cstr) { return hash_djb2(p_cstr); }
|
static _FORCE_INLINE_ uint32_t hash(const char *p_cstr) { return hash_djb2(p_cstr); }
|
||||||
static _FORCE_INLINE_ uint32_t hash(const uint64_t p_int) {
|
static _FORCE_INLINE_ uint32_t hash(const uint64_t p_int) {
|
||||||
|
@ -66,8 +66,8 @@ public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @class HashMap
|
* @class HashMap
|
||||||
* @author Juan Linietsky <reduzio@gmail.com>
|
* @author Juan Linietsky <reduzio@gmail.com>
|
||||||
*
|
*
|
||||||
* Implementation of a standard Hashing HashMap, for quick lookups of Data associated with a Key.
|
* Implementation of a standard Hashing HashMap, for quick lookups of Data associated with a Key.
|
||||||
* The implementation provides hashers for the default types, if you need a special kind of hasher, provide
|
* The implementation provides hashers for the default types, if you need a special kind of hasher, provide
|
||||||
* your own.
|
* your own.
|
||||||
|
@ -77,213 +77,213 @@ public:
|
||||||
* @param MIN_HASH_TABLE_POWER Miminum size of the hash table, as a power of two. You rarely need to change this parameter.
|
* @param MIN_HASH_TABLE_POWER Miminum size of the hash table, as a power of two. You rarely need to change this parameter.
|
||||||
* @param RELATIONSHIP Relationship at which the hash table is resized. if amount of elements is RELATIONSHIP
|
* @param RELATIONSHIP Relationship at which the hash table is resized. if amount of elements is RELATIONSHIP
|
||||||
* times bigger than the hash table, table is resized to solve this condition. if RELATIONSHIP is zero, table is always MIN_HASH_TABLE_POWER.
|
* times bigger than the hash table, table is resized to solve this condition. if RELATIONSHIP is zero, table is always MIN_HASH_TABLE_POWER.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
template<class TKey, class TData, class Hasher=HashMapHahserDefault,uint8_t MIN_HASH_TABLE_POWER=3,uint8_t RELATIONSHIP=8>
|
template<class TKey, class TData, class Hasher=HashMapHahserDefault,uint8_t MIN_HASH_TABLE_POWER=3,uint8_t RELATIONSHIP=8>
|
||||||
class HashMap {
|
class HashMap {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
struct Pair {
|
struct Pair {
|
||||||
|
|
||||||
TKey key;
|
TKey key;
|
||||||
TData data;
|
TData data;
|
||||||
|
|
||||||
Pair() {}
|
Pair() {}
|
||||||
Pair(const TKey& p_key, const TData& p_data) { key=p_key; data=p_data; }
|
Pair(const TKey& p_key, const TData& p_data) { key=p_key; data=p_data; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Entry {
|
struct Entry {
|
||||||
|
|
||||||
uint32_t hash;
|
uint32_t hash;
|
||||||
Entry *next;
|
Entry *next;
|
||||||
Pair pair;
|
Pair pair;
|
||||||
|
|
||||||
Entry() { next=0; }
|
Entry() { next=0; }
|
||||||
};
|
};
|
||||||
|
|
||||||
Entry **hash_table;
|
Entry **hash_table;
|
||||||
uint8_t hash_table_power;
|
uint8_t hash_table_power;
|
||||||
uint32_t elements;
|
uint32_t elements;
|
||||||
|
|
||||||
void make_hash_table() {
|
void make_hash_table() {
|
||||||
|
|
||||||
ERR_FAIL_COND( hash_table );
|
ERR_FAIL_COND( hash_table );
|
||||||
|
|
||||||
|
|
||||||
hash_table = memnew_arr( Entry*, (1<<MIN_HASH_TABLE_POWER) );
|
hash_table = memnew_arr( Entry*, (1<<MIN_HASH_TABLE_POWER) );
|
||||||
|
|
||||||
hash_table_power = MIN_HASH_TABLE_POWER;
|
hash_table_power = MIN_HASH_TABLE_POWER;
|
||||||
elements=0;
|
elements=0;
|
||||||
for (int i=0;i<(1<<MIN_HASH_TABLE_POWER);i++)
|
for (int i=0;i<(1<<MIN_HASH_TABLE_POWER);i++)
|
||||||
hash_table[i]=0;
|
hash_table[i]=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void erase_hash_table() {
|
void erase_hash_table() {
|
||||||
|
|
||||||
ERR_FAIL_COND(elements);
|
ERR_FAIL_COND(elements);
|
||||||
|
|
||||||
memdelete_arr( hash_table );
|
memdelete_arr( hash_table );
|
||||||
hash_table=0;
|
hash_table=0;
|
||||||
hash_table_power=0;
|
hash_table_power=0;
|
||||||
elements=0;
|
elements=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void check_hash_table() {
|
void check_hash_table() {
|
||||||
|
|
||||||
int new_hash_table_power=-1;
|
int new_hash_table_power=-1;
|
||||||
|
|
||||||
if ((int)elements > ( (1<<hash_table_power) * RELATIONSHIP ) ) {
|
if ((int)elements > ( (1<<hash_table_power) * RELATIONSHIP ) ) {
|
||||||
/* rehash up */
|
/* rehash up */
|
||||||
new_hash_table_power=hash_table_power+1;
|
new_hash_table_power=hash_table_power+1;
|
||||||
|
|
||||||
while( (int)elements > ( (1<<new_hash_table_power) * RELATIONSHIP ) ) {
|
while( (int)elements > ( (1<<new_hash_table_power) * RELATIONSHIP ) ) {
|
||||||
|
|
||||||
new_hash_table_power++;
|
new_hash_table_power++;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if ( (hash_table_power>(int)MIN_HASH_TABLE_POWER) && ((int)elements < ( (1<<(hash_table_power-1)) * RELATIONSHIP ) ) ) {
|
} else if ( (hash_table_power>(int)MIN_HASH_TABLE_POWER) && ((int)elements < ( (1<<(hash_table_power-1)) * RELATIONSHIP ) ) ) {
|
||||||
|
|
||||||
/* rehash down */
|
/* rehash down */
|
||||||
new_hash_table_power=hash_table_power-1;
|
new_hash_table_power=hash_table_power-1;
|
||||||
|
|
||||||
while( (int)elements < ( (1<<(new_hash_table_power-1)) * RELATIONSHIP ) ) {
|
while( (int)elements < ( (1<<(new_hash_table_power-1)) * RELATIONSHIP ) ) {
|
||||||
|
|
||||||
new_hash_table_power--;
|
new_hash_table_power--;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (new_hash_table_power<(int)MIN_HASH_TABLE_POWER)
|
if (new_hash_table_power<(int)MIN_HASH_TABLE_POWER)
|
||||||
new_hash_table_power=MIN_HASH_TABLE_POWER;
|
new_hash_table_power=MIN_HASH_TABLE_POWER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (new_hash_table_power==-1)
|
if (new_hash_table_power==-1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Entry ** new_hash_table = memnew_arr( Entry*, (1<<new_hash_table_power) );
|
Entry ** new_hash_table = memnew_arr( Entry*, (1<<new_hash_table_power) );
|
||||||
if (!new_hash_table) {
|
if (!new_hash_table) {
|
||||||
|
|
||||||
ERR_PRINT("Out of Memory");
|
ERR_PRINT("Out of Memory");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i=0;i<(1<<new_hash_table_power);i++) {
|
for (int i=0;i<(1<<new_hash_table_power);i++) {
|
||||||
|
|
||||||
new_hash_table[i]=0;
|
new_hash_table[i]=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i=0;i<(1<<hash_table_power);i++) {
|
for (int i=0;i<(1<<hash_table_power);i++) {
|
||||||
|
|
||||||
while( hash_table[i] ) {
|
while( hash_table[i] ) {
|
||||||
|
|
||||||
Entry *se=hash_table[i];
|
Entry *se=hash_table[i];
|
||||||
hash_table[i]=se->next;
|
hash_table[i]=se->next;
|
||||||
int new_pos = se->hash & ((1<<new_hash_table_power)-1);
|
int new_pos = se->hash & ((1<<new_hash_table_power)-1);
|
||||||
se->next=new_hash_table[new_pos];
|
se->next=new_hash_table[new_pos];
|
||||||
new_hash_table[new_pos]=se;
|
new_hash_table[new_pos]=se;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hash_table)
|
if (hash_table)
|
||||||
memdelete_arr( hash_table );
|
memdelete_arr( hash_table );
|
||||||
hash_table=new_hash_table;
|
hash_table=new_hash_table;
|
||||||
hash_table_power=new_hash_table_power;
|
hash_table_power=new_hash_table_power;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* I want to have only one function.. */
|
/* I want to have only one function.. */
|
||||||
_FORCE_INLINE_ const Entry * get_entry( const TKey& p_key ) const {
|
_FORCE_INLINE_ const Entry * get_entry( const TKey& p_key ) const {
|
||||||
|
|
||||||
uint32_t hash = Hasher::hash( p_key );
|
uint32_t hash = Hasher::hash( p_key );
|
||||||
uint32_t index = hash&((1<<hash_table_power)-1);
|
uint32_t index = hash&((1<<hash_table_power)-1);
|
||||||
|
|
||||||
Entry *e = hash_table[index];
|
Entry *e = hash_table[index];
|
||||||
|
|
||||||
while (e) {
|
while (e) {
|
||||||
|
|
||||||
/* checking hash first avoids comparing key, which may take longer */
|
/* checking hash first avoids comparing key, which may take longer */
|
||||||
if (e->hash == hash && e->pair.key == p_key ) {
|
if (e->hash == hash && e->pair.key == p_key ) {
|
||||||
|
|
||||||
/* the pair exists in this hashtable, so just update data */
|
/* the pair exists in this hashtable, so just update data */
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
e=e->next;
|
e=e->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Entry * create_entry(const TKey& p_key) {
|
Entry * create_entry(const TKey& p_key) {
|
||||||
|
|
||||||
/* if entry doesn't exist, create it */
|
/* if entry doesn't exist, create it */
|
||||||
Entry *e = memnew( Entry );
|
Entry *e = memnew( Entry );
|
||||||
ERR_FAIL_COND_V(!e,NULL); /* out of memory */
|
ERR_FAIL_COND_V(!e,NULL); /* out of memory */
|
||||||
uint32_t hash = Hasher::hash( p_key );
|
uint32_t hash = Hasher::hash( p_key );
|
||||||
uint32_t index = hash&((1<<hash_table_power)-1);
|
uint32_t index = hash&((1<<hash_table_power)-1);
|
||||||
e->next = hash_table[index];
|
e->next = hash_table[index];
|
||||||
e->hash = hash;
|
e->hash = hash;
|
||||||
e->pair.key=p_key;
|
e->pair.key=p_key;
|
||||||
|
|
||||||
hash_table[index]=e;
|
hash_table[index]=e;
|
||||||
elements++;
|
elements++;
|
||||||
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void copy_from(const HashMap& p_t) {
|
void copy_from(const HashMap& p_t) {
|
||||||
|
|
||||||
if (&p_t==this)
|
if (&p_t==this)
|
||||||
return; /* much less bother with that */
|
return; /* much less bother with that */
|
||||||
|
|
||||||
clear();
|
clear();
|
||||||
|
|
||||||
if (!p_t.hash_table || p_t.hash_table_power==0)
|
if (!p_t.hash_table || p_t.hash_table_power==0)
|
||||||
return; /* not copying from empty table */
|
return; /* not copying from empty table */
|
||||||
|
|
||||||
hash_table = memnew_arr(Entry*,1<<p_t.hash_table_power);
|
hash_table = memnew_arr(Entry*,1<<p_t.hash_table_power);
|
||||||
hash_table_power=p_t.hash_table_power;
|
hash_table_power=p_t.hash_table_power;
|
||||||
elements=p_t.elements;
|
elements=p_t.elements;
|
||||||
|
|
||||||
for (int i=0;i<( 1<<p_t.hash_table_power );i++) {
|
for (int i=0;i<( 1<<p_t.hash_table_power );i++) {
|
||||||
|
|
||||||
hash_table[i]=NULL;
|
hash_table[i]=NULL;
|
||||||
/* elements will be in the reverse order, but it doesn't matter */
|
/* elements will be in the reverse order, but it doesn't matter */
|
||||||
|
|
||||||
const Entry *e = p_t.hash_table[i];
|
const Entry *e = p_t.hash_table[i];
|
||||||
|
|
||||||
while(e) {
|
while(e) {
|
||||||
|
|
||||||
Entry *le = memnew( Entry ); /* local entry */
|
Entry *le = memnew( Entry ); /* local entry */
|
||||||
|
|
||||||
*le=*e; /* copy data */
|
*le=*e; /* copy data */
|
||||||
|
|
||||||
/* add to list and reassign pointers */
|
/* add to list and reassign pointers */
|
||||||
le->next=hash_table[i];
|
le->next=hash_table[i];
|
||||||
hash_table[i]=le;
|
hash_table[i]=le;
|
||||||
|
|
||||||
e=e->next;
|
e=e->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
||||||
void set( const TKey& p_key, const TData& p_data ) {
|
void set( const TKey& p_key, const TData& p_data ) {
|
||||||
|
|
||||||
set( Pair( p_key, p_data ) );
|
set( Pair( p_key, p_data ) );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void set( const Pair& p_pair ) {
|
void set( const Pair& p_pair ) {
|
||||||
|
|
||||||
Entry *e=NULL;
|
Entry *e=NULL;
|
||||||
|
@ -291,63 +291,63 @@ public:
|
||||||
make_hash_table(); // if no table, make one
|
make_hash_table(); // if no table, make one
|
||||||
else
|
else
|
||||||
e = const_cast<Entry*>( get_entry(p_pair.key) );
|
e = const_cast<Entry*>( get_entry(p_pair.key) );
|
||||||
|
|
||||||
/* if we made it up to here, the pair doesn't exist, create and assign */
|
/* if we made it up to here, the pair doesn't exist, create and assign */
|
||||||
|
|
||||||
if (!e) {
|
if (!e) {
|
||||||
|
|
||||||
e=create_entry(p_pair.key);
|
e=create_entry(p_pair.key);
|
||||||
if (!e)
|
if (!e)
|
||||||
return;
|
return;
|
||||||
check_hash_table(); // perform mantenience routine
|
check_hash_table(); // perform mantenience routine
|
||||||
}
|
}
|
||||||
|
|
||||||
e->pair.data = p_pair.data;
|
e->pair.data = p_pair.data;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool has( const TKey& p_key ) const {
|
bool has( const TKey& p_key ) const {
|
||||||
|
|
||||||
return getptr(p_key)!=NULL;
|
return getptr(p_key)!=NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a key from data, return a const reference.
|
* Get a key from data, return a const reference.
|
||||||
* WARNING: this doesn't check errors, use either getptr and check NULL, or check
|
* WARNING: this doesn't check errors, use either getptr and check NULL, or check
|
||||||
* first with has(key)
|
* first with has(key)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const TData& get( const TKey& p_key ) const {
|
const TData& get( const TKey& p_key ) const {
|
||||||
|
|
||||||
const TData* res = getptr(p_key);
|
const TData* res = getptr(p_key);
|
||||||
ERR_FAIL_COND_V(!res,*res);
|
ERR_FAIL_COND_V(!res,*res);
|
||||||
return *res;
|
return *res;
|
||||||
}
|
}
|
||||||
|
|
||||||
TData& get( const TKey& p_key ) {
|
TData& get( const TKey& p_key ) {
|
||||||
|
|
||||||
TData* res = getptr(p_key);
|
TData* res = getptr(p_key);
|
||||||
ERR_FAIL_COND_V(!res,*res);
|
ERR_FAIL_COND_V(!res,*res);
|
||||||
return *res;
|
return *res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Same as get, except it can return NULL when item was not found.
|
* Same as get, except it can return NULL when item was not found.
|
||||||
* This is mainly used for speed purposes.
|
* This is mainly used for speed purposes.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
_FORCE_INLINE_ TData* getptr( const TKey& p_key ) {
|
_FORCE_INLINE_ TData* getptr( const TKey& p_key ) {
|
||||||
|
|
||||||
if (!hash_table)
|
if (!hash_table)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
Entry *e=const_cast<Entry*>(get_entry(p_key ));
|
Entry *e=const_cast<Entry*>(get_entry(p_key ));
|
||||||
|
|
||||||
if (e)
|
if (e)
|
||||||
return &e->pair.data;
|
return &e->pair.data;
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -427,108 +427,108 @@ public:
|
||||||
/**
|
/**
|
||||||
* Erase an item, return true if erasing was succesful
|
* Erase an item, return true if erasing was succesful
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool erase( const TKey& p_key ) {
|
bool erase( const TKey& p_key ) {
|
||||||
|
|
||||||
if (!hash_table)
|
if (!hash_table)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
uint32_t hash = Hasher::hash( p_key );
|
uint32_t hash = Hasher::hash( p_key );
|
||||||
uint32_t index = hash&((1<<hash_table_power)-1);
|
uint32_t index = hash&((1<<hash_table_power)-1);
|
||||||
|
|
||||||
|
|
||||||
Entry *e = hash_table[index];
|
Entry *e = hash_table[index];
|
||||||
Entry *p=NULL;
|
Entry *p=NULL;
|
||||||
while (e) {
|
while (e) {
|
||||||
|
|
||||||
/* checking hash first avoids comparing key, which may take longer */
|
/* checking hash first avoids comparing key, which may take longer */
|
||||||
if (e->hash == hash && e->pair.key == p_key ) {
|
if (e->hash == hash && e->pair.key == p_key ) {
|
||||||
|
|
||||||
if (p) {
|
if (p) {
|
||||||
|
|
||||||
p->next=e->next;
|
p->next=e->next;
|
||||||
} else {
|
} else {
|
||||||
//begin of list
|
//begin of list
|
||||||
hash_table[index]=e->next;
|
hash_table[index]=e->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
memdelete(e);
|
memdelete(e);
|
||||||
elements--;
|
elements--;
|
||||||
|
|
||||||
if (elements==0)
|
if (elements==0)
|
||||||
erase_hash_table();
|
erase_hash_table();
|
||||||
else
|
else
|
||||||
check_hash_table();
|
check_hash_table();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
p=e;
|
p=e;
|
||||||
e=e->next;
|
e=e->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const TData& operator[](const TKey& p_key) const { //constref
|
inline const TData& operator[](const TKey& p_key) const { //constref
|
||||||
|
|
||||||
return get(p_key);
|
return get(p_key);
|
||||||
}
|
}
|
||||||
inline TData& operator[](const TKey& p_key ) { //assignment
|
inline TData& operator[](const TKey& p_key ) { //assignment
|
||||||
|
|
||||||
Entry *e=NULL;
|
Entry *e=NULL;
|
||||||
if (!hash_table)
|
if (!hash_table)
|
||||||
make_hash_table(); // if no table, make one
|
make_hash_table(); // if no table, make one
|
||||||
else
|
else
|
||||||
e = const_cast<Entry*>( get_entry(p_key) );
|
e = const_cast<Entry*>( get_entry(p_key) );
|
||||||
|
|
||||||
/* if we made it up to here, the pair doesn't exist, create */
|
/* if we made it up to here, the pair doesn't exist, create */
|
||||||
if (!e) {
|
if (!e) {
|
||||||
|
|
||||||
e=create_entry(p_key);
|
e=create_entry(p_key);
|
||||||
if (!e)
|
if (!e)
|
||||||
return *(TData*)NULL; /* panic! */
|
return *(TData*)NULL; /* panic! */
|
||||||
check_hash_table(); // perform mantenience routine
|
check_hash_table(); // perform mantenience routine
|
||||||
}
|
}
|
||||||
|
|
||||||
return e->pair.data;
|
return e->pair.data;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the next key to p_key, and the first key if p_key is null.
|
* Get the next key to p_key, and the first key if p_key is null.
|
||||||
* Returns a pointer to the next key if found, NULL otherwise.
|
* Returns a pointer to the next key if found, NULL otherwise.
|
||||||
* Adding/Removing elements while iterating will, of course, have unexpected results, don't do it.
|
* Adding/Removing elements while iterating will, of course, have unexpected results, don't do it.
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
*
|
*
|
||||||
* const TKey *k=NULL;
|
* const TKey *k=NULL;
|
||||||
*
|
*
|
||||||
* while( (k=table.next(k)) ) {
|
* while( (k=table.next(k)) ) {
|
||||||
*
|
*
|
||||||
* print( *k );
|
* print( *k );
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
const TKey* next(const TKey* p_key) const {
|
const TKey* next(const TKey* p_key) const {
|
||||||
|
|
||||||
if (!hash_table) return NULL;
|
if (!hash_table) return NULL;
|
||||||
|
|
||||||
if (!p_key) { /* get the first key */
|
if (!p_key) { /* get the first key */
|
||||||
|
|
||||||
for (int i=0;i<(1<<hash_table_power);i++) {
|
for (int i=0;i<(1<<hash_table_power);i++) {
|
||||||
|
|
||||||
if (hash_table[i]) {
|
if (hash_table[i]) {
|
||||||
return &hash_table[i]->pair.key;
|
return &hash_table[i]->pair.key;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else { /* get the next key */
|
} else { /* get the next key */
|
||||||
|
|
||||||
const Entry *e = get_entry( *p_key );
|
const Entry *e = get_entry( *p_key );
|
||||||
ERR_FAIL_COND_V( !e, NULL ); /* invalid key supplied */
|
ERR_FAIL_COND_V( !e, NULL ); /* invalid key supplied */
|
||||||
|
|
||||||
if (e->next) {
|
if (e->next) {
|
||||||
/* if there is a "next" in the list, return that */
|
/* if there is a "next" in the list, return that */
|
||||||
return &e->next->pair.key;
|
return &e->next->pair.key;
|
||||||
|
@ -537,60 +537,60 @@ public:
|
||||||
uint32_t index = e->hash&((1<<hash_table_power)-1);
|
uint32_t index = e->hash&((1<<hash_table_power)-1);
|
||||||
index++;
|
index++;
|
||||||
for (int i=index;i<(1<<hash_table_power);i++) {
|
for (int i=index;i<(1<<hash_table_power);i++) {
|
||||||
|
|
||||||
if (hash_table[i]) {
|
if (hash_table[i]) {
|
||||||
return &hash_table[i]->pair.key;
|
return &hash_table[i]->pair.key;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* nothing found, was at end */
|
/* nothing found, was at end */
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return NULL; /* nothing found */
|
return NULL; /* nothing found */
|
||||||
}
|
}
|
||||||
|
|
||||||
inline unsigned int size() const {
|
inline unsigned int size() const {
|
||||||
|
|
||||||
return elements;
|
return elements;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool empty() const {
|
inline bool empty() const {
|
||||||
|
|
||||||
return elements==0;
|
return elements==0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear() {
|
void clear() {
|
||||||
|
|
||||||
/* clean up */
|
/* clean up */
|
||||||
if (hash_table) {
|
if (hash_table) {
|
||||||
for (int i=0;i<(1<<hash_table_power);i++) {
|
for (int i=0;i<(1<<hash_table_power);i++) {
|
||||||
|
|
||||||
while (hash_table[i]) {
|
while (hash_table[i]) {
|
||||||
|
|
||||||
Entry *e=hash_table[i];
|
Entry *e=hash_table[i];
|
||||||
hash_table[i]=e->next;
|
hash_table[i]=e->next;
|
||||||
memdelete( e );
|
memdelete( e );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
memdelete_arr( hash_table );
|
memdelete_arr( hash_table );
|
||||||
}
|
}
|
||||||
|
|
||||||
hash_table=0;
|
hash_table=0;
|
||||||
hash_table_power=0;
|
hash_table_power=0;
|
||||||
elements=0;
|
elements=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void operator=(const HashMap& p_table) {
|
void operator=(const HashMap& p_table) {
|
||||||
|
|
||||||
copy_from(p_table);
|
copy_from(p_table);
|
||||||
}
|
}
|
||||||
|
|
||||||
HashMap() {
|
HashMap() {
|
||||||
hash_table=NULL;
|
hash_table=NULL;
|
||||||
elements=0;
|
elements=0;
|
||||||
hash_table_power=0;
|
hash_table_power=0;
|
||||||
|
@ -609,18 +609,18 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HashMap(const HashMap& p_table) {
|
HashMap(const HashMap& p_table) {
|
||||||
|
|
||||||
hash_table=NULL;
|
hash_table=NULL;
|
||||||
elements=0;
|
elements=0;
|
||||||
hash_table_power=0;
|
hash_table_power=0;
|
||||||
|
|
||||||
copy_from(p_table);
|
copy_from(p_table);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
~HashMap() {
|
~HashMap() {
|
||||||
|
|
||||||
clear();
|
clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,10 +47,10 @@ static inline uint32_t hash_djb2(const char *p_cstr) {
|
||||||
const unsigned char* chr=(const unsigned char*)p_cstr;
|
const unsigned char* chr=(const unsigned char*)p_cstr;
|
||||||
uint32_t hash = 5381;
|
uint32_t hash = 5381;
|
||||||
uint32_t c;
|
uint32_t c;
|
||||||
|
|
||||||
while ((c = *chr++))
|
while ((c = *chr++))
|
||||||
hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
|
hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
|
||||||
|
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ static inline uint32_t make_uint32_t(T p_in) {
|
||||||
T t;
|
T t;
|
||||||
uint32_t _u32;
|
uint32_t _u32;
|
||||||
} _u;
|
} _u;
|
||||||
_u._u32=0;
|
_u._u32=0;
|
||||||
_u.t=p_in;
|
_u.t=p_in;
|
||||||
return _u._u32;
|
return _u._u32;
|
||||||
}
|
}
|
||||||
|
@ -106,7 +106,7 @@ static inline uint64_t make_uint64_t(T p_in) {
|
||||||
uint64_t _u64;
|
uint64_t _u64;
|
||||||
} _u;
|
} _u;
|
||||||
_u._u64=0; // in case p_in is smaller
|
_u._u64=0; // in case p_in is smaller
|
||||||
|
|
||||||
_u.t=p_in;
|
_u.t=p_in;
|
||||||
return _u._u64;
|
return _u._u64;
|
||||||
}
|
}
|
||||||
|
|
199
core/image.cpp
199
core/image.cpp
|
@ -382,7 +382,7 @@ void Image::convert( Format p_new_format ){
|
||||||
|
|
||||||
|
|
||||||
Image new_img(width,height,0,p_new_format);
|
Image new_img(width,height,0,p_new_format);
|
||||||
|
|
||||||
int len=data.size();
|
int len=data.size();
|
||||||
|
|
||||||
DVector<uint8_t>::Read r = data.read();
|
DVector<uint8_t>::Read r = data.read();
|
||||||
|
@ -413,7 +413,7 @@ void Image::convert( Format p_new_format ){
|
||||||
w = DVector<uint8_t>::Write();
|
w = DVector<uint8_t>::Write();
|
||||||
|
|
||||||
bool gen_mipmaps=mipmaps>0;
|
bool gen_mipmaps=mipmaps>0;
|
||||||
|
|
||||||
*this=new_img;
|
*this=new_img;
|
||||||
|
|
||||||
if (gen_mipmaps)
|
if (gen_mipmaps)
|
||||||
|
@ -643,13 +643,13 @@ void Image::resize( int p_width, int p_height, Interpolation p_interpolation ) {
|
||||||
ERR_FAIL_COND(p_height<=0);
|
ERR_FAIL_COND(p_height<=0);
|
||||||
ERR_FAIL_COND(p_width>MAX_WIDTH);
|
ERR_FAIL_COND(p_width>MAX_WIDTH);
|
||||||
ERR_FAIL_COND(p_height>MAX_HEIGHT);
|
ERR_FAIL_COND(p_height>MAX_HEIGHT);
|
||||||
|
|
||||||
|
|
||||||
if (p_width==width && p_height==height)
|
if (p_width==width && p_height==height)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Image dst( p_width, p_height, 0, format );
|
Image dst( p_width, p_height, 0, format );
|
||||||
|
|
||||||
if (format==FORMAT_INDEXED)
|
if (format==FORMAT_INDEXED)
|
||||||
p_interpolation=INTERPOLATE_NEAREST;
|
p_interpolation=INTERPOLATE_NEAREST;
|
||||||
|
|
||||||
|
@ -714,34 +714,34 @@ void Image::crop( int p_width, int p_height ) {
|
||||||
ERR_FAIL_COND(p_height<=0);
|
ERR_FAIL_COND(p_height<=0);
|
||||||
ERR_FAIL_COND(p_width>MAX_WIDTH);
|
ERR_FAIL_COND(p_width>MAX_WIDTH);
|
||||||
ERR_FAIL_COND(p_height>MAX_HEIGHT);
|
ERR_FAIL_COND(p_height>MAX_HEIGHT);
|
||||||
|
|
||||||
/* to save memory, cropping should be done in-place, however, since this function
|
/* to save memory, cropping should be done in-place, however, since this function
|
||||||
will most likely either not be used much, or in critical areas, for now it wont, because
|
will most likely either not be used much, or in critical areas, for now it wont, because
|
||||||
it's a waste of time. */
|
it's a waste of time. */
|
||||||
|
|
||||||
if (p_width==width && p_height==height)
|
if (p_width==width && p_height==height)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Image dst( p_width, p_height,0, format );
|
Image dst( p_width, p_height,0, format );
|
||||||
|
|
||||||
|
|
||||||
for (int y=0;y<p_height;y++) {
|
for (int y=0;y<p_height;y++) {
|
||||||
|
|
||||||
for (int x=0;x<p_width;x++) {
|
for (int x=0;x<p_width;x++) {
|
||||||
|
|
||||||
Color col = (x>=width || y>=height)? Color() : get_pixel(x,y);
|
Color col = (x>=width || y>=height)? Color() : get_pixel(x,y);
|
||||||
dst.put_pixel(x,y,col);
|
dst.put_pixel(x,y,col);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mipmaps>0)
|
if (mipmaps>0)
|
||||||
dst.generate_mipmaps();
|
dst.generate_mipmaps();
|
||||||
*this=dst;
|
*this=dst;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Image::flip_y() {
|
void Image::flip_y() {
|
||||||
|
|
||||||
if (!_can_modify(format)) {
|
if (!_can_modify(format)) {
|
||||||
ERR_EXPLAIN("Cannot flip_y in indexed, compressed or custom image formats.");
|
ERR_EXPLAIN("Cannot flip_y in indexed, compressed or custom image formats.");
|
||||||
ERR_FAIL();
|
ERR_FAIL();
|
||||||
|
@ -756,12 +756,12 @@ void Image::flip_y() {
|
||||||
|
|
||||||
|
|
||||||
for (int y=0;y<(height/2);y++) {
|
for (int y=0;y<(height/2);y++) {
|
||||||
|
|
||||||
for (int x=0;x<width;x++) {
|
for (int x=0;x<width;x++) {
|
||||||
|
|
||||||
Color up = get_pixel(x,y);
|
Color up = get_pixel(x,y);
|
||||||
Color down = get_pixel(x,height-y-1);
|
Color down = get_pixel(x,height-y-1);
|
||||||
|
|
||||||
put_pixel(x,y,down);
|
put_pixel(x,y,down);
|
||||||
put_pixel(x,height-y-1,up);
|
put_pixel(x,height-y-1,up);
|
||||||
}
|
}
|
||||||
|
@ -783,12 +783,12 @@ void Image::flip_x() {
|
||||||
clear_mipmaps();;
|
clear_mipmaps();;
|
||||||
|
|
||||||
for (int y=0;y<(height/2);y++) {
|
for (int y=0;y<(height/2);y++) {
|
||||||
|
|
||||||
for (int x=0;x<width;x++) {
|
for (int x=0;x<width;x++) {
|
||||||
|
|
||||||
Color up = get_pixel(x,y);
|
Color up = get_pixel(x,y);
|
||||||
Color down = get_pixel(width-x-1,y);
|
Color down = get_pixel(width-x-1,y);
|
||||||
|
|
||||||
put_pixel(x,y,down);
|
put_pixel(x,y,down);
|
||||||
put_pixel(width-x-1,y,up);
|
put_pixel(width-x-1,y,up);
|
||||||
}
|
}
|
||||||
|
@ -901,6 +901,66 @@ static void _generate_po2_mipmap(const uint8_t* p_src, uint8_t* p_dst, uint32_t
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Image::shrink_x2() {
|
||||||
|
|
||||||
|
ERR_FAIL_COND(format==FORMAT_INDEXED || format==FORMAT_INDEXED_ALPHA);
|
||||||
|
ERR_FAIL_COND( data.size()==0 );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (mipmaps) {
|
||||||
|
|
||||||
|
//just use the lower mipmap as base and copy all
|
||||||
|
DVector<uint8_t> new_img;
|
||||||
|
|
||||||
|
int ofs = get_mipmap_offset(1);
|
||||||
|
|
||||||
|
int new_size = data.size()-ofs;
|
||||||
|
new_img.resize(new_size);
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
DVector<uint8_t>::Write w=new_img.write();
|
||||||
|
DVector<uint8_t>::Read r=data.read();
|
||||||
|
|
||||||
|
copymem(w.ptr(),&r[ofs],new_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
mipmaps--;
|
||||||
|
width/=2;
|
||||||
|
height/=2;
|
||||||
|
data=new_img;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
DVector<uint8_t> new_img;
|
||||||
|
|
||||||
|
ERR_FAIL_COND( format>=FORMAT_INDEXED );
|
||||||
|
int ps = get_format_pixel_size(format);
|
||||||
|
new_img.resize((width/2)*(height/2)*ps);
|
||||||
|
|
||||||
|
{
|
||||||
|
DVector<uint8_t>::Write w=new_img.write();
|
||||||
|
DVector<uint8_t>::Read r=data.read();
|
||||||
|
|
||||||
|
switch(format) {
|
||||||
|
|
||||||
|
case FORMAT_GRAYSCALE:
|
||||||
|
case FORMAT_INTENSITY: _generate_po2_mipmap<1>(r.ptr(), w.ptr(), width,height); break;
|
||||||
|
case FORMAT_GRAYSCALE_ALPHA: _generate_po2_mipmap<2>(r.ptr(), w.ptr(), width,height); break;
|
||||||
|
case FORMAT_RGB: _generate_po2_mipmap<3>(r.ptr(), w.ptr(), width,height); break;
|
||||||
|
case FORMAT_RGBA: _generate_po2_mipmap<4>(r.ptr(), w.ptr(), width,height); break;
|
||||||
|
default: {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
width/=2;
|
||||||
|
height/=2;
|
||||||
|
data=new_img;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Error Image::generate_mipmaps(int p_mipmaps,bool p_keep_existing) {
|
Error Image::generate_mipmaps(int p_mipmaps,bool p_keep_existing) {
|
||||||
|
|
||||||
if (!_can_modify(format)) {
|
if (!_can_modify(format)) {
|
||||||
|
@ -1040,26 +1100,26 @@ void Image::make_normalmap(float p_height_scale) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ERR_FAIL_COND( empty() );
|
ERR_FAIL_COND( empty() );
|
||||||
|
|
||||||
Image normalmap(width,height,0, FORMAT_RGB);
|
Image normalmap(width,height,0, FORMAT_RGB);
|
||||||
/*
|
/*
|
||||||
for (int y=0;y<height;y++) {
|
for (int y=0;y<height;y++) {
|
||||||
for (int x=0;x<width;x++) {
|
for (int x=0;x<width;x++) {
|
||||||
|
|
||||||
float center=get_pixel(x,y).gray()/255.0;
|
float center=get_pixel(x,y).gray()/255.0;
|
||||||
float up=(y>0)?get_pixel(x,y-1).gray()/255.0:center;
|
float up=(y>0)?get_pixel(x,y-1).gray()/255.0:center;
|
||||||
float down=(y<(height-1))?get_pixel(x,y+1).gray()/255.0:center;
|
float down=(y<(height-1))?get_pixel(x,y+1).gray()/255.0:center;
|
||||||
float left=(x>0)?get_pixel(x-1,y).gray()/255.0:center;
|
float left=(x>0)?get_pixel(x-1,y).gray()/255.0:center;
|
||||||
float right=(x<(width-1))?get_pixel(x+1,y).gray()/255.0:center;
|
float right=(x<(width-1))?get_pixel(x+1,y).gray()/255.0:center;
|
||||||
|
|
||||||
|
|
||||||
// uhm, how do i do this? ....
|
// uhm, how do i do this? ....
|
||||||
|
|
||||||
Color result( (uint8_t)((normal.x+1.0)*127.0), (uint8_t)((normal.y+1.0)*127.0), (uint8_t)((normal.z+1.0)*127.0) );
|
Color result( (uint8_t)((normal.x+1.0)*127.0), (uint8_t)((normal.y+1.0)*127.0), (uint8_t)((normal.z+1.0)*127.0) );
|
||||||
|
|
||||||
normalmap.put_pixel( x, y, result );
|
normalmap.put_pixel( x, y, result );
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
*this=normalmap;
|
*this=normalmap;
|
||||||
|
@ -1071,14 +1131,14 @@ bool Image::empty() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
DVector<uint8_t> Image::get_data() const {
|
DVector<uint8_t> Image::get_data() const {
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Image::create(int p_width, int p_height, bool p_use_mipmaps,Format p_format) {
|
void Image::create(int p_width, int p_height, bool p_use_mipmaps,Format p_format) {
|
||||||
|
|
||||||
|
|
||||||
int mm=0;
|
int mm=0;
|
||||||
int size = _get_dst_image_size(p_width,p_height,p_format,mm,p_use_mipmaps?-1:0);
|
int size = _get_dst_image_size(p_width,p_height,p_format,mm,p_use_mipmaps?-1:0);
|
||||||
data.resize( size );
|
data.resize( size );
|
||||||
{
|
{
|
||||||
|
@ -1095,7 +1155,7 @@ void Image::create(int p_width, int p_height, bool p_use_mipmaps,Format p_format
|
||||||
}
|
}
|
||||||
|
|
||||||
void Image::create(int p_width, int p_height, int p_mipmaps, Format p_format, const DVector<uint8_t>& p_data) {
|
void Image::create(int p_width, int p_height, int p_mipmaps, Format p_format, const DVector<uint8_t>& p_data) {
|
||||||
|
|
||||||
ERR_FAIL_INDEX(p_width-1,MAX_WIDTH);
|
ERR_FAIL_INDEX(p_width-1,MAX_WIDTH);
|
||||||
ERR_FAIL_INDEX(p_height-1,MAX_HEIGHT);
|
ERR_FAIL_INDEX(p_height-1,MAX_HEIGHT);
|
||||||
|
|
||||||
|
@ -1108,48 +1168,48 @@ void Image::create(int p_width, int p_height, int p_mipmaps, Format p_format, co
|
||||||
ERR_FAIL_COND(p_data.size()!=size);
|
ERR_FAIL_COND(p_data.size()!=size);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
height=p_height;
|
height=p_height;
|
||||||
width=p_width;
|
width=p_width;
|
||||||
format=p_format;
|
format=p_format;
|
||||||
data=p_data;
|
data=p_data;
|
||||||
mipmaps=p_mipmaps;
|
mipmaps=p_mipmaps;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Image::create( const char ** p_xpm ) {
|
void Image::create( const char ** p_xpm ) {
|
||||||
|
|
||||||
|
|
||||||
int size_width,size_height;
|
int size_width,size_height;
|
||||||
int pixelchars=0;
|
int pixelchars=0;
|
||||||
mipmaps=0;
|
mipmaps=0;
|
||||||
bool has_alpha=false;
|
bool has_alpha=false;
|
||||||
|
|
||||||
enum Status {
|
enum Status {
|
||||||
READING_HEADER,
|
READING_HEADER,
|
||||||
READING_COLORS,
|
READING_COLORS,
|
||||||
READING_PIXELS,
|
READING_PIXELS,
|
||||||
DONE
|
DONE
|
||||||
};
|
};
|
||||||
|
|
||||||
Status status = READING_HEADER;
|
Status status = READING_HEADER;
|
||||||
int line=0;
|
int line=0;
|
||||||
|
|
||||||
HashMap<String,Color> colormap;
|
HashMap<String,Color> colormap;
|
||||||
int colormap_size;
|
int colormap_size;
|
||||||
|
|
||||||
while (status!=DONE) {
|
while (status!=DONE) {
|
||||||
|
|
||||||
const char * line_ptr = p_xpm[line];
|
const char * line_ptr = p_xpm[line];
|
||||||
|
|
||||||
|
|
||||||
switch (status) {
|
switch (status) {
|
||||||
|
|
||||||
case READING_HEADER: {
|
case READING_HEADER: {
|
||||||
|
|
||||||
String line_str=line_ptr;
|
String line_str=line_ptr;
|
||||||
line_str.replace("\t"," ");
|
line_str.replace("\t"," ");
|
||||||
|
|
||||||
size_width=line_str.get_slicec(' ',0).to_int();
|
size_width=line_str.get_slicec(' ',0).to_int();
|
||||||
size_height=line_str.get_slicec(' ',1).to_int();
|
size_height=line_str.get_slicec(' ',1).to_int();
|
||||||
colormap_size=line_str.get_slicec(' ',2).to_int();
|
colormap_size=line_str.get_slicec(' ',2).to_int();
|
||||||
|
@ -1161,10 +1221,10 @@ void Image::create( const char ** p_xpm ) {
|
||||||
status=READING_COLORS;
|
status=READING_COLORS;
|
||||||
} break;
|
} break;
|
||||||
case READING_COLORS: {
|
case READING_COLORS: {
|
||||||
|
|
||||||
String colorstring;
|
String colorstring;
|
||||||
for (int i=0;i<pixelchars;i++) {
|
for (int i=0;i<pixelchars;i++) {
|
||||||
|
|
||||||
colorstring+=*line_ptr;
|
colorstring+=*line_ptr;
|
||||||
line_ptr++;
|
line_ptr++;
|
||||||
}
|
}
|
||||||
|
@ -1175,25 +1235,25 @@ void Image::create( const char ** p_xpm ) {
|
||||||
line_ptr++;
|
line_ptr++;
|
||||||
}
|
}
|
||||||
if (*line_ptr=='c') {
|
if (*line_ptr=='c') {
|
||||||
|
|
||||||
line_ptr++;
|
line_ptr++;
|
||||||
while (*line_ptr==' ' || *line_ptr=='\t' || *line_ptr==0) {
|
while (*line_ptr==' ' || *line_ptr=='\t' || *line_ptr==0) {
|
||||||
if (*line_ptr==0)
|
if (*line_ptr==0)
|
||||||
break;
|
break;
|
||||||
line_ptr++;
|
line_ptr++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*line_ptr=='#') {
|
if (*line_ptr=='#') {
|
||||||
line_ptr++;
|
line_ptr++;
|
||||||
uint8_t col_r;
|
uint8_t col_r;
|
||||||
uint8_t col_g;
|
uint8_t col_g;
|
||||||
uint8_t col_b;
|
uint8_t col_b;
|
||||||
// uint8_t col_a=255;
|
// uint8_t col_a=255;
|
||||||
|
|
||||||
for (int i=0;i<6;i++) {
|
for (int i=0;i<6;i++) {
|
||||||
|
|
||||||
char v = line_ptr[i];
|
char v = line_ptr[i];
|
||||||
|
|
||||||
if (v>='0' && v<='9')
|
if (v>='0' && v<='9')
|
||||||
v-='0';
|
v-='0';
|
||||||
else if (v>='A' && v<='F')
|
else if (v>='A' && v<='F')
|
||||||
|
@ -1202,7 +1262,7 @@ void Image::create( const char ** p_xpm ) {
|
||||||
v=(v-'a')+10;
|
v=(v-'a')+10;
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
|
|
||||||
switch(i) {
|
switch(i) {
|
||||||
case 0: col_r=v<<4; break;
|
case 0: col_r=v<<4; break;
|
||||||
case 1: col_r|=v; break;
|
case 1: col_r|=v; break;
|
||||||
|
@ -1211,48 +1271,48 @@ void Image::create( const char ** p_xpm ) {
|
||||||
case 4: col_b=v<<4; break;
|
case 4: col_b=v<<4; break;
|
||||||
case 5: col_b|=v; break;
|
case 5: col_b|=v; break;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// magenta mask
|
// magenta mask
|
||||||
if (col_r==255 && col_g==0 && col_b==255) {
|
if (col_r==255 && col_g==0 && col_b==255) {
|
||||||
|
|
||||||
colormap[colorstring]=Color(0,0,0,0);
|
colormap[colorstring]=Color(0,0,0,0);
|
||||||
has_alpha=true;
|
has_alpha=true;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
colormap[colorstring]=Color(col_r/255.0,col_g/255.0,col_b/255.0,1.0);
|
colormap[colorstring]=Color(col_r/255.0,col_g/255.0,col_b/255.0,1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (line==colormap_size) {
|
if (line==colormap_size) {
|
||||||
|
|
||||||
status=READING_PIXELS;
|
status=READING_PIXELS;
|
||||||
create(size_width,size_height,0,has_alpha?FORMAT_RGBA:FORMAT_RGB);
|
create(size_width,size_height,0,has_alpha?FORMAT_RGBA:FORMAT_RGB);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case READING_PIXELS: {
|
case READING_PIXELS: {
|
||||||
|
|
||||||
int y=line-colormap_size-1;
|
int y=line-colormap_size-1;
|
||||||
for (int x=0;x<size_width;x++) {
|
for (int x=0;x<size_width;x++) {
|
||||||
|
|
||||||
char pixelstr[6]={0,0,0,0,0,0};
|
char pixelstr[6]={0,0,0,0,0,0};
|
||||||
for (int i=0;i<pixelchars;i++)
|
for (int i=0;i<pixelchars;i++)
|
||||||
pixelstr[i]=line_ptr[x*pixelchars+i];
|
pixelstr[i]=line_ptr[x*pixelchars+i];
|
||||||
|
|
||||||
Color *colorptr = colormap.getptr(pixelstr);
|
Color *colorptr = colormap.getptr(pixelstr);
|
||||||
ERR_FAIL_COND(!colorptr);
|
ERR_FAIL_COND(!colorptr);
|
||||||
put_pixel(x,y,*colorptr);
|
put_pixel(x,y,*colorptr);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (y==(size_height-1))
|
if (y==(size_height-1))
|
||||||
status=DONE;
|
status=DONE;
|
||||||
} break;
|
} break;
|
||||||
default:{}
|
default:{}
|
||||||
}
|
}
|
||||||
|
|
||||||
line++;
|
line++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1637,8 +1697,17 @@ Error Image::_decompress_bc() {
|
||||||
|
|
||||||
print_line("decompressing bc");
|
print_line("decompressing bc");
|
||||||
|
|
||||||
|
int wd=width,ht=height;
|
||||||
|
if (wd%4!=0) {
|
||||||
|
wd+=4-(wd%4);
|
||||||
|
}
|
||||||
|
if (ht%4!=0) {
|
||||||
|
ht+=4-(ht%4);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int mm;
|
int mm;
|
||||||
int size = _get_dst_image_size(width,height,FORMAT_RGBA,mm,mipmaps);
|
int size = _get_dst_image_size(wd,ht,FORMAT_RGBA,mm,mipmaps);
|
||||||
|
|
||||||
DVector<uint8_t> newdata;
|
DVector<uint8_t> newdata;
|
||||||
newdata.resize(size);
|
newdata.resize(size);
|
||||||
|
@ -1648,7 +1717,8 @@ Error Image::_decompress_bc() {
|
||||||
|
|
||||||
int rofs=0;
|
int rofs=0;
|
||||||
int wofs=0;
|
int wofs=0;
|
||||||
int wd=width,ht=height;
|
|
||||||
|
//print_line("width: "+itos(wd)+" height: "+itos(ht));
|
||||||
|
|
||||||
for(int i=0;i<=mm;i++) {
|
for(int i=0;i<=mm;i++) {
|
||||||
|
|
||||||
|
@ -1953,6 +2023,11 @@ Error Image::_decompress_bc() {
|
||||||
|
|
||||||
data=newdata;
|
data=newdata;
|
||||||
format=FORMAT_RGBA;
|
format=FORMAT_RGBA;
|
||||||
|
if (wd!=width || ht!=height) {
|
||||||
|
//todo, crop
|
||||||
|
width=wd;
|
||||||
|
height=ht;
|
||||||
|
}
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
@ -2022,7 +2097,7 @@ Image Image::compressed(int p_mode) {
|
||||||
};
|
};
|
||||||
|
|
||||||
Image::Image(const char **p_xpm) {
|
Image::Image(const char **p_xpm) {
|
||||||
|
|
||||||
width=0;
|
width=0;
|
||||||
height=0;
|
height=0;
|
||||||
mipmaps=0;
|
mipmaps=0;
|
||||||
|
|
53
core/image.h
53
core/image.h
|
@ -46,7 +46,7 @@ typedef Error (*SavePNGFunc)(const String &p_path, Image& p_img);
|
||||||
|
|
||||||
class Image {
|
class Image {
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
MAX_WIDTH=16384, // force a limit somehow
|
MAX_WIDTH=16384, // force a limit somehow
|
||||||
MAX_HEIGHT=16384// force a limit somehow
|
MAX_HEIGHT=16384// force a limit somehow
|
||||||
};
|
};
|
||||||
|
@ -55,12 +55,12 @@ public:
|
||||||
static SavePNGFunc save_png_func;
|
static SavePNGFunc save_png_func;
|
||||||
|
|
||||||
enum Format {
|
enum Format {
|
||||||
FORMAT_GRAYSCALE, ///< one byte per pixel, 0-255
|
FORMAT_GRAYSCALE, ///< one byte per pixel, 0-255
|
||||||
FORMAT_INTENSITY, ///< one byte per pixel, 0-255
|
FORMAT_INTENSITY, ///< one byte per pixel, 0-255
|
||||||
FORMAT_GRAYSCALE_ALPHA, ///< two bytes per pixel, 0-255. alpha 0-255
|
FORMAT_GRAYSCALE_ALPHA, ///< two bytes per pixel, 0-255. alpha 0-255
|
||||||
FORMAT_RGB, ///< one byte R, one byte G, one byte B
|
FORMAT_RGB, ///< one byte R, one byte G, one byte B
|
||||||
FORMAT_RGBA, ///< one byte R, one byte G, one byte B, one byte A
|
FORMAT_RGBA, ///< one byte R, one byte G, one byte B, one byte A
|
||||||
FORMAT_INDEXED, ///< index byte 0-256, and after image end, 256*3 bytes of palette
|
FORMAT_INDEXED, ///< index byte 0-256, and after image end, 256*3 bytes of palette
|
||||||
FORMAT_INDEXED_ALPHA, ///< index byte 0-256, and after image end, 256*4 bytes of palette (alpha)
|
FORMAT_INDEXED_ALPHA, ///< index byte 0-256, and after image end, 256*4 bytes of palette (alpha)
|
||||||
FORMAT_YUV_422,
|
FORMAT_YUV_422,
|
||||||
FORMAT_YUV_444,
|
FORMAT_YUV_444,
|
||||||
|
@ -89,7 +89,7 @@ public:
|
||||||
|
|
||||||
static const char* format_names[FORMAT_MAX];
|
static const char* format_names[FORMAT_MAX];
|
||||||
enum Interpolation {
|
enum Interpolation {
|
||||||
|
|
||||||
INTERPOLATE_NEAREST,
|
INTERPOLATE_NEAREST,
|
||||||
INTERPOLATE_BILINEAR,
|
INTERPOLATE_BILINEAR,
|
||||||
INTERPOLATE_CUBIC,
|
INTERPOLATE_CUBIC,
|
||||||
|
@ -186,7 +186,7 @@ private:
|
||||||
DVector<uint8_t> data;
|
DVector<uint8_t> data;
|
||||||
int width,height,mipmaps;
|
int width,height,mipmaps;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
_FORCE_INLINE_ BColor _get_pixel(int p_x,int p_y,const unsigned char *p_data,int p_data_size) const;
|
_FORCE_INLINE_ BColor _get_pixel(int p_x,int p_y,const unsigned char *p_data,int p_data_size) const;
|
||||||
_FORCE_INLINE_ BColor _get_pixelw(int p_x,int p_y,int p_width,const unsigned char *p_data,int p_data_size) const;
|
_FORCE_INLINE_ BColor _get_pixelw(int p_x,int p_y,int p_width,const unsigned char *p_data,int p_data_size) const;
|
||||||
|
@ -207,7 +207,7 @@ public:
|
||||||
int get_width() const; ///< Get image width
|
int get_width() const; ///< Get image width
|
||||||
int get_height() const; ///< Get image height
|
int get_height() const; ///< Get image height
|
||||||
int get_mipmaps() const;
|
int get_mipmaps() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a pixel from the image. for grayscale or indexed formats, use Color::gray to obtain the actual
|
* Get a pixel from the image. for grayscale or indexed formats, use Color::gray to obtain the actual
|
||||||
* value.
|
* value.
|
||||||
|
@ -217,7 +217,7 @@ public:
|
||||||
* Set a pixel into the image. for grayscale or indexed formats, a suitable Color constructor.
|
* Set a pixel into the image. for grayscale or indexed formats, a suitable Color constructor.
|
||||||
*/
|
*/
|
||||||
void put_pixel(int p_x,int p_y, const Color& p_color,int p_mipmap=0); /* alpha and index are averaged */
|
void put_pixel(int p_x,int p_y, const Color& p_color,int p_mipmap=0); /* alpha and index are averaged */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert the image to another format, as close as it can be done.
|
* Convert the image to another format, as close as it can be done.
|
||||||
*/
|
*/
|
||||||
|
@ -230,7 +230,7 @@ public:
|
||||||
ret.convert((Format)p_new_format);
|
ret.convert((Format)p_new_format);
|
||||||
return ret;
|
return ret;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the current image format.
|
* Get the current image format.
|
||||||
*/
|
*/
|
||||||
|
@ -243,31 +243,32 @@ public:
|
||||||
/**
|
/**
|
||||||
* Resize the image, using the prefered interpolation method.
|
* Resize the image, using the prefered interpolation method.
|
||||||
* Indexed-Color images always use INTERPOLATE_NEAREST.
|
* Indexed-Color images always use INTERPOLATE_NEAREST.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void resize_to_po2(bool p_square=false);
|
void resize_to_po2(bool p_square=false);
|
||||||
void resize( int p_width, int p_height, Interpolation p_interpolation=INTERPOLATE_BILINEAR );
|
void resize( int p_width, int p_height, Interpolation p_interpolation=INTERPOLATE_BILINEAR );
|
||||||
Image resized( int p_width, int p_height, int p_interpolation=INTERPOLATE_BILINEAR );
|
Image resized( int p_width, int p_height, int p_interpolation=INTERPOLATE_BILINEAR );
|
||||||
|
void shrink_x2();
|
||||||
/**
|
/**
|
||||||
* Crop the image to a specific size, if larger, then the image is filled by black
|
* Crop the image to a specific size, if larger, then the image is filled by black
|
||||||
*/
|
*/
|
||||||
void crop( int p_width, int p_height );
|
void crop( int p_width, int p_height );
|
||||||
|
|
||||||
|
|
||||||
void flip_x();
|
void flip_x();
|
||||||
void flip_y();
|
void flip_y();
|
||||||
/**
|
/**
|
||||||
* Generate a mipmap to an image (creates an image 1/4 the size, with averaging of 4->1)
|
* Generate a mipmap to an image (creates an image 1/4 the size, with averaging of 4->1)
|
||||||
*/
|
*/
|
||||||
Error generate_mipmaps(int p_amount=-1,bool p_keep_existing=false);
|
Error generate_mipmaps(int p_amount=-1,bool p_keep_existing=false);
|
||||||
|
|
||||||
void clear_mipmaps();
|
void clear_mipmaps();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate a normal map from a grayscale image
|
* Generate a normal map from a grayscale image
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void make_normalmap(float p_height_scale=1.0);
|
void make_normalmap(float p_height_scale=1.0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -276,26 +277,26 @@ public:
|
||||||
void create(int p_width, int p_height, bool p_use_mipmaps, Format p_format);
|
void create(int p_width, int p_height, bool p_use_mipmaps, Format p_format);
|
||||||
void create(int p_width, int p_height, int p_mipmaps, Format p_format, const DVector<uint8_t>& p_data);
|
void create(int p_width, int p_height, int p_mipmaps, Format p_format, const DVector<uint8_t>& p_data);
|
||||||
|
|
||||||
void create( const char ** p_xpm );
|
void create( const char ** p_xpm );
|
||||||
/**
|
/**
|
||||||
* returns true when the image is empty (0,0) in size
|
* returns true when the image is empty (0,0) in size
|
||||||
*/
|
*/
|
||||||
bool empty() const;
|
bool empty() const;
|
||||||
|
|
||||||
DVector<uint8_t> get_data() const;
|
DVector<uint8_t> get_data() const;
|
||||||
|
|
||||||
Error load(const String& p_path);
|
Error load(const String& p_path);
|
||||||
Error save_png(const String& p_path);
|
Error save_png(const String& p_path);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* create an empty image
|
* create an empty image
|
||||||
*/
|
*/
|
||||||
Image();
|
Image();
|
||||||
/**
|
/**
|
||||||
* create an empty image of a specific size and format
|
* create an empty image of a specific size and format
|
||||||
*/
|
*/
|
||||||
Image(int p_width, int p_height, bool p_use_mipmaps, Format p_format);
|
Image(int p_width, int p_height, bool p_use_mipmaps, Format p_format);
|
||||||
/**
|
/**
|
||||||
* import an image of a specific size and format from a pointer
|
* import an image of a specific size and format from a pointer
|
||||||
*/
|
*/
|
||||||
Image(int p_width, int p_height, int p_mipmaps, Format p_format, const DVector<uint8_t>& p_data);
|
Image(int p_width, int p_height, int p_mipmaps, Format p_format, const DVector<uint8_t>& p_data);
|
||||||
|
@ -313,7 +314,7 @@ public:
|
||||||
uint8_t get_indexed_pixel(int p_x, int p_y,int p_mipmap=0) const;
|
uint8_t get_indexed_pixel(int p_x, int p_y,int p_mipmap=0) const;
|
||||||
void set_pallete(const DVector<uint8_t>& p_data);
|
void set_pallete(const DVector<uint8_t>& p_data);
|
||||||
|
|
||||||
|
|
||||||
static int get_format_pixel_size(Format p_format);
|
static int get_format_pixel_size(Format p_format);
|
||||||
static int get_format_pixel_rshift(Format p_format);
|
static int get_format_pixel_rshift(Format p_format);
|
||||||
static int get_format_pallete_size(Format p_format);
|
static int get_format_pallete_size(Format p_format);
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
#include "input_map.h"
|
#include "input_map.h"
|
||||||
#include "globals.h"
|
#include "globals.h"
|
||||||
|
#include "os/keyboard.h"
|
||||||
|
|
||||||
InputMap *InputMap::singleton=NULL;
|
InputMap *InputMap::singleton=NULL;
|
||||||
|
|
||||||
|
@ -36,9 +37,10 @@ void InputMap::_bind_methods() {
|
||||||
ObjectTypeDB::bind_method(_MD("has_action","action"),&InputMap::has_action);
|
ObjectTypeDB::bind_method(_MD("has_action","action"),&InputMap::has_action);
|
||||||
ObjectTypeDB::bind_method(_MD("get_action_id","action"),&InputMap::get_action_id);
|
ObjectTypeDB::bind_method(_MD("get_action_id","action"),&InputMap::get_action_id);
|
||||||
ObjectTypeDB::bind_method(_MD("get_action_from_id","id"),&InputMap::get_action_from_id);
|
ObjectTypeDB::bind_method(_MD("get_action_from_id","id"),&InputMap::get_action_from_id);
|
||||||
|
ObjectTypeDB::bind_method(_MD("get_actions"),&InputMap::_get_actions);
|
||||||
ObjectTypeDB::bind_method(_MD("add_action","action"),&InputMap::add_action);
|
ObjectTypeDB::bind_method(_MD("add_action","action"),&InputMap::add_action);
|
||||||
ObjectTypeDB::bind_method(_MD("erase_action","action"),&InputMap::erase_action);
|
ObjectTypeDB::bind_method(_MD("erase_action","action"),&InputMap::erase_action);
|
||||||
|
|
||||||
ObjectTypeDB::bind_method(_MD("action_add_event","action","event"),&InputMap::action_add_event);
|
ObjectTypeDB::bind_method(_MD("action_add_event","action","event"),&InputMap::action_add_event);
|
||||||
ObjectTypeDB::bind_method(_MD("action_has_event","action","event"),&InputMap::action_has_event);
|
ObjectTypeDB::bind_method(_MD("action_has_event","action","event"),&InputMap::action_has_event);
|
||||||
ObjectTypeDB::bind_method(_MD("action_erase_event","action","event"),&InputMap::action_erase_event);
|
ObjectTypeDB::bind_method(_MD("action_erase_event","action","event"),&InputMap::action_erase_event);
|
||||||
|
@ -75,6 +77,35 @@ StringName InputMap::get_action_from_id(int p_id) const {
|
||||||
return input_id_map[p_id];
|
return input_id_map[p_id];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Array InputMap::_get_actions() {
|
||||||
|
|
||||||
|
Array ret;
|
||||||
|
List<StringName> actions = get_actions();
|
||||||
|
if(actions.empty())
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
for(const List<StringName>::Element *E=actions.front();E;E=E->next()) {
|
||||||
|
|
||||||
|
ret.push_back(E->get());
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<StringName> InputMap::get_actions() const {
|
||||||
|
|
||||||
|
List<StringName> actions = List<StringName>();
|
||||||
|
if(input_map.empty()){
|
||||||
|
return actions;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Map<StringName, Action>::Element *E=input_map.front();E;E=E->next()) {
|
||||||
|
actions.push_back(E->key());
|
||||||
|
}
|
||||||
|
|
||||||
|
return actions;
|
||||||
|
}
|
||||||
|
|
||||||
List<InputEvent>::Element *InputMap::_find_event(List<InputEvent> &p_list,const InputEvent& p_event) const {
|
List<InputEvent>::Element *InputMap::_find_event(List<InputEvent> &p_list,const InputEvent& p_event) const {
|
||||||
|
|
||||||
for (List<InputEvent>::Element *E=p_list.front();E;E=E->next()) {
|
for (List<InputEvent>::Element *E=p_list.front();E;E=E->next()) {
|
||||||
|
@ -106,7 +137,7 @@ List<InputEvent>::Element *InputMap::_find_event(List<InputEvent> &p_list,const
|
||||||
} break;
|
} break;
|
||||||
case InputEvent::JOYSTICK_MOTION: {
|
case InputEvent::JOYSTICK_MOTION: {
|
||||||
|
|
||||||
same=(e.joy_motion.axis==p_event.joy_motion.axis);
|
same=(e.joy_motion.axis==p_event.joy_motion.axis && (e.joy_motion.axis_value < 0) == (p_event.joy_motion.axis_value < 0));
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
|
@ -156,10 +187,7 @@ void InputMap::action_erase_event(const StringName& p_action,const InputEvent& p
|
||||||
|
|
||||||
List<InputEvent>::Element *E=_find_event(input_map[p_action].inputs,p_event);
|
List<InputEvent>::Element *E=_find_event(input_map[p_action].inputs,p_event);
|
||||||
if (E)
|
if (E)
|
||||||
return; //already gots
|
input_map[p_action].inputs.erase(E);
|
||||||
|
|
||||||
input_map[p_action].inputs.erase(E);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -292,6 +320,67 @@ void InputMap::load_from_globals() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputMap::load_default() {
|
||||||
|
|
||||||
|
InputEvent key;
|
||||||
|
key.type=InputEvent::KEY;
|
||||||
|
|
||||||
|
add_action("ui_accept");
|
||||||
|
key.key.scancode=KEY_RETURN;
|
||||||
|
action_add_event("ui_accept",key);
|
||||||
|
key.key.scancode=KEY_ENTER;
|
||||||
|
action_add_event("ui_accept",key);
|
||||||
|
key.key.scancode=KEY_SPACE;
|
||||||
|
action_add_event("ui_accept",key);
|
||||||
|
|
||||||
|
add_action("ui_select");
|
||||||
|
key.key.scancode=KEY_SPACE;
|
||||||
|
action_add_event("ui_select",key);
|
||||||
|
|
||||||
|
add_action("ui_cancel");
|
||||||
|
key.key.scancode=KEY_ESCAPE;
|
||||||
|
action_add_event("ui_cancel",key);
|
||||||
|
|
||||||
|
add_action("ui_focus_next");
|
||||||
|
key.key.scancode=KEY_TAB;
|
||||||
|
action_add_event("ui_focus_next",key);
|
||||||
|
|
||||||
|
add_action("ui_focus_prev");
|
||||||
|
key.key.scancode=KEY_TAB;
|
||||||
|
key.key.mod.shift=true;
|
||||||
|
action_add_event("ui_focus_prev",key);
|
||||||
|
key.key.mod.shift=false;
|
||||||
|
|
||||||
|
add_action("ui_left");
|
||||||
|
key.key.scancode=KEY_LEFT;
|
||||||
|
action_add_event("ui_left",key);
|
||||||
|
|
||||||
|
add_action("ui_right");
|
||||||
|
key.key.scancode=KEY_RIGHT;
|
||||||
|
action_add_event("ui_right",key);
|
||||||
|
|
||||||
|
add_action("ui_up");
|
||||||
|
key.key.scancode=KEY_UP;
|
||||||
|
action_add_event("ui_up",key);
|
||||||
|
|
||||||
|
add_action("ui_down");
|
||||||
|
key.key.scancode=KEY_DOWN;
|
||||||
|
action_add_event("ui_down",key);
|
||||||
|
|
||||||
|
|
||||||
|
add_action("ui_page_up");
|
||||||
|
key.key.scancode=KEY_PAGEUP;
|
||||||
|
action_add_event("ui_page_up",key);
|
||||||
|
|
||||||
|
add_action("ui_page_down");
|
||||||
|
key.key.scancode=KEY_PAGEDOWN;
|
||||||
|
action_add_event("ui_page_down",key);
|
||||||
|
|
||||||
|
// set("display/orientation", "landscape");
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
InputMap::InputMap() {
|
InputMap::InputMap() {
|
||||||
|
|
|
@ -47,6 +47,7 @@ class InputMap : public Object {
|
||||||
List<InputEvent>::Element *_find_event(List<InputEvent> &p_list,const InputEvent& p_event) const;
|
List<InputEvent>::Element *_find_event(List<InputEvent> &p_list,const InputEvent& p_event) const;
|
||||||
|
|
||||||
Array _get_action_list(const StringName& p_action);
|
Array _get_action_list(const StringName& p_action);
|
||||||
|
Array _get_actions();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
@ -59,6 +60,7 @@ public:
|
||||||
bool has_action(const StringName& p_action) const;
|
bool has_action(const StringName& p_action) const;
|
||||||
int get_action_id(const StringName& p_action) const;
|
int get_action_id(const StringName& p_action) const;
|
||||||
StringName get_action_from_id(int p_id) const;
|
StringName get_action_from_id(int p_id) const;
|
||||||
|
List<StringName> get_actions() const;
|
||||||
void add_action(const StringName& p_action);
|
void add_action(const StringName& p_action);
|
||||||
void erase_action(const StringName& p_action);
|
void erase_action(const StringName& p_action);
|
||||||
|
|
||||||
|
@ -72,6 +74,7 @@ public:
|
||||||
|
|
||||||
|
|
||||||
void load_from_globals();
|
void load_from_globals();
|
||||||
|
void load_default();
|
||||||
|
|
||||||
InputMap();
|
InputMap();
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
This is version 2007-Mar-4 of the Info-ZIP license.
|
||||||
|
The definitive version of this document should be available at
|
||||||
|
ftp://ftp.info-zip.org/pub/infozip/license.html indefinitely and
|
||||||
|
a copy at http://www.info-zip.org/pub/infozip/license.html.
|
||||||
|
|
||||||
|
|
||||||
|
Copyright (c) 1990-2007 Info-ZIP. All rights reserved.
|
||||||
|
|
||||||
|
For the purposes of this copyright and license, "Info-ZIP" is defined as
|
||||||
|
the following set of individuals:
|
||||||
|
|
||||||
|
Mark Adler, John Bush, Karl Davis, Harald Denker, Jean-Michel Dubois,
|
||||||
|
Jean-loup Gailly, Hunter Goatley, Ed Gordon, Ian Gorman, Chris Herborth,
|
||||||
|
Dirk Haase, Greg Hartwig, Robert Heath, Jonathan Hudson, Paul Kienitz,
|
||||||
|
David Kirschbaum, Johnny Lee, Onno van der Linden, Igor Mandrichenko,
|
||||||
|
Steve P. Miller, Sergio Monesi, Keith Owens, George Petrov, Greg Roelofs,
|
||||||
|
Kai Uwe Rommel, Steve Salisbury, Dave Smith, Steven M. Schweda,
|
||||||
|
Christian Spieler, Cosmin Truta, Antoine Verheijen, Paul von Behren,
|
||||||
|
Rich Wales, Mike White.
|
||||||
|
|
||||||
|
This software is provided "as is," without warranty of any kind, express
|
||||||
|
or implied. In no event shall Info-ZIP or its contributors be held liable
|
||||||
|
for any direct, indirect, incidental, special or consequential damages
|
||||||
|
arising out of the use of or inability to use this software.
|
||||||
|
|
||||||
|
Permission is granted to anyone to use this software for any purpose,
|
||||||
|
including commercial applications, and to alter it and redistribute it
|
||||||
|
freely, subject to the above disclaimer and the following restrictions:
|
||||||
|
|
||||||
|
1. Redistributions of source code (in whole or in part) must retain
|
||||||
|
the above copyright notice, definition, disclaimer, and this list
|
||||||
|
of conditions.
|
||||||
|
|
||||||
|
2. Redistributions in binary form (compiled executables and libraries)
|
||||||
|
must reproduce the above copyright notice, definition, disclaimer,
|
||||||
|
and this list of conditions in documentation and/or other materials
|
||||||
|
provided with the distribution. The sole exception to this condition
|
||||||
|
is redistribution of a standard UnZipSFX binary (including SFXWiz) as
|
||||||
|
part of a self-extracting archive; that is permitted without inclusion
|
||||||
|
of this license, as long as the normal SFX banner has not been removed
|
||||||
|
from the binary or disabled.
|
||||||
|
|
||||||
|
3. Altered versions--including, but not limited to, ports to new operating
|
||||||
|
systems, existing ports with new graphical interfaces, versions with
|
||||||
|
modified or added functionality, and dynamic, shared, or static library
|
||||||
|
versions not from Info-ZIP--must be plainly marked as such and must not
|
||||||
|
be misrepresented as being the original source or, if binaries,
|
||||||
|
compiled from the original source. Such altered versions also must not
|
||||||
|
be misrepresented as being Info-ZIP releases--including, but not
|
||||||
|
limited to, labeling of the altered versions with the names "Info-ZIP"
|
||||||
|
(or any variation thereof, including, but not limited to, different
|
||||||
|
capitalizations), "Pocket UnZip," "WiZ" or "MacZip" without the
|
||||||
|
explicit permission of Info-ZIP. Such altered versions are further
|
||||||
|
prohibited from misrepresentative use of the Zip-Bugs or Info-ZIP
|
||||||
|
e-mail addresses or the Info-ZIP URL(s), such as to imply Info-ZIP
|
||||||
|
will provide support for the altered versions.
|
||||||
|
|
||||||
|
4. Info-ZIP retains the right to use the names "Info-ZIP," "Zip," "UnZip,"
|
||||||
|
"UnZipSFX," "WiZ," "Pocket UnZip," "Pocket Zip," and "MacZip" for its
|
||||||
|
own source and binary releases.
|
|
@ -0,0 +1,32 @@
|
||||||
|
Credits
|
||||||
|
|
||||||
|
Gilles Vollant - Original MiniZip author
|
||||||
|
Even Rouault - ZIP64 unzip Support
|
||||||
|
Daniel Borca - BZip Compression method support in unzip
|
||||||
|
Mathias Svensson - ZIP64 zip support
|
||||||
|
Mathias Svensson - BZip Compression method support in zip
|
||||||
|
|
||||||
|
This version has been modified for Godot Engine
|
||||||
|
|
||||||
|
|
||||||
|
License
|
||||||
|
----------------------------------------------------------------------------
|
||||||
|
Condition of use and distribution are the same than zlib :
|
||||||
|
|
||||||
|
This software is provided 'as-is', without any express or implied
|
||||||
|
warranty. In no event will the authors be held liable for any damages
|
||||||
|
arising from the use of this software.
|
||||||
|
|
||||||
|
Permission is granted to anyone to use this software for any purpose,
|
||||||
|
including commercial applications, and to alter it and redistribute it
|
||||||
|
freely, subject to the following restrictions:
|
||||||
|
|
||||||
|
1. The origin of this software must not be misrepresented; you must not
|
||||||
|
claim that you wrote the original software. If you use this software
|
||||||
|
in a product, an acknowledgment in the product documentation would be
|
||||||
|
appreciated but is not required.
|
||||||
|
2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
misrepresented as being the original software.
|
||||||
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
|
|
||||||
|
----------------------------------------------------------------------------
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Byte-oriented AES-256 implementation.
|
* Byte-oriented AES-256 implementation.
|
||||||
* All lookup tables replaced with 'on the fly' calculations.
|
* All lookup tables replaced with 'on the fly' calculations.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2007-2009 Ilya O. Levin, http://www.literatecode.com
|
* Copyright (c) 2007-2009 Ilya O. Levin, http://www.literatecode.com
|
||||||
* Other contributors: Hal Finney
|
* Other contributors: Hal Finney
|
||||||
|
@ -24,14 +24,14 @@
|
||||||
#include "typedefs.h"
|
#include "typedefs.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t key[32];
|
uint8_t key[32];
|
||||||
uint8_t enckey[32];
|
uint8_t enckey[32];
|
||||||
uint8_t deckey[32];
|
uint8_t deckey[32];
|
||||||
} aes256_context;
|
} aes256_context;
|
||||||
|
|
||||||
|
|
||||||
void aes256_init(aes256_context *, uint8_t * /* key */);
|
void aes256_init(aes256_context *, uint8_t * /* key */);
|
||||||
|
|
|
@ -207,7 +207,7 @@ Error ConfigFile::load(const String& p_path) {
|
||||||
void ConfigFile::_bind_methods(){
|
void ConfigFile::_bind_methods(){
|
||||||
|
|
||||||
ObjectTypeDB::bind_method(_MD("set_value","section","key","value"),&ConfigFile::set_value);
|
ObjectTypeDB::bind_method(_MD("set_value","section","key","value"),&ConfigFile::set_value);
|
||||||
ObjectTypeDB::bind_method(_MD("get_value","section","key","default"),&ConfigFile::get_value,DEFVAL(Variant()));
|
ObjectTypeDB::bind_method(_MD("get_value:Variant","section","key","default"),&ConfigFile::get_value,DEFVAL(Variant()));
|
||||||
|
|
||||||
ObjectTypeDB::bind_method(_MD("has_section","section"),&ConfigFile::has_section);
|
ObjectTypeDB::bind_method(_MD("has_section","section"),&ConfigFile::has_section);
|
||||||
ObjectTypeDB::bind_method(_MD("has_section_key","section","key"),&ConfigFile::has_section_key);
|
ObjectTypeDB::bind_method(_MD("has_section_key","section","key"),&ConfigFile::has_section_key);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
FastLZ - lightning-fast lossless compression library
|
FastLZ - lightning-fast lossless compression library
|
||||||
|
|
||||||
Copyright (C) 2007 Ariya Hidayat (ariya@kde.org)
|
Copyright (C) 2007 Ariya Hidayat (ariya@kde.org)
|
||||||
|
@ -40,11 +40,11 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Compress a block of data in the input buffer and returns the size of
|
Compress a block of data in the input buffer and returns the size of
|
||||||
compressed block. The size of input buffer is specified by length. The
|
compressed block. The size of input buffer is specified by length. The
|
||||||
minimum input buffer size is 16.
|
minimum input buffer size is 16.
|
||||||
|
|
||||||
The output buffer must be at least 5% larger than the input buffer
|
The output buffer must be at least 5% larger than the input buffer
|
||||||
and can not be smaller than 66 bytes.
|
and can not be smaller than 66 bytes.
|
||||||
|
|
||||||
If the input is not compressible, the return value might be larger than
|
If the input is not compressible, the return value might be larger than
|
||||||
|
@ -56,9 +56,9 @@ extern "C" {
|
||||||
int fastlz_compress(const void* input, int length, void* output);
|
int fastlz_compress(const void* input, int length, void* output);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Decompress a block of compressed data and returns the size of the
|
Decompress a block of compressed data and returns the size of the
|
||||||
decompressed block. If error occurs, e.g. the compressed data is
|
decompressed block. If error occurs, e.g. the compressed data is
|
||||||
corrupted or the output buffer is not large enough, then 0 (zero)
|
corrupted or the output buffer is not large enough, then 0 (zero)
|
||||||
will be returned instead.
|
will be returned instead.
|
||||||
|
|
||||||
The input buffer and the output buffer can not overlap.
|
The input buffer and the output buffer can not overlap.
|
||||||
|
@ -67,14 +67,14 @@ int fastlz_compress(const void* input, int length, void* output);
|
||||||
more than what is specified in maxout.
|
more than what is specified in maxout.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int fastlz_decompress(const void* input, int length, void* output, int maxout);
|
int fastlz_decompress(const void* input, int length, void* output, int maxout);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Compress a block of data in the input buffer and returns the size of
|
Compress a block of data in the input buffer and returns the size of
|
||||||
compressed block. The size of input buffer is specified by length. The
|
compressed block. The size of input buffer is specified by length. The
|
||||||
minimum input buffer size is 16.
|
minimum input buffer size is 16.
|
||||||
|
|
||||||
The output buffer must be at least 5% larger than the input buffer
|
The output buffer must be at least 5% larger than the input buffer
|
||||||
and can not be smaller than 66 bytes.
|
and can not be smaller than 66 bytes.
|
||||||
|
|
||||||
If the input is not compressible, the return value might be larger than
|
If the input is not compressible, the return value might be larger than
|
||||||
|
@ -82,14 +82,14 @@ int fastlz_decompress(const void* input, int length, void* output, int maxout);
|
||||||
|
|
||||||
The input buffer and the output buffer can not overlap.
|
The input buffer and the output buffer can not overlap.
|
||||||
|
|
||||||
Compression level can be specified in parameter level. At the moment,
|
Compression level can be specified in parameter level. At the moment,
|
||||||
only level 1 and level 2 are supported.
|
only level 1 and level 2 are supported.
|
||||||
Level 1 is the fastest compression and generally useful for short data.
|
Level 1 is the fastest compression and generally useful for short data.
|
||||||
Level 2 is slightly slower but it gives better compression ratio.
|
Level 2 is slightly slower but it gives better compression ratio.
|
||||||
|
|
||||||
Note that the compressed data, regardless of the level, can always be
|
Note that the compressed data, regardless of the level, can always be
|
||||||
decompressed using the function fastlz_decompress above.
|
decompressed using the function fastlz_decompress above.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int fastlz_compress_level(int level, const void* input, int length, void* output);
|
int fastlz_compress_level(int level, const void* input, int length, void* output);
|
||||||
|
|
||||||
|
|
|
@ -33,17 +33,17 @@
|
||||||
#include "error_macros.h"
|
#include "error_macros.h"
|
||||||
|
|
||||||
Error FileAccessBuffered::set_error(Error p_error) const {
|
Error FileAccessBuffered::set_error(Error p_error) const {
|
||||||
|
|
||||||
return (last_error = p_error);
|
return (last_error = p_error);
|
||||||
};
|
};
|
||||||
|
|
||||||
void FileAccessBuffered::set_cache_size(int p_size) {
|
void FileAccessBuffered::set_cache_size(int p_size) {
|
||||||
|
|
||||||
cache_size = p_size;
|
cache_size = p_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
int FileAccessBuffered::get_cache_size() {
|
int FileAccessBuffered::get_cache_size() {
|
||||||
|
|
||||||
return cache_size;
|
return cache_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -66,27 +66,27 @@ int FileAccessBuffered::cache_data_left() const {
|
||||||
};
|
};
|
||||||
|
|
||||||
void FileAccessBuffered::seek(size_t p_position) {
|
void FileAccessBuffered::seek(size_t p_position) {
|
||||||
|
|
||||||
file.offset = p_position;
|
file.offset = p_position;
|
||||||
};
|
};
|
||||||
|
|
||||||
void FileAccessBuffered::seek_end(int64_t p_position) {
|
void FileAccessBuffered::seek_end(int64_t p_position) {
|
||||||
|
|
||||||
file.offset = file.size + p_position;
|
file.offset = file.size + p_position;
|
||||||
};
|
};
|
||||||
|
|
||||||
size_t FileAccessBuffered::get_pos() const {
|
size_t FileAccessBuffered::get_pos() const {
|
||||||
|
|
||||||
return file.offset;
|
return file.offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
size_t FileAccessBuffered::get_len() const {
|
size_t FileAccessBuffered::get_len() const {
|
||||||
|
|
||||||
return file.size;
|
return file.size;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool FileAccessBuffered::eof_reached() const {
|
bool FileAccessBuffered::eof_reached() const {
|
||||||
|
|
||||||
return file.offset > file.size;
|
return file.offset > file.size;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -165,12 +165,12 @@ int FileAccessBuffered::get_buffer(uint8_t *p_dest,int p_elements) const {
|
||||||
};
|
};
|
||||||
|
|
||||||
bool FileAccessBuffered::is_open() const {
|
bool FileAccessBuffered::is_open() const {
|
||||||
|
|
||||||
return file.open;
|
return file.open;
|
||||||
};
|
};
|
||||||
|
|
||||||
Error FileAccessBuffered::get_error() const {
|
Error FileAccessBuffered::get_error() const {
|
||||||
|
|
||||||
return last_error;
|
return last_error;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -180,5 +180,5 @@ FileAccessBuffered::FileAccessBuffered() {
|
||||||
};
|
};
|
||||||
|
|
||||||
FileAccessBuffered::~FileAccessBuffered(){
|
FileAccessBuffered::~FileAccessBuffered(){
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,9 +60,9 @@ protected:
|
||||||
String name;
|
String name;
|
||||||
int access_flags;
|
int access_flags;
|
||||||
} file;
|
} file;
|
||||||
|
|
||||||
mutable struct Cache {
|
mutable struct Cache {
|
||||||
|
|
||||||
Vector<uint8_t> buffer;
|
Vector<uint8_t> buffer;
|
||||||
int offset;
|
int offset;
|
||||||
} cache;
|
} cache;
|
||||||
|
@ -71,7 +71,7 @@ protected:
|
||||||
|
|
||||||
void set_cache_size(int p_size);
|
void set_cache_size(int p_size);
|
||||||
int get_cache_size();
|
int get_cache_size();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
virtual size_t get_pos() const; ///< get position in the file
|
virtual size_t get_pos() const; ///< get position in the file
|
||||||
|
|
|
@ -217,7 +217,7 @@ Error FileAccessNetworkClient::connect(const String& p_host,int p_port,const Str
|
||||||
return ERR_CANT_CONNECT;
|
return ERR_CANT_CONNECT;
|
||||||
}
|
}
|
||||||
|
|
||||||
CharString cs = p_password.utf8();
|
CharString cs = p_password.utf8();
|
||||||
put_32(cs.length());
|
put_32(cs.length());
|
||||||
client->put_data((const uint8_t*)cs.ptr(),cs.length());
|
client->put_data((const uint8_t*)cs.ptr(),cs.length());
|
||||||
|
|
||||||
|
|
|
@ -81,6 +81,7 @@ void HTTPClient::set_connection(const Ref<StreamPeer>& p_connection){
|
||||||
|
|
||||||
close();
|
close();
|
||||||
connection=p_connection;
|
connection=p_connection;
|
||||||
|
status=STATUS_CONNECTED;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -301,6 +302,7 @@ Error HTTPClient::poll(){
|
||||||
chunked=false;
|
chunked=false;
|
||||||
body_left=0;
|
body_left=0;
|
||||||
chunk_left=0;
|
chunk_left=0;
|
||||||
|
response_str.clear();
|
||||||
response_headers.clear();
|
response_headers.clear();
|
||||||
response_num = RESPONSE_OK;
|
response_num = RESPONSE_OK;
|
||||||
|
|
||||||
|
@ -309,7 +311,7 @@ Error HTTPClient::poll(){
|
||||||
String header = responses[i].strip_edges();
|
String header = responses[i].strip_edges();
|
||||||
String s = header.to_lower();
|
String s = header.to_lower();
|
||||||
if (s.length()==0)
|
if (s.length()==0)
|
||||||
continue;
|
continue;
|
||||||
if (s.begins_with("content-length:")) {
|
if (s.begins_with("content-length:")) {
|
||||||
body_size = s.substr(s.find(":")+1,s.length()).strip_edges().to_int();
|
body_size = s.substr(s.find(":")+1,s.length()).strip_edges().to_int();
|
||||||
body_left=body_size;
|
body_left=body_size;
|
||||||
|
|
|
@ -40,7 +40,7 @@ class HTTPClient : public Reference {
|
||||||
OBJ_TYPE(HTTPClient,Reference);
|
OBJ_TYPE(HTTPClient,Reference);
|
||||||
public:
|
public:
|
||||||
|
|
||||||
enum RespondeCode {
|
enum ResponseCode {
|
||||||
|
|
||||||
// 1xx informational
|
// 1xx informational
|
||||||
RESPONSE_CONTINUE = 100,
|
RESPONSE_CONTINUE = 100,
|
||||||
|
|
|
@ -30,16 +30,16 @@
|
||||||
|
|
||||||
#include "print_string.h"
|
#include "print_string.h"
|
||||||
bool ImageFormatLoader::recognize(const String& p_extension) const {
|
bool ImageFormatLoader::recognize(const String& p_extension) const {
|
||||||
|
|
||||||
|
|
||||||
List<String> extensions;
|
List<String> extensions;
|
||||||
get_recognized_extensions(&extensions);
|
get_recognized_extensions(&extensions);
|
||||||
for (List<String>::Element *E=extensions.front();E;E=E->next()) {
|
for (List<String>::Element *E=extensions.front();E;E=E->next()) {
|
||||||
|
|
||||||
if (E->get().nocasecmp_to(p_extension.extension())==0)
|
if (E->get().nocasecmp_to(p_extension.extension())==0)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,12 +55,12 @@ Error ImageLoader::load_image(String p_file,Image *p_image, FileAccess *p_custom
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String extension = p_file.extension();
|
String extension = p_file.extension();
|
||||||
|
|
||||||
|
|
||||||
for (int i=0;i<loader_count;i++) {
|
for (int i=0;i<loader_count;i++) {
|
||||||
|
|
||||||
if (!loader[i]->recognize(extension))
|
if (!loader[i]->recognize(extension))
|
||||||
continue;
|
continue;
|
||||||
Error err = loader[i]->load_image(p_image,f);
|
Error err = loader[i]->load_image(p_image,f);
|
||||||
|
@ -73,25 +73,25 @@ Error ImageLoader::load_image(String p_file,Image *p_image, FileAccess *p_custom
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
print_line("NO LOADER?");
|
print_line("NO LOADER?");
|
||||||
|
|
||||||
if (!p_custom)
|
if (!p_custom)
|
||||||
memdelete(f);
|
memdelete(f);
|
||||||
|
|
||||||
return ERR_FILE_UNRECOGNIZED;
|
return ERR_FILE_UNRECOGNIZED;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImageLoader::get_recognized_extensions(List<String> *p_extensions) {
|
void ImageLoader::get_recognized_extensions(List<String> *p_extensions) {
|
||||||
|
|
||||||
for (int i=0;i<loader_count;i++) {
|
for (int i=0;i<loader_count;i++) {
|
||||||
|
|
||||||
loader[i]->get_recognized_extensions(p_extensions);
|
loader[i]->get_recognized_extensions(p_extensions);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImageLoader::recognize(const String& p_extension) {
|
bool ImageLoader::recognize(const String& p_extension) {
|
||||||
|
|
|
@ -41,11 +41,11 @@
|
||||||
/**
|
/**
|
||||||
* @class ImageScanLineLoader
|
* @class ImageScanLineLoader
|
||||||
* @author Juan Linietsky <reduzio@gmail.com>
|
* @author Juan Linietsky <reduzio@gmail.com>
|
||||||
*
|
*
|
||||||
|
|
||||||
*/
|
*/
|
||||||
class ImageLoader;
|
class ImageLoader;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @class ImageLoader
|
* @class ImageLoader
|
||||||
|
@ -60,8 +60,8 @@ protected:
|
||||||
virtual Error load_image(Image *p_image,FileAccess *p_fileaccess)=0;
|
virtual Error load_image(Image *p_image,FileAccess *p_fileaccess)=0;
|
||||||
virtual void get_recognized_extensions(List<String> *p_extensions) const=0;
|
virtual void get_recognized_extensions(List<String> *p_extensions) const=0;
|
||||||
bool recognize(const String& p_extension) const;
|
bool recognize(const String& p_extension) const;
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ~ImageFormatLoader() {}
|
virtual ~ImageFormatLoader() {}
|
||||||
};
|
};
|
||||||
|
@ -79,11 +79,11 @@ protected:
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
static Error load_image(String p_file,Image *p_image, FileAccess *p_custom=NULL);
|
static Error load_image(String p_file,Image *p_image, FileAccess *p_custom=NULL);
|
||||||
static void get_recognized_extensions(List<String> *p_extensions) ;
|
static void get_recognized_extensions(List<String> *p_extensions) ;
|
||||||
static bool recognize(const String& p_extension) ;
|
static bool recognize(const String& p_extension) ;
|
||||||
|
|
||||||
static void add_image_format_loader(ImageFormatLoader *p_loader);
|
static void add_image_format_loader(ImageFormatLoader *p_loader);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
Modifications for Zip64 support
|
Modifications for Zip64 support
|
||||||
Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
|
Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
|
||||||
|
|
||||||
For more info read MiniZip_info.txt
|
For more info read LICENSE-MiniZip.txt
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
Modifications for Zip64 support
|
Modifications for Zip64 support
|
||||||
Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
|
Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
|
||||||
|
|
||||||
For more info read MiniZip_info.txt
|
For more info read LICENSE-MiniZip.txt
|
||||||
|
|
||||||
Changes
|
Changes
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,7 @@ struct _IP_ResolverPrivate {
|
||||||
response = IP_Address();
|
response = IP_Address();
|
||||||
hostname="";
|
hostname="";
|
||||||
};
|
};
|
||||||
|
|
||||||
QueueItem() {
|
QueueItem() {
|
||||||
clear();
|
clear();
|
||||||
};
|
};
|
||||||
|
|
|
@ -95,7 +95,7 @@ Error decode_variant(Variant& r_variant,const uint8_t *p_buffer, int p_len,int *
|
||||||
str.parse_utf8((const char*)buf,strlen);
|
str.parse_utf8((const char*)buf,strlen);
|
||||||
r_variant=str;
|
r_variant=str;
|
||||||
|
|
||||||
if (r_len) {
|
if (r_len) {
|
||||||
if (strlen%4)
|
if (strlen%4)
|
||||||
(*r_len)+=4-strlen%4;
|
(*r_len)+=4-strlen%4;
|
||||||
(*r_len)+=4+strlen;
|
(*r_len)+=4+strlen;
|
||||||
|
@ -294,7 +294,7 @@ Error decode_variant(Variant& r_variant,const uint8_t *p_buffer, int p_len,int *
|
||||||
} break;
|
} break;
|
||||||
case Variant::NODE_PATH: {
|
case Variant::NODE_PATH: {
|
||||||
|
|
||||||
ERR_FAIL_COND_V(len<4,ERR_INVALID_DATA);
|
ERR_FAIL_COND_V(len<4,ERR_INVALID_DATA);
|
||||||
uint32_t strlen = decode_uint32(buf);
|
uint32_t strlen = decode_uint32(buf);
|
||||||
|
|
||||||
if (strlen&0x80000000) {
|
if (strlen&0x80000000) {
|
||||||
|
@ -438,8 +438,9 @@ Error decode_variant(Variant& r_variant,const uint8_t *p_buffer, int p_len,int *
|
||||||
case InputEvent::JOYSTICK_MOTION: {
|
case InputEvent::JOYSTICK_MOTION: {
|
||||||
|
|
||||||
ie.joy_motion.axis=decode_uint32(&buf[12]);
|
ie.joy_motion.axis=decode_uint32(&buf[12]);
|
||||||
|
ie.joy_motion.axis_value=decode_float(&buf[16]);
|
||||||
if (r_len)
|
if (r_len)
|
||||||
(*r_len)+=4;
|
(*r_len)+=8;
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1077,7 +1078,7 @@ Error encode_variant(const Variant& p_variant, uint8_t *r_buffer, int &r_len) {
|
||||||
|
|
||||||
r_len+=data.size()+5*4+pad;
|
r_len+=data.size()+5*4+pad;
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
/*case Variant::RESOURCE: {
|
/*case Variant::RESOURCE: {
|
||||||
|
|
||||||
ERR_EXPLAIN("Can't marshallize resources");
|
ERR_EXPLAIN("Can't marshallize resources");
|
||||||
|
@ -1154,8 +1155,9 @@ Error encode_variant(const Variant& p_variant, uint8_t *r_buffer, int &r_len) {
|
||||||
|
|
||||||
int axis = ie.joy_motion.axis;
|
int axis = ie.joy_motion.axis;
|
||||||
encode_uint32(axis,&buf[llen]);
|
encode_uint32(axis,&buf[llen]);
|
||||||
|
encode_float(ie.joy_motion.axis_value, &buf[llen+4]);
|
||||||
}
|
}
|
||||||
llen+=4;
|
llen+=8;
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1238,7 +1240,7 @@ Error encode_variant(const Variant& p_variant, uint8_t *r_buffer, int &r_len) {
|
||||||
DVector<uint8_t> data = p_variant;
|
DVector<uint8_t> data = p_variant;
|
||||||
int datalen=data.size();
|
int datalen=data.size();
|
||||||
int datasize=sizeof(uint8_t);
|
int datasize=sizeof(uint8_t);
|
||||||
|
|
||||||
if (buf) {
|
if (buf) {
|
||||||
encode_uint32(datalen,buf);
|
encode_uint32(datalen,buf);
|
||||||
buf+=4;
|
buf+=4;
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
* Miscelaneous helpers for marshalling data types, and encoding
|
* Miscelaneous helpers for marshalling data types, and encoding
|
||||||
* in an endian independent way
|
* in an endian independent way
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
union MarshallFloat {
|
union MarshallFloat {
|
||||||
|
|
||||||
|
@ -54,22 +54,22 @@ union MarshallDouble {
|
||||||
static inline unsigned int encode_uint16(uint16_t p_uint, uint8_t *p_arr) {
|
static inline unsigned int encode_uint16(uint16_t p_uint, uint8_t *p_arr) {
|
||||||
|
|
||||||
for (int i=0;i<2;i++) {
|
for (int i=0;i<2;i++) {
|
||||||
|
|
||||||
*p_arr=p_uint&0xFF;
|
*p_arr=p_uint&0xFF;
|
||||||
p_arr++; p_uint>>=8;
|
p_arr++; p_uint>>=8;
|
||||||
}
|
}
|
||||||
|
|
||||||
return sizeof( uint16_t );
|
return sizeof( uint16_t );
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline unsigned int encode_uint32(uint32_t p_uint, uint8_t *p_arr) {
|
static inline unsigned int encode_uint32(uint32_t p_uint, uint8_t *p_arr) {
|
||||||
|
|
||||||
for (int i=0;i<4;i++) {
|
for (int i=0;i<4;i++) {
|
||||||
|
|
||||||
*p_arr=p_uint&0xFF;
|
*p_arr=p_uint&0xFF;
|
||||||
p_arr++; p_uint>>=8;
|
p_arr++; p_uint>>=8;
|
||||||
}
|
}
|
||||||
|
|
||||||
return sizeof( uint32_t );
|
return sizeof( uint32_t );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,11 +85,11 @@ static inline unsigned int encode_float(float p_float, uint8_t *p_arr) {
|
||||||
static inline unsigned int encode_uint64(uint64_t p_uint, uint8_t *p_arr) {
|
static inline unsigned int encode_uint64(uint64_t p_uint, uint8_t *p_arr) {
|
||||||
|
|
||||||
for (int i=0;i<8;i++) {
|
for (int i=0;i<8;i++) {
|
||||||
|
|
||||||
*p_arr=p_uint&0xFF;
|
*p_arr=p_uint&0xFF;
|
||||||
p_arr++; p_uint>>=8;
|
p_arr++; p_uint>>=8;
|
||||||
}
|
}
|
||||||
|
|
||||||
return sizeof(uint64_t);
|
return sizeof(uint64_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,25 +100,25 @@ static inline unsigned int encode_double(double p_double, uint8_t *p_arr) {
|
||||||
encode_uint64( md.l, p_arr );
|
encode_uint64( md.l, p_arr );
|
||||||
|
|
||||||
return sizeof(uint64_t);
|
return sizeof(uint64_t);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline int encode_cstring(const char *p_string, uint8_t * p_data) {
|
static inline int encode_cstring(const char *p_string, uint8_t * p_data) {
|
||||||
|
|
||||||
int len=0;
|
int len=0;
|
||||||
|
|
||||||
while (*p_string) {
|
while (*p_string) {
|
||||||
|
|
||||||
if (p_data) {
|
if (p_data) {
|
||||||
|
|
||||||
*p_data=(uint8_t)*p_string;
|
*p_data=(uint8_t)*p_string;
|
||||||
p_data++;
|
p_data++;
|
||||||
}
|
}
|
||||||
p_string++;
|
p_string++;
|
||||||
len++;
|
len++;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (p_data) *p_data = 0;
|
if (p_data) *p_data = 0;
|
||||||
return len+1;
|
return len+1;
|
||||||
}
|
}
|
||||||
|
@ -126,35 +126,35 @@ static inline int encode_cstring(const char *p_string, uint8_t * p_data) {
|
||||||
static inline uint16_t decode_uint16(const uint8_t *p_arr) {
|
static inline uint16_t decode_uint16(const uint8_t *p_arr) {
|
||||||
|
|
||||||
uint16_t u=0;
|
uint16_t u=0;
|
||||||
|
|
||||||
for (int i=0;i<2;i++) {
|
for (int i=0;i<2;i++) {
|
||||||
|
|
||||||
uint16_t b = *p_arr;
|
uint16_t b = *p_arr;
|
||||||
b<<=(i*8);
|
b<<=(i*8);
|
||||||
u|=b;
|
u|=b;
|
||||||
p_arr++;
|
p_arr++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return u;
|
return u;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t decode_uint32(const uint8_t *p_arr) {
|
static inline uint32_t decode_uint32(const uint8_t *p_arr) {
|
||||||
|
|
||||||
uint32_t u=0;
|
uint32_t u=0;
|
||||||
|
|
||||||
for (int i=0;i<4;i++) {
|
for (int i=0;i<4;i++) {
|
||||||
|
|
||||||
uint32_t b = *p_arr;
|
uint32_t b = *p_arr;
|
||||||
b<<=(i*8);
|
b<<=(i*8);
|
||||||
u|=b;
|
u|=b;
|
||||||
p_arr++;
|
p_arr++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return u;
|
return u;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline float decode_float(const uint8_t *p_arr) {
|
static inline float decode_float(const uint8_t *p_arr) {
|
||||||
|
|
||||||
MarshallFloat mf;
|
MarshallFloat mf;
|
||||||
mf.i = decode_uint32(p_arr);
|
mf.i = decode_uint32(p_arr);
|
||||||
return mf.f;
|
return mf.f;
|
||||||
|
@ -163,15 +163,15 @@ static inline float decode_float(const uint8_t *p_arr) {
|
||||||
static inline uint64_t decode_uint64(const uint8_t *p_arr) {
|
static inline uint64_t decode_uint64(const uint8_t *p_arr) {
|
||||||
|
|
||||||
uint64_t u=0;
|
uint64_t u=0;
|
||||||
|
|
||||||
for (int i=0;i<8;i++) {
|
for (int i=0;i<8;i++) {
|
||||||
|
|
||||||
uint64_t b = (*p_arr)&0xFF;
|
uint64_t b = (*p_arr)&0xFF;
|
||||||
b<<=(i*8);
|
b<<=(i*8);
|
||||||
u|=b;
|
u|=b;
|
||||||
p_arr++;
|
p_arr++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return u;
|
return u;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -126,7 +126,7 @@ Error PacketPeer::_get_packet_error() const {
|
||||||
|
|
||||||
void PacketPeer::_bind_methods() {
|
void PacketPeer::_bind_methods() {
|
||||||
|
|
||||||
ObjectTypeDB::bind_method(_MD("get_var"),&PacketPeer::_bnd_get_var);
|
ObjectTypeDB::bind_method(_MD("get_var:Variant"),&PacketPeer::_bnd_get_var);
|
||||||
ObjectTypeDB::bind_method(_MD("put_var", "var:Variant"),&PacketPeer::put_var);
|
ObjectTypeDB::bind_method(_MD("put_var", "var:Variant"),&PacketPeer::put_var);
|
||||||
ObjectTypeDB::bind_method(_MD("get_packet"),&PacketPeer::_get_packet);
|
ObjectTypeDB::bind_method(_MD("get_packet"),&PacketPeer::_get_packet);
|
||||||
ObjectTypeDB::bind_method(_MD("put_packet:Error", "buffer"),&PacketPeer::_put_packet);
|
ObjectTypeDB::bind_method(_MD("put_packet:Error", "buffer"),&PacketPeer::_put_packet);
|
||||||
|
@ -180,10 +180,10 @@ int PacketPeerStream::get_available_packet_count() const {
|
||||||
ring_buffer.copy(lbuf,ofs,4);
|
ring_buffer.copy(lbuf,ofs,4);
|
||||||
uint32_t len = decode_uint32(lbuf);
|
uint32_t len = decode_uint32(lbuf);
|
||||||
remaining-=4;
|
remaining-=4;
|
||||||
ofs+=4;
|
ofs+=4;
|
||||||
if (len>remaining)
|
if (len>remaining)
|
||||||
break;
|
break;
|
||||||
remaining-=len;
|
remaining-=len;
|
||||||
ofs+=len;
|
ofs+=len;
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
@ -201,7 +201,7 @@ Error PacketPeerStream::get_packet(const uint8_t **r_buffer,int &r_buffer_size)
|
||||||
uint8_t lbuf[4];
|
uint8_t lbuf[4];
|
||||||
ring_buffer.copy(lbuf,0,4);
|
ring_buffer.copy(lbuf,0,4);
|
||||||
remaining-=4;
|
remaining-=4;
|
||||||
uint32_t len = decode_uint32(lbuf);
|
uint32_t len = decode_uint32(lbuf);
|
||||||
ERR_FAIL_COND_V(remaining<(int)len,ERR_UNAVAILABLE);
|
ERR_FAIL_COND_V(remaining<(int)len,ERR_UNAVAILABLE);
|
||||||
|
|
||||||
ring_buffer.read(lbuf,4); //get rid of first 4 bytes
|
ring_buffer.read(lbuf,4); //get rid of first 4 bytes
|
||||||
|
|
|
@ -378,7 +378,7 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant& r_v) {
|
||||||
} break;
|
} break;
|
||||||
case OBJECT_INTERNAL_RESOURCE: {
|
case OBJECT_INTERNAL_RESOURCE: {
|
||||||
uint32_t index=f->get_32();
|
uint32_t index=f->get_32();
|
||||||
String path = res_path+"::"+itos(index);
|
String path = res_path+"::"+itos(index);
|
||||||
RES res = ResourceLoader::load(path);
|
RES res = ResourceLoader::load(path);
|
||||||
if (res.is_null()) {
|
if (res.is_null()) {
|
||||||
WARN_PRINT(String("Couldn't load resource: "+path).utf8().get_data());
|
WARN_PRINT(String("Couldn't load resource: "+path).utf8().get_data());
|
||||||
|
@ -2100,7 +2100,7 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path,const RES& p_
|
||||||
p.value=E->get()->get(F->get().name);
|
p.value=E->get()->get(F->get().name);
|
||||||
if ((F->get().usage&PROPERTY_USAGE_STORE_IF_NONZERO && p.value.is_zero())||(F->get().usage&PROPERTY_USAGE_STORE_IF_NONONE && p.value.is_one()) )
|
if ((F->get().usage&PROPERTY_USAGE_STORE_IF_NONZERO && p.value.is_zero())||(F->get().usage&PROPERTY_USAGE_STORE_IF_NONONE && p.value.is_one()) )
|
||||||
continue;
|
continue;
|
||||||
p.pi=F->get();
|
p.pi=F->get();
|
||||||
|
|
||||||
rd.properties.push_back(p);
|
rd.properties.push_back(p);
|
||||||
|
|
||||||
|
|
|
@ -1818,7 +1818,7 @@ Error ResourceInteractiveLoaderXML::rename_dependencies(FileAccess *p_f, const S
|
||||||
|
|
||||||
void ResourceInteractiveLoaderXML::open(FileAccess *p_f) {
|
void ResourceInteractiveLoaderXML::open(FileAccess *p_f) {
|
||||||
|
|
||||||
error=OK;
|
error=OK;
|
||||||
|
|
||||||
lines=1;
|
lines=1;
|
||||||
f=p_f;
|
f=p_f;
|
||||||
|
|
|
@ -49,16 +49,16 @@ Error ResourceInteractiveLoader::wait() {
|
||||||
|
|
||||||
|
|
||||||
bool ResourceFormatLoader::recognize(const String& p_extension) const {
|
bool ResourceFormatLoader::recognize(const String& p_extension) const {
|
||||||
|
|
||||||
|
|
||||||
List<String> extensions;
|
List<String> extensions;
|
||||||
get_recognized_extensions(&extensions);
|
get_recognized_extensions(&extensions);
|
||||||
for (List<String>::Element *E=extensions.front();E;E=E->next()) {
|
for (List<String>::Element *E=extensions.front();E;E=E->next()) {
|
||||||
|
|
||||||
if (E->get().nocasecmp_to(p_extension.extension())==0)
|
if (E->get().nocasecmp_to(p_extension.extension())==0)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,9 +184,9 @@ RES ResourceLoader::load(const String &p_path, const String& p_type_hint, bool p
|
||||||
|
|
||||||
String extension=remapped_path.extension();
|
String extension=remapped_path.extension();
|
||||||
bool found=false;
|
bool found=false;
|
||||||
|
|
||||||
for (int i=0;i<loader_count;i++) {
|
for (int i=0;i<loader_count;i++) {
|
||||||
|
|
||||||
if (!loader[i]->recognize(extension))
|
if (!loader[i]->recognize(extension))
|
||||||
continue;
|
continue;
|
||||||
if (p_type_hint!="" && !loader[i]->handles_type(p_type_hint))
|
if (p_type_hint!="" && !loader[i]->handles_type(p_type_hint))
|
||||||
|
@ -318,7 +318,11 @@ Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(const String &p_
|
||||||
if (OS::get_singleton()->is_stdout_verbose())
|
if (OS::get_singleton()->is_stdout_verbose())
|
||||||
print_line("load resource: "+local_path+" (cached)");
|
print_line("load resource: "+local_path+" (cached)");
|
||||||
|
|
||||||
return RES( ResourceCache::get(local_path ) );
|
Ref<Resource> res_cached = ResourceCache::get(local_path);
|
||||||
|
Ref<ResourceInteractiveLoaderDefault> ril = Ref<ResourceInteractiveLoaderDefault>(memnew(ResourceInteractiveLoaderDefault));
|
||||||
|
|
||||||
|
ril->resource = res_cached;
|
||||||
|
return ril;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (OS::get_singleton()->is_stdout_verbose())
|
if (OS::get_singleton()->is_stdout_verbose())
|
||||||
|
@ -356,7 +360,7 @@ Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(const String &p_
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceLoader::add_resource_format_loader(ResourceFormatLoader *p_format_loader) {
|
void ResourceLoader::add_resource_format_loader(ResourceFormatLoader *p_format_loader) {
|
||||||
|
|
||||||
ERR_FAIL_COND( loader_count >= MAX_LOADERS );
|
ERR_FAIL_COND( loader_count >= MAX_LOADERS );
|
||||||
loader[loader_count++]=p_format_loader;
|
loader[loader_count++]=p_format_loader;
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,7 @@ public:
|
||||||
virtual Ref<Resource> get_resource()=0;
|
virtual Ref<Resource> get_resource()=0;
|
||||||
virtual Error poll()=0;
|
virtual Error poll()=0;
|
||||||
virtual int get_stage() const=0;
|
virtual int get_stage() const=0;
|
||||||
virtual int get_stage_count() const=0;
|
virtual int get_stage_count() const=0;
|
||||||
virtual Error wait();
|
virtual Error wait();
|
||||||
|
|
||||||
ResourceInteractiveLoader() {}
|
ResourceInteractiveLoader() {}
|
||||||
|
@ -76,12 +76,12 @@ typedef void (*ResourceLoadErrorNotify)(void *p_ud,const String& p_text);
|
||||||
typedef void (*DependencyErrorNotify)(void *p_ud,const String& p_loading,const String& p_which,const String& p_type);
|
typedef void (*DependencyErrorNotify)(void *p_ud,const String& p_loading,const String& p_which,const String& p_type);
|
||||||
|
|
||||||
|
|
||||||
class ResourceLoader {
|
class ResourceLoader {
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
MAX_LOADERS=64
|
MAX_LOADERS=64
|
||||||
};
|
};
|
||||||
|
|
||||||
static ResourceFormatLoader *loader[MAX_LOADERS];
|
static ResourceFormatLoader *loader[MAX_LOADERS];
|
||||||
static int loader_count;
|
static int loader_count;
|
||||||
static bool timestamp_on_load;
|
static bool timestamp_on_load;
|
||||||
|
@ -96,7 +96,7 @@ class ResourceLoader {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static Ref<ResourceInteractiveLoader> load_interactive(const String &p_path,const String& p_type_hint="",bool p_no_cache=false,Error *r_error=NULL);
|
static Ref<ResourceInteractiveLoader> load_interactive(const String &p_path,const String& p_type_hint="",bool p_no_cache=false,Error *r_error=NULL);
|
||||||
static RES load(const String &p_path,const String& p_type_hint="",bool p_no_cache=false,Error *r_error=NULL);
|
static RES load(const String &p_path,const String& p_type_hint="",bool p_no_cache=false,Error *r_error=NULL);
|
||||||
static Ref<ResourceImportMetadata> load_import_metadata(const String &p_path);
|
static Ref<ResourceImportMetadata> load_import_metadata(const String &p_path);
|
||||||
|
|
|
@ -39,30 +39,30 @@ bool ResourceSaver::timestamp_on_save=false;
|
||||||
ResourceSavedCallback ResourceSaver::save_callback=0;
|
ResourceSavedCallback ResourceSaver::save_callback=0;
|
||||||
|
|
||||||
Error ResourceSaver::save(const String &p_path,const RES& p_resource,uint32_t p_flags) {
|
Error ResourceSaver::save(const String &p_path,const RES& p_resource,uint32_t p_flags) {
|
||||||
|
|
||||||
String extension=p_path.extension();
|
String extension=p_path.extension();
|
||||||
Error err=ERR_FILE_UNRECOGNIZED;
|
Error err=ERR_FILE_UNRECOGNIZED;
|
||||||
|
|
||||||
for (int i=0;i<saver_count;i++) {
|
for (int i=0;i<saver_count;i++) {
|
||||||
|
|
||||||
if (!saver[i]->recognize(p_resource))
|
if (!saver[i]->recognize(p_resource))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
List<String> extensions;
|
List<String> extensions;
|
||||||
bool recognized=false;
|
bool recognized=false;
|
||||||
saver[i]->get_recognized_extensions(p_resource,&extensions);
|
saver[i]->get_recognized_extensions(p_resource,&extensions);
|
||||||
|
|
||||||
for (List<String>::Element *E=extensions.front();E;E=E->next()) {
|
for (List<String>::Element *E=extensions.front();E;E=E->next()) {
|
||||||
|
|
||||||
if (E->get().nocasecmp_to(extension.extension())==0)
|
if (E->get().nocasecmp_to(extension.extension())==0)
|
||||||
recognized=true;
|
recognized=true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!recognized)
|
if (!recognized)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
String old_path=p_resource->get_path();
|
String old_path=p_resource->get_path();
|
||||||
|
|
||||||
|
|
||||||
String local_path=Globals::get_singleton()->localize_path(p_path);
|
String local_path=Globals::get_singleton()->localize_path(p_path);
|
||||||
|
|
||||||
|
@ -92,10 +92,10 @@ Error ResourceSaver::save(const String &p_path,const RES& p_resource,uint32_t p_
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,16 +108,16 @@ void ResourceSaver::set_save_callback(ResourceSavedCallback p_callback) {
|
||||||
|
|
||||||
void ResourceSaver::get_recognized_extensions(const RES& p_resource,List<String> *p_extensions) {
|
void ResourceSaver::get_recognized_extensions(const RES& p_resource,List<String> *p_extensions) {
|
||||||
|
|
||||||
|
|
||||||
for (int i=0;i<saver_count;i++) {
|
for (int i=0;i<saver_count;i++) {
|
||||||
|
|
||||||
saver[i]->get_recognized_extensions(p_resource,p_extensions);
|
saver[i]->get_recognized_extensions(p_resource,p_extensions);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceSaver::add_resource_format_saver(ResourceFormatSaver *p_format_saver) {
|
void ResourceSaver::add_resource_format_saver(ResourceFormatSaver *p_format_saver) {
|
||||||
|
|
||||||
ERR_FAIL_COND( saver_count >= MAX_SAVERS );
|
ERR_FAIL_COND( saver_count >= MAX_SAVERS );
|
||||||
saver[saver_count++]=p_format_saver;
|
saver[saver_count++]=p_format_saver;
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,7 @@
|
||||||
|
|
||||||
class ResourceFormatSaver {
|
class ResourceFormatSaver {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
virtual Error save(const String &p_path,const RES& p_resource,uint32_t p_flags=0)=0;
|
virtual Error save(const String &p_path,const RES& p_resource,uint32_t p_flags=0)=0;
|
||||||
virtual bool recognize(const RES& p_resource) const=0;
|
virtual bool recognize(const RES& p_resource) const=0;
|
||||||
virtual void get_recognized_extensions(const RES& p_resource,List<String> *p_extensions) const=0;
|
virtual void get_recognized_extensions(const RES& p_resource,List<String> *p_extensions) const=0;
|
||||||
|
@ -52,12 +52,12 @@ public:
|
||||||
|
|
||||||
typedef void (*ResourceSavedCallback)(const String& p_path);
|
typedef void (*ResourceSavedCallback)(const String& p_path);
|
||||||
|
|
||||||
class ResourceSaver {
|
class ResourceSaver {
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
MAX_SAVERS=64
|
MAX_SAVERS=64
|
||||||
};
|
};
|
||||||
|
|
||||||
static ResourceFormatSaver *saver[MAX_SAVERS];
|
static ResourceFormatSaver *saver[MAX_SAVERS];
|
||||||
static int saver_count;
|
static int saver_count;
|
||||||
static bool timestamp_on_save;
|
static bool timestamp_on_save;
|
||||||
|
@ -86,7 +86,7 @@ public:
|
||||||
static void set_save_callback(ResourceSavedCallback p_callback);
|
static void set_save_callback(ResourceSavedCallback p_callback);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -357,7 +357,6 @@ String StreamPeer::get_string(int p_bytes){
|
||||||
String StreamPeer::get_utf8_string(int p_bytes){
|
String StreamPeer::get_utf8_string(int p_bytes){
|
||||||
|
|
||||||
ERR_FAIL_COND_V(p_bytes<0,String());
|
ERR_FAIL_COND_V(p_bytes<0,String());
|
||||||
ERR_FAIL_COND_V(p_bytes<0,String());
|
|
||||||
|
|
||||||
Vector<uint8_t> buf;
|
Vector<uint8_t> buf;
|
||||||
buf.resize(p_bytes);
|
buf.resize(p_bytes);
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
Modifications for Zip64 support on both zip and unzip
|
Modifications for Zip64 support on both zip and unzip
|
||||||
Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
|
Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
|
||||||
|
|
||||||
For more info read MiniZip_info.txt
|
For more info read LICENSE-MiniZip.txt
|
||||||
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------------
|
------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
Modifications for Zip64 support on both zip and unzip
|
Modifications for Zip64 support on both zip and unzip
|
||||||
Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
|
Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
|
||||||
|
|
||||||
For more info read MiniZip_info.txt
|
For more info read LICENSE-MiniZip.txt
|
||||||
|
|
||||||
---------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
Modifications for Zip64 support
|
Modifications for Zip64 support
|
||||||
Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
|
Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
|
||||||
|
|
||||||
For more info read MiniZip_info.txt
|
For more info read LICENSE-MiniZip.txt
|
||||||
|
|
||||||
Changes
|
Changes
|
||||||
Oct-2009 - Mathias Svensson - Remove old C style function prototypes
|
Oct-2009 - Mathias Svensson - Remove old C style function prototypes
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
Modifications for Zip64 support
|
Modifications for Zip64 support
|
||||||
Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
|
Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
|
||||||
|
|
||||||
For more info read MiniZip_info.txt
|
For more info read LICENSE-MiniZip.txt
|
||||||
|
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -39,11 +39,14 @@ static void* zipio_open(void* data, const char* p_fname, int mode) {
|
||||||
|
|
||||||
FileAccess *&f = *(FileAccess**)data;
|
FileAccess *&f = *(FileAccess**)data;
|
||||||
|
|
||||||
|
String fname;
|
||||||
|
fname.parse_utf8(p_fname);
|
||||||
|
|
||||||
if (mode & ZLIB_FILEFUNC_MODE_WRITE) {
|
if (mode & ZLIB_FILEFUNC_MODE_WRITE) {
|
||||||
f = FileAccess::open(p_fname,FileAccess::WRITE);
|
f = FileAccess::open(fname,FileAccess::WRITE);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
f = FileAccess::open(p_fname,FileAccess::READ);
|
f = FileAccess::open(fname,FileAccess::READ);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!f)
|
if (!f)
|
||||||
|
|
52
core/list.h
52
core/list.h
|
@ -245,7 +245,7 @@ public:
|
||||||
_data->first=n;
|
_data->first=n;
|
||||||
|
|
||||||
_data->size_cache++;
|
_data->size_cache++;
|
||||||
|
|
||||||
return n;
|
return n;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -285,7 +285,7 @@ public:
|
||||||
_data->last=n;
|
_data->last=n;
|
||||||
|
|
||||||
_data->size_cache++;
|
_data->size_cache++;
|
||||||
|
|
||||||
return n;
|
return n;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -363,30 +363,30 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void swap(Element* p_A, Element *p_B) {
|
void swap(Element* p_A, Element *p_B) {
|
||||||
|
|
||||||
ERR_FAIL_COND(!p_A || !p_B);
|
ERR_FAIL_COND(!p_A || !p_B);
|
||||||
ERR_FAIL_COND(p_A->data!=_data);
|
ERR_FAIL_COND(p_A->data!=_data);
|
||||||
ERR_FAIL_COND(p_B->data!=_data);
|
ERR_FAIL_COND(p_B->data!=_data);
|
||||||
|
|
||||||
Element* A_prev=p_A->prev_ptr;
|
Element* A_prev=p_A->prev_ptr;
|
||||||
Element* A_next=p_A->next_ptr;
|
Element* A_next=p_A->next_ptr;
|
||||||
|
|
||||||
p_A->next_ptr=p_B->next_ptr;
|
p_A->next_ptr=p_B->next_ptr;
|
||||||
p_A->prev_ptr=p_B->prev_ptr;
|
p_A->prev_ptr=p_B->prev_ptr;
|
||||||
|
|
||||||
p_B->next_ptr=A_next;
|
p_B->next_ptr=A_next;
|
||||||
p_B->prev_ptr=A_prev;
|
p_B->prev_ptr=A_prev;
|
||||||
|
|
||||||
if (p_A->prev_ptr)
|
if (p_A->prev_ptr)
|
||||||
p_A->prev_ptr->next_ptr=p_A;
|
p_A->prev_ptr->next_ptr=p_A;
|
||||||
if (p_A->next_ptr)
|
if (p_A->next_ptr)
|
||||||
p_A->next_ptr->prev_ptr=p_A;
|
p_A->next_ptr->prev_ptr=p_A;
|
||||||
|
|
||||||
if (p_B->prev_ptr)
|
if (p_B->prev_ptr)
|
||||||
p_B->prev_ptr->next_ptr=p_B;
|
p_B->prev_ptr->next_ptr=p_B;
|
||||||
if (p_B->next_ptr)
|
if (p_B->next_ptr)
|
||||||
p_B->next_ptr->prev_ptr=p_B;
|
p_B->next_ptr->prev_ptr=p_B;
|
||||||
|
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* copy the list
|
* copy the list
|
||||||
|
@ -552,10 +552,10 @@ public:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void sort() {
|
void sort() {
|
||||||
|
|
||||||
sort_custom< Comparator<T> >();
|
sort_custom< Comparator<T> >();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class C>
|
template<class C>
|
||||||
void sort_custom_inplace() {
|
void sort_custom_inplace() {
|
||||||
|
|
||||||
|
@ -565,44 +565,44 @@ public:
|
||||||
Element *from=front();
|
Element *from=front();
|
||||||
Element *current=from;
|
Element *current=from;
|
||||||
Element *to=from;
|
Element *to=from;
|
||||||
|
|
||||||
while(current) {
|
while(current) {
|
||||||
|
|
||||||
Element *next=current->next_ptr;
|
Element *next=current->next_ptr;
|
||||||
|
|
||||||
//disconnect
|
//disconnect
|
||||||
current->next_ptr=NULL;
|
current->next_ptr=NULL;
|
||||||
|
|
||||||
if (from!=current) {
|
if (from!=current) {
|
||||||
|
|
||||||
current->prev_ptr=NULL;
|
current->prev_ptr=NULL;
|
||||||
current->next_ptr=from;
|
current->next_ptr=from;
|
||||||
|
|
||||||
Element *find=from;
|
Element *find=from;
|
||||||
C less;
|
C less;
|
||||||
while( find && less(find->value,current->value) ) {
|
while( find && less(find->value,current->value) ) {
|
||||||
|
|
||||||
current->prev_ptr=find;
|
current->prev_ptr=find;
|
||||||
current->next_ptr=find->next_ptr;
|
current->next_ptr=find->next_ptr;
|
||||||
find=find->next_ptr;
|
find=find->next_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (current->prev_ptr)
|
if (current->prev_ptr)
|
||||||
current->prev_ptr->next_ptr=current;
|
current->prev_ptr->next_ptr=current;
|
||||||
else
|
else
|
||||||
from=current;
|
from=current;
|
||||||
|
|
||||||
if (current->next_ptr)
|
if (current->next_ptr)
|
||||||
current->next_ptr->prev_ptr=current;
|
current->next_ptr->prev_ptr=current;
|
||||||
else
|
else
|
||||||
to=current;
|
to=current;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
current->prev_ptr=NULL;
|
current->prev_ptr=NULL;
|
||||||
current->next_ptr=NULL;
|
current->next_ptr=NULL;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
current=next;
|
current=next;
|
||||||
}
|
}
|
||||||
_data->first=from;
|
_data->first=from;
|
||||||
|
|
|
@ -6,7 +6,7 @@ template_typed="""
|
||||||
template<class T $ifret ,class R$ $ifargs ,$ $arg, class P@$>
|
template<class T $ifret ,class R$ $ifargs ,$ $arg, class P@$>
|
||||||
class MethodBind$argc$$ifret R$$ifconst C$ : public MethodBind {
|
class MethodBind$argc$$ifret R$$ifconst C$ : public MethodBind {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
$ifret R$ $ifnoret void$ (T::*method)($arg, P@$) $ifconst const$;
|
$ifret R$ $ifnoret void$ (T::*method)($arg, P@$) $ifconst const$;
|
||||||
#ifdef DEBUG_METHODS_ENABLED
|
#ifdef DEBUG_METHODS_ENABLED
|
||||||
virtual Variant::Type _gen_argument_type(int p_arg) const { return _get_argument_type(p_arg); }
|
virtual Variant::Type _gen_argument_type(int p_arg) const { return _get_argument_type(p_arg); }
|
||||||
|
@ -16,13 +16,13 @@ public:
|
||||||
$
|
$
|
||||||
return Variant::NIL;
|
return Variant::NIL;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
virtual String get_instance_type() const {
|
virtual String get_instance_type() const {
|
||||||
return T::get_type_static();
|
return T::get_type_static();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Variant call(Object* p_object,const Variant** p_args,int p_arg_count, Variant::CallError& r_error) {
|
virtual Variant call(Object* p_object,const Variant** p_args,int p_arg_count, Variant::CallError& r_error) {
|
||||||
|
|
||||||
T *instance=p_object->cast_to<T>();
|
T *instance=p_object->cast_to<T>();
|
||||||
r_error.error=Variant::CallError::CALL_OK;
|
r_error.error=Variant::CallError::CALL_OK;
|
||||||
#ifdef DEBUG_METHODS_ENABLED
|
#ifdef DEBUG_METHODS_ENABLED
|
||||||
|
@ -47,7 +47,7 @@ public:
|
||||||
$ifret return Variant(ret);$
|
$ifret return Variant(ret);$
|
||||||
$ifnoret return Variant();$
|
$ifnoret return Variant();$
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MethodBind$argc$$ifret R$$ifconst C$ () {
|
MethodBind$argc$$ifret R$$ifconst C$ () {
|
||||||
#ifdef DEBUG_METHODS_ENABLED
|
#ifdef DEBUG_METHODS_ENABLED
|
||||||
|
@ -55,14 +55,14 @@ public:
|
||||||
_generate_argument_types($argc$);
|
_generate_argument_types($argc$);
|
||||||
#else
|
#else
|
||||||
set_argument_count($argc$);
|
set_argument_count($argc$);
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class T $ifret ,class R$ $ifargs ,$ $arg, class P@$>
|
template<class T $ifret ,class R$ $ifargs ,$ $arg, class P@$>
|
||||||
MethodBind* create_method_bind($ifret R$ $ifnoret void$ (T::*p_method)($arg, P@$) $ifconst const$ ) {
|
MethodBind* create_method_bind($ifret R$ $ifnoret void$ (T::*p_method)($arg, P@$) $ifconst const$ ) {
|
||||||
|
|
||||||
MethodBind$argc$$ifret R$$ifconst C$<T $ifret ,R$ $ifargs ,$ $arg, P@$> * a = memnew( (MethodBind$argc$$ifret R$$ifconst C$<T $ifret ,R$ $ifargs ,$ $arg, P@$>) );
|
MethodBind$argc$$ifret R$$ifconst C$<T $ifret ,R$ $ifargs ,$ $arg, P@$> * a = memnew( (MethodBind$argc$$ifret R$$ifconst C$<T $ifret ,R$ $ifargs ,$ $arg, P@$>) );
|
||||||
a->method=p_method;
|
a->method=p_method;
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
@ -88,7 +88,7 @@ public:
|
||||||
$
|
$
|
||||||
return Variant::NIL;
|
return Variant::NIL;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
virtual String get_instance_type() const {
|
virtual String get_instance_type() const {
|
||||||
return type_name;
|
return type_name;
|
||||||
}
|
}
|
||||||
|
@ -105,15 +105,15 @@ public:
|
||||||
r_error.error=Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
|
r_error.error=Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
|
||||||
r_error.argument=get_argument_count();
|
r_error.argument=get_argument_count();
|
||||||
return Variant();
|
return Variant();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p_arg_count<(get_argument_count()-get_default_argument_count())) {
|
if (p_arg_count<(get_argument_count()-get_default_argument_count())) {
|
||||||
|
|
||||||
r_error.error=Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
|
r_error.error=Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
|
||||||
r_error.argument=get_argument_count()-get_default_argument_count();
|
r_error.argument=get_argument_count()-get_default_argument_count();
|
||||||
return Variant();
|
return Variant();
|
||||||
}
|
}
|
||||||
|
|
||||||
$arg CHECK_ARG(@);
|
$arg CHECK_ARG(@);
|
||||||
$
|
$
|
||||||
#endif
|
#endif
|
||||||
|
@ -128,7 +128,7 @@ public:
|
||||||
_generate_argument_types($argc$);
|
_generate_argument_types($argc$);
|
||||||
#else
|
#else
|
||||||
set_argument_count($argc$);
|
set_argument_count($argc$);
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -151,12 +151,12 @@ MethodBind* create_method_bind($ifret R$ $ifnoret void$ (T::*p_method)($arg, P@$
|
||||||
|
|
||||||
|
|
||||||
def make_version(template,nargs,argmax,const,ret):
|
def make_version(template,nargs,argmax,const,ret):
|
||||||
|
|
||||||
intext=template
|
intext=template
|
||||||
from_pos=0
|
from_pos=0
|
||||||
outtext=""
|
outtext=""
|
||||||
|
|
||||||
while(True):
|
while(True):
|
||||||
to_pos=intext.find("$",from_pos)
|
to_pos=intext.find("$",from_pos)
|
||||||
if (to_pos==-1):
|
if (to_pos==-1):
|
||||||
outtext+=intext[from_pos:]
|
outtext+=intext[from_pos:]
|
||||||
|
@ -169,13 +169,13 @@ def make_version(template,nargs,argmax,const,ret):
|
||||||
macro=intext[to_pos+1:end]
|
macro=intext[to_pos+1:end]
|
||||||
cmd=""
|
cmd=""
|
||||||
data=""
|
data=""
|
||||||
|
|
||||||
if (macro.find(" ")!=-1):
|
if (macro.find(" ")!=-1):
|
||||||
cmd=macro[0:macro.find(" ")]
|
cmd=macro[0:macro.find(" ")]
|
||||||
data=macro[macro.find(" ")+1:]
|
data=macro[macro.find(" ")+1:]
|
||||||
else:
|
else:
|
||||||
cmd=macro
|
cmd=macro
|
||||||
|
|
||||||
if (cmd=="argc"):
|
if (cmd=="argc"):
|
||||||
outtext+=str(nargs)
|
outtext+=str(nargs)
|
||||||
if (cmd=="ifret" and ret):
|
if (cmd=="ifret" and ret):
|
||||||
|
@ -206,11 +206,11 @@ def make_version(template,nargs,argmax,const,ret):
|
||||||
elif (cmd=="noarg"):
|
elif (cmd=="noarg"):
|
||||||
for i in range(nargs+1,argmax+1):
|
for i in range(nargs+1,argmax+1):
|
||||||
outtext+=data.replace("@",str(i))
|
outtext+=data.replace("@",str(i))
|
||||||
|
|
||||||
from_pos=end+1
|
from_pos=end+1
|
||||||
|
|
||||||
return outtext
|
return outtext
|
||||||
|
|
||||||
|
|
||||||
def run(target, source, env):
|
def run(target, source, env):
|
||||||
|
|
||||||
|
@ -244,9 +244,9 @@ def run(target, source, env):
|
||||||
f.write(text_ext)
|
f.write(text_ext)
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
284
core/map.h
284
core/map.h
|
@ -39,12 +39,12 @@
|
||||||
|
|
||||||
template <class K,class V,class C=Comparator<K>,class A=DefaultAllocator>
|
template <class K,class V,class C=Comparator<K>,class A=DefaultAllocator>
|
||||||
class Map {
|
class Map {
|
||||||
|
|
||||||
enum Color {
|
enum Color {
|
||||||
RED,
|
RED,
|
||||||
BLACK
|
BLACK
|
||||||
};
|
};
|
||||||
struct _Data;
|
struct _Data;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
class Element {
|
class Element {
|
||||||
|
@ -66,34 +66,34 @@ public:
|
||||||
public:
|
public:
|
||||||
|
|
||||||
const Element *next() const {
|
const Element *next() const {
|
||||||
|
|
||||||
return _next;
|
return _next;
|
||||||
}
|
}
|
||||||
Element *next() {
|
Element *next() {
|
||||||
|
|
||||||
return _next;
|
return _next;
|
||||||
}
|
}
|
||||||
const Element *prev() const {
|
const Element *prev() const {
|
||||||
|
|
||||||
return _prev;
|
return _prev;
|
||||||
}
|
}
|
||||||
Element *prev() {
|
Element *prev() {
|
||||||
|
|
||||||
return _prev;
|
return _prev;
|
||||||
}
|
}
|
||||||
const K& key() const {
|
const K& key() const {
|
||||||
return _key;
|
return _key;
|
||||||
};
|
};
|
||||||
V& value() {
|
V& value() {
|
||||||
return _value;
|
return _value;
|
||||||
};
|
};
|
||||||
const V& value() const {
|
const V& value() const {
|
||||||
return _value;
|
return _value;
|
||||||
};
|
};
|
||||||
V& get() {
|
V& get() {
|
||||||
return _value;
|
return _value;
|
||||||
};
|
};
|
||||||
const V& get() const {
|
const V& get() const {
|
||||||
return _value;
|
return _value;
|
||||||
};
|
};
|
||||||
Element() {
|
Element() {
|
||||||
|
@ -106,15 +106,15 @@ public:
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
struct _Data {
|
struct _Data {
|
||||||
|
|
||||||
Element* _root;
|
Element* _root;
|
||||||
Element* _nil;
|
Element* _nil;
|
||||||
int size_cache;
|
int size_cache;
|
||||||
|
|
||||||
_FORCE_INLINE_ _Data() {
|
_FORCE_INLINE_ _Data() {
|
||||||
#ifdef GLOBALNIL_DISABLED
|
#ifdef GLOBALNIL_DISABLED
|
||||||
_nil = memnew_allocator( Element, A );
|
_nil = memnew_allocator( Element, A );
|
||||||
|
@ -126,7 +126,7 @@ private:
|
||||||
_root=NULL;
|
_root=NULL;
|
||||||
size_cache=0;
|
size_cache=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _create_root() {
|
void _create_root() {
|
||||||
|
|
||||||
_root = memnew_allocator( Element,A );
|
_root = memnew_allocator( Element,A );
|
||||||
|
@ -145,23 +145,23 @@ private:
|
||||||
~_Data() {
|
~_Data() {
|
||||||
|
|
||||||
_free_root();
|
_free_root();
|
||||||
|
|
||||||
#ifdef GLOBALNIL_DISABLED
|
#ifdef GLOBALNIL_DISABLED
|
||||||
memdelete_allocator<Element,A>(_nil);
|
memdelete_allocator<Element,A>(_nil);
|
||||||
#endif
|
#endif
|
||||||
// memdelete_allocator<Element,A>(_root);
|
// memdelete_allocator<Element,A>(_root);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
_Data _data;
|
_Data _data;
|
||||||
|
|
||||||
inline void _set_color(Element *p_node, int p_color) {
|
inline void _set_color(Element *p_node, int p_color) {
|
||||||
|
|
||||||
ERR_FAIL_COND( p_node == _data._nil && p_color == RED );
|
ERR_FAIL_COND( p_node == _data._nil && p_color == RED );
|
||||||
p_node->color=p_color;
|
p_node->color=p_color;
|
||||||
}
|
}
|
||||||
inline void _rotate_left(Element *p_node) {
|
inline void _rotate_left(Element *p_node) {
|
||||||
|
|
||||||
Element *r=p_node->right;
|
Element *r=p_node->right;
|
||||||
p_node->right=r->left;
|
p_node->right=r->left;
|
||||||
if (r->left != _data._nil )
|
if (r->left != _data._nil )
|
||||||
|
@ -171,14 +171,14 @@ private:
|
||||||
p_node->parent->left=r;
|
p_node->parent->left=r;
|
||||||
else
|
else
|
||||||
p_node->parent->right=r;
|
p_node->parent->right=r;
|
||||||
|
|
||||||
r->left=p_node;
|
r->left=p_node;
|
||||||
p_node->parent=r;
|
p_node->parent=r;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void _rotate_right(Element *p_node) {
|
inline void _rotate_right(Element *p_node) {
|
||||||
|
|
||||||
Element *l=p_node->left;
|
Element *l=p_node->left;
|
||||||
p_node->left=l->right;
|
p_node->left=l->right;
|
||||||
if (l->right != _data._nil)
|
if (l->right != _data._nil)
|
||||||
|
@ -188,25 +188,25 @@ private:
|
||||||
p_node->parent->right=l;
|
p_node->parent->right=l;
|
||||||
else
|
else
|
||||||
p_node->parent->left=l;
|
p_node->parent->left=l;
|
||||||
|
|
||||||
l->right=p_node;
|
l->right=p_node;
|
||||||
p_node->parent=l;
|
p_node->parent=l;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Element* _successor(Element *p_node) const {
|
inline Element* _successor(Element *p_node) const {
|
||||||
|
|
||||||
Element *node=p_node;
|
Element *node=p_node;
|
||||||
|
|
||||||
if (node->right != _data._nil) {
|
if (node->right != _data._nil) {
|
||||||
|
|
||||||
node=node->right;
|
node=node->right;
|
||||||
while(node->left != _data._nil) { /* returns the minium of the right subtree of node */
|
while(node->left != _data._nil) { /* returns the minium of the right subtree of node */
|
||||||
node=node->left;
|
node=node->left;
|
||||||
}
|
}
|
||||||
return node;
|
return node;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
while(node == node->parent->right) {
|
while(node == node->parent->right) {
|
||||||
node=node->parent;
|
node=node->parent;
|
||||||
}
|
}
|
||||||
|
@ -215,44 +215,44 @@ private:
|
||||||
return node->parent;
|
return node->parent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Element* _predecessor(Element *p_node) const {
|
inline Element* _predecessor(Element *p_node) const {
|
||||||
Element *node=p_node;
|
Element *node=p_node;
|
||||||
|
|
||||||
if (node->left != _data._nil) {
|
if (node->left != _data._nil) {
|
||||||
|
|
||||||
node=node->left;
|
node=node->left;
|
||||||
while(node->right != _data._nil) { /* returns the minium of the left subtree of node */
|
while(node->right != _data._nil) { /* returns the minium of the left subtree of node */
|
||||||
node=node->right;
|
node=node->right;
|
||||||
}
|
}
|
||||||
return node;
|
return node;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
while(node == node->parent->left) {
|
while(node == node->parent->left) {
|
||||||
if (node->parent == _data._root)
|
if (node->parent == _data._root)
|
||||||
return NULL;
|
return NULL;
|
||||||
node=node->parent;
|
node=node->parent;
|
||||||
}
|
}
|
||||||
return node->parent;
|
return node->parent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Element *_find(const K& p_key) const {
|
Element *_find(const K& p_key) const {
|
||||||
|
|
||||||
Element *node = _data._root->left;
|
Element *node = _data._root->left;
|
||||||
C less;
|
C less;
|
||||||
|
|
||||||
while(node!=_data._nil) {
|
while(node!=_data._nil) {
|
||||||
|
|
||||||
if (less(p_key,node->_key))
|
if (less(p_key,node->_key))
|
||||||
node=node->left;
|
node=node->left;
|
||||||
else if (less(node->_key,p_key))
|
else if (less(node->_key,p_key))
|
||||||
node=node->right;
|
node=node->right;
|
||||||
else
|
else
|
||||||
break; // found
|
break; // found
|
||||||
}
|
}
|
||||||
|
|
||||||
return (node!=_data._nil)?node:NULL;
|
return (node!=_data._nil)?node:NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -289,73 +289,73 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
Element *_insert(const K& p_key, bool& r_exists) {
|
Element *_insert(const K& p_key, bool& r_exists) {
|
||||||
|
|
||||||
Element *new_parent=_data._root;
|
Element *new_parent=_data._root;
|
||||||
Element *node = _data._root->left;
|
Element *node = _data._root->left;
|
||||||
C less;
|
C less;
|
||||||
|
|
||||||
while (node!=_data._nil) {
|
while (node!=_data._nil) {
|
||||||
|
|
||||||
new_parent=node;
|
new_parent=node;
|
||||||
|
|
||||||
if (less(p_key,node->_key))
|
if (less(p_key,node->_key))
|
||||||
node=node->left;
|
node=node->left;
|
||||||
else if (less(node->_key,p_key))
|
else if (less(node->_key,p_key))
|
||||||
node=node->right;
|
node=node->right;
|
||||||
else {
|
else {
|
||||||
r_exists=true;
|
r_exists=true;
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Element *new_node = memnew_allocator( Element, A );
|
Element *new_node = memnew_allocator( Element, A );
|
||||||
|
|
||||||
|
|
||||||
new_node->parent=new_parent;
|
new_node->parent=new_parent;
|
||||||
new_node->right=_data._nil;
|
new_node->right=_data._nil;
|
||||||
new_node->left=_data._nil;
|
new_node->left=_data._nil;
|
||||||
new_node->_key=p_key;
|
new_node->_key=p_key;
|
||||||
//new_node->data=_data;
|
//new_node->data=_data;
|
||||||
if (new_parent==_data._root || less(p_key,new_parent->_key)) {
|
if (new_parent==_data._root || less(p_key,new_parent->_key)) {
|
||||||
|
|
||||||
new_parent->left=new_node;
|
new_parent->left=new_node;
|
||||||
} else {
|
} else {
|
||||||
new_parent->right=new_node;
|
new_parent->right=new_node;
|
||||||
}
|
}
|
||||||
|
|
||||||
r_exists=false;
|
r_exists=false;
|
||||||
|
|
||||||
new_node->_next=_successor(new_node);
|
new_node->_next=_successor(new_node);
|
||||||
new_node->_prev=_predecessor(new_node);
|
new_node->_prev=_predecessor(new_node);
|
||||||
if (new_node->_next)
|
if (new_node->_next)
|
||||||
new_node->_next->_prev=new_node;
|
new_node->_next->_prev=new_node;
|
||||||
if (new_node->_prev)
|
if (new_node->_prev)
|
||||||
new_node->_prev->_next=new_node;
|
new_node->_prev->_next=new_node;
|
||||||
|
|
||||||
|
|
||||||
return new_node;
|
return new_node;
|
||||||
}
|
}
|
||||||
|
|
||||||
Element * _insert_rb(const K& p_key, const V& p_value) {
|
Element * _insert_rb(const K& p_key, const V& p_value) {
|
||||||
|
|
||||||
bool exists=false;
|
bool exists=false;
|
||||||
Element *new_node = _insert(p_key,exists);
|
Element *new_node = _insert(p_key,exists);
|
||||||
|
|
||||||
if (new_node) {
|
if (new_node) {
|
||||||
new_node->_value=p_value;
|
new_node->_value=p_value;
|
||||||
}
|
}
|
||||||
if (exists)
|
if (exists)
|
||||||
return new_node;
|
return new_node;
|
||||||
|
|
||||||
Element *node=new_node;
|
Element *node=new_node;
|
||||||
_data.size_cache++;
|
_data.size_cache++;
|
||||||
|
|
||||||
while(node->parent->color==RED) {
|
while(node->parent->color==RED) {
|
||||||
|
|
||||||
if (node->parent == node->parent->parent->left) {
|
if (node->parent == node->parent->parent->left) {
|
||||||
|
|
||||||
Element *aux=node->parent->parent->right;
|
Element *aux=node->parent->parent->right;
|
||||||
|
|
||||||
if (aux->color==RED) {
|
if (aux->color==RED) {
|
||||||
_set_color(node->parent,BLACK);
|
_set_color(node->parent,BLACK);
|
||||||
_set_color(aux,BLACK);
|
_set_color(aux,BLACK);
|
||||||
|
@ -369,10 +369,10 @@ private:
|
||||||
_set_color(node->parent,BLACK);
|
_set_color(node->parent,BLACK);
|
||||||
_set_color(node->parent->parent,RED);
|
_set_color(node->parent->parent,RED);
|
||||||
_rotate_right(node->parent->parent);
|
_rotate_right(node->parent->parent);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Element *aux=node->parent->parent->left;
|
Element *aux=node->parent->parent->left;
|
||||||
|
|
||||||
if (aux->color==RED) {
|
if (aux->color==RED) {
|
||||||
_set_color(node->parent,BLACK);
|
_set_color(node->parent,BLACK);
|
||||||
_set_color(aux,BLACK);
|
_set_color(aux,BLACK);
|
||||||
|
@ -386,19 +386,19 @@ private:
|
||||||
_set_color(node->parent,BLACK);
|
_set_color(node->parent,BLACK);
|
||||||
_set_color(node->parent->parent,RED);
|
_set_color(node->parent->parent,RED);
|
||||||
_rotate_left(node->parent->parent);
|
_rotate_left(node->parent->parent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_set_color(_data._root->left,BLACK);
|
_set_color(_data._root->left,BLACK);
|
||||||
return new_node;
|
return new_node;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _erase_fix(Element *p_node) {
|
void _erase_fix(Element *p_node) {
|
||||||
|
|
||||||
Element *root = _data._root->left;
|
Element *root = _data._root->left;
|
||||||
Element *node=p_node;
|
Element *node=p_node;
|
||||||
|
|
||||||
|
|
||||||
while( (node->color==BLACK) && (root != node)) {
|
while( (node->color==BLACK) && (root != node)) {
|
||||||
if (node == node->parent->left) {
|
if (node == node->parent->left) {
|
||||||
Element *aux=node->parent->right;
|
Element *aux=node->parent->right;
|
||||||
|
@ -408,7 +408,7 @@ private:
|
||||||
_rotate_left(node->parent);
|
_rotate_left(node->parent);
|
||||||
aux=node->parent->right;
|
aux=node->parent->right;
|
||||||
}
|
}
|
||||||
if ( (aux->right->color==BLACK) && (aux->left->color==BLACK) ) {
|
if ( (aux->right->color==BLACK) && (aux->left->color==BLACK) ) {
|
||||||
_set_color(aux,RED);
|
_set_color(aux,RED);
|
||||||
node=node->parent;
|
node=node->parent;
|
||||||
} else {
|
} else {
|
||||||
|
@ -432,7 +432,7 @@ private:
|
||||||
_rotate_right(node->parent);
|
_rotate_right(node->parent);
|
||||||
aux=node->parent->left;
|
aux=node->parent->left;
|
||||||
}
|
}
|
||||||
if ( (aux->right->color==BLACK) && (aux->left->color==BLACK) ) {
|
if ( (aux->right->color==BLACK) && (aux->left->color==BLACK) ) {
|
||||||
_set_color(aux,RED);
|
_set_color(aux,RED);
|
||||||
node=node->parent;
|
node=node->parent;
|
||||||
} else {
|
} else {
|
||||||
|
@ -446,24 +446,24 @@ private:
|
||||||
_set_color(node->parent,BLACK);
|
_set_color(node->parent,BLACK);
|
||||||
_set_color(aux->left,BLACK);
|
_set_color(aux->left,BLACK);
|
||||||
_rotate_right(node->parent);
|
_rotate_right(node->parent);
|
||||||
node=root;
|
node=root;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_set_color(node,BLACK);
|
_set_color(node,BLACK);
|
||||||
|
|
||||||
ERR_FAIL_COND(_data._nil->color!=BLACK);
|
ERR_FAIL_COND(_data._nil->color!=BLACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _erase(Element *p_node) {
|
void _erase(Element *p_node) {
|
||||||
|
|
||||||
|
|
||||||
Element *rp= ((p_node->left == _data._nil) || (p_node->right == _data._nil)) ? p_node : _successor(p_node);
|
Element *rp= ((p_node->left == _data._nil) || (p_node->right == _data._nil)) ? p_node : _successor(p_node);
|
||||||
if (!rp)
|
if (!rp)
|
||||||
rp=_data._nil;
|
rp=_data._nil;
|
||||||
Element *node= (rp->left == _data._nil) ? rp->right : rp->left;
|
Element *node= (rp->left == _data._nil) ? rp->right : rp->left;
|
||||||
|
|
||||||
if (_data._root == (node->parent=rp->parent) ) {
|
if (_data._root == (node->parent=rp->parent) ) {
|
||||||
_data._root->left=node;
|
_data._root->left=node;
|
||||||
} else {
|
} else {
|
||||||
|
@ -473,47 +473,47 @@ private:
|
||||||
rp->parent->right=node;
|
rp->parent->right=node;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rp != p_node) {
|
if (rp != p_node) {
|
||||||
|
|
||||||
ERR_FAIL_COND( rp == _data._nil );
|
ERR_FAIL_COND( rp == _data._nil );
|
||||||
|
|
||||||
if (rp->color==BLACK)
|
if (rp->color==BLACK)
|
||||||
_erase_fix(node);
|
_erase_fix(node);
|
||||||
|
|
||||||
|
|
||||||
rp->left=p_node->left;
|
rp->left=p_node->left;
|
||||||
rp->right=p_node->right;
|
rp->right=p_node->right;
|
||||||
rp->parent=p_node->parent;
|
rp->parent=p_node->parent;
|
||||||
rp->color=p_node->color;
|
rp->color=p_node->color;
|
||||||
p_node->left->parent=rp;
|
p_node->left->parent=rp;
|
||||||
p_node->right->parent=rp;
|
p_node->right->parent=rp;
|
||||||
|
|
||||||
if (p_node == p_node->parent->left) {
|
if (p_node == p_node->parent->left) {
|
||||||
p_node->parent->left=rp;
|
p_node->parent->left=rp;
|
||||||
} else {
|
} else {
|
||||||
p_node->parent->right=rp;
|
p_node->parent->right=rp;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (p_node->color==BLACK)
|
if (p_node->color==BLACK)
|
||||||
_erase_fix(node);
|
_erase_fix(node);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (p_node->_next)
|
if (p_node->_next)
|
||||||
p_node->_next->_prev=p_node->_prev;
|
p_node->_next->_prev=p_node->_prev;
|
||||||
if (p_node->_prev)
|
if (p_node->_prev)
|
||||||
p_node->_prev->_next=p_node->_next;
|
p_node->_prev->_next=p_node->_next;
|
||||||
|
|
||||||
memdelete_allocator<Element,A>(p_node);
|
memdelete_allocator<Element,A>(p_node);
|
||||||
_data.size_cache--;
|
_data.size_cache--;
|
||||||
ERR_FAIL_COND( _data._nil->color==RED );
|
ERR_FAIL_COND( _data._nil->color==RED );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void _calculate_depth(Element *p_element,int &max_d,int d) const {
|
void _calculate_depth(Element *p_element,int &max_d,int d) const {
|
||||||
|
|
||||||
if (p_element==_data._nil) {
|
if (p_element==_data._nil) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -522,23 +522,23 @@ private:
|
||||||
if (d>max_d)
|
if (d>max_d)
|
||||||
max_d=d;
|
max_d=d;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _cleanup_tree(Element *p_element) {
|
void _cleanup_tree(Element *p_element) {
|
||||||
|
|
||||||
if (p_element==_data._nil)
|
if (p_element==_data._nil)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_cleanup_tree(p_element->left);
|
_cleanup_tree(p_element->left);
|
||||||
_cleanup_tree(p_element->right);
|
_cleanup_tree(p_element->right);
|
||||||
memdelete_allocator<Element,A>( p_element );
|
memdelete_allocator<Element,A>( p_element );
|
||||||
}
|
}
|
||||||
|
|
||||||
void _copy_from( const Map& p_map) {
|
void _copy_from( const Map& p_map) {
|
||||||
|
|
||||||
clear();
|
clear();
|
||||||
// not the fastest way, but safeset to write.
|
// not the fastest way, but safeset to write.
|
||||||
for(Element *I=p_map.front();I;I=I->next()) {
|
for(Element *I=p_map.front();I;I=I->next()) {
|
||||||
|
|
||||||
insert(I->key(),I->value());
|
insert(I->key(),I->value());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -554,7 +554,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
Element *find(const K& p_key) {
|
Element *find(const K& p_key) {
|
||||||
|
|
||||||
if (!_data._root)
|
if (!_data._root)
|
||||||
return NULL;
|
return NULL;
|
||||||
Element *res=_find(p_key);
|
Element *res=_find(p_key);
|
||||||
|
@ -578,15 +578,15 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
Element *insert(const K& p_key,const V& p_value) {
|
Element *insert(const K& p_key,const V& p_value) {
|
||||||
|
|
||||||
if (!_data._root)
|
if (!_data._root)
|
||||||
_data._create_root();
|
_data._create_root();
|
||||||
return _insert_rb(p_key,p_value);
|
return _insert_rb(p_key,p_value);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void erase(Element* p_element) {
|
void erase(Element* p_element) {
|
||||||
|
|
||||||
if (!_data._root)
|
if (!_data._root)
|
||||||
return;
|
return;
|
||||||
_erase(p_element);
|
_erase(p_element);
|
||||||
|
@ -595,72 +595,72 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
bool erase(const K& p_key) {
|
bool erase(const K& p_key) {
|
||||||
|
|
||||||
if (!_data._root)
|
if (!_data._root)
|
||||||
return false;
|
return false;
|
||||||
Element *e=find(p_key);
|
Element *e=find(p_key);
|
||||||
if (!e)
|
if (!e)
|
||||||
return false;
|
return false;
|
||||||
_erase(e);
|
_erase(e);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool has(const K& p_key) const {
|
bool has(const K& p_key) const {
|
||||||
|
|
||||||
if (!_data._root)
|
if (!_data._root)
|
||||||
return false;
|
return false;
|
||||||
return find(p_key) != NULL;
|
return find(p_key) != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
const V& operator[](const K& p_key) const {
|
const V& operator[](const K& p_key) const {
|
||||||
|
|
||||||
ERR_FAIL_COND_V(!_data._root, *(V*)NULL); // crash on purpose
|
ERR_FAIL_COND_V(!_data._root, *(V*)NULL); // crash on purpose
|
||||||
const Element *e=find(p_key);
|
const Element *e=find(p_key);
|
||||||
ERR_FAIL_COND_V(!e, *(V*)NULL); // crash on purpose
|
ERR_FAIL_COND_V(!e, *(V*)NULL); // crash on purpose
|
||||||
return e->_value;
|
return e->_value;
|
||||||
}
|
}
|
||||||
V& operator[](const K& p_key) {
|
V& operator[](const K& p_key) {
|
||||||
|
|
||||||
if (!_data._root)
|
if (!_data._root)
|
||||||
_data._create_root();
|
_data._create_root();
|
||||||
|
|
||||||
Element *e=find(p_key);
|
Element *e=find(p_key);
|
||||||
if (!e)
|
if (!e)
|
||||||
e=insert(p_key,V());
|
e=insert(p_key,V());
|
||||||
|
|
||||||
ERR_FAIL_COND_V(!e, *(V*)NULL); // crash on purpose
|
ERR_FAIL_COND_V(!e, *(V*)NULL); // crash on purpose
|
||||||
return e->_value;
|
return e->_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
Element *front() const {
|
Element *front() const {
|
||||||
|
|
||||||
if (!_data._root)
|
if (!_data._root)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
Element *e=_data._root->left;
|
Element *e=_data._root->left;
|
||||||
if (e==_data._nil)
|
if (e==_data._nil)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
while(e->left!=_data._nil)
|
while(e->left!=_data._nil)
|
||||||
e=e->left;
|
e=e->left;
|
||||||
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
Element *back() const {
|
Element *back() const {
|
||||||
|
|
||||||
if (!_data._root)
|
if (!_data._root)
|
||||||
return NULL;
|
return NULL;
|
||||||
Element *e=_data._root->left;
|
Element *e=_data._root->left;
|
||||||
if (e==_data._nil)
|
if (e==_data._nil)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
while(e->right!=_data._nil)
|
while(e->right!=_data._nil)
|
||||||
e=e->right;
|
e=e->right;
|
||||||
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool empty() const { return _data.size_cache==0; }
|
inline bool empty() const { return _data.size_cache==0; }
|
||||||
inline int size() const { return _data.size_cache; }
|
inline int size() const { return _data.size_cache; }
|
||||||
int calculate_depth() const {
|
int calculate_depth() const {
|
||||||
|
@ -671,9 +671,9 @@ public:
|
||||||
_calculate_depth(_data._root->left,max_d,0);
|
_calculate_depth(_data._root->left,max_d,0);
|
||||||
return max_d;
|
return max_d;
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear() {
|
void clear() {
|
||||||
|
|
||||||
if (!_data._root)
|
if (!_data._root)
|
||||||
return;
|
return;
|
||||||
_cleanup_tree(_data._root->left);
|
_cleanup_tree(_data._root->left);
|
||||||
|
@ -682,25 +682,25 @@ public:
|
||||||
_data._nil->parent=_data._nil;
|
_data._nil->parent=_data._nil;
|
||||||
_data._free_root();
|
_data._free_root();
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator=(const Map& p_map) {
|
void operator=(const Map& p_map) {
|
||||||
|
|
||||||
_copy_from( p_map );
|
_copy_from( p_map );
|
||||||
}
|
}
|
||||||
|
|
||||||
Map(const Map& p_map) {
|
Map(const Map& p_map) {
|
||||||
|
|
||||||
_copy_from( p_map );
|
_copy_from( p_map );
|
||||||
}
|
}
|
||||||
|
|
||||||
_FORCE_INLINE_ Map() {
|
_FORCE_INLINE_ Map() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
~Map() {
|
~Map() {
|
||||||
|
|
||||||
clear();
|
clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -47,21 +47,21 @@ public:
|
||||||
|
|
||||||
float get_area() const; /// get area
|
float get_area() const; /// get area
|
||||||
_FORCE_INLINE_ bool has_no_area() const {
|
_FORCE_INLINE_ bool has_no_area() const {
|
||||||
|
|
||||||
return (size.x<=CMP_EPSILON || size.y<=CMP_EPSILON || size.z<=CMP_EPSILON);
|
return (size.x<=CMP_EPSILON || size.y<=CMP_EPSILON || size.z<=CMP_EPSILON);
|
||||||
}
|
}
|
||||||
|
|
||||||
_FORCE_INLINE_ bool has_no_surface() const {
|
_FORCE_INLINE_ bool has_no_surface() const {
|
||||||
|
|
||||||
return (size.x<=CMP_EPSILON && size.y<=CMP_EPSILON && size.z<=CMP_EPSILON);
|
return (size.x<=CMP_EPSILON && size.y<=CMP_EPSILON && size.z<=CMP_EPSILON);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Vector3& get_pos() const { return pos; }
|
const Vector3& get_pos() const { return pos; }
|
||||||
void set_pos(const Vector3& p_pos) { pos=p_pos; }
|
void set_pos(const Vector3& p_pos) { pos=p_pos; }
|
||||||
const Vector3& get_size() const { return size; }
|
const Vector3& get_size() const { return size; }
|
||||||
void set_size(const Vector3& p_size) { size=p_size; }
|
void set_size(const Vector3& p_size) { size=p_size; }
|
||||||
|
|
||||||
|
|
||||||
bool operator==(const AABB& p_rval) const;
|
bool operator==(const AABB& p_rval) const;
|
||||||
bool operator!=(const AABB& p_rval) const;
|
bool operator!=(const AABB& p_rval) const;
|
||||||
|
|
||||||
|
@ -265,7 +265,7 @@ bool AABB::has_point(const Vector3& p_point) const {
|
||||||
return false;
|
return false;
|
||||||
if (p_point.z>pos.z+size.z)
|
if (p_point.z>pos.z+size.z)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -297,11 +297,11 @@ void AABB::project_range_in_plane(const Plane& p_plane,float &r_min,float& r_max
|
||||||
|
|
||||||
Vector3 half_extents( size.x * 0.5, size.y * 0.5, size.z * 0.5 );
|
Vector3 half_extents( size.x * 0.5, size.y * 0.5, size.z * 0.5 );
|
||||||
Vector3 center( pos.x + half_extents.x, pos.y + half_extents.y, pos.z + half_extents.z );
|
Vector3 center( pos.x + half_extents.x, pos.y + half_extents.y, pos.z + half_extents.z );
|
||||||
|
|
||||||
float length = p_plane.normal.abs().dot(half_extents);
|
float length = p_plane.normal.abs().dot(half_extents);
|
||||||
float distance = p_plane.distance_to( center );
|
float distance = p_plane.distance_to( center );
|
||||||
r_min = distance - length;
|
r_min = distance - length;
|
||||||
r_max = distance + length;
|
r_max = distance + length;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline real_t AABB::get_longest_axis_size() const {
|
inline real_t AABB::get_longest_axis_size() const {
|
||||||
|
|
|
@ -66,12 +66,12 @@ Vector<Plane> BSP_Tree::get_planes() const {
|
||||||
|
|
||||||
return planes;
|
return planes;
|
||||||
}
|
}
|
||||||
|
|
||||||
AABB BSP_Tree::get_aabb() const {
|
AABB BSP_Tree::get_aabb() const {
|
||||||
|
|
||||||
return aabb;
|
return aabb;
|
||||||
}
|
}
|
||||||
|
|
||||||
int BSP_Tree::_get_points_inside(int p_node,const Vector3* p_points,int *p_indices, const Vector3& p_center,const Vector3& p_half_extents,int p_indices_count) const {
|
int BSP_Tree::_get_points_inside(int p_node,const Vector3* p_points,int *p_indices, const Vector3& p_center,const Vector3& p_half_extents,int p_indices_count) const {
|
||||||
|
|
||||||
|
|
||||||
|
@ -245,22 +245,22 @@ bool BSP_Tree::point_is_inside(const Vector3& p_point) const {
|
||||||
if (!aabb.has_point(p_point)) {
|
if (!aabb.has_point(p_point)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int node_count=nodes.size();
|
int node_count=nodes.size();
|
||||||
|
|
||||||
if (node_count==0) // no nodes!
|
if (node_count==0) // no nodes!
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
||||||
const Node *nodesptr=&nodes[0];
|
const Node *nodesptr=&nodes[0];
|
||||||
const Plane *planesptr=&planes[0];
|
const Plane *planesptr=&planes[0];
|
||||||
int plane_count=planes.size();
|
int plane_count=planes.size();
|
||||||
|
|
||||||
int idx=node_count-1;
|
int idx=node_count-1;
|
||||||
int steps=0;
|
int steps=0;
|
||||||
|
|
||||||
while(true) {
|
while(true) {
|
||||||
|
|
||||||
if (idx==OVER_LEAF) {
|
if (idx==OVER_LEAF) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -268,28 +268,28 @@ bool BSP_Tree::point_is_inside(const Vector3& p_point) const {
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t plane=nodesptr[ idx ].plane;
|
uint16_t plane=nodesptr[ idx ].plane;
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
|
|
||||||
ERR_FAIL_INDEX_V( plane, plane_count, false );
|
ERR_FAIL_INDEX_V( plane, plane_count, false );
|
||||||
#endif
|
#endif
|
||||||
bool over = planesptr[ nodesptr[ idx ].plane ].is_point_over(p_point);
|
bool over = planesptr[ nodesptr[ idx ].plane ].is_point_over(p_point);
|
||||||
|
|
||||||
idx = over ? nodes[ idx ].over : nodes[ idx ].under;
|
idx = over ? nodes[ idx ].over : nodes[ idx ].under;
|
||||||
|
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
|
|
||||||
ERR_FAIL_COND_V( idx<MAX_NODES && idx>=node_count, false );
|
ERR_FAIL_COND_V( idx<MAX_NODES && idx>=node_count, false );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
steps++;
|
steps++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int _bsp_find_best_half_plane(const Face3* p_faces,const Vector<int>& p_indices,float p_tolerance) {
|
static int _bsp_find_best_half_plane(const Face3* p_faces,const Vector<int>& p_indices,float p_tolerance) {
|
||||||
|
|
||||||
int ic = p_indices.size();
|
int ic = p_indices.size();
|
||||||
|
@ -304,7 +304,7 @@ static int _bsp_find_best_half_plane(const Face3* p_faces,const Vector<int>& p_i
|
||||||
|
|
||||||
const Face3& f=p_faces[ indices[i] ];
|
const Face3& f=p_faces[ indices[i] ];
|
||||||
Plane p = f.get_plane();
|
Plane p = f.get_plane();
|
||||||
|
|
||||||
int num_over=0,num_under=0,num_spanning=0;
|
int num_over=0,num_under=0,num_spanning=0;
|
||||||
|
|
||||||
for(int j=0;j<ic;j++) {
|
for(int j=0;j<ic;j++) {
|
||||||
|
@ -335,17 +335,17 @@ static int _bsp_find_best_half_plane(const Face3* p_faces,const Vector<int>& p_i
|
||||||
num_over++;
|
num_over++;
|
||||||
else
|
else
|
||||||
num_under++;
|
num_under++;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//double split_cost = num_spanning / (double) face_count;
|
//double split_cost = num_spanning / (double) face_count;
|
||||||
double relation = Math::abs(num_over-num_under) / (double) ic;
|
double relation = Math::abs(num_over-num_under) / (double) ic;
|
||||||
|
|
||||||
// being honest, i never found a way to add split cost to the mix in a meaninguful way
|
// being honest, i never found a way to add split cost to the mix in a meaninguful way
|
||||||
// in this engine, also, will likely be ignored anyway
|
// in this engine, also, will likely be ignored anyway
|
||||||
|
|
||||||
double plane_cost = /*split_cost +*/ relation;
|
double plane_cost = /*split_cost +*/ relation;
|
||||||
|
|
||||||
//printf("plane %i, %i over, %i under, %i spanning, cost is %g\n",i,num_over,num_under,num_spanning,plane_cost);
|
//printf("plane %i, %i over, %i under, %i spanning, cost is %g\n",i,num_over,num_under,num_spanning,plane_cost);
|
||||||
|
@ -360,10 +360,10 @@ static int _bsp_find_best_half_plane(const Face3* p_faces,const Vector<int>& p_i
|
||||||
return best_plane;
|
return best_plane;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int _bsp_create_node(const Face3 *p_faces,const Vector<int>& p_indices,Vector<Plane> &p_planes, Vector<BSP_Tree::Node> &p_nodes,float p_tolerance) {
|
static int _bsp_create_node(const Face3 *p_faces,const Vector<int>& p_indices,Vector<Plane> &p_planes, Vector<BSP_Tree::Node> &p_nodes,float p_tolerance) {
|
||||||
|
|
||||||
ERR_FAIL_COND_V( p_nodes.size() == BSP_Tree::MAX_NODES, -1 );
|
ERR_FAIL_COND_V( p_nodes.size() == BSP_Tree::MAX_NODES, -1 );
|
||||||
|
|
||||||
// should not reach here
|
// should not reach here
|
||||||
|
@ -387,7 +387,7 @@ static int _bsp_create_node(const Face3 *p_faces,const Vector<int>& p_indices,Ve
|
||||||
|
|
||||||
if (i==divisor_idx)
|
if (i==divisor_idx)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const Face3& f=p_faces[ indices[i] ];
|
const Face3& f=p_faces[ indices[i] ];
|
||||||
|
|
||||||
//if (f.get_plane().is_almost_like(divisor_plane))
|
//if (f.get_plane().is_almost_like(divisor_plane))
|
||||||
|
@ -416,7 +416,7 @@ static int _bsp_create_node(const Face3 *p_faces,const Vector<int>& p_indices,Ve
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint16_t over_idx=BSP_Tree::OVER_LEAF,under_idx=BSP_Tree::UNDER_LEAF;
|
uint16_t over_idx=BSP_Tree::OVER_LEAF,under_idx=BSP_Tree::UNDER_LEAF;
|
||||||
|
|
||||||
if (faces_over.size()>0) { //have facess above?
|
if (faces_over.size()>0) { //have facess above?
|
||||||
|
@ -434,13 +434,13 @@ static int _bsp_create_node(const Face3 *p_faces,const Vector<int>& p_indices,Ve
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create the node */
|
/* Create the node */
|
||||||
|
|
||||||
// find existing divisor plane
|
// find existing divisor plane
|
||||||
int divisor_plane_idx=-1;
|
int divisor_plane_idx=-1;
|
||||||
|
|
||||||
|
|
||||||
for (int i=0;i<p_planes.size();i++) {
|
for (int i=0;i<p_planes.size();i++) {
|
||||||
|
|
||||||
if (p_planes[i].is_almost_like( divisor_plane )) {
|
if (p_planes[i].is_almost_like( divisor_plane )) {
|
||||||
divisor_plane_idx=i;
|
divisor_plane_idx=i;
|
||||||
break;
|
break;
|
||||||
|
@ -448,22 +448,22 @@ static int _bsp_create_node(const Face3 *p_faces,const Vector<int>& p_indices,Ve
|
||||||
}
|
}
|
||||||
|
|
||||||
if (divisor_plane_idx==-1) {
|
if (divisor_plane_idx==-1) {
|
||||||
|
|
||||||
ERR_FAIL_COND_V( p_planes.size() == BSP_Tree::MAX_PLANES, -1 );
|
ERR_FAIL_COND_V( p_planes.size() == BSP_Tree::MAX_PLANES, -1 );
|
||||||
divisor_plane_idx=p_planes.size();
|
divisor_plane_idx=p_planes.size();
|
||||||
p_planes.push_back( divisor_plane );
|
p_planes.push_back( divisor_plane );
|
||||||
}
|
}
|
||||||
|
|
||||||
BSP_Tree::Node node;
|
BSP_Tree::Node node;
|
||||||
node.plane=divisor_plane_idx;
|
node.plane=divisor_plane_idx;
|
||||||
node.under=under_idx;
|
node.under=under_idx;
|
||||||
node.over=over_idx;
|
node.over=over_idx;
|
||||||
|
|
||||||
p_nodes.push_back(node);
|
p_nodes.push_back(node);
|
||||||
|
|
||||||
return p_nodes.size()-1;
|
return p_nodes.size()-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BSP_Tree::operator Variant() const {
|
BSP_Tree::operator Variant() const {
|
||||||
|
|
||||||
|
@ -563,7 +563,7 @@ BSP_Tree::BSP_Tree(const Variant& p_variant) {
|
||||||
BSP_Tree::BSP_Tree(const DVector<Face3>& p_faces,float p_error_radius) {
|
BSP_Tree::BSP_Tree(const DVector<Face3>& p_faces,float p_error_radius) {
|
||||||
|
|
||||||
// compute aabb
|
// compute aabb
|
||||||
|
|
||||||
int face_count=p_faces.size();
|
int face_count=p_faces.size();
|
||||||
DVector<Face3>::Read faces_r=p_faces.read();
|
DVector<Face3>::Read faces_r=p_faces.read();
|
||||||
const Face3 *facesptr = faces_r.ptr();
|
const Face3 *facesptr = faces_r.ptr();
|
||||||
|
@ -574,26 +574,26 @@ BSP_Tree::BSP_Tree(const DVector<Face3>& p_faces,float p_error_radius) {
|
||||||
Vector<int> indices;
|
Vector<int> indices;
|
||||||
|
|
||||||
for (int i=0;i<face_count;i++) {
|
for (int i=0;i<face_count;i++) {
|
||||||
|
|
||||||
const Face3& f=facesptr[i];
|
const Face3& f=facesptr[i];
|
||||||
|
|
||||||
if (f.is_degenerate())
|
if (f.is_degenerate())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (int j=0;j<3;j++) {
|
for (int j=0;j<3;j++) {
|
||||||
|
|
||||||
if (first) {
|
if (first) {
|
||||||
|
|
||||||
aabb.pos=f.vertex[0];
|
aabb.pos=f.vertex[0];
|
||||||
first=false;
|
first=false;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
aabb.expand_to(f.vertex[j]);
|
aabb.expand_to(f.vertex[j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
indices.push_back(i);
|
indices.push_back(i);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ERR_FAIL_COND( aabb.has_no_area() );
|
ERR_FAIL_COND( aabb.has_no_area() );
|
||||||
|
@ -609,7 +609,7 @@ BSP_Tree::BSP_Tree(const DVector<Face3>& p_faces,float p_error_radius) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
error_radius=p_error_radius;
|
error_radius=p_error_radius;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ class BSP_Tree {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
|
||||||
UNDER_LEAF=0xFFFF,
|
UNDER_LEAF=0xFFFF,
|
||||||
OVER_LEAF=0xFFFE,
|
OVER_LEAF=0xFFFE,
|
||||||
MAX_NODES=0xFFFE,
|
MAX_NODES=0xFFFE,
|
||||||
|
@ -51,22 +51,22 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Node {
|
struct Node {
|
||||||
|
|
||||||
uint16_t plane;
|
uint16_t plane;
|
||||||
uint16_t under;
|
uint16_t under;
|
||||||
uint16_t over;
|
uint16_t over;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// thanks to the properties of Vector,
|
// thanks to the properties of Vector,
|
||||||
// this class can be assigned and passed around between threads
|
// this class can be assigned and passed around between threads
|
||||||
// with no cost.
|
// with no cost.
|
||||||
|
|
||||||
Vector<Node> nodes;
|
Vector<Node> nodes;
|
||||||
Vector<Plane> planes;
|
Vector<Plane> planes;
|
||||||
AABB aabb;
|
AABB aabb;
|
||||||
float error_radius;
|
float error_radius;
|
||||||
|
|
||||||
int _get_points_inside(int p_node,const Vector3* p_points,int *p_indices, const Vector3& p_center,const Vector3& p_half_extents,int p_indices_count) const;
|
int _get_points_inside(int p_node,const Vector3* p_points,int *p_indices, const Vector3& p_center,const Vector3& p_half_extents,int p_indices_count) const;
|
||||||
|
|
||||||
|
@ -79,8 +79,8 @@ public:
|
||||||
Vector<Node> get_nodes() const;
|
Vector<Node> get_nodes() const;
|
||||||
Vector<Plane> get_planes() const;
|
Vector<Plane> get_planes() const;
|
||||||
AABB get_aabb() const;
|
AABB get_aabb() const;
|
||||||
|
|
||||||
bool point_is_inside(const Vector3& p_point) const;
|
bool point_is_inside(const Vector3& p_point) const;
|
||||||
int get_points_inside(const Vector3* p_points, int p_point_count) const;
|
int get_points_inside(const Vector3* p_points, int p_point_count) const;
|
||||||
template<class T>
|
template<class T>
|
||||||
bool convex_is_inside(const T& p_convex) const;
|
bool convex_is_inside(const T& p_convex) const;
|
||||||
|
@ -91,8 +91,8 @@ public:
|
||||||
|
|
||||||
BSP_Tree();
|
BSP_Tree();
|
||||||
BSP_Tree(const Variant& p_variant);
|
BSP_Tree(const Variant& p_variant);
|
||||||
BSP_Tree(const DVector<Face3>& p_faces,float p_error_radius=0);
|
BSP_Tree(const DVector<Face3>& p_faces,float p_error_radius=0);
|
||||||
BSP_Tree(const Vector<Node> &p_nodes, const Vector<Plane> &p_planes, const AABB& p_aabb,float p_error_radius=0);
|
BSP_Tree(const Vector<Node> &p_nodes, const Vector<Plane> &p_planes, const AABB& p_aabb,float p_error_radius=0);
|
||||||
~BSP_Tree();
|
~BSP_Tree();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -33,9 +33,9 @@
|
||||||
void CameraMatrix::set_identity() {
|
void CameraMatrix::set_identity() {
|
||||||
|
|
||||||
for (int i=0;i<4;i++) {
|
for (int i=0;i<4;i++) {
|
||||||
|
|
||||||
for (int j=0;j<4;j++) {
|
for (int j=0;j<4;j++) {
|
||||||
|
|
||||||
matrix[i][j]=(i==j)?1:0;
|
matrix[i][j]=(i==j)?1:0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -90,7 +90,7 @@ void CameraMatrix::set_perspective(float p_fovy_degrees, float p_aspect, float p
|
||||||
matrix[2][2] = -(p_z_far + p_z_near) / deltaZ;
|
matrix[2][2] = -(p_z_far + p_z_near) / deltaZ;
|
||||||
matrix[2][3] = -1;
|
matrix[2][3] = -1;
|
||||||
matrix[3][2] = -2 * p_z_near * p_z_far / deltaZ;
|
matrix[3][2] = -2 * p_z_near * p_z_far / deltaZ;
|
||||||
matrix[3][3] = 0;
|
matrix[3][3] = 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,95 +155,95 @@ void CameraMatrix::set_frustum(float p_left, float p_right, float p_bottom, floa
|
||||||
|
|
||||||
|
|
||||||
float CameraMatrix::get_z_far() const {
|
float CameraMatrix::get_z_far() const {
|
||||||
|
|
||||||
const float * matrix = (const float*)this->matrix;
|
const float * matrix = (const float*)this->matrix;
|
||||||
Plane new_plane=Plane(matrix[ 3] - matrix[ 2],
|
Plane new_plane=Plane(matrix[ 3] - matrix[ 2],
|
||||||
matrix[ 7] - matrix[ 6],
|
matrix[ 7] - matrix[ 6],
|
||||||
matrix[11] - matrix[10],
|
matrix[11] - matrix[10],
|
||||||
matrix[15] - matrix[14]);
|
matrix[15] - matrix[14]);
|
||||||
|
|
||||||
new_plane.normal=-new_plane.normal;
|
new_plane.normal=-new_plane.normal;
|
||||||
new_plane.normalize();
|
new_plane.normalize();
|
||||||
|
|
||||||
return new_plane.d;
|
return new_plane.d;
|
||||||
}
|
}
|
||||||
float CameraMatrix::get_z_near() const {
|
float CameraMatrix::get_z_near() const {
|
||||||
|
|
||||||
const float * matrix = (const float*)this->matrix;
|
const float * matrix = (const float*)this->matrix;
|
||||||
Plane new_plane=Plane(matrix[ 3] + matrix[ 2],
|
Plane new_plane=Plane(matrix[ 3] + matrix[ 2],
|
||||||
matrix[ 7] + matrix[ 6],
|
matrix[ 7] + matrix[ 6],
|
||||||
matrix[11] + matrix[10],
|
matrix[11] + matrix[10],
|
||||||
-matrix[15] - matrix[14]);
|
-matrix[15] - matrix[14]);
|
||||||
|
|
||||||
new_plane.normalize();
|
new_plane.normalize();
|
||||||
return new_plane.d;
|
return new_plane.d;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CameraMatrix::get_viewport_size(float& r_width, float& r_height) const {
|
void CameraMatrix::get_viewport_size(float& r_width, float& r_height) const {
|
||||||
|
|
||||||
const float * matrix = (const float*)this->matrix;
|
const float * matrix = (const float*)this->matrix;
|
||||||
///////--- Near Plane ---///////
|
///////--- Near Plane ---///////
|
||||||
Plane near_plane=Plane(matrix[ 3] + matrix[ 2],
|
Plane near_plane=Plane(matrix[ 3] + matrix[ 2],
|
||||||
matrix[ 7] + matrix[ 6],
|
matrix[ 7] + matrix[ 6],
|
||||||
matrix[11] + matrix[10],
|
matrix[11] + matrix[10],
|
||||||
-matrix[15] - matrix[14]).normalized();
|
-matrix[15] - matrix[14]).normalized();
|
||||||
|
|
||||||
///////--- Right Plane ---///////
|
///////--- Right Plane ---///////
|
||||||
Plane right_plane=Plane(matrix[ 3] - matrix[ 0],
|
Plane right_plane=Plane(matrix[ 3] - matrix[ 0],
|
||||||
matrix[ 7] - matrix[ 4],
|
matrix[ 7] - matrix[ 4],
|
||||||
matrix[11] - matrix[ 8],
|
matrix[11] - matrix[ 8],
|
||||||
- matrix[15] + matrix[12]).normalized();
|
- matrix[15] + matrix[12]).normalized();
|
||||||
|
|
||||||
Plane top_plane=Plane(matrix[ 3] - matrix[ 1],
|
Plane top_plane=Plane(matrix[ 3] - matrix[ 1],
|
||||||
matrix[ 7] - matrix[ 5],
|
matrix[ 7] - matrix[ 5],
|
||||||
matrix[11] - matrix[ 9],
|
matrix[11] - matrix[ 9],
|
||||||
-matrix[15] + matrix[13]).normalized();
|
-matrix[15] + matrix[13]).normalized();
|
||||||
|
|
||||||
Vector3 res;
|
Vector3 res;
|
||||||
near_plane.intersect_3(right_plane,top_plane,&res);
|
near_plane.intersect_3(right_plane,top_plane,&res);
|
||||||
|
|
||||||
r_width=res.x;
|
r_width=res.x;
|
||||||
r_height=res.y;
|
r_height=res.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CameraMatrix::get_endpoints(const Transform& p_transform, Vector3 *p_8points) const {
|
bool CameraMatrix::get_endpoints(const Transform& p_transform, Vector3 *p_8points) const {
|
||||||
|
|
||||||
const float * matrix = (const float*)this->matrix;
|
const float * matrix = (const float*)this->matrix;
|
||||||
|
|
||||||
///////--- Near Plane ---///////
|
///////--- Near Plane ---///////
|
||||||
Plane near_plane=Plane(matrix[ 3] + matrix[ 2],
|
Plane near_plane=Plane(matrix[ 3] + matrix[ 2],
|
||||||
matrix[ 7] + matrix[ 6],
|
matrix[ 7] + matrix[ 6],
|
||||||
matrix[11] + matrix[10],
|
matrix[11] + matrix[10],
|
||||||
-matrix[15] - matrix[14]).normalized();
|
-matrix[15] - matrix[14]).normalized();
|
||||||
|
|
||||||
///////--- Far Plane ---///////
|
///////--- Far Plane ---///////
|
||||||
Plane far_plane=Plane(matrix[ 2] - matrix[ 3],
|
Plane far_plane=Plane(matrix[ 2] - matrix[ 3],
|
||||||
matrix[ 6] - matrix[ 7],
|
matrix[ 6] - matrix[ 7],
|
||||||
matrix[10] - matrix[11],
|
matrix[10] - matrix[11],
|
||||||
matrix[15] - matrix[14]).normalized();
|
matrix[15] - matrix[14]).normalized();
|
||||||
|
|
||||||
|
|
||||||
///////--- Right Plane ---///////
|
///////--- Right Plane ---///////
|
||||||
Plane right_plane=Plane(matrix[ 0] - matrix[ 3],
|
Plane right_plane=Plane(matrix[ 0] - matrix[ 3],
|
||||||
matrix[ 4] - matrix[ 7],
|
matrix[ 4] - matrix[ 7],
|
||||||
matrix[8] - matrix[ 11],
|
matrix[8] - matrix[ 11],
|
||||||
- matrix[15] + matrix[12]).normalized();
|
- matrix[15] + matrix[12]).normalized();
|
||||||
|
|
||||||
///////--- Top Plane ---///////
|
///////--- Top Plane ---///////
|
||||||
Plane top_plane=Plane(matrix[ 1] - matrix[ 3],
|
Plane top_plane=Plane(matrix[ 1] - matrix[ 3],
|
||||||
matrix[ 5] - matrix[ 7],
|
matrix[ 5] - matrix[ 7],
|
||||||
matrix[9] - matrix[ 11],
|
matrix[9] - matrix[ 11],
|
||||||
-matrix[15] + matrix[13]).normalized();
|
-matrix[15] + matrix[13]).normalized();
|
||||||
|
|
||||||
Vector3 near_endpoint;
|
Vector3 near_endpoint;
|
||||||
Vector3 far_endpoint;
|
Vector3 far_endpoint;
|
||||||
|
|
||||||
bool res=near_plane.intersect_3(right_plane,top_plane,&near_endpoint);
|
bool res=near_plane.intersect_3(right_plane,top_plane,&near_endpoint);
|
||||||
ERR_FAIL_COND_V(!res,false);
|
ERR_FAIL_COND_V(!res,false);
|
||||||
|
|
||||||
res=far_plane.intersect_3(right_plane,top_plane,&far_endpoint);
|
res=far_plane.intersect_3(right_plane,top_plane,&far_endpoint);
|
||||||
ERR_FAIL_COND_V(!res,false);
|
ERR_FAIL_COND_V(!res,false);
|
||||||
|
|
||||||
p_8points[0]=p_transform.xform( Vector3( near_endpoint.x, near_endpoint.y, near_endpoint.z ) );
|
p_8points[0]=p_transform.xform( Vector3( near_endpoint.x, near_endpoint.y, near_endpoint.z ) );
|
||||||
p_8points[1]=p_transform.xform( Vector3( near_endpoint.x,-near_endpoint.y, near_endpoint.z ) );
|
p_8points[1]=p_transform.xform( Vector3( near_endpoint.x,-near_endpoint.y, near_endpoint.z ) );
|
||||||
p_8points[2]=p_transform.xform( Vector3(-near_endpoint.x, near_endpoint.y, near_endpoint.z ) );
|
p_8points[2]=p_transform.xform( Vector3(-near_endpoint.x, near_endpoint.y, near_endpoint.z ) );
|
||||||
|
@ -252,7 +252,7 @@ bool CameraMatrix::get_endpoints(const Transform& p_transform, Vector3 *p_8point
|
||||||
p_8points[5]=p_transform.xform( Vector3( far_endpoint.x,-far_endpoint.y, far_endpoint.z ) );
|
p_8points[5]=p_transform.xform( Vector3( far_endpoint.x,-far_endpoint.y, far_endpoint.z ) );
|
||||||
p_8points[6]=p_transform.xform( Vector3(-far_endpoint.x, far_endpoint.y, far_endpoint.z ) );
|
p_8points[6]=p_transform.xform( Vector3(-far_endpoint.x, far_endpoint.y, far_endpoint.z ) );
|
||||||
p_8points[7]=p_transform.xform( Vector3(-far_endpoint.x,-far_endpoint.y, far_endpoint.z ) );
|
p_8points[7]=p_transform.xform( Vector3(-far_endpoint.x,-far_endpoint.y, far_endpoint.z ) );
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,10 +263,10 @@ Vector<Plane> CameraMatrix::get_projection_planes(const Transform& p_transform)
|
||||||
* http://www.markmorley.com/opengl/frustumculling.html
|
* http://www.markmorley.com/opengl/frustumculling.html
|
||||||
* http://www2.ravensoft.com/users/ggribb/plane%20extraction.pdf
|
* http://www2.ravensoft.com/users/ggribb/plane%20extraction.pdf
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Vector<Plane> planes;
|
Vector<Plane> planes;
|
||||||
|
|
||||||
const float * matrix = (const float*)this->matrix;
|
const float * matrix = (const float*)this->matrix;
|
||||||
|
|
||||||
Plane new_plane;
|
Plane new_plane;
|
||||||
|
|
||||||
|
@ -275,7 +275,7 @@ Vector<Plane> CameraMatrix::get_projection_planes(const Transform& p_transform)
|
||||||
matrix[ 7] + matrix[ 6],
|
matrix[ 7] + matrix[ 6],
|
||||||
matrix[11] + matrix[10],
|
matrix[11] + matrix[10],
|
||||||
matrix[15] + matrix[14]);
|
matrix[15] + matrix[14]);
|
||||||
|
|
||||||
new_plane.normal=-new_plane.normal;
|
new_plane.normal=-new_plane.normal;
|
||||||
new_plane.normalize();
|
new_plane.normalize();
|
||||||
|
|
||||||
|
@ -298,7 +298,7 @@ Vector<Plane> CameraMatrix::get_projection_planes(const Transform& p_transform)
|
||||||
matrix[ 7] + matrix[ 4],
|
matrix[ 7] + matrix[ 4],
|
||||||
matrix[11] + matrix[ 8],
|
matrix[11] + matrix[ 8],
|
||||||
matrix[15] + matrix[12]);
|
matrix[15] + matrix[12]);
|
||||||
|
|
||||||
new_plane.normal=-new_plane.normal;
|
new_plane.normal=-new_plane.normal;
|
||||||
new_plane.normalize();
|
new_plane.normalize();
|
||||||
|
|
||||||
|
@ -310,8 +310,8 @@ Vector<Plane> CameraMatrix::get_projection_planes(const Transform& p_transform)
|
||||||
matrix[ 7] - matrix[ 5],
|
matrix[ 7] - matrix[ 5],
|
||||||
matrix[11] - matrix[ 9],
|
matrix[11] - matrix[ 9],
|
||||||
matrix[15] - matrix[13]);
|
matrix[15] - matrix[13]);
|
||||||
|
|
||||||
|
|
||||||
new_plane.normal=-new_plane.normal;
|
new_plane.normal=-new_plane.normal;
|
||||||
new_plane.normalize();
|
new_plane.normalize();
|
||||||
|
|
||||||
|
@ -324,10 +324,10 @@ Vector<Plane> CameraMatrix::get_projection_planes(const Transform& p_transform)
|
||||||
matrix[11] - matrix[ 8],
|
matrix[11] - matrix[ 8],
|
||||||
matrix[15] - matrix[12]);
|
matrix[15] - matrix[12]);
|
||||||
|
|
||||||
|
|
||||||
new_plane.normal=-new_plane.normal;
|
new_plane.normal=-new_plane.normal;
|
||||||
new_plane.normalize();
|
new_plane.normalize();
|
||||||
|
|
||||||
planes.push_back( p_transform.xform(new_plane) );
|
planes.push_back( p_transform.xform(new_plane) );
|
||||||
|
|
||||||
|
|
||||||
|
@ -337,12 +337,12 @@ Vector<Plane> CameraMatrix::get_projection_planes(const Transform& p_transform)
|
||||||
matrix[11] + matrix[ 9],
|
matrix[11] + matrix[ 9],
|
||||||
matrix[15] + matrix[13]);
|
matrix[15] + matrix[13]);
|
||||||
|
|
||||||
|
|
||||||
new_plane.normal=-new_plane.normal;
|
new_plane.normal=-new_plane.normal;
|
||||||
new_plane.normalize();
|
new_plane.normalize();
|
||||||
|
|
||||||
planes.push_back( p_transform.xform(new_plane) );
|
planes.push_back( p_transform.xform(new_plane) );
|
||||||
|
|
||||||
return planes;
|
return planes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -356,7 +356,7 @@ CameraMatrix CameraMatrix::inverse() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CameraMatrix::invert() {
|
void CameraMatrix::invert() {
|
||||||
|
|
||||||
int i,j,k;
|
int i,j,k;
|
||||||
int pvt_i[4], pvt_j[4]; /* Locations of pivot matrix */
|
int pvt_i[4], pvt_j[4]; /* Locations of pivot matrix */
|
||||||
float pvt_val; /* Value of current pivot element */
|
float pvt_val; /* Value of current pivot element */
|
||||||
|
@ -448,7 +448,7 @@ void CameraMatrix::invert() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CameraMatrix::CameraMatrix() {
|
CameraMatrix::CameraMatrix() {
|
||||||
|
@ -475,31 +475,31 @@ CameraMatrix CameraMatrix::operator*(const CameraMatrix& p_matrix) const {
|
||||||
void CameraMatrix::set_light_bias() {
|
void CameraMatrix::set_light_bias() {
|
||||||
|
|
||||||
float *m=&matrix[0][0];
|
float *m=&matrix[0][0];
|
||||||
|
|
||||||
m[0]=0.5,
|
m[0]=0.5,
|
||||||
m[1]=0.0,
|
m[1]=0.0,
|
||||||
m[2]=0.0,
|
m[2]=0.0,
|
||||||
m[3]=0.0,
|
m[3]=0.0,
|
||||||
m[4]=0.0,
|
m[4]=0.0,
|
||||||
m[5]=0.5,
|
m[5]=0.5,
|
||||||
m[6]=0.0,
|
m[6]=0.0,
|
||||||
m[7]=0.0,
|
m[7]=0.0,
|
||||||
m[8]=0.0,
|
m[8]=0.0,
|
||||||
m[9]=0.0,
|
m[9]=0.0,
|
||||||
m[10]=0.5,
|
m[10]=0.5,
|
||||||
m[11]=0.0,
|
m[11]=0.0,
|
||||||
m[12]=0.5,
|
m[12]=0.5,
|
||||||
m[13]=0.5,
|
m[13]=0.5,
|
||||||
m[14]=0.5,
|
m[14]=0.5,
|
||||||
m[15]=1.0;
|
m[15]=1.0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CameraMatrix::operator String() const {
|
CameraMatrix::operator String() const {
|
||||||
|
|
||||||
String str;
|
String str;
|
||||||
for (int i=0;i<4;i++)
|
for (int i=0;i<4;i++)
|
||||||
for (int j=0;j<4;j++)
|
for (int j=0;j<4;j++)
|
||||||
str+=String((j>0)?", ":"\n")+rtos(matrix[i][j]);
|
str+=String((j>0)?", ":"\n")+rtos(matrix[i][j]);
|
||||||
|
|
||||||
return str;
|
return str;
|
||||||
|
@ -513,7 +513,7 @@ float CameraMatrix::get_aspect() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
float CameraMatrix::get_fov() const {
|
float CameraMatrix::get_fov() const {
|
||||||
const float * matrix = (const float*)this->matrix;
|
const float * matrix = (const float*)this->matrix;
|
||||||
|
|
||||||
Plane right_plane=Plane(matrix[ 3] - matrix[ 0],
|
Plane right_plane=Plane(matrix[ 3] - matrix[ 0],
|
||||||
matrix[ 7] - matrix[ 4],
|
matrix[ 7] - matrix[ 4],
|
||||||
|
@ -588,7 +588,7 @@ CameraMatrix::CameraMatrix(const Transform& p_transform) {
|
||||||
|
|
||||||
const Transform &tr = p_transform;
|
const Transform &tr = p_transform;
|
||||||
float *m=&matrix[0][0];
|
float *m=&matrix[0][0];
|
||||||
|
|
||||||
m[0]=tr.basis.elements[0][0];
|
m[0]=tr.basis.elements[0][0];
|
||||||
m[1]=tr.basis.elements[1][0];
|
m[1]=tr.basis.elements[1][0];
|
||||||
m[2]=tr.basis.elements[2][0];
|
m[2]=tr.basis.elements[2][0];
|
||||||
|
@ -604,7 +604,7 @@ CameraMatrix::CameraMatrix(const Transform& p_transform) {
|
||||||
m[12]=tr.origin.x;
|
m[12]=tr.origin.x;
|
||||||
m[13]=tr.origin.y;
|
m[13]=tr.origin.y;
|
||||||
m[14]=tr.origin.z;
|
m[14]=tr.origin.z;
|
||||||
m[15]=1.0;
|
m[15]=1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
CameraMatrix::~CameraMatrix()
|
CameraMatrix::~CameraMatrix()
|
||||||
|
|
|
@ -48,8 +48,8 @@ struct CameraMatrix {
|
||||||
};
|
};
|
||||||
|
|
||||||
float matrix[4][4];
|
float matrix[4][4];
|
||||||
|
|
||||||
|
|
||||||
void set_identity();
|
void set_identity();
|
||||||
void set_zero();
|
void set_zero();
|
||||||
void set_light_bias();
|
void set_light_bias();
|
||||||
|
@ -67,12 +67,12 @@ struct CameraMatrix {
|
||||||
float get_z_near() const;
|
float get_z_near() const;
|
||||||
float get_aspect() const;
|
float get_aspect() const;
|
||||||
float get_fov() const;
|
float get_fov() const;
|
||||||
|
|
||||||
Vector<Plane> get_projection_planes(const Transform& p_transform) const;
|
Vector<Plane> get_projection_planes(const Transform& p_transform) const;
|
||||||
|
|
||||||
bool get_endpoints(const Transform& p_transform,Vector3 *p_8points) const;
|
bool get_endpoints(const Transform& p_transform,Vector3 *p_8points) const;
|
||||||
void get_viewport_size(float& r_width, float& r_height) const;
|
void get_viewport_size(float& r_width, float& r_height) const;
|
||||||
|
|
||||||
void invert();
|
void invert();
|
||||||
CameraMatrix inverse() const;
|
CameraMatrix inverse() const;
|
||||||
|
|
||||||
|
@ -80,15 +80,15 @@ struct CameraMatrix {
|
||||||
|
|
||||||
Plane xform4(const Plane& p_vec4);
|
Plane xform4(const Plane& p_vec4);
|
||||||
_FORCE_INLINE_ Vector3 xform(const Vector3& p_vec3) const;
|
_FORCE_INLINE_ Vector3 xform(const Vector3& p_vec3) const;
|
||||||
|
|
||||||
operator String() const;
|
operator String() const;
|
||||||
|
|
||||||
void scale_translate_to_fit(const AABB& p_aabb);
|
void scale_translate_to_fit(const AABB& p_aabb);
|
||||||
void make_scale(const Vector3 &p_scale);
|
void make_scale(const Vector3 &p_scale);
|
||||||
operator Transform() const;
|
operator Transform() const;
|
||||||
|
|
||||||
CameraMatrix();
|
CameraMatrix();
|
||||||
CameraMatrix(const Transform& p_transform);
|
CameraMatrix(const Transform& p_transform);
|
||||||
~CameraMatrix();
|
~CameraMatrix();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -55,7 +55,7 @@ public:
|
||||||
* @param _epsilon constant used for numerical error rounding, to add "thickness" to the plane (so coplanar points can happen)
|
* @param _epsilon constant used for numerical error rounding, to add "thickness" to the plane (so coplanar points can happen)
|
||||||
* @return amount of faces generated by the split, either 0 (means no split possible), 2 or 3
|
* @return amount of faces generated by the split, either 0 (means no split possible), 2 or 3
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int split_by_plane(const Plane& p_plane,Face3 *p_res,bool *p_is_point_over) const;
|
int split_by_plane(const Plane& p_plane,Face3 *p_res,bool *p_is_point_over) const;
|
||||||
|
|
||||||
Plane get_plane(ClockDirection p_dir=CLOCKWISE) const;
|
Plane get_plane(ClockDirection p_dir=CLOCKWISE) const;
|
||||||
|
@ -77,7 +77,7 @@ public:
|
||||||
|
|
||||||
void get_support(const Vector3& p_normal,const Transform& p_transform,Vector3 *p_vertices,int* p_count,int p_max) const;
|
void get_support(const Vector3& p_normal,const Transform& p_transform,Vector3 *p_vertices,int* p_count,int p_max) const;
|
||||||
void project_range(const Vector3& p_normal,const Transform& p_transform,float& r_min, float& r_max) const;
|
void project_range(const Vector3& p_normal,const Transform& p_transform,float& r_min, float& r_max) const;
|
||||||
|
|
||||||
AABB get_aabb() const {
|
AABB get_aabb() const {
|
||||||
|
|
||||||
AABB aabb( vertex[0], Vector3() );
|
AABB aabb( vertex[0], Vector3() );
|
||||||
|
|
|
@ -211,7 +211,7 @@ DVector< DVector< Face3 > > Geometry::separate_objects( DVector< Face3 > p_array
|
||||||
int len = p_array.size();
|
int len = p_array.size();
|
||||||
|
|
||||||
DVector<Face3>::Read r=p_array.read();
|
DVector<Face3>::Read r=p_array.read();
|
||||||
|
|
||||||
const Face3* arrayptr = r.ptr();
|
const Face3* arrayptr = r.ptr();
|
||||||
|
|
||||||
DVector< _FaceClassify> fc;
|
DVector< _FaceClassify> fc;
|
||||||
|
@ -219,7 +219,7 @@ DVector< DVector< Face3 > > Geometry::separate_objects( DVector< Face3 > p_array
|
||||||
fc.resize( len );
|
fc.resize( len );
|
||||||
|
|
||||||
DVector< _FaceClassify >::Write fcw=fc.write();
|
DVector< _FaceClassify >::Write fcw=fc.write();
|
||||||
|
|
||||||
_FaceClassify * _fcptr = fcw.ptr();
|
_FaceClassify * _fcptr = fcw.ptr();
|
||||||
|
|
||||||
for (int i=0;i<len;i++) {
|
for (int i=0;i<len;i++) {
|
||||||
|
@ -278,7 +278,7 @@ DVector< DVector< Face3 > > Geometry::separate_objects( DVector< Face3 > p_array
|
||||||
/*** GEOMETRY WRAPPER ***/
|
/*** GEOMETRY WRAPPER ***/
|
||||||
|
|
||||||
enum _CellFlags {
|
enum _CellFlags {
|
||||||
|
|
||||||
_CELL_SOLID=1,
|
_CELL_SOLID=1,
|
||||||
_CELL_EXTERIOR=2,
|
_CELL_EXTERIOR=2,
|
||||||
_CELL_STEP_MASK=0x1C,
|
_CELL_STEP_MASK=0x1C,
|
||||||
|
@ -299,7 +299,7 @@ enum _CellFlags {
|
||||||
_CELL_PREV_Z_POS=5<<5,
|
_CELL_PREV_Z_POS=5<<5,
|
||||||
_CELL_PREV_Z_NEG=6<<5,
|
_CELL_PREV_Z_NEG=6<<5,
|
||||||
_CELL_PREV_FIRST=7<<5,
|
_CELL_PREV_FIRST=7<<5,
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline void _plot_face(uint8_t*** p_cell_status,int x,int y,int z,int len_x,int len_y,int len_z,const Vector3& voxelsize,const Face3& p_face) {
|
static inline void _plot_face(uint8_t*** p_cell_status,int x,int y,int z,int len_x,int len_y,int len_z,const Vector3& voxelsize,const Face3& p_face) {
|
||||||
|
@ -316,9 +316,9 @@ static inline void _plot_face(uint8_t*** p_cell_status,int x,int y,int z,int len
|
||||||
p_cell_status[x][y][z]=_CELL_SOLID;
|
p_cell_status[x][y][z]=_CELL_SOLID;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int div_x=len_x>1?2:1;
|
int div_x=len_x>1?2:1;
|
||||||
int div_y=len_y>1?2:1;
|
int div_y=len_y>1?2:1;
|
||||||
int div_z=len_z>1?2:1;
|
int div_z=len_z>1?2:1;
|
||||||
|
@ -343,14 +343,14 @@ static inline void _plot_face(uint8_t*** p_cell_status,int x,int y,int z,int len
|
||||||
int new_len_z;
|
int new_len_z;
|
||||||
|
|
||||||
for (int i=0;i<div_x;i++) {
|
for (int i=0;i<div_x;i++) {
|
||||||
|
|
||||||
|
|
||||||
_SPLIT(i,div_x,x,len_x,new_x,new_len_x);
|
_SPLIT(i,div_x,x,len_x,new_x,new_len_x);
|
||||||
|
|
||||||
for (int j=0;j<div_y;j++) {
|
for (int j=0;j<div_y;j++) {
|
||||||
|
|
||||||
_SPLIT(j,div_y,y,len_y,new_y,new_len_y);
|
_SPLIT(j,div_y,y,len_y,new_y,new_len_y);
|
||||||
|
|
||||||
for (int k=0;k<div_z;k++) {
|
for (int k=0;k<div_z;k++) {
|
||||||
|
|
||||||
_SPLIT(k,div_z,z,len_z,new_z,new_len_z);
|
_SPLIT(k,div_z,z,len_z,new_z,new_len_z);
|
||||||
|
@ -365,39 +365,39 @@ static inline void _mark_outside(uint8_t*** p_cell_status,int x,int y,int z,int
|
||||||
|
|
||||||
if (p_cell_status[x][y][z]&3)
|
if (p_cell_status[x][y][z]&3)
|
||||||
return; // nothing to do, already used and/or visited
|
return; // nothing to do, already used and/or visited
|
||||||
|
|
||||||
p_cell_status[x][y][z]=_CELL_PREV_FIRST;
|
p_cell_status[x][y][z]=_CELL_PREV_FIRST;
|
||||||
|
|
||||||
while(true) {
|
while(true) {
|
||||||
|
|
||||||
uint8_t &c = p_cell_status[x][y][z];
|
uint8_t &c = p_cell_status[x][y][z];
|
||||||
|
|
||||||
//printf("at %i,%i,%i\n",x,y,z);
|
//printf("at %i,%i,%i\n",x,y,z);
|
||||||
|
|
||||||
if ( (c&_CELL_STEP_MASK)==_CELL_STEP_NONE) {
|
if ( (c&_CELL_STEP_MASK)==_CELL_STEP_NONE) {
|
||||||
/* Haven't been in here, mark as outside */
|
/* Haven't been in here, mark as outside */
|
||||||
p_cell_status[x][y][z]|=_CELL_EXTERIOR;
|
p_cell_status[x][y][z]|=_CELL_EXTERIOR;
|
||||||
//printf("not marked as anything, marking exterior\n");
|
//printf("not marked as anything, marking exterior\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
//printf("cell step is %i\n",(c&_CELL_STEP_MASK));
|
//printf("cell step is %i\n",(c&_CELL_STEP_MASK));
|
||||||
|
|
||||||
if ( (c&_CELL_STEP_MASK)!=_CELL_STEP_DONE) {
|
if ( (c&_CELL_STEP_MASK)!=_CELL_STEP_DONE) {
|
||||||
/* if not done, increase step */
|
/* if not done, increase step */
|
||||||
c+=1<<2;
|
c+=1<<2;
|
||||||
//printf("incrementing cell step\n");
|
//printf("incrementing cell step\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( (c&_CELL_STEP_MASK)==_CELL_STEP_DONE) {
|
if ( (c&_CELL_STEP_MASK)==_CELL_STEP_DONE) {
|
||||||
/* Go back */
|
/* Go back */
|
||||||
//printf("done, going back a cell\n");
|
//printf("done, going back a cell\n");
|
||||||
|
|
||||||
switch(c&_CELL_PREV_MASK) {
|
switch(c&_CELL_PREV_MASK) {
|
||||||
case _CELL_PREV_FIRST: {
|
case _CELL_PREV_FIRST: {
|
||||||
//printf("at end, finished marking\n");
|
//printf("at end, finished marking\n");
|
||||||
return;
|
return;
|
||||||
} break;
|
} break;
|
||||||
case _CELL_PREV_Y_POS: {
|
case _CELL_PREV_Y_POS: {
|
||||||
y++;
|
y++;
|
||||||
ERR_FAIL_COND(y>=len_y);
|
ERR_FAIL_COND(y>=len_y);
|
||||||
} break;
|
} break;
|
||||||
|
@ -427,16 +427,16 @@ static inline void _mark_outside(uint8_t*** p_cell_status,int x,int y,int z,int
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
//printf("attempting new cell!\n");
|
//printf("attempting new cell!\n");
|
||||||
|
|
||||||
int next_x=x,next_y=y,next_z=z;
|
int next_x=x,next_y=y,next_z=z;
|
||||||
uint8_t prev=0;
|
uint8_t prev=0;
|
||||||
|
|
||||||
switch(c&_CELL_STEP_MASK) {
|
switch(c&_CELL_STEP_MASK) {
|
||||||
|
|
||||||
case _CELL_STEP_Y_POS: {
|
case _CELL_STEP_Y_POS: {
|
||||||
|
|
||||||
next_y++;
|
next_y++;
|
||||||
prev=_CELL_PREV_Y_NEG;
|
prev=_CELL_PREV_Y_NEG;
|
||||||
} break;
|
} break;
|
||||||
|
@ -454,32 +454,32 @@ static inline void _mark_outside(uint8_t*** p_cell_status,int x,int y,int z,int
|
||||||
} break;
|
} break;
|
||||||
case _CELL_STEP_Z_POS: {
|
case _CELL_STEP_Z_POS: {
|
||||||
next_z++;
|
next_z++;
|
||||||
prev=_CELL_PREV_Z_NEG;
|
prev=_CELL_PREV_Z_NEG;
|
||||||
} break;
|
} break;
|
||||||
case _CELL_STEP_Z_NEG: {
|
case _CELL_STEP_Z_NEG: {
|
||||||
next_z--;
|
next_z--;
|
||||||
prev=_CELL_PREV_Z_POS;
|
prev=_CELL_PREV_Z_POS;
|
||||||
} break;
|
} break;
|
||||||
default: ERR_FAIL();
|
default: ERR_FAIL();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//printf("testing if new cell will be ok...!\n");
|
//printf("testing if new cell will be ok...!\n");
|
||||||
|
|
||||||
if (next_x<0 || next_x>=len_x)
|
if (next_x<0 || next_x>=len_x)
|
||||||
continue;
|
continue;
|
||||||
if (next_y<0 || next_y>=len_y)
|
if (next_y<0 || next_y>=len_y)
|
||||||
continue;
|
continue;
|
||||||
if (next_z<0 || next_z>=len_z)
|
if (next_z<0 || next_z>=len_z)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
//printf("testing if new cell is traversable\n");
|
//printf("testing if new cell is traversable\n");
|
||||||
|
|
||||||
if (p_cell_status[next_x][next_y][next_z]&3)
|
if (p_cell_status[next_x][next_y][next_z]&3)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
//printf("move to it\n");
|
//printf("move to it\n");
|
||||||
|
|
||||||
x=next_x;
|
x=next_x;
|
||||||
y=next_y;
|
y=next_y;
|
||||||
z=next_z;
|
z=next_z;
|
||||||
|
@ -488,14 +488,14 @@ static inline void _mark_outside(uint8_t*** p_cell_status,int x,int y,int z,int
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void _build_faces(uint8_t*** p_cell_status,int x,int y,int z,int len_x,int len_y,int len_z,DVector<Face3>& p_faces) {
|
static inline void _build_faces(uint8_t*** p_cell_status,int x,int y,int z,int len_x,int len_y,int len_z,DVector<Face3>& p_faces) {
|
||||||
|
|
||||||
ERR_FAIL_INDEX(x,len_x);
|
ERR_FAIL_INDEX(x,len_x);
|
||||||
ERR_FAIL_INDEX(y,len_y);
|
ERR_FAIL_INDEX(y,len_y);
|
||||||
ERR_FAIL_INDEX(z,len_z);
|
ERR_FAIL_INDEX(z,len_z);
|
||||||
|
|
||||||
if (p_cell_status[x][y][z]&_CELL_EXTERIOR)
|
if (p_cell_status[x][y][z]&_CELL_EXTERIOR)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* static const Vector3 vertices[8]={
|
/* static const Vector3 vertices[8]={
|
||||||
Vector3(0,0,0),
|
Vector3(0,0,0),
|
||||||
Vector3(0,0,1),
|
Vector3(0,0,1),
|
||||||
|
@ -510,73 +510,73 @@ static inline void _build_faces(uint8_t*** p_cell_status,int x,int y,int z,int l
|
||||||
#define vert(m_idx) Vector3( (m_idx&4)>>2, (m_idx&2)>>1, m_idx&1 )
|
#define vert(m_idx) Vector3( (m_idx&4)>>2, (m_idx&2)>>1, m_idx&1 )
|
||||||
|
|
||||||
static const uint8_t indices[6][4]={
|
static const uint8_t indices[6][4]={
|
||||||
{7,6,4,5},
|
{7,6,4,5},
|
||||||
{7,3,2,6},
|
{7,3,2,6},
|
||||||
{7,5,1,3},
|
{7,5,1,3},
|
||||||
{0,2,3,1},
|
{0,2,3,1},
|
||||||
{0,1,5,4},
|
{0,1,5,4},
|
||||||
{0,4,6,2},
|
{0,4,6,2},
|
||||||
|
|
||||||
};
|
};
|
||||||
/*
|
/*
|
||||||
|
|
||||||
{0,1,2,3},
|
{0,1,2,3},
|
||||||
{0,1,4,5},
|
{0,1,4,5},
|
||||||
{0,2,4,6},
|
{0,2,4,6},
|
||||||
{4,5,6,7},
|
{4,5,6,7},
|
||||||
{2,3,7,6},
|
{2,3,7,6},
|
||||||
{1,3,5,7},
|
{1,3,5,7},
|
||||||
|
|
||||||
{0,2,3,1},
|
{0,2,3,1},
|
||||||
{0,1,5,4},
|
{0,1,5,4},
|
||||||
{0,4,6,2},
|
{0,4,6,2},
|
||||||
{7,6,4,5},
|
{7,6,4,5},
|
||||||
{7,3,2,6},
|
{7,3,2,6},
|
||||||
{7,5,1,3},
|
{7,5,1,3},
|
||||||
*/
|
*/
|
||||||
|
|
||||||
for (int i=0;i<6;i++) {
|
for (int i=0;i<6;i++) {
|
||||||
|
|
||||||
Vector3 face_points[4];
|
Vector3 face_points[4];
|
||||||
int disp_x=x+((i%3)==0?((i<3)?1:-1):0);
|
int disp_x=x+((i%3)==0?((i<3)?1:-1):0);
|
||||||
int disp_y=y+(((i-1)%3)==0?((i<3)?1:-1):0);
|
int disp_y=y+(((i-1)%3)==0?((i<3)?1:-1):0);
|
||||||
int disp_z=z+(((i-2)%3)==0?((i<3)?1:-1):0);
|
int disp_z=z+(((i-2)%3)==0?((i<3)?1:-1):0);
|
||||||
|
|
||||||
bool plot=false;
|
bool plot=false;
|
||||||
|
|
||||||
if (disp_x<0 || disp_x>=len_x)
|
if (disp_x<0 || disp_x>=len_x)
|
||||||
plot=true;
|
plot=true;
|
||||||
if (disp_y<0 || disp_y>=len_y)
|
if (disp_y<0 || disp_y>=len_y)
|
||||||
plot=true;
|
plot=true;
|
||||||
if (disp_z<0 || disp_z>=len_z)
|
if (disp_z<0 || disp_z>=len_z)
|
||||||
plot=true;
|
plot=true;
|
||||||
|
|
||||||
if (!plot && (p_cell_status[disp_x][disp_y][disp_z]&_CELL_EXTERIOR))
|
if (!plot && (p_cell_status[disp_x][disp_y][disp_z]&_CELL_EXTERIOR))
|
||||||
plot=true;
|
plot=true;
|
||||||
|
|
||||||
if (!plot)
|
if (!plot)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (int j=0;j<4;j++)
|
for (int j=0;j<4;j++)
|
||||||
face_points[j]=vert( indices[i][j] ) + Vector3(x,y,z);
|
face_points[j]=vert( indices[i][j] ) + Vector3(x,y,z);
|
||||||
|
|
||||||
p_faces.push_back(
|
p_faces.push_back(
|
||||||
Face3(
|
Face3(
|
||||||
face_points[0],
|
face_points[0],
|
||||||
face_points[1],
|
face_points[1],
|
||||||
face_points[2]
|
face_points[2]
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
p_faces.push_back(
|
p_faces.push_back(
|
||||||
Face3(
|
Face3(
|
||||||
face_points[2],
|
face_points[2],
|
||||||
face_points[3],
|
face_points[3],
|
||||||
face_points[0]
|
face_points[0]
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -601,7 +601,7 @@ DVector< Face3 > Geometry::wrap_geometry( DVector< Face3 > p_array,float *p_erro
|
||||||
global_aabb.merge_with( faces[i].get_aabb() );
|
global_aabb.merge_with( faces[i].get_aabb() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
global_aabb.grow_by(0.01); // avoid numerical error
|
global_aabb.grow_by(0.01); // avoid numerical error
|
||||||
|
|
||||||
// determine amount of cells in grid axis
|
// determine amount of cells in grid axis
|
||||||
|
@ -649,7 +649,7 @@ DVector< Face3 > Geometry::wrap_geometry( DVector< Face3 > p_array,float *p_erro
|
||||||
|
|
||||||
// plot faces into cells
|
// plot faces into cells
|
||||||
print_line("Wrapper (1/6): Plotting Faces");
|
print_line("Wrapper (1/6): Plotting Faces");
|
||||||
|
|
||||||
for (int i=0;i<face_count;i++) {
|
for (int i=0;i<face_count;i++) {
|
||||||
|
|
||||||
Face3 f=faces[i];
|
Face3 f=faces[i];
|
||||||
|
@ -666,68 +666,68 @@ DVector< Face3 > Geometry::wrap_geometry( DVector< Face3 > p_array,float *p_erro
|
||||||
print_line("Wrapper (2/6) Flood Filling");
|
print_line("Wrapper (2/6) Flood Filling");
|
||||||
|
|
||||||
for (int i=0;i<div_x;i++) {
|
for (int i=0;i<div_x;i++) {
|
||||||
|
|
||||||
for (int j=0;j<div_y;j++) {
|
for (int j=0;j<div_y;j++) {
|
||||||
|
|
||||||
_mark_outside(cell_status,i,j,0,div_x,div_y,div_z);
|
_mark_outside(cell_status,i,j,0,div_x,div_y,div_z);
|
||||||
_mark_outside(cell_status,i,j,div_z-1,div_x,div_y,div_z);
|
_mark_outside(cell_status,i,j,div_z-1,div_x,div_y,div_z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i=0;i<div_z;i++) {
|
for (int i=0;i<div_z;i++) {
|
||||||
|
|
||||||
for (int j=0;j<div_y;j++) {
|
for (int j=0;j<div_y;j++) {
|
||||||
|
|
||||||
_mark_outside(cell_status,0,j,i,div_x,div_y,div_z);
|
_mark_outside(cell_status,0,j,i,div_x,div_y,div_z);
|
||||||
_mark_outside(cell_status,div_x-1,j,i,div_x,div_y,div_z);
|
_mark_outside(cell_status,div_x-1,j,i,div_x,div_y,div_z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i=0;i<div_x;i++) {
|
for (int i=0;i<div_x;i++) {
|
||||||
|
|
||||||
for (int j=0;j<div_z;j++) {
|
for (int j=0;j<div_z;j++) {
|
||||||
|
|
||||||
_mark_outside(cell_status,i,0,j,div_x,div_y,div_z);
|
_mark_outside(cell_status,i,0,j,div_x,div_y,div_z);
|
||||||
_mark_outside(cell_status,i,div_y-1,j,div_x,div_y,div_z);
|
_mark_outside(cell_status,i,div_y-1,j,div_x,div_y,div_z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// build faces for the inside-outside cell divisors
|
// build faces for the inside-outside cell divisors
|
||||||
|
|
||||||
print_line("Wrapper (3/6): Building Faces");
|
print_line("Wrapper (3/6): Building Faces");
|
||||||
|
|
||||||
DVector<Face3> wrapped_faces;
|
DVector<Face3> wrapped_faces;
|
||||||
|
|
||||||
for (int i=0;i<div_x;i++) {
|
for (int i=0;i<div_x;i++) {
|
||||||
|
|
||||||
for (int j=0;j<div_y;j++) {
|
for (int j=0;j<div_y;j++) {
|
||||||
|
|
||||||
for (int k=0;k<div_z;k++) {
|
for (int k=0;k<div_z;k++) {
|
||||||
|
|
||||||
_build_faces(cell_status,i,j,k,div_x,div_y,div_z,wrapped_faces);
|
_build_faces(cell_status,i,j,k,div_x,div_y,div_z,wrapped_faces);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
print_line("Wrapper (4/6): Transforming Back Vertices");
|
print_line("Wrapper (4/6): Transforming Back Vertices");
|
||||||
|
|
||||||
// transform face vertices to global coords
|
// transform face vertices to global coords
|
||||||
|
|
||||||
int wrapped_faces_count=wrapped_faces.size();
|
int wrapped_faces_count=wrapped_faces.size();
|
||||||
DVector<Face3>::Write wrapped_facesw=wrapped_faces.write();
|
DVector<Face3>::Write wrapped_facesw=wrapped_faces.write();
|
||||||
Face3* wrapped_faces_ptr=wrapped_facesw.ptr();
|
Face3* wrapped_faces_ptr=wrapped_facesw.ptr();
|
||||||
|
|
||||||
for(int i=0;i<wrapped_faces_count;i++) {
|
for(int i=0;i<wrapped_faces_count;i++) {
|
||||||
|
|
||||||
for(int j=0;j<3;j++) {
|
for(int j=0;j<3;j++) {
|
||||||
|
|
||||||
Vector3& v = wrapped_faces_ptr[i].vertex[j];
|
Vector3& v = wrapped_faces_ptr[i].vertex[j];
|
||||||
v=v*voxelsize;
|
v=v*voxelsize;
|
||||||
v+=global_aabb.pos;
|
v+=global_aabb.pos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// clean up grid
|
// clean up grid
|
||||||
print_line("Wrapper (5/6): Grid Cleanup");
|
print_line("Wrapper (5/6): Grid Cleanup");
|
||||||
|
|
||||||
for(int i=0;i<div_x;i++) {
|
for(int i=0;i<div_x;i++) {
|
||||||
|
@ -736,14 +736,14 @@ DVector< Face3 > Geometry::wrap_geometry( DVector< Face3 > p_array,float *p_erro
|
||||||
|
|
||||||
memdelete_arr( cell_status[i][j] );
|
memdelete_arr( cell_status[i][j] );
|
||||||
}
|
}
|
||||||
|
|
||||||
memdelete_arr( cell_status[i] );
|
memdelete_arr( cell_status[i] );
|
||||||
}
|
}
|
||||||
|
|
||||||
memdelete_arr(cell_status);
|
memdelete_arr(cell_status);
|
||||||
if (p_error)
|
if (p_error)
|
||||||
*p_error=voxelsize.length();
|
*p_error=voxelsize.length();
|
||||||
|
|
||||||
print_line("Wrapper (6/6): Finished.");
|
print_line("Wrapper (6/6): Finished.");
|
||||||
return wrapped_faces;
|
return wrapped_faces;
|
||||||
}
|
}
|
||||||
|
@ -751,67 +751,67 @@ DVector< Face3 > Geometry::wrap_geometry( DVector< Face3 > p_array,float *p_erro
|
||||||
Geometry::MeshData Geometry::build_convex_mesh(const DVector<Plane> &p_planes) {
|
Geometry::MeshData Geometry::build_convex_mesh(const DVector<Plane> &p_planes) {
|
||||||
|
|
||||||
MeshData mesh;
|
MeshData mesh;
|
||||||
|
|
||||||
|
|
||||||
#define SUBPLANE_SIZE 1024.0
|
#define SUBPLANE_SIZE 1024.0
|
||||||
|
|
||||||
float subplane_size = 1024.0; // should compute this from the actual plane
|
float subplane_size = 1024.0; // should compute this from the actual plane
|
||||||
for (int i=0;i<p_planes.size();i++) {
|
for (int i=0;i<p_planes.size();i++) {
|
||||||
|
|
||||||
Plane p =p_planes[i];
|
Plane p =p_planes[i];
|
||||||
|
|
||||||
Vector3 ref=Vector3(0.0,1.0,0.0);
|
Vector3 ref=Vector3(0.0,1.0,0.0);
|
||||||
|
|
||||||
if (ABS(p.normal.dot(ref))>0.95)
|
if (ABS(p.normal.dot(ref))>0.95)
|
||||||
ref=Vector3(0.0,0.0,1.0); // change axis
|
ref=Vector3(0.0,0.0,1.0); // change axis
|
||||||
|
|
||||||
Vector3 right = p.normal.cross(ref).normalized();
|
Vector3 right = p.normal.cross(ref).normalized();
|
||||||
Vector3 up = p.normal.cross( right ).normalized();
|
Vector3 up = p.normal.cross( right ).normalized();
|
||||||
|
|
||||||
Vector< Vector3 > vertices;
|
Vector< Vector3 > vertices;
|
||||||
|
|
||||||
Vector3 center = p.get_any_point();
|
Vector3 center = p.get_any_point();
|
||||||
// make a quad clockwise
|
// make a quad clockwise
|
||||||
vertices.push_back( center - up * subplane_size + right * subplane_size );
|
vertices.push_back( center - up * subplane_size + right * subplane_size );
|
||||||
vertices.push_back( center - up * subplane_size - right * subplane_size );
|
vertices.push_back( center - up * subplane_size - right * subplane_size );
|
||||||
vertices.push_back( center + up * subplane_size - right * subplane_size );
|
vertices.push_back( center + up * subplane_size - right * subplane_size );
|
||||||
vertices.push_back( center + up * subplane_size + right * subplane_size );
|
vertices.push_back( center + up * subplane_size + right * subplane_size );
|
||||||
|
|
||||||
for (int j=0;j<p_planes.size();j++) {
|
for (int j=0;j<p_planes.size();j++) {
|
||||||
|
|
||||||
if (j==i)
|
if (j==i)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
||||||
Vector< Vector3 > new_vertices;
|
Vector< Vector3 > new_vertices;
|
||||||
Plane clip=p_planes[j];
|
Plane clip=p_planes[j];
|
||||||
|
|
||||||
if (clip.normal.dot(p.normal)>0.95)
|
if (clip.normal.dot(p.normal)>0.95)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (vertices.size()<3)
|
if (vertices.size()<3)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
for(int k=0;k<vertices.size();k++) {
|
for(int k=0;k<vertices.size();k++) {
|
||||||
|
|
||||||
int k_n=(k+1)%vertices.size();
|
int k_n=(k+1)%vertices.size();
|
||||||
|
|
||||||
Vector3 edge0_A=vertices[k];
|
Vector3 edge0_A=vertices[k];
|
||||||
Vector3 edge1_A=vertices[k_n];
|
Vector3 edge1_A=vertices[k_n];
|
||||||
|
|
||||||
real_t dist0 = clip.distance_to(edge0_A);
|
real_t dist0 = clip.distance_to(edge0_A);
|
||||||
real_t dist1 = clip.distance_to(edge1_A);
|
real_t dist1 = clip.distance_to(edge1_A);
|
||||||
|
|
||||||
|
|
||||||
if ( dist0 <= 0 ) { // behind plane
|
if ( dist0 <= 0 ) { // behind plane
|
||||||
|
|
||||||
new_vertices.push_back(vertices[k]);
|
new_vertices.push_back(vertices[k]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// check for different sides and non coplanar
|
// check for different sides and non coplanar
|
||||||
if ( (dist0*dist1) < 0) {
|
if ( (dist0*dist1) < 0) {
|
||||||
|
|
||||||
// calculate intersection
|
// calculate intersection
|
||||||
Vector3 rel = edge1_A - edge0_A;
|
Vector3 rel = edge1_A - edge0_A;
|
||||||
|
|
||||||
|
@ -822,55 +822,55 @@ Geometry::MeshData Geometry::build_convex_mesh(const DVector<Plane> &p_planes) {
|
||||||
real_t dist=-(clip.normal.dot( edge0_A )-clip.d)/den;
|
real_t dist=-(clip.normal.dot( edge0_A )-clip.d)/den;
|
||||||
Vector3 inters = edge0_A+rel*dist;
|
Vector3 inters = edge0_A+rel*dist;
|
||||||
new_vertices.push_back(inters);
|
new_vertices.push_back(inters);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vertices=new_vertices;
|
vertices=new_vertices;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vertices.size()<3)
|
if (vertices.size()<3)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
||||||
//result is a clockwise face
|
//result is a clockwise face
|
||||||
|
|
||||||
MeshData::Face face;
|
MeshData::Face face;
|
||||||
|
|
||||||
// add face indices
|
// add face indices
|
||||||
for (int j=0;j<vertices.size();j++) {
|
for (int j=0;j<vertices.size();j++) {
|
||||||
|
|
||||||
|
|
||||||
int idx=-1;
|
int idx=-1;
|
||||||
for (int k=0;k<mesh.vertices.size();k++) {
|
for (int k=0;k<mesh.vertices.size();k++) {
|
||||||
|
|
||||||
if (mesh.vertices[k].distance_to(vertices[j])<0.001) {
|
if (mesh.vertices[k].distance_to(vertices[j])<0.001) {
|
||||||
|
|
||||||
idx=k;
|
idx=k;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (idx==-1) {
|
if (idx==-1) {
|
||||||
|
|
||||||
idx=mesh.vertices.size();
|
idx=mesh.vertices.size();
|
||||||
mesh.vertices.push_back(vertices[j]);
|
mesh.vertices.push_back(vertices[j]);
|
||||||
}
|
}
|
||||||
|
|
||||||
face.indices.push_back(idx);
|
face.indices.push_back(idx);
|
||||||
}
|
}
|
||||||
face.plane=p;
|
face.plane=p;
|
||||||
mesh.faces.push_back(face);
|
mesh.faces.push_back(face);
|
||||||
|
|
||||||
//add edge
|
//add edge
|
||||||
|
|
||||||
for(int j=0;j<face.indices.size();j++) {
|
for(int j=0;j<face.indices.size();j++) {
|
||||||
|
|
||||||
int a=face.indices[j];
|
int a=face.indices[j];
|
||||||
int b=face.indices[(j+1)%face.indices.size()];
|
int b=face.indices[(j+1)%face.indices.size()];
|
||||||
|
|
||||||
bool found=false;
|
bool found=false;
|
||||||
for(int k=0;k<mesh.edges.size();k++) {
|
for(int k=0;k<mesh.edges.size();k++) {
|
||||||
|
|
||||||
if (mesh.edges[k].a==a && mesh.edges[k].b==b) {
|
if (mesh.edges[k].a==a && mesh.edges[k].b==b) {
|
||||||
found=true;
|
found=true;
|
||||||
break;
|
break;
|
||||||
|
@ -878,9 +878,9 @@ Geometry::MeshData Geometry::build_convex_mesh(const DVector<Plane> &p_planes) {
|
||||||
if (mesh.edges[k].b==a && mesh.edges[k].a==b) {
|
if (mesh.edges[k].b==a && mesh.edges[k].a==b) {
|
||||||
found=true;
|
found=true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (found)
|
if (found)
|
||||||
continue;
|
continue;
|
||||||
MeshData::Edge edge;
|
MeshData::Edge edge;
|
||||||
|
@ -888,8 +888,8 @@ Geometry::MeshData Geometry::build_convex_mesh(const DVector<Plane> &p_planes) {
|
||||||
edge.b=b;
|
edge.b=b;
|
||||||
mesh.edges.push_back(edge);
|
mesh.edges.push_back(edge);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return mesh;
|
return mesh;
|
||||||
|
@ -899,36 +899,36 @@ Geometry::MeshData Geometry::build_convex_mesh(const DVector<Plane> &p_planes) {
|
||||||
DVector<Plane> Geometry::build_box_planes(const Vector3& p_extents) {
|
DVector<Plane> Geometry::build_box_planes(const Vector3& p_extents) {
|
||||||
|
|
||||||
DVector<Plane> planes;
|
DVector<Plane> planes;
|
||||||
|
|
||||||
planes.push_back( Plane( Vector3(1,0,0), p_extents.x ) );
|
planes.push_back( Plane( Vector3(1,0,0), p_extents.x ) );
|
||||||
planes.push_back( Plane( Vector3(-1,0,0), p_extents.x ) );
|
planes.push_back( Plane( Vector3(-1,0,0), p_extents.x ) );
|
||||||
planes.push_back( Plane( Vector3(0,1,0), p_extents.y ) );
|
planes.push_back( Plane( Vector3(0,1,0), p_extents.y ) );
|
||||||
planes.push_back( Plane( Vector3(0,-1,0), p_extents.y ) );
|
planes.push_back( Plane( Vector3(0,-1,0), p_extents.y ) );
|
||||||
planes.push_back( Plane( Vector3(0,0,1), p_extents.z ) );
|
planes.push_back( Plane( Vector3(0,0,1), p_extents.z ) );
|
||||||
planes.push_back( Plane( Vector3(0,0,-1), p_extents.z ) );
|
planes.push_back( Plane( Vector3(0,0,-1), p_extents.z ) );
|
||||||
|
|
||||||
return planes;
|
return planes;
|
||||||
}
|
}
|
||||||
|
|
||||||
DVector<Plane> Geometry::build_cylinder_planes(float p_radius, float p_height, int p_sides, Vector3::Axis p_axis) {
|
DVector<Plane> Geometry::build_cylinder_planes(float p_radius, float p_height, int p_sides, Vector3::Axis p_axis) {
|
||||||
|
|
||||||
DVector<Plane> planes;
|
DVector<Plane> planes;
|
||||||
|
|
||||||
for (int i=0;i<p_sides;i++) {
|
for (int i=0;i<p_sides;i++) {
|
||||||
|
|
||||||
Vector3 normal;
|
Vector3 normal;
|
||||||
normal[(p_axis+1)%3]=Math::cos(i*(2.0*Math_PI)/p_sides);
|
normal[(p_axis+1)%3]=Math::cos(i*(2.0*Math_PI)/p_sides);
|
||||||
normal[(p_axis+2)%3]=Math::sin(i*(2.0*Math_PI)/p_sides);
|
normal[(p_axis+2)%3]=Math::sin(i*(2.0*Math_PI)/p_sides);
|
||||||
|
|
||||||
planes.push_back( Plane( normal, p_radius ) );
|
planes.push_back( Plane( normal, p_radius ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3 axis;
|
Vector3 axis;
|
||||||
axis[p_axis]=1.0;
|
axis[p_axis]=1.0;
|
||||||
|
|
||||||
planes.push_back( Plane( axis, p_height*0.5 ) );
|
planes.push_back( Plane( axis, p_height*0.5 ) );
|
||||||
planes.push_back( Plane( -axis, p_height*0.5 ) );
|
planes.push_back( Plane( -axis, p_height*0.5 ) );
|
||||||
|
|
||||||
return planes;
|
return planes;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -972,34 +972,34 @@ DVector<Plane> Geometry::build_sphere_planes(float p_radius, int p_lats,int p_lo
|
||||||
DVector<Plane> Geometry::build_capsule_planes(float p_radius, float p_height, int p_sides, int p_lats, Vector3::Axis p_axis) {
|
DVector<Plane> Geometry::build_capsule_planes(float p_radius, float p_height, int p_sides, int p_lats, Vector3::Axis p_axis) {
|
||||||
|
|
||||||
DVector<Plane> planes;
|
DVector<Plane> planes;
|
||||||
|
|
||||||
Vector3 axis;
|
Vector3 axis;
|
||||||
axis[p_axis]=1.0;
|
axis[p_axis]=1.0;
|
||||||
|
|
||||||
Vector3 axis_neg;
|
Vector3 axis_neg;
|
||||||
axis_neg[(p_axis+1)%3]=1.0;
|
axis_neg[(p_axis+1)%3]=1.0;
|
||||||
axis_neg[(p_axis+2)%3]=1.0;
|
axis_neg[(p_axis+2)%3]=1.0;
|
||||||
axis_neg[p_axis]=-1.0;
|
axis_neg[p_axis]=-1.0;
|
||||||
|
|
||||||
for (int i=0;i<p_sides;i++) {
|
for (int i=0;i<p_sides;i++) {
|
||||||
|
|
||||||
Vector3 normal;
|
Vector3 normal;
|
||||||
normal[(p_axis+1)%3]=Math::cos(i*(2.0*Math_PI)/p_sides);
|
normal[(p_axis+1)%3]=Math::cos(i*(2.0*Math_PI)/p_sides);
|
||||||
normal[(p_axis+2)%3]=Math::sin(i*(2.0*Math_PI)/p_sides);
|
normal[(p_axis+2)%3]=Math::sin(i*(2.0*Math_PI)/p_sides);
|
||||||
|
|
||||||
planes.push_back( Plane( normal, p_radius ) );
|
planes.push_back( Plane( normal, p_radius ) );
|
||||||
|
|
||||||
for (int j=1;j<=p_lats;j++) {
|
for (int j=1;j<=p_lats;j++) {
|
||||||
|
|
||||||
Vector3 angle = normal.linear_interpolate(axis,j/(float)p_lats).normalized();
|
Vector3 angle = normal.linear_interpolate(axis,j/(float)p_lats).normalized();
|
||||||
Vector3 pos = axis*p_height*0.5 + angle*p_radius;
|
Vector3 pos = axis*p_height*0.5 + angle*p_radius;
|
||||||
planes.push_back( Plane( pos, angle ) );
|
planes.push_back( Plane( pos, angle ) );
|
||||||
planes.push_back( Plane( pos * axis_neg, angle * axis_neg) );
|
planes.push_back( Plane( pos * axis_neg, angle * axis_neg) );
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return planes;
|
return planes;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@
|
||||||
class Geometry {
|
class Geometry {
|
||||||
Geometry();
|
Geometry();
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -201,37 +201,37 @@ public:
|
||||||
real_t a =e1.dot(h);
|
real_t a =e1.dot(h);
|
||||||
if (a>-CMP_EPSILON && a < CMP_EPSILON) // parallel test
|
if (a>-CMP_EPSILON && a < CMP_EPSILON) // parallel test
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
real_t f=1.0/a;
|
real_t f=1.0/a;
|
||||||
|
|
||||||
Vector3 s=p_from-p_v0;
|
Vector3 s=p_from-p_v0;
|
||||||
real_t u = f * s.dot(h);
|
real_t u = f * s.dot(h);
|
||||||
|
|
||||||
if ( u< 0.0 || u > 1.0)
|
if ( u< 0.0 || u > 1.0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
Vector3 q=s.cross(e1);
|
Vector3 q=s.cross(e1);
|
||||||
|
|
||||||
real_t v = f * p_dir.dot(q);
|
real_t v = f * p_dir.dot(q);
|
||||||
|
|
||||||
if (v < 0.0 || u + v > 1.0)
|
if (v < 0.0 || u + v > 1.0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// at this stage we can compute t to find out where
|
// at this stage we can compute t to find out where
|
||||||
// the intersection point is on the line
|
// the intersection point is on the line
|
||||||
real_t t = f * e2.dot(q);
|
real_t t = f * e2.dot(q);
|
||||||
|
|
||||||
if (t > 0.00001) {// ray intersection
|
if (t > 0.00001) {// ray intersection
|
||||||
if (r_res)
|
if (r_res)
|
||||||
*r_res=p_from+p_dir*t;
|
*r_res=p_from+p_dir*t;
|
||||||
return true;
|
return true;
|
||||||
} else // this means that there is a line intersection
|
} else // this means that there is a line intersection
|
||||||
// but not a ray intersection
|
// but not a ray intersection
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool segment_intersects_triangle( const Vector3& p_from, const Vector3& p_to, const Vector3& p_v0,const Vector3& p_v1,const Vector3& p_v2,Vector3* r_res=0) {
|
static inline bool segment_intersects_triangle( const Vector3& p_from, const Vector3& p_to, const Vector3& p_v0,const Vector3& p_v1,const Vector3& p_v2,Vector3* r_res=0) {
|
||||||
|
|
||||||
Vector3 rel=p_to-p_from;
|
Vector3 rel=p_to-p_from;
|
||||||
Vector3 e1=p_v1-p_v0;
|
Vector3 e1=p_v1-p_v0;
|
||||||
Vector3 e2=p_v2-p_v0;
|
Vector3 e2=p_v2-p_v0;
|
||||||
|
@ -239,34 +239,34 @@ public:
|
||||||
real_t a =e1.dot(h);
|
real_t a =e1.dot(h);
|
||||||
if (a>-CMP_EPSILON && a < CMP_EPSILON) // parallel test
|
if (a>-CMP_EPSILON && a < CMP_EPSILON) // parallel test
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
real_t f=1.0/a;
|
real_t f=1.0/a;
|
||||||
|
|
||||||
Vector3 s=p_from-p_v0;
|
Vector3 s=p_from-p_v0;
|
||||||
real_t u = f * s.dot(h);
|
real_t u = f * s.dot(h);
|
||||||
|
|
||||||
if ( u< 0.0 || u > 1.0)
|
if ( u< 0.0 || u > 1.0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
Vector3 q=s.cross(e1);
|
Vector3 q=s.cross(e1);
|
||||||
|
|
||||||
real_t v = f * rel.dot(q);
|
real_t v = f * rel.dot(q);
|
||||||
|
|
||||||
if (v < 0.0 || u + v > 1.0)
|
if (v < 0.0 || u + v > 1.0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// at this stage we can compute t to find out where
|
// at this stage we can compute t to find out where
|
||||||
// the intersection point is on the line
|
// the intersection point is on the line
|
||||||
real_t t = f * e2.dot(q);
|
real_t t = f * e2.dot(q);
|
||||||
|
|
||||||
if (t > CMP_EPSILON && t<=1.0) {// ray intersection
|
if (t > CMP_EPSILON && t<=1.0) {// ray intersection
|
||||||
if (r_res)
|
if (r_res)
|
||||||
*r_res=p_from+rel*t;
|
*r_res=p_from+rel*t;
|
||||||
return true;
|
return true;
|
||||||
} else // this means that there is a line intersection
|
} else // this means that there is a line intersection
|
||||||
// but not a ray intersection
|
// but not a ray intersection
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool segment_intersects_sphere( const Vector3& p_from, const Vector3& p_to, const Vector3& p_sphere_pos,real_t p_sphere_radius,Vector3* r_res=0,Vector3 *r_norm=0) {
|
static inline bool segment_intersects_sphere( const Vector3& p_from, const Vector3& p_to, const Vector3& p_sphere_pos,real_t p_sphere_radius,Vector3* r_res=0,Vector3 *r_norm=0) {
|
||||||
|
|
||||||
|
@ -356,24 +356,24 @@ public:
|
||||||
real_t box_end=size[i];
|
real_t box_end=size[i];
|
||||||
real_t cmin,cmax;
|
real_t cmin,cmax;
|
||||||
|
|
||||||
|
|
||||||
if (seg_from < seg_to) {
|
if (seg_from < seg_to) {
|
||||||
|
|
||||||
if (seg_from > box_end || seg_to < box_begin)
|
if (seg_from > box_end || seg_to < box_begin)
|
||||||
return false;
|
return false;
|
||||||
real_t length=seg_to-seg_from;
|
real_t length=seg_to-seg_from;
|
||||||
cmin = (seg_from < box_begin)?((box_begin - seg_from)/length):0;
|
cmin = (seg_from < box_begin)?((box_begin - seg_from)/length):0;
|
||||||
cmax = (seg_to > box_end)?((box_end - seg_from)/length):1;
|
cmax = (seg_to > box_end)?((box_end - seg_from)/length):1;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if (seg_to > box_end || seg_from < box_begin)
|
if (seg_to > box_end || seg_from < box_begin)
|
||||||
return false;
|
return false;
|
||||||
real_t length=seg_to-seg_from;
|
real_t length=seg_to-seg_from;
|
||||||
cmin = (seg_from > box_end)?(box_end - seg_from)/length:0;
|
cmin = (seg_from > box_end)?(box_end - seg_from)/length:0;
|
||||||
cmax = (seg_to < box_begin)?(box_begin - seg_from)/length:1;
|
cmax = (seg_to < box_begin)?(box_begin - seg_from)/length:1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmin > min) {
|
if (cmin > min) {
|
||||||
min = cmin;
|
min = cmin;
|
||||||
axis=i;
|
axis=i;
|
||||||
|
@ -468,9 +468,9 @@ public:
|
||||||
if (l<1e-10)
|
if (l<1e-10)
|
||||||
return p_segment[0]; // both points are the same, just give any
|
return p_segment[0]; // both points are the same, just give any
|
||||||
n/=l;
|
n/=l;
|
||||||
|
|
||||||
float d=n.dot(p);
|
float d=n.dot(p);
|
||||||
|
|
||||||
if (d<=0.0)
|
if (d<=0.0)
|
||||||
return p_segment[0]; // before first point
|
return p_segment[0]; // before first point
|
||||||
else if (d>=l)
|
else if (d>=l)
|
||||||
|
@ -570,27 +570,27 @@ public:
|
||||||
|
|
||||||
|
|
||||||
static inline bool point_in_projected_triangle(const Vector3& p_point,const Vector3& p_v1,const Vector3& p_v2,const Vector3& p_v3) {
|
static inline bool point_in_projected_triangle(const Vector3& p_point,const Vector3& p_v1,const Vector3& p_v2,const Vector3& p_v3) {
|
||||||
|
|
||||||
|
|
||||||
Vector3 face_n = (p_v1-p_v3).cross(p_v1-p_v2);
|
Vector3 face_n = (p_v1-p_v3).cross(p_v1-p_v2);
|
||||||
|
|
||||||
Vector3 n1 = (p_point-p_v3).cross(p_point-p_v2);
|
Vector3 n1 = (p_point-p_v3).cross(p_point-p_v2);
|
||||||
|
|
||||||
if (face_n.dot(n1)<0)
|
if (face_n.dot(n1)<0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
Vector3 n2 = (p_v1-p_v3).cross(p_v1-p_point);
|
Vector3 n2 = (p_v1-p_v3).cross(p_v1-p_point);
|
||||||
|
|
||||||
if (face_n.dot(n2)<0)
|
if (face_n.dot(n2)<0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
Vector3 n3 = (p_v1-p_point).cross(p_v1-p_v2);
|
Vector3 n3 = (p_v1-p_point).cross(p_v1-p_v2);
|
||||||
|
|
||||||
if (face_n.dot(n3)<0)
|
if (face_n.dot(n3)<0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool triangle_sphere_intersection_test(const Vector3 *p_triangle,const Vector3& p_normal,const Vector3& p_sphere_pos, real_t p_sphere_radius,Vector3& r_triangle_contact,Vector3& r_sphere_contact) {
|
static inline bool triangle_sphere_intersection_test(const Vector3 *p_triangle,const Vector3& p_normal,const Vector3& p_sphere_pos, real_t p_sphere_radius,Vector3& r_triangle_contact,Vector3& r_sphere_contact) {
|
||||||
|
@ -814,21 +814,21 @@ public:
|
||||||
|
|
||||||
|
|
||||||
struct MeshData {
|
struct MeshData {
|
||||||
|
|
||||||
struct Face {
|
struct Face {
|
||||||
Plane plane;
|
Plane plane;
|
||||||
Vector<int> indices;
|
Vector<int> indices;
|
||||||
};
|
};
|
||||||
|
|
||||||
Vector<Face> faces;
|
Vector<Face> faces;
|
||||||
|
|
||||||
struct Edge {
|
struct Edge {
|
||||||
|
|
||||||
int a,b;
|
int a,b;
|
||||||
};
|
};
|
||||||
|
|
||||||
Vector<Edge> edges;
|
Vector<Edge> edges;
|
||||||
|
|
||||||
Vector< Vector3 > vertices;
|
Vector< Vector3 > vertices;
|
||||||
|
|
||||||
void optimize_vertices();
|
void optimize_vertices();
|
||||||
|
@ -927,7 +927,7 @@ public:
|
||||||
|
|
||||||
static void make_atlas(const Vector<Size2i>& p_rects,Vector<Point2i>& r_result, Size2i& r_size);
|
static void make_atlas(const Vector<Size2i>& p_rects,Vector<Point2i>& r_result, Size2i& r_size);
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -45,10 +45,10 @@ float Vector2::length_squared() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Vector2::normalize() {
|
void Vector2::normalize() {
|
||||||
|
|
||||||
float l = x*x + y*y;
|
float l = x*x + y*y;
|
||||||
if (l!=0) {
|
if (l!=0) {
|
||||||
|
|
||||||
l=Math::sqrt(l);
|
l=Math::sqrt(l);
|
||||||
x/=l;
|
x/=l;
|
||||||
y/=l;
|
y/=l;
|
||||||
|
@ -56,14 +56,14 @@ void Vector2::normalize() {
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector2 Vector2::normalized() const {
|
Vector2 Vector2::normalized() const {
|
||||||
|
|
||||||
Vector2 v=*this;
|
Vector2 v=*this;
|
||||||
v.normalize();
|
v.normalize();
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
float Vector2::distance_to(const Vector2& p_vector2) const {
|
float Vector2::distance_to(const Vector2& p_vector2) const {
|
||||||
|
|
||||||
return Math::sqrt( (x-p_vector2.x)*(x-p_vector2.x) + (y-p_vector2.y)*(y-p_vector2.y));
|
return Math::sqrt( (x-p_vector2.x)*(x-p_vector2.x) + (y-p_vector2.y)*(y-p_vector2.y));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ float Vector2::distance_squared_to(const Vector2& p_vector2) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
float Vector2::angle_to(const Vector2& p_vector2) const {
|
float Vector2::angle_to(const Vector2& p_vector2) const {
|
||||||
|
|
||||||
return Math::atan2( tangent().dot(p_vector2), dot(p_vector2) );
|
return Math::atan2( tangent().dot(p_vector2), dot(p_vector2) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,7 +83,7 @@ float Vector2::angle_to_point(const Vector2& p_vector2) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
float Vector2::dot(const Vector2& p_other) const {
|
float Vector2::dot(const Vector2& p_other) const {
|
||||||
|
|
||||||
return x*p_other.x + y*p_other.y;
|
return x*p_other.x + y*p_other.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,62 +99,62 @@ Vector2 Vector2::cross(real_t p_other) const {
|
||||||
|
|
||||||
|
|
||||||
Vector2 Vector2::operator+(const Vector2& p_v) const {
|
Vector2 Vector2::operator+(const Vector2& p_v) const {
|
||||||
|
|
||||||
return Vector2(x+p_v.x,y+p_v.y);
|
return Vector2(x+p_v.x,y+p_v.y);
|
||||||
}
|
}
|
||||||
void Vector2::operator+=(const Vector2& p_v) {
|
void Vector2::operator+=(const Vector2& p_v) {
|
||||||
|
|
||||||
x+=p_v.x; y+=p_v.y;
|
x+=p_v.x; y+=p_v.y;
|
||||||
}
|
}
|
||||||
Vector2 Vector2::operator-(const Vector2& p_v) const {
|
Vector2 Vector2::operator-(const Vector2& p_v) const {
|
||||||
|
|
||||||
return Vector2(x-p_v.x,y-p_v.y);
|
return Vector2(x-p_v.x,y-p_v.y);
|
||||||
}
|
}
|
||||||
void Vector2::operator-=(const Vector2& p_v) {
|
void Vector2::operator-=(const Vector2& p_v) {
|
||||||
|
|
||||||
x-=p_v.x; y-=p_v.y;
|
x-=p_v.x; y-=p_v.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector2 Vector2::operator*(const Vector2 &p_v1) const {
|
Vector2 Vector2::operator*(const Vector2 &p_v1) const {
|
||||||
|
|
||||||
return Vector2(x * p_v1.x, y * p_v1.y);
|
return Vector2(x * p_v1.x, y * p_v1.y);
|
||||||
};
|
};
|
||||||
|
|
||||||
Vector2 Vector2::operator*(const float &rvalue) const {
|
Vector2 Vector2::operator*(const float &rvalue) const {
|
||||||
|
|
||||||
return Vector2(x * rvalue, y * rvalue);
|
return Vector2(x * rvalue, y * rvalue);
|
||||||
};
|
};
|
||||||
void Vector2::operator*=(const float &rvalue) {
|
void Vector2::operator*=(const float &rvalue) {
|
||||||
|
|
||||||
x *= rvalue; y *= rvalue;
|
x *= rvalue; y *= rvalue;
|
||||||
};
|
};
|
||||||
|
|
||||||
Vector2 Vector2::operator/(const Vector2 &p_v1) const {
|
Vector2 Vector2::operator/(const Vector2 &p_v1) const {
|
||||||
|
|
||||||
return Vector2(x / p_v1.x, y / p_v1.y);
|
return Vector2(x / p_v1.x, y / p_v1.y);
|
||||||
};
|
};
|
||||||
|
|
||||||
Vector2 Vector2::operator/(const float &rvalue) const {
|
Vector2 Vector2::operator/(const float &rvalue) const {
|
||||||
|
|
||||||
return Vector2(x / rvalue, y / rvalue);
|
return Vector2(x / rvalue, y / rvalue);
|
||||||
};
|
};
|
||||||
|
|
||||||
void Vector2::operator/=(const float &rvalue) {
|
void Vector2::operator/=(const float &rvalue) {
|
||||||
|
|
||||||
x /= rvalue; y /= rvalue;
|
x /= rvalue; y /= rvalue;
|
||||||
};
|
};
|
||||||
|
|
||||||
Vector2 Vector2::operator-() const {
|
Vector2 Vector2::operator-() const {
|
||||||
|
|
||||||
return Vector2(-x,-y);
|
return Vector2(-x,-y);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Vector2::operator==(const Vector2& p_vec2) const {
|
bool Vector2::operator==(const Vector2& p_vec2) const {
|
||||||
|
|
||||||
return x==p_vec2.x && y==p_vec2.y;
|
return x==p_vec2.x && y==p_vec2.y;
|
||||||
}
|
}
|
||||||
bool Vector2::operator!=(const Vector2& p_vec2) const {
|
bool Vector2::operator!=(const Vector2& p_vec2) const {
|
||||||
|
|
||||||
return x!=p_vec2.x || y!=p_vec2.y;
|
return x!=p_vec2.x || y!=p_vec2.y;
|
||||||
}
|
}
|
||||||
Vector2 Vector2::floor() const {
|
Vector2 Vector2::floor() const {
|
||||||
|
@ -621,25 +621,25 @@ float Matrix32::basis_determinant() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
Matrix32 Matrix32::interpolate_with(const Matrix32& p_transform, float p_c) const {
|
Matrix32 Matrix32::interpolate_with(const Matrix32& p_transform, float p_c) const {
|
||||||
|
|
||||||
//extract parameters
|
//extract parameters
|
||||||
Vector2 p1 = get_origin();
|
Vector2 p1 = get_origin();
|
||||||
Vector2 p2 = p_transform.get_origin();
|
Vector2 p2 = p_transform.get_origin();
|
||||||
|
|
||||||
real_t r1 = get_rotation();
|
real_t r1 = get_rotation();
|
||||||
real_t r2 = p_transform.get_rotation();
|
real_t r2 = p_transform.get_rotation();
|
||||||
|
|
||||||
Vector2 s1 = get_scale();
|
Vector2 s1 = get_scale();
|
||||||
Vector2 s2 = p_transform.get_scale();
|
Vector2 s2 = p_transform.get_scale();
|
||||||
|
|
||||||
//slerp rotation
|
//slerp rotation
|
||||||
Vector2 v1(Math::cos(r1), Math::sin(r1));
|
Vector2 v1(Math::cos(r1), Math::sin(r1));
|
||||||
Vector2 v2(Math::cos(r2), Math::sin(r2));
|
Vector2 v2(Math::cos(r2), Math::sin(r2));
|
||||||
|
|
||||||
real_t dot = v1.dot(v2);
|
real_t dot = v1.dot(v2);
|
||||||
|
|
||||||
dot = (dot < -1.0) ? -1.0 : ((dot > 1.0) ? 1.0 : dot); //clamp dot to [-1,1]
|
dot = (dot < -1.0) ? -1.0 : ((dot > 1.0) ? 1.0 : dot); //clamp dot to [-1,1]
|
||||||
|
|
||||||
Vector2 v;
|
Vector2 v;
|
||||||
|
|
||||||
if (dot > 0.9995) {
|
if (dot > 0.9995) {
|
||||||
|
@ -649,7 +649,7 @@ Matrix32 Matrix32::interpolate_with(const Matrix32& p_transform, float p_c) cons
|
||||||
Vector2 v3 = (v2 - v1*dot).normalized();
|
Vector2 v3 = (v2 - v1*dot).normalized();
|
||||||
v = v1*Math::cos(angle) + v3*Math::sin(angle);
|
v = v1*Math::cos(angle) + v3*Math::sin(angle);
|
||||||
}
|
}
|
||||||
|
|
||||||
//construct matrix
|
//construct matrix
|
||||||
Matrix32 res(Math::atan2(v.y, v.x), Vector2::linear_interpolate(p1, p2, p_c));
|
Matrix32 res(Math::atan2(v.y, v.x), Vector2::linear_interpolate(p1, p2, p_c));
|
||||||
res.scale_basis(Vector2::linear_interpolate(s1, s2, p_c));
|
res.scale_basis(Vector2::linear_interpolate(s1, s2, p_c));
|
||||||
|
|
|
@ -35,15 +35,15 @@
|
||||||
@author Juan Linietsky <reduzio@gmail.com>
|
@author Juan Linietsky <reduzio@gmail.com>
|
||||||
*/
|
*/
|
||||||
enum Margin {
|
enum Margin {
|
||||||
|
|
||||||
MARGIN_LEFT,
|
MARGIN_LEFT,
|
||||||
MARGIN_TOP,
|
MARGIN_TOP,
|
||||||
MARGIN_RIGHT,
|
MARGIN_RIGHT,
|
||||||
MARGIN_BOTTOM
|
MARGIN_BOTTOM
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Orientation {
|
enum Orientation {
|
||||||
|
|
||||||
HORIZONTAL,
|
HORIZONTAL,
|
||||||
VERTICAL
|
VERTICAL
|
||||||
};
|
};
|
||||||
|
@ -63,7 +63,7 @@ enum VAlign {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Vector2 {
|
struct Vector2 {
|
||||||
|
|
||||||
union {
|
union {
|
||||||
float x;
|
float x;
|
||||||
float width;
|
float width;
|
||||||
|
@ -87,7 +87,7 @@ struct Vector2 {
|
||||||
float length() const;
|
float length() const;
|
||||||
float length_squared() const;
|
float length_squared() const;
|
||||||
|
|
||||||
float distance_to(const Vector2& p_vector2) const;
|
float distance_to(const Vector2& p_vector2) const;
|
||||||
float distance_squared_to(const Vector2& p_vector2) const;
|
float distance_squared_to(const Vector2& p_vector2) const;
|
||||||
float angle_to(const Vector2& p_vector2) const;
|
float angle_to(const Vector2& p_vector2) const;
|
||||||
float angle_to_point(const Vector2& p_vector2) const;
|
float angle_to_point(const Vector2& p_vector2) const;
|
||||||
|
@ -114,19 +114,19 @@ struct Vector2 {
|
||||||
Vector2 operator-(const Vector2& p_v) const;
|
Vector2 operator-(const Vector2& p_v) const;
|
||||||
void operator-=(const Vector2& p_v);
|
void operator-=(const Vector2& p_v);
|
||||||
Vector2 operator*(const Vector2 &p_v1) const;
|
Vector2 operator*(const Vector2 &p_v1) const;
|
||||||
|
|
||||||
Vector2 operator*(const float &rvalue) const;
|
Vector2 operator*(const float &rvalue) const;
|
||||||
void operator*=(const float &rvalue);
|
void operator*=(const float &rvalue);
|
||||||
void operator*=(const Vector2 &rvalue) { *this = *this * rvalue; }
|
void operator*=(const Vector2 &rvalue) { *this = *this * rvalue; }
|
||||||
|
|
||||||
Vector2 operator/(const Vector2 &p_v1) const;
|
Vector2 operator/(const Vector2 &p_v1) const;
|
||||||
|
|
||||||
Vector2 operator/(const float &rvalue) const;
|
Vector2 operator/(const float &rvalue) const;
|
||||||
|
|
||||||
void operator/=(const float &rvalue);
|
void operator/=(const float &rvalue);
|
||||||
|
|
||||||
Vector2 operator-() const;
|
Vector2 operator-() const;
|
||||||
|
|
||||||
bool operator==(const Vector2& p_vec2) const;
|
bool operator==(const Vector2& p_vec2) const;
|
||||||
bool operator!=(const Vector2& p_vec2) const;
|
bool operator!=(const Vector2& p_vec2) const;
|
||||||
|
|
||||||
|
@ -151,14 +151,14 @@ struct Vector2 {
|
||||||
|
|
||||||
return Vector2(y,-x);
|
return Vector2(y,-x);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector2 floor() const;
|
Vector2 floor() const;
|
||||||
Vector2 snapped(const Vector2& p_by) const;
|
Vector2 snapped(const Vector2& p_by) const;
|
||||||
float get_aspect() const { return width/height; }
|
float get_aspect() const { return width/height; }
|
||||||
|
|
||||||
|
|
||||||
operator String() const { return String::num(x)+","+String::num(y); }
|
operator String() const { return String::num(x)+","+String::num(y); }
|
||||||
|
|
||||||
_FORCE_INLINE_ Vector2(float p_x,float p_y) { x=p_x; y=p_y; }
|
_FORCE_INLINE_ Vector2(float p_x,float p_y) { x=p_x; y=p_y; }
|
||||||
_FORCE_INLINE_ Vector2() { x=0; y=0; }
|
_FORCE_INLINE_ Vector2() { x=0; y=0; }
|
||||||
};
|
};
|
||||||
|
@ -202,7 +202,7 @@ struct Matrix32;
|
||||||
|
|
||||||
|
|
||||||
struct Rect2 {
|
struct Rect2 {
|
||||||
|
|
||||||
Point2 pos;
|
Point2 pos;
|
||||||
Size2 size;
|
Size2 size;
|
||||||
|
|
||||||
|
@ -213,7 +213,7 @@ struct Rect2 {
|
||||||
|
|
||||||
float get_area() const { return size.width*size.height; }
|
float get_area() const { return size.width*size.height; }
|
||||||
|
|
||||||
inline bool intersects(const Rect2& p_rect) const {
|
inline bool intersects(const Rect2& p_rect) const {
|
||||||
if ( pos.x >= (p_rect.pos.x + p_rect.size.width) )
|
if ( pos.x >= (p_rect.pos.x + p_rect.size.width) )
|
||||||
return false;
|
return false;
|
||||||
if ( (pos.x+size.width) <= p_rect.pos.x )
|
if ( (pos.x+size.width) <= p_rect.pos.x )
|
||||||
|
@ -222,7 +222,7 @@ struct Rect2 {
|
||||||
return false;
|
return false;
|
||||||
if ( (pos.y+size.height) <= p_rect.pos.y )
|
if ( (pos.y+size.height) <= p_rect.pos.y )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -254,73 +254,73 @@ struct Rect2 {
|
||||||
bool intersects_segment(const Point2& p_from, const Point2& p_to, Point2* r_pos=NULL, Point2* r_normal=NULL) const;
|
bool intersects_segment(const Point2& p_from, const Point2& p_to, Point2* r_pos=NULL, Point2* r_normal=NULL) const;
|
||||||
|
|
||||||
inline bool encloses(const Rect2& p_rect) const {
|
inline bool encloses(const Rect2& p_rect) const {
|
||||||
|
|
||||||
return (p_rect.pos.x>=pos.x) && (p_rect.pos.y>=pos.y) &&
|
return (p_rect.pos.x>=pos.x) && (p_rect.pos.y>=pos.y) &&
|
||||||
((p_rect.pos.x+p_rect.size.x)<(pos.x+size.x)) &&
|
((p_rect.pos.x+p_rect.size.x)<(pos.x+size.x)) &&
|
||||||
((p_rect.pos.y+p_rect.size.y)<(pos.y+size.y));
|
((p_rect.pos.y+p_rect.size.y)<(pos.y+size.y));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool has_no_area() const {
|
inline bool has_no_area() const {
|
||||||
|
|
||||||
return (size.x<=0 || size.y<=0);
|
return (size.x<=0 || size.y<=0);
|
||||||
|
|
||||||
}
|
}
|
||||||
inline Rect2 clip(const Rect2& p_rect) const { /// return a clipped rect
|
inline Rect2 clip(const Rect2& p_rect) const { /// return a clipped rect
|
||||||
|
|
||||||
Rect2 new_rect=p_rect;
|
Rect2 new_rect=p_rect;
|
||||||
|
|
||||||
if (!intersects( new_rect ))
|
if (!intersects( new_rect ))
|
||||||
return Rect2();
|
return Rect2();
|
||||||
|
|
||||||
new_rect.pos.x = MAX( p_rect.pos.x , pos.x );
|
new_rect.pos.x = MAX( p_rect.pos.x , pos.x );
|
||||||
new_rect.pos.y = MAX( p_rect.pos.y , pos.y );
|
new_rect.pos.y = MAX( p_rect.pos.y , pos.y );
|
||||||
|
|
||||||
Point2 p_rect_end=p_rect.pos+p_rect.size;
|
Point2 p_rect_end=p_rect.pos+p_rect.size;
|
||||||
Point2 end=pos+size;
|
Point2 end=pos+size;
|
||||||
|
|
||||||
new_rect.size.x=MIN(p_rect_end.x,end.x) - new_rect.pos.x;
|
new_rect.size.x=MIN(p_rect_end.x,end.x) - new_rect.pos.x;
|
||||||
new_rect.size.y=MIN(p_rect_end.y,end.y) - new_rect.pos.y;
|
new_rect.size.y=MIN(p_rect_end.y,end.y) - new_rect.pos.y;
|
||||||
|
|
||||||
return new_rect;
|
return new_rect;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Rect2 merge(const Rect2& p_rect) const { ///< return a merged rect
|
inline Rect2 merge(const Rect2& p_rect) const { ///< return a merged rect
|
||||||
|
|
||||||
Rect2 new_rect;
|
Rect2 new_rect;
|
||||||
|
|
||||||
new_rect.pos.x=MIN( p_rect.pos.x , pos.x );
|
new_rect.pos.x=MIN( p_rect.pos.x , pos.x );
|
||||||
new_rect.pos.y=MIN( p_rect.pos.y , pos.y );
|
new_rect.pos.y=MIN( p_rect.pos.y , pos.y );
|
||||||
|
|
||||||
|
|
||||||
new_rect.size.x = MAX( p_rect.pos.x+p_rect.size.x , pos.x+size.x );
|
new_rect.size.x = MAX( p_rect.pos.x+p_rect.size.x , pos.x+size.x );
|
||||||
new_rect.size.y = MAX( p_rect.pos.y+p_rect.size.y , pos.y+size.y );
|
new_rect.size.y = MAX( p_rect.pos.y+p_rect.size.y , pos.y+size.y );
|
||||||
|
|
||||||
new_rect.size = new_rect.size - new_rect.pos; //make relative again
|
new_rect.size = new_rect.size - new_rect.pos; //make relative again
|
||||||
|
|
||||||
return new_rect;
|
return new_rect;
|
||||||
};
|
};
|
||||||
inline bool has_point(const Point2& p_point) const {
|
inline bool has_point(const Point2& p_point) const {
|
||||||
if (p_point.x < pos.x)
|
if (p_point.x < pos.x)
|
||||||
return false;
|
return false;
|
||||||
if (p_point.y < pos.y)
|
if (p_point.y < pos.y)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (p_point.x >= (pos.x+size.x) )
|
if (p_point.x >= (pos.x+size.x) )
|
||||||
return false;
|
return false;
|
||||||
if (p_point.y >= (pos.y+size.y) )
|
if (p_point.y >= (pos.y+size.y) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool no_area() const { return (size.width<=0 || size.height<=0 ); }
|
inline bool no_area() const { return (size.width<=0 || size.height<=0 ); }
|
||||||
|
|
||||||
bool operator==(const Rect2& p_rect) const { return pos==p_rect.pos && size==p_rect.size; }
|
bool operator==(const Rect2& p_rect) const { return pos==p_rect.pos && size==p_rect.size; }
|
||||||
bool operator!=(const Rect2& p_rect) const { return pos!=p_rect.pos || size!=p_rect.size; }
|
bool operator!=(const Rect2& p_rect) const { return pos!=p_rect.pos || size!=p_rect.size; }
|
||||||
|
|
||||||
inline Rect2 grow(real_t p_by) const {
|
inline Rect2 grow(real_t p_by) const {
|
||||||
|
|
||||||
Rect2 g=*this;
|
Rect2 g=*this;
|
||||||
g.pos.x-=p_by;
|
g.pos.x-=p_by;
|
||||||
g.pos.y-=p_by;
|
g.pos.y-=p_by;
|
||||||
|
@ -357,9 +357,9 @@ struct Rect2 {
|
||||||
|
|
||||||
|
|
||||||
operator String() const { return String(pos)+","+String(size); }
|
operator String() const { return String(pos)+","+String(size); }
|
||||||
|
|
||||||
Rect2() {}
|
Rect2() {}
|
||||||
Rect2( float p_x, float p_y, float p_width, float p_height) { pos=Point2(p_x,p_y); size=Size2( p_width, p_height ); }
|
Rect2( float p_x, float p_y, float p_width, float p_height) { pos=Point2(p_x,p_y); size=Size2( p_width, p_height ); }
|
||||||
Rect2( const Point2& p_pos, const Size2& p_size ) { pos=p_pos; size=p_size; }
|
Rect2( const Point2& p_pos, const Size2& p_size ) { pos=p_pos; size=p_size; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -135,18 +135,20 @@ double Math::rad2deg(double p_y) {
|
||||||
|
|
||||||
double Math::round(double p_val) {
|
double Math::round(double p_val) {
|
||||||
|
|
||||||
if (p_val>0) {
|
if (p_val>=0) {
|
||||||
return ::floor(p_val+0.5);
|
return ::floor(p_val+0.5);
|
||||||
} else {
|
} else {
|
||||||
p_val=-p_val;
|
p_val=-p_val;
|
||||||
return -::floor(p_val+0.5);
|
return -::floor(p_val+0.5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
double Math::asin(double p_x) {
|
double Math::asin(double p_x) {
|
||||||
|
|
||||||
return ::asin(p_x);
|
return ::asin(p_x);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
double Math::acos(double p_x) {
|
double Math::acos(double p_x) {
|
||||||
|
|
||||||
return ::acos(p_x);
|
return ::acos(p_x);
|
||||||
|
@ -185,12 +187,12 @@ double Math::fmod(double p_x,double p_y) {
|
||||||
double Math::fposmod(double p_x,double p_y) {
|
double Math::fposmod(double p_x,double p_y) {
|
||||||
|
|
||||||
if (p_x>=0) {
|
if (p_x>=0) {
|
||||||
|
|
||||||
return Math::fmod(p_x,p_y);
|
return Math::fmod(p_x,p_y);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
return p_y-Math::fmod(-p_x,p_y);
|
return p_y-Math::fmod(-p_x,p_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -205,7 +207,7 @@ double Math::ceil(double p_x) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int Math::decimals(double p_step) {
|
int Math::decimals(double p_step) {
|
||||||
|
|
||||||
int max=4;
|
int max=4;
|
||||||
double llimit = Math::pow(0.1,max);
|
double llimit = Math::pow(0.1,max);
|
||||||
double ulimit = 1.0-llimit;
|
double ulimit = 1.0-llimit;
|
||||||
|
@ -220,7 +222,7 @@ int Math::decimals(double p_step) {
|
||||||
max--;
|
max--;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return i;
|
return i;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -251,11 +253,11 @@ double Math::ease(double p_x, double p_c) {
|
||||||
}
|
}
|
||||||
|
|
||||||
double Math::stepify(double p_value,double p_step) {
|
double Math::stepify(double p_value,double p_step) {
|
||||||
|
|
||||||
if (p_step!=0) {
|
if (p_step!=0) {
|
||||||
|
|
||||||
p_value=floor( p_value / p_step + 0.5 ) * p_step;
|
p_value=floor( p_value / p_step + 0.5 ) * p_step;
|
||||||
}
|
}
|
||||||
return p_value;
|
return p_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -91,25 +91,25 @@ public:
|
||||||
|
|
||||||
static uint32_t rand();
|
static uint32_t rand();
|
||||||
static double randf();
|
static double randf();
|
||||||
|
|
||||||
static double round(double p_val);
|
static double round(double p_val);
|
||||||
|
|
||||||
static double random(double from, double to);
|
static double random(double from, double to);
|
||||||
|
|
||||||
|
|
||||||
static _FORCE_INLINE_ real_t abs(real_t g) {
|
static _FORCE_INLINE_ real_t abs(real_t g) {
|
||||||
|
|
||||||
#ifdef REAL_T_IS_DOUBLE
|
#ifdef REAL_T_IS_DOUBLE
|
||||||
|
|
||||||
return absd(g);
|
return absd(g);
|
||||||
#else
|
#else
|
||||||
|
|
||||||
return absf(g);
|
return absf(g);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static _FORCE_INLINE_ float absf(float g) {
|
static _FORCE_INLINE_ float absf(float g) {
|
||||||
|
|
||||||
union {
|
union {
|
||||||
float f;
|
float f;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
@ -174,7 +174,7 @@ public:
|
||||||
static double pow(double x, double y);
|
static double pow(double x, double y);
|
||||||
static double log(double x);
|
static double log(double x);
|
||||||
static double exp(double x);
|
static double exp(double x);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -62,11 +62,11 @@ void Matrix3::invert() {
|
||||||
real_t det = elements[0][0] * co[0]+
|
real_t det = elements[0][0] * co[0]+
|
||||||
elements[0][1] * co[1]+
|
elements[0][1] * co[1]+
|
||||||
elements[0][2] * co[2];
|
elements[0][2] * co[2];
|
||||||
|
|
||||||
ERR_FAIL_COND( det == 0 );
|
ERR_FAIL_COND( det == 0 );
|
||||||
real_t s = 1.0/det;
|
real_t s = 1.0/det;
|
||||||
|
|
||||||
set( co[0]*s, cofac(0, 2, 2, 1) * s, cofac(0, 1, 1, 2) * s,
|
set( co[0]*s, cofac(0, 2, 2, 1) * s, cofac(0, 1, 1, 2) * s,
|
||||||
co[1]*s, cofac(0, 0, 2, 2) * s, cofac(0, 2, 1, 0) * s,
|
co[1]*s, cofac(0, 0, 2, 2) * s, cofac(0, 2, 1, 0) * s,
|
||||||
co[2]*s, cofac(0, 1, 2, 0) * s, cofac(0, 0, 1, 1) * s );
|
co[2]*s, cofac(0, 1, 2, 0) * s, cofac(0, 0, 1, 1) * s );
|
||||||
|
|
||||||
|
@ -148,7 +148,7 @@ Vector3 Matrix3::get_scale() const {
|
||||||
Vector3(elements[0][1],elements[1][1],elements[2][1]).length(),
|
Vector3(elements[0][1],elements[1][1],elements[2][1]).length(),
|
||||||
Vector3(elements[0][2],elements[1][2],elements[2][2]).length()
|
Vector3(elements[0][2],elements[1][2],elements[2][2]).length()
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
void Matrix3::rotate(const Vector3& p_axis, real_t p_phi) {
|
void Matrix3::rotate(const Vector3& p_axis, real_t p_phi) {
|
||||||
|
|
||||||
|
@ -223,7 +223,7 @@ bool Matrix3::operator==(const Matrix3& p_matrix) const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool Matrix3::operator!=(const Matrix3& p_matrix) const {
|
bool Matrix3::operator!=(const Matrix3& p_matrix) const {
|
||||||
|
@ -235,16 +235,16 @@ Matrix3::operator String() const {
|
||||||
|
|
||||||
String mtx;
|
String mtx;
|
||||||
for (int i=0;i<3;i++) {
|
for (int i=0;i<3;i++) {
|
||||||
|
|
||||||
for (int j=0;j<3;j++) {
|
for (int j=0;j<3;j++) {
|
||||||
|
|
||||||
if (i!=0 || j!=0)
|
if (i!=0 || j!=0)
|
||||||
mtx+=", ";
|
mtx+=", ";
|
||||||
|
|
||||||
mtx+=rtos( elements[i][j] );
|
mtx+=rtos( elements[i][j] );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return mtx;
|
return mtx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -255,34 +255,34 @@ Matrix3::operator Quat() const {
|
||||||
|
|
||||||
real_t trace = m.elements[0][0] + m.elements[1][1] + m.elements[2][2];
|
real_t trace = m.elements[0][0] + m.elements[1][1] + m.elements[2][2];
|
||||||
real_t temp[4];
|
real_t temp[4];
|
||||||
|
|
||||||
if (trace > 0.0)
|
if (trace > 0.0)
|
||||||
{
|
{
|
||||||
real_t s = Math::sqrt(trace + 1.0);
|
real_t s = Math::sqrt(trace + 1.0);
|
||||||
temp[3]=(s * 0.5);
|
temp[3]=(s * 0.5);
|
||||||
s = 0.5 / s;
|
s = 0.5 / s;
|
||||||
|
|
||||||
temp[0]=((m.elements[2][1] - m.elements[1][2]) * s);
|
temp[0]=((m.elements[2][1] - m.elements[1][2]) * s);
|
||||||
temp[1]=((m.elements[0][2] - m.elements[2][0]) * s);
|
temp[1]=((m.elements[0][2] - m.elements[2][0]) * s);
|
||||||
temp[2]=((m.elements[1][0] - m.elements[0][1]) * s);
|
temp[2]=((m.elements[1][0] - m.elements[0][1]) * s);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int i = m.elements[0][0] < m.elements[1][1] ?
|
int i = m.elements[0][0] < m.elements[1][1] ?
|
||||||
(m.elements[1][1] < m.elements[2][2] ? 2 : 1) :
|
(m.elements[1][1] < m.elements[2][2] ? 2 : 1) :
|
||||||
(m.elements[0][0] < m.elements[2][2] ? 2 : 0);
|
(m.elements[0][0] < m.elements[2][2] ? 2 : 0);
|
||||||
int j = (i + 1) % 3;
|
int j = (i + 1) % 3;
|
||||||
int k = (i + 2) % 3;
|
int k = (i + 2) % 3;
|
||||||
|
|
||||||
real_t s = Math::sqrt(m.elements[i][i] - m.elements[j][j] - m.elements[k][k] + 1.0);
|
real_t s = Math::sqrt(m.elements[i][i] - m.elements[j][j] - m.elements[k][k] + 1.0);
|
||||||
temp[i] = s * 0.5;
|
temp[i] = s * 0.5;
|
||||||
s = 0.5 / s;
|
s = 0.5 / s;
|
||||||
|
|
||||||
temp[3] = (m.elements[k][j] - m.elements[j][k]) * s;
|
temp[3] = (m.elements[k][j] - m.elements[j][k]) * s;
|
||||||
temp[j] = (m.elements[j][i] + m.elements[i][j]) * s;
|
temp[j] = (m.elements[j][i] + m.elements[i][j]) * s;
|
||||||
temp[k] = (m.elements[k][i] + m.elements[i][k]) * s;
|
temp[k] = (m.elements[k][i] + m.elements[i][k]) * s;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Quat(temp[0],temp[1],temp[2],temp[3]);
|
return Quat(temp[0],temp[1],temp[2],temp[3]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -439,7 +439,7 @@ void Matrix3::get_axis_and_angle(Vector3 &r_axis,real_t& r_angle) const {
|
||||||
Matrix3::Matrix3(const Vector3& p_euler) {
|
Matrix3::Matrix3(const Vector3& p_euler) {
|
||||||
|
|
||||||
set_euler( p_euler );
|
set_euler( p_euler );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Matrix3::Matrix3(const Quat& p_quat) {
|
Matrix3::Matrix3(const Quat& p_quat) {
|
||||||
|
@ -450,8 +450,8 @@ Matrix3::Matrix3(const Quat& p_quat) {
|
||||||
real_t wx = p_quat.w * xs, wy = p_quat.w * ys, wz = p_quat.w * zs;
|
real_t wx = p_quat.w * xs, wy = p_quat.w * ys, wz = p_quat.w * zs;
|
||||||
real_t xx = p_quat.x * xs, xy = p_quat.x * ys, xz = p_quat.x * zs;
|
real_t xx = p_quat.x * xs, xy = p_quat.x * ys, xz = p_quat.x * zs;
|
||||||
real_t yy = p_quat.y * ys, yz = p_quat.y * zs, zz = p_quat.z * zs;
|
real_t yy = p_quat.y * ys, yz = p_quat.y * zs, zz = p_quat.z * zs;
|
||||||
set( 1.0 - (yy + zz), xy - wz, xz + wy,
|
set( 1.0 - (yy + zz), xy - wz, xz + wy,
|
||||||
xy + wz, 1.0 - (xx + zz), yz - wx,
|
xy + wz, 1.0 - (xx + zz), yz - wx,
|
||||||
xz - wy, yz + wx, 1.0 - (xx + yy)) ;
|
xz - wy, yz + wx, 1.0 - (xx + yy)) ;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,20 +39,20 @@ class Matrix3 {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Vector3 elements[3];
|
Vector3 elements[3];
|
||||||
|
|
||||||
_FORCE_INLINE_ const Vector3& operator[](int axis) const {
|
_FORCE_INLINE_ const Vector3& operator[](int axis) const {
|
||||||
|
|
||||||
return elements[axis];
|
return elements[axis];
|
||||||
}
|
}
|
||||||
_FORCE_INLINE_ Vector3& operator[](int axis) {
|
_FORCE_INLINE_ Vector3& operator[](int axis) {
|
||||||
|
|
||||||
return elements[axis];
|
return elements[axis];
|
||||||
}
|
}
|
||||||
|
|
||||||
void invert();
|
void invert();
|
||||||
void transpose();
|
void transpose();
|
||||||
|
|
||||||
Matrix3 inverse() const;
|
Matrix3 inverse() const;
|
||||||
Matrix3 transposed() const;
|
Matrix3 transposed() const;
|
||||||
|
|
||||||
_FORCE_INLINE_ float determinant() const;
|
_FORCE_INLINE_ float determinant() const;
|
||||||
|
@ -90,7 +90,7 @@ public:
|
||||||
_FORCE_INLINE_ real_t tdotz(const Vector3& v) const {
|
_FORCE_INLINE_ real_t tdotz(const Vector3& v) const {
|
||||||
return elements[0][2] * v[0] + elements[1][2] * v[1] + elements[2][2] * v[2];
|
return elements[0][2] * v[0] + elements[1][2] * v[1] + elements[2][2] * v[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const Matrix3& p_matrix) const;
|
bool operator==(const Matrix3& p_matrix) const;
|
||||||
bool operator!=(const Matrix3& p_matrix) const;
|
bool operator!=(const Matrix3& p_matrix) const;
|
||||||
|
|
||||||
|
@ -110,7 +110,7 @@ public:
|
||||||
|
|
||||||
|
|
||||||
_FORCE_INLINE_ void set(real_t xx, real_t xy, real_t xz, real_t yx, real_t yy, real_t yz, real_t zx, real_t zy, real_t zz) {
|
_FORCE_INLINE_ void set(real_t xx, real_t xy, real_t xz, real_t yx, real_t yy, real_t yz, real_t zx, real_t zy, real_t zz) {
|
||||||
|
|
||||||
elements[0][0]=xx;
|
elements[0][0]=xx;
|
||||||
elements[0][1]=xy;
|
elements[0][1]=xy;
|
||||||
elements[0][2]=xz;
|
elements[0][2]=xz;
|
||||||
|
@ -119,15 +119,15 @@ public:
|
||||||
elements[1][2]=yz;
|
elements[1][2]=yz;
|
||||||
elements[2][0]=zx;
|
elements[2][0]=zx;
|
||||||
elements[2][1]=zy;
|
elements[2][1]=zy;
|
||||||
elements[2][2]=zz;
|
elements[2][2]=zz;
|
||||||
}
|
}
|
||||||
_FORCE_INLINE_ Vector3 get_column(int i) const {
|
_FORCE_INLINE_ Vector3 get_column(int i) const {
|
||||||
|
|
||||||
return Vector3(elements[0][i],elements[1][i],elements[2][i]);
|
return Vector3(elements[0][i],elements[1][i],elements[2][i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
_FORCE_INLINE_ Vector3 get_row(int i) const {
|
_FORCE_INLINE_ Vector3 get_row(int i) const {
|
||||||
|
|
||||||
return Vector3(elements[i][0],elements[i][1],elements[i][2]);
|
return Vector3(elements[i][0],elements[i][1],elements[i][2]);
|
||||||
}
|
}
|
||||||
_FORCE_INLINE_ void set_row(int i, const Vector3& p_row) {
|
_FORCE_INLINE_ void set_row(int i, const Vector3& p_row) {
|
||||||
|
@ -155,8 +155,8 @@ public:
|
||||||
elements[0].z * m[0].y + elements[1].z * m[1].y + elements[2].z * m[2].y,
|
elements[0].z * m[0].y + elements[1].z * m[1].y + elements[2].z * m[2].y,
|
||||||
elements[0].z * m[0].z + elements[1].z * m[1].z + elements[2].z * m[2].z);
|
elements[0].z * m[0].z + elements[1].z * m[1].z + elements[2].z * m[2].z);
|
||||||
}
|
}
|
||||||
Matrix3(real_t xx, real_t xy, real_t xz, real_t yx, real_t yy, real_t yz, real_t zx, real_t zy, real_t zz) {
|
Matrix3(real_t xx, real_t xy, real_t xz, real_t yx, real_t yy, real_t yz, real_t zx, real_t zy, real_t zz) {
|
||||||
|
|
||||||
set(xx, xy, xz, yx, yy, yz, zx, zy, zz);
|
set(xx, xy, xz, yx, yy, yz, zx, zy, zz);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,7 +170,7 @@ public:
|
||||||
Matrix3(const Vector3& p_axis, real_t p_phi);
|
Matrix3(const Vector3& p_axis, real_t p_phi);
|
||||||
|
|
||||||
_FORCE_INLINE_ Matrix3() {
|
_FORCE_INLINE_ Matrix3() {
|
||||||
|
|
||||||
elements[0][0]=1;
|
elements[0][0]=1;
|
||||||
elements[0][1]=0;
|
elements[0][1]=0;
|
||||||
elements[0][2]=0;
|
elements[0][2]=0;
|
||||||
|
@ -191,7 +191,7 @@ _FORCE_INLINE_ void Matrix3::operator*=(const Matrix3& p_matrix) {
|
||||||
p_matrix.tdotx(elements[0]), p_matrix.tdoty(elements[0]), p_matrix.tdotz(elements[0]),
|
p_matrix.tdotx(elements[0]), p_matrix.tdoty(elements[0]), p_matrix.tdotz(elements[0]),
|
||||||
p_matrix.tdotx(elements[1]), p_matrix.tdoty(elements[1]), p_matrix.tdotz(elements[1]),
|
p_matrix.tdotx(elements[1]), p_matrix.tdoty(elements[1]), p_matrix.tdotz(elements[1]),
|
||||||
p_matrix.tdotx(elements[2]), p_matrix.tdoty(elements[2]), p_matrix.tdotz(elements[2]));
|
p_matrix.tdotx(elements[2]), p_matrix.tdoty(elements[2]), p_matrix.tdotz(elements[2]));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_FORCE_INLINE_ Matrix3 Matrix3::operator*(const Matrix3& p_matrix) const {
|
_FORCE_INLINE_ Matrix3 Matrix3::operator*(const Matrix3& p_matrix) const {
|
||||||
|
|
|
@ -52,11 +52,11 @@ public:
|
||||||
typedef void* (*PairCallback)(void*,OctreeElementID, T*,int,OctreeElementID, T*,int);
|
typedef void* (*PairCallback)(void*,OctreeElementID, T*,int,OctreeElementID, T*,int);
|
||||||
typedef void (*UnpairCallback)(void*,OctreeElementID, T*,int,OctreeElementID, T*,int,void*);
|
typedef void (*UnpairCallback)(void*,OctreeElementID, T*,int,OctreeElementID, T*,int,void*);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum {
|
enum {
|
||||||
|
|
||||||
NEG=0,
|
NEG=0,
|
||||||
POS=1,
|
POS=1,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
@ -72,7 +72,7 @@ private:
|
||||||
|
|
||||||
|
|
||||||
struct PairKey {
|
struct PairKey {
|
||||||
|
|
||||||
union {
|
union {
|
||||||
struct {
|
struct {
|
||||||
OctreeElementID A;
|
OctreeElementID A;
|
||||||
|
@ -80,66 +80,66 @@ private:
|
||||||
};
|
};
|
||||||
uint64_t key;
|
uint64_t key;
|
||||||
};
|
};
|
||||||
|
|
||||||
_FORCE_INLINE_ bool operator<(const PairKey& p_pair) const {
|
_FORCE_INLINE_ bool operator<(const PairKey& p_pair) const {
|
||||||
|
|
||||||
return key<p_pair.key;
|
return key<p_pair.key;
|
||||||
}
|
}
|
||||||
|
|
||||||
_FORCE_INLINE_ PairKey( OctreeElementID p_A, OctreeElementID p_B) {
|
_FORCE_INLINE_ PairKey( OctreeElementID p_A, OctreeElementID p_B) {
|
||||||
|
|
||||||
if (p_A<p_B) {
|
if (p_A<p_B) {
|
||||||
|
|
||||||
A=p_A;
|
A=p_A;
|
||||||
B=p_B;
|
B=p_B;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
B=p_A;
|
B=p_A;
|
||||||
A=p_B;
|
A=p_B;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_FORCE_INLINE_ PairKey() {}
|
_FORCE_INLINE_ PairKey() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Element;
|
struct Element;
|
||||||
|
|
||||||
struct Octant {
|
struct Octant {
|
||||||
|
|
||||||
// cached for FAST plane check
|
// cached for FAST plane check
|
||||||
AABB aabb;
|
AABB aabb;
|
||||||
|
|
||||||
uint64_t last_pass;
|
uint64_t last_pass;
|
||||||
Octant *parent;
|
Octant *parent;
|
||||||
Octant *children[8];
|
Octant *children[8];
|
||||||
|
|
||||||
int children_count; // cache for amount of childrens (fast check for removal)
|
int children_count; // cache for amount of childrens (fast check for removal)
|
||||||
int parent_index; // cache for parent index (fast check for removal)
|
int parent_index; // cache for parent index (fast check for removal)
|
||||||
|
|
||||||
List<Element*,AL> pairable_elements;
|
List<Element*,AL> pairable_elements;
|
||||||
List<Element*,AL> elements;
|
List<Element*,AL> elements;
|
||||||
|
|
||||||
Octant() {
|
Octant() {
|
||||||
children_count=0;
|
children_count=0;
|
||||||
parent_index=-1;
|
parent_index=-1;
|
||||||
last_pass=0;
|
last_pass=0;
|
||||||
parent=NULL;
|
parent=NULL;
|
||||||
for (int i=0;i<8;i++)
|
for (int i=0;i<8;i++)
|
||||||
children[i]=NULL;
|
children[i]=NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
~Octant() {
|
~Octant() {
|
||||||
|
|
||||||
//for (int i=0;i<8;i++)
|
//for (int i=0;i<8;i++)
|
||||||
// memdelete_notnull(children[i]);
|
// memdelete_notnull(children[i]);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct PairData;
|
struct PairData;
|
||||||
|
|
||||||
struct Element {
|
struct Element {
|
||||||
|
|
||||||
Octree *octree;
|
Octree *octree;
|
||||||
|
|
||||||
T *userdata;
|
T *userdata;
|
||||||
|
@ -147,28 +147,28 @@ private:
|
||||||
bool pairable;
|
bool pairable;
|
||||||
uint32_t pairable_mask;
|
uint32_t pairable_mask;
|
||||||
uint32_t pairable_type;
|
uint32_t pairable_type;
|
||||||
|
|
||||||
uint64_t last_pass;
|
uint64_t last_pass;
|
||||||
OctreeElementID _id;
|
OctreeElementID _id;
|
||||||
Octant *common_parent;
|
Octant *common_parent;
|
||||||
|
|
||||||
AABB aabb;
|
AABB aabb;
|
||||||
AABB container_aabb;
|
AABB container_aabb;
|
||||||
|
|
||||||
List<PairData*,AL> pair_list;
|
List<PairData*,AL> pair_list;
|
||||||
|
|
||||||
struct OctantOwner {
|
struct OctantOwner {
|
||||||
|
|
||||||
Octant *octant;
|
Octant *octant;
|
||||||
typename List<Element*,AL>::Element *E;
|
typename List<Element*,AL>::Element *E;
|
||||||
}; // an element can be in max 8 octants
|
}; // an element can be in max 8 octants
|
||||||
|
|
||||||
List<OctantOwner,AL> octant_owners;
|
List<OctantOwner,AL> octant_owners;
|
||||||
|
|
||||||
|
|
||||||
Element() { last_pass=0; _id=0; pairable=false; subindex=0; userdata=0; octree=0; pairable_mask=0; pairable_type=0; common_parent=NULL; }
|
Element() { last_pass=0; _id=0; pairable=false; subindex=0; userdata=0; octree=0; pairable_mask=0; pairable_type=0; common_parent=NULL; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct PairData {
|
struct PairData {
|
||||||
|
|
||||||
|
@ -181,15 +181,15 @@ private:
|
||||||
|
|
||||||
typedef Map<OctreeElementID, Element, Comparator<OctreeElementID>, AL> ElementMap;
|
typedef Map<OctreeElementID, Element, Comparator<OctreeElementID>, AL> ElementMap;
|
||||||
typedef Map<PairKey, PairData, Comparator<PairKey>, AL> PairMap;
|
typedef Map<PairKey, PairData, Comparator<PairKey>, AL> PairMap;
|
||||||
ElementMap element_map;
|
ElementMap element_map;
|
||||||
PairMap pair_map;
|
PairMap pair_map;
|
||||||
|
|
||||||
PairCallback pair_callback;
|
PairCallback pair_callback;
|
||||||
UnpairCallback unpair_callback;
|
UnpairCallback unpair_callback;
|
||||||
void *pair_callback_userdata;
|
void *pair_callback_userdata;
|
||||||
void *unpair_callback_userdata;
|
void *unpair_callback_userdata;
|
||||||
|
|
||||||
OctreeElementID last_element_id;
|
OctreeElementID last_element_id;
|
||||||
uint64_t pass;
|
uint64_t pass;
|
||||||
|
|
||||||
real_t unit_size;
|
real_t unit_size;
|
||||||
|
@ -231,7 +231,7 @@ private:
|
||||||
|
|
||||||
if (p_A==p_B || (p_A->userdata==p_B->userdata && p_A->userdata))
|
if (p_A==p_B || (p_A->userdata==p_B->userdata && p_A->userdata))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ( !(p_A->pairable_type&p_B->pairable_mask) &&
|
if ( !(p_A->pairable_type&p_B->pairable_mask) &&
|
||||||
!(p_B->pairable_type&p_A->pairable_mask) )
|
!(p_B->pairable_type&p_A->pairable_mask) )
|
||||||
return; // none can pair with none
|
return; // none can pair with none
|
||||||
|
@ -253,17 +253,17 @@ private:
|
||||||
// if (pair_callback)
|
// if (pair_callback)
|
||||||
// pair_callback(pair_callback_userdata,p_A->userdata,p_B->userdata);
|
// pair_callback(pair_callback_userdata,p_A->userdata,p_B->userdata);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
E->get().refcount++;
|
E->get().refcount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_FORCE_INLINE_ void _pair_unreference(Element* p_A,Element* p_B) {
|
_FORCE_INLINE_ void _pair_unreference(Element* p_A,Element* p_B) {
|
||||||
|
|
||||||
if (p_A==p_B)
|
if (p_A==p_B)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
PairKey key(p_A->_id, p_B->_id);
|
PairKey key(p_A->_id, p_B->_id);
|
||||||
typename PairMap::Element *E=pair_map.find(key);
|
typename PairMap::Element *E=pair_map.find(key);
|
||||||
if (!E) {
|
if (!E) {
|
||||||
|
@ -293,7 +293,7 @@ private:
|
||||||
p_B->pair_list.erase( E->get().eB );
|
p_B->pair_list.erase( E->get().eB );
|
||||||
pair_map.erase(E);
|
pair_map.erase(E);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_FORCE_INLINE_ void _element_check_pairs(Element *p_element) {
|
_FORCE_INLINE_ void _element_check_pairs(Element *p_element) {
|
||||||
|
@ -341,7 +341,7 @@ private:
|
||||||
void _ensure_valid_root(const AABB& p_aabb);
|
void _ensure_valid_root(const AABB& p_aabb);
|
||||||
bool _remove_element_from_octant(Element *p_element,Octant *p_octant,Octant *p_limit=NULL);
|
bool _remove_element_from_octant(Element *p_element,Octant *p_octant,Octant *p_limit=NULL);
|
||||||
void _remove_element(Element *p_element);
|
void _remove_element(Element *p_element);
|
||||||
void _pair_element(Element *p_element,Octant *p_octant);
|
void _pair_element(Element *p_element,Octant *p_octant);
|
||||||
void _unpair_element(Element *p_element,Octant *p_octant);
|
void _unpair_element(Element *p_element,Octant *p_octant);
|
||||||
|
|
||||||
|
|
||||||
|
@ -361,16 +361,16 @@ private:
|
||||||
void _cull_point(Octant *p_octant,const Vector3& p_point,T** p_result_array,int *p_result_idx,int p_result_max,int *p_subindex_array,uint32_t p_mask);
|
void _cull_point(Octant *p_octant,const Vector3& p_point,T** p_result_array,int *p_result_idx,int p_result_max,int *p_subindex_array,uint32_t p_mask);
|
||||||
|
|
||||||
void _remove_tree(Octant *p_octant) {
|
void _remove_tree(Octant *p_octant) {
|
||||||
|
|
||||||
if (!p_octant)
|
if (!p_octant)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for(int i=0;i<8;i++) {
|
for(int i=0;i<8;i++) {
|
||||||
|
|
||||||
if (p_octant->children[i])
|
if (p_octant->children[i])
|
||||||
_remove_tree(p_octant->children[i]);
|
_remove_tree(p_octant->children[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
memdelete_allocator<Octant,AL>(p_octant);
|
memdelete_allocator<Octant,AL>(p_octant);
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
|
@ -432,24 +432,24 @@ template<class T,bool use_pairs,class AL>
|
||||||
void Octree<T,use_pairs,AL>::_insert_element(Element *p_element,Octant *p_octant) {
|
void Octree<T,use_pairs,AL>::_insert_element(Element *p_element,Octant *p_octant) {
|
||||||
|
|
||||||
float element_size = p_element->aabb.get_longest_axis_size() * 1.01; // avoid precision issues
|
float element_size = p_element->aabb.get_longest_axis_size() * 1.01; // avoid precision issues
|
||||||
|
|
||||||
if (p_octant->aabb.size.x/OCTREE_DIVISOR < element_size) {
|
if (p_octant->aabb.size.x/OCTREE_DIVISOR < element_size) {
|
||||||
//if (p_octant->aabb.size.x*0.5 < element_size) {
|
//if (p_octant->aabb.size.x*0.5 < element_size) {
|
||||||
|
|
||||||
/* at smallest possible size for the element */
|
/* at smallest possible size for the element */
|
||||||
typename Element::OctantOwner owner;
|
typename Element::OctantOwner owner;
|
||||||
owner.octant=p_octant;
|
owner.octant=p_octant;
|
||||||
|
|
||||||
if (use_pairs && p_element->pairable) {
|
if (use_pairs && p_element->pairable) {
|
||||||
|
|
||||||
p_octant->pairable_elements.push_back(p_element);
|
p_octant->pairable_elements.push_back(p_element);
|
||||||
owner.E = p_octant->pairable_elements.back();
|
owner.E = p_octant->pairable_elements.back();
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
p_octant->elements.push_back(p_element);
|
p_octant->elements.push_back(p_element);
|
||||||
owner.E = p_octant->elements.back();
|
owner.E = p_octant->elements.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
p_element->octant_owners.push_back( owner );
|
p_element->octant_owners.push_back( owner );
|
||||||
|
|
||||||
if (p_element->common_parent==NULL) {
|
if (p_element->common_parent==NULL) {
|
||||||
|
@ -461,13 +461,13 @@ void Octree<T,use_pairs,AL>::_insert_element(Element *p_element,Octant *p_octant
|
||||||
|
|
||||||
|
|
||||||
if (use_pairs && p_octant->children_count>0) {
|
if (use_pairs && p_octant->children_count>0) {
|
||||||
|
|
||||||
pass++; //elements below this only get ONE reference added
|
pass++; //elements below this only get ONE reference added
|
||||||
|
|
||||||
for (int i=0;i<8;i++) {
|
for (int i=0;i<8;i++) {
|
||||||
|
|
||||||
if (p_octant->children[i]) {
|
if (p_octant->children[i]) {
|
||||||
_pair_element(p_element,p_octant->children[i]);
|
_pair_element(p_element,p_octant->children[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -477,7 +477,7 @@ void Octree<T,use_pairs,AL>::_insert_element(Element *p_element,Octant *p_octant
|
||||||
bool candidate=p_element->common_parent==NULL;
|
bool candidate=p_element->common_parent==NULL;
|
||||||
|
|
||||||
for (int i=0;i<8;i++) {
|
for (int i=0;i<8;i++) {
|
||||||
|
|
||||||
if (p_octant->children[i]) {
|
if (p_octant->children[i]) {
|
||||||
/* element exists, go straight to it */
|
/* element exists, go straight to it */
|
||||||
if (p_octant->children[i]->aabb.intersects_inclusive( p_element->aabb ) ) {
|
if (p_octant->children[i]->aabb.intersects_inclusive( p_element->aabb ) ) {
|
||||||
|
@ -486,20 +486,20 @@ void Octree<T,use_pairs,AL>::_insert_element(Element *p_element,Octant *p_octant
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* check againt AABB where child should be */
|
/* check againt AABB where child should be */
|
||||||
|
|
||||||
AABB aabb=p_octant->aabb;
|
AABB aabb=p_octant->aabb;
|
||||||
aabb.size*=0.5;
|
aabb.size*=0.5;
|
||||||
|
|
||||||
if (i&1)
|
if (i&1)
|
||||||
aabb.pos.x+=aabb.size.x;
|
aabb.pos.x+=aabb.size.x;
|
||||||
if (i&2)
|
if (i&2)
|
||||||
aabb.pos.y+=aabb.size.y;
|
aabb.pos.y+=aabb.size.y;
|
||||||
if (i&4)
|
if (i&4)
|
||||||
aabb.pos.z+=aabb.size.z;
|
aabb.pos.z+=aabb.size.z;
|
||||||
|
|
||||||
if (aabb.intersects_inclusive( p_element->aabb) ) {
|
if (aabb.intersects_inclusive( p_element->aabb) ) {
|
||||||
/* if actually intersects, create the child */
|
/* if actually intersects, create the child */
|
||||||
|
|
||||||
Octant *child = memnew_allocator( Octant, AL );
|
Octant *child = memnew_allocator( Octant, AL );
|
||||||
p_octant->children[i]=child;
|
p_octant->children[i]=child;
|
||||||
child->parent=p_octant;
|
child->parent=p_octant;
|
||||||
|
@ -517,14 +517,14 @@ void Octree<T,use_pairs,AL>::_insert_element(Element *p_element,Octant *p_octant
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (candidate && splits>1) {
|
if (candidate && splits>1) {
|
||||||
|
|
||||||
p_element->common_parent=p_octant;
|
p_element->common_parent=p_octant;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (use_pairs) {
|
if (use_pairs) {
|
||||||
|
|
||||||
typename List<Element*,AL>::Element *E=p_octant->pairable_elements.front();
|
typename List<Element*,AL>::Element *E=p_octant->pairable_elements.front();
|
||||||
|
@ -532,8 +532,8 @@ void Octree<T,use_pairs,AL>::_insert_element(Element *p_element,Octant *p_octant
|
||||||
while(E) {
|
while(E) {
|
||||||
_pair_reference( p_element,E->get() );
|
_pair_reference( p_element,E->get() );
|
||||||
E=E->next();
|
E=E->next();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p_element->pairable) {
|
if (p_element->pairable) {
|
||||||
// and always test non-pairable if element is pairable
|
// and always test non-pairable if element is pairable
|
||||||
E=p_octant->elements.front();
|
E=p_octant->elements.front();
|
||||||
|
@ -541,9 +541,9 @@ void Octree<T,use_pairs,AL>::_insert_element(Element *p_element,Octant *p_octant
|
||||||
_pair_reference( p_element,E->get() );
|
_pair_reference( p_element,E->get() );
|
||||||
E=E->next();
|
E=E->next();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -553,35 +553,35 @@ void Octree<T,use_pairs,AL>::_ensure_valid_root(const AABB& p_aabb) {
|
||||||
|
|
||||||
if (!root) {
|
if (!root) {
|
||||||
// octre is empty
|
// octre is empty
|
||||||
|
|
||||||
AABB base( Vector3(), Vector3(1.0,1.0,1.0) * unit_size);
|
AABB base( Vector3(), Vector3(1.0,1.0,1.0) * unit_size);
|
||||||
|
|
||||||
while ( !base.encloses(p_aabb) ) {
|
while ( !base.encloses(p_aabb) ) {
|
||||||
|
|
||||||
if ( ABS(base.pos.x+base.size.x) <= ABS(base.pos.x) ) {
|
if ( ABS(base.pos.x+base.size.x) <= ABS(base.pos.x) ) {
|
||||||
/* grow towards positive */
|
/* grow towards positive */
|
||||||
base.size*=2.0;
|
base.size*=2.0;
|
||||||
} else {
|
} else {
|
||||||
base.pos-=base.size;
|
base.pos-=base.size;
|
||||||
base.size*=2.0;
|
base.size*=2.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
root = memnew_allocator( Octant, AL );
|
root = memnew_allocator( Octant, AL );
|
||||||
|
|
||||||
root->parent=NULL;
|
root->parent=NULL;
|
||||||
root->parent_index=-1;
|
root->parent_index=-1;
|
||||||
root->aabb=base;
|
root->aabb=base;
|
||||||
|
|
||||||
octant_count++;
|
octant_count++;
|
||||||
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
AABB base=root->aabb;
|
AABB base=root->aabb;
|
||||||
|
|
||||||
while( !base.encloses( p_aabb ) ) {
|
while( !base.encloses( p_aabb ) ) {
|
||||||
|
|
||||||
if (base.size.x > OCTREE_SIZE_LIMIT) {
|
if (base.size.x > OCTREE_SIZE_LIMIT) {
|
||||||
ERR_EXPLAIN("Octree upper size limit reeached, does the AABB supplied contain NAN?");
|
ERR_EXPLAIN("Octree upper size limit reeached, does the AABB supplied contain NAN?");
|
||||||
ERR_FAIL();
|
ERR_FAIL();
|
||||||
|
@ -590,7 +590,7 @@ void Octree<T,use_pairs,AL>::_ensure_valid_root(const AABB& p_aabb) {
|
||||||
Octant * gp = memnew_allocator( Octant, AL );
|
Octant * gp = memnew_allocator( Octant, AL );
|
||||||
octant_count++;
|
octant_count++;
|
||||||
root->parent=gp;
|
root->parent=gp;
|
||||||
|
|
||||||
if ( ABS(base.pos.x+base.size.x) <= ABS(base.pos.x) ) {
|
if ( ABS(base.pos.x+base.size.x) <= ABS(base.pos.x) ) {
|
||||||
/* grow towards positive */
|
/* grow towards positive */
|
||||||
base.size*=2.0;
|
base.size*=2.0;
|
||||||
|
@ -598,16 +598,16 @@ void Octree<T,use_pairs,AL>::_ensure_valid_root(const AABB& p_aabb) {
|
||||||
gp->children[0]=root;
|
gp->children[0]=root;
|
||||||
root->parent_index=0;
|
root->parent_index=0;
|
||||||
} else {
|
} else {
|
||||||
base.pos-=base.size;
|
base.pos-=base.size;
|
||||||
base.size*=2.0;
|
base.size*=2.0;
|
||||||
gp->aabb=base;
|
gp->aabb=base;
|
||||||
gp->children[(1<<0)|(1<<1)|(1<<2)]=root; // add at all-positive
|
gp->children[(1<<0)|(1<<1)|(1<<2)]=root; // add at all-positive
|
||||||
root->parent_index=(1<<0)|(1<<1)|(1<<2);
|
root->parent_index=(1<<0)|(1<<1)|(1<<2);
|
||||||
}
|
}
|
||||||
|
|
||||||
gp->children_count=1;
|
gp->children_count=1;
|
||||||
root=gp;
|
root=gp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -615,16 +615,16 @@ template<class T,bool use_pairs,class AL>
|
||||||
bool Octree<T,use_pairs,AL>::_remove_element_from_octant(Element *p_element,Octant *p_octant,Octant *p_limit) {
|
bool Octree<T,use_pairs,AL>::_remove_element_from_octant(Element *p_element,Octant *p_octant,Octant *p_limit) {
|
||||||
|
|
||||||
bool octant_removed=false;
|
bool octant_removed=false;
|
||||||
|
|
||||||
while(true) {
|
while(true) {
|
||||||
|
|
||||||
// check all exit conditions
|
// check all exit conditions
|
||||||
|
|
||||||
if (p_octant==p_limit) // reached limit, nothing to erase, exit
|
if (p_octant==p_limit) // reached limit, nothing to erase, exit
|
||||||
return octant_removed;
|
return octant_removed;
|
||||||
|
|
||||||
bool unpaired=false;
|
bool unpaired=false;
|
||||||
|
|
||||||
if (use_pairs && p_octant->last_pass!=pass) {
|
if (use_pairs && p_octant->last_pass!=pass) {
|
||||||
// check wether we should unpair stuff
|
// check wether we should unpair stuff
|
||||||
// always test pairable
|
// always test pairable
|
||||||
|
@ -644,21 +644,21 @@ bool Octree<T,use_pairs,AL>::_remove_element_from_octant(Element *p_element,Octa
|
||||||
p_octant->last_pass=pass;
|
p_octant->last_pass=pass;
|
||||||
unpaired=true;
|
unpaired=true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool removed=false;
|
bool removed=false;
|
||||||
|
|
||||||
Octant *parent=p_octant->parent;
|
Octant *parent=p_octant->parent;
|
||||||
|
|
||||||
if (p_octant->children_count==0 && p_octant->elements.empty() && p_octant->pairable_elements.empty()) {
|
if (p_octant->children_count==0 && p_octant->elements.empty() && p_octant->pairable_elements.empty()) {
|
||||||
|
|
||||||
// erase octant
|
// erase octant
|
||||||
|
|
||||||
if (p_octant==root) { // won't have a parent, just erase
|
if (p_octant==root) { // won't have a parent, just erase
|
||||||
|
|
||||||
root=NULL;
|
root=NULL;
|
||||||
} else {
|
} else {
|
||||||
ERR_FAIL_INDEX_V(p_octant->parent_index,8,octant_removed);
|
ERR_FAIL_INDEX_V(p_octant->parent_index,8,octant_removed);
|
||||||
|
|
||||||
parent->children[ p_octant->parent_index ]=NULL;
|
parent->children[ p_octant->parent_index ]=NULL;
|
||||||
parent->children_count--;
|
parent->children_count--;
|
||||||
}
|
}
|
||||||
|
@ -668,12 +668,12 @@ bool Octree<T,use_pairs,AL>::_remove_element_from_octant(Element *p_element,Octa
|
||||||
removed=true;
|
removed=true;
|
||||||
octant_removed=true;
|
octant_removed=true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!removed && !unpaired)
|
if (!removed && !unpaired)
|
||||||
return octant_removed; // no reason to keep going up anymore! was already visited and was not removed
|
return octant_removed; // no reason to keep going up anymore! was already visited and was not removed
|
||||||
|
|
||||||
p_octant=parent;
|
p_octant=parent;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return octant_removed;
|
return octant_removed;
|
||||||
|
@ -682,8 +682,8 @@ bool Octree<T,use_pairs,AL>::_remove_element_from_octant(Element *p_element,Octa
|
||||||
template<class T,bool use_pairs,class AL>
|
template<class T,bool use_pairs,class AL>
|
||||||
void Octree<T,use_pairs,AL>::_unpair_element(Element *p_element,Octant *p_octant) {
|
void Octree<T,use_pairs,AL>::_unpair_element(Element *p_element,Octant *p_octant) {
|
||||||
|
|
||||||
|
|
||||||
// always test pairable
|
// always test pairable
|
||||||
typename List<Element*,AL>::Element *E=p_octant->pairable_elements.front();
|
typename List<Element*,AL>::Element *E=p_octant->pairable_elements.front();
|
||||||
while(E) {
|
while(E) {
|
||||||
if (E->get()->last_pass!=pass) { // only remove ONE reference
|
if (E->get()->last_pass!=pass) { // only remove ONE reference
|
||||||
|
@ -692,7 +692,7 @@ void Octree<T,use_pairs,AL>::_unpair_element(Element *p_element,Octant *p_octant
|
||||||
}
|
}
|
||||||
E=E->next();
|
E=E->next();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p_element->pairable) {
|
if (p_element->pairable) {
|
||||||
// and always test non-pairable if element is pairable
|
// and always test non-pairable if element is pairable
|
||||||
E=p_octant->elements.front();
|
E=p_octant->elements.front();
|
||||||
|
@ -704,14 +704,14 @@ void Octree<T,use_pairs,AL>::_unpair_element(Element *p_element,Octant *p_octant
|
||||||
E=E->next();
|
E=E->next();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
p_octant->last_pass=pass;
|
p_octant->last_pass=pass;
|
||||||
|
|
||||||
if (p_octant->children_count==0)
|
if (p_octant->children_count==0)
|
||||||
return; // small optimization for leafs
|
return; // small optimization for leafs
|
||||||
|
|
||||||
for (int i=0;i<8;i++) {
|
for (int i=0;i<8;i++) {
|
||||||
|
|
||||||
if (p_octant->children[i])
|
if (p_octant->children[i])
|
||||||
_unpair_element(p_element,p_octant->children[i]);
|
_unpair_element(p_element,p_octant->children[i]);
|
||||||
}
|
}
|
||||||
|
@ -732,7 +732,7 @@ void Octree<T,use_pairs,AL>::_pair_element(Element *p_element,Octant *p_octant)
|
||||||
}
|
}
|
||||||
E=E->next();
|
E=E->next();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p_element->pairable) {
|
if (p_element->pairable) {
|
||||||
// and always test non-pairable if element is pairable
|
// and always test non-pairable if element is pairable
|
||||||
E=p_octant->elements.front();
|
E=p_octant->elements.front();
|
||||||
|
@ -745,12 +745,12 @@ void Octree<T,use_pairs,AL>::_pair_element(Element *p_element,Octant *p_octant)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
p_octant->last_pass=pass;
|
p_octant->last_pass=pass;
|
||||||
|
|
||||||
if (p_octant->children_count==0)
|
if (p_octant->children_count==0)
|
||||||
return; // small optimization for leafs
|
return; // small optimization for leafs
|
||||||
|
|
||||||
for (int i=0;i<8;i++) {
|
for (int i=0;i<8;i++) {
|
||||||
|
|
||||||
if (p_octant->children[i])
|
if (p_octant->children[i])
|
||||||
_pair_element(p_element,p_octant->children[i]);
|
_pair_element(p_element,p_octant->children[i]);
|
||||||
}
|
}
|
||||||
|
@ -760,13 +760,13 @@ template<class T,bool use_pairs,class AL>
|
||||||
void Octree<T,use_pairs,AL>::_remove_element(Element *p_element) {
|
void Octree<T,use_pairs,AL>::_remove_element(Element *p_element) {
|
||||||
|
|
||||||
pass++; // will do a new pass for this
|
pass++; // will do a new pass for this
|
||||||
|
|
||||||
typename List< typename Element::OctantOwner,AL >::Element *I=p_element->octant_owners.front();
|
typename List< typename Element::OctantOwner,AL >::Element *I=p_element->octant_owners.front();
|
||||||
|
|
||||||
|
|
||||||
/* FIRST remove going up normally */
|
/* FIRST remove going up normally */
|
||||||
for(;I;I=I->next()) {
|
for(;I;I=I->next()) {
|
||||||
|
|
||||||
Octant *o=I->get().octant;
|
Octant *o=I->get().octant;
|
||||||
|
|
||||||
if (!use_pairs) // small speedup
|
if (!use_pairs) // small speedup
|
||||||
|
@ -809,14 +809,14 @@ void Octree<T,use_pairs,AL>::_remove_element(Element *p_element) {
|
||||||
int remaining=p_element->pair_list.size();
|
int remaining=p_element->pair_list.size();
|
||||||
//p_element->pair_list.clear();
|
//p_element->pair_list.clear();
|
||||||
ERR_FAIL_COND( remaining );
|
ERR_FAIL_COND( remaining );
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T,bool use_pairs,class AL>
|
template<class T,bool use_pairs,class AL>
|
||||||
OctreeElementID Octree<T,use_pairs,AL>::create(T* p_userdata, const AABB& p_aabb, int p_subindex,bool p_pairable,uint32_t p_pairable_type,uint32_t p_pairable_mask) {
|
OctreeElementID Octree<T,use_pairs,AL>::create(T* p_userdata, const AABB& p_aabb, int p_subindex,bool p_pairable,uint32_t p_pairable_type,uint32_t p_pairable_mask) {
|
||||||
|
|
||||||
// check for AABB validity
|
// check for AABB validity
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
ERR_FAIL_COND_V( p_aabb.pos.x > 1e15 || p_aabb.pos.x < -1e15, 0 );
|
ERR_FAIL_COND_V( p_aabb.pos.x > 1e15 || p_aabb.pos.x < -1e15, 0 );
|
||||||
ERR_FAIL_COND_V( p_aabb.pos.y > 1e15 || p_aabb.pos.y < -1e15, 0 );
|
ERR_FAIL_COND_V( p_aabb.pos.y > 1e15 || p_aabb.pos.y < -1e15, 0 );
|
||||||
|
@ -828,12 +828,12 @@ OctreeElementID Octree<T,use_pairs,AL>::create(T* p_userdata, const AABB& p_aabb
|
||||||
ERR_FAIL_COND_V( Math::is_nan(p_aabb.size.y) , 0 );
|
ERR_FAIL_COND_V( Math::is_nan(p_aabb.size.y) , 0 );
|
||||||
ERR_FAIL_COND_V( Math::is_nan(p_aabb.size.z) , 0 );
|
ERR_FAIL_COND_V( Math::is_nan(p_aabb.size.z) , 0 );
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
typename ElementMap::Element *E = element_map.insert(last_element_id++,
|
typename ElementMap::Element *E = element_map.insert(last_element_id++,
|
||||||
Element());
|
Element());
|
||||||
Element &e = E->get();
|
Element &e = E->get();
|
||||||
|
|
||||||
e.aabb=p_aabb;
|
e.aabb=p_aabb;
|
||||||
e.userdata=p_userdata;
|
e.userdata=p_userdata;
|
||||||
e.subindex=p_subindex;
|
e.subindex=p_subindex;
|
||||||
|
@ -843,7 +843,7 @@ OctreeElementID Octree<T,use_pairs,AL>::create(T* p_userdata, const AABB& p_aabb
|
||||||
e.pairable_type=p_pairable_type;
|
e.pairable_type=p_pairable_type;
|
||||||
e.pairable_mask=p_pairable_mask;
|
e.pairable_mask=p_pairable_mask;
|
||||||
e._id=last_element_id-1;
|
e._id=last_element_id-1;
|
||||||
|
|
||||||
if (!e.aabb.has_no_surface()) {
|
if (!e.aabb.has_no_surface()) {
|
||||||
_ensure_valid_root(p_aabb);
|
_ensure_valid_root(p_aabb);
|
||||||
_insert_element(&e,root);
|
_insert_element(&e,root);
|
||||||
|
@ -964,7 +964,7 @@ void Octree<T,use_pairs,AL>::move(OctreeElementID p_id, const AABB& p_aabb) {
|
||||||
_insert_element(&e,common_parent); // reinsert from this point
|
_insert_element(&e,common_parent); // reinsert from this point
|
||||||
|
|
||||||
pass++;
|
pass++;
|
||||||
|
|
||||||
for(typename List<typename Element::OctantOwner,AL>::Element *E=owners.front();E;) {
|
for(typename List<typename Element::OctantOwner,AL>::Element *E=owners.front();E;) {
|
||||||
|
|
||||||
Octant *o=E->get().octant;
|
Octant *o=E->get().octant;
|
||||||
|
@ -1018,28 +1018,28 @@ void Octree<T,use_pairs,AL>::set_pairable(OctreeElementID p_id,bool p_pairable,u
|
||||||
|
|
||||||
typename ElementMap::Element *E = element_map.find(p_id);
|
typename ElementMap::Element *E = element_map.find(p_id);
|
||||||
ERR_FAIL_COND(!E);
|
ERR_FAIL_COND(!E);
|
||||||
|
|
||||||
Element &e = E->get();
|
Element &e = E->get();
|
||||||
|
|
||||||
if (p_pairable == e.pairable && e.pairable_type==p_pairable_type && e.pairable_mask==p_pairable_mask)
|
if (p_pairable == e.pairable && e.pairable_type==p_pairable_type && e.pairable_mask==p_pairable_mask)
|
||||||
return; // no changes, return
|
return; // no changes, return
|
||||||
|
|
||||||
if (!e.aabb.has_no_surface()) {
|
if (!e.aabb.has_no_surface()) {
|
||||||
_remove_element(&e);
|
_remove_element(&e);
|
||||||
}
|
}
|
||||||
|
|
||||||
e.pairable=p_pairable;
|
e.pairable=p_pairable;
|
||||||
e.pairable_type=p_pairable_type;
|
e.pairable_type=p_pairable_type;
|
||||||
e.pairable_mask=p_pairable_mask;
|
e.pairable_mask=p_pairable_mask;
|
||||||
e.common_parent=NULL;
|
e.common_parent=NULL;
|
||||||
|
|
||||||
if (!e.aabb.has_no_surface()) {
|
if (!e.aabb.has_no_surface()) {
|
||||||
_ensure_valid_root(e.aabb);
|
_ensure_valid_root(e.aabb);
|
||||||
_insert_element(&e,root);
|
_insert_element(&e,root);
|
||||||
if (use_pairs)
|
if (use_pairs)
|
||||||
_element_check_pairs(&e);
|
_element_check_pairs(&e);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1048,155 +1048,155 @@ void Octree<T,use_pairs,AL>::erase(OctreeElementID p_id) {
|
||||||
|
|
||||||
typename ElementMap::Element *E = element_map.find(p_id);
|
typename ElementMap::Element *E = element_map.find(p_id);
|
||||||
ERR_FAIL_COND(!E);
|
ERR_FAIL_COND(!E);
|
||||||
|
|
||||||
Element &e = E->get();
|
Element &e = E->get();
|
||||||
|
|
||||||
if (!e.aabb.has_no_surface()) {
|
if (!e.aabb.has_no_surface()) {
|
||||||
|
|
||||||
_remove_element(&e);
|
_remove_element(&e);
|
||||||
}
|
}
|
||||||
|
|
||||||
element_map.erase(p_id);
|
element_map.erase(p_id);
|
||||||
_optimize();
|
_optimize();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T,bool use_pairs,class AL>
|
template<class T,bool use_pairs,class AL>
|
||||||
void Octree<T,use_pairs,AL>::_cull_convex(Octant *p_octant,_CullConvexData *p_cull) {
|
void Octree<T,use_pairs,AL>::_cull_convex(Octant *p_octant,_CullConvexData *p_cull) {
|
||||||
|
|
||||||
if (*p_cull->result_idx==p_cull->result_max)
|
if (*p_cull->result_idx==p_cull->result_max)
|
||||||
return; //pointless
|
return; //pointless
|
||||||
|
|
||||||
if (!p_octant->elements.empty()) {
|
if (!p_octant->elements.empty()) {
|
||||||
|
|
||||||
typename List< Element*,AL >::Element *I;
|
typename List< Element*,AL >::Element *I;
|
||||||
I=p_octant->elements.front();
|
I=p_octant->elements.front();
|
||||||
|
|
||||||
for(;I;I=I->next()) {
|
for(;I;I=I->next()) {
|
||||||
|
|
||||||
Element *e=I->get();
|
Element *e=I->get();
|
||||||
|
|
||||||
if (e->last_pass==pass || (use_pairs && !(e->pairable_type&p_cull->mask)))
|
if (e->last_pass==pass || (use_pairs && !(e->pairable_type&p_cull->mask)))
|
||||||
continue;
|
continue;
|
||||||
e->last_pass=pass;
|
e->last_pass=pass;
|
||||||
|
|
||||||
if (e->aabb.intersects_convex_shape(p_cull->planes,p_cull->plane_count)) {
|
if (e->aabb.intersects_convex_shape(p_cull->planes,p_cull->plane_count)) {
|
||||||
|
|
||||||
if (*p_cull->result_idx<p_cull->result_max) {
|
if (*p_cull->result_idx<p_cull->result_max) {
|
||||||
p_cull->result_array[*p_cull->result_idx] = e->userdata;
|
p_cull->result_array[*p_cull->result_idx] = e->userdata;
|
||||||
(*p_cull->result_idx)++;
|
(*p_cull->result_idx)++;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
return; // pointless to continue
|
return; // pointless to continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (use_pairs && !p_octant->pairable_elements.empty()) {
|
if (use_pairs && !p_octant->pairable_elements.empty()) {
|
||||||
|
|
||||||
typename List< Element*,AL >::Element *I;
|
typename List< Element*,AL >::Element *I;
|
||||||
I=p_octant->pairable_elements.front();
|
I=p_octant->pairable_elements.front();
|
||||||
|
|
||||||
for(;I;I=I->next()) {
|
for(;I;I=I->next()) {
|
||||||
|
|
||||||
Element *e=I->get();
|
Element *e=I->get();
|
||||||
|
|
||||||
if (e->last_pass==pass || (use_pairs && !(e->pairable_type&p_cull->mask)))
|
if (e->last_pass==pass || (use_pairs && !(e->pairable_type&p_cull->mask)))
|
||||||
continue;
|
continue;
|
||||||
e->last_pass=pass;
|
e->last_pass=pass;
|
||||||
|
|
||||||
if (e->aabb.intersects_convex_shape(p_cull->planes,p_cull->plane_count)) {
|
if (e->aabb.intersects_convex_shape(p_cull->planes,p_cull->plane_count)) {
|
||||||
|
|
||||||
if (*p_cull->result_idx<p_cull->result_max) {
|
if (*p_cull->result_idx<p_cull->result_max) {
|
||||||
|
|
||||||
p_cull->result_array[*p_cull->result_idx] = e->userdata;
|
p_cull->result_array[*p_cull->result_idx] = e->userdata;
|
||||||
(*p_cull->result_idx)++;
|
(*p_cull->result_idx)++;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
return; // pointless to continue
|
return; // pointless to continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i=0;i<8;i++) {
|
for (int i=0;i<8;i++) {
|
||||||
|
|
||||||
if (p_octant->children[i] && p_octant->children[i]->aabb.intersects_convex_shape(p_cull->planes,p_cull->plane_count)) {
|
if (p_octant->children[i] && p_octant->children[i]->aabb.intersects_convex_shape(p_cull->planes,p_cull->plane_count)) {
|
||||||
_cull_convex(p_octant->children[i],p_cull);
|
_cull_convex(p_octant->children[i],p_cull);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class T,bool use_pairs,class AL>
|
template<class T,bool use_pairs,class AL>
|
||||||
void Octree<T,use_pairs,AL>::_cull_AABB(Octant *p_octant,const AABB& p_aabb, T** p_result_array,int *p_result_idx,int p_result_max,int *p_subindex_array,uint32_t p_mask) {
|
void Octree<T,use_pairs,AL>::_cull_AABB(Octant *p_octant,const AABB& p_aabb, T** p_result_array,int *p_result_idx,int p_result_max,int *p_subindex_array,uint32_t p_mask) {
|
||||||
|
|
||||||
if (*p_result_idx==p_result_max)
|
if (*p_result_idx==p_result_max)
|
||||||
return; //pointless
|
return; //pointless
|
||||||
|
|
||||||
if (!p_octant->elements.empty()) {
|
if (!p_octant->elements.empty()) {
|
||||||
|
|
||||||
typename List< Element*,AL >::Element *I;
|
typename List< Element*,AL >::Element *I;
|
||||||
I=p_octant->elements.front();
|
I=p_octant->elements.front();
|
||||||
for(;I;I=I->next()) {
|
for(;I;I=I->next()) {
|
||||||
|
|
||||||
Element *e=I->get();
|
Element *e=I->get();
|
||||||
|
|
||||||
if (e->last_pass==pass || (use_pairs && !(e->pairable_type&p_mask)))
|
if (e->last_pass==pass || (use_pairs && !(e->pairable_type&p_mask)))
|
||||||
continue;
|
continue;
|
||||||
e->last_pass=pass;
|
e->last_pass=pass;
|
||||||
|
|
||||||
if (p_aabb.intersects_inclusive(e->aabb)) {
|
if (p_aabb.intersects_inclusive(e->aabb)) {
|
||||||
|
|
||||||
if (*p_result_idx<p_result_max) {
|
if (*p_result_idx<p_result_max) {
|
||||||
|
|
||||||
p_result_array[*p_result_idx] = e->userdata;
|
p_result_array[*p_result_idx] = e->userdata;
|
||||||
if (p_subindex_array)
|
if (p_subindex_array)
|
||||||
p_subindex_array[*p_result_idx] = e->subindex;
|
p_subindex_array[*p_result_idx] = e->subindex;
|
||||||
|
|
||||||
(*p_result_idx)++;
|
(*p_result_idx)++;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
return; // pointless to continue
|
return; // pointless to continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (use_pairs && !p_octant->pairable_elements.empty()) {
|
if (use_pairs && !p_octant->pairable_elements.empty()) {
|
||||||
|
|
||||||
typename List< Element*,AL >::Element *I;
|
typename List< Element*,AL >::Element *I;
|
||||||
I=p_octant->pairable_elements.front();
|
I=p_octant->pairable_elements.front();
|
||||||
for(;I;I=I->next()) {
|
for(;I;I=I->next()) {
|
||||||
|
|
||||||
Element *e=I->get();
|
Element *e=I->get();
|
||||||
|
|
||||||
if (e->last_pass==pass || (use_pairs && !(e->pairable_type&p_mask)))
|
if (e->last_pass==pass || (use_pairs && !(e->pairable_type&p_mask)))
|
||||||
continue;
|
continue;
|
||||||
e->last_pass=pass;
|
e->last_pass=pass;
|
||||||
|
|
||||||
if (p_aabb.intersects_inclusive(e->aabb)) {
|
if (p_aabb.intersects_inclusive(e->aabb)) {
|
||||||
|
|
||||||
if (*p_result_idx<p_result_max) {
|
if (*p_result_idx<p_result_max) {
|
||||||
|
|
||||||
p_result_array[*p_result_idx] = e->userdata;
|
p_result_array[*p_result_idx] = e->userdata;
|
||||||
if (p_subindex_array)
|
if (p_subindex_array)
|
||||||
p_subindex_array[*p_result_idx] = e->subindex;
|
p_subindex_array[*p_result_idx] = e->subindex;
|
||||||
(*p_result_idx)++;
|
(*p_result_idx)++;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
return; // pointless to continue
|
return; // pointless to continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i=0;i<8;i++) {
|
for (int i=0;i<8;i++) {
|
||||||
|
|
||||||
if (p_octant->children[i] && p_octant->children[i]->aabb.intersects_inclusive(p_aabb)) {
|
if (p_octant->children[i] && p_octant->children[i]->aabb.intersects_inclusive(p_aabb)) {
|
||||||
_cull_AABB(p_octant->children[i],p_aabb, p_result_array,p_result_idx,p_result_max,p_subindex_array,p_mask);
|
_cull_AABB(p_octant->children[i],p_aabb, p_result_array,p_result_idx,p_result_max,p_subindex_array,p_mask);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1205,53 +1205,53 @@ void Octree<T,use_pairs,AL>::_cull_segment(Octant *p_octant,const Vector3& p_fro
|
||||||
|
|
||||||
if (*p_result_idx==p_result_max)
|
if (*p_result_idx==p_result_max)
|
||||||
return; //pointless
|
return; //pointless
|
||||||
|
|
||||||
if (!p_octant->elements.empty()) {
|
if (!p_octant->elements.empty()) {
|
||||||
|
|
||||||
typename List< Element*,AL >::Element *I;
|
typename List< Element*,AL >::Element *I;
|
||||||
I=p_octant->elements.front();
|
I=p_octant->elements.front();
|
||||||
for(;I;I=I->next()) {
|
for(;I;I=I->next()) {
|
||||||
|
|
||||||
Element *e=I->get();
|
Element *e=I->get();
|
||||||
|
|
||||||
if (e->last_pass==pass || (use_pairs && !(e->pairable_type&p_mask)))
|
if (e->last_pass==pass || (use_pairs && !(e->pairable_type&p_mask)))
|
||||||
continue;
|
continue;
|
||||||
e->last_pass=pass;
|
e->last_pass=pass;
|
||||||
|
|
||||||
if (e->aabb.intersects_segment(p_from,p_to)) {
|
if (e->aabb.intersects_segment(p_from,p_to)) {
|
||||||
|
|
||||||
if (*p_result_idx<p_result_max) {
|
if (*p_result_idx<p_result_max) {
|
||||||
|
|
||||||
p_result_array[*p_result_idx] = e->userdata;
|
p_result_array[*p_result_idx] = e->userdata;
|
||||||
if (p_subindex_array)
|
if (p_subindex_array)
|
||||||
p_subindex_array[*p_result_idx] = e->subindex;
|
p_subindex_array[*p_result_idx] = e->subindex;
|
||||||
(*p_result_idx)++;
|
(*p_result_idx)++;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
return; // pointless to continue
|
return; // pointless to continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (use_pairs && !p_octant->pairable_elements.empty()) {
|
if (use_pairs && !p_octant->pairable_elements.empty()) {
|
||||||
|
|
||||||
typename List< Element*,AL >::Element *I;
|
typename List< Element*,AL >::Element *I;
|
||||||
I=p_octant->pairable_elements.front();
|
I=p_octant->pairable_elements.front();
|
||||||
for(;I;I=I->next()) {
|
for(;I;I=I->next()) {
|
||||||
|
|
||||||
Element *e=I->get();
|
Element *e=I->get();
|
||||||
|
|
||||||
if (e->last_pass==pass || (use_pairs && !(e->pairable_type&p_mask)))
|
if (e->last_pass==pass || (use_pairs && !(e->pairable_type&p_mask)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
e->last_pass=pass;
|
e->last_pass=pass;
|
||||||
|
|
||||||
if (e->aabb.intersects_segment(p_from,p_to)) {
|
if (e->aabb.intersects_segment(p_from,p_to)) {
|
||||||
|
|
||||||
if (*p_result_idx<p_result_max) {
|
if (*p_result_idx<p_result_max) {
|
||||||
|
|
||||||
p_result_array[*p_result_idx] = e->userdata;
|
p_result_array[*p_result_idx] = e->userdata;
|
||||||
if (p_subindex_array)
|
if (p_subindex_array)
|
||||||
p_subindex_array[*p_result_idx] = e->subindex;
|
p_subindex_array[*p_result_idx] = e->subindex;
|
||||||
|
@ -1259,20 +1259,20 @@ void Octree<T,use_pairs,AL>::_cull_segment(Octant *p_octant,const Vector3& p_fro
|
||||||
(*p_result_idx)++;
|
(*p_result_idx)++;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
return; // pointless to continue
|
return; // pointless to continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
for (int i=0;i<8;i++) {
|
for (int i=0;i<8;i++) {
|
||||||
|
|
||||||
if (p_octant->children[i] && p_octant->children[i]->aabb.intersects_segment(p_from,p_to)) {
|
if (p_octant->children[i] && p_octant->children[i]->aabb.intersects_segment(p_from,p_to)) {
|
||||||
_cull_segment(p_octant->children[i],p_from,p_to, p_result_array,p_result_idx,p_result_max,p_subindex_array,p_mask);
|
_cull_segment(p_octant->children[i],p_from,p_to, p_result_array,p_result_idx,p_result_max,p_subindex_array,p_mask);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1357,7 +1357,7 @@ int Octree<T,use_pairs,AL>::cull_convex(const Vector<Plane>& p_convex,T** p_resu
|
||||||
|
|
||||||
if (!root)
|
if (!root)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
int result_count=0;
|
int result_count=0;
|
||||||
pass++;
|
pass++;
|
||||||
_CullConvexData cdata;
|
_CullConvexData cdata;
|
||||||
|
@ -1367,9 +1367,9 @@ int Octree<T,use_pairs,AL>::cull_convex(const Vector<Plane>& p_convex,T** p_resu
|
||||||
cdata.result_max=p_result_max;
|
cdata.result_max=p_result_max;
|
||||||
cdata.result_idx=&result_count;
|
cdata.result_idx=&result_count;
|
||||||
cdata.mask=p_mask;
|
cdata.mask=p_mask;
|
||||||
|
|
||||||
_cull_convex(root,&cdata);
|
_cull_convex(root,&cdata);
|
||||||
|
|
||||||
return result_count;
|
return result_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1381,11 +1381,11 @@ int Octree<T,use_pairs,AL>::cull_AABB(const AABB& p_aabb,T** p_result_array,int
|
||||||
|
|
||||||
if (!root)
|
if (!root)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
int result_count=0;
|
int result_count=0;
|
||||||
pass++;
|
pass++;
|
||||||
_cull_AABB(root,p_aabb,p_result_array,&result_count,p_result_max,p_subindex_array,p_mask);
|
_cull_AABB(root,p_aabb,p_result_array,&result_count,p_result_max,p_subindex_array,p_mask);
|
||||||
|
|
||||||
return result_count;
|
return result_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1395,11 +1395,11 @@ int Octree<T,use_pairs,AL>::cull_segment(const Vector3& p_from, const Vector3& p
|
||||||
|
|
||||||
if (!root)
|
if (!root)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
int result_count=0;
|
int result_count=0;
|
||||||
pass++;
|
pass++;
|
||||||
_cull_segment(root,p_from,p_to,p_result_array,&result_count,p_result_max,p_subindex_array,p_mask);
|
_cull_segment(root,p_from,p_to,p_result_array,&result_count,p_result_max,p_subindex_array,p_mask);
|
||||||
|
|
||||||
return result_count;
|
return result_count;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1436,7 +1436,7 @@ void Octree<T,use_pairs,AL>::set_unpair_callback( UnpairCallback p_callback, voi
|
||||||
|
|
||||||
template<class T,bool use_pairs,class AL>
|
template<class T,bool use_pairs,class AL>
|
||||||
Octree<T,use_pairs,AL>::Octree(real_t p_unit_size) {
|
Octree<T,use_pairs,AL>::Octree(real_t p_unit_size) {
|
||||||
|
|
||||||
last_element_id=1;
|
last_element_id=1;
|
||||||
pass=1;
|
pass=1;
|
||||||
unit_size=p_unit_size;
|
unit_size=p_unit_size;
|
||||||
|
|
|
@ -50,7 +50,7 @@ void Plane::normalize() {
|
||||||
}
|
}
|
||||||
|
|
||||||
Plane Plane::normalized() const {
|
Plane Plane::normalized() const {
|
||||||
|
|
||||||
Plane p = *this;
|
Plane p = *this;
|
||||||
p.normalize();
|
p.normalize();
|
||||||
return p;
|
return p;
|
||||||
|
@ -66,12 +66,12 @@ Vector3 Plane::get_any_perpendicular_normal() const {
|
||||||
static const Vector3 p1 = Vector3(1,0,0);
|
static const Vector3 p1 = Vector3(1,0,0);
|
||||||
static const Vector3 p2 = Vector3(0,1,0);
|
static const Vector3 p2 = Vector3(0,1,0);
|
||||||
Vector3 p;
|
Vector3 p;
|
||||||
|
|
||||||
if (ABS(normal.dot(p1)) > 0.99) // if too similar to p1
|
if (ABS(normal.dot(p1)) > 0.99) // if too similar to p1
|
||||||
p=p2; // use p2
|
p=p2; // use p2
|
||||||
else
|
else
|
||||||
p=p1; // use p1
|
p=p1; // use p1
|
||||||
|
|
||||||
p-=normal * normal.dot(p);
|
p-=normal * normal.dot(p);
|
||||||
p.normalize();
|
p.normalize();
|
||||||
|
|
||||||
|
|
|
@ -62,9 +62,9 @@ public:
|
||||||
bool intersects_segment(Vector3 p_begin, Vector3 p_end, Vector3* p_intersection) const;
|
bool intersects_segment(Vector3 p_begin, Vector3 p_end, Vector3* p_intersection) const;
|
||||||
|
|
||||||
_FORCE_INLINE_ Vector3 project(const Vector3& p_point) const {
|
_FORCE_INLINE_ Vector3 project(const Vector3& p_point) const {
|
||||||
|
|
||||||
return p_point - normal * distance_to(p_point);
|
return p_point - normal * distance_to(p_point);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* misc */
|
/* misc */
|
||||||
|
|
||||||
|
|
|
@ -30,9 +30,9 @@
|
||||||
#include "print_string.h"
|
#include "print_string.h"
|
||||||
|
|
||||||
void Quat::set_euler(const Vector3& p_euler) {
|
void Quat::set_euler(const Vector3& p_euler) {
|
||||||
real_t half_yaw = p_euler.x * 0.5;
|
real_t half_yaw = p_euler.x * 0.5;
|
||||||
real_t half_pitch = p_euler.y * 0.5;
|
real_t half_pitch = p_euler.y * 0.5;
|
||||||
real_t half_roll = p_euler.z * 0.5;
|
real_t half_roll = p_euler.z * 0.5;
|
||||||
real_t cos_yaw = Math::cos(half_yaw);
|
real_t cos_yaw = Math::cos(half_yaw);
|
||||||
real_t sin_yaw = Math::sin(half_yaw);
|
real_t sin_yaw = Math::sin(half_yaw);
|
||||||
real_t cos_pitch = Math::cos(half_pitch);
|
real_t cos_pitch = Math::cos(half_pitch);
|
||||||
|
@ -75,7 +75,7 @@ void Quat::normalize() {
|
||||||
|
|
||||||
Quat Quat::normalized() const {
|
Quat Quat::normalized() const {
|
||||||
return *this / length();
|
return *this / length();
|
||||||
}
|
}
|
||||||
|
|
||||||
Quat Quat::inverse() const {
|
Quat Quat::inverse() const {
|
||||||
return Quat( -x, -y, -z, w );
|
return Quat( -x, -y, -z, w );
|
||||||
|
@ -252,7 +252,7 @@ Quat Quat::cubic_slerp(const Quat& q, const Quat& prep, const Quat& postq,const
|
||||||
|
|
||||||
Quat::operator String() const {
|
Quat::operator String() const {
|
||||||
|
|
||||||
return String::num(x)+","+String::num(y)+","+ String::num(z)+","+ String::num(w);
|
return String::num(x)+","+String::num(y)+","+ String::num(z)+","+ String::num(w);
|
||||||
}
|
}
|
||||||
|
|
||||||
Quat::Quat(const Vector3& axis, const real_t& angle) {
|
Quat::Quat(const Vector3& axis, const real_t& angle) {
|
||||||
|
@ -261,7 +261,7 @@ Quat::Quat(const Vector3& axis, const real_t& angle) {
|
||||||
set(0,0,0,0);
|
set(0,0,0,0);
|
||||||
else {
|
else {
|
||||||
real_t s = Math::sin(-angle * 0.5) / d;
|
real_t s = Math::sin(-angle * 0.5) / d;
|
||||||
set(axis.x * s, axis.y * s, axis.z * s,
|
set(axis.x * s, axis.y * s, axis.z * s,
|
||||||
Math::cos(-angle * 0.5));
|
Math::cos(-angle * 0.5));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,18 +89,18 @@ public:
|
||||||
_FORCE_INLINE_ Quat operator-() const;
|
_FORCE_INLINE_ Quat operator-() const;
|
||||||
_FORCE_INLINE_ Quat operator*(const real_t& s) const;
|
_FORCE_INLINE_ Quat operator*(const real_t& s) const;
|
||||||
_FORCE_INLINE_ Quat operator/(const real_t& s) const;
|
_FORCE_INLINE_ Quat operator/(const real_t& s) const;
|
||||||
|
|
||||||
|
|
||||||
_FORCE_INLINE_ bool operator==(const Quat& p_quat) const;
|
_FORCE_INLINE_ bool operator==(const Quat& p_quat) const;
|
||||||
_FORCE_INLINE_ bool operator!=(const Quat& p_quat) const;
|
_FORCE_INLINE_ bool operator!=(const Quat& p_quat) const;
|
||||||
|
|
||||||
operator String() const;
|
operator String() const;
|
||||||
|
|
||||||
inline void set( real_t p_x, real_t p_y, real_t p_z, real_t p_w) {
|
inline void set( real_t p_x, real_t p_y, real_t p_z, real_t p_w) {
|
||||||
x=p_x; y=p_y; z=p_z; w=p_w;
|
x=p_x; y=p_y; z=p_z; w=p_w;
|
||||||
}
|
}
|
||||||
inline Quat(real_t p_x, real_t p_y, real_t p_z, real_t p_w) {
|
inline Quat(real_t p_x, real_t p_y, real_t p_z, real_t p_w) {
|
||||||
x=p_x; y=p_y; z=p_z; w=p_w;
|
x=p_x; y=p_y; z=p_z; w=p_w;
|
||||||
}
|
}
|
||||||
Quat(const Vector3& axis, const real_t& angle);
|
Quat(const Vector3& axis, const real_t& angle);
|
||||||
|
|
||||||
|
@ -127,7 +127,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Quat() {x=y=z=0; w=1; }
|
inline Quat() {x=y=z=0; w=1; }
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -141,7 +141,7 @@ real_t Quat::length_squared() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Quat::operator+=(const Quat& q) {
|
void Quat::operator+=(const Quat& q) {
|
||||||
x += q.x; y += q.y; z += q.z; w += q.w;
|
x += q.x; y += q.y; z += q.z; w += q.w;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Quat::operator-=(const Quat& q) {
|
void Quat::operator-=(const Quat& q) {
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
#include "math_funcs.h"
|
#include "math_funcs.h"
|
||||||
#include "os/copymem.h"
|
#include "os/copymem.h"
|
||||||
#include "print_string.h"
|
#include "print_string.h"
|
||||||
|
|
||||||
|
|
||||||
void Transform::affine_invert() {
|
void Transform::affine_invert() {
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ Transform Transform::affine_inverse() const {
|
||||||
void Transform::invert() {
|
void Transform::invert() {
|
||||||
|
|
||||||
basis.transpose();
|
basis.transpose();
|
||||||
origin = basis.xform(-origin);
|
origin = basis.xform(-origin);
|
||||||
}
|
}
|
||||||
|
|
||||||
Transform Transform::inverse() const {
|
Transform Transform::inverse() const {
|
||||||
|
@ -87,30 +87,30 @@ void Transform::set_look_at( const Vector3& p_eye, const Vector3& p_target, cons
|
||||||
|
|
||||||
// Reference: MESA source code
|
// Reference: MESA source code
|
||||||
Vector3 v_x, v_y, v_z;
|
Vector3 v_x, v_y, v_z;
|
||||||
|
|
||||||
/* Make rotation matrix */
|
/* Make rotation matrix */
|
||||||
|
|
||||||
/* Z vector */
|
/* Z vector */
|
||||||
v_z = p_eye - p_target;
|
v_z = p_eye - p_target;
|
||||||
|
|
||||||
v_z.normalize();
|
v_z.normalize();
|
||||||
|
|
||||||
v_y = p_up;
|
v_y = p_up;
|
||||||
|
|
||||||
|
|
||||||
v_x=v_y.cross(v_z);
|
v_x=v_y.cross(v_z);
|
||||||
|
|
||||||
/* Recompute Y = Z cross X */
|
/* Recompute Y = Z cross X */
|
||||||
v_y=v_z.cross(v_x);
|
v_y=v_z.cross(v_x);
|
||||||
|
|
||||||
v_x.normalize();
|
v_x.normalize();
|
||||||
v_y.normalize();
|
v_y.normalize();
|
||||||
|
|
||||||
basis.set_axis(0,v_x);
|
basis.set_axis(0,v_x);
|
||||||
basis.set_axis(1,v_y);
|
basis.set_axis(1,v_y);
|
||||||
basis.set_axis(2,v_z);
|
basis.set_axis(2,v_z);
|
||||||
origin=p_eye;
|
origin=p_eye;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Transform Transform::interpolate_with(const Transform& p_transform, float p_c) const {
|
Transform Transform::interpolate_with(const Transform& p_transform, float p_c) const {
|
||||||
|
@ -193,7 +193,7 @@ bool Transform::operator!=(const Transform& p_transform) const {
|
||||||
void Transform::operator*=(const Transform& p_transform) {
|
void Transform::operator*=(const Transform& p_transform) {
|
||||||
|
|
||||||
origin=xform(p_transform.origin);
|
origin=xform(p_transform.origin);
|
||||||
basis*=p_transform.basis;
|
basis*=p_transform.basis;
|
||||||
}
|
}
|
||||||
|
|
||||||
Transform Transform::operator*(const Transform& p_transform) const {
|
Transform Transform::operator*(const Transform& p_transform) const {
|
||||||
|
|
|
@ -40,9 +40,9 @@ public:
|
||||||
|
|
||||||
Matrix3 basis;
|
Matrix3 basis;
|
||||||
Vector3 origin;
|
Vector3 origin;
|
||||||
|
|
||||||
void invert();
|
void invert();
|
||||||
Transform inverse() const;
|
Transform inverse() const;
|
||||||
|
|
||||||
void affine_invert();
|
void affine_invert();
|
||||||
Transform affine_inverse() const;
|
Transform affine_inverse() const;
|
||||||
|
@ -76,27 +76,27 @@ public:
|
||||||
|
|
||||||
_FORCE_INLINE_ Vector3 xform(const Vector3& p_vector) const;
|
_FORCE_INLINE_ Vector3 xform(const Vector3& p_vector) const;
|
||||||
_FORCE_INLINE_ Vector3 xform_inv(const Vector3& p_vector) const;
|
_FORCE_INLINE_ Vector3 xform_inv(const Vector3& p_vector) const;
|
||||||
|
|
||||||
_FORCE_INLINE_ Plane xform(const Plane& p_plane) const;
|
_FORCE_INLINE_ Plane xform(const Plane& p_plane) const;
|
||||||
_FORCE_INLINE_ Plane xform_inv(const Plane& p_plane) const;
|
_FORCE_INLINE_ Plane xform_inv(const Plane& p_plane) const;
|
||||||
|
|
||||||
_FORCE_INLINE_ AABB xform(const AABB& p_aabb) const;
|
_FORCE_INLINE_ AABB xform(const AABB& p_aabb) const;
|
||||||
_FORCE_INLINE_ AABB xform_inv(const AABB& p_aabb) const;
|
_FORCE_INLINE_ AABB xform_inv(const AABB& p_aabb) const;
|
||||||
|
|
||||||
void operator*=(const Transform& p_transform);
|
void operator*=(const Transform& p_transform);
|
||||||
Transform operator*(const Transform& p_transform) const;
|
Transform operator*(const Transform& p_transform) const;
|
||||||
|
|
||||||
Transform interpolate_with(const Transform& p_transform, float p_c) const;
|
Transform interpolate_with(const Transform& p_transform, float p_c) const;
|
||||||
|
|
||||||
_FORCE_INLINE_ Transform inverse_xform(const Transform& t) const {
|
_FORCE_INLINE_ Transform inverse_xform(const Transform& t) const {
|
||||||
|
|
||||||
Vector3 v = t.origin - origin;
|
Vector3 v = t.origin - origin;
|
||||||
return Transform(basis.transpose_xform(t.basis),
|
return Transform(basis.transpose_xform(t.basis),
|
||||||
basis.xform(v));
|
basis.xform(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
void set(real_t xx, real_t xy, real_t xz, real_t yx, real_t yy, real_t yz, real_t zx, real_t zy, real_t zz,real_t tx, real_t ty, real_t tz) {
|
void set(real_t xx, real_t xy, real_t xz, real_t yx, real_t yy, real_t yz, real_t zx, real_t zy, real_t zz,real_t tx, real_t ty, real_t tz) {
|
||||||
|
|
||||||
basis.elements[0][0]=xx;
|
basis.elements[0][0]=xx;
|
||||||
basis.elements[0][1]=xy;
|
basis.elements[0][1]=xy;
|
||||||
basis.elements[0][2]=xz;
|
basis.elements[0][2]=xz;
|
||||||
|
@ -105,14 +105,14 @@ public:
|
||||||
basis.elements[1][2]=yz;
|
basis.elements[1][2]=yz;
|
||||||
basis.elements[2][0]=zx;
|
basis.elements[2][0]=zx;
|
||||||
basis.elements[2][1]=zy;
|
basis.elements[2][1]=zy;
|
||||||
basis.elements[2][2]=zz;
|
basis.elements[2][2]=zz;
|
||||||
origin.x=tx;
|
origin.x=tx;
|
||||||
origin.y=ty;
|
origin.y=ty;
|
||||||
origin.z=tz;
|
origin.z=tz;
|
||||||
}
|
}
|
||||||
|
|
||||||
operator String() const;
|
operator String() const;
|
||||||
|
|
||||||
Transform(const Matrix3& p_basis, const Vector3& p_origin=Vector3());
|
Transform(const Matrix3& p_basis, const Vector3& p_origin=Vector3());
|
||||||
Transform() {}
|
Transform() {}
|
||||||
|
|
||||||
|
@ -128,9 +128,9 @@ _FORCE_INLINE_ Vector3 Transform::xform(const Vector3& p_vector) const {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
_FORCE_INLINE_ Vector3 Transform::xform_inv(const Vector3& p_vector) const {
|
_FORCE_INLINE_ Vector3 Transform::xform_inv(const Vector3& p_vector) const {
|
||||||
|
|
||||||
Vector3 v = p_vector - origin;
|
Vector3 v = p_vector - origin;
|
||||||
|
|
||||||
return Vector3(
|
return Vector3(
|
||||||
(basis.elements[0][0]*v.x ) + ( basis.elements[1][0]*v.y ) + ( basis.elements[2][0]*v.z ),
|
(basis.elements[0][0]*v.x ) + ( basis.elements[1][0]*v.y ) + ( basis.elements[2][0]*v.z ),
|
||||||
(basis.elements[0][1]*v.x ) + ( basis.elements[1][1]*v.y ) + ( basis.elements[2][1]*v.z ),
|
(basis.elements[0][1]*v.x ) + ( basis.elements[1][1]*v.y ) + ( basis.elements[2][1]*v.z ),
|
||||||
|
@ -140,16 +140,16 @@ _FORCE_INLINE_ Vector3 Transform::xform_inv(const Vector3& p_vector) const {
|
||||||
|
|
||||||
_FORCE_INLINE_ Plane Transform::xform(const Plane& p_plane) const {
|
_FORCE_INLINE_ Plane Transform::xform(const Plane& p_plane) const {
|
||||||
|
|
||||||
|
|
||||||
Vector3 point=p_plane.normal*p_plane.d;
|
Vector3 point=p_plane.normal*p_plane.d;
|
||||||
Vector3 point_dir=point+p_plane.normal;
|
Vector3 point_dir=point+p_plane.normal;
|
||||||
point=xform(point);
|
point=xform(point);
|
||||||
point_dir=xform(point_dir);
|
point_dir=xform(point_dir);
|
||||||
|
|
||||||
Vector3 normal=point_dir-point;
|
Vector3 normal=point_dir-point;
|
||||||
normal.normalize();
|
normal.normalize();
|
||||||
real_t d=normal.dot(point);
|
real_t d=normal.dot(point);
|
||||||
|
|
||||||
return Plane(normal,d);
|
return Plane(normal,d);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -159,11 +159,11 @@ _FORCE_INLINE_ Plane Transform::xform_inv(const Plane& p_plane) const {
|
||||||
Vector3 point_dir=point+p_plane.normal;
|
Vector3 point_dir=point+p_plane.normal;
|
||||||
xform_inv(point);
|
xform_inv(point);
|
||||||
xform_inv(point_dir);
|
xform_inv(point_dir);
|
||||||
|
|
||||||
Vector3 normal=point_dir-point;
|
Vector3 normal=point_dir-point;
|
||||||
normal.normalize();
|
normal.normalize();
|
||||||
real_t d=normal.dot(point);
|
real_t d=normal.dot(point);
|
||||||
|
|
||||||
return Plane(normal,d);
|
return Plane(normal,d);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -199,17 +199,17 @@ _FORCE_INLINE_ AABB Transform::xform(const AABB& p_aabb) const {
|
||||||
Vector3(p_aabb.pos.x, p_aabb.pos.y, p_aabb.pos.z+p_aabb.size.z),
|
Vector3(p_aabb.pos.x, p_aabb.pos.y, p_aabb.pos.z+p_aabb.size.z),
|
||||||
Vector3(p_aabb.pos.x, p_aabb.pos.y, p_aabb.pos.z)
|
Vector3(p_aabb.pos.x, p_aabb.pos.y, p_aabb.pos.z)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
AABB ret;
|
AABB ret;
|
||||||
|
|
||||||
ret.pos=xform(vertices[0]);
|
ret.pos=xform(vertices[0]);
|
||||||
|
|
||||||
for (int i=1;i<8;i++) {
|
for (int i=1;i<8;i++) {
|
||||||
|
|
||||||
ret.expand_to( xform(vertices[i]) );
|
ret.expand_to( xform(vertices[i]) );
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -227,17 +227,17 @@ _FORCE_INLINE_ AABB Transform::xform_inv(const AABB& p_aabb) const {
|
||||||
Vector3(p_aabb.pos.x, p_aabb.pos.y, p_aabb.pos.z+p_aabb.size.z),
|
Vector3(p_aabb.pos.x, p_aabb.pos.y, p_aabb.pos.z+p_aabb.size.z),
|
||||||
Vector3(p_aabb.pos.x, p_aabb.pos.y, p_aabb.pos.z)
|
Vector3(p_aabb.pos.x, p_aabb.pos.y, p_aabb.pos.z)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
AABB ret;
|
AABB ret;
|
||||||
|
|
||||||
ret.pos=xform_inv(vertices[0]);
|
ret.pos=xform_inv(vertices[0]);
|
||||||
|
|
||||||
for (int i=1;i<8;i++) {
|
for (int i=1;i<8;i++) {
|
||||||
|
|
||||||
ret.expand_to( xform_inv(vertices[i]) );
|
ret.expand_to( xform_inv(vertices[i]) );
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -320,7 +320,7 @@ void MessageQueue::_call_function(Object* p_target, const StringName& p_func, co
|
||||||
void MessageQueue::flush() {
|
void MessageQueue::flush() {
|
||||||
|
|
||||||
|
|
||||||
if (buffer_max_used<buffer_end); {
|
if (buffer_end > buffer_max_used) {
|
||||||
buffer_max_used=buffer_end;
|
buffer_max_used=buffer_end;
|
||||||
//statistics();
|
//statistics();
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,8 +58,8 @@ template<class T>
|
||||||
struct VariantCaster {
|
struct VariantCaster {
|
||||||
|
|
||||||
static _FORCE_INLINE_ T cast(const Variant& p_variant) {
|
static _FORCE_INLINE_ T cast(const Variant& p_variant) {
|
||||||
|
|
||||||
return p_variant;
|
return p_variant;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -67,8 +67,8 @@ template<class T>
|
||||||
struct VariantCaster<T&> {
|
struct VariantCaster<T&> {
|
||||||
|
|
||||||
static _FORCE_INLINE_ T cast(const Variant& p_variant) {
|
static _FORCE_INLINE_ T cast(const Variant& p_variant) {
|
||||||
|
|
||||||
return p_variant;
|
return p_variant;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -76,8 +76,8 @@ template<class T>
|
||||||
struct VariantCaster<const T&> {
|
struct VariantCaster<const T&> {
|
||||||
|
|
||||||
static _FORCE_INLINE_ T cast(const Variant& p_variant) {
|
static _FORCE_INLINE_ T cast(const Variant& p_variant) {
|
||||||
|
|
||||||
return p_variant;
|
return p_variant;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -255,7 +255,7 @@ Object::Connection::Connection(const Variant& p_variant) {
|
||||||
|
|
||||||
|
|
||||||
bool Object::_predelete() {
|
bool Object::_predelete() {
|
||||||
|
|
||||||
_predelete_ok=1;
|
_predelete_ok=1;
|
||||||
notification(NOTIFICATION_PREDELETE,true);
|
notification(NOTIFICATION_PREDELETE,true);
|
||||||
if (_predelete_ok) {
|
if (_predelete_ok) {
|
||||||
|
@ -269,16 +269,16 @@ void Object::_postinitialize() {
|
||||||
_type_ptr=_get_type_namev();
|
_type_ptr=_get_type_namev();
|
||||||
_initialize_typev();
|
_initialize_typev();
|
||||||
notification(NOTIFICATION_POSTINITIALIZE);
|
notification(NOTIFICATION_POSTINITIALIZE);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Object::get_valid_parents_static(List<String> *p_parents) {
|
void Object::get_valid_parents_static(List<String> *p_parents) {
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
void Object::_get_valid_parents_static(List<String> *p_parents) {
|
void Object::_get_valid_parents_static(List<String> *p_parents) {
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
#if 0
|
#if 0
|
||||||
//old style set, deprecated
|
//old style set, deprecated
|
||||||
|
@ -286,7 +286,7 @@ void Object::_get_valid_parents_static(List<String> *p_parents) {
|
||||||
void Object::set(const String& p_name, const Variant& p_value) {
|
void Object::set(const String& p_name, const Variant& p_value) {
|
||||||
|
|
||||||
_setv(p_name,p_value);
|
_setv(p_name,p_value);
|
||||||
|
|
||||||
//if (!_use_builtin_script())
|
//if (!_use_builtin_script())
|
||||||
// return;
|
// return;
|
||||||
|
|
||||||
|
@ -303,8 +303,8 @@ void Object::set(const String& p_name, const Variant& p_value) {
|
||||||
} else if (script_instance) {
|
} else if (script_instance) {
|
||||||
script_instance->set(p_name,p_value);
|
script_instance->set(p_name,p_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -348,7 +348,7 @@ void Object::set(const StringName& p_name, const Variant& p_value, bool *r_valid
|
||||||
*r_valid=true;
|
*r_valid=true;
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
//something inside the object... :|
|
//something inside the object... :|
|
||||||
bool success = _setv(p_name,p_value);
|
bool success = _setv(p_name,p_value);
|
||||||
if (success) {
|
if (success) {
|
||||||
if (r_valid)
|
if (r_valid)
|
||||||
|
@ -420,7 +420,7 @@ Variant Object::get(const String& p_name) const {
|
||||||
Variant ret=_getv(p_name);
|
Variant ret=_getv(p_name);
|
||||||
if (ret.get_type()!=Variant::NIL)
|
if (ret.get_type()!=Variant::NIL)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
bool success;
|
bool success;
|
||||||
ObjectTypeDB::get_property(const_cast<Object*>(this),p_name,ret,success);
|
ObjectTypeDB::get_property(const_cast<Object*>(this),p_name,ret,success);
|
||||||
if (success) {
|
if (success) {
|
||||||
|
@ -431,11 +431,11 @@ Variant Object::get(const String& p_name) const {
|
||||||
return metadata;
|
return metadata;
|
||||||
else if (p_name=="script/script")
|
else if (p_name=="script/script")
|
||||||
return script;
|
return script;
|
||||||
|
|
||||||
if (script_instance) {
|
if (script_instance) {
|
||||||
return script_instance->get(p_name);
|
return script_instance->get(p_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Variant();
|
return Variant();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -449,10 +449,10 @@ void Object::get_property_list(List<PropertyInfo> *p_list,bool p_reversed) const
|
||||||
}
|
}
|
||||||
|
|
||||||
_get_property_listv(p_list,p_reversed);
|
_get_property_listv(p_list,p_reversed);
|
||||||
|
|
||||||
if (!_use_builtin_script())
|
if (!_use_builtin_script())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!is_type("Script")) // can still be set, but this is for userfriendlyness
|
if (!is_type("Script")) // can still be set, but this is for userfriendlyness
|
||||||
p_list->push_back( PropertyInfo( Variant::OBJECT, "script/script", PROPERTY_HINT_RESOURCE_TYPE, "Script",PROPERTY_USAGE_DEFAULT|PROPERTY_USAGE_STORE_IF_NONZERO));
|
p_list->push_back( PropertyInfo( Variant::OBJECT, "script/script", PROPERTY_HINT_RESOURCE_TYPE, "Script",PROPERTY_USAGE_DEFAULT|PROPERTY_USAGE_STORE_IF_NONZERO));
|
||||||
if (!metadata.empty())
|
if (!metadata.empty())
|
||||||
|
@ -460,15 +460,15 @@ void Object::get_property_list(List<PropertyInfo> *p_list,bool p_reversed) const
|
||||||
if (script_instance && !p_reversed) {
|
if (script_instance && !p_reversed) {
|
||||||
p_list->push_back( PropertyInfo(Variant::NIL,"Script Variables",PROPERTY_HINT_NONE,String(),PROPERTY_USAGE_CATEGORY));
|
p_list->push_back( PropertyInfo(Variant::NIL,"Script Variables",PROPERTY_HINT_NONE,String(),PROPERTY_USAGE_CATEGORY));
|
||||||
script_instance->get_property_list(p_list);
|
script_instance->get_property_list(p_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
void Object::get_method_list(List<MethodInfo> *p_list) const {
|
void Object::get_method_list(List<MethodInfo> *p_list) const {
|
||||||
|
|
||||||
ObjectTypeDB::get_method_list(get_type_name(),p_list);
|
ObjectTypeDB::get_method_list(get_type_name(),p_list);
|
||||||
if (script_instance) {
|
if (script_instance) {
|
||||||
script_instance->get_method_list(p_list);
|
script_instance->get_method_list(p_list);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -898,22 +898,22 @@ Variant Object::call(const StringName& p_method,const Variant** p_args,int p_arg
|
||||||
|
|
||||||
|
|
||||||
void Object::notification(int p_notification,bool p_reversed) {
|
void Object::notification(int p_notification,bool p_reversed) {
|
||||||
|
|
||||||
|
|
||||||
_notificationv(p_notification,p_reversed);
|
_notificationv(p_notification,p_reversed);
|
||||||
|
|
||||||
if (script_instance) {
|
if (script_instance) {
|
||||||
script_instance->notification(p_notification);
|
script_instance->notification(p_notification);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Object::_changed_callback(Object *p_changed,const char *p_prop) {
|
void Object::_changed_callback(Object *p_changed,const char *p_prop) {
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Object::add_change_receptor( Object *p_receptor ) {
|
void Object::add_change_receptor( Object *p_receptor ) {
|
||||||
|
|
||||||
change_receptors.insert(p_receptor);
|
change_receptors.insert(p_receptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -941,8 +941,8 @@ void Object::set_script(const RefPtr& p_script) {
|
||||||
memdelete(script_instance);
|
memdelete(script_instance);
|
||||||
script_instance=NULL;
|
script_instance=NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
script=p_script;
|
script=p_script;
|
||||||
Ref<Script> s(script);
|
Ref<Script> s(script);
|
||||||
|
|
||||||
if (!s.is_null() && s->can_instance() ) {
|
if (!s.is_null() && s->can_instance() ) {
|
||||||
|
@ -1760,7 +1760,7 @@ bool Object::is_edited() const {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Object::Object() {
|
Object::Object() {
|
||||||
|
|
||||||
_type_ptr=NULL;
|
_type_ptr=NULL;
|
||||||
_block_signals=false;
|
_block_signals=false;
|
||||||
_predelete_ok=0;
|
_predelete_ok=0;
|
||||||
|
@ -1831,12 +1831,12 @@ Object::~Object() {
|
||||||
|
|
||||||
|
|
||||||
bool predelete_handler(Object *p_object) {
|
bool predelete_handler(Object *p_object) {
|
||||||
|
|
||||||
return p_object->_predelete();
|
return p_object->_predelete();
|
||||||
}
|
}
|
||||||
|
|
||||||
void postinitialize_handler(Object *p_object) {
|
void postinitialize_handler(Object *p_object) {
|
||||||
|
|
||||||
p_object->_postinitialize();
|
p_object->_postinitialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1900,8 +1900,8 @@ void ObjectDB::cleanup() {
|
||||||
|
|
||||||
GLOBAL_LOCK_FUNCTION;
|
GLOBAL_LOCK_FUNCTION;
|
||||||
if (instances.size()) {
|
if (instances.size()) {
|
||||||
|
|
||||||
WARN_PRINT("ObjectDB Instances still exist!");
|
WARN_PRINT("ObjectDB Instances still exist!");
|
||||||
if (OS::get_singleton()->is_stdout_verbose()) {
|
if (OS::get_singleton()->is_stdout_verbose()) {
|
||||||
const uint32_t *K=NULL;
|
const uint32_t *K=NULL;
|
||||||
while((K=instances.next(K))) {
|
while((K=instances.next(K))) {
|
||||||
|
|
|
@ -200,37 +200,37 @@ ObjectTypeDB::TypeInfo::TypeInfo() {
|
||||||
disabled=false;
|
disabled=false;
|
||||||
}
|
}
|
||||||
ObjectTypeDB::TypeInfo::~TypeInfo() {
|
ObjectTypeDB::TypeInfo::~TypeInfo() {
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool ObjectTypeDB::is_type(const StringName &p_type,const StringName& p_inherits) {
|
bool ObjectTypeDB::is_type(const StringName &p_type,const StringName& p_inherits) {
|
||||||
|
|
||||||
OBJTYPE_LOCK;
|
OBJTYPE_LOCK;
|
||||||
|
|
||||||
StringName inherits=p_type;
|
StringName inherits=p_type;
|
||||||
|
|
||||||
while (inherits.operator String().length()) {
|
while (inherits.operator String().length()) {
|
||||||
|
|
||||||
if (inherits==p_inherits)
|
if (inherits==p_inherits)
|
||||||
return true;
|
return true;
|
||||||
inherits=type_inherits_from(inherits);
|
inherits=type_inherits_from(inherits);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
void ObjectTypeDB::get_type_list( List<StringName> *p_types) {
|
void ObjectTypeDB::get_type_list( List<StringName> *p_types) {
|
||||||
|
|
||||||
OBJTYPE_LOCK;
|
OBJTYPE_LOCK;
|
||||||
|
|
||||||
const StringName *k=NULL;
|
const StringName *k=NULL;
|
||||||
|
|
||||||
while((k=types.next(k))) {
|
while((k=types.next(k))) {
|
||||||
|
|
||||||
p_types->push_back(*k);
|
p_types->push_back(*k);
|
||||||
}
|
}
|
||||||
|
|
||||||
p_types->sort();
|
p_types->sort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -238,11 +238,11 @@ void ObjectTypeDB::get_type_list( List<StringName> *p_types) {
|
||||||
void ObjectTypeDB::get_inheriters_from( const StringName& p_type,List<StringName> *p_types) {
|
void ObjectTypeDB::get_inheriters_from( const StringName& p_type,List<StringName> *p_types) {
|
||||||
|
|
||||||
OBJTYPE_LOCK;
|
OBJTYPE_LOCK;
|
||||||
|
|
||||||
const StringName *k=NULL;
|
const StringName *k=NULL;
|
||||||
|
|
||||||
while((k=types.next(k))) {
|
while((k=types.next(k))) {
|
||||||
|
|
||||||
if (*k!=p_type && is_type(*k,p_type))
|
if (*k!=p_type && is_type(*k,p_type))
|
||||||
p_types->push_back(*k);
|
p_types->push_back(*k);
|
||||||
}
|
}
|
||||||
|
@ -250,18 +250,18 @@ void ObjectTypeDB::get_inheriters_from( const StringName& p_type,List<StringName
|
||||||
}
|
}
|
||||||
|
|
||||||
StringName ObjectTypeDB::type_inherits_from(const StringName& p_type) {
|
StringName ObjectTypeDB::type_inherits_from(const StringName& p_type) {
|
||||||
|
|
||||||
OBJTYPE_LOCK;
|
OBJTYPE_LOCK;
|
||||||
|
|
||||||
TypeInfo *ti = types.getptr(p_type);
|
TypeInfo *ti = types.getptr(p_type);
|
||||||
ERR_FAIL_COND_V(!ti,"");
|
ERR_FAIL_COND_V(!ti,"");
|
||||||
return ti->inherits;
|
return ti->inherits;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ObjectTypeDB::type_exists(const StringName &p_type) {
|
bool ObjectTypeDB::type_exists(const StringName &p_type) {
|
||||||
|
|
||||||
OBJTYPE_LOCK;
|
OBJTYPE_LOCK;
|
||||||
return types.has(p_type);
|
return types.has(p_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjectTypeDB::add_compatibility_type(const StringName& p_type,const StringName& p_fallback) {
|
void ObjectTypeDB::add_compatibility_type(const StringName& p_type,const StringName& p_fallback) {
|
||||||
|
@ -270,7 +270,7 @@ void ObjectTypeDB::add_compatibility_type(const StringName& p_type,const StringN
|
||||||
}
|
}
|
||||||
|
|
||||||
Object *ObjectTypeDB::instance(const StringName &p_type) {
|
Object *ObjectTypeDB::instance(const StringName &p_type) {
|
||||||
|
|
||||||
TypeInfo *ti;
|
TypeInfo *ti;
|
||||||
{
|
{
|
||||||
OBJTYPE_LOCK;
|
OBJTYPE_LOCK;
|
||||||
|
@ -288,9 +288,9 @@ Object *ObjectTypeDB::instance(const StringName &p_type) {
|
||||||
return ti->creation_func();
|
return ti->creation_func();
|
||||||
}
|
}
|
||||||
bool ObjectTypeDB::can_instance(const StringName &p_type) {
|
bool ObjectTypeDB::can_instance(const StringName &p_type) {
|
||||||
|
|
||||||
OBJTYPE_LOCK;
|
OBJTYPE_LOCK;
|
||||||
|
|
||||||
TypeInfo *ti = types.getptr(p_type);
|
TypeInfo *ti = types.getptr(p_type);
|
||||||
ERR_FAIL_COND_V(!ti,false);
|
ERR_FAIL_COND_V(!ti,false);
|
||||||
return (!ti->disabled && ti->creation_func!=NULL);
|
return (!ti->disabled && ti->creation_func!=NULL);
|
||||||
|
@ -326,11 +326,11 @@ void ObjectTypeDB::get_method_list(StringName p_type,List<MethodInfo> *p_methods
|
||||||
|
|
||||||
|
|
||||||
OBJTYPE_LOCK;
|
OBJTYPE_LOCK;
|
||||||
|
|
||||||
TypeInfo *type=types.getptr(p_type);
|
TypeInfo *type=types.getptr(p_type);
|
||||||
|
|
||||||
while(type) {
|
while(type) {
|
||||||
|
|
||||||
if (type->disabled) {
|
if (type->disabled) {
|
||||||
|
|
||||||
if (p_no_inheritance)
|
if (p_no_inheritance)
|
||||||
|
@ -348,14 +348,14 @@ void ObjectTypeDB::get_method_list(StringName p_type,List<MethodInfo> *p_methods
|
||||||
}
|
}
|
||||||
|
|
||||||
for( List<StringName>::Element *E=type->method_order.front();E;E=E->next()) {
|
for( List<StringName>::Element *E=type->method_order.front();E;E=E->next()) {
|
||||||
|
|
||||||
MethodBind *method=type->method_map.get(E->get());
|
MethodBind *method=type->method_map.get(E->get());
|
||||||
MethodInfo minfo;
|
MethodInfo minfo;
|
||||||
minfo.name=E->get();
|
minfo.name=E->get();
|
||||||
minfo.id=method->get_method_id();
|
minfo.id=method->get_method_id();
|
||||||
|
|
||||||
for (int i=0;i<method->get_argument_count();i++) {
|
for (int i=0;i<method->get_argument_count();i++) {
|
||||||
|
|
||||||
//Variant::Type t=method->get_argument_type(i);
|
//Variant::Type t=method->get_argument_type(i);
|
||||||
|
|
||||||
minfo.arguments.push_back(method->get_argument_info(i));
|
minfo.arguments.push_back(method->get_argument_info(i));
|
||||||
|
@ -386,24 +386,24 @@ void ObjectTypeDB::get_method_list(StringName p_type,List<MethodInfo> *p_methods
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (p_no_inheritance)
|
if (p_no_inheritance)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
type=type->inherits_ptr;
|
type=type->inherits_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MethodBind *ObjectTypeDB::get_method(StringName p_type, StringName p_name) {
|
MethodBind *ObjectTypeDB::get_method(StringName p_type, StringName p_name) {
|
||||||
|
|
||||||
OBJTYPE_LOCK;
|
OBJTYPE_LOCK;
|
||||||
|
|
||||||
TypeInfo *type=types.getptr(p_type);
|
TypeInfo *type=types.getptr(p_type);
|
||||||
|
|
||||||
while(type) {
|
while(type) {
|
||||||
|
|
||||||
MethodBind **method=type->method_map.getptr(p_name);
|
MethodBind **method=type->method_map.getptr(p_name);
|
||||||
if (method && *method)
|
if (method && *method)
|
||||||
return *method;
|
return *method;
|
||||||
|
@ -416,18 +416,18 @@ MethodBind *ObjectTypeDB::get_method(StringName p_type, StringName p_name) {
|
||||||
void ObjectTypeDB::bind_integer_constant(const StringName& p_type, const StringName &p_name, int p_constant) {
|
void ObjectTypeDB::bind_integer_constant(const StringName& p_type, const StringName &p_name, int p_constant) {
|
||||||
|
|
||||||
OBJTYPE_LOCK;
|
OBJTYPE_LOCK;
|
||||||
|
|
||||||
TypeInfo *type=types.getptr(p_type);
|
TypeInfo *type=types.getptr(p_type);
|
||||||
if (!type) {
|
if (!type) {
|
||||||
|
|
||||||
ERR_FAIL_COND(!type);
|
ERR_FAIL_COND(!type);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type->constant_map.has(p_name)) {
|
if (type->constant_map.has(p_name)) {
|
||||||
|
|
||||||
ERR_FAIL();
|
ERR_FAIL();
|
||||||
}
|
}
|
||||||
|
|
||||||
type->constant_map[p_name]=p_constant;
|
type->constant_map[p_name]=p_constant;
|
||||||
#ifdef DEBUG_METHODS_ENABLED
|
#ifdef DEBUG_METHODS_ENABLED
|
||||||
type->constant_order.push_back(p_name);
|
type->constant_order.push_back(p_name);
|
||||||
|
@ -438,11 +438,11 @@ void ObjectTypeDB::bind_integer_constant(const StringName& p_type, const StringN
|
||||||
void ObjectTypeDB::get_integer_constant_list(const StringName& p_type, List<String> *p_constants, bool p_no_inheritance) {
|
void ObjectTypeDB::get_integer_constant_list(const StringName& p_type, List<String> *p_constants, bool p_no_inheritance) {
|
||||||
|
|
||||||
OBJTYPE_LOCK;
|
OBJTYPE_LOCK;
|
||||||
|
|
||||||
TypeInfo *type=types.getptr(p_type);
|
TypeInfo *type=types.getptr(p_type);
|
||||||
|
|
||||||
while(type) {
|
while(type) {
|
||||||
|
|
||||||
#ifdef DEBUG_METHODS_ENABLED
|
#ifdef DEBUG_METHODS_ENABLED
|
||||||
for(List<StringName>::Element *E=type->constant_order.front();E;E=E->next())
|
for(List<StringName>::Element *E=type->constant_order.front();E;E=E->next())
|
||||||
p_constants->push_back(E->get());
|
p_constants->push_back(E->get());
|
||||||
|
@ -456,7 +456,7 @@ void ObjectTypeDB::get_integer_constant_list(const StringName& p_type, List<Stri
|
||||||
#endif
|
#endif
|
||||||
if (p_no_inheritance)
|
if (p_no_inheritance)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
type=type->inherits_ptr;
|
type=type->inherits_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -466,28 +466,28 @@ void ObjectTypeDB::get_integer_constant_list(const StringName& p_type, List<Stri
|
||||||
int ObjectTypeDB::get_integer_constant(const StringName& p_type, const StringName &p_name, bool *p_success) {
|
int ObjectTypeDB::get_integer_constant(const StringName& p_type, const StringName &p_name, bool *p_success) {
|
||||||
|
|
||||||
OBJTYPE_LOCK;
|
OBJTYPE_LOCK;
|
||||||
|
|
||||||
|
|
||||||
TypeInfo *type=types.getptr(p_type);
|
TypeInfo *type=types.getptr(p_type);
|
||||||
|
|
||||||
while(type) {
|
while(type) {
|
||||||
|
|
||||||
|
|
||||||
int *constant=type->constant_map.getptr(p_name);
|
int *constant=type->constant_map.getptr(p_name);
|
||||||
if (constant) {
|
if (constant) {
|
||||||
|
|
||||||
if (p_success)
|
if (p_success)
|
||||||
*p_success=true;
|
*p_success=true;
|
||||||
return *constant;
|
return *constant;
|
||||||
}
|
}
|
||||||
|
|
||||||
type=type->inherits_ptr;
|
type=type->inherits_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p_success)
|
|
||||||
*p_success=false;
|
|
||||||
|
|
||||||
return 0;
|
if (p_success)
|
||||||
|
*p_success=false;
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjectTypeDB::add_signal(StringName p_type,const MethodInfo& p_signal) {
|
void ObjectTypeDB::add_signal(StringName p_type,const MethodInfo& p_signal) {
|
||||||
|
@ -966,7 +966,7 @@ void ObjectTypeDB::init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjectTypeDB::cleanup() {
|
void ObjectTypeDB::cleanup() {
|
||||||
|
|
||||||
|
|
||||||
#ifndef NO_THREADS
|
#ifndef NO_THREADS
|
||||||
|
|
||||||
|
@ -974,19 +974,19 @@ void ObjectTypeDB::cleanup() {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//OBJTYPE_LOCK; hah not here
|
//OBJTYPE_LOCK; hah not here
|
||||||
|
|
||||||
const StringName *k=NULL;
|
const StringName *k=NULL;
|
||||||
|
|
||||||
while((k=types.next(k))) {
|
while((k=types.next(k))) {
|
||||||
|
|
||||||
TypeInfo &ti=types[*k];
|
TypeInfo &ti=types[*k];
|
||||||
|
|
||||||
const StringName *m=NULL;
|
const StringName *m=NULL;
|
||||||
while((m=ti.method_map.next(m))) {
|
while((m=ti.method_map.next(m))) {
|
||||||
|
|
||||||
memdelete( ti.method_map[*m] );
|
memdelete( ti.method_map[*m] );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
types.clear();
|
types.clear();
|
||||||
resource_base_extensions.clear();
|
resource_base_extensions.clear();
|
||||||
compat_types.clear();
|
compat_types.clear();
|
||||||
|
|
|
@ -42,9 +42,9 @@ struct ParamHint {
|
||||||
PropertyHint hint;
|
PropertyHint hint;
|
||||||
String hint_text;
|
String hint_text;
|
||||||
Variant default_val;
|
Variant default_val;
|
||||||
|
|
||||||
ParamHint(const String& p_name="", PropertyHint p_hint=PROPERTY_HINT_NONE, const String& p_hint_text="",Variant p_default_val=Variant()) {
|
ParamHint(const String& p_name="", PropertyHint p_hint=PROPERTY_HINT_NONE, const String& p_hint_text="",Variant p_default_val=Variant()) {
|
||||||
|
|
||||||
name=p_name;
|
name=p_name;
|
||||||
hint=p_hint;
|
hint=p_hint;
|
||||||
hint_text=p_hint_text;
|
hint_text=p_hint_text;
|
||||||
|
@ -73,9 +73,9 @@ struct MethodDefinition {
|
||||||
|
|
||||||
StringName name;
|
StringName name;
|
||||||
Vector<StringName> args;
|
Vector<StringName> args;
|
||||||
MethodDefinition() {}
|
MethodDefinition() {}
|
||||||
MethodDefinition(const char *p_name) { name=p_name; }
|
MethodDefinition(const char *p_name) { name=p_name; }
|
||||||
MethodDefinition(const StringName& p_name) { name=p_name; }
|
MethodDefinition(const StringName& p_name) { name=p_name; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -109,7 +109,7 @@ static _FORCE_INLINE_ const char* _MD(const char* m_name, ...) { return m_name;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class ObjectTypeDB {
|
class ObjectTypeDB {
|
||||||
|
|
||||||
struct PropertySetGet {
|
struct PropertySetGet {
|
||||||
|
|
||||||
int index;
|
int index;
|
||||||
|
@ -121,7 +121,7 @@ class ObjectTypeDB {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TypeInfo {
|
struct TypeInfo {
|
||||||
|
|
||||||
TypeInfo *inherits_ptr;
|
TypeInfo *inherits_ptr;
|
||||||
HashMap<StringName,MethodBind*,StringNameHasher> method_map;
|
HashMap<StringName,MethodBind*,StringNameHasher> method_map;
|
||||||
HashMap<StringName,int,StringNameHasher> constant_map;
|
HashMap<StringName,int,StringNameHasher> constant_map;
|
||||||
|
@ -143,12 +143,12 @@ class ObjectTypeDB {
|
||||||
TypeInfo();
|
TypeInfo();
|
||||||
~TypeInfo();
|
~TypeInfo();
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
static Object *creator() {
|
static Object *creator() {
|
||||||
return memnew( T );
|
return memnew( T );
|
||||||
}
|
}
|
||||||
|
|
||||||
static Mutex *lock;
|
static Mutex *lock;
|
||||||
static HashMap<StringName,TypeInfo,StringNameHasher> types;
|
static HashMap<StringName,TypeInfo,StringNameHasher> types;
|
||||||
static HashMap<StringName,StringName,StringNameHasher> resource_base_extensions;
|
static HashMap<StringName,StringName,StringNameHasher> resource_base_extensions;
|
||||||
|
@ -163,8 +163,8 @@ class ObjectTypeDB {
|
||||||
|
|
||||||
|
|
||||||
static void _add_type2(const StringName& p_type, const StringName& p_inherits);
|
static void _add_type2(const StringName& p_type, const StringName& p_inherits);
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// DO NOT USE THIS!!!!!! NEEDS TO BE PUBLIC BUT DO NOT USE NO MATTER WHAT!!!
|
// DO NOT USE THIS!!!!!! NEEDS TO BE PUBLIC BUT DO NOT USE NO MATTER WHAT!!!
|
||||||
template<class T>
|
template<class T>
|
||||||
static void _add_type() {
|
static void _add_type() {
|
||||||
|
@ -195,7 +195,7 @@ public:
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
static void register_type() {
|
static void register_type() {
|
||||||
|
|
||||||
GLOBAL_LOCK_FUNCTION;
|
GLOBAL_LOCK_FUNCTION;
|
||||||
T::initialize_type();
|
T::initialize_type();
|
||||||
TypeInfo *t=types.getptr(T::get_type_static());
|
TypeInfo *t=types.getptr(T::get_type_static());
|
||||||
|
@ -206,7 +206,7 @@ public:
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
static void register_virtual_type() {
|
static void register_virtual_type() {
|
||||||
|
|
||||||
GLOBAL_LOCK_FUNCTION;
|
GLOBAL_LOCK_FUNCTION;
|
||||||
T::initialize_type();
|
T::initialize_type();
|
||||||
//nothing
|
//nothing
|
||||||
|
@ -247,9 +247,9 @@ public:
|
||||||
ParamDef d4=ParamDef(),
|
ParamDef d4=ParamDef(),
|
||||||
ParamDef d5=ParamDef()
|
ParamDef d5=ParamDef()
|
||||||
) {
|
) {
|
||||||
|
|
||||||
return bind_methodf(METHOD_FLAGS_DEFAULT,p_method_name, p_method, d1,d2,d3,d4,d5);
|
return bind_methodf(METHOD_FLAGS_DEFAULT,p_method_name, p_method, d1,d2,d3,d4,d5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -472,7 +472,7 @@ public:
|
||||||
|
|
||||||
static void add_virtual_method(const StringName& p_type,const MethodInfo& p_method,bool p_virtual=true );
|
static void add_virtual_method(const StringName& p_type,const MethodInfo& p_method,bool p_virtual=true );
|
||||||
static void get_virtual_methods(const StringName& p_type,List<MethodInfo> * p_methods,bool p_no_inheritance=false );
|
static void get_virtual_methods(const StringName& p_type,List<MethodInfo> * p_methods,bool p_no_inheritance=false );
|
||||||
|
|
||||||
static void bind_integer_constant(const StringName& p_type, const StringName &p_name, int p_constant);
|
static void bind_integer_constant(const StringName& p_type, const StringName &p_name, int p_constant);
|
||||||
static void get_integer_constant_list(const StringName& p_type, List<String> *p_constants, bool p_no_inheritance=false);
|
static void get_integer_constant_list(const StringName& p_type, List<String> *p_constants, bool p_no_inheritance=false);
|
||||||
static int get_integer_constant(const StringName& p_type, const StringName &p_name, bool *p_success=NULL);
|
static int get_integer_constant(const StringName& p_type, const StringName &p_name, bool *p_success=NULL);
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
|
|
||||||
void movemem_system(void *to, void *from,int amount) {
|
void movemem_system(void *to, void *from,int amount) {
|
||||||
|
|
||||||
memmove(to,from,amount);
|
memmove(to,from,amount);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -344,7 +344,7 @@ DirAccess *DirAccess::open(const String& p_path,Error *r_error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
DirAccess *DirAccess::create(AccessType p_access) {
|
DirAccess *DirAccess::create(AccessType p_access) {
|
||||||
|
|
||||||
DirAccess * da = create_func[p_access]?create_func[p_access]():NULL;
|
DirAccess * da = create_func[p_access]?create_func[p_access]():NULL;
|
||||||
if (da) {
|
if (da) {
|
||||||
da->_access_type=p_access;
|
da->_access_type=p_access;
|
||||||
|
@ -359,7 +359,7 @@ String DirAccess::get_full_path(const String& p_path,AccessType p_access) {
|
||||||
DirAccess *d=DirAccess::create(p_access);
|
DirAccess *d=DirAccess::create(p_access);
|
||||||
if (!d)
|
if (!d)
|
||||||
return p_path;
|
return p_path;
|
||||||
|
|
||||||
d->change_dir(p_path);
|
d->change_dir(p_path);
|
||||||
String full=d->get_current_dir();
|
String full=d->get_current_dir();
|
||||||
memdelete(d);
|
memdelete(d);
|
||||||
|
@ -367,31 +367,31 @@ String DirAccess::get_full_path(const String& p_path,AccessType p_access) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Error DirAccess::copy(String p_from,String p_to) {
|
Error DirAccess::copy(String p_from,String p_to) {
|
||||||
|
|
||||||
//printf("copy %s -> %s\n",p_from.ascii().get_data(),p_to.ascii().get_data());
|
//printf("copy %s -> %s\n",p_from.ascii().get_data(),p_to.ascii().get_data());
|
||||||
Error err;
|
Error err;
|
||||||
FileAccess *fsrc = FileAccess::open(p_from, FileAccess::READ,&err);
|
FileAccess *fsrc = FileAccess::open(p_from, FileAccess::READ,&err);
|
||||||
|
|
||||||
if (err) {
|
if (err) {
|
||||||
|
|
||||||
ERR_FAIL_COND_V( err, err );
|
ERR_FAIL_COND_V( err, err );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
FileAccess *fdst = FileAccess::open(p_to, FileAccess::WRITE,&err );
|
FileAccess *fdst = FileAccess::open(p_to, FileAccess::WRITE,&err );
|
||||||
if (err) {
|
if (err) {
|
||||||
|
|
||||||
fsrc->close();
|
fsrc->close();
|
||||||
memdelete( fsrc );
|
memdelete( fsrc );
|
||||||
ERR_FAIL_COND_V( err, err );
|
ERR_FAIL_COND_V( err, err );
|
||||||
}
|
}
|
||||||
|
|
||||||
fsrc->seek_end(0);
|
fsrc->seek_end(0);
|
||||||
int size = fsrc->get_pos();
|
int size = fsrc->get_pos();
|
||||||
fsrc->seek(0);
|
fsrc->seek(0);
|
||||||
err = OK;
|
err = OK;
|
||||||
while(size--) {
|
while(size--) {
|
||||||
|
|
||||||
if (fsrc->get_error()!=OK) {
|
if (fsrc->get_error()!=OK) {
|
||||||
err= fsrc->get_error();
|
err= fsrc->get_error();
|
||||||
break;
|
break;
|
||||||
|
@ -400,13 +400,13 @@ Error DirAccess::copy(String p_from,String p_to) {
|
||||||
err= fdst->get_error();
|
err= fdst->get_error();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
fdst->store_8( fsrc->get_8() );
|
fdst->store_8( fsrc->get_8() );
|
||||||
}
|
}
|
||||||
|
|
||||||
memdelete(fsrc);
|
memdelete(fsrc);
|
||||||
memdelete(fdst);
|
memdelete(fdst);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -79,13 +79,13 @@ public:
|
||||||
virtual String get_next()=0;
|
virtual String get_next()=0;
|
||||||
virtual bool current_is_dir() const=0;
|
virtual bool current_is_dir() const=0;
|
||||||
virtual bool current_is_hidden() const=0;
|
virtual bool current_is_hidden() const=0;
|
||||||
|
|
||||||
virtual void list_dir_end()=0; ///<
|
virtual void list_dir_end()=0; ///<
|
||||||
|
|
||||||
virtual int get_drive_count()=0;
|
virtual int get_drive_count()=0;
|
||||||
virtual String get_drive(int p_drive)=0;
|
virtual String get_drive(int p_drive)=0;
|
||||||
virtual int get_current_drive();
|
virtual int get_current_drive();
|
||||||
|
|
||||||
virtual Error change_dir(String p_dir)=0; ///< can be relative or absolute, return false on success
|
virtual Error change_dir(String p_dir)=0; ///< can be relative or absolute, return false on success
|
||||||
virtual String get_current_dir()=0; ///< return current dir location
|
virtual String get_current_dir()=0; ///< return current dir location
|
||||||
virtual Error make_dir(String p_dir)=0;
|
virtual Error make_dir(String p_dir)=0;
|
||||||
|
@ -100,7 +100,7 @@ public:
|
||||||
virtual Error copy(String p_from,String p_to);
|
virtual Error copy(String p_from,String p_to);
|
||||||
virtual Error rename(String p_from, String p_to)=0;
|
virtual Error rename(String p_from, String p_to)=0;
|
||||||
virtual Error remove(String p_name)=0;
|
virtual Error remove(String p_name)=0;
|
||||||
|
|
||||||
static String get_full_path(const String& p_path,AccessType p_access);
|
static String get_full_path(const String& p_path,AccessType p_access);
|
||||||
static DirAccess *create_for_path(const String& p_path);
|
static DirAccess *create_for_path(const String& p_path);
|
||||||
|
|
||||||
|
@ -111,7 +111,7 @@ public:
|
||||||
FILE_TYPE_FILE,
|
FILE_TYPE_FILE,
|
||||||
FILE_TYPE_DIR,
|
FILE_TYPE_DIR,
|
||||||
};
|
};
|
||||||
|
|
||||||
//virtual DirType get_file_type() const=0;
|
//virtual DirType get_file_type() const=0;
|
||||||
*/
|
*/
|
||||||
static DirAccess *create(AccessType p_access);
|
static DirAccess *create(AccessType p_access);
|
||||||
|
|
|
@ -169,69 +169,69 @@ String FileAccess::fix_path(const String& p_path) const {
|
||||||
return r_path;
|
return r_path;
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return r_path;
|
return r_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* these are all implemented for ease of porting, then can later be optimized */
|
/* these are all implemented for ease of porting, then can later be optimized */
|
||||||
|
|
||||||
uint16_t FileAccess::get_16()const {
|
uint16_t FileAccess::get_16()const {
|
||||||
|
|
||||||
uint16_t res;
|
uint16_t res;
|
||||||
uint8_t a,b;
|
uint8_t a,b;
|
||||||
|
|
||||||
a=get_8();
|
a=get_8();
|
||||||
b=get_8();
|
b=get_8();
|
||||||
|
|
||||||
if (endian_swap) {
|
if (endian_swap) {
|
||||||
|
|
||||||
SWAP( a,b );
|
SWAP( a,b );
|
||||||
}
|
}
|
||||||
|
|
||||||
res=b;
|
res=b;
|
||||||
res<<=8;
|
res<<=8;
|
||||||
res|=a;
|
res|=a;
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
uint32_t FileAccess::get_32() const{
|
uint32_t FileAccess::get_32() const{
|
||||||
|
|
||||||
uint32_t res;
|
uint32_t res;
|
||||||
uint16_t a,b;
|
uint16_t a,b;
|
||||||
|
|
||||||
a=get_16();
|
a=get_16();
|
||||||
b=get_16();
|
b=get_16();
|
||||||
|
|
||||||
if (endian_swap) {
|
if (endian_swap) {
|
||||||
|
|
||||||
SWAP( a,b );
|
SWAP( a,b );
|
||||||
}
|
}
|
||||||
|
|
||||||
res=b;
|
res=b;
|
||||||
res<<=16;
|
res<<=16;
|
||||||
res|=a;
|
res|=a;
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
uint64_t FileAccess::get_64()const {
|
uint64_t FileAccess::get_64()const {
|
||||||
|
|
||||||
uint64_t res;
|
uint64_t res;
|
||||||
uint32_t a,b;
|
uint32_t a,b;
|
||||||
|
|
||||||
a=get_32();
|
a=get_32();
|
||||||
b=get_32();
|
b=get_32();
|
||||||
|
|
||||||
if (endian_swap) {
|
if (endian_swap) {
|
||||||
|
|
||||||
SWAP( a,b );
|
SWAP( a,b );
|
||||||
}
|
}
|
||||||
|
|
||||||
res=b;
|
res=b;
|
||||||
res<<=32;
|
res<<=32;
|
||||||
res|=a;
|
res|=a;
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float FileAccess::get_float() const {
|
float FileAccess::get_float() const {
|
||||||
|
@ -262,15 +262,15 @@ String FileAccess::get_line() const {
|
||||||
CharString line;
|
CharString line;
|
||||||
|
|
||||||
CharType c=get_8();
|
CharType c=get_8();
|
||||||
|
|
||||||
while(!eof_reached()) {
|
while(!eof_reached()) {
|
||||||
|
|
||||||
if (c=='\n' || c=='\0') {
|
if (c=='\n' || c=='\0') {
|
||||||
line.push_back(0);
|
line.push_back(0);
|
||||||
return String::utf8(line.get_data());
|
return String::utf8(line.get_data());
|
||||||
} else if (c!='\r')
|
} else if (c!='\r')
|
||||||
line.push_back(c);
|
line.push_back(c);
|
||||||
|
|
||||||
c=get_8();
|
c=get_8();
|
||||||
}
|
}
|
||||||
line.push_back(0);
|
line.push_back(0);
|
||||||
|
@ -284,7 +284,7 @@ Vector<String> FileAccess::get_csv_line(String delim) const {
|
||||||
String l;
|
String l;
|
||||||
int qc=0;
|
int qc=0;
|
||||||
do {
|
do {
|
||||||
l+=get_line();
|
l+=get_line()+"\n";
|
||||||
qc=0;
|
qc=0;
|
||||||
for(int i=0;i<l.length();i++) {
|
for(int i=0;i<l.length();i++) {
|
||||||
|
|
||||||
|
@ -295,6 +295,8 @@ Vector<String> FileAccess::get_csv_line(String delim) const {
|
||||||
|
|
||||||
} while (qc%2);
|
} while (qc%2);
|
||||||
|
|
||||||
|
l=l.substr(0, l.length()-1);
|
||||||
|
|
||||||
Vector<String> strings;
|
Vector<String> strings;
|
||||||
|
|
||||||
bool in_quote=false;
|
bool in_quote=false;
|
||||||
|
@ -331,7 +333,7 @@ Vector<String> FileAccess::get_csv_line(String delim) const {
|
||||||
|
|
||||||
|
|
||||||
int FileAccess::get_buffer(uint8_t *p_dst,int p_length) const{
|
int FileAccess::get_buffer(uint8_t *p_dst,int p_length) const{
|
||||||
|
|
||||||
int i=0;
|
int i=0;
|
||||||
for (i=0; i<p_length && !eof_reached(); i++)
|
for (i=0; i<p_length && !eof_reached(); i++)
|
||||||
p_dst[i]=get_8();
|
p_dst[i]=get_8();
|
||||||
|
@ -340,53 +342,53 @@ int FileAccess::get_buffer(uint8_t *p_dst,int p_length) const{
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileAccess::store_16(uint16_t p_dest) {
|
void FileAccess::store_16(uint16_t p_dest) {
|
||||||
|
|
||||||
uint8_t a,b;
|
uint8_t a,b;
|
||||||
|
|
||||||
a=p_dest&0xFF;
|
a=p_dest&0xFF;
|
||||||
b=p_dest>>8;
|
b=p_dest>>8;
|
||||||
|
|
||||||
if (endian_swap) {
|
if (endian_swap) {
|
||||||
|
|
||||||
SWAP( a,b );
|
SWAP( a,b );
|
||||||
}
|
}
|
||||||
|
|
||||||
store_8(a);
|
store_8(a);
|
||||||
store_8(b);
|
store_8(b);
|
||||||
|
|
||||||
}
|
}
|
||||||
void FileAccess::store_32(uint32_t p_dest) {
|
void FileAccess::store_32(uint32_t p_dest) {
|
||||||
|
|
||||||
|
|
||||||
uint16_t a,b;
|
uint16_t a,b;
|
||||||
|
|
||||||
a=p_dest&0xFFFF;
|
a=p_dest&0xFFFF;
|
||||||
b=p_dest>>16;
|
b=p_dest>>16;
|
||||||
|
|
||||||
if (endian_swap) {
|
if (endian_swap) {
|
||||||
|
|
||||||
SWAP( a,b );
|
SWAP( a,b );
|
||||||
}
|
}
|
||||||
|
|
||||||
store_16(a);
|
store_16(a);
|
||||||
store_16(b);
|
store_16(b);
|
||||||
|
|
||||||
}
|
}
|
||||||
void FileAccess::store_64(uint64_t p_dest) {
|
void FileAccess::store_64(uint64_t p_dest) {
|
||||||
|
|
||||||
uint32_t a,b;
|
uint32_t a,b;
|
||||||
|
|
||||||
a=p_dest&0xFFFFFFFF;
|
a=p_dest&0xFFFFFFFF;
|
||||||
b=p_dest>>32;
|
b=p_dest>>32;
|
||||||
|
|
||||||
if (endian_swap) {
|
if (endian_swap) {
|
||||||
|
|
||||||
SWAP( a,b );
|
SWAP( a,b );
|
||||||
}
|
}
|
||||||
|
|
||||||
store_32(a);
|
store_32(a);
|
||||||
store_32(b);
|
store_32(b);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileAccess::store_real(real_t p_real) {
|
void FileAccess::store_real(real_t p_real) {
|
||||||
|
@ -461,7 +463,7 @@ void FileAccess::store_line(const String& p_line) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileAccess::store_buffer(const uint8_t *p_src,int p_length) {
|
void FileAccess::store_buffer(const uint8_t *p_src,int p_length) {
|
||||||
|
|
||||||
for (int i=0;i<p_length;i++)
|
for (int i=0;i<p_length;i++)
|
||||||
store_8(p_src[i]);
|
store_8(p_src[i]);
|
||||||
}
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue