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/android/logo.h
|
||||
platform/bb10/logo.h
|
||||
platform/iphone/logo.h
|
||||
platform/javascript/logo.h
|
||||
platform/nacl/logo.h
|
||||
platform/osx/logo.h
|
||||
platform/windows/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/doc_data_compressed.h
|
||||
tools/editor/editor_icons.cpp
|
||||
-fpic
|
||||
tools/editor/builtin_fonts.h
|
||||
tools/editor/certs_compressed.h
|
||||
tools/editor/translations.h
|
||||
.fscache
|
||||
make.bat
|
||||
log.txt
|
||||
|
@ -31,6 +32,7 @@ doc/_build/
|
|||
*.bc
|
||||
|
||||
# Android specific
|
||||
platform/android/java/build.gradle
|
||||
platform/android/java/.gradle
|
||||
platform/android/java/.gradletasknamecache
|
||||
platform/android/java/local.properties
|
||||
|
@ -145,6 +147,8 @@ ipch/
|
|||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
*.VC.db
|
||||
*.VC.VC.opendb
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
|
|
38
.travis.yml
38
.travis.yml
|
@ -1,7 +1,6 @@
|
|||
language: cpp
|
||||
|
||||
sudo: required
|
||||
dist: trusty
|
||||
sudo: false
|
||||
|
||||
compiler:
|
||||
- gcc
|
||||
|
@ -41,12 +40,39 @@ matrix:
|
|||
- compiler: clang
|
||||
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:
|
||||
- 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" ] && [ "$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:
|
||||
- scons platform=$GODOT_TARGET CXX=$CXX
|
||||
- scons platform=$GODOT_TARGET CXX=$CXX openssl=builtin
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
![GODOT](/logo.png)
|
||||
|
||||
http://www.godotengine.org
|
||||
https://godotengine.org
|
||||
|
||||
### The Engine
|
||||
|
||||
|
@ -13,17 +13,17 @@ Godot has been developed by Juan Linietsky and Ariel Manzur for several years, a
|
|||
|
||||
### 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. can be found in Godot homepage:
|
||||
|
||||
http://www.godotengine.org
|
||||
https://godotengine.org
|
||||
|
||||
### 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
|
||||
|
||||
[![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=[]
|
||||
|
||||
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
|
||||
tmppath="./"+x
|
||||
|
||||
|
@ -63,9 +63,9 @@ elif (os.name=="nt"):
|
|||
if (os.getenv("VSINSTALLDIR")==None or platform_arg=="android"):
|
||||
custom_tools=['mingw']
|
||||
|
||||
env_base=Environment(tools=custom_tools,ENV = {'PATH' : os.environ['PATH']});
|
||||
|
||||
#env_base=Environment(tools=custom_tools);
|
||||
env_base=Environment(tools=custom_tools);
|
||||
env_base.AppendENVPath('PATH', os.getenv('PATH'))
|
||||
env_base.AppendENVPath('PKG_CONFIG_PATH', os.getenv('PKG_CONFIG_PATH'))
|
||||
env_base.global_defaults=global_defaults
|
||||
env_base.android_maven_repos=[]
|
||||
env_base.android_dependencies=[]
|
||||
|
@ -112,7 +112,8 @@ if profile:
|
|||
|
||||
opts=Variables(customs, ARGUMENTS)
|
||||
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('p','Platform (same as platform=).',"")
|
||||
opts.Add('tools','Build Tools (Including Editor): (yes/no)','yes')
|
||||
|
@ -267,10 +268,14 @@ if selected_platform in platform_list:
|
|||
else:
|
||||
suffix+=".debug"
|
||||
|
||||
if (env["bits"]=="32"):
|
||||
if env["arch"] != "":
|
||||
suffix += "."+env["arch"]
|
||||
elif (env["bits"]=="32"):
|
||||
suffix+=".32"
|
||||
elif (env["bits"]=="64"):
|
||||
suffix+=".64"
|
||||
elif (env["bits"]=="fat"):
|
||||
suffix+=".fat"
|
||||
|
||||
suffix+=env.extra_suffix
|
||||
|
||||
|
@ -302,10 +307,10 @@ if selected_platform in platform_list:
|
|||
if (env['musepack']=='yes'):
|
||||
env.Append(CPPFLAGS=['-DMUSEPACK_ENABLED']);
|
||||
|
||||
if (env['openssl']!='no'):
|
||||
env.Append(CPPFLAGS=['-DOPENSSL_ENABLED']);
|
||||
if (env['openssl']=="builtin"):
|
||||
env.Append(CPPPATH=['#drivers/builtin_openssl2'])
|
||||
#if (env['openssl']!='no'):
|
||||
# env.Append(CPPFLAGS=['-DOPENSSL_ENABLED']);
|
||||
# if (env['openssl']=="builtin"):
|
||||
# env.Append(CPPPATH=['#drivers/builtin_openssl2'])
|
||||
|
||||
if (env["builtin_zlib"]=='yes'):
|
||||
env.Append(CPPPATH=['#drivers/builtin_zlib/zlib'])
|
||||
|
@ -324,7 +329,7 @@ if selected_platform in platform_list:
|
|||
|
||||
if (env['theora']=='yes'):
|
||||
env['theoralib']='yes'
|
||||
env.Append(CPPFLAGS=['-DTHEORA_ENABLED']);
|
||||
env.Append(CPPFLAGS=['-DTHEORA_ENABLED']);
|
||||
if (env['theoralib']=='yes'):
|
||||
env.Append(CPPFLAGS=['-DTHEORALIB_ENABLED']);
|
||||
|
||||
|
@ -389,14 +394,25 @@ if selected_platform in platform_list:
|
|||
AddToVSProject(env.servers_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['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"
|
||||
|
||||
debug_variants = ['Debug|Win32']+['Debug|x64']
|
||||
release_variants = ['Release|Win32']+['Release|x64']
|
||||
release_debug_variants = ['Release_Debug|Win32']+['Release_Debug|x64']
|
||||
|
||||
|
||||
# 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
|
||||
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'
|
||||
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'
|
||||
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
|
||||
debug_targets = ['Debug']+['Debug']
|
||||
release_targets = ['Release']+['Release']
|
||||
|
|
|
@ -44,9 +44,9 @@ MainLoop * test() {
|
|||
|
||||
/*
|
||||
HashMap<int,int> int_map;
|
||||
|
||||
|
||||
for (int i=0;i<68000;i++) {
|
||||
|
||||
|
||||
int num=(int)Math::random(0,1024);
|
||||
int_map[i]=num;
|
||||
}
|
||||
|
@ -70,21 +70,21 @@ MainLoop * test() {
|
|||
};
|
||||
|
||||
};
|
||||
|
||||
#if 0
|
||||
|
||||
#if 0
|
||||
Set<int> set;
|
||||
|
||||
|
||||
print_line("Begin Insert");
|
||||
for (int i=0;i<1100;i++) {
|
||||
|
||||
|
||||
int num=i;//(int)Math::random(0,1024);
|
||||
// print_line("inserting "+itos(num));
|
||||
// print_line("inserting "+itos(num));
|
||||
set.insert( num );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
for (int i=0;i<400;i++) {
|
||||
|
||||
|
||||
int num=(int)Math::random(0,1024);
|
||||
set.erase(num);
|
||||
}
|
||||
|
@ -92,11 +92,11 @@ MainLoop * test() {
|
|||
//set.print_tree();
|
||||
|
||||
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("depth is "+itos(set.calculate_depth()));
|
||||
print_line("Insert Success");
|
||||
#endif
|
||||
|
|
|
@ -44,7 +44,7 @@ class TestMainLoop : public MainLoop {
|
|||
RID light;
|
||||
RID mesh;
|
||||
RID scenario;
|
||||
|
||||
|
||||
#define MULTIMESH_COUNT 1500
|
||||
|
||||
float ofs_x,ofs_y;
|
||||
|
@ -122,9 +122,9 @@ public:
|
|||
}
|
||||
|
||||
virtual void input_event(const InputEvent& p_event) {
|
||||
|
||||
|
||||
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_y+=p_event.mouse_motion.relative_x/200.0;
|
||||
}
|
||||
|
@ -142,16 +142,16 @@ public:
|
|||
|
||||
|
||||
}
|
||||
|
||||
|
||||
virtual void request_quit() {
|
||||
|
||||
|
||||
quit=true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
virtual void init() {
|
||||
|
||||
|
||||
VisualServer *vs=VisualServer::get_singleton();
|
||||
|
||||
|
||||
|
@ -163,13 +163,13 @@ public:
|
|||
_update_qh();
|
||||
|
||||
instance = vs->instance_create2(mesh,scenario);
|
||||
|
||||
|
||||
camera = vs->camera_create();
|
||||
|
||||
|
||||
|
||||
vs->camera_set_perspective( camera, 60.0,0.1, 100.0 );
|
||||
viewport = vs->viewport_create();
|
||||
vs->viewport_attach_camera( viewport, camera );
|
||||
vs->viewport_attach_camera( viewport, camera );
|
||||
vs->viewport_attach_to_screen(viewport);
|
||||
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) );
|
||||
light = vs->instance_create2( lightaux,scenario );
|
||||
vs->instance_set_transform(light,Transform(Matrix3(Vector3(0.1,0.4,0.7).normalized(),0.9)));
|
||||
|
||||
|
||||
ofs_x=0;
|
||||
ofs_y=0;
|
||||
quit=false;
|
||||
|
@ -190,20 +190,20 @@ public:
|
|||
}
|
||||
|
||||
virtual bool iteration(float p_time) {
|
||||
|
||||
|
||||
VisualServer *vs=VisualServer::get_singleton();
|
||||
|
||||
|
||||
Transform tr_camera;
|
||||
tr_camera.rotate( Vector3(0,1,0), ofs_y );
|
||||
tr_camera.rotate( Vector3(1,0,0),ofs_x );
|
||||
tr_camera.translate(0,0,10);
|
||||
|
||||
|
||||
vs->camera_set_transform( camera, tr_camera );
|
||||
|
||||
|
||||
return quit;
|
||||
}
|
||||
virtual void finish() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
@ -81,7 +81,7 @@ static String _parser_expr(const GDParser::Node *p_expr) {
|
|||
|
||||
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;
|
||||
} break;
|
||||
case GDParser::Node::TYPE_CONSTANT: {
|
||||
|
|
|
@ -62,16 +62,16 @@ class TestMainLoop : public SceneTree {
|
|||
|
||||
|
||||
Control *control;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
virtual void request_quit() {
|
||||
|
||||
|
||||
quit();
|
||||
|
||||
|
||||
}
|
||||
virtual void init() {
|
||||
|
||||
|
||||
SceneTree::init();
|
||||
|
||||
|
||||
|
@ -112,7 +112,7 @@ public:
|
|||
|
||||
Ref<Theme> t = memnew( Theme );
|
||||
frame->set_theme(t);
|
||||
|
||||
|
||||
get_root()->add_child( frame );
|
||||
|
||||
Label *label = memnew( Label );
|
||||
|
@ -198,21 +198,21 @@ public:
|
|||
//root->add_child( control );
|
||||
|
||||
|
||||
|
||||
|
||||
LineEdit *line_edit = memnew( LineEdit );
|
||||
|
||||
|
||||
line_edit->set_pos( Point2( 30,190 ) );
|
||||
line_edit->set_size( Point2( 180,1 ) );
|
||||
|
||||
|
||||
frame->add_child(line_edit);
|
||||
|
||||
|
||||
HScrollBar *hscroll = memnew( HScrollBar );
|
||||
|
||||
|
||||
hscroll->set_pos( Point2( 30,290 ) );
|
||||
hscroll->set_size( Point2( 180,1 ) );
|
||||
hscroll->set_max(10);
|
||||
hscroll->set_page(4);
|
||||
|
||||
|
||||
frame->add_child(hscroll);
|
||||
|
||||
|
||||
|
@ -234,36 +234,36 @@ public:
|
|||
hscroll->share(progress);
|
||||
|
||||
MenuButton *menu_button = memnew( MenuButton );
|
||||
|
||||
|
||||
menu_button->set_text("I'm a menu!");
|
||||
menu_button->set_pos( Point2( 30,380 ) );
|
||||
menu_button->set_size( Point2( 1,1 ) );
|
||||
|
||||
frame->add_child(menu_button);
|
||||
|
||||
|
||||
frame->add_child(menu_button);
|
||||
|
||||
PopupMenu *popup = menu_button->get_popup();
|
||||
|
||||
|
||||
popup->add_item("Hello, testing");
|
||||
popup->add_item("My Dearest");
|
||||
popup->add_separator();
|
||||
popup->add_item("Popup");
|
||||
popup->add_check_item("Check Popup");
|
||||
popup->set_item_checked(4,true);
|
||||
|
||||
popup->set_item_checked(4,true);
|
||||
|
||||
OptionButton *options = memnew( OptionButton );
|
||||
|
||||
|
||||
options->add_item("Hello, testing");
|
||||
options->add_item("My Dearest");
|
||||
|
||||
|
||||
options->set_pos( Point2( 230,180 ) );
|
||||
options->set_size( Point2( 1,1 ) );
|
||||
|
||||
frame->add_child(options);
|
||||
|
||||
frame->add_child(options);
|
||||
|
||||
/*
|
||||
Tree * tree = memnew( Tree );
|
||||
tree->set_columns(2);
|
||||
|
||||
|
||||
tree->set_pos( Point2( 230,210 ) );
|
||||
tree->set_size( Point2( 150,250 ) );
|
||||
|
||||
|
@ -286,7 +286,7 @@ public:
|
|||
item->set_editable(0,true);
|
||||
item->set_text(0,"Have,Many,Several,Options!");
|
||||
item->set_range(0,2);
|
||||
|
||||
|
||||
frame->add_child(tree);
|
||||
*/
|
||||
|
||||
|
@ -365,11 +365,11 @@ public:
|
|||
tabc->add_child(ctl);
|
||||
|
||||
frame->add_child(tabc);
|
||||
|
||||
|
||||
tabc->set_pos( Point2( 400,210 ) );
|
||||
tabc->set_size( Point2( 180,250 ) );
|
||||
|
||||
|
||||
|
||||
Ref<ImageTexture> text = memnew( ImageTexture );
|
||||
text->load("test_data/concave.png");
|
||||
|
||||
|
@ -387,13 +387,13 @@ public:
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
MainLoop* test() {
|
||||
|
||||
|
||||
|
||||
return memnew( TestMainLoop );
|
||||
}
|
||||
|
||||
|
|
|
@ -47,37 +47,37 @@ namespace TestIO {
|
|||
|
||||
|
||||
class TestMainLoop : public MainLoop {
|
||||
|
||||
|
||||
|
||||
|
||||
bool quit;
|
||||
|
||||
|
||||
public:
|
||||
virtual void input_event(const InputEvent& p_event) {
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
virtual bool idle(float p_time) {
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void request_quit() {
|
||||
|
||||
|
||||
quit=true;
|
||||
|
||||
|
||||
}
|
||||
virtual void init() {
|
||||
|
||||
quit=true;
|
||||
}
|
||||
virtual bool iteration(float p_time) {
|
||||
|
||||
|
||||
return quit;
|
||||
}
|
||||
virtual void finish() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -64,7 +64,7 @@ const char ** tests_get_names() {
|
|||
"physics",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
return test_names;
|
||||
}
|
||||
|
||||
|
@ -72,22 +72,22 @@ MainLoop* test_main(String p_test,const List<String>& p_args) {
|
|||
|
||||
|
||||
if (p_test=="string") {
|
||||
|
||||
|
||||
return TestString::test();
|
||||
}
|
||||
|
||||
|
||||
if (p_test=="containers") {
|
||||
|
||||
|
||||
return TestContainers::test();
|
||||
}
|
||||
|
||||
|
||||
if (p_test=="math") {
|
||||
|
||||
|
||||
return TestMath::test();
|
||||
}
|
||||
|
||||
|
||||
if (p_test=="physics") {
|
||||
|
||||
|
||||
return TestPhysics::test();
|
||||
}
|
||||
|
||||
|
@ -97,15 +97,15 @@ MainLoop* test_main(String p_test,const List<String>& p_args) {
|
|||
}
|
||||
|
||||
if (p_test=="misc") {
|
||||
|
||||
|
||||
return TestMisc::test();
|
||||
}
|
||||
|
||||
if (p_test=="render") {
|
||||
|
||||
|
||||
return TestRender::test();
|
||||
}
|
||||
|
||||
|
||||
#ifndef _3D_DISABLED
|
||||
if (p_test=="gui") {
|
||||
|
||||
|
@ -119,17 +119,17 @@ MainLoop* test_main(String p_test,const List<String>& p_args) {
|
|||
}
|
||||
|
||||
if (p_test=="io") {
|
||||
|
||||
|
||||
return TestIO::test();
|
||||
}
|
||||
|
||||
|
||||
if (p_test=="particles") {
|
||||
|
||||
return TestParticles::test();
|
||||
}
|
||||
|
||||
|
||||
if (p_test=="multimesh") {
|
||||
|
||||
|
||||
return TestMultiMesh::test();
|
||||
}
|
||||
|
||||
|
@ -171,7 +171,7 @@ MainLoop* test_main(String p_test,const List<String>& p_args) {
|
|||
#ifdef PYTHON_ENABLED
|
||||
|
||||
if (p_test=="python") {
|
||||
|
||||
|
||||
return TestPython::test();
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -70,7 +70,7 @@ fix: 0, 0, 49.949951, 50
|
|||
v0: 0, 0, 100, 100
|
||||
v1: 0, 0, 100, 100
|
||||
fix: 0, 0, 100, 100
|
||||
*/
|
||||
*/
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -43,38 +43,38 @@ class TestMainLoop : public MainLoop {
|
|||
RID viewport;
|
||||
RID light;
|
||||
RID scenario;
|
||||
|
||||
|
||||
struct InstanceInfo {
|
||||
|
||||
|
||||
RID instance;
|
||||
Transform base;
|
||||
Vector3 rot_axis;
|
||||
};
|
||||
|
||||
|
||||
List<InstanceInfo> instances;
|
||||
|
||||
|
||||
float ofs;
|
||||
bool quit;
|
||||
public:
|
||||
virtual void input_event(const InputEvent& p_event) {
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
virtual void request_quit() {
|
||||
|
||||
|
||||
quit=true;
|
||||
}
|
||||
virtual void init() {
|
||||
|
||||
|
||||
VisualServer *vs=VisualServer::get_singleton();
|
||||
particles = vs->particles_create();
|
||||
vs->particles_set_amount(particles,1000);
|
||||
|
||||
|
||||
instance = vs->instance_create2(particles,scenario);
|
||||
|
||||
|
||||
|
||||
|
||||
camera = vs->camera_create();
|
||||
|
||||
|
||||
// vs->camera_set_perspective( camera, 60.0,0.1, 100.0 );
|
||||
viewport = vs->viewport_create();
|
||||
vs->viewport_attach_camera( viewport, camera );
|
||||
|
@ -89,7 +89,7 @@ public:
|
|||
RID lightaux = vs->light_create( VisualServer::LIGHT_DIRECTIONAL );
|
||||
// vs->light_set_color( lightaux, VisualServer::LIGHT_COLOR_AMBIENT, Color(0.0,0.0,0.0) );
|
||||
light = vs->instance_create2( lightaux, scenario );
|
||||
|
||||
|
||||
ofs=0;
|
||||
quit=false;
|
||||
}
|
||||
|
@ -99,14 +99,14 @@ public:
|
|||
|
||||
|
||||
virtual bool iteration(float p_time) {
|
||||
|
||||
|
||||
// VisualServer *vs=VisualServer::get_singleton();
|
||||
|
||||
|
||||
ofs+=p_time;
|
||||
return quit;
|
||||
}
|
||||
virtual void finish() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
@ -47,7 +47,7 @@ class TestPhysicsMainLoop : public MainLoop {
|
|||
};
|
||||
|
||||
RID test_cube;
|
||||
|
||||
|
||||
RID plane;
|
||||
RID sphere;
|
||||
RID light;
|
||||
|
@ -74,13 +74,13 @@ class TestPhysicsMainLoop : public MainLoop {
|
|||
//t.basis.scale( Vector3(1.0,0.5,0.2) );
|
||||
vs->instance_set_transform(p_visual_instance,t);
|
||||
}
|
||||
|
||||
|
||||
bool quit;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
static void _bind_methods() {
|
||||
|
||||
|
||||
ObjectTypeDB::bind_method("body_changed_transform",&TestPhysicsMainLoop::body_changed_transform);
|
||||
}
|
||||
|
||||
|
@ -90,11 +90,11 @@ protected:
|
|||
PhysicsServer * ps = PhysicsServer::get_singleton();
|
||||
|
||||
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_param(body,PhysicsServer::BODY_PARAM_BOUNCE,0.0);
|
||||
//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_state( body, PhysicsServer::BODY_STATE_TRANSFORM,p_location);
|
||||
|
@ -289,7 +289,7 @@ protected:
|
|||
|
||||
public:
|
||||
virtual void input_event(const InputEvent& p_event) {
|
||||
|
||||
|
||||
if (p_event.type==InputEvent::MOUSE_MOTION && p_event.mouse_motion.button_mask&4) {
|
||||
|
||||
ofs_y-=p_event.mouse_motion.relative_y/200.0;
|
||||
|
@ -329,7 +329,7 @@ public:
|
|||
}
|
||||
|
||||
virtual void request_quit() {
|
||||
|
||||
|
||||
quit=true;
|
||||
}
|
||||
virtual void init() {
|
||||
|
@ -388,53 +388,53 @@ public:
|
|||
/* Make Trimesh */
|
||||
quit=false;
|
||||
return;
|
||||
|
||||
|
||||
#if 0
|
||||
#define GRID_SIZE 5
|
||||
|
||||
|
||||
float grid[GRID_SIZE][GRID_SIZE];
|
||||
|
||||
|
||||
for (int i=0;i<GRID_SIZE;i++) {
|
||||
|
||||
|
||||
for (int j=0;j<GRID_SIZE;j++) {
|
||||
|
||||
|
||||
grid[j][i]=Math::random(0.0, 1.0 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Vector<Vector3> faces;
|
||||
|
||||
|
||||
for (int i=1;i<GRID_SIZE;i++) {
|
||||
|
||||
|
||||
for (int j=1;j<GRID_SIZE;j++) {
|
||||
|
||||
|
||||
|
||||
|
||||
#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 )
|
||||
|
||||
|
||||
MAKE_VERTEX(i,j-1);
|
||||
MAKE_VERTEX(i,j);
|
||||
MAKE_VERTEX(i-1,j);
|
||||
|
||||
|
||||
MAKE_VERTEX(i-1,j-1);
|
||||
MAKE_VERTEX(i,j-1);
|
||||
MAKE_VERTEX(i-1,j);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
/*
|
||||
faces.clear();
|
||||
faces.clear();
|
||||
faces.push_back( Vector3(0,0,-5) );
|
||||
faces.push_back( Vector3(1,0,-1) );
|
||||
faces.push_back( Vector3(-1,-0,-1) );
|
||||
*/
|
||||
|
||||
|
||||
RID trimesh_shape = ps->shape_create();
|
||||
ps->shape_set_data(trimesh_shape, PhysicsServer::SHAPE_CONCAVE_POLYGON,faces);
|
||||
faces=ps->shape_get_shape(trimesh_shape, 0);
|
||||
Vector<Vector3> normals; // for drawing
|
||||
for (int i=0;i<faces.size()/3;i++) {
|
||||
|
||||
|
||||
Plane p( faces[i*3+0],faces[i*3+1], faces[i*3+2] );
|
||||
normals.push_back(p.normal);
|
||||
normals.push_back(p.normal);
|
||||
|
@ -448,11 +448,11 @@ public:
|
|||
RID trimesh_mat = vs->fixed_material_create();
|
||||
vs->material_generate( trimesh_mat, Color(1.0,0.5,0.3) );
|
||||
vs->mesh_surface_set_material( trimesh_mesh, 0, trimesh_mat );
|
||||
|
||||
|
||||
RID triins = vs->instance_create2(trimesh_mesh);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
RID tribody = ps->body_create( PhysicsServer::BODY_MODE_STATIC, trimesh_shape);
|
||||
Transform tritrans = Transform( Matrix3(), Vector3(0,0,-2) );
|
||||
ps->body_set_state( tribody, PhysicsServer::BODY_STATE_TRANSFORM, tritrans );
|
||||
|
@ -483,7 +483,7 @@ public:
|
|||
return quit;
|
||||
}
|
||||
virtual void finish() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
void test_joint() {
|
||||
|
@ -599,7 +599,7 @@ public:
|
|||
PhysicsServer::ShapeType type=shape_idx[i%4];
|
||||
//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.7+0.0*i,0.5+4.1*i,0);
|
||||
|
|
|
@ -47,7 +47,7 @@ void test() {
|
|||
PyRun_SimpleString("b=Moch();\n");
|
||||
PyRun_SimpleString("b.mooch();\n");
|
||||
PyRun_SimpleString("b.meis();\n");
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -49,16 +49,16 @@ class TestMainLoop : public MainLoop {
|
|||
RID viewport;
|
||||
RID light;
|
||||
RID scenario;
|
||||
|
||||
|
||||
struct InstanceInfo {
|
||||
|
||||
|
||||
RID instance;
|
||||
Transform base;
|
||||
Vector3 rot_axis;
|
||||
};
|
||||
|
||||
|
||||
List<InstanceInfo> instances;
|
||||
|
||||
|
||||
float ofs;
|
||||
bool quit;
|
||||
protected:
|
||||
|
@ -66,13 +66,13 @@ protected:
|
|||
|
||||
public:
|
||||
virtual void input_event(const InputEvent& p_event) {
|
||||
|
||||
|
||||
if (p_event.type==InputEvent::KEY && p_event.key.pressed)
|
||||
quit=true;
|
||||
}
|
||||
|
||||
virtual void init() {
|
||||
|
||||
|
||||
|
||||
print_line("INITIALIZING TEST RENDER");
|
||||
VisualServer *vs=VisualServer::get_singleton();
|
||||
|
@ -150,26 +150,26 @@ public:
|
|||
};
|
||||
|
||||
for (int i=0;i<object_count;i++) {
|
||||
|
||||
|
||||
InstanceInfo ii;
|
||||
|
||||
|
||||
|
||||
|
||||
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.rotate( Vector3(0,1,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();
|
||||
|
||||
|
||||
instances.push_back(ii);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
camera = vs->camera_create();
|
||||
|
||||
|
||||
// vs->camera_set_perspective( camera, 60.0,0.1, 100.0 );
|
||||
|
||||
viewport = vs->viewport_create();
|
||||
|
@ -226,9 +226,9 @@ public:
|
|||
ofs+=p_time*0.05;
|
||||
|
||||
//return quit;
|
||||
|
||||
|
||||
for(List<InstanceInfo>::Element *E=instances.front();E;E=E->next()) {
|
||||
|
||||
|
||||
Transform pre( Matrix3(E->get().rot_axis, ofs), Vector3() );
|
||||
vs->instance_set_transform( E->get().instance, pre * E->get().base );
|
||||
/*
|
||||
|
@ -238,7 +238,7 @@ public:
|
|||
instances.erase(E );
|
||||
}*/
|
||||
}
|
||||
|
||||
|
||||
return quit;
|
||||
}
|
||||
|
||||
|
|
|
@ -290,7 +290,7 @@ MainLoop* test() {
|
|||
|
||||
FileAccess *fa = FileAccess::open(test,FileAccess::READ);
|
||||
|
||||
if (!fa) {
|
||||
if (!fa) {
|
||||
ERR_FAIL_V(NULL);
|
||||
}
|
||||
|
||||
|
|
|
@ -38,145 +38,145 @@
|
|||
namespace TestString {
|
||||
|
||||
bool test_1() {
|
||||
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 1: Assign from cstr\n");
|
||||
|
||||
|
||||
String s = "Hello";
|
||||
|
||||
|
||||
OS::get_singleton()->print("\tExpected: Hello\n");
|
||||
OS::get_singleton()->print("\tResulted: %ls\n",s.c_str());
|
||||
|
||||
|
||||
return (wcscmp(s.c_str(),L"Hello")==0);
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool test_2() {
|
||||
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 2: Assign from string (operator=)\n");
|
||||
|
||||
|
||||
String s = "Dolly";
|
||||
String t = s;
|
||||
|
||||
|
||||
OS::get_singleton()->print("\tExpected: Dolly\n");
|
||||
OS::get_singleton()->print("\tResulted: %ls\n",t.c_str());
|
||||
|
||||
|
||||
return (wcscmp(t.c_str(),L"Dolly")==0);
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool test_3() {
|
||||
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 3: Assign from c-string (copycon)\n");
|
||||
|
||||
|
||||
String s("Sheep");
|
||||
String t(s);
|
||||
|
||||
|
||||
OS::get_singleton()->print("\tExpected: Sheep\n");
|
||||
OS::get_singleton()->print("\tResulted: %ls\n",t.c_str());
|
||||
|
||||
|
||||
return (wcscmp(t.c_str(),L"Sheep")==0);
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool test_4() {
|
||||
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 4: Assign from c-widechar (operator=)\n");
|
||||
|
||||
|
||||
String s(L"Give me");
|
||||
|
||||
|
||||
OS::get_singleton()->print("\tExpected: Give me\n");
|
||||
OS::get_singleton()->print("\tResulted: %ls\n",s.c_str());
|
||||
|
||||
|
||||
return (wcscmp(s.c_str(),L"Give me")==0);
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool test_5() {
|
||||
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 5: Assign from c-widechar (copycon)\n");
|
||||
|
||||
|
||||
String s(L"Wool");
|
||||
|
||||
|
||||
OS::get_singleton()->print("\tExpected: Wool\n");
|
||||
OS::get_singleton()->print("\tResulted: %ls\n",s.c_str());
|
||||
|
||||
|
||||
return (wcscmp(s.c_str(),L"Wool")==0);
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool test_6() {
|
||||
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 6: comparisons (equal)\n");
|
||||
|
||||
|
||||
|
||||
|
||||
String s="Test Compare";
|
||||
|
||||
|
||||
OS::get_singleton()->print("\tComparing to \"Test Compare\"\n");
|
||||
|
||||
|
||||
if (! ( s=="Test Compare" ) )
|
||||
return false;
|
||||
|
||||
|
||||
if (! ( s==L"Test Compare" ) )
|
||||
return false;
|
||||
|
||||
|
||||
if (! ( s==String("Test Compare") ) )
|
||||
return false;
|
||||
|
||||
|
||||
return true;
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool test_7() {
|
||||
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 7: comparisons (unequal)\n");
|
||||
|
||||
|
||||
|
||||
|
||||
String s="Test Compare";
|
||||
|
||||
|
||||
OS::get_singleton()->print("\tComparing to \"Test Compare\"\n");
|
||||
|
||||
|
||||
if (! ( s!="Peanut" ) )
|
||||
return false;
|
||||
|
||||
|
||||
if (! ( s!=L"Coconut" ) )
|
||||
return false;
|
||||
|
||||
|
||||
if (! ( s!=String("Butter") ) )
|
||||
return false;
|
||||
|
||||
|
||||
return true;
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool test_8() {
|
||||
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 8: comparisons (operator<)\n");
|
||||
|
||||
|
||||
|
||||
|
||||
String s="Bees";
|
||||
|
||||
|
||||
OS::get_singleton()->print("\tComparing to \"Bees\"\n");
|
||||
|
||||
|
||||
if ( ! (s < "Elephant") )
|
||||
return false;
|
||||
|
||||
|
||||
if ( s < L"Amber" )
|
||||
return false;
|
||||
|
||||
|
||||
if ( s < String("Beatrix") )
|
||||
return false;
|
||||
|
||||
|
||||
return true;
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool test_9() {
|
||||
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 9: Concatenation\n");
|
||||
|
||||
|
||||
|
||||
|
||||
String s;
|
||||
|
||||
|
||||
s+="Have";
|
||||
s+=' ';
|
||||
s+='a';
|
||||
|
@ -184,279 +184,279 @@ bool test_9() {
|
|||
s = s + L"Nice";
|
||||
s = s + " ";
|
||||
s = s + String("Day");
|
||||
|
||||
|
||||
OS::get_singleton()->print("\tComparing to \"Have a Nice Day\"\n");
|
||||
|
||||
|
||||
return (s == "Have a Nice Day");
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool test_10() {
|
||||
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 10: Misc funcs (size/length/empty/etc)\n");
|
||||
|
||||
|
||||
if (! String("").empty())
|
||||
return false;
|
||||
|
||||
|
||||
if (String("Mellon").size() != 7)
|
||||
return false;
|
||||
|
||||
if (String("Oranges").length() != 7)
|
||||
return false;
|
||||
|
||||
|
||||
return true;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool test_11() {
|
||||
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 11: Operator[]\n");
|
||||
|
||||
|
||||
String a="Kugar Sane";
|
||||
|
||||
|
||||
a[0]='S';
|
||||
a[6]='C';
|
||||
|
||||
|
||||
if (a != "Sugar Cane")
|
||||
return false;
|
||||
|
||||
|
||||
if (a[1]!='u')
|
||||
return false;
|
||||
|
||||
|
||||
return true;
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool test_12() {
|
||||
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 12: case functions\n");
|
||||
|
||||
|
||||
|
||||
|
||||
String a="MoMoNgA";
|
||||
|
||||
|
||||
if (a.to_upper() != "MOMONGA")
|
||||
return false;
|
||||
|
||||
|
||||
if (a.nocasecmp_to("momonga")!=0)
|
||||
return false;
|
||||
|
||||
|
||||
return true;
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool test_13() {
|
||||
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 13: UTF8\n");
|
||||
|
||||
|
||||
/* how can i embed UTF in here? */
|
||||
|
||||
|
||||
static const CharType ustr[] = { 0x304A , 0x360F, 0x3088, 0x3046, 0 };
|
||||
// static const wchar_t ustr[] = { 'P', 0xCE, 'p',0xD3, 0 };
|
||||
String s=ustr;
|
||||
|
||||
|
||||
OS::get_singleton()->print("\tUnicode: %ls\n",ustr);
|
||||
s.parse_utf8( s.utf8().get_data() );
|
||||
OS::get_singleton()->print("\tConvert/Parse UTF8: %ls\n",s.c_str());
|
||||
|
||||
|
||||
return (s==ustr);
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool test_14() {
|
||||
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 14: ASCII\n");
|
||||
|
||||
|
||||
String s = L"Primero Leche";
|
||||
OS::get_singleton()->print("\tAscii: %s\n",s.ascii().get_data());
|
||||
|
||||
|
||||
String t=s.ascii().get_data();
|
||||
return (s==t);
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool test_15() {
|
||||
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 15: substr\n");
|
||||
|
||||
|
||||
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());
|
||||
|
||||
|
||||
return (s.substr(3,4)=="ler ");
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool test_16() {
|
||||
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 16: find\n");
|
||||
|
||||
|
||||
String s="Pretty Woman";
|
||||
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\"Revenge of the Monster Truck\" is at %i pos.\n",s.find("Revenge of the Monster Truck"));
|
||||
|
||||
|
||||
if (s.find("tty")!=3)
|
||||
return false;
|
||||
|
||||
|
||||
if (s.find("Revenge of the Monster Truck")!=-1)
|
||||
return false;
|
||||
|
||||
|
||||
return true;
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool test_17() {
|
||||
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 17: find no case\n");
|
||||
|
||||
|
||||
String s="Pretty Whale";
|
||||
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\"Revenge of the Monster SawFish\" is at %i pos.\n",s.findn("Revenge of the Monster Truck"));
|
||||
|
||||
|
||||
if (s.findn("WHA")!=7)
|
||||
return false;
|
||||
|
||||
|
||||
if (s.findn("Revenge of the Monster SawFish")!=-1)
|
||||
return false;
|
||||
|
||||
|
||||
return true;
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool test_18() {
|
||||
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 18: find no case\n");
|
||||
|
||||
|
||||
String s="Pretty Whale";
|
||||
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\"Revenge of the Monster SawFish\" is at %i pos.\n",s.findn("Revenge of the Monster Truck"));
|
||||
|
||||
|
||||
if (s.findn("WHA")!=7)
|
||||
return false;
|
||||
|
||||
|
||||
if (s.findn("Revenge of the Monster SawFish")!=-1)
|
||||
return false;
|
||||
|
||||
|
||||
return true;
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool test_19() {
|
||||
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 19: Search & replace\n");
|
||||
|
||||
|
||||
String s="Happy Birthday, Anna!";
|
||||
OS::get_singleton()->print("\tString: %ls\n",s.c_str());
|
||||
|
||||
|
||||
s=s.replace("Birthday","Halloween");
|
||||
OS::get_singleton()->print("\tReplaced Birthday/Halloween: %ls.\n",s.c_str());
|
||||
|
||||
|
||||
return (s=="Happy Halloween, Anna!");
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool test_20() {
|
||||
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 20: Insertion\n");
|
||||
|
||||
|
||||
String s="Who is Frederic?";
|
||||
|
||||
|
||||
OS::get_singleton()->print("\tString: %ls\n",s.c_str());
|
||||
s=s.insert( s.find("?")," Chopin" );
|
||||
OS::get_singleton()->print("\tInserted Chopin: %ls.\n",s.c_str());
|
||||
|
||||
|
||||
return (s=="Who is Frederic Chopin?");
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool test_21() {
|
||||
|
||||
|
||||
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 String is %ls\n",String::num(3.141593).c_str());
|
||||
|
||||
|
||||
return String::num(3.141593)=="3.141593";
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool test_22() {
|
||||
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 22: String -> Int\n");
|
||||
|
||||
|
||||
static const char* nums[4]={ "1237461283", "- 22", "0", " - 1123412" };
|
||||
static const int num[4]={ 1237461283, -22, 0, -1123412 };
|
||||
|
||||
|
||||
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());
|
||||
|
||||
|
||||
if (String(nums[i]).to_int()!=num[i])
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool test_23() {
|
||||
|
||||
|
||||
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 double num[4]={ -12348298412.2, 0.05, 2.0002, -0.0001 };
|
||||
|
||||
|
||||
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());
|
||||
|
||||
|
||||
if ( ABS(String(nums[i]).to_double()-num[i])>0.00001)
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool test_24() {
|
||||
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 24: Slicing\n");
|
||||
|
||||
|
||||
String s="Mars,Jupiter,Saturn,Uranus";
|
||||
|
||||
|
||||
const char*slices[4]={"Mars","Jupiter","Saturn","Uranus"};
|
||||
|
||||
|
||||
OS::get_singleton()->print("\tSlicing \"%ls\" by \"%s\"..\n",s.c_str(),",");
|
||||
|
||||
|
||||
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());
|
||||
|
||||
|
||||
|
||||
|
||||
if (s.get_slice(",",i)!=slices[i])
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool test_25() {
|
||||
|
||||
|
||||
OS::get_singleton()->print("\n\nTest 25: Erasing\n");
|
||||
|
||||
|
||||
String s="Josephine is such a cute girl!";
|
||||
|
||||
|
||||
OS::get_singleton()->print("\tString: %ls\n",s.c_str());
|
||||
OS::get_singleton()->print("\tRemoving \"cute\"\n");
|
||||
|
||||
|
||||
s.erase(s.find("cute "),String("cute ").length());
|
||||
OS::get_singleton()->print("\tResult: %ls\n",s.c_str());
|
||||
|
||||
|
||||
|
||||
|
||||
return (s=="Josephine is such a girl!");
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool test_26() {
|
||||
|
@ -516,7 +516,7 @@ bool test_28() {
|
|||
String format, output;
|
||||
Array args;
|
||||
bool error;
|
||||
|
||||
|
||||
// %%
|
||||
format = "fish %% frog";
|
||||
args.clear();
|
||||
|
@ -846,7 +846,7 @@ bool test_28() {
|
|||
typedef bool (*TestFunc)(void);
|
||||
|
||||
TestFunc test_funcs[] = {
|
||||
|
||||
|
||||
test_1,
|
||||
test_2,
|
||||
test_3,
|
||||
|
@ -876,18 +876,18 @@ TestFunc test_funcs[] = {
|
|||
test_27,
|
||||
test_28,
|
||||
0
|
||||
|
||||
|
||||
};
|
||||
|
||||
MainLoop* test() {
|
||||
|
||||
|
||||
/** A character length != wchar_t may be forced, so the tests wont work */
|
||||
|
||||
|
||||
ERR_FAIL_COND_V( sizeof(CharType) != sizeof(wchar_t), NULL );
|
||||
|
||||
|
||||
int count=0;
|
||||
int passed=0;
|
||||
|
||||
|
||||
while(true) {
|
||||
if (!test_funcs[count])
|
||||
break;
|
||||
|
@ -895,17 +895,17 @@ MainLoop* test() {
|
|||
if (pass)
|
||||
passed++;
|
||||
OS::get_singleton()->print("\t%s\n",pass?"PASS":"FAILED");
|
||||
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
|
||||
OS::get_singleton()->print("\n\n\n");
|
||||
OS::get_singleton()->print("*************\n");
|
||||
OS::get_singleton()->print("***TOTALS!***\n");
|
||||
OS::get_singleton()->print("*************\n");
|
||||
|
||||
|
||||
OS::get_singleton()->print("Passed %i of %i tests\n", passed, count);
|
||||
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -1307,7 +1307,12 @@ DVector<uint8_t> _File::get_buffer(int p_length) const{
|
|||
|
||||
String _File::get_as_text() const {
|
||||
|
||||
ERR_FAIL_COND_V(!f, String());
|
||||
|
||||
String text;
|
||||
size_t original_pos = f->get_pos();
|
||||
f->seek(0);
|
||||
|
||||
String l = get_line();
|
||||
while(!eof_reached()) {
|
||||
text+=l+"\n";
|
||||
|
@ -1315,6 +1320,8 @@ String _File::get_as_text() const {
|
|||
}
|
||||
text+=l;
|
||||
|
||||
f->seek(original_pos);
|
||||
|
||||
return text;
|
||||
|
||||
|
||||
|
@ -1669,15 +1676,15 @@ void _Directory::_bind_methods() {
|
|||
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("get_current_dir"),&_Directory::get_current_dir);
|
||||
ObjectTypeDB::bind_method(_MD("make_dir:Error","name"),&_Directory::make_dir);
|
||||
ObjectTypeDB::bind_method(_MD("make_dir_recursive:Error","name"),&_Directory::make_dir_recursive);
|
||||
ObjectTypeDB::bind_method(_MD("file_exists","name"),&_Directory::file_exists);
|
||||
ObjectTypeDB::bind_method(_MD("dir_exists","name"),&_Directory::dir_exists);
|
||||
ObjectTypeDB::bind_method(_MD("make_dir:Error","path"),&_Directory::make_dir);
|
||||
ObjectTypeDB::bind_method(_MD("make_dir_recursive:Error","path"),&_Directory::make_dir_recursive);
|
||||
ObjectTypeDB::bind_method(_MD("file_exists","path"),&_Directory::file_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_space_left"),&_Directory::get_space_left);
|
||||
ObjectTypeDB::bind_method(_MD("copy:Error","from","to"),&_Directory::copy);
|
||||
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
|
||||
else
|
||||
h = 4 + ( r - g ) / delta; // between magenta & cyan
|
||||
|
||||
|
||||
h/=6.0;
|
||||
if (h<0)
|
||||
h+=1.0;
|
||||
|
||||
|
||||
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 = Math::fmod(p_h,6);
|
||||
i = Math::floor( p_h );
|
||||
|
||||
|
||||
f = p_h - i;
|
||||
p = p_v * ( 1 - p_s );
|
||||
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;
|
||||
b = p;
|
||||
break;
|
||||
case 2:
|
||||
case 2:
|
||||
r = p;
|
||||
g = p_v;
|
||||
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() {
|
||||
|
||||
r=1.0-r;
|
||||
g=1.0-g;
|
||||
b=1.0-b;
|
||||
g=1.0-g;
|
||||
b=1.0-b;
|
||||
}
|
||||
void Color::contrast() {
|
||||
|
||||
|
@ -368,7 +368,7 @@ String Color::to_html(bool p_alpha) const {
|
|||
|
||||
float Color::gray() const {
|
||||
|
||||
return (r+g+b)/3.0;
|
||||
return (r+g+b)/3.0;
|
||||
}
|
||||
|
||||
Color::operator String() const {
|
||||
|
|
18
core/color.h
18
core/color.h
|
@ -37,13 +37,13 @@
|
|||
struct Color {
|
||||
|
||||
union {
|
||||
|
||||
|
||||
struct {
|
||||
float r;
|
||||
float g;
|
||||
float b;
|
||||
float a;
|
||||
};
|
||||
};
|
||||
float components[4];
|
||||
};
|
||||
|
||||
|
@ -58,28 +58,28 @@ struct Color {
|
|||
float get_v() const;
|
||||
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];
|
||||
}
|
||||
_FORCE_INLINE_ const float& operator[](int idx) const {
|
||||
_FORCE_INLINE_ const float& operator[](int idx) const {
|
||||
return components[idx];
|
||||
}
|
||||
|
||||
|
||||
void invert();
|
||||
void contrast();
|
||||
Color inverted() const;
|
||||
Color contrasted() const;
|
||||
|
||||
_FORCE_INLINE_ Color linear_interpolate(const Color& p_b, float p_t) const {
|
||||
|
||||
|
||||
Color res=*this;
|
||||
|
||||
|
||||
res.r+= (p_t * (p_b.r-r));
|
||||
res.g+= (p_t * (p_b.g-g));
|
||||
res.b+= (p_t * (p_b.b-b));
|
||||
res.a+= (p_t * (p_b.a-a));
|
||||
|
||||
return res;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ Color blend(const Color& p_over) const {
|
||||
|
|
|
@ -76,7 +76,7 @@ CommandQueueMT::SyncSemaphore* CommandQueueMT::_alloc_sync_sem() {
|
|||
CommandQueueMT::CommandQueueMT(bool p_sync){
|
||||
|
||||
read_ptr=0;
|
||||
write_ptr=0;
|
||||
write_ptr=0;
|
||||
mutex = Mutex::create();
|
||||
|
||||
for(int i=0;i<SYNC_SEMAPHORES;i++) {
|
||||
|
|
|
@ -47,69 +47,69 @@ class CommandQueueMT {
|
|||
};
|
||||
|
||||
struct CommandBase {
|
||||
|
||||
|
||||
virtual void call()=0;
|
||||
virtual ~CommandBase() {};
|
||||
};
|
||||
|
||||
|
||||
template<class T,class M>
|
||||
struct Command0 : public CommandBase {
|
||||
|
||||
T*instance;
|
||||
M method;
|
||||
|
||||
|
||||
virtual void call() { (instance->*method)(); }
|
||||
};
|
||||
|
||||
|
||||
template<class T,class M,class P1>
|
||||
struct Command1 : public CommandBase {
|
||||
|
||||
|
||||
T*instance;
|
||||
M method;
|
||||
typename GetSimpleTypeT<P1>::type_t p1;
|
||||
|
||||
|
||||
virtual void call() { (instance->*method)(p1); }
|
||||
};
|
||||
|
||||
|
||||
template<class T,class M,class P1,class P2>
|
||||
struct Command2 : public CommandBase {
|
||||
|
||||
|
||||
T*instance;
|
||||
M method;
|
||||
typename GetSimpleTypeT<P1>::type_t p1;
|
||||
typename GetSimpleTypeT<P2>::type_t p2;
|
||||
|
||||
|
||||
virtual void call() { (instance->*method)(p1,p2); }
|
||||
};
|
||||
|
||||
template<class T,class M,class P1,class P2,class P3>
|
||||
struct Command3 : public CommandBase {
|
||||
|
||||
|
||||
T*instance;
|
||||
M method;
|
||||
typename GetSimpleTypeT<P1>::type_t p1;
|
||||
typename GetSimpleTypeT<P2>::type_t p2;
|
||||
typename GetSimpleTypeT<P3>::type_t p3;
|
||||
|
||||
|
||||
virtual void call() { (instance->*method)(p1,p2,p3); }
|
||||
};
|
||||
|
||||
template<class T,class M,class P1,class P2,class P3,class P4>
|
||||
struct Command4 : public CommandBase {
|
||||
|
||||
|
||||
T*instance;
|
||||
M method;
|
||||
typename GetSimpleTypeT<P1>::type_t p1;
|
||||
typename GetSimpleTypeT<P2>::type_t p2;
|
||||
typename GetSimpleTypeT<P3>::type_t p3;
|
||||
typename GetSimpleTypeT<P4>::type_t 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>
|
||||
struct Command5 : public CommandBase {
|
||||
|
||||
|
||||
T*instance;
|
||||
M method;
|
||||
typename GetSimpleTypeT<P1>::type_t p1;
|
||||
|
@ -117,13 +117,13 @@ class CommandQueueMT {
|
|||
typename GetSimpleTypeT<P3>::type_t p3;
|
||||
typename GetSimpleTypeT<P4>::type_t p4;
|
||||
typename GetSimpleTypeT<P5>::type_t 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>
|
||||
struct Command6 : public CommandBase {
|
||||
|
||||
|
||||
T*instance;
|
||||
M method;
|
||||
typename GetSimpleTypeT<P1>::type_t p1;
|
||||
|
@ -132,13 +132,13 @@ class CommandQueueMT {
|
|||
typename GetSimpleTypeT<P4>::type_t p4;
|
||||
typename GetSimpleTypeT<P5>::type_t p5;
|
||||
typename GetSimpleTypeT<P6>::type_t 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>
|
||||
struct Command7 : public CommandBase {
|
||||
|
||||
|
||||
T*instance;
|
||||
M method;
|
||||
typename GetSimpleTypeT<P1>::type_t p1;
|
||||
|
@ -148,12 +148,12 @@ class CommandQueueMT {
|
|||
typename GetSimpleTypeT<P5>::type_t p5;
|
||||
typename GetSimpleTypeT<P6>::type_t p6;
|
||||
typename GetSimpleTypeT<P7>::type_t p7;
|
||||
|
||||
|
||||
virtual void call() { (instance->*method)(p1,p2,p3,p4,p5,p6,p7); }
|
||||
};
|
||||
|
||||
|
||||
/* comands that return */
|
||||
|
||||
|
||||
template<class T,class M,class R>
|
||||
struct CommandRet0 : public CommandBase {
|
||||
|
||||
|
@ -161,38 +161,38 @@ class CommandQueueMT {
|
|||
M method;
|
||||
R* ret;
|
||||
SyncSemaphore *sync;
|
||||
|
||||
|
||||
virtual void call() { *ret = (instance->*method)(); sync->sem->post(); sync->in_use=false; ; }
|
||||
};
|
||||
|
||||
|
||||
template<class T,class M,class P1,class R>
|
||||
struct CommandRet1 : public CommandBase {
|
||||
|
||||
|
||||
T*instance;
|
||||
M method;
|
||||
typename GetSimpleTypeT<P1>::type_t p1;
|
||||
R* ret;
|
||||
SyncSemaphore *sync;
|
||||
|
||||
|
||||
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>
|
||||
struct CommandRet2 : public CommandBase {
|
||||
|
||||
|
||||
T*instance;
|
||||
M method;
|
||||
typename GetSimpleTypeT<P1>::type_t p1;
|
||||
typename GetSimpleTypeT<P2>::type_t p2;
|
||||
R* ret;
|
||||
SyncSemaphore *sync;
|
||||
|
||||
|
||||
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>
|
||||
struct CommandRet3 : public CommandBase {
|
||||
|
||||
|
||||
T*instance;
|
||||
M method;
|
||||
typename GetSimpleTypeT<P1>::type_t p1;
|
||||
|
@ -200,13 +200,13 @@ class CommandQueueMT {
|
|||
typename GetSimpleTypeT<P3>::type_t p3;
|
||||
R* ret;
|
||||
SyncSemaphore *sync;
|
||||
|
||||
|
||||
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>
|
||||
struct CommandRet4 : public CommandBase {
|
||||
|
||||
|
||||
T*instance;
|
||||
M method;
|
||||
typename GetSimpleTypeT<P1>::type_t p1;
|
||||
|
@ -215,13 +215,13 @@ class CommandQueueMT {
|
|||
typename GetSimpleTypeT<P4>::type_t p4;
|
||||
R* ret;
|
||||
SyncSemaphore *sync;
|
||||
|
||||
|
||||
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>
|
||||
struct CommandRet5 : public CommandBase {
|
||||
|
||||
|
||||
T*instance;
|
||||
M method;
|
||||
typename GetSimpleTypeT<P1>::type_t p1;
|
||||
|
@ -231,13 +231,13 @@ class CommandQueueMT {
|
|||
typename GetSimpleTypeT<P5>::type_t p5;
|
||||
R* ret;
|
||||
SyncSemaphore *sync;
|
||||
|
||||
|
||||
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>
|
||||
struct CommandRet6 : public CommandBase {
|
||||
|
||||
|
||||
T*instance;
|
||||
M method;
|
||||
typename GetSimpleTypeT<P1>::type_t p1;
|
||||
|
@ -248,13 +248,13 @@ class CommandQueueMT {
|
|||
typename GetSimpleTypeT<P6>::type_t p6;
|
||||
R* ret;
|
||||
SyncSemaphore *sync;
|
||||
|
||||
|
||||
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>
|
||||
struct CommandRet7 : public CommandBase {
|
||||
|
||||
|
||||
T*instance;
|
||||
M method;
|
||||
typename GetSimpleTypeT<P1>::type_t p1;
|
||||
|
@ -266,9 +266,9 @@ class CommandQueueMT {
|
|||
typename GetSimpleTypeT<P7>::type_t p7;
|
||||
R* ret;
|
||||
SyncSemaphore *sync;
|
||||
|
||||
|
||||
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 */
|
||||
|
||||
|
@ -392,7 +392,7 @@ class CommandQueueMT {
|
|||
|
||||
/***** BASE *******/
|
||||
|
||||
enum {
|
||||
enum {
|
||||
COMMAND_MEM_SIZE_KB=256,
|
||||
COMMAND_MEM_SIZE=COMMAND_MEM_SIZE_KB*1024,
|
||||
SYNC_SEMAPHORES=8
|
||||
|
@ -405,30 +405,30 @@ class CommandQueueMT {
|
|||
SyncSemaphore sync_sems[SYNC_SEMAPHORES];
|
||||
Mutex *mutex;
|
||||
Semaphore *sync;
|
||||
|
||||
|
||||
|
||||
|
||||
template<class T>
|
||||
T* allocate() {
|
||||
|
||||
|
||||
// alloc size is size+T+safeguard
|
||||
uint32_t alloc_size=sizeof(T)+sizeof(uint32_t);
|
||||
|
||||
|
||||
tryagain:
|
||||
|
||||
|
||||
if (write_ptr < read_ptr) {
|
||||
// behind read_ptr, check that there is room
|
||||
if ( (read_ptr-write_ptr) <= alloc_size )
|
||||
return NULL;
|
||||
} else if (write_ptr >= read_ptr) {
|
||||
// ahead of read_ptr, check that there is room
|
||||
|
||||
|
||||
|
||||
|
||||
if ( (COMMAND_MEM_SIZE-write_ptr) < alloc_size+4 ) {
|
||||
// no room at the end, wrap down;
|
||||
|
||||
|
||||
if (read_ptr==0) // dont want write_ptr to become read_ptr
|
||||
return NULL;
|
||||
|
||||
|
||||
// if this happens, it's a bug
|
||||
ERR_FAIL_COND_V( (COMMAND_MEM_SIZE-write_ptr) < sizeof(uint32_t), NULL );
|
||||
// zero means, wrap to begining
|
||||
|
@ -447,147 +447,147 @@ class CommandQueueMT {
|
|||
T* cmd = memnew_placement( &command_mem[write_ptr], T );
|
||||
write_ptr+=sizeof(T);
|
||||
return cmd;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
T* allocate_and_lock() {
|
||||
|
||||
|
||||
lock();
|
||||
T* ret;
|
||||
|
||||
|
||||
while ( (ret=allocate<T>())==NULL ) {
|
||||
|
||||
|
||||
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();
|
||||
lock();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool flush_one() {
|
||||
|
||||
|
||||
tryagain:
|
||||
|
||||
|
||||
// tried to read an empty queue
|
||||
if (read_ptr == write_ptr )
|
||||
return false;
|
||||
|
||||
|
||||
uint32_t size = *(uint32_t*)( &command_mem[read_ptr] );
|
||||
|
||||
|
||||
if (size==0) {
|
||||
//end of ringbuffer, wrap
|
||||
read_ptr=0;
|
||||
goto tryagain;
|
||||
}
|
||||
|
||||
|
||||
read_ptr+=sizeof(uint32_t);
|
||||
|
||||
|
||||
CommandBase *cmd = reinterpret_cast<CommandBase*>( &command_mem[read_ptr] );
|
||||
|
||||
|
||||
cmd->call();
|
||||
cmd->~CommandBase();
|
||||
|
||||
read_ptr+=size;
|
||||
|
||||
read_ptr+=size;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void lock();
|
||||
void unlock();
|
||||
void wait_for_flush();
|
||||
SyncSemaphore* _alloc_sync_sem();
|
||||
|
||||
|
||||
|
||||
|
||||
public:
|
||||
|
||||
/* NORMAL PUSH COMMANDS */
|
||||
|
||||
|
||||
template<class T, class M>
|
||||
void push( T * p_instance, M p_method ) {
|
||||
|
||||
|
||||
Command0<T,M> * cmd = allocate_and_lock< Command0<T,M> >();
|
||||
|
||||
|
||||
cmd->instance=p_instance;
|
||||
cmd->method=p_method;
|
||||
|
||||
|
||||
unlock();
|
||||
|
||||
|
||||
if (sync) sync->post();
|
||||
}
|
||||
|
||||
template<class T, class M, class P1>
|
||||
void push( T * p_instance, M p_method, P1 p1 ) {
|
||||
|
||||
|
||||
Command1<T,M,P1> * cmd = allocate_and_lock< Command1<T,M,P1> >();
|
||||
|
||||
|
||||
cmd->instance=p_instance;
|
||||
cmd->method=p_method;
|
||||
cmd->p1=p1;
|
||||
|
||||
|
||||
unlock();
|
||||
|
||||
|
||||
if (sync) sync->post();
|
||||
}
|
||||
|
||||
template<class T, class M, class P1, class 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> >();
|
||||
|
||||
|
||||
cmd->instance=p_instance;
|
||||
cmd->method=p_method;
|
||||
cmd->p1=p1;
|
||||
cmd->p2=p2;
|
||||
|
||||
|
||||
unlock();
|
||||
|
||||
|
||||
if (sync) sync->post();
|
||||
}
|
||||
|
||||
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 ) {
|
||||
|
||||
|
||||
Command3<T,M,P1,P2,P3> * cmd = allocate_and_lock< Command3<T,M,P1,P2,P3> >();
|
||||
|
||||
|
||||
cmd->instance=p_instance;
|
||||
cmd->method=p_method;
|
||||
cmd->p1=p1;
|
||||
cmd->p2=p2;
|
||||
cmd->p3=p3;
|
||||
|
||||
|
||||
unlock();
|
||||
|
||||
|
||||
if (sync) sync->post();
|
||||
}
|
||||
|
||||
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 ) {
|
||||
|
||||
|
||||
Command4<T,M,P1,P2,P3,P4> * cmd = allocate_and_lock< Command4<T,M,P1,P2,P3,P4> >();
|
||||
|
||||
|
||||
cmd->instance=p_instance;
|
||||
cmd->method=p_method;
|
||||
cmd->p1=p1;
|
||||
cmd->p2=p2;
|
||||
cmd->p3=p3;
|
||||
cmd->p4=p4;
|
||||
|
||||
|
||||
unlock();
|
||||
|
||||
|
||||
if (sync) sync->post();
|
||||
}
|
||||
|
||||
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 ) {
|
||||
|
||||
|
||||
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->method=p_method;
|
||||
cmd->p1=p1;
|
||||
|
@ -595,17 +595,17 @@ public:
|
|||
cmd->p3=p3;
|
||||
cmd->p4=p4;
|
||||
cmd->p5=p5;
|
||||
|
||||
|
||||
unlock();
|
||||
|
||||
|
||||
if (sync) sync->post();
|
||||
}
|
||||
|
||||
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 ) {
|
||||
|
||||
|
||||
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->method=p_method;
|
||||
cmd->p1=p1;
|
||||
|
@ -614,17 +614,17 @@ public:
|
|||
cmd->p4=p4;
|
||||
cmd->p5=p5;
|
||||
cmd->p6=p6;
|
||||
|
||||
|
||||
unlock();
|
||||
|
||||
|
||||
if (sync) sync->post();
|
||||
}
|
||||
|
||||
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 ) {
|
||||
|
||||
|
||||
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->method=p_method;
|
||||
cmd->p1=p1;
|
||||
|
@ -634,19 +634,19 @@ public:
|
|||
cmd->p5=p5;
|
||||
cmd->p6=p6;
|
||||
cmd->p7=p7;
|
||||
|
||||
|
||||
unlock();
|
||||
|
||||
|
||||
if (sync) sync->post();
|
||||
}
|
||||
/*** PUSH AND RET COMMANDS ***/
|
||||
|
||||
|
||||
|
||||
|
||||
template<class T, class M,class R>
|
||||
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> >();
|
||||
|
||||
|
||||
cmd->instance=p_instance;
|
||||
cmd->method=p_method;
|
||||
cmd->ret=r_ret;
|
||||
|
@ -654,34 +654,34 @@ public:
|
|||
cmd->sync=ss;
|
||||
|
||||
unlock();
|
||||
|
||||
|
||||
if (sync) sync->post();
|
||||
ss->sem->wait();
|
||||
}
|
||||
|
||||
template<class T, class M, class P1,class R>
|
||||
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> >();
|
||||
|
||||
|
||||
cmd->instance=p_instance;
|
||||
cmd->method=p_method;
|
||||
cmd->p1=p1;
|
||||
cmd->ret=r_ret;
|
||||
SyncSemaphore *ss=_alloc_sync_sem();
|
||||
cmd->sync=ss;
|
||||
|
||||
|
||||
unlock();
|
||||
|
||||
|
||||
if (sync) sync->post();
|
||||
ss->sem->wait();
|
||||
}
|
||||
|
||||
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) {
|
||||
|
||||
|
||||
CommandRet2<T,M,P1,P2,R> * cmd = allocate_and_lock< CommandRet2<T,M,P1,P2,R> >();
|
||||
|
||||
|
||||
cmd->instance=p_instance;
|
||||
cmd->method=p_method;
|
||||
cmd->p1=p1;
|
||||
|
@ -691,16 +691,16 @@ public:
|
|||
cmd->sync=ss;
|
||||
|
||||
unlock();
|
||||
|
||||
|
||||
if (sync) sync->post();
|
||||
ss->sem->wait();
|
||||
}
|
||||
|
||||
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 ) {
|
||||
|
||||
|
||||
CommandRet3<T,M,P1,P2,P3,R> * cmd = allocate_and_lock< CommandRet3<T,M,P1,P2,P3,R> >();
|
||||
|
||||
|
||||
cmd->instance=p_instance;
|
||||
cmd->method=p_method;
|
||||
cmd->p1=p1;
|
||||
|
@ -711,16 +711,16 @@ public:
|
|||
cmd->sync=ss;
|
||||
|
||||
unlock();
|
||||
|
||||
|
||||
if (sync) sync->post();
|
||||
ss->sem->wait();
|
||||
}
|
||||
|
||||
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 ) {
|
||||
|
||||
|
||||
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->method=p_method;
|
||||
cmd->p1=p1;
|
||||
|
@ -732,16 +732,16 @@ public:
|
|||
cmd->sync=ss;
|
||||
|
||||
unlock();
|
||||
|
||||
|
||||
if (sync) sync->post();
|
||||
ss->sem->wait();
|
||||
}
|
||||
|
||||
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 ) {
|
||||
|
||||
|
||||
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->method=p_method;
|
||||
cmd->p1=p1;
|
||||
|
@ -754,16 +754,16 @@ public:
|
|||
cmd->sync=ss;
|
||||
|
||||
unlock();
|
||||
|
||||
|
||||
if (sync) sync->post();
|
||||
ss->sem->wait();
|
||||
}
|
||||
|
||||
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 ) {
|
||||
|
||||
|
||||
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->method=p_method;
|
||||
cmd->p1=p1;
|
||||
|
@ -777,16 +777,16 @@ public:
|
|||
cmd->sync=ss;
|
||||
|
||||
unlock();
|
||||
|
||||
|
||||
if (sync) sync->post();
|
||||
ss->sem->wait();
|
||||
}
|
||||
|
||||
|
||||
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 ) {
|
||||
|
||||
|
||||
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->method=p_method;
|
||||
cmd->p1=p1;
|
||||
|
@ -801,7 +801,7 @@ public:
|
|||
cmd->sync=ss;
|
||||
|
||||
unlock();
|
||||
|
||||
|
||||
if (sync) sync->post();
|
||||
ss->sem->wait();
|
||||
}
|
||||
|
@ -975,12 +975,12 @@ public:
|
|||
ERR_FAIL_COND(!sync);
|
||||
sync->wait();
|
||||
lock();
|
||||
flush_one();
|
||||
flush_one();
|
||||
unlock();
|
||||
}
|
||||
|
||||
|
||||
void flush_all() {
|
||||
|
||||
|
||||
//ERR_FAIL_COND(sync);
|
||||
lock();
|
||||
while (true) {
|
||||
|
@ -990,10 +990,10 @@ public:
|
|||
}
|
||||
unlock();
|
||||
}
|
||||
|
||||
|
||||
CommandQueueMT(bool p_sync);
|
||||
~CommandQueueMT();
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -110,6 +110,16 @@ bool Dictionary::has(const Variant& p_key) const {
|
|||
|
||||
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) {
|
||||
_copy_on_write();
|
||||
_p->variant_map.erase(p_key);
|
||||
|
|
|
@ -69,6 +69,8 @@ public:
|
|||
bool is_shared() const;
|
||||
|
||||
bool has(const Variant& p_key) const;
|
||||
bool has_all(const Array& p_keys) const;
|
||||
|
||||
void erase(const Variant& p_key);
|
||||
|
||||
bool operator==(const Dictionary& p_dictionary) const;
|
||||
|
|
198
core/dvector.h
198
core/dvector.h
|
@ -43,18 +43,18 @@ template<class T>
|
|||
class DVector {
|
||||
|
||||
mutable MID mem;
|
||||
|
||||
|
||||
|
||||
|
||||
void copy_on_write() {
|
||||
|
||||
|
||||
if (!mem.is_valid())
|
||||
return;
|
||||
|
||||
if (dvector_lock)
|
||||
dvector_lock->lock();
|
||||
|
||||
|
||||
MID_Lock lock( mem );
|
||||
|
||||
|
||||
|
||||
if ( *(int*)lock.data() == 1 ) {
|
||||
// one reference, means no refcount changes
|
||||
|
@ -62,114 +62,114 @@ class DVector {
|
|||
dvector_lock->unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
MID new_mem= dynalloc( mem.get_size() );
|
||||
|
||||
|
||||
if (!new_mem.is_valid()) {
|
||||
|
||||
|
||||
if (dvector_lock)
|
||||
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 );
|
||||
|
||||
|
||||
int *rc = (int*)dst_lock.data();
|
||||
|
||||
|
||||
*rc=1;
|
||||
|
||||
|
||||
T * dst = (T*)(rc + 1 );
|
||||
|
||||
|
||||
T * src =(T*) ((int*)lock.data() + 1 );
|
||||
|
||||
|
||||
int count = (mem.get_size() - sizeof(int)) / sizeof(T);
|
||||
|
||||
|
||||
for (int i=0;i<count;i++) {
|
||||
|
||||
|
||||
memnew_placement( &dst[i], T(src[i]) );
|
||||
}
|
||||
|
||||
|
||||
(*(int*)lock.data())--;
|
||||
|
||||
|
||||
// unlock all
|
||||
dst_lock=MID_Lock();
|
||||
lock=MID_Lock();
|
||||
|
||||
|
||||
mem=new_mem;
|
||||
|
||||
|
||||
if (dvector_lock)
|
||||
dvector_lock->unlock();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void reference( const DVector& p_dvector ) {
|
||||
|
||||
|
||||
unreference();
|
||||
|
||||
|
||||
if (dvector_lock)
|
||||
dvector_lock->lock();
|
||||
|
||||
|
||||
if (!p_dvector.mem.is_valid()) {
|
||||
|
||||
|
||||
if (dvector_lock)
|
||||
dvector_lock->unlock();
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
MID_Lock lock(p_dvector.mem);
|
||||
|
||||
|
||||
int * rc = (int*)lock.data();
|
||||
(*rc)++;
|
||||
|
||||
|
||||
lock = MID_Lock();
|
||||
mem=p_dvector.mem;
|
||||
|
||||
|
||||
if (dvector_lock)
|
||||
dvector_lock->unlock();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void unreference() {
|
||||
|
||||
|
||||
if (dvector_lock)
|
||||
dvector_lock->lock();
|
||||
|
||||
|
||||
if (!mem.is_valid()) {
|
||||
|
||||
|
||||
if (dvector_lock)
|
||||
dvector_lock->unlock();
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
MID_Lock lock(mem);
|
||||
|
||||
|
||||
int * rc = (int*)lock.data();
|
||||
(*rc)--;
|
||||
|
||||
|
||||
if (*rc==0) {
|
||||
// no one else using it, destruct
|
||||
|
||||
|
||||
T * t= (T*)(rc+1);
|
||||
int count = (mem.get_size() - sizeof(int)) / sizeof(T);
|
||||
|
||||
|
||||
for (int i=0;i<count;i++) {
|
||||
|
||||
|
||||
t[i].~T();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
lock = MID_Lock();
|
||||
|
||||
|
||||
mem = MID ();
|
||||
|
||||
|
||||
if (dvector_lock)
|
||||
dvector_lock->unlock();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
|
||||
class Read {
|
||||
|
@ -177,10 +177,10 @@ public:
|
|||
MID_Lock lock;
|
||||
const T * mem;
|
||||
public:
|
||||
|
||||
|
||||
_FORCE_INLINE_ const T& operator[](int p_index) const { return mem[p_index]; }
|
||||
_FORCE_INLINE_ const T *ptr() const { return mem; }
|
||||
|
||||
|
||||
Read() { mem=NULL; }
|
||||
};
|
||||
|
||||
|
@ -189,32 +189,32 @@ public:
|
|||
MID_Lock lock;
|
||||
T * mem;
|
||||
public:
|
||||
|
||||
|
||||
_FORCE_INLINE_ T& operator[](int p_index) { return mem[p_index]; }
|
||||
_FORCE_INLINE_ T *ptr() { return mem; }
|
||||
|
||||
|
||||
Write() { mem=NULL; }
|
||||
};
|
||||
|
||||
|
||||
Read read() const {
|
||||
|
||||
|
||||
Read r;
|
||||
if (mem.is_valid()) {
|
||||
if (mem.is_valid()) {
|
||||
r.lock = MID_Lock( mem );
|
||||
r.mem = (const T*)((int*)r.lock.data()+1);
|
||||
}
|
||||
return r;
|
||||
return r;
|
||||
}
|
||||
Write write() {
|
||||
|
||||
|
||||
Write w;
|
||||
if (mem.is_valid()) {
|
||||
copy_on_write();
|
||||
w.lock = MID_Lock( mem );
|
||||
w.mem = (T*)((int*)w.lock.data()+1);
|
||||
}
|
||||
return w;
|
||||
return w;
|
||||
}
|
||||
|
||||
template<class MC>
|
||||
|
@ -280,12 +280,12 @@ public:
|
|||
|
||||
|
||||
bool is_locked() const { return mem.is_locked(); }
|
||||
|
||||
|
||||
inline const T operator[](int p_index) const;
|
||||
|
||||
Error resize(int p_size);
|
||||
|
||||
|
||||
|
||||
|
||||
void operator=(const DVector& p_dvector) { reference(p_dvector); }
|
||||
DVector() {}
|
||||
DVector(const DVector& p_dvector) { reference(p_dvector); }
|
||||
|
@ -308,7 +308,7 @@ T DVector<T>::get(int p_index) const {
|
|||
template<class T>
|
||||
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());
|
||||
}
|
||||
|
||||
|
@ -332,7 +332,7 @@ const T DVector<T>::operator[](int p_index) const {
|
|||
}
|
||||
|
||||
Read r = read();
|
||||
|
||||
|
||||
return r[p_index];
|
||||
}
|
||||
|
||||
|
@ -344,83 +344,83 @@ Error DVector<T>::resize(int p_size) {
|
|||
dvector_lock->lock();
|
||||
|
||||
bool same = p_size==size();
|
||||
|
||||
|
||||
if (dvector_lock)
|
||||
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)
|
||||
return OK;
|
||||
|
||||
if (p_size == 0 ) {
|
||||
|
||||
|
||||
unreference();
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
copy_on_write(); // make it unique
|
||||
|
||||
|
||||
ERR_FAIL_COND_V( mem.is_locked(), ERR_LOCKED ); // if after copy on write, memory is locked, fail.
|
||||
|
||||
|
||||
if (p_size > size() ) {
|
||||
|
||||
|
||||
int oldsize=size();
|
||||
|
||||
|
||||
MID_Lock lock;
|
||||
|
||||
|
||||
if (oldsize==0) {
|
||||
|
||||
mem = dynalloc( p_size * sizeof(T) + sizeof(int) );
|
||||
lock=MID_Lock(mem);
|
||||
int *rc = ((int*)lock.data());
|
||||
*rc=1;
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
if (dynrealloc( mem, p_size * sizeof(T) + sizeof(int) )!=OK ) {
|
||||
|
||||
|
||||
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);
|
||||
|
||||
|
||||
for (int i=oldsize;i<p_size;i++) {
|
||||
|
||||
|
||||
memnew_placement(&t[i], T );
|
||||
}
|
||||
|
||||
|
||||
lock = MID_Lock(); // clear
|
||||
} else {
|
||||
|
||||
|
||||
int oldsize=size();
|
||||
|
||||
|
||||
MID_Lock lock(mem);
|
||||
|
||||
|
||||
|
||||
|
||||
T *t = (T*)((int*)lock.data() + 1);
|
||||
|
||||
|
||||
for (int i=p_size;i<oldsize;i++) {
|
||||
|
||||
|
||||
t[i].~T();
|
||||
}
|
||||
|
||||
|
||||
lock = MID_Lock(); // clear
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -33,12 +33,12 @@
|
|||
/**
|
||||
* 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
|
||||
* 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
|
||||
* to fail or crash.
|
||||
*/
|
||||
|
||||
/**
|
||||
/**
|
||||
* 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; \
|
||||
}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.
|
||||
*/
|
||||
|
||||
|
@ -146,7 +146,7 @@ extern bool _err_error_exists;
|
|||
return; \
|
||||
}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.
|
||||
* This function returns an error value, if returning Error, please select the most
|
||||
* appropriate error condition from error_macros.h
|
||||
|
@ -158,7 +158,7 @@ extern bool _err_error_exists;
|
|||
return m_retval; \
|
||||
}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.
|
||||
*/
|
||||
|
||||
|
@ -168,7 +168,7 @@ extern bool _err_error_exists;
|
|||
continue;\
|
||||
} 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
|
||||
*/
|
||||
|
||||
|
|
|
@ -43,118 +43,118 @@ Error EventQueue::push_call(uint32_t p_instance_ID, const StringName& p_method,
|
|||
args=2;
|
||||
else if (p_arg1.get_type()!=Variant::NIL)
|
||||
args=1;
|
||||
else
|
||||
else
|
||||
args=0;
|
||||
|
||||
|
||||
room_needed+=sizeof(Variant)*args;
|
||||
|
||||
|
||||
ERR_FAIL_COND_V( (buffer_end+room_needed) >= buffer_size , ERR_OUT_OF_MEMORY );
|
||||
Event * ev = memnew_placement( &event_buffer[ buffer_end ], Event );
|
||||
ev->args=args;
|
||||
ev->instance_ID=p_instance_ID;
|
||||
ev->method=p_method;
|
||||
|
||||
|
||||
buffer_end+=sizeof(Event);
|
||||
|
||||
|
||||
if (args>=1) {
|
||||
|
||||
|
||||
Variant * v = memnew_placement( &event_buffer[ buffer_end ], Variant );
|
||||
buffer_end+=sizeof(Variant);
|
||||
*v=p_arg1;
|
||||
}
|
||||
|
||||
if (args>=2) {
|
||||
|
||||
|
||||
Variant * v = memnew_placement( &event_buffer[ buffer_end ], Variant );
|
||||
buffer_end+=sizeof(Variant);
|
||||
*v=p_arg2;
|
||||
}
|
||||
|
||||
if (args>=3) {
|
||||
|
||||
|
||||
Variant * v = memnew_placement( &event_buffer[ buffer_end ], Variant );
|
||||
buffer_end+=sizeof(Variant);
|
||||
*v=p_arg3;
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (args>=4) {
|
||||
|
||||
|
||||
Variant * v = memnew_placement( &event_buffer[ buffer_end ], Variant );
|
||||
buffer_end+=sizeof(Variant);
|
||||
*v=p_arg4;
|
||||
}
|
||||
|
||||
if (args>=5) {
|
||||
|
||||
|
||||
Variant * v = memnew_placement( &event_buffer[ buffer_end ], Variant );
|
||||
buffer_end+=sizeof(Variant);
|
||||
*v=p_arg5;
|
||||
}
|
||||
|
||||
if (buffer_max_used>buffer_end);
|
||||
|
||||
if (buffer_end > buffer_max_used)
|
||||
buffer_max_used=buffer_end;
|
||||
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
void EventQueue::flush_events() {
|
||||
|
||||
uint32_t read_pos=0;
|
||||
|
||||
|
||||
while (read_pos < buffer_end ) {
|
||||
|
||||
|
||||
Event *event = (Event*)&event_buffer[ read_pos ];
|
||||
Variant *args= (Variant*)(event+1);
|
||||
Object *obj = ObjectDB::get_instance(event->instance_ID);
|
||||
|
||||
if (obj) {
|
||||
|
||||
if (obj) {
|
||||
// events don't expect a return value
|
||||
obj->call( event->method,
|
||||
obj->call( event->method,
|
||||
(event->args>=1) ? args[0] : Variant(),
|
||||
(event->args>=2) ? args[1] : Variant(),
|
||||
(event->args>=3) ? args[2] : Variant(),
|
||||
(event->args>=4) ? args[3] : Variant(),
|
||||
(event->args>=5) ? args[4] : Variant() );
|
||||
}
|
||||
|
||||
|
||||
if (event->args>=1) args[0].~Variant();
|
||||
if (event->args>=2) args[1].~Variant();
|
||||
if (event->args>=3) args[2].~Variant();
|
||||
if (event->args>=4) args[3].~Variant();
|
||||
if (event->args>=5) args[4].~Variant();
|
||||
event->~Event();
|
||||
|
||||
|
||||
read_pos+=sizeof(Event)+sizeof(Variant)*event->args;
|
||||
}
|
||||
|
||||
|
||||
buffer_end=0; // reset buffer
|
||||
}
|
||||
|
||||
EventQueue::EventQueue(uint32_t p_buffer_size) {
|
||||
|
||||
|
||||
|
||||
buffer_end=0;
|
||||
buffer_max_used=0;
|
||||
buffer_size=p_buffer_size;
|
||||
event_buffer = memnew_arr( uint8_t, buffer_size );
|
||||
|
||||
|
||||
}
|
||||
EventQueue::~EventQueue() {
|
||||
|
||||
uint32_t read_pos=0;
|
||||
|
||||
|
||||
while (read_pos < buffer_end ) {
|
||||
|
||||
|
||||
Event *event = (Event*)&event_buffer[ read_pos ];
|
||||
Variant *args= (Variant*)(event+1);
|
||||
for (int i=0;i<event->args;i++)
|
||||
args[i].~Variant();
|
||||
event->~Event();
|
||||
|
||||
|
||||
read_pos+=sizeof(Event)+sizeof(Variant)*event->args;
|
||||
}
|
||||
|
||||
|
||||
memdelete_arr(event_buffer);
|
||||
event_buffer=NULL;
|
||||
}
|
||||
|
|
|
@ -36,18 +36,18 @@
|
|||
class EventQueue {
|
||||
|
||||
enum {
|
||||
|
||||
|
||||
DEFAULT_EVENT_QUEUE_SIZE_KB=256
|
||||
};
|
||||
|
||||
struct Event {
|
||||
|
||||
|
||||
uint32_t instance_ID;
|
||||
StringName method;
|
||||
int args;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
uint8_t *event_buffer;
|
||||
uint32_t buffer_end;
|
||||
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);
|
||||
void flush_events();
|
||||
|
||||
|
||||
EventQueue(uint32_t p_buffer_size=DEFAULT_EVENT_QUEUE_SIZE_KB*1024);
|
||||
~EventQueue();
|
||||
|
||||
|
|
|
@ -474,7 +474,6 @@ static _GlobalConstant _global_constants[]={
|
|||
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_EDITOR ),
|
||||
BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_NETWORK ),
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
Globals *Globals::singleton=NULL;
|
||||
|
||||
Globals *Globals::get_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 {
|
||||
|
||||
|
||||
if (p_path.begins_with("res://")) {
|
||||
|
||||
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) {
|
||||
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
|
||||
if (p_value.get_type()==Variant::NIL)
|
||||
props.erase(p_name);
|
||||
else {
|
||||
|
@ -174,7 +174,7 @@ bool Globals::_get(const StringName& p_name,Variant &r_ret) const {
|
|||
return false;
|
||||
r_ret=props[p_name].variant;
|
||||
return true;
|
||||
|
||||
|
||||
}
|
||||
|
||||
struct _VCSort {
|
||||
|
@ -188,13 +188,13 @@ struct _VCSort {
|
|||
};
|
||||
|
||||
void Globals::_get_property_list(List<PropertyInfo> *p_list) const {
|
||||
|
||||
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
Set<_VCSort> vclist;
|
||||
|
||||
|
||||
for(Map<StringName,VariantContainer>::Element *E=props.front();E;E=E->next()) {
|
||||
|
||||
|
||||
const VariantContainer *v=&E->get();
|
||||
|
||||
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) {
|
||||
|
||||
//an absolute mess of a function, must be cleaned up and reorganized somehow at some point
|
||||
|
||||
|
||||
//_load_settings(p_path+"/override.cfg");
|
||||
|
||||
if (p_main_pack!="") {
|
||||
|
@ -292,7 +292,7 @@ Error Globals::setup(const String& p_path,const String & p_main_pack) {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (FileAccessNetworkClient::get_singleton()) {
|
||||
|
||||
|
@ -332,7 +332,7 @@ Error Globals::setup(const String& p_path,const String & p_main_pack) {
|
|||
resource_path = p_path;
|
||||
|
||||
} else {
|
||||
|
||||
|
||||
d->change_dir(p_path);
|
||||
|
||||
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 {
|
||||
|
||||
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
return props.has(p_var);
|
||||
|
@ -1410,7 +1410,7 @@ void Globals::_bind_methods() {
|
|||
}
|
||||
|
||||
Globals::Globals() {
|
||||
|
||||
|
||||
|
||||
singleton=this;
|
||||
last_order=0;
|
||||
|
@ -1531,7 +1531,7 @@ Globals::Globals() {
|
|||
|
||||
|
||||
Globals::~Globals() {
|
||||
|
||||
|
||||
singleton=NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
|
||||
|
||||
class Globals : public Object {
|
||||
|
||||
|
||||
OBJ_TYPE( Globals, Object );
|
||||
_THREAD_SAFE_CLASS_
|
||||
|
||||
|
@ -77,13 +77,13 @@ protected:
|
|||
bool using_datapack;
|
||||
List<String> input_presets;
|
||||
|
||||
|
||||
|
||||
bool _set(const StringName& p_name, const Variant& p_value);
|
||||
bool _get(const StringName& p_name,Variant &r_ret) const;
|
||||
void _get_property_list(List<PropertyInfo> *p_list) const;
|
||||
|
||||
|
||||
static Globals *singleton;
|
||||
|
||||
|
||||
Error _load_settings(const String p_path);
|
||||
Error _load_settings_binary(const String p_path);
|
||||
|
||||
|
@ -101,7 +101,7 @@ protected:
|
|||
static void _bind_methods();
|
||||
public:
|
||||
|
||||
|
||||
|
||||
bool has(String p_var) const;
|
||||
String localize_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;
|
||||
|
||||
String get_resource_path() const;
|
||||
|
||||
|
||||
static Globals *get_singleton();
|
||||
|
||||
void clear(const String& p_name);
|
||||
int get_order(const String& p_name) const;
|
||||
void set_order(const String& p_name, int p_order);
|
||||
|
||||
|
||||
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>());
|
||||
|
@ -141,7 +141,7 @@ public:
|
|||
|
||||
void set_registering_order(bool p_registering);
|
||||
|
||||
Globals();
|
||||
Globals();
|
||||
~Globals();
|
||||
|
||||
};
|
||||
|
|
330
core/hash_map.h
330
core/hash_map.h
|
@ -38,7 +38,7 @@
|
|||
|
||||
class HashMapHahserDefault {
|
||||
public:
|
||||
|
||||
|
||||
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 uint64_t p_int) {
|
||||
|
@ -66,8 +66,8 @@ public:
|
|||
|
||||
/**
|
||||
* @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.
|
||||
* The implementation provides hashers for the default types, if you need a special kind of hasher, provide
|
||||
* 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 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.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
template<class TKey, class TData, class Hasher=HashMapHahserDefault,uint8_t MIN_HASH_TABLE_POWER=3,uint8_t RELATIONSHIP=8>
|
||||
class HashMap {
|
||||
public:
|
||||
|
||||
public:
|
||||
|
||||
struct Pair {
|
||||
|
||||
|
||||
TKey key;
|
||||
TData data;
|
||||
|
||||
|
||||
Pair() {}
|
||||
Pair(const TKey& p_key, const TData& p_data) { key=p_key; data=p_data; }
|
||||
};
|
||||
|
||||
|
||||
private:
|
||||
|
||||
|
||||
private:
|
||||
struct Entry {
|
||||
|
||||
|
||||
uint32_t hash;
|
||||
Entry *next;
|
||||
Pair pair;
|
||||
|
||||
|
||||
Entry() { next=0; }
|
||||
};
|
||||
|
||||
|
||||
Entry **hash_table;
|
||||
uint8_t hash_table_power;
|
||||
uint32_t elements;
|
||||
|
||||
|
||||
void make_hash_table() {
|
||||
|
||||
|
||||
ERR_FAIL_COND( hash_table );
|
||||
|
||||
|
||||
|
||||
|
||||
hash_table = memnew_arr( Entry*, (1<<MIN_HASH_TABLE_POWER) );
|
||||
|
||||
|
||||
hash_table_power = MIN_HASH_TABLE_POWER;
|
||||
elements=0;
|
||||
for (int i=0;i<(1<<MIN_HASH_TABLE_POWER);i++)
|
||||
hash_table[i]=0;
|
||||
}
|
||||
|
||||
|
||||
void erase_hash_table() {
|
||||
|
||||
|
||||
ERR_FAIL_COND(elements);
|
||||
|
||||
|
||||
memdelete_arr( hash_table );
|
||||
hash_table=0;
|
||||
hash_table_power=0;
|
||||
elements=0;
|
||||
}
|
||||
|
||||
hash_table_power=0;
|
||||
elements=0;
|
||||
}
|
||||
|
||||
void check_hash_table() {
|
||||
|
||||
int new_hash_table_power=-1;
|
||||
|
||||
|
||||
if ((int)elements > ( (1<<hash_table_power) * RELATIONSHIP ) ) {
|
||||
/* rehash up */
|
||||
new_hash_table_power=hash_table_power+1;
|
||||
|
||||
|
||||
while( (int)elements > ( (1<<new_hash_table_power) * RELATIONSHIP ) ) {
|
||||
|
||||
|
||||
new_hash_table_power++;
|
||||
}
|
||||
|
||||
|
||||
} else if ( (hash_table_power>(int)MIN_HASH_TABLE_POWER) && ((int)elements < ( (1<<(hash_table_power-1)) * RELATIONSHIP ) ) ) {
|
||||
|
||||
|
||||
/* rehash down */
|
||||
new_hash_table_power=hash_table_power-1;
|
||||
|
||||
|
||||
while( (int)elements < ( (1<<(new_hash_table_power-1)) * RELATIONSHIP ) ) {
|
||||
|
||||
|
||||
new_hash_table_power--;
|
||||
}
|
||||
|
||||
|
||||
if (new_hash_table_power<(int)MIN_HASH_TABLE_POWER)
|
||||
new_hash_table_power=MIN_HASH_TABLE_POWER;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if (new_hash_table_power==-1)
|
||||
return;
|
||||
|
||||
|
||||
Entry ** new_hash_table = memnew_arr( Entry*, (1<<new_hash_table_power) );
|
||||
if (!new_hash_table) {
|
||||
|
||||
|
||||
ERR_PRINT("Out of Memory");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
for (int i=0;i<(1<<new_hash_table_power);i++) {
|
||||
|
||||
|
||||
new_hash_table[i]=0;
|
||||
}
|
||||
|
||||
|
||||
for (int i=0;i<(1<<hash_table_power);i++) {
|
||||
|
||||
|
||||
while( hash_table[i] ) {
|
||||
|
||||
|
||||
Entry *se=hash_table[i];
|
||||
hash_table[i]=se->next;
|
||||
int new_pos = se->hash & ((1<<new_hash_table_power)-1);
|
||||
se->next=new_hash_table[new_pos];
|
||||
new_hash_table[new_pos]=se;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (hash_table)
|
||||
memdelete_arr( 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.. */
|
||||
_FORCE_INLINE_ const Entry * get_entry( const TKey& p_key ) const {
|
||||
|
||||
|
||||
uint32_t hash = Hasher::hash( p_key );
|
||||
uint32_t index = hash&((1<<hash_table_power)-1);
|
||||
|
||||
|
||||
Entry *e = hash_table[index];
|
||||
|
||||
|
||||
while (e) {
|
||||
|
||||
|
||||
/* checking hash first avoids comparing key, which may take longer */
|
||||
if (e->hash == hash && e->pair.key == p_key ) {
|
||||
|
||||
|
||||
/* the pair exists in this hashtable, so just update data */
|
||||
return e;
|
||||
}
|
||||
|
||||
|
||||
e=e->next;
|
||||
}
|
||||
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
Entry * create_entry(const TKey& p_key) {
|
||||
|
||||
|
||||
/* if entry doesn't exist, create it */
|
||||
Entry *e = memnew( Entry );
|
||||
ERR_FAIL_COND_V(!e,NULL); /* out of memory */
|
||||
uint32_t hash = Hasher::hash( p_key );
|
||||
uint32_t index = hash&((1<<hash_table_power)-1);
|
||||
e->next = hash_table[index];
|
||||
e->next = hash_table[index];
|
||||
e->hash = hash;
|
||||
e->pair.key=p_key;
|
||||
|
||||
|
||||
hash_table[index]=e;
|
||||
elements++;
|
||||
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void copy_from(const HashMap& p_t) {
|
||||
|
||||
|
||||
if (&p_t==this)
|
||||
return; /* much less bother with that */
|
||||
|
||||
|
||||
clear();
|
||||
|
||||
|
||||
if (!p_t.hash_table || p_t.hash_table_power==0)
|
||||
return; /* not copying from empty table */
|
||||
|
||||
|
||||
hash_table = memnew_arr(Entry*,1<<p_t.hash_table_power);
|
||||
hash_table_power=p_t.hash_table_power;
|
||||
elements=p_t.elements;
|
||||
|
||||
|
||||
for (int i=0;i<( 1<<p_t.hash_table_power );i++) {
|
||||
|
||||
|
||||
hash_table[i]=NULL;
|
||||
/* elements will be in the reverse order, but it doesn't matter */
|
||||
|
||||
|
||||
const Entry *e = p_t.hash_table[i];
|
||||
|
||||
|
||||
while(e) {
|
||||
|
||||
|
||||
Entry *le = memnew( Entry ); /* local entry */
|
||||
|
||||
|
||||
*le=*e; /* copy data */
|
||||
|
||||
|
||||
/* add to list and reassign pointers */
|
||||
le->next=hash_table[i];
|
||||
hash_table[i]=le;
|
||||
|
||||
|
||||
e=e->next;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
public:
|
||||
|
||||
|
||||
|
||||
|
||||
void set( const TKey& p_key, const TData& p_data ) {
|
||||
|
||||
|
||||
set( Pair( p_key, p_data ) );
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void set( const Pair& p_pair ) {
|
||||
|
||||
Entry *e=NULL;
|
||||
|
@ -291,63 +291,63 @@ public:
|
|||
make_hash_table(); // if no table, make one
|
||||
else
|
||||
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 (!e) {
|
||||
|
||||
|
||||
e=create_entry(p_pair.key);
|
||||
if (!e)
|
||||
return;
|
||||
check_hash_table(); // perform mantenience routine
|
||||
}
|
||||
|
||||
|
||||
e->pair.data = p_pair.data;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool has( const TKey& p_key ) const {
|
||||
|
||||
|
||||
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
|
||||
* first with has(key)
|
||||
*/
|
||||
|
||||
|
||||
const TData& get( const TKey& p_key ) const {
|
||||
|
||||
|
||||
const TData* res = getptr(p_key);
|
||||
ERR_FAIL_COND_V(!res,*res);
|
||||
return *res;
|
||||
}
|
||||
|
||||
|
||||
TData& get( const TKey& p_key ) {
|
||||
|
||||
|
||||
TData* res = getptr(p_key);
|
||||
ERR_FAIL_COND_V(!res,*res);
|
||||
return *res;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Same as get, except it can return NULL when item was not found.
|
||||
* This is mainly used for speed purposes.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
_FORCE_INLINE_ TData* getptr( const TKey& p_key ) {
|
||||
|
||||
|
||||
if (!hash_table)
|
||||
return NULL;
|
||||
|
||||
|
||||
Entry *e=const_cast<Entry*>(get_entry(p_key ));
|
||||
|
||||
|
||||
if (e)
|
||||
return &e->pair.data;
|
||||
|
||||
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
@ -427,108 +427,108 @@ public:
|
|||
/**
|
||||
* Erase an item, return true if erasing was succesful
|
||||
*/
|
||||
|
||||
|
||||
bool erase( const TKey& p_key ) {
|
||||
|
||||
|
||||
if (!hash_table)
|
||||
return false;
|
||||
|
||||
|
||||
uint32_t hash = Hasher::hash( p_key );
|
||||
uint32_t index = hash&((1<<hash_table_power)-1);
|
||||
|
||||
|
||||
|
||||
|
||||
Entry *e = hash_table[index];
|
||||
Entry *p=NULL;
|
||||
while (e) {
|
||||
|
||||
|
||||
/* checking hash first avoids comparing key, which may take longer */
|
||||
if (e->hash == hash && e->pair.key == p_key ) {
|
||||
|
||||
|
||||
if (p) {
|
||||
|
||||
|
||||
p->next=e->next;
|
||||
} else {
|
||||
} else {
|
||||
//begin of list
|
||||
hash_table[index]=e->next;
|
||||
}
|
||||
|
||||
|
||||
memdelete(e);
|
||||
elements--;
|
||||
|
||||
|
||||
if (elements==0)
|
||||
erase_hash_table();
|
||||
else
|
||||
check_hash_table();
|
||||
check_hash_table();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
p=e;
|
||||
e=e->next;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
return false;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
inline const TData& operator[](const TKey& p_key) const { //constref
|
||||
|
||||
|
||||
return get(p_key);
|
||||
}
|
||||
inline TData& operator[](const TKey& p_key ) { //assignment
|
||||
|
||||
|
||||
Entry *e=NULL;
|
||||
if (!hash_table)
|
||||
make_hash_table(); // if no table, make one
|
||||
else
|
||||
e = const_cast<Entry*>( get_entry(p_key) );
|
||||
|
||||
|
||||
/* if we made it up to here, the pair doesn't exist, create */
|
||||
if (!e) {
|
||||
|
||||
|
||||
e=create_entry(p_key);
|
||||
if (!e)
|
||||
return *(TData*)NULL; /* panic! */
|
||||
check_hash_table(); // perform mantenience routine
|
||||
}
|
||||
|
||||
|
||||
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.
|
||||
* Adding/Removing elements while iterating will, of course, have unexpected results, don't do it.
|
||||
*
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
*
|
||||
* const TKey *k=NULL;
|
||||
*
|
||||
*
|
||||
* while( (k=table.next(k)) ) {
|
||||
*
|
||||
*
|
||||
* print( *k );
|
||||
* }
|
||||
*
|
||||
*
|
||||
*/
|
||||
const TKey* next(const TKey* p_key) const {
|
||||
|
||||
|
||||
if (!hash_table) return NULL;
|
||||
|
||||
|
||||
if (!p_key) { /* get the first key */
|
||||
|
||||
|
||||
for (int i=0;i<(1<<hash_table_power);i++) {
|
||||
|
||||
|
||||
if (hash_table[i]) {
|
||||
return &hash_table[i]->pair.key;
|
||||
}
|
||||
}
|
||||
|
||||
} else { /* get the next key */
|
||||
|
||||
|
||||
const Entry *e = get_entry( *p_key );
|
||||
ERR_FAIL_COND_V( !e, NULL ); /* invalid key supplied */
|
||||
|
||||
|
||||
if (e->next) {
|
||||
/* if there is a "next" in the list, return that */
|
||||
return &e->next->pair.key;
|
||||
|
@ -537,60 +537,60 @@ public:
|
|||
uint32_t index = e->hash&((1<<hash_table_power)-1);
|
||||
index++;
|
||||
for (int i=index;i<(1<<hash_table_power);i++) {
|
||||
|
||||
|
||||
if (hash_table[i]) {
|
||||
return &hash_table[i]->pair.key;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* nothing found, was at end */
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
return NULL; /* nothing found */
|
||||
}
|
||||
|
||||
|
||||
inline unsigned int size() const {
|
||||
|
||||
|
||||
return elements;
|
||||
}
|
||||
|
||||
|
||||
inline bool empty() const {
|
||||
|
||||
|
||||
return elements==0;
|
||||
}
|
||||
|
||||
|
||||
void clear() {
|
||||
|
||||
|
||||
/* clean up */
|
||||
if (hash_table) {
|
||||
for (int i=0;i<(1<<hash_table_power);i++) {
|
||||
|
||||
|
||||
while (hash_table[i]) {
|
||||
|
||||
|
||||
Entry *e=hash_table[i];
|
||||
hash_table[i]=e->next;
|
||||
memdelete( e );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
memdelete_arr( hash_table );
|
||||
}
|
||||
|
||||
|
||||
hash_table=0;
|
||||
hash_table_power=0;
|
||||
elements=0;
|
||||
elements=0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void operator=(const HashMap& p_table) {
|
||||
|
||||
|
||||
copy_from(p_table);
|
||||
}
|
||||
|
||||
HashMap() {
|
||||
|
||||
HashMap() {
|
||||
hash_table=NULL;
|
||||
elements=0;
|
||||
hash_table_power=0;
|
||||
|
@ -609,18 +609,18 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
HashMap(const HashMap& p_table) {
|
||||
|
||||
HashMap(const HashMap& p_table) {
|
||||
|
||||
hash_table=NULL;
|
||||
elements=0;
|
||||
hash_table_power=0;
|
||||
|
||||
|
||||
copy_from(p_table);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
~HashMap() {
|
||||
|
||||
|
||||
clear();
|
||||
}
|
||||
|
||||
|
|
|
@ -47,10 +47,10 @@ static inline uint32_t hash_djb2(const char *p_cstr) {
|
|||
const unsigned char* chr=(const unsigned char*)p_cstr;
|
||||
uint32_t hash = 5381;
|
||||
uint32_t c;
|
||||
|
||||
|
||||
while ((c = *chr++))
|
||||
hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
|
||||
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
|
@ -86,7 +86,7 @@ static inline uint32_t make_uint32_t(T p_in) {
|
|||
T t;
|
||||
uint32_t _u32;
|
||||
} _u;
|
||||
_u._u32=0;
|
||||
_u._u32=0;
|
||||
_u.t=p_in;
|
||||
return _u._u32;
|
||||
}
|
||||
|
@ -106,7 +106,7 @@ static inline uint64_t make_uint64_t(T p_in) {
|
|||
uint64_t _u64;
|
||||
} _u;
|
||||
_u._u64=0; // in case p_in is smaller
|
||||
|
||||
|
||||
_u.t=p_in;
|
||||
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);
|
||||
|
||||
|
||||
int len=data.size();
|
||||
|
||||
DVector<uint8_t>::Read r = data.read();
|
||||
|
@ -413,7 +413,7 @@ void Image::convert( Format p_new_format ){
|
|||
w = DVector<uint8_t>::Write();
|
||||
|
||||
bool gen_mipmaps=mipmaps>0;
|
||||
|
||||
|
||||
*this=new_img;
|
||||
|
||||
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_width>MAX_WIDTH);
|
||||
ERR_FAIL_COND(p_height>MAX_HEIGHT);
|
||||
|
||||
|
||||
|
||||
if (p_width==width && p_height==height)
|
||||
return;
|
||||
|
||||
|
||||
Image dst( p_width, p_height, 0, format );
|
||||
|
||||
|
||||
if (format==FORMAT_INDEXED)
|
||||
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_width>MAX_WIDTH);
|
||||
ERR_FAIL_COND(p_height>MAX_HEIGHT);
|
||||
|
||||
|
||||
/* 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
|
||||
it's a waste of time. */
|
||||
|
||||
if (p_width==width && p_height==height)
|
||||
return;
|
||||
|
||||
|
||||
Image dst( p_width, p_height,0, format );
|
||||
|
||||
|
||||
|
||||
for (int y=0;y<p_height;y++) {
|
||||
|
||||
|
||||
for (int x=0;x<p_width;x++) {
|
||||
|
||||
Color col = (x>=width || y>=height)? Color() : get_pixel(x,y);
|
||||
dst.put_pixel(x,y,col);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (mipmaps>0)
|
||||
dst.generate_mipmaps();
|
||||
*this=dst;
|
||||
|
||||
|
||||
}
|
||||
|
||||
void Image::flip_y() {
|
||||
|
||||
|
||||
if (!_can_modify(format)) {
|
||||
ERR_EXPLAIN("Cannot flip_y in indexed, compressed or custom image formats.");
|
||||
ERR_FAIL();
|
||||
|
@ -756,12 +756,12 @@ void Image::flip_y() {
|
|||
|
||||
|
||||
for (int y=0;y<(height/2);y++) {
|
||||
|
||||
|
||||
for (int x=0;x<width;x++) {
|
||||
|
||||
Color up = get_pixel(x,y);
|
||||
Color down = get_pixel(x,height-y-1);
|
||||
|
||||
|
||||
put_pixel(x,y,down);
|
||||
put_pixel(x,height-y-1,up);
|
||||
}
|
||||
|
@ -783,12 +783,12 @@ void Image::flip_x() {
|
|||
clear_mipmaps();;
|
||||
|
||||
for (int y=0;y<(height/2);y++) {
|
||||
|
||||
|
||||
for (int x=0;x<width;x++) {
|
||||
|
||||
|
||||
Color up = get_pixel(x,y);
|
||||
Color down = get_pixel(width-x-1,y);
|
||||
|
||||
|
||||
put_pixel(x,y,down);
|
||||
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) {
|
||||
|
||||
if (!_can_modify(format)) {
|
||||
|
@ -1040,26 +1100,26 @@ void Image::make_normalmap(float p_height_scale) {
|
|||
}
|
||||
|
||||
ERR_FAIL_COND( empty() );
|
||||
|
||||
|
||||
Image normalmap(width,height,0, FORMAT_RGB);
|
||||
/*
|
||||
for (int y=0;y<height;y++) {
|
||||
for (int x=0;x<width;x++) {
|
||||
|
||||
|
||||
float center=get_pixel(x,y).gray()/255.0;
|
||||
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 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;
|
||||
|
||||
|
||||
|
||||
|
||||
// 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) );
|
||||
|
||||
|
||||
normalmap.put_pixel( x, y, result );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
*/
|
||||
*this=normalmap;
|
||||
|
@ -1071,14 +1131,14 @@ bool Image::empty() const {
|
|||
}
|
||||
|
||||
DVector<uint8_t> Image::get_data() const {
|
||||
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
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);
|
||||
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) {
|
||||
|
||||
|
||||
ERR_FAIL_INDEX(p_width-1,MAX_WIDTH);
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
height=p_height;
|
||||
width=p_width;
|
||||
format=p_format;
|
||||
data=p_data;
|
||||
data=p_data;
|
||||
mipmaps=p_mipmaps;
|
||||
}
|
||||
|
||||
|
||||
void Image::create( const char ** p_xpm ) {
|
||||
|
||||
|
||||
|
||||
int size_width,size_height;
|
||||
int pixelchars=0;
|
||||
mipmaps=0;
|
||||
bool has_alpha=false;
|
||||
|
||||
|
||||
enum Status {
|
||||
READING_HEADER,
|
||||
READING_COLORS,
|
||||
READING_PIXELS,
|
||||
DONE
|
||||
};
|
||||
|
||||
|
||||
Status status = READING_HEADER;
|
||||
int line=0;
|
||||
|
||||
|
||||
HashMap<String,Color> colormap;
|
||||
int colormap_size;
|
||||
|
||||
|
||||
while (status!=DONE) {
|
||||
|
||||
|
||||
const char * line_ptr = p_xpm[line];
|
||||
|
||||
|
||||
|
||||
|
||||
switch (status) {
|
||||
|
||||
|
||||
case READING_HEADER: {
|
||||
|
||||
|
||||
String line_str=line_ptr;
|
||||
line_str.replace("\t"," ");
|
||||
|
||||
|
||||
size_width=line_str.get_slicec(' ',0).to_int();
|
||||
size_height=line_str.get_slicec(' ',1).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;
|
||||
} break;
|
||||
case READING_COLORS: {
|
||||
|
||||
|
||||
String colorstring;
|
||||
for (int i=0;i<pixelchars;i++) {
|
||||
|
||||
|
||||
colorstring+=*line_ptr;
|
||||
line_ptr++;
|
||||
}
|
||||
|
@ -1175,25 +1235,25 @@ void Image::create( const char ** p_xpm ) {
|
|||
line_ptr++;
|
||||
}
|
||||
if (*line_ptr=='c') {
|
||||
|
||||
|
||||
line_ptr++;
|
||||
while (*line_ptr==' ' || *line_ptr=='\t' || *line_ptr==0) {
|
||||
if (*line_ptr==0)
|
||||
break;
|
||||
line_ptr++;
|
||||
}
|
||||
|
||||
|
||||
if (*line_ptr=='#') {
|
||||
line_ptr++;
|
||||
uint8_t col_r;
|
||||
uint8_t col_g;
|
||||
uint8_t col_b;
|
||||
// uint8_t col_a=255;
|
||||
|
||||
|
||||
for (int i=0;i<6;i++) {
|
||||
|
||||
|
||||
char v = line_ptr[i];
|
||||
|
||||
|
||||
if (v>='0' && v<='9')
|
||||
v-='0';
|
||||
else if (v>='A' && v<='F')
|
||||
|
@ -1202,7 +1262,7 @@ void Image::create( const char ** p_xpm ) {
|
|||
v=(v-'a')+10;
|
||||
else
|
||||
break;
|
||||
|
||||
|
||||
switch(i) {
|
||||
case 0: col_r=v<<4; 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 5: col_b|=v; break;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
// magenta mask
|
||||
if (col_r==255 && col_g==0 && col_b==255) {
|
||||
|
||||
|
||||
colormap[colorstring]=Color(0,0,0,0);
|
||||
has_alpha=true;
|
||||
} else {
|
||||
|
||||
colormap[colorstring]=Color(col_r/255.0,col_g/255.0,col_b/255.0,1.0);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
if (line==colormap_size) {
|
||||
|
||||
|
||||
status=READING_PIXELS;
|
||||
create(size_width,size_height,0,has_alpha?FORMAT_RGBA:FORMAT_RGB);
|
||||
}
|
||||
} break;
|
||||
case READING_PIXELS: {
|
||||
|
||||
|
||||
int y=line-colormap_size-1;
|
||||
for (int x=0;x<size_width;x++) {
|
||||
|
||||
|
||||
char pixelstr[6]={0,0,0,0,0,0};
|
||||
for (int i=0;i<pixelchars;i++)
|
||||
pixelstr[i]=line_ptr[x*pixelchars+i];
|
||||
|
||||
|
||||
Color *colorptr = colormap.getptr(pixelstr);
|
||||
ERR_FAIL_COND(!colorptr);
|
||||
put_pixel(x,y,*colorptr);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (y==(size_height-1))
|
||||
status=DONE;
|
||||
} break;
|
||||
default:{}
|
||||
}
|
||||
|
||||
|
||||
line++;
|
||||
}
|
||||
}
|
||||
|
@ -1637,8 +1697,17 @@ Error Image::_decompress_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 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;
|
||||
newdata.resize(size);
|
||||
|
@ -1648,7 +1717,8 @@ Error Image::_decompress_bc() {
|
|||
|
||||
int rofs=0;
|
||||
int wofs=0;
|
||||
int wd=width,ht=height;
|
||||
|
||||
//print_line("width: "+itos(wd)+" height: "+itos(ht));
|
||||
|
||||
for(int i=0;i<=mm;i++) {
|
||||
|
||||
|
@ -1953,6 +2023,11 @@ Error Image::_decompress_bc() {
|
|||
|
||||
data=newdata;
|
||||
format=FORMAT_RGBA;
|
||||
if (wd!=width || ht!=height) {
|
||||
//todo, crop
|
||||
width=wd;
|
||||
height=ht;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
@ -2022,7 +2097,7 @@ Image Image::compressed(int p_mode) {
|
|||
};
|
||||
|
||||
Image::Image(const char **p_xpm) {
|
||||
|
||||
|
||||
width=0;
|
||||
height=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 {
|
||||
|
||||
enum {
|
||||
enum {
|
||||
MAX_WIDTH=16384, // force a limit somehow
|
||||
MAX_HEIGHT=16384// force a limit somehow
|
||||
};
|
||||
|
@ -55,12 +55,12 @@ public:
|
|||
static SavePNGFunc save_png_func;
|
||||
|
||||
enum Format {
|
||||
FORMAT_GRAYSCALE, ///< 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_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_INDEXED, ///< index byte 0-256, and after image end, 256*3 bytes of palette
|
||||
FORMAT_GRAYSCALE, ///< 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_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_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_YUV_422,
|
||||
FORMAT_YUV_444,
|
||||
|
@ -89,7 +89,7 @@ public:
|
|||
|
||||
static const char* format_names[FORMAT_MAX];
|
||||
enum Interpolation {
|
||||
|
||||
|
||||
INTERPOLATE_NEAREST,
|
||||
INTERPOLATE_BILINEAR,
|
||||
INTERPOLATE_CUBIC,
|
||||
|
@ -186,7 +186,7 @@ private:
|
|||
DVector<uint8_t> data;
|
||||
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_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_height() const; ///< Get image height
|
||||
int get_mipmaps() const;
|
||||
|
||||
|
||||
/**
|
||||
* Get a pixel from the image. for grayscale or indexed formats, use Color::gray to obtain the actual
|
||||
* value.
|
||||
|
@ -217,7 +217,7 @@ public:
|
|||
* 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 */
|
||||
|
||||
|
||||
/**
|
||||
* Convert the image to another format, as close as it can be done.
|
||||
*/
|
||||
|
@ -230,7 +230,7 @@ public:
|
|||
ret.convert((Format)p_new_format);
|
||||
return ret;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the current image format.
|
||||
*/
|
||||
|
@ -243,31 +243,32 @@ public:
|
|||
/**
|
||||
* Resize the image, using the prefered interpolation method.
|
||||
* Indexed-Color images always use INTERPOLATE_NEAREST.
|
||||
*/
|
||||
*/
|
||||
|
||||
void resize_to_po2(bool p_square=false);
|
||||
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 );
|
||||
void shrink_x2();
|
||||
/**
|
||||
* 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 flip_x();
|
||||
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);
|
||||
|
||||
void clear_mipmaps();
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Generate a normal map from a grayscale image
|
||||
*/
|
||||
|
||||
|
||||
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, 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
|
||||
*/
|
||||
bool empty() const;
|
||||
|
||||
|
||||
DVector<uint8_t> get_data() const;
|
||||
|
||||
|
||||
Error load(const String& p_path);
|
||||
Error save_png(const String& p_path);
|
||||
|
||||
/**
|
||||
|
||||
/**
|
||||
* create an empty image
|
||||
*/
|
||||
Image();
|
||||
/**
|
||||
/**
|
||||
* create an empty image of a specific size and 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
|
||||
*/
|
||||
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;
|
||||
void set_pallete(const DVector<uint8_t>& p_data);
|
||||
|
||||
|
||||
|
||||
static int get_format_pixel_size(Format p_format);
|
||||
static int get_format_pixel_rshift(Format p_format);
|
||||
static int get_format_pallete_size(Format p_format);
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
/*************************************************************************/
|
||||
#include "input_map.h"
|
||||
#include "globals.h"
|
||||
#include "os/keyboard.h"
|
||||
|
||||
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("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_actions"),&InputMap::_get_actions);
|
||||
ObjectTypeDB::bind_method(_MD("add_action","action"),&InputMap::add_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_has_event","action","event"),&InputMap::action_has_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];
|
||||
}
|
||||
|
||||
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 {
|
||||
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
@ -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);
|
||||
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() {
|
||||
|
|
|
@ -47,6 +47,7 @@ class InputMap : public Object {
|
|||
List<InputEvent>::Element *_find_event(List<InputEvent> &p_list,const InputEvent& p_event) const;
|
||||
|
||||
Array _get_action_list(const StringName& p_action);
|
||||
Array _get_actions();
|
||||
|
||||
protected:
|
||||
|
||||
|
@ -59,6 +60,7 @@ public:
|
|||
bool has_action(const StringName& p_action) const;
|
||||
int get_action_id(const StringName& p_action) const;
|
||||
StringName get_action_from_id(int p_id) const;
|
||||
List<StringName> get_actions() const;
|
||||
void add_action(const StringName& p_action);
|
||||
void erase_action(const StringName& p_action);
|
||||
|
||||
|
@ -72,6 +74,7 @@ public:
|
|||
|
||||
|
||||
void load_from_globals();
|
||||
void load_default();
|
||||
|
||||
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.
|
||||
* 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
|
||||
* Other contributors: Hal Finney
|
||||
|
@ -24,14 +24,14 @@
|
|||
#include "typedefs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
uint8_t key[32];
|
||||
uint8_t enckey[32];
|
||||
uint8_t key[32];
|
||||
uint8_t enckey[32];
|
||||
uint8_t deckey[32];
|
||||
} aes256_context;
|
||||
} aes256_context;
|
||||
|
||||
|
||||
void aes256_init(aes256_context *, uint8_t * /* key */);
|
||||
|
|
|
@ -207,7 +207,7 @@ Error ConfigFile::load(const String& p_path) {
|
|||
void ConfigFile::_bind_methods(){
|
||||
|
||||
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_key","section","key"),&ConfigFile::has_section_key);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
FastLZ - lightning-fast lossless compression library
|
||||
|
||||
Copyright (C) 2007 Ariya Hidayat (ariya@kde.org)
|
||||
|
@ -40,11 +40,11 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
/**
|
||||
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
|
||||
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
|
||||
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.
|
||||
|
||||
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);
|
||||
|
||||
/**
|
||||
Decompress a block of compressed data and returns the size of the
|
||||
decompressed block. If error occurs, e.g. the compressed data is
|
||||
corrupted or the output buffer is not large enough, then 0 (zero)
|
||||
Decompress a block of compressed data and returns the size of the
|
||||
decompressed block. If error occurs, e.g. the compressed data is
|
||||
corrupted or the output buffer is not large enough, then 0 (zero)
|
||||
will be returned instead.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
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
|
||||
compressed block. The size of input buffer is specified by length. The
|
||||
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
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
Level 1 is the fastest compression and generally useful for short data.
|
||||
Level 2 is slightly slower but it gives better compression ratio.
|
||||
|
||||
Note that the compressed data, regardless of the level, can always be
|
||||
decompressed using the function fastlz_decompress above.
|
||||
*/
|
||||
*/
|
||||
|
||||
int fastlz_compress_level(int level, const void* input, int length, void* output);
|
||||
|
||||
|
|
|
@ -33,17 +33,17 @@
|
|||
#include "error_macros.h"
|
||||
|
||||
Error FileAccessBuffered::set_error(Error p_error) const {
|
||||
|
||||
|
||||
return (last_error = p_error);
|
||||
};
|
||||
|
||||
void FileAccessBuffered::set_cache_size(int p_size) {
|
||||
|
||||
|
||||
cache_size = p_size;
|
||||
};
|
||||
|
||||
int FileAccessBuffered::get_cache_size() {
|
||||
|
||||
|
||||
return cache_size;
|
||||
};
|
||||
|
||||
|
@ -66,27 +66,27 @@ int FileAccessBuffered::cache_data_left() const {
|
|||
};
|
||||
|
||||
void FileAccessBuffered::seek(size_t p_position) {
|
||||
|
||||
|
||||
file.offset = p_position;
|
||||
};
|
||||
|
||||
void FileAccessBuffered::seek_end(int64_t p_position) {
|
||||
|
||||
|
||||
file.offset = file.size + p_position;
|
||||
};
|
||||
|
||||
size_t FileAccessBuffered::get_pos() const {
|
||||
|
||||
|
||||
return file.offset;
|
||||
};
|
||||
|
||||
size_t FileAccessBuffered::get_len() const {
|
||||
|
||||
|
||||
return file.size;
|
||||
};
|
||||
|
||||
bool FileAccessBuffered::eof_reached() const {
|
||||
|
||||
|
||||
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 {
|
||||
|
||||
|
||||
return file.open;
|
||||
};
|
||||
|
||||
Error FileAccessBuffered::get_error() const {
|
||||
|
||||
|
||||
return last_error;
|
||||
};
|
||||
|
||||
|
@ -180,5 +180,5 @@ FileAccessBuffered::FileAccessBuffered() {
|
|||
};
|
||||
|
||||
FileAccessBuffered::~FileAccessBuffered(){
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -60,9 +60,9 @@ protected:
|
|||
String name;
|
||||
int access_flags;
|
||||
} file;
|
||||
|
||||
|
||||
mutable struct Cache {
|
||||
|
||||
|
||||
Vector<uint8_t> buffer;
|
||||
int offset;
|
||||
} cache;
|
||||
|
@ -71,7 +71,7 @@ protected:
|
|||
|
||||
void set_cache_size(int p_size);
|
||||
int get_cache_size();
|
||||
|
||||
|
||||
public:
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
CharString cs = p_password.utf8();
|
||||
CharString cs = p_password.utf8();
|
||||
put_32(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();
|
||||
connection=p_connection;
|
||||
status=STATUS_CONNECTED;
|
||||
|
||||
}
|
||||
|
||||
|
@ -301,6 +302,7 @@ Error HTTPClient::poll(){
|
|||
chunked=false;
|
||||
body_left=0;
|
||||
chunk_left=0;
|
||||
response_str.clear();
|
||||
response_headers.clear();
|
||||
response_num = RESPONSE_OK;
|
||||
|
||||
|
@ -309,7 +311,7 @@ Error HTTPClient::poll(){
|
|||
String header = responses[i].strip_edges();
|
||||
String s = header.to_lower();
|
||||
if (s.length()==0)
|
||||
continue;
|
||||
continue;
|
||||
if (s.begins_with("content-length:")) {
|
||||
body_size = s.substr(s.find(":")+1,s.length()).strip_edges().to_int();
|
||||
body_left=body_size;
|
||||
|
|
|
@ -40,7 +40,7 @@ class HTTPClient : public Reference {
|
|||
OBJ_TYPE(HTTPClient,Reference);
|
||||
public:
|
||||
|
||||
enum RespondeCode {
|
||||
enum ResponseCode {
|
||||
|
||||
// 1xx informational
|
||||
RESPONSE_CONTINUE = 100,
|
||||
|
|
|
@ -30,16 +30,16 @@
|
|||
|
||||
#include "print_string.h"
|
||||
bool ImageFormatLoader::recognize(const String& p_extension) const {
|
||||
|
||||
|
||||
|
||||
|
||||
List<String> extensions;
|
||||
get_recognized_extensions(&extensions);
|
||||
for (List<String>::Element *E=extensions.front();E;E=E->next()) {
|
||||
|
||||
|
||||
if (E->get().nocasecmp_to(p_extension.extension())==0)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -55,12 +55,12 @@ Error ImageLoader::load_image(String p_file,Image *p_image, FileAccess *p_custom
|
|||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
String extension = p_file.extension();
|
||||
|
||||
|
||||
for (int i=0;i<loader_count;i++) {
|
||||
|
||||
|
||||
if (!loader[i]->recognize(extension))
|
||||
continue;
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
print_line("NO LOADER?");
|
||||
|
||||
if (!p_custom)
|
||||
memdelete(f);
|
||||
|
||||
memdelete(f);
|
||||
|
||||
return ERR_FILE_UNRECOGNIZED;
|
||||
|
||||
}
|
||||
|
||||
void ImageLoader::get_recognized_extensions(List<String> *p_extensions) {
|
||||
|
||||
|
||||
for (int i=0;i<loader_count;i++) {
|
||||
|
||||
|
||||
loader[i]->get_recognized_extensions(p_extensions);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
bool ImageLoader::recognize(const String& p_extension) {
|
||||
|
|
|
@ -41,11 +41,11 @@
|
|||
/**
|
||||
* @class ImageScanLineLoader
|
||||
* @author Juan Linietsky <reduzio@gmail.com>
|
||||
*
|
||||
|
||||
*
|
||||
|
||||
*/
|
||||
class ImageLoader;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @class ImageLoader
|
||||
|
@ -60,8 +60,8 @@ protected:
|
|||
virtual Error load_image(Image *p_image,FileAccess *p_fileaccess)=0;
|
||||
virtual void get_recognized_extensions(List<String> *p_extensions) const=0;
|
||||
bool recognize(const String& p_extension) const;
|
||||
|
||||
|
||||
|
||||
|
||||
public:
|
||||
virtual ~ImageFormatLoader() {}
|
||||
};
|
||||
|
@ -79,11 +79,11 @@ protected:
|
|||
|
||||
|
||||
public:
|
||||
|
||||
|
||||
static Error load_image(String p_file,Image *p_image, FileAccess *p_custom=NULL);
|
||||
static void get_recognized_extensions(List<String> *p_extensions) ;
|
||||
static bool recognize(const String& p_extension) ;
|
||||
|
||||
|
||||
static void add_image_format_loader(ImageFormatLoader *p_loader);
|
||||
|
||||
};
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
Modifications for Zip64 support
|
||||
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
|
||||
Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
|
||||
|
||||
For more info read MiniZip_info.txt
|
||||
For more info read LICENSE-MiniZip.txt
|
||||
|
||||
Changes
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ struct _IP_ResolverPrivate {
|
|||
response = IP_Address();
|
||||
hostname="";
|
||||
};
|
||||
|
||||
|
||||
QueueItem() {
|
||||
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);
|
||||
r_variant=str;
|
||||
|
||||
if (r_len) {
|
||||
if (r_len) {
|
||||
if (strlen%4)
|
||||
(*r_len)+=4-strlen%4;
|
||||
(*r_len)+=4+strlen;
|
||||
|
@ -294,7 +294,7 @@ Error decode_variant(Variant& r_variant,const uint8_t *p_buffer, int p_len,int *
|
|||
} break;
|
||||
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);
|
||||
|
||||
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: {
|
||||
|
||||
ie.joy_motion.axis=decode_uint32(&buf[12]);
|
||||
ie.joy_motion.axis_value=decode_float(&buf[16]);
|
||||
if (r_len)
|
||||
(*r_len)+=4;
|
||||
(*r_len)+=8;
|
||||
} 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;
|
||||
|
||||
} break;
|
||||
} break;
|
||||
/*case Variant::RESOURCE: {
|
||||
|
||||
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;
|
||||
encode_uint32(axis,&buf[llen]);
|
||||
encode_float(ie.joy_motion.axis_value, &buf[llen+4]);
|
||||
}
|
||||
llen+=4;
|
||||
llen+=8;
|
||||
} 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;
|
||||
int datalen=data.size();
|
||||
int datasize=sizeof(uint8_t);
|
||||
|
||||
|
||||
if (buf) {
|
||||
encode_uint32(datalen,buf);
|
||||
buf+=4;
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
* Miscelaneous helpers for marshalling data types, and encoding
|
||||
* in an endian independent way
|
||||
*/
|
||||
|
||||
|
||||
|
||||
union MarshallFloat {
|
||||
|
||||
|
@ -54,22 +54,22 @@ union MarshallDouble {
|
|||
static inline unsigned int encode_uint16(uint16_t p_uint, uint8_t *p_arr) {
|
||||
|
||||
for (int i=0;i<2;i++) {
|
||||
|
||||
|
||||
*p_arr=p_uint&0xFF;
|
||||
p_arr++; p_uint>>=8;
|
||||
}
|
||||
|
||||
|
||||
return sizeof( uint16_t );
|
||||
}
|
||||
|
||||
static inline unsigned int encode_uint32(uint32_t p_uint, uint8_t *p_arr) {
|
||||
|
||||
for (int i=0;i<4;i++) {
|
||||
|
||||
|
||||
*p_arr=p_uint&0xFF;
|
||||
p_arr++; p_uint>>=8;
|
||||
}
|
||||
|
||||
|
||||
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) {
|
||||
|
||||
for (int i=0;i<8;i++) {
|
||||
|
||||
|
||||
*p_arr=p_uint&0xFF;
|
||||
p_arr++; p_uint>>=8;
|
||||
}
|
||||
|
||||
|
||||
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 );
|
||||
|
||||
return sizeof(uint64_t);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
static inline int encode_cstring(const char *p_string, uint8_t * p_data) {
|
||||
|
||||
int len=0;
|
||||
|
||||
|
||||
while (*p_string) {
|
||||
|
||||
if (p_data) {
|
||||
|
||||
|
||||
*p_data=(uint8_t)*p_string;
|
||||
p_data++;
|
||||
}
|
||||
p_string++;
|
||||
len++;
|
||||
};
|
||||
|
||||
|
||||
if (p_data) *p_data = 0;
|
||||
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) {
|
||||
|
||||
uint16_t u=0;
|
||||
|
||||
|
||||
for (int i=0;i<2;i++) {
|
||||
|
||||
|
||||
uint16_t b = *p_arr;
|
||||
b<<=(i*8);
|
||||
u|=b;
|
||||
p_arr++;
|
||||
}
|
||||
|
||||
|
||||
return u;
|
||||
}
|
||||
|
||||
static inline uint32_t decode_uint32(const uint8_t *p_arr) {
|
||||
|
||||
uint32_t u=0;
|
||||
|
||||
|
||||
for (int i=0;i<4;i++) {
|
||||
|
||||
|
||||
uint32_t b = *p_arr;
|
||||
b<<=(i*8);
|
||||
u|=b;
|
||||
p_arr++;
|
||||
}
|
||||
|
||||
|
||||
return u;
|
||||
}
|
||||
|
||||
static inline float decode_float(const uint8_t *p_arr) {
|
||||
|
||||
|
||||
MarshallFloat mf;
|
||||
mf.i = decode_uint32(p_arr);
|
||||
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) {
|
||||
|
||||
uint64_t u=0;
|
||||
|
||||
|
||||
for (int i=0;i<8;i++) {
|
||||
|
||||
|
||||
uint64_t b = (*p_arr)&0xFF;
|
||||
b<<=(i*8);
|
||||
u|=b;
|
||||
p_arr++;
|
||||
}
|
||||
|
||||
|
||||
return u;
|
||||
}
|
||||
|
||||
|
|
|
@ -126,7 +126,7 @@ Error PacketPeer::_get_packet_error() const {
|
|||
|
||||
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("get_packet"),&PacketPeer::_get_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);
|
||||
uint32_t len = decode_uint32(lbuf);
|
||||
remaining-=4;
|
||||
ofs+=4;
|
||||
ofs+=4;
|
||||
if (len>remaining)
|
||||
break;
|
||||
remaining-=len;
|
||||
remaining-=len;
|
||||
ofs+=len;
|
||||
count++;
|
||||
}
|
||||
|
@ -201,7 +201,7 @@ Error PacketPeerStream::get_packet(const uint8_t **r_buffer,int &r_buffer_size)
|
|||
uint8_t lbuf[4];
|
||||
ring_buffer.copy(lbuf,0,4);
|
||||
remaining-=4;
|
||||
uint32_t len = decode_uint32(lbuf);
|
||||
uint32_t len = decode_uint32(lbuf);
|
||||
ERR_FAIL_COND_V(remaining<(int)len,ERR_UNAVAILABLE);
|
||||
|
||||
ring_buffer.read(lbuf,4); //get rid of first 4 bytes
|
||||
|
|
|
@ -378,7 +378,7 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant& r_v) {
|
|||
} break;
|
||||
case OBJECT_INTERNAL_RESOURCE: {
|
||||
uint32_t index=f->get_32();
|
||||
String path = res_path+"::"+itos(index);
|
||||
String path = res_path+"::"+itos(index);
|
||||
RES res = ResourceLoader::load(path);
|
||||
if (res.is_null()) {
|
||||
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);
|
||||
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;
|
||||
p.pi=F->get();
|
||||
p.pi=F->get();
|
||||
|
||||
rd.properties.push_back(p);
|
||||
|
||||
|
|
|
@ -1818,7 +1818,7 @@ Error ResourceInteractiveLoaderXML::rename_dependencies(FileAccess *p_f, const S
|
|||
|
||||
void ResourceInteractiveLoaderXML::open(FileAccess *p_f) {
|
||||
|
||||
error=OK;
|
||||
error=OK;
|
||||
|
||||
lines=1;
|
||||
f=p_f;
|
||||
|
|
|
@ -49,16 +49,16 @@ Error ResourceInteractiveLoader::wait() {
|
|||
|
||||
|
||||
bool ResourceFormatLoader::recognize(const String& p_extension) const {
|
||||
|
||||
|
||||
|
||||
|
||||
List<String> extensions;
|
||||
get_recognized_extensions(&extensions);
|
||||
for (List<String>::Element *E=extensions.front();E;E=E->next()) {
|
||||
|
||||
|
||||
if (E->get().nocasecmp_to(p_extension.extension())==0)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
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();
|
||||
bool found=false;
|
||||
|
||||
|
||||
for (int i=0;i<loader_count;i++) {
|
||||
|
||||
|
||||
if (!loader[i]->recognize(extension))
|
||||
continue;
|
||||
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())
|
||||
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())
|
||||
|
@ -356,7 +360,7 @@ Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(const String &p_
|
|||
}
|
||||
|
||||
void ResourceLoader::add_resource_format_loader(ResourceFormatLoader *p_format_loader) {
|
||||
|
||||
|
||||
ERR_FAIL_COND( loader_count >= MAX_LOADERS );
|
||||
loader[loader_count++]=p_format_loader;
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ public:
|
|||
virtual Ref<Resource> get_resource()=0;
|
||||
virtual Error poll()=0;
|
||||
virtual int get_stage() const=0;
|
||||
virtual int get_stage_count() const=0;
|
||||
virtual int get_stage_count() const=0;
|
||||
virtual Error wait();
|
||||
|
||||
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);
|
||||
|
||||
|
||||
class ResourceLoader {
|
||||
|
||||
class ResourceLoader {
|
||||
|
||||
enum {
|
||||
MAX_LOADERS=64
|
||||
};
|
||||
|
||||
|
||||
static ResourceFormatLoader *loader[MAX_LOADERS];
|
||||
static int loader_count;
|
||||
static bool timestamp_on_load;
|
||||
|
@ -96,7 +96,7 @@ class ResourceLoader {
|
|||
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 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);
|
||||
|
|
|
@ -39,30 +39,30 @@ bool ResourceSaver::timestamp_on_save=false;
|
|||
ResourceSavedCallback ResourceSaver::save_callback=0;
|
||||
|
||||
Error ResourceSaver::save(const String &p_path,const RES& p_resource,uint32_t p_flags) {
|
||||
|
||||
|
||||
String extension=p_path.extension();
|
||||
Error err=ERR_FILE_UNRECOGNIZED;
|
||||
|
||||
for (int i=0;i<saver_count;i++) {
|
||||
|
||||
|
||||
if (!saver[i]->recognize(p_resource))
|
||||
continue;
|
||||
|
||||
|
||||
List<String> extensions;
|
||||
bool recognized=false;
|
||||
saver[i]->get_recognized_extensions(p_resource,&extensions);
|
||||
|
||||
|
||||
for (List<String>::Element *E=extensions.front();E;E=E->next()) {
|
||||
|
||||
|
||||
if (E->get().nocasecmp_to(extension.extension())==0)
|
||||
recognized=true;
|
||||
}
|
||||
|
||||
if (!recognized)
|
||||
continue;
|
||||
|
||||
|
||||
String old_path=p_resource->get_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;
|
||||
} else {
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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) {
|
||||
|
||||
|
||||
|
||||
for (int i=0;i<saver_count;i++) {
|
||||
|
||||
|
||||
saver[i]->get_recognized_extensions(p_resource,p_extensions);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void ResourceSaver::add_resource_format_saver(ResourceFormatSaver *p_format_saver) {
|
||||
|
||||
|
||||
ERR_FAIL_COND( saver_count >= MAX_SAVERS );
|
||||
saver[saver_count++]=p_format_saver;
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
|
||||
class ResourceFormatSaver {
|
||||
public:
|
||||
|
||||
|
||||
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 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);
|
||||
|
||||
class ResourceSaver {
|
||||
|
||||
class ResourceSaver {
|
||||
|
||||
enum {
|
||||
MAX_SAVERS=64
|
||||
};
|
||||
|
||||
|
||||
static ResourceFormatSaver *saver[MAX_SAVERS];
|
||||
static int saver_count;
|
||||
static bool timestamp_on_save;
|
||||
|
@ -86,7 +86,7 @@ public:
|
|||
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){
|
||||
|
||||
ERR_FAIL_COND_V(p_bytes<0,String());
|
||||
ERR_FAIL_COND_V(p_bytes<0,String());
|
||||
|
||||
Vector<uint8_t> buf;
|
||||
buf.resize(p_bytes);
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
Modifications for Zip64 support on both zip and unzip
|
||||
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
|
||||
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
|
||||
Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
|
||||
|
||||
For more info read MiniZip_info.txt
|
||||
For more info read LICENSE-MiniZip.txt
|
||||
|
||||
Changes
|
||||
Oct-2009 - Mathias Svensson - Remove old C style function prototypes
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
Modifications for Zip64 support
|
||||
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;
|
||||
|
||||
String fname;
|
||||
fname.parse_utf8(p_fname);
|
||||
|
||||
if (mode & ZLIB_FILEFUNC_MODE_WRITE) {
|
||||
f = FileAccess::open(p_fname,FileAccess::WRITE);
|
||||
f = FileAccess::open(fname,FileAccess::WRITE);
|
||||
} else {
|
||||
|
||||
f = FileAccess::open(p_fname,FileAccess::READ);
|
||||
f = FileAccess::open(fname,FileAccess::READ);
|
||||
}
|
||||
|
||||
if (!f)
|
||||
|
|
52
core/list.h
52
core/list.h
|
@ -245,7 +245,7 @@ public:
|
|||
_data->first=n;
|
||||
|
||||
_data->size_cache++;
|
||||
|
||||
|
||||
return n;
|
||||
};
|
||||
|
||||
|
@ -285,7 +285,7 @@ public:
|
|||
_data->last=n;
|
||||
|
||||
_data->size_cache++;
|
||||
|
||||
|
||||
return n;
|
||||
};
|
||||
|
||||
|
@ -363,30 +363,30 @@ public:
|
|||
}
|
||||
|
||||
void swap(Element* p_A, Element *p_B) {
|
||||
|
||||
|
||||
ERR_FAIL_COND(!p_A || !p_B);
|
||||
ERR_FAIL_COND(p_A->data!=_data);
|
||||
ERR_FAIL_COND(p_B->data!=_data);
|
||||
|
||||
|
||||
Element* A_prev=p_A->prev_ptr;
|
||||
Element* A_next=p_A->next_ptr;
|
||||
|
||||
|
||||
p_A->next_ptr=p_B->next_ptr;
|
||||
p_A->prev_ptr=p_B->prev_ptr;
|
||||
|
||||
|
||||
p_B->next_ptr=A_next;
|
||||
p_B->prev_ptr=A_prev;
|
||||
|
||||
p_B->prev_ptr=A_prev;
|
||||
|
||||
if (p_A->prev_ptr)
|
||||
p_A->prev_ptr->next_ptr=p_A;
|
||||
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)
|
||||
p_B->prev_ptr->next_ptr=p_B;
|
||||
if (p_B->next_ptr)
|
||||
p_B->next_ptr->prev_ptr=p_B;
|
||||
|
||||
p_B->next_ptr->prev_ptr=p_B;
|
||||
|
||||
}
|
||||
/**
|
||||
* copy the list
|
||||
|
@ -552,10 +552,10 @@ public:
|
|||
*/
|
||||
|
||||
void sort() {
|
||||
|
||||
|
||||
sort_custom< Comparator<T> >();
|
||||
}
|
||||
|
||||
|
||||
template<class C>
|
||||
void sort_custom_inplace() {
|
||||
|
||||
|
@ -565,44 +565,44 @@ public:
|
|||
Element *from=front();
|
||||
Element *current=from;
|
||||
Element *to=from;
|
||||
|
||||
|
||||
while(current) {
|
||||
|
||||
|
||||
Element *next=current->next_ptr;
|
||||
|
||||
|
||||
//disconnect
|
||||
current->next_ptr=NULL;
|
||||
|
||||
|
||||
if (from!=current) {
|
||||
|
||||
|
||||
current->prev_ptr=NULL;
|
||||
current->next_ptr=from;
|
||||
|
||||
|
||||
Element *find=from;
|
||||
C less;
|
||||
while( find && less(find->value,current->value) ) {
|
||||
|
||||
|
||||
current->prev_ptr=find;
|
||||
current->next_ptr=find->next_ptr;
|
||||
find=find->next_ptr;
|
||||
}
|
||||
|
||||
|
||||
if (current->prev_ptr)
|
||||
current->prev_ptr->next_ptr=current;
|
||||
else
|
||||
from=current;
|
||||
|
||||
|
||||
if (current->next_ptr)
|
||||
current->next_ptr->prev_ptr=current;
|
||||
else
|
||||
to=current;
|
||||
} else {
|
||||
|
||||
|
||||
current->prev_ptr=NULL;
|
||||
current->next_ptr=NULL;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
current=next;
|
||||
}
|
||||
_data->first=from;
|
||||
|
|
|
@ -6,7 +6,7 @@ template_typed="""
|
|||
template<class T $ifret ,class R$ $ifargs ,$ $arg, class P@$>
|
||||
class MethodBind$argc$$ifret R$$ifconst C$ : public MethodBind {
|
||||
public:
|
||||
|
||||
|
||||
$ifret R$ $ifnoret void$ (T::*method)($arg, P@$) $ifconst const$;
|
||||
#ifdef DEBUG_METHODS_ENABLED
|
||||
virtual Variant::Type _gen_argument_type(int p_arg) const { return _get_argument_type(p_arg); }
|
||||
|
@ -16,13 +16,13 @@ public:
|
|||
$
|
||||
return Variant::NIL;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
virtual String get_instance_type() const {
|
||||
return T::get_type_static();
|
||||
}
|
||||
|
||||
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>();
|
||||
r_error.error=Variant::CallError::CALL_OK;
|
||||
#ifdef DEBUG_METHODS_ENABLED
|
||||
|
@ -47,7 +47,7 @@ public:
|
|||
$ifret return Variant(ret);$
|
||||
$ifnoret return Variant();$
|
||||
}
|
||||
|
||||
|
||||
|
||||
MethodBind$argc$$ifret R$$ifconst C$ () {
|
||||
#ifdef DEBUG_METHODS_ENABLED
|
||||
|
@ -55,14 +55,14 @@ public:
|
|||
_generate_argument_types($argc$);
|
||||
#else
|
||||
set_argument_count($argc$);
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
};
|
||||
|
||||
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$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;
|
||||
return a;
|
||||
}
|
||||
|
@ -88,7 +88,7 @@ public:
|
|||
$
|
||||
return Variant::NIL;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
virtual String get_instance_type() const {
|
||||
return type_name;
|
||||
}
|
||||
|
@ -105,15 +105,15 @@ public:
|
|||
r_error.error=Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
|
||||
r_error.argument=get_argument_count();
|
||||
return Variant();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (p_arg_count<(get_argument_count()-get_default_argument_count())) {
|
||||
|
||||
r_error.error=Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
|
||||
r_error.argument=get_argument_count()-get_default_argument_count();
|
||||
return Variant();
|
||||
}
|
||||
|
||||
|
||||
$arg CHECK_ARG(@);
|
||||
$
|
||||
#endif
|
||||
|
@ -128,7 +128,7 @@ public:
|
|||
_generate_argument_types($argc$);
|
||||
#else
|
||||
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):
|
||||
|
||||
|
||||
intext=template
|
||||
from_pos=0
|
||||
outtext=""
|
||||
|
||||
while(True):
|
||||
|
||||
while(True):
|
||||
to_pos=intext.find("$",from_pos)
|
||||
if (to_pos==-1):
|
||||
outtext+=intext[from_pos:]
|
||||
|
@ -169,13 +169,13 @@ def make_version(template,nargs,argmax,const,ret):
|
|||
macro=intext[to_pos+1:end]
|
||||
cmd=""
|
||||
data=""
|
||||
|
||||
|
||||
if (macro.find(" ")!=-1):
|
||||
cmd=macro[0:macro.find(" ")]
|
||||
data=macro[macro.find(" ")+1:]
|
||||
else:
|
||||
cmd=macro
|
||||
|
||||
|
||||
if (cmd=="argc"):
|
||||
outtext+=str(nargs)
|
||||
if (cmd=="ifret" and ret):
|
||||
|
@ -206,11 +206,11 @@ def make_version(template,nargs,argmax,const,ret):
|
|||
elif (cmd=="noarg"):
|
||||
for i in range(nargs+1,argmax+1):
|
||||
outtext+=data.replace("@",str(i))
|
||||
|
||||
|
||||
from_pos=end+1
|
||||
|
||||
|
||||
return outtext
|
||||
|
||||
|
||||
|
||||
def run(target, source, env):
|
||||
|
||||
|
@ -244,9 +244,9 @@ def run(target, source, env):
|
|||
f.write(text_ext)
|
||||
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>
|
||||
class Map {
|
||||
|
||||
enum Color {
|
||||
|
||||
enum Color {
|
||||
RED,
|
||||
BLACK
|
||||
};
|
||||
struct _Data;
|
||||
struct _Data;
|
||||
public:
|
||||
|
||||
class Element {
|
||||
|
@ -66,34 +66,34 @@ public:
|
|||
public:
|
||||
|
||||
const Element *next() const {
|
||||
|
||||
|
||||
return _next;
|
||||
}
|
||||
Element *next() {
|
||||
|
||||
|
||||
return _next;
|
||||
}
|
||||
const Element *prev() const {
|
||||
|
||||
|
||||
return _prev;
|
||||
}
|
||||
Element *prev() {
|
||||
|
||||
|
||||
return _prev;
|
||||
}
|
||||
const K& key() const {
|
||||
const K& key() const {
|
||||
return _key;
|
||||
};
|
||||
V& value() {
|
||||
V& value() {
|
||||
return _value;
|
||||
};
|
||||
const V& value() const {
|
||||
const V& value() const {
|
||||
return _value;
|
||||
};
|
||||
V& get() {
|
||||
V& get() {
|
||||
return _value;
|
||||
};
|
||||
const V& get() const {
|
||||
const V& get() const {
|
||||
return _value;
|
||||
};
|
||||
Element() {
|
||||
|
@ -106,15 +106,15 @@ public:
|
|||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
private:
|
||||
|
||||
struct _Data {
|
||||
|
||||
|
||||
Element* _root;
|
||||
Element* _nil;
|
||||
int size_cache;
|
||||
|
||||
|
||||
_FORCE_INLINE_ _Data() {
|
||||
#ifdef GLOBALNIL_DISABLED
|
||||
_nil = memnew_allocator( Element, A );
|
||||
|
@ -126,7 +126,7 @@ private:
|
|||
_root=NULL;
|
||||
size_cache=0;
|
||||
}
|
||||
|
||||
|
||||
void _create_root() {
|
||||
|
||||
_root = memnew_allocator( Element,A );
|
||||
|
@ -145,23 +145,23 @@ private:
|
|||
~_Data() {
|
||||
|
||||
_free_root();
|
||||
|
||||
|
||||
#ifdef GLOBALNIL_DISABLED
|
||||
memdelete_allocator<Element,A>(_nil);
|
||||
#endif
|
||||
// memdelete_allocator<Element,A>(_root);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
_Data _data;
|
||||
|
||||
|
||||
inline void _set_color(Element *p_node, int p_color) {
|
||||
|
||||
|
||||
ERR_FAIL_COND( p_node == _data._nil && p_color == RED );
|
||||
p_node->color=p_color;
|
||||
}
|
||||
inline void _rotate_left(Element *p_node) {
|
||||
|
||||
|
||||
Element *r=p_node->right;
|
||||
p_node->right=r->left;
|
||||
if (r->left != _data._nil )
|
||||
|
@ -171,14 +171,14 @@ private:
|
|||
p_node->parent->left=r;
|
||||
else
|
||||
p_node->parent->right=r;
|
||||
|
||||
|
||||
r->left=p_node;
|
||||
p_node->parent=r;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
inline void _rotate_right(Element *p_node) {
|
||||
|
||||
|
||||
Element *l=p_node->left;
|
||||
p_node->left=l->right;
|
||||
if (l->right != _data._nil)
|
||||
|
@ -188,25 +188,25 @@ private:
|
|||
p_node->parent->right=l;
|
||||
else
|
||||
p_node->parent->left=l;
|
||||
|
||||
|
||||
l->right=p_node;
|
||||
p_node->parent=l;
|
||||
|
||||
|
||||
}
|
||||
|
||||
inline Element* _successor(Element *p_node) const {
|
||||
|
||||
|
||||
inline Element* _successor(Element *p_node) const {
|
||||
|
||||
Element *node=p_node;
|
||||
|
||||
|
||||
if (node->right != _data._nil) {
|
||||
|
||||
|
||||
node=node->right;
|
||||
while(node->left != _data._nil) { /* returns the minium of the right subtree of node */
|
||||
node=node->left;
|
||||
}
|
||||
return node;
|
||||
} else {
|
||||
|
||||
|
||||
while(node == node->parent->right) {
|
||||
node=node->parent;
|
||||
}
|
||||
|
@ -215,44 +215,44 @@ private:
|
|||
return node->parent;
|
||||
}
|
||||
}
|
||||
|
||||
inline Element* _predecessor(Element *p_node) const {
|
||||
|
||||
inline Element* _predecessor(Element *p_node) const {
|
||||
Element *node=p_node;
|
||||
|
||||
|
||||
if (node->left != _data._nil) {
|
||||
|
||||
|
||||
node=node->left;
|
||||
while(node->right != _data._nil) { /* returns the minium of the left subtree of node */
|
||||
node=node->right;
|
||||
}
|
||||
return node;
|
||||
} else {
|
||||
|
||||
|
||||
while(node == node->parent->left) {
|
||||
if (node->parent == _data._root)
|
||||
return NULL;
|
||||
return NULL;
|
||||
node=node->parent;
|
||||
}
|
||||
return node->parent;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Element *_find(const K& p_key) const {
|
||||
|
||||
|
||||
Element *node = _data._root->left;
|
||||
C less;
|
||||
|
||||
C less;
|
||||
|
||||
while(node!=_data._nil) {
|
||||
|
||||
if (less(p_key,node->_key))
|
||||
|
||||
if (less(p_key,node->_key))
|
||||
node=node->left;
|
||||
else if (less(node->_key,p_key))
|
||||
node=node->right;
|
||||
else
|
||||
break; // found
|
||||
}
|
||||
|
||||
|
||||
return (node!=_data._nil)?node:NULL;
|
||||
}
|
||||
|
||||
|
@ -289,73 +289,73 @@ private:
|
|||
}
|
||||
|
||||
Element *_insert(const K& p_key, bool& r_exists) {
|
||||
|
||||
|
||||
Element *new_parent=_data._root;
|
||||
Element *node = _data._root->left;
|
||||
C less;
|
||||
|
||||
C less;
|
||||
|
||||
while (node!=_data._nil) {
|
||||
|
||||
|
||||
new_parent=node;
|
||||
|
||||
|
||||
if (less(p_key,node->_key))
|
||||
node=node->left;
|
||||
else if (less(node->_key,p_key))
|
||||
node=node->right;
|
||||
else {
|
||||
else {
|
||||
r_exists=true;
|
||||
return node;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Element *new_node = memnew_allocator( Element, A );
|
||||
|
||||
|
||||
|
||||
new_node->parent=new_parent;
|
||||
new_node->right=_data._nil;
|
||||
new_node->left=_data._nil;
|
||||
new_node->_key=p_key;
|
||||
//new_node->data=_data;
|
||||
if (new_parent==_data._root || less(p_key,new_parent->_key)) {
|
||||
|
||||
|
||||
new_parent->left=new_node;
|
||||
} else {
|
||||
new_parent->right=new_node;
|
||||
}
|
||||
|
||||
|
||||
r_exists=false;
|
||||
|
||||
|
||||
new_node->_next=_successor(new_node);
|
||||
new_node->_prev=_predecessor(new_node);
|
||||
if (new_node->_next)
|
||||
new_node->_next->_prev=new_node;
|
||||
if (new_node->_prev)
|
||||
new_node->_prev->_next=new_node;
|
||||
|
||||
|
||||
|
||||
return new_node;
|
||||
}
|
||||
|
||||
|
||||
Element * _insert_rb(const K& p_key, const V& p_value) {
|
||||
|
||||
|
||||
bool exists=false;
|
||||
Element *new_node = _insert(p_key,exists);
|
||||
|
||||
|
||||
if (new_node) {
|
||||
new_node->_value=p_value;
|
||||
}
|
||||
if (exists)
|
||||
return new_node;
|
||||
|
||||
|
||||
Element *node=new_node;
|
||||
_data.size_cache++;
|
||||
|
||||
while(node->parent->color==RED) {
|
||||
|
||||
while(node->parent->color==RED) {
|
||||
|
||||
if (node->parent == node->parent->parent->left) {
|
||||
|
||||
|
||||
Element *aux=node->parent->parent->right;
|
||||
|
||||
|
||||
if (aux->color==RED) {
|
||||
_set_color(node->parent,BLACK);
|
||||
_set_color(aux,BLACK);
|
||||
|
@ -369,10 +369,10 @@ private:
|
|||
_set_color(node->parent,BLACK);
|
||||
_set_color(node->parent->parent,RED);
|
||||
_rotate_right(node->parent->parent);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
} else {
|
||||
Element *aux=node->parent->parent->left;
|
||||
|
||||
|
||||
if (aux->color==RED) {
|
||||
_set_color(node->parent,BLACK);
|
||||
_set_color(aux,BLACK);
|
||||
|
@ -386,19 +386,19 @@ private:
|
|||
_set_color(node->parent,BLACK);
|
||||
_set_color(node->parent->parent,RED);
|
||||
_rotate_left(node->parent->parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_set_color(_data._root->left,BLACK);
|
||||
return new_node;
|
||||
}
|
||||
return new_node;
|
||||
}
|
||||
|
||||
void _erase_fix(Element *p_node) {
|
||||
|
||||
|
||||
Element *root = _data._root->left;
|
||||
Element *node=p_node;
|
||||
|
||||
|
||||
|
||||
|
||||
while( (node->color==BLACK) && (root != node)) {
|
||||
if (node == node->parent->left) {
|
||||
Element *aux=node->parent->right;
|
||||
|
@ -408,7 +408,7 @@ private:
|
|||
_rotate_left(node->parent);
|
||||
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);
|
||||
node=node->parent;
|
||||
} else {
|
||||
|
@ -432,7 +432,7 @@ private:
|
|||
_rotate_right(node->parent);
|
||||
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);
|
||||
node=node->parent;
|
||||
} else {
|
||||
|
@ -446,24 +446,24 @@ private:
|
|||
_set_color(node->parent,BLACK);
|
||||
_set_color(aux->left,BLACK);
|
||||
_rotate_right(node->parent);
|
||||
node=root;
|
||||
node=root;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
_set_color(node,BLACK);
|
||||
|
||||
|
||||
ERR_FAIL_COND(_data._nil->color!=BLACK);
|
||||
}
|
||||
|
||||
|
||||
void _erase(Element *p_node) {
|
||||
|
||||
|
||||
|
||||
|
||||
Element *rp= ((p_node->left == _data._nil) || (p_node->right == _data._nil)) ? p_node : _successor(p_node);
|
||||
if (!rp)
|
||||
rp=_data._nil;
|
||||
Element *node= (rp->left == _data._nil) ? rp->right : rp->left;
|
||||
|
||||
|
||||
if (_data._root == (node->parent=rp->parent) ) {
|
||||
_data._root->left=node;
|
||||
} else {
|
||||
|
@ -473,47 +473,47 @@ private:
|
|||
rp->parent->right=node;
|
||||
}
|
||||
}
|
||||
|
||||
if (rp != p_node) {
|
||||
|
||||
|
||||
if (rp != p_node) {
|
||||
|
||||
ERR_FAIL_COND( rp == _data._nil );
|
||||
|
||||
|
||||
if (rp->color==BLACK)
|
||||
_erase_fix(node);
|
||||
|
||||
|
||||
|
||||
|
||||
rp->left=p_node->left;
|
||||
rp->right=p_node->right;
|
||||
rp->parent=p_node->parent;
|
||||
rp->color=p_node->color;
|
||||
p_node->left->parent=rp;
|
||||
p_node->right->parent=rp;
|
||||
|
||||
|
||||
if (p_node == p_node->parent->left) {
|
||||
p_node->parent->left=rp;
|
||||
p_node->parent->left=rp;
|
||||
} else {
|
||||
p_node->parent->right=rp;
|
||||
}
|
||||
} else {
|
||||
if (p_node->color==BLACK)
|
||||
if (p_node->color==BLACK)
|
||||
_erase_fix(node);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if (p_node->_next)
|
||||
p_node->_next->_prev=p_node->_prev;
|
||||
if (p_node->_prev)
|
||||
p_node->_prev->_next=p_node->_next;
|
||||
|
||||
|
||||
memdelete_allocator<Element,A>(p_node);
|
||||
_data.size_cache--;
|
||||
ERR_FAIL_COND( _data._nil->color==RED );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void _calculate_depth(Element *p_element,int &max_d,int d) const {
|
||||
|
||||
|
||||
if (p_element==_data._nil) {
|
||||
return;
|
||||
}
|
||||
|
@ -522,23 +522,23 @@ private:
|
|||
if (d>max_d)
|
||||
max_d=d;
|
||||
}
|
||||
|
||||
|
||||
void _cleanup_tree(Element *p_element) {
|
||||
|
||||
|
||||
if (p_element==_data._nil)
|
||||
return;
|
||||
|
||||
|
||||
_cleanup_tree(p_element->left);
|
||||
_cleanup_tree(p_element->right);
|
||||
memdelete_allocator<Element,A>( p_element );
|
||||
}
|
||||
|
||||
|
||||
void _copy_from( const Map& p_map) {
|
||||
|
||||
|
||||
clear();
|
||||
// not the fastest way, but safeset to write.
|
||||
for(Element *I=p_map.front();I;I=I->next()) {
|
||||
|
||||
|
||||
insert(I->key(),I->value());
|
||||
}
|
||||
}
|
||||
|
@ -554,7 +554,7 @@ public:
|
|||
}
|
||||
|
||||
Element *find(const K& p_key) {
|
||||
|
||||
|
||||
if (!_data._root)
|
||||
return NULL;
|
||||
Element *res=_find(p_key);
|
||||
|
@ -578,15 +578,15 @@ public:
|
|||
}
|
||||
|
||||
Element *insert(const K& p_key,const V& p_value) {
|
||||
|
||||
|
||||
if (!_data._root)
|
||||
_data._create_root();
|
||||
return _insert_rb(p_key,p_value);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void erase(Element* p_element) {
|
||||
|
||||
|
||||
if (!_data._root)
|
||||
return;
|
||||
_erase(p_element);
|
||||
|
@ -595,72 +595,72 @@ public:
|
|||
}
|
||||
|
||||
bool erase(const K& p_key) {
|
||||
|
||||
|
||||
if (!_data._root)
|
||||
return false;
|
||||
Element *e=find(p_key);
|
||||
if (!e)
|
||||
return false;
|
||||
_erase(e);
|
||||
_erase(e);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool has(const K& p_key) const {
|
||||
|
||||
|
||||
if (!_data._root)
|
||||
return false;
|
||||
return find(p_key) != NULL;
|
||||
}
|
||||
|
||||
|
||||
const V& operator[](const K& p_key) const {
|
||||
|
||||
|
||||
ERR_FAIL_COND_V(!_data._root, *(V*)NULL); // crash on purpose
|
||||
const Element *e=find(p_key);
|
||||
ERR_FAIL_COND_V(!e, *(V*)NULL); // crash on purpose
|
||||
return e->_value;
|
||||
}
|
||||
V& operator[](const K& p_key) {
|
||||
|
||||
|
||||
if (!_data._root)
|
||||
_data._create_root();
|
||||
|
||||
Element *e=find(p_key);
|
||||
if (!e)
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
Element *front() const {
|
||||
|
||||
|
||||
if (!_data._root)
|
||||
return NULL;
|
||||
|
||||
Element *e=_data._root->left;
|
||||
if (e==_data._nil)
|
||||
return NULL;
|
||||
|
||||
|
||||
while(e->left!=_data._nil)
|
||||
e=e->left;
|
||||
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
|
||||
Element *back() const {
|
||||
|
||||
|
||||
if (!_data._root)
|
||||
return NULL;
|
||||
Element *e=_data._root->left;
|
||||
if (e==_data._nil)
|
||||
return NULL;
|
||||
|
||||
|
||||
while(e->right!=_data._nil)
|
||||
e=e->right;
|
||||
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
|
||||
inline bool empty() const { return _data.size_cache==0; }
|
||||
inline int size() const { return _data.size_cache; }
|
||||
int calculate_depth() const {
|
||||
|
@ -671,9 +671,9 @@ public:
|
|||
_calculate_depth(_data._root->left,max_d,0);
|
||||
return max_d;
|
||||
}
|
||||
|
||||
|
||||
void clear() {
|
||||
|
||||
|
||||
if (!_data._root)
|
||||
return;
|
||||
_cleanup_tree(_data._root->left);
|
||||
|
@ -682,25 +682,25 @@ public:
|
|||
_data._nil->parent=_data._nil;
|
||||
_data._free_root();
|
||||
}
|
||||
|
||||
|
||||
void operator=(const Map& p_map) {
|
||||
|
||||
|
||||
_copy_from( p_map );
|
||||
}
|
||||
|
||||
|
||||
Map(const Map& p_map) {
|
||||
|
||||
|
||||
_copy_from( p_map );
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ Map() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
~Map() {
|
||||
|
||||
clear();
|
||||
|
||||
clear();
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
@ -47,21 +47,21 @@ public:
|
|||
|
||||
float get_area() const; /// get area
|
||||
_FORCE_INLINE_ bool has_no_area() const {
|
||||
|
||||
|
||||
return (size.x<=CMP_EPSILON || size.y<=CMP_EPSILON || size.z<=CMP_EPSILON);
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ bool has_no_surface() const {
|
||||
|
||||
|
||||
return (size.x<=CMP_EPSILON && size.y<=CMP_EPSILON && size.z<=CMP_EPSILON);
|
||||
}
|
||||
|
||||
|
||||
const Vector3& get_pos() const { return pos; }
|
||||
void set_pos(const Vector3& p_pos) { pos=p_pos; }
|
||||
const Vector3& get_size() const { return 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;
|
||||
|
||||
|
@ -265,7 +265,7 @@ bool AABB::has_point(const Vector3& p_point) const {
|
|||
return false;
|
||||
if (p_point.z>pos.z+size.z)
|
||||
return false;
|
||||
|
||||
|
||||
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 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 distance = p_plane.distance_to( center );
|
||||
r_min = distance - length;
|
||||
r_max = distance + length;
|
||||
r_max = distance + length;
|
||||
}
|
||||
|
||||
inline real_t AABB::get_longest_axis_size() const {
|
||||
|
|
|
@ -66,12 +66,12 @@ Vector<Plane> BSP_Tree::get_planes() const {
|
|||
|
||||
return planes;
|
||||
}
|
||||
|
||||
|
||||
AABB BSP_Tree::get_aabb() const {
|
||||
|
||||
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 {
|
||||
|
||||
|
||||
|
@ -245,22 +245,22 @@ bool BSP_Tree::point_is_inside(const Vector3& p_point) const {
|
|||
if (!aabb.has_point(p_point)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
int node_count=nodes.size();
|
||||
|
||||
|
||||
if (node_count==0) // no nodes!
|
||||
return false;
|
||||
|
||||
|
||||
|
||||
|
||||
const Node *nodesptr=&nodes[0];
|
||||
const Plane *planesptr=&planes[0];
|
||||
int plane_count=planes.size();
|
||||
|
||||
|
||||
int idx=node_count-1;
|
||||
int steps=0;
|
||||
|
||||
|
||||
while(true) {
|
||||
|
||||
|
||||
if (idx==OVER_LEAF) {
|
||||
return false;
|
||||
}
|
||||
|
@ -268,28 +268,28 @@ bool BSP_Tree::point_is_inside(const Vector3& p_point) const {
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
uint16_t plane=nodesptr[ idx ].plane;
|
||||
#ifdef DEBUG_ENABLED
|
||||
|
||||
|
||||
ERR_FAIL_INDEX_V( plane, plane_count, false );
|
||||
#endif
|
||||
bool over = planesptr[ nodesptr[ idx ].plane ].is_point_over(p_point);
|
||||
|
||||
idx = over ? nodes[ idx ].over : nodes[ idx ].under;
|
||||
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
|
||||
|
||||
ERR_FAIL_COND_V( idx<MAX_NODES && idx>=node_count, false );
|
||||
#endif
|
||||
|
||||
|
||||
steps++;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static int _bsp_find_best_half_plane(const Face3* p_faces,const Vector<int>& p_indices,float p_tolerance) {
|
||||
|
||||
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] ];
|
||||
Plane p = f.get_plane();
|
||||
|
||||
|
||||
int num_over=0,num_under=0,num_spanning=0;
|
||||
|
||||
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++;
|
||||
else
|
||||
num_under++;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//double split_cost = num_spanning / (double) face_count;
|
||||
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
|
||||
// in this engine, also, will likely be ignored anyway
|
||||
|
||||
|
||||
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);
|
||||
|
@ -360,10 +360,10 @@ static int _bsp_find_best_half_plane(const Face3* p_faces,const Vector<int>& p_i
|
|||
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) {
|
||||
|
||||
|
||||
ERR_FAIL_COND_V( p_nodes.size() == BSP_Tree::MAX_NODES, -1 );
|
||||
|
||||
// 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)
|
||||
continue;
|
||||
|
||||
|
||||
const Face3& f=p_faces[ indices[i] ];
|
||||
|
||||
//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;
|
||||
|
||||
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 */
|
||||
|
||||
|
||||
// find existing divisor plane
|
||||
int divisor_plane_idx=-1;
|
||||
|
||||
|
||||
|
||||
|
||||
for (int i=0;i<p_planes.size();i++) {
|
||||
|
||||
|
||||
if (p_planes[i].is_almost_like( divisor_plane )) {
|
||||
divisor_plane_idx=i;
|
||||
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) {
|
||||
|
||||
|
||||
ERR_FAIL_COND_V( p_planes.size() == BSP_Tree::MAX_PLANES, -1 );
|
||||
divisor_plane_idx=p_planes.size();
|
||||
p_planes.push_back( divisor_plane );
|
||||
}
|
||||
|
||||
|
||||
BSP_Tree::Node node;
|
||||
node.plane=divisor_plane_idx;
|
||||
node.under=under_idx;
|
||||
node.over=over_idx;
|
||||
|
||||
|
||||
p_nodes.push_back(node);
|
||||
|
||||
|
||||
return p_nodes.size()-1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
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) {
|
||||
|
||||
// compute aabb
|
||||
|
||||
|
||||
int face_count=p_faces.size();
|
||||
DVector<Face3>::Read faces_r=p_faces.read();
|
||||
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;
|
||||
|
||||
for (int i=0;i<face_count;i++) {
|
||||
|
||||
|
||||
const Face3& f=facesptr[i];
|
||||
|
||||
|
||||
if (f.is_degenerate())
|
||||
continue;
|
||||
|
||||
|
||||
for (int j=0;j<3;j++) {
|
||||
|
||||
|
||||
if (first) {
|
||||
|
||||
|
||||
aabb.pos=f.vertex[0];
|
||||
first=false;
|
||||
} else {
|
||||
|
||||
|
||||
aabb.expand_to(f.vertex[j]);
|
||||
}
|
||||
}
|
||||
|
||||
indices.push_back(i);
|
||||
|
||||
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ class BSP_Tree {
|
|||
public:
|
||||
|
||||
enum {
|
||||
|
||||
|
||||
UNDER_LEAF=0xFFFF,
|
||||
OVER_LEAF=0xFFFE,
|
||||
MAX_NODES=0xFFFE,
|
||||
|
@ -51,22 +51,22 @@ public:
|
|||
};
|
||||
|
||||
struct Node {
|
||||
|
||||
|
||||
uint16_t plane;
|
||||
uint16_t under;
|
||||
uint16_t over;
|
||||
};
|
||||
|
||||
|
||||
private:
|
||||
// thanks to the properties of Vector,
|
||||
|
||||
private:
|
||||
// thanks to the properties of Vector,
|
||||
// this class can be assigned and passed around between threads
|
||||
// with no cost.
|
||||
|
||||
|
||||
Vector<Node> nodes;
|
||||
Vector<Plane> planes;
|
||||
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;
|
||||
|
||||
|
@ -79,8 +79,8 @@ public:
|
|||
Vector<Node> get_nodes() const;
|
||||
Vector<Plane> get_planes() 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;
|
||||
template<class T>
|
||||
bool convex_is_inside(const T& p_convex) const;
|
||||
|
@ -91,8 +91,8 @@ public:
|
|||
|
||||
BSP_Tree();
|
||||
BSP_Tree(const Variant& p_variant);
|
||||
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 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();
|
||||
|
||||
};
|
||||
|
|
|
@ -33,9 +33,9 @@
|
|||
void CameraMatrix::set_identity() {
|
||||
|
||||
for (int i=0;i<4;i++) {
|
||||
|
||||
|
||||
for (int j=0;j<4;j++) {
|
||||
|
||||
|
||||
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][3] = -1;
|
||||
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 {
|
||||
|
||||
const float * matrix = (const float*)this->matrix;
|
||||
|
||||
const float * matrix = (const float*)this->matrix;
|
||||
Plane new_plane=Plane(matrix[ 3] - matrix[ 2],
|
||||
matrix[ 7] - matrix[ 6],
|
||||
matrix[11] - matrix[10],
|
||||
matrix[15] - matrix[14]);
|
||||
|
||||
|
||||
new_plane.normal=-new_plane.normal;
|
||||
new_plane.normalize();
|
||||
|
||||
|
||||
return new_plane.d;
|
||||
}
|
||||
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],
|
||||
matrix[ 7] + matrix[ 6],
|
||||
matrix[11] + matrix[10],
|
||||
-matrix[15] - matrix[14]);
|
||||
|
||||
|
||||
new_plane.normalize();
|
||||
return new_plane.d;
|
||||
}
|
||||
|
||||
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 ---///////
|
||||
Plane near_plane=Plane(matrix[ 3] + matrix[ 2],
|
||||
matrix[ 7] + matrix[ 6],
|
||||
matrix[11] + matrix[10],
|
||||
-matrix[15] - matrix[14]).normalized();
|
||||
|
||||
|
||||
///////--- Right Plane ---///////
|
||||
Plane right_plane=Plane(matrix[ 3] - matrix[ 0],
|
||||
matrix[ 7] - matrix[ 4],
|
||||
matrix[11] - matrix[ 8],
|
||||
- matrix[15] + matrix[12]).normalized();
|
||||
|
||||
|
||||
Plane top_plane=Plane(matrix[ 3] - matrix[ 1],
|
||||
matrix[ 7] - matrix[ 5],
|
||||
matrix[11] - matrix[ 9],
|
||||
-matrix[15] + matrix[13]).normalized();
|
||||
|
||||
|
||||
Vector3 res;
|
||||
near_plane.intersect_3(right_plane,top_plane,&res);
|
||||
|
||||
|
||||
r_width=res.x;
|
||||
r_height=res.y;
|
||||
}
|
||||
|
||||
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 ---///////
|
||||
Plane near_plane=Plane(matrix[ 3] + matrix[ 2],
|
||||
matrix[ 7] + matrix[ 6],
|
||||
matrix[11] + matrix[10],
|
||||
-matrix[15] - matrix[14]).normalized();
|
||||
|
||||
|
||||
///////--- Far Plane ---///////
|
||||
Plane far_plane=Plane(matrix[ 2] - matrix[ 3],
|
||||
matrix[ 6] - matrix[ 7],
|
||||
matrix[10] - matrix[11],
|
||||
matrix[15] - matrix[14]).normalized();
|
||||
|
||||
|
||||
|
||||
///////--- Right Plane ---///////
|
||||
Plane right_plane=Plane(matrix[ 0] - matrix[ 3],
|
||||
matrix[ 4] - matrix[ 7],
|
||||
matrix[8] - matrix[ 11],
|
||||
- matrix[15] + matrix[12]).normalized();
|
||||
|
||||
///////--- Top Plane ---///////
|
||||
|
||||
///////--- Top Plane ---///////
|
||||
Plane top_plane=Plane(matrix[ 1] - matrix[ 3],
|
||||
matrix[ 5] - matrix[ 7],
|
||||
matrix[9] - matrix[ 11],
|
||||
-matrix[15] + matrix[13]).normalized();
|
||||
|
||||
|
||||
Vector3 near_endpoint;
|
||||
Vector3 far_endpoint;
|
||||
|
||||
|
||||
bool res=near_plane.intersect_3(right_plane,top_plane,&near_endpoint);
|
||||
ERR_FAIL_COND_V(!res,false);
|
||||
|
||||
|
||||
res=far_plane.intersect_3(right_plane,top_plane,&far_endpoint);
|
||||
ERR_FAIL_COND_V(!res,false);
|
||||
|
||||
|
||||
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[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[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 ) );
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -263,10 +263,10 @@ Vector<Plane> CameraMatrix::get_projection_planes(const Transform& p_transform)
|
|||
* http://www.markmorley.com/opengl/frustumculling.html
|
||||
* http://www2.ravensoft.com/users/ggribb/plane%20extraction.pdf
|
||||
*/
|
||||
|
||||
|
||||
Vector<Plane> planes;
|
||||
|
||||
const float * matrix = (const float*)this->matrix;
|
||||
|
||||
const float * matrix = (const float*)this->matrix;
|
||||
|
||||
Plane new_plane;
|
||||
|
||||
|
@ -275,7 +275,7 @@ Vector<Plane> CameraMatrix::get_projection_planes(const Transform& p_transform)
|
|||
matrix[ 7] + matrix[ 6],
|
||||
matrix[11] + matrix[10],
|
||||
matrix[15] + matrix[14]);
|
||||
|
||||
|
||||
new_plane.normal=-new_plane.normal;
|
||||
new_plane.normalize();
|
||||
|
||||
|
@ -298,7 +298,7 @@ Vector<Plane> CameraMatrix::get_projection_planes(const Transform& p_transform)
|
|||
matrix[ 7] + matrix[ 4],
|
||||
matrix[11] + matrix[ 8],
|
||||
matrix[15] + matrix[12]);
|
||||
|
||||
|
||||
new_plane.normal=-new_plane.normal;
|
||||
new_plane.normalize();
|
||||
|
||||
|
@ -310,8 +310,8 @@ Vector<Plane> CameraMatrix::get_projection_planes(const Transform& p_transform)
|
|||
matrix[ 7] - matrix[ 5],
|
||||
matrix[11] - matrix[ 9],
|
||||
matrix[15] - matrix[13]);
|
||||
|
||||
|
||||
|
||||
|
||||
new_plane.normal=-new_plane.normal;
|
||||
new_plane.normalize();
|
||||
|
||||
|
@ -324,10 +324,10 @@ Vector<Plane> CameraMatrix::get_projection_planes(const Transform& p_transform)
|
|||
matrix[11] - matrix[ 8],
|
||||
matrix[15] - matrix[12]);
|
||||
|
||||
|
||||
|
||||
new_plane.normal=-new_plane.normal;
|
||||
new_plane.normalize();
|
||||
|
||||
|
||||
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[15] + matrix[13]);
|
||||
|
||||
|
||||
|
||||
new_plane.normal=-new_plane.normal;
|
||||
new_plane.normalize();
|
||||
|
||||
planes.push_back( p_transform.xform(new_plane) );
|
||||
|
||||
|
||||
return planes;
|
||||
}
|
||||
|
||||
|
@ -356,7 +356,7 @@ CameraMatrix CameraMatrix::inverse() const {
|
|||
}
|
||||
|
||||
void CameraMatrix::invert() {
|
||||
|
||||
|
||||
int i,j,k;
|
||||
int pvt_i[4], pvt_j[4]; /* Locations of pivot matrix */
|
||||
float pvt_val; /* Value of current pivot element */
|
||||
|
@ -448,7 +448,7 @@ void CameraMatrix::invert() {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
CameraMatrix::CameraMatrix() {
|
||||
|
@ -475,31 +475,31 @@ CameraMatrix CameraMatrix::operator*(const CameraMatrix& p_matrix) const {
|
|||
void CameraMatrix::set_light_bias() {
|
||||
|
||||
float *m=&matrix[0][0];
|
||||
|
||||
m[0]=0.5,
|
||||
m[1]=0.0,
|
||||
m[2]=0.0,
|
||||
|
||||
m[0]=0.5,
|
||||
m[1]=0.0,
|
||||
m[2]=0.0,
|
||||
m[3]=0.0,
|
||||
m[4]=0.0,
|
||||
m[5]=0.5,
|
||||
m[6]=0.0,
|
||||
m[4]=0.0,
|
||||
m[5]=0.5,
|
||||
m[6]=0.0,
|
||||
m[7]=0.0,
|
||||
m[8]=0.0,
|
||||
m[9]=0.0,
|
||||
m[10]=0.5,
|
||||
m[8]=0.0,
|
||||
m[9]=0.0,
|
||||
m[10]=0.5,
|
||||
m[11]=0.0,
|
||||
m[12]=0.5,
|
||||
m[13]=0.5,
|
||||
m[14]=0.5,
|
||||
m[15]=1.0;
|
||||
|
||||
m[12]=0.5,
|
||||
m[13]=0.5,
|
||||
m[14]=0.5,
|
||||
m[15]=1.0;
|
||||
|
||||
}
|
||||
|
||||
CameraMatrix::operator String() const {
|
||||
|
||||
String str;
|
||||
for (int i=0;i<4;i++)
|
||||
for (int j=0;j<4;j++)
|
||||
for (int i=0;i<4;i++)
|
||||
for (int j=0;j<4;j++)
|
||||
str+=String((j>0)?", ":"\n")+rtos(matrix[i][j]);
|
||||
|
||||
return str;
|
||||
|
@ -513,7 +513,7 @@ float CameraMatrix::get_aspect() 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],
|
||||
matrix[ 7] - matrix[ 4],
|
||||
|
@ -588,7 +588,7 @@ CameraMatrix::CameraMatrix(const Transform& p_transform) {
|
|||
|
||||
const Transform &tr = p_transform;
|
||||
float *m=&matrix[0][0];
|
||||
|
||||
|
||||
m[0]=tr.basis.elements[0][0];
|
||||
m[1]=tr.basis.elements[1][0];
|
||||
m[2]=tr.basis.elements[2][0];
|
||||
|
@ -604,7 +604,7 @@ CameraMatrix::CameraMatrix(const Transform& p_transform) {
|
|||
m[12]=tr.origin.x;
|
||||
m[13]=tr.origin.y;
|
||||
m[14]=tr.origin.z;
|
||||
m[15]=1.0;
|
||||
m[15]=1.0;
|
||||
}
|
||||
|
||||
CameraMatrix::~CameraMatrix()
|
||||
|
|
|
@ -48,8 +48,8 @@ struct CameraMatrix {
|
|||
};
|
||||
|
||||
float matrix[4][4];
|
||||
|
||||
|
||||
|
||||
|
||||
void set_identity();
|
||||
void set_zero();
|
||||
void set_light_bias();
|
||||
|
@ -67,12 +67,12 @@ struct CameraMatrix {
|
|||
float get_z_near() const;
|
||||
float get_aspect() const;
|
||||
float get_fov() const;
|
||||
|
||||
|
||||
Vector<Plane> get_projection_planes(const Transform& p_transform) const;
|
||||
|
||||
|
||||
bool get_endpoints(const Transform& p_transform,Vector3 *p_8points) const;
|
||||
void get_viewport_size(float& r_width, float& r_height) const;
|
||||
|
||||
|
||||
void invert();
|
||||
CameraMatrix inverse() const;
|
||||
|
||||
|
@ -80,15 +80,15 @@ struct CameraMatrix {
|
|||
|
||||
Plane xform4(const Plane& p_vec4);
|
||||
_FORCE_INLINE_ Vector3 xform(const Vector3& p_vec3) const;
|
||||
|
||||
|
||||
operator String() const;
|
||||
|
||||
void scale_translate_to_fit(const AABB& p_aabb);
|
||||
void make_scale(const Vector3 &p_scale);
|
||||
operator Transform() const;
|
||||
|
||||
CameraMatrix();
|
||||
CameraMatrix(const Transform& p_transform);
|
||||
CameraMatrix();
|
||||
CameraMatrix(const Transform& p_transform);
|
||||
~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)
|
||||
* @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;
|
||||
|
||||
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 project_range(const Vector3& p_normal,const Transform& p_transform,float& r_min, float& r_max) const;
|
||||
|
||||
|
||||
AABB get_aabb() const {
|
||||
|
||||
AABB aabb( vertex[0], Vector3() );
|
||||
|
|
|
@ -211,7 +211,7 @@ DVector< DVector< Face3 > > Geometry::separate_objects( DVector< Face3 > p_array
|
|||
int len = p_array.size();
|
||||
|
||||
DVector<Face3>::Read r=p_array.read();
|
||||
|
||||
|
||||
const Face3* arrayptr = r.ptr();
|
||||
|
||||
DVector< _FaceClassify> fc;
|
||||
|
@ -219,7 +219,7 @@ DVector< DVector< Face3 > > Geometry::separate_objects( DVector< Face3 > p_array
|
|||
fc.resize( len );
|
||||
|
||||
DVector< _FaceClassify >::Write fcw=fc.write();
|
||||
|
||||
|
||||
_FaceClassify * _fcptr = fcw.ptr();
|
||||
|
||||
for (int i=0;i<len;i++) {
|
||||
|
@ -278,7 +278,7 @@ DVector< DVector< Face3 > > Geometry::separate_objects( DVector< Face3 > p_array
|
|||
/*** GEOMETRY WRAPPER ***/
|
||||
|
||||
enum _CellFlags {
|
||||
|
||||
|
||||
_CELL_SOLID=1,
|
||||
_CELL_EXTERIOR=2,
|
||||
_CELL_STEP_MASK=0x1C,
|
||||
|
@ -299,7 +299,7 @@ enum _CellFlags {
|
|||
_CELL_PREV_Z_POS=5<<5,
|
||||
_CELL_PREV_Z_NEG=6<<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) {
|
||||
|
@ -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;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int div_x=len_x>1?2:1;
|
||||
int div_y=len_y>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;
|
||||
|
||||
for (int i=0;i<div_x;i++) {
|
||||
|
||||
|
||||
|
||||
|
||||
_SPLIT(i,div_x,x,len_x,new_x,new_len_x);
|
||||
|
||||
|
||||
for (int j=0;j<div_y;j++) {
|
||||
|
||||
_SPLIT(j,div_y,y,len_y,new_y,new_len_y);
|
||||
|
||||
|
||||
for (int k=0;k<div_z;k++) {
|
||||
|
||||
_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)
|
||||
return; // nothing to do, already used and/or visited
|
||||
|
||||
|
||||
p_cell_status[x][y][z]=_CELL_PREV_FIRST;
|
||||
|
||||
|
||||
while(true) {
|
||||
|
||||
|
||||
uint8_t &c = p_cell_status[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 */
|
||||
p_cell_status[x][y][z]|=_CELL_EXTERIOR;
|
||||
//printf("not marked as anything, marking exterior\n");
|
||||
}
|
||||
|
||||
|
||||
//printf("cell step is %i\n",(c&_CELL_STEP_MASK));
|
||||
|
||||
|
||||
if ( (c&_CELL_STEP_MASK)!=_CELL_STEP_DONE) {
|
||||
/* if not done, increase step */
|
||||
c+=1<<2;
|
||||
//printf("incrementing cell step\n");
|
||||
}
|
||||
|
||||
|
||||
if ( (c&_CELL_STEP_MASK)==_CELL_STEP_DONE) {
|
||||
/* Go back */
|
||||
//printf("done, going back a cell\n");
|
||||
|
||||
|
||||
switch(c&_CELL_PREV_MASK) {
|
||||
case _CELL_PREV_FIRST: {
|
||||
//printf("at end, finished marking\n");
|
||||
//printf("at end, finished marking\n");
|
||||
return;
|
||||
} break;
|
||||
case _CELL_PREV_Y_POS: {
|
||||
case _CELL_PREV_Y_POS: {
|
||||
y++;
|
||||
ERR_FAIL_COND(y>=len_y);
|
||||
} break;
|
||||
|
@ -427,16 +427,16 @@ static inline void _mark_outside(uint8_t*** p_cell_status,int x,int y,int z,int
|
|||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
//printf("attempting new cell!\n");
|
||||
|
||||
|
||||
int next_x=x,next_y=y,next_z=z;
|
||||
uint8_t prev=0;
|
||||
|
||||
|
||||
switch(c&_CELL_STEP_MASK) {
|
||||
|
||||
|
||||
case _CELL_STEP_Y_POS: {
|
||||
|
||||
|
||||
next_y++;
|
||||
prev=_CELL_PREV_Y_NEG;
|
||||
} break;
|
||||
|
@ -454,32 +454,32 @@ static inline void _mark_outside(uint8_t*** p_cell_status,int x,int y,int z,int
|
|||
} break;
|
||||
case _CELL_STEP_Z_POS: {
|
||||
next_z++;
|
||||
prev=_CELL_PREV_Z_NEG;
|
||||
prev=_CELL_PREV_Z_NEG;
|
||||
} break;
|
||||
case _CELL_STEP_Z_NEG: {
|
||||
next_z--;
|
||||
prev=_CELL_PREV_Z_POS;
|
||||
prev=_CELL_PREV_Z_POS;
|
||||
} break;
|
||||
default: ERR_FAIL();
|
||||
|
||||
default: ERR_FAIL();
|
||||
|
||||
}
|
||||
|
||||
|
||||
//printf("testing if new cell will be ok...!\n");
|
||||
|
||||
|
||||
if (next_x<0 || next_x>=len_x)
|
||||
continue;
|
||||
if (next_y<0 || next_y>=len_y)
|
||||
continue;
|
||||
if (next_z<0 || next_z>=len_z)
|
||||
continue;
|
||||
|
||||
|
||||
//printf("testing if new cell is traversable\n");
|
||||
|
||||
|
||||
if (p_cell_status[next_x][next_y][next_z]&3)
|
||||
continue;
|
||||
|
||||
|
||||
//printf("move to it\n");
|
||||
|
||||
|
||||
x=next_x;
|
||||
y=next_y;
|
||||
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) {
|
||||
|
||||
|
||||
ERR_FAIL_INDEX(x,len_x);
|
||||
ERR_FAIL_INDEX(y,len_y);
|
||||
ERR_FAIL_INDEX(z,len_z);
|
||||
|
||||
|
||||
if (p_cell_status[x][y][z]&_CELL_EXTERIOR)
|
||||
return;
|
||||
|
||||
return;
|
||||
|
||||
/* static const Vector3 vertices[8]={
|
||||
Vector3(0,0,0),
|
||||
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 )
|
||||
|
||||
static const uint8_t indices[6][4]={
|
||||
{7,6,4,5},
|
||||
{7,6,4,5},
|
||||
{7,3,2,6},
|
||||
{7,5,1,3},
|
||||
{0,2,3,1},
|
||||
{0,1,5,4},
|
||||
{7,5,1,3},
|
||||
{0,2,3,1},
|
||||
{0,1,5,4},
|
||||
{0,4,6,2},
|
||||
|
||||
};
|
||||
/*
|
||||
/*
|
||||
|
||||
{0,1,2,3},
|
||||
{0,1,4,5},
|
||||
{0,1,2,3},
|
||||
{0,1,4,5},
|
||||
{0,2,4,6},
|
||||
{4,5,6,7},
|
||||
{4,5,6,7},
|
||||
{2,3,7,6},
|
||||
{1,3,5,7},
|
||||
{1,3,5,7},
|
||||
|
||||
{0,2,3,1},
|
||||
{0,1,5,4},
|
||||
{0,2,3,1},
|
||||
{0,1,5,4},
|
||||
{0,4,6,2},
|
||||
{7,6,4,5},
|
||||
{7,6,4,5},
|
||||
{7,3,2,6},
|
||||
{7,5,1,3},
|
||||
{7,5,1,3},
|
||||
*/
|
||||
|
||||
|
||||
for (int i=0;i<6;i++) {
|
||||
|
||||
|
||||
Vector3 face_points[4];
|
||||
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_z=z+(((i-2)%3)==0?((i<3)?1:-1):0);
|
||||
|
||||
|
||||
bool plot=false;
|
||||
|
||||
|
||||
if (disp_x<0 || disp_x>=len_x)
|
||||
plot=true;
|
||||
if (disp_y<0 || disp_y>=len_y)
|
||||
plot=true;
|
||||
if (disp_z<0 || disp_z>=len_z)
|
||||
plot=true;
|
||||
|
||||
|
||||
if (!plot && (p_cell_status[disp_x][disp_y][disp_z]&_CELL_EXTERIOR))
|
||||
plot=true;
|
||||
|
||||
|
||||
if (!plot)
|
||||
continue;
|
||||
|
||||
|
||||
for (int j=0;j<4;j++)
|
||||
face_points[j]=vert( indices[i][j] ) + Vector3(x,y,z);
|
||||
|
||||
p_faces.push_back(
|
||||
Face3(
|
||||
|
||||
p_faces.push_back(
|
||||
Face3(
|
||||
face_points[0],
|
||||
face_points[1],
|
||||
face_points[2]
|
||||
)
|
||||
);
|
||||
|
||||
p_faces.push_back(
|
||||
Face3(
|
||||
|
||||
p_faces.push_back(
|
||||
Face3(
|
||||
face_points[2],
|
||||
face_points[3],
|
||||
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.grow_by(0.01); // avoid numerical error
|
||||
|
||||
// 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
|
||||
print_line("Wrapper (1/6): Plotting Faces");
|
||||
|
||||
|
||||
for (int i=0;i<face_count;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");
|
||||
|
||||
for (int i=0;i<div_x;i++) {
|
||||
|
||||
|
||||
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,div_z-1,div_x,div_y,div_z);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (int i=0;i<div_z;i++) {
|
||||
|
||||
|
||||
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,div_x-1,j,i,div_x,div_y,div_z);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (int i=0;i<div_x;i++) {
|
||||
|
||||
|
||||
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,div_y-1,j,div_x,div_y,div_z);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// build faces for the inside-outside cell divisors
|
||||
|
||||
|
||||
print_line("Wrapper (3/6): Building Faces");
|
||||
|
||||
DVector<Face3> wrapped_faces;
|
||||
|
||||
|
||||
for (int i=0;i<div_x;i++) {
|
||||
|
||||
|
||||
for (int j=0;j<div_y;j++) {
|
||||
|
||||
|
||||
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");
|
||||
|
||||
// transform face vertices to global coords
|
||||
|
||||
|
||||
int wrapped_faces_count=wrapped_faces.size();
|
||||
DVector<Face3>::Write wrapped_facesw=wrapped_faces.write();
|
||||
Face3* wrapped_faces_ptr=wrapped_facesw.ptr();
|
||||
|
||||
|
||||
for(int i=0;i<wrapped_faces_count;i++) {
|
||||
|
||||
|
||||
for(int j=0;j<3;j++) {
|
||||
|
||||
|
||||
Vector3& v = wrapped_faces_ptr[i].vertex[j];
|
||||
v=v*voxelsize;
|
||||
v+=global_aabb.pos;
|
||||
}
|
||||
}
|
||||
|
||||
// clean up grid
|
||||
|
||||
// clean up grid
|
||||
print_line("Wrapper (5/6): Grid Cleanup");
|
||||
|
||||
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] );
|
||||
}
|
||||
|
||||
|
||||
memdelete_arr(cell_status);
|
||||
if (p_error)
|
||||
*p_error=voxelsize.length();
|
||||
|
||||
|
||||
print_line("Wrapper (6/6): Finished.");
|
||||
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) {
|
||||
|
||||
MeshData mesh;
|
||||
|
||||
|
||||
|
||||
|
||||
#define SUBPLANE_SIZE 1024.0
|
||||
|
||||
|
||||
float subplane_size = 1024.0; // should compute this from the actual plane
|
||||
for (int i=0;i<p_planes.size();i++) {
|
||||
|
||||
|
||||
Plane p =p_planes[i];
|
||||
|
||||
|
||||
Vector3 ref=Vector3(0.0,1.0,0.0);
|
||||
|
||||
|
||||
if (ABS(p.normal.dot(ref))>0.95)
|
||||
ref=Vector3(0.0,0.0,1.0); // change axis
|
||||
|
||||
|
||||
Vector3 right = p.normal.cross(ref).normalized();
|
||||
Vector3 up = p.normal.cross( right ).normalized();
|
||||
|
||||
|
||||
Vector< Vector3 > vertices;
|
||||
|
||||
|
||||
Vector3 center = p.get_any_point();
|
||||
// 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 );
|
||||
|
||||
|
||||
for (int j=0;j<p_planes.size();j++) {
|
||||
|
||||
if (j==i)
|
||||
continue;
|
||||
|
||||
|
||||
|
||||
Vector< Vector3 > new_vertices;
|
||||
Plane clip=p_planes[j];
|
||||
|
||||
|
||||
if (clip.normal.dot(p.normal)>0.95)
|
||||
continue;
|
||||
|
||||
|
||||
if (vertices.size()<3)
|
||||
break;
|
||||
|
||||
|
||||
for(int k=0;k<vertices.size();k++) {
|
||||
|
||||
|
||||
int k_n=(k+1)%vertices.size();
|
||||
|
||||
|
||||
Vector3 edge0_A=vertices[k];
|
||||
Vector3 edge1_A=vertices[k_n];
|
||||
|
||||
|
||||
real_t dist0 = clip.distance_to(edge0_A);
|
||||
real_t dist1 = clip.distance_to(edge1_A);
|
||||
|
||||
|
||||
if ( dist0 <= 0 ) { // behind plane
|
||||
|
||||
new_vertices.push_back(vertices[k]);
|
||||
|
||||
|
||||
if ( dist0 <= 0 ) { // behind plane
|
||||
|
||||
new_vertices.push_back(vertices[k]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// check for different sides and non coplanar
|
||||
if ( (dist0*dist1) < 0) {
|
||||
|
||||
if ( (dist0*dist1) < 0) {
|
||||
|
||||
// calculate intersection
|
||||
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;
|
||||
Vector3 inters = edge0_A+rel*dist;
|
||||
new_vertices.push_back(inters);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
vertices=new_vertices;
|
||||
}
|
||||
|
||||
|
||||
if (vertices.size()<3)
|
||||
continue;
|
||||
|
||||
|
||||
|
||||
|
||||
//result is a clockwise face
|
||||
|
||||
|
||||
MeshData::Face face;
|
||||
|
||||
|
||||
// add face indices
|
||||
for (int j=0;j<vertices.size();j++) {
|
||||
|
||||
|
||||
|
||||
|
||||
int idx=-1;
|
||||
for (int k=0;k<mesh.vertices.size();k++) {
|
||||
|
||||
|
||||
if (mesh.vertices[k].distance_to(vertices[j])<0.001) {
|
||||
|
||||
|
||||
idx=k;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (idx==-1) {
|
||||
|
||||
|
||||
idx=mesh.vertices.size();
|
||||
mesh.vertices.push_back(vertices[j]);
|
||||
}
|
||||
|
||||
|
||||
face.indices.push_back(idx);
|
||||
}
|
||||
face.plane=p;
|
||||
mesh.faces.push_back(face);
|
||||
|
||||
|
||||
//add edge
|
||||
|
||||
|
||||
for(int j=0;j<face.indices.size();j++) {
|
||||
|
||||
|
||||
int a=face.indices[j];
|
||||
int b=face.indices[(j+1)%face.indices.size()];
|
||||
|
||||
|
||||
bool found=false;
|
||||
for(int k=0;k<mesh.edges.size();k++) {
|
||||
|
||||
|
||||
if (mesh.edges[k].a==a && mesh.edges[k].b==b) {
|
||||
found=true;
|
||||
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) {
|
||||
found=true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (found)
|
||||
continue;
|
||||
MeshData::Edge edge;
|
||||
|
@ -888,8 +888,8 @@ Geometry::MeshData Geometry::build_convex_mesh(const DVector<Plane> &p_planes) {
|
|||
edge.b=b;
|
||||
mesh.edges.push_back(edge);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
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> 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(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 ) );
|
||||
|
||||
|
||||
return planes;
|
||||
}
|
||||
|
||||
DVector<Plane> Geometry::build_cylinder_planes(float p_radius, float p_height, int p_sides, Vector3::Axis p_axis) {
|
||||
|
||||
DVector<Plane> planes;
|
||||
|
||||
|
||||
for (int i=0;i<p_sides;i++) {
|
||||
|
||||
|
||||
Vector3 normal;
|
||||
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);
|
||||
|
||||
|
||||
planes.push_back( Plane( normal, p_radius ) );
|
||||
}
|
||||
|
||||
|
||||
Vector3 axis;
|
||||
axis[p_axis]=1.0;
|
||||
|
||||
|
||||
planes.push_back( Plane( axis, p_height*0.5 ) );
|
||||
planes.push_back( Plane( -axis, p_height*0.5 ) );
|
||||
|
||||
|
||||
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> planes;
|
||||
|
||||
|
||||
Vector3 axis;
|
||||
axis[p_axis]=1.0;
|
||||
|
||||
Vector3 axis_neg;
|
||||
|
||||
Vector3 axis_neg;
|
||||
axis_neg[(p_axis+1)%3]=1.0;
|
||||
axis_neg[(p_axis+2)%3]=1.0;
|
||||
axis_neg[p_axis]=-1.0;
|
||||
|
||||
|
||||
for (int i=0;i<p_sides;i++) {
|
||||
|
||||
|
||||
Vector3 normal;
|
||||
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);
|
||||
|
||||
|
||||
planes.push_back( Plane( normal, p_radius ) );
|
||||
|
||||
|
||||
for (int j=1;j<=p_lats;j++) {
|
||||
|
||||
|
||||
Vector3 angle = normal.linear_interpolate(axis,j/(float)p_lats).normalized();
|
||||
Vector3 pos = axis*p_height*0.5 + angle*p_radius;
|
||||
planes.push_back( Plane( pos, angle ) );
|
||||
planes.push_back( Plane( pos * axis_neg, angle * axis_neg) );
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
return planes;
|
||||
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
class Geometry {
|
||||
Geometry();
|
||||
public:
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -201,37 +201,37 @@ public:
|
|||
real_t a =e1.dot(h);
|
||||
if (a>-CMP_EPSILON && a < CMP_EPSILON) // parallel test
|
||||
return false;
|
||||
|
||||
|
||||
real_t f=1.0/a;
|
||||
|
||||
|
||||
Vector3 s=p_from-p_v0;
|
||||
real_t u = f * s.dot(h);
|
||||
|
||||
|
||||
if ( u< 0.0 || u > 1.0)
|
||||
return false;
|
||||
|
||||
|
||||
Vector3 q=s.cross(e1);
|
||||
|
||||
|
||||
real_t v = f * p_dir.dot(q);
|
||||
|
||||
|
||||
if (v < 0.0 || u + v > 1.0)
|
||||
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
|
||||
real_t t = f * e2.dot(q);
|
||||
|
||||
|
||||
if (t > 0.00001) {// ray intersection
|
||||
if (r_res)
|
||||
*r_res=p_from+p_dir*t;
|
||||
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
|
||||
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) {
|
||||
|
||||
|
||||
Vector3 rel=p_to-p_from;
|
||||
Vector3 e1=p_v1-p_v0;
|
||||
Vector3 e2=p_v2-p_v0;
|
||||
|
@ -239,34 +239,34 @@ public:
|
|||
real_t a =e1.dot(h);
|
||||
if (a>-CMP_EPSILON && a < CMP_EPSILON) // parallel test
|
||||
return false;
|
||||
|
||||
|
||||
real_t f=1.0/a;
|
||||
|
||||
|
||||
Vector3 s=p_from-p_v0;
|
||||
real_t u = f * s.dot(h);
|
||||
|
||||
|
||||
if ( u< 0.0 || u > 1.0)
|
||||
return false;
|
||||
|
||||
|
||||
Vector3 q=s.cross(e1);
|
||||
|
||||
|
||||
real_t v = f * rel.dot(q);
|
||||
|
||||
|
||||
if (v < 0.0 || u + v > 1.0)
|
||||
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
|
||||
real_t t = f * e2.dot(q);
|
||||
|
||||
|
||||
if (t > CMP_EPSILON && t<=1.0) {// ray intersection
|
||||
if (r_res)
|
||||
*r_res=p_from+rel*t;
|
||||
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
|
||||
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) {
|
||||
|
||||
|
@ -356,24 +356,24 @@ public:
|
|||
real_t box_end=size[i];
|
||||
real_t cmin,cmax;
|
||||
|
||||
|
||||
|
||||
if (seg_from < seg_to) {
|
||||
|
||||
|
||||
if (seg_from > box_end || seg_to < box_begin)
|
||||
return false;
|
||||
real_t length=seg_to-seg_from;
|
||||
cmin = (seg_from < box_begin)?((box_begin - seg_from)/length):0;
|
||||
cmax = (seg_to > box_end)?((box_end - seg_from)/length):1;
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
|
||||
if (seg_to > box_end || seg_from < box_begin)
|
||||
return false;
|
||||
real_t length=seg_to-seg_from;
|
||||
cmin = (seg_from > box_end)?(box_end - seg_from)/length:0;
|
||||
cmax = (seg_to < box_begin)?(box_begin - seg_from)/length:1;
|
||||
}
|
||||
|
||||
|
||||
if (cmin > min) {
|
||||
min = cmin;
|
||||
axis=i;
|
||||
|
@ -468,9 +468,9 @@ public:
|
|||
if (l<1e-10)
|
||||
return p_segment[0]; // both points are the same, just give any
|
||||
n/=l;
|
||||
|
||||
|
||||
float d=n.dot(p);
|
||||
|
||||
|
||||
if (d<=0.0)
|
||||
return p_segment[0]; // before first point
|
||||
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) {
|
||||
|
||||
|
||||
Vector3 face_n = (p_v1-p_v3).cross(p_v1-p_v2);
|
||||
|
||||
Vector3 n1 = (p_point-p_v3).cross(p_point-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);
|
||||
|
||||
if (face_n.dot(n1)<0)
|
||||
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)
|
||||
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)
|
||||
return false;
|
||||
|
||||
|
||||
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) {
|
||||
|
@ -814,21 +814,21 @@ public:
|
|||
|
||||
|
||||
struct MeshData {
|
||||
|
||||
|
||||
struct Face {
|
||||
Plane plane;
|
||||
Vector<int> indices;
|
||||
};
|
||||
|
||||
|
||||
Vector<Face> faces;
|
||||
|
||||
|
||||
struct Edge {
|
||||
|
||||
|
||||
int a,b;
|
||||
};
|
||||
|
||||
|
||||
Vector<Edge> edges;
|
||||
|
||||
|
||||
Vector< Vector3 > 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);
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -45,10 +45,10 @@ float Vector2::length_squared() const {
|
|||
}
|
||||
|
||||
void Vector2::normalize() {
|
||||
|
||||
|
||||
float l = x*x + y*y;
|
||||
if (l!=0) {
|
||||
|
||||
|
||||
l=Math::sqrt(l);
|
||||
x/=l;
|
||||
y/=l;
|
||||
|
@ -56,14 +56,14 @@ void Vector2::normalize() {
|
|||
}
|
||||
|
||||
Vector2 Vector2::normalized() const {
|
||||
|
||||
|
||||
Vector2 v=*this;
|
||||
v.normalize();
|
||||
return v;
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
|
@ -73,7 +73,7 @@ float Vector2::distance_squared_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) );
|
||||
}
|
||||
|
||||
|
@ -83,7 +83,7 @@ float Vector2::angle_to_point(const Vector2& p_vector2) const {
|
|||
}
|
||||
|
||||
float Vector2::dot(const Vector2& p_other) const {
|
||||
|
||||
|
||||
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 {
|
||||
|
||||
|
||||
return Vector2(x+p_v.x,y+p_v.y);
|
||||
}
|
||||
void Vector2::operator+=(const Vector2& p_v) {
|
||||
|
||||
|
||||
x+=p_v.x; y+=p_v.y;
|
||||
}
|
||||
Vector2 Vector2::operator-(const Vector2& p_v) const {
|
||||
|
||||
|
||||
return Vector2(x-p_v.x,y-p_v.y);
|
||||
}
|
||||
void Vector2::operator-=(const Vector2& p_v) {
|
||||
|
||||
|
||||
x-=p_v.x; y-=p_v.y;
|
||||
}
|
||||
|
||||
Vector2 Vector2::operator*(const Vector2 &p_v1) const {
|
||||
|
||||
|
||||
return Vector2(x * p_v1.x, y * p_v1.y);
|
||||
};
|
||||
|
||||
Vector2 Vector2::operator*(const float &rvalue) const {
|
||||
|
||||
|
||||
return Vector2(x * rvalue, y * rvalue);
|
||||
};
|
||||
void Vector2::operator*=(const float &rvalue) {
|
||||
|
||||
|
||||
x *= rvalue; y *= rvalue;
|
||||
};
|
||||
|
||||
Vector2 Vector2::operator/(const Vector2 &p_v1) const {
|
||||
|
||||
|
||||
return Vector2(x / p_v1.x, y / p_v1.y);
|
||||
};
|
||||
|
||||
Vector2 Vector2::operator/(const float &rvalue) const {
|
||||
|
||||
|
||||
return Vector2(x / rvalue, y / rvalue);
|
||||
};
|
||||
|
||||
void Vector2::operator/=(const float &rvalue) {
|
||||
|
||||
|
||||
x /= rvalue; y /= rvalue;
|
||||
};
|
||||
|
||||
Vector2 Vector2::operator-() const {
|
||||
|
||||
|
||||
return Vector2(-x,-y);
|
||||
}
|
||||
|
||||
bool Vector2::operator==(const Vector2& p_vec2) const {
|
||||
|
||||
|
||||
return x==p_vec2.x && y==p_vec2.y;
|
||||
}
|
||||
bool Vector2::operator!=(const Vector2& p_vec2) const {
|
||||
|
||||
|
||||
return x!=p_vec2.x || y!=p_vec2.y;
|
||||
}
|
||||
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 {
|
||||
|
||||
|
||||
//extract parameters
|
||||
Vector2 p1 = get_origin();
|
||||
Vector2 p2 = p_transform.get_origin();
|
||||
|
||||
|
||||
real_t r1 = get_rotation();
|
||||
real_t r2 = p_transform.get_rotation();
|
||||
|
||||
|
||||
Vector2 s1 = get_scale();
|
||||
Vector2 s2 = p_transform.get_scale();
|
||||
|
||||
|
||||
//slerp rotation
|
||||
Vector2 v1(Math::cos(r1), Math::sin(r1));
|
||||
Vector2 v2(Math::cos(r2), Math::sin(r2));
|
||||
|
||||
|
||||
real_t dot = v1.dot(v2);
|
||||
|
||||
|
||||
dot = (dot < -1.0) ? -1.0 : ((dot > 1.0) ? 1.0 : dot); //clamp dot to [-1,1]
|
||||
|
||||
|
||||
Vector2 v;
|
||||
|
||||
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();
|
||||
v = v1*Math::cos(angle) + v3*Math::sin(angle);
|
||||
}
|
||||
|
||||
|
||||
//construct matrix
|
||||
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));
|
||||
|
|
|
@ -35,15 +35,15 @@
|
|||
@author Juan Linietsky <reduzio@gmail.com>
|
||||
*/
|
||||
enum Margin {
|
||||
|
||||
|
||||
MARGIN_LEFT,
|
||||
MARGIN_TOP,
|
||||
MARGIN_RIGHT,
|
||||
MARGIN_BOTTOM
|
||||
MARGIN_BOTTOM
|
||||
};
|
||||
|
||||
enum Orientation {
|
||||
|
||||
|
||||
HORIZONTAL,
|
||||
VERTICAL
|
||||
};
|
||||
|
@ -63,7 +63,7 @@ enum VAlign {
|
|||
};
|
||||
|
||||
struct Vector2 {
|
||||
|
||||
|
||||
union {
|
||||
float x;
|
||||
float width;
|
||||
|
@ -87,7 +87,7 @@ struct Vector2 {
|
|||
float length() 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 angle_to(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;
|
||||
void operator-=(const Vector2& p_v);
|
||||
Vector2 operator*(const Vector2 &p_v1) const;
|
||||
|
||||
|
||||
Vector2 operator*(const float &rvalue) const;
|
||||
void operator*=(const float &rvalue);
|
||||
void operator*=(const Vector2 &rvalue) { *this = *this * rvalue; }
|
||||
|
||||
Vector2 operator/(const Vector2 &p_v1) const;
|
||||
|
||||
|
||||
Vector2 operator/(const float &rvalue) const;
|
||||
|
||||
|
||||
void operator/=(const float &rvalue);
|
||||
|
||||
|
||||
Vector2 operator-() 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);
|
||||
}
|
||||
|
||||
|
||||
Vector2 floor() const;
|
||||
Vector2 snapped(const Vector2& p_by) const;
|
||||
float get_aspect() const { return width/height; }
|
||||
|
||||
|
||||
|
||||
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() { x=0; y=0; }
|
||||
};
|
||||
|
@ -202,7 +202,7 @@ struct Matrix32;
|
|||
|
||||
|
||||
struct Rect2 {
|
||||
|
||||
|
||||
Point2 pos;
|
||||
Size2 size;
|
||||
|
||||
|
@ -213,7 +213,7 @@ struct Rect2 {
|
|||
|
||||
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) )
|
||||
return false;
|
||||
if ( (pos.x+size.width) <= p_rect.pos.x )
|
||||
|
@ -222,7 +222,7 @@ struct Rect2 {
|
|||
return false;
|
||||
if ( (pos.y+size.height) <= p_rect.pos.y )
|
||||
return false;
|
||||
|
||||
|
||||
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;
|
||||
|
||||
inline bool encloses(const Rect2& p_rect) const {
|
||||
|
||||
|
||||
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.y+p_rect.size.y)<(pos.y+size.y));
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
inline bool has_no_area() const {
|
||||
|
||||
|
||||
return (size.x<=0 || size.y<=0);
|
||||
|
||||
|
||||
}
|
||||
inline Rect2 clip(const Rect2& p_rect) const { /// return a clipped rect
|
||||
|
||||
|
||||
Rect2 new_rect=p_rect;
|
||||
|
||||
|
||||
if (!intersects( new_rect ))
|
||||
return Rect2();
|
||||
|
||||
|
||||
new_rect.pos.x = MAX( p_rect.pos.x , pos.x );
|
||||
new_rect.pos.y = MAX( p_rect.pos.y , pos.y );
|
||||
|
||||
|
||||
Point2 p_rect_end=p_rect.pos+p_rect.size;
|
||||
Point2 end=pos+size;
|
||||
|
||||
|
||||
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;
|
||||
|
||||
|
||||
return new_rect;
|
||||
}
|
||||
|
||||
|
||||
inline Rect2 merge(const Rect2& p_rect) const { ///< return a merged rect
|
||||
|
||||
|
||||
Rect2 new_rect;
|
||||
|
||||
|
||||
new_rect.pos.x=MIN( p_rect.pos.x , pos.x );
|
||||
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.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
|
||||
|
||||
|
||||
return new_rect;
|
||||
};
|
||||
inline bool has_point(const Point2& p_point) const {
|
||||
if (p_point.x < pos.x)
|
||||
return false;
|
||||
return false;
|
||||
if (p_point.y < pos.y)
|
||||
return false;
|
||||
|
||||
return false;
|
||||
|
||||
if (p_point.x >= (pos.x+size.x) )
|
||||
return false;
|
||||
return false;
|
||||
if (p_point.y >= (pos.y+size.y) )
|
||||
return false;
|
||||
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
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; }
|
||||
|
||||
|
||||
inline Rect2 grow(real_t p_by) const {
|
||||
|
||||
|
||||
Rect2 g=*this;
|
||||
g.pos.x-=p_by;
|
||||
g.pos.y-=p_by;
|
||||
|
@ -357,9 +357,9 @@ struct Rect2 {
|
|||
|
||||
|
||||
operator String() const { return String(pos)+","+String(size); }
|
||||
|
||||
|
||||
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; }
|
||||
};
|
||||
|
||||
|
|
|
@ -135,18 +135,20 @@ double Math::rad2deg(double p_y) {
|
|||
|
||||
double Math::round(double p_val) {
|
||||
|
||||
if (p_val>0) {
|
||||
if (p_val>=0) {
|
||||
return ::floor(p_val+0.5);
|
||||
} else {
|
||||
p_val=-p_val;
|
||||
return -::floor(p_val+0.5);
|
||||
}
|
||||
}
|
||||
|
||||
double Math::asin(double p_x) {
|
||||
|
||||
return ::asin(p_x);
|
||||
|
||||
}
|
||||
|
||||
double Math::acos(double 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) {
|
||||
|
||||
if (p_x>=0) {
|
||||
|
||||
|
||||
return Math::fmod(p_x,p_y);
|
||||
|
||||
|
||||
} 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 max=4;
|
||||
double llimit = Math::pow(0.1,max);
|
||||
double ulimit = 1.0-llimit;
|
||||
|
@ -220,7 +222,7 @@ int Math::decimals(double p_step) {
|
|||
max--;
|
||||
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) {
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -91,25 +91,25 @@ public:
|
|||
|
||||
static uint32_t rand();
|
||||
static double randf();
|
||||
|
||||
|
||||
static double round(double p_val);
|
||||
|
||||
static double random(double from, double to);
|
||||
|
||||
|
||||
|
||||
static _FORCE_INLINE_ real_t abs(real_t g) {
|
||||
|
||||
#ifdef REAL_T_IS_DOUBLE
|
||||
|
||||
return absd(g);
|
||||
#ifdef REAL_T_IS_DOUBLE
|
||||
|
||||
return absd(g);
|
||||
#else
|
||||
|
||||
return absf(g);
|
||||
return absf(g);
|
||||
#endif
|
||||
}
|
||||
|
||||
static _FORCE_INLINE_ float absf(float g) {
|
||||
|
||||
|
||||
union {
|
||||
float f;
|
||||
uint32_t i;
|
||||
|
@ -174,7 +174,7 @@ public:
|
|||
static double pow(double x, double y);
|
||||
static double log(double x);
|
||||
static double exp(double x);
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -62,11 +62,11 @@ void Matrix3::invert() {
|
|||
real_t det = elements[0][0] * co[0]+
|
||||
elements[0][1] * co[1]+
|
||||
elements[0][2] * co[2];
|
||||
|
||||
|
||||
ERR_FAIL_COND( det == 0 );
|
||||
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[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][2],elements[1][2],elements[2][2]).length()
|
||||
);
|
||||
|
||||
|
||||
}
|
||||
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 true;
|
||||
}
|
||||
bool Matrix3::operator!=(const Matrix3& p_matrix) const {
|
||||
|
@ -235,16 +235,16 @@ Matrix3::operator String() const {
|
|||
|
||||
String mtx;
|
||||
for (int i=0;i<3;i++) {
|
||||
|
||||
|
||||
for (int j=0;j<3;j++) {
|
||||
|
||||
|
||||
if (i!=0 || j!=0)
|
||||
mtx+=", ";
|
||||
|
||||
|
||||
mtx+=rtos( elements[i][j] );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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 temp[4];
|
||||
|
||||
if (trace > 0.0)
|
||||
|
||||
if (trace > 0.0)
|
||||
{
|
||||
real_t s = Math::sqrt(trace + 1.0);
|
||||
temp[3]=(s * 0.5);
|
||||
s = 0.5 / s;
|
||||
|
||||
|
||||
temp[0]=((m.elements[2][1] - m.elements[1][2]) * s);
|
||||
temp[1]=((m.elements[0][2] - m.elements[2][0]) * s);
|
||||
temp[2]=((m.elements[1][0] - m.elements[0][1]) * s);
|
||||
}
|
||||
else
|
||||
}
|
||||
else
|
||||
{
|
||||
int i = m.elements[0][0] < m.elements[1][1] ?
|
||||
(m.elements[1][1] < m.elements[2][2] ? 2 : 1) :
|
||||
(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;
|
||||
|
||||
|
||||
real_t s = Math::sqrt(m.elements[i][i] - m.elements[j][j] - m.elements[k][k] + 1.0);
|
||||
temp[i] = s * 0.5;
|
||||
s = 0.5 / s;
|
||||
|
||||
|
||||
temp[3] = (m.elements[k][j] - m.elements[j][k]) * s;
|
||||
temp[j] = (m.elements[j][i] + m.elements[i][j]) * s;
|
||||
temp[k] = (m.elements[k][i] + m.elements[i][k]) * s;
|
||||
}
|
||||
|
||||
|
||||
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) {
|
||||
|
||||
set_euler( p_euler );
|
||||
|
||||
|
||||
}
|
||||
|
||||
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 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;
|
||||
set( 1.0 - (yy + zz), xy - wz, xz + wy,
|
||||
xy + wz, 1.0 - (xx + zz), yz - wx,
|
||||
set( 1.0 - (yy + zz), xy - wz, xz + wy,
|
||||
xy + wz, 1.0 - (xx + zz), yz - wx,
|
||||
xz - wy, yz + wx, 1.0 - (xx + yy)) ;
|
||||
|
||||
}
|
||||
|
|
|
@ -39,20 +39,20 @@ class Matrix3 {
|
|||
public:
|
||||
|
||||
Vector3 elements[3];
|
||||
|
||||
|
||||
_FORCE_INLINE_ const Vector3& operator[](int axis) const {
|
||||
|
||||
|
||||
return elements[axis];
|
||||
}
|
||||
_FORCE_INLINE_ Vector3& operator[](int axis) {
|
||||
|
||||
|
||||
return elements[axis];
|
||||
}
|
||||
|
||||
void invert();
|
||||
void invert();
|
||||
void transpose();
|
||||
|
||||
Matrix3 inverse() const;
|
||||
|
||||
Matrix3 inverse() const;
|
||||
Matrix3 transposed() const;
|
||||
|
||||
_FORCE_INLINE_ float determinant() const;
|
||||
|
@ -90,7 +90,7 @@ public:
|
|||
_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];
|
||||
}
|
||||
|
||||
|
||||
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) {
|
||||
|
||||
|
||||
elements[0][0]=xx;
|
||||
elements[0][1]=xy;
|
||||
elements[0][2]=xz;
|
||||
|
@ -119,15 +119,15 @@ public:
|
|||
elements[1][2]=yz;
|
||||
elements[2][0]=zx;
|
||||
elements[2][1]=zy;
|
||||
elements[2][2]=zz;
|
||||
elements[2][2]=zz;
|
||||
}
|
||||
_FORCE_INLINE_ Vector3 get_column(int i) const {
|
||||
|
||||
|
||||
return Vector3(elements[0][i],elements[1][i],elements[2][i]);
|
||||
}
|
||||
|
||||
|
||||
_FORCE_INLINE_ Vector3 get_row(int i) const {
|
||||
|
||||
|
||||
return Vector3(elements[i][0],elements[i][1],elements[i][2]);
|
||||
}
|
||||
_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].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);
|
||||
}
|
||||
|
||||
|
@ -170,7 +170,7 @@ public:
|
|||
Matrix3(const Vector3& p_axis, real_t p_phi);
|
||||
|
||||
_FORCE_INLINE_ Matrix3() {
|
||||
|
||||
|
||||
elements[0][0]=1;
|
||||
elements[0][1]=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[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]));
|
||||
|
||||
|
||||
}
|
||||
|
||||
_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 (*UnpairCallback)(void*,OctreeElementID, T*,int,OctreeElementID, T*,int,void*);
|
||||
|
||||
private:
|
||||
private:
|
||||
enum {
|
||||
|
||||
|
||||
NEG=0,
|
||||
POS=1,
|
||||
POS=1,
|
||||
};
|
||||
|
||||
enum {
|
||||
|
@ -72,7 +72,7 @@ private:
|
|||
|
||||
|
||||
struct PairKey {
|
||||
|
||||
|
||||
union {
|
||||
struct {
|
||||
OctreeElementID A;
|
||||
|
@ -80,66 +80,66 @@ private:
|
|||
};
|
||||
uint64_t key;
|
||||
};
|
||||
|
||||
|
||||
_FORCE_INLINE_ bool operator<(const PairKey& p_pair) const {
|
||||
|
||||
|
||||
return key<p_pair.key;
|
||||
}
|
||||
|
||||
|
||||
_FORCE_INLINE_ PairKey( OctreeElementID p_A, OctreeElementID p_B) {
|
||||
|
||||
|
||||
if (p_A<p_B) {
|
||||
|
||||
|
||||
A=p_A;
|
||||
B=p_B;
|
||||
B=p_B;
|
||||
} else {
|
||||
|
||||
|
||||
B=p_A;
|
||||
A=p_B;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
_FORCE_INLINE_ PairKey() {}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
struct Element;
|
||||
|
||||
|
||||
struct Octant {
|
||||
|
||||
|
||||
// cached for FAST plane check
|
||||
AABB aabb;
|
||||
|
||||
|
||||
uint64_t last_pass;
|
||||
Octant *parent;
|
||||
Octant *children[8];
|
||||
|
||||
|
||||
int children_count; // cache for amount of childrens (fast check for removal)
|
||||
int parent_index; // cache for parent index (fast check for removal)
|
||||
|
||||
|
||||
List<Element*,AL> pairable_elements;
|
||||
List<Element*,AL> elements;
|
||||
|
||||
|
||||
Octant() {
|
||||
children_count=0;
|
||||
parent_index=-1;
|
||||
last_pass=0;
|
||||
parent=NULL;
|
||||
for (int i=0;i<8;i++)
|
||||
children[i]=NULL;
|
||||
children[i]=NULL;
|
||||
}
|
||||
|
||||
|
||||
~Octant() {
|
||||
|
||||
|
||||
//for (int i=0;i<8;i++)
|
||||
// memdelete_notnull(children[i]);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct PairData;
|
||||
|
||||
struct Element {
|
||||
|
||||
|
||||
Octree *octree;
|
||||
|
||||
T *userdata;
|
||||
|
@ -147,28 +147,28 @@ private:
|
|||
bool pairable;
|
||||
uint32_t pairable_mask;
|
||||
uint32_t pairable_type;
|
||||
|
||||
|
||||
uint64_t last_pass;
|
||||
OctreeElementID _id;
|
||||
Octant *common_parent;
|
||||
|
||||
|
||||
AABB aabb;
|
||||
AABB container_aabb;
|
||||
|
||||
List<PairData*,AL> pair_list;
|
||||
|
||||
|
||||
struct OctantOwner {
|
||||
|
||||
|
||||
Octant *octant;
|
||||
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;
|
||||
|
||||
|
||||
|
||||
|
||||
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 {
|
||||
|
||||
|
@ -181,15 +181,15 @@ private:
|
|||
|
||||
typedef Map<OctreeElementID, Element, Comparator<OctreeElementID>, AL> ElementMap;
|
||||
typedef Map<PairKey, PairData, Comparator<PairKey>, AL> PairMap;
|
||||
ElementMap element_map;
|
||||
PairMap pair_map;
|
||||
ElementMap element_map;
|
||||
PairMap pair_map;
|
||||
|
||||
PairCallback pair_callback;
|
||||
UnpairCallback unpair_callback;
|
||||
void *pair_callback_userdata;
|
||||
void *unpair_callback_userdata;
|
||||
|
||||
OctreeElementID last_element_id;
|
||||
|
||||
OctreeElementID last_element_id;
|
||||
uint64_t pass;
|
||||
|
||||
real_t unit_size;
|
||||
|
@ -231,7 +231,7 @@ private:
|
|||
|
||||
if (p_A==p_B || (p_A->userdata==p_B->userdata && p_A->userdata))
|
||||
return;
|
||||
|
||||
|
||||
if ( !(p_A->pairable_type&p_B->pairable_mask) &&
|
||||
!(p_B->pairable_type&p_A->pairable_mask) )
|
||||
return; // none can pair with none
|
||||
|
@ -253,17 +253,17 @@ private:
|
|||
// if (pair_callback)
|
||||
// pair_callback(pair_callback_userdata,p_A->userdata,p_B->userdata);
|
||||
} else {
|
||||
|
||||
|
||||
E->get().refcount++;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
_FORCE_INLINE_ void _pair_unreference(Element* p_A,Element* p_B) {
|
||||
|
||||
|
||||
if (p_A==p_B)
|
||||
return;
|
||||
|
||||
|
||||
PairKey key(p_A->_id, p_B->_id);
|
||||
typename PairMap::Element *E=pair_map.find(key);
|
||||
if (!E) {
|
||||
|
@ -293,7 +293,7 @@ private:
|
|||
p_B->pair_list.erase( E->get().eB );
|
||||
pair_map.erase(E);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ void _element_check_pairs(Element *p_element) {
|
||||
|
@ -341,7 +341,7 @@ private:
|
|||
void _ensure_valid_root(const AABB& p_aabb);
|
||||
bool _remove_element_from_octant(Element *p_element,Octant *p_octant,Octant *p_limit=NULL);
|
||||
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);
|
||||
|
||||
|
||||
|
@ -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 _remove_tree(Octant *p_octant) {
|
||||
|
||||
|
||||
if (!p_octant)
|
||||
return;
|
||||
|
||||
for(int i=0;i<8;i++) {
|
||||
|
||||
|
||||
if (p_octant->children[i])
|
||||
_remove_tree(p_octant->children[i]);
|
||||
}
|
||||
|
||||
|
||||
memdelete_allocator<Octant,AL>(p_octant);
|
||||
}
|
||||
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) {
|
||||
|
||||
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*0.5 < element_size) {
|
||||
|
||||
/* at smallest possible size for the element */
|
||||
//if (p_octant->aabb.size.x*0.5 < element_size) {
|
||||
|
||||
/* at smallest possible size for the element */
|
||||
typename Element::OctantOwner owner;
|
||||
owner.octant=p_octant;
|
||||
|
||||
|
||||
if (use_pairs && p_element->pairable) {
|
||||
|
||||
|
||||
p_octant->pairable_elements.push_back(p_element);
|
||||
owner.E = p_octant->pairable_elements.back();
|
||||
} else {
|
||||
|
||||
|
||||
p_octant->elements.push_back(p_element);
|
||||
owner.E = p_octant->elements.back();
|
||||
}
|
||||
|
||||
|
||||
p_element->octant_owners.push_back( owner );
|
||||
|
||||
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) {
|
||||
|
||||
|
||||
pass++; //elements below this only get ONE reference added
|
||||
|
||||
for (int i=0;i<8;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;
|
||||
|
||||
for (int i=0;i<8;i++) {
|
||||
|
||||
|
||||
if (p_octant->children[i]) {
|
||||
/* element exists, go straight to it */
|
||||
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 {
|
||||
/* check againt AABB where child should be */
|
||||
|
||||
|
||||
AABB aabb=p_octant->aabb;
|
||||
aabb.size*=0.5;
|
||||
|
||||
|
||||
if (i&1)
|
||||
aabb.pos.x+=aabb.size.x;
|
||||
if (i&2)
|
||||
aabb.pos.y+=aabb.size.y;
|
||||
if (i&4)
|
||||
aabb.pos.z+=aabb.size.z;
|
||||
|
||||
|
||||
if (aabb.intersects_inclusive( p_element->aabb) ) {
|
||||
/* if actually intersects, create the child */
|
||||
|
||||
|
||||
Octant *child = memnew_allocator( Octant, AL );
|
||||
p_octant->children[i]=child;
|
||||
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) {
|
||||
|
||||
p_element->common_parent=p_octant;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (use_pairs) {
|
||||
|
||||
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) {
|
||||
_pair_reference( p_element,E->get() );
|
||||
E=E->next();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (p_element->pairable) {
|
||||
// and always test non-pairable if element is pairable
|
||||
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() );
|
||||
E=E->next();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -553,35 +553,35 @@ void Octree<T,use_pairs,AL>::_ensure_valid_root(const AABB& p_aabb) {
|
|||
|
||||
if (!root) {
|
||||
// octre is empty
|
||||
|
||||
|
||||
AABB base( Vector3(), Vector3(1.0,1.0,1.0) * unit_size);
|
||||
|
||||
|
||||
while ( !base.encloses(p_aabb) ) {
|
||||
|
||||
|
||||
if ( ABS(base.pos.x+base.size.x) <= ABS(base.pos.x) ) {
|
||||
/* grow towards positive */
|
||||
base.size*=2.0;
|
||||
} else {
|
||||
base.pos-=base.size;
|
||||
base.pos-=base.size;
|
||||
base.size*=2.0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
root = memnew_allocator( Octant, AL );
|
||||
|
||||
root->parent=NULL;
|
||||
root->parent_index=-1;
|
||||
root->parent=NULL;
|
||||
root->parent_index=-1;
|
||||
root->aabb=base;
|
||||
|
||||
|
||||
octant_count++;
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
AABB base=root->aabb;
|
||||
|
||||
|
||||
while( !base.encloses( p_aabb ) ) {
|
||||
|
||||
|
||||
if (base.size.x > OCTREE_SIZE_LIMIT) {
|
||||
ERR_EXPLAIN("Octree upper size limit reeached, does the AABB supplied contain NAN?");
|
||||
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_count++;
|
||||
root->parent=gp;
|
||||
|
||||
|
||||
if ( ABS(base.pos.x+base.size.x) <= ABS(base.pos.x) ) {
|
||||
/* grow towards positive */
|
||||
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;
|
||||
root->parent_index=0;
|
||||
} else {
|
||||
base.pos-=base.size;
|
||||
base.pos-=base.size;
|
||||
base.size*=2.0;
|
||||
gp->aabb=base;
|
||||
gp->children[(1<<0)|(1<<1)|(1<<2)]=root; // add at all-positive
|
||||
root->parent_index=(1<<0)|(1<<1)|(1<<2);
|
||||
}
|
||||
|
||||
|
||||
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 octant_removed=false;
|
||||
|
||||
|
||||
while(true) {
|
||||
|
||||
|
||||
// check all exit conditions
|
||||
|
||||
|
||||
if (p_octant==p_limit) // reached limit, nothing to erase, exit
|
||||
return octant_removed;
|
||||
|
||||
|
||||
bool unpaired=false;
|
||||
|
||||
|
||||
if (use_pairs && p_octant->last_pass!=pass) {
|
||||
// check wether we should unpair stuff
|
||||
// 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;
|
||||
unpaired=true;
|
||||
}
|
||||
|
||||
|
||||
bool removed=false;
|
||||
|
||||
|
||||
Octant *parent=p_octant->parent;
|
||||
|
||||
|
||||
if (p_octant->children_count==0 && p_octant->elements.empty() && p_octant->pairable_elements.empty()) {
|
||||
|
||||
|
||||
// erase octant
|
||||
|
||||
|
||||
if (p_octant==root) { // won't have a parent, just erase
|
||||
|
||||
|
||||
root=NULL;
|
||||
} else {
|
||||
ERR_FAIL_INDEX_V(p_octant->parent_index,8,octant_removed);
|
||||
|
||||
|
||||
parent->children[ p_octant->parent_index ]=NULL;
|
||||
parent->children_count--;
|
||||
}
|
||||
|
@ -668,12 +668,12 @@ bool Octree<T,use_pairs,AL>::_remove_element_from_octant(Element *p_element,Octa
|
|||
removed=true;
|
||||
octant_removed=true;
|
||||
}
|
||||
|
||||
|
||||
if (!removed && !unpaired)
|
||||
return octant_removed; // no reason to keep going up anymore! was already visited and was not removed
|
||||
|
||||
|
||||
p_octant=parent;
|
||||
|
||||
|
||||
}
|
||||
|
||||
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>
|
||||
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();
|
||||
while(E) {
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
if (p_element->pairable) {
|
||||
// and always test non-pairable if element is pairable
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
p_octant->last_pass=pass;
|
||||
|
||||
|
||||
if (p_octant->children_count==0)
|
||||
return; // small optimization for leafs
|
||||
|
||||
|
||||
for (int i=0;i<8;i++) {
|
||||
|
||||
|
||||
if (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();
|
||||
}
|
||||
|
||||
|
||||
if (p_element->pairable) {
|
||||
// and always test non-pairable if element is pairable
|
||||
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;
|
||||
|
||||
|
||||
if (p_octant->children_count==0)
|
||||
return; // small optimization for leafs
|
||||
|
||||
|
||||
for (int i=0;i<8;i++) {
|
||||
|
||||
|
||||
if (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) {
|
||||
|
||||
pass++; // will do a new pass for this
|
||||
|
||||
|
||||
typename List< typename Element::OctantOwner,AL >::Element *I=p_element->octant_owners.front();
|
||||
|
||||
|
||||
|
||||
/* FIRST remove going up normally */
|
||||
for(;I;I=I->next()) {
|
||||
|
||||
|
||||
Octant *o=I->get().octant;
|
||||
|
||||
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();
|
||||
//p_element->pair_list.clear();
|
||||
ERR_FAIL_COND( remaining );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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) {
|
||||
|
||||
// check for AABB validity
|
||||
// check for AABB validity
|
||||
#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.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.z) , 0 );
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
typename ElementMap::Element *E = element_map.insert(last_element_id++,
|
||||
Element());
|
||||
Element &e = E->get();
|
||||
|
||||
|
||||
e.aabb=p_aabb;
|
||||
e.userdata=p_userdata;
|
||||
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_mask=p_pairable_mask;
|
||||
e._id=last_element_id-1;
|
||||
|
||||
|
||||
if (!e.aabb.has_no_surface()) {
|
||||
_ensure_valid_root(p_aabb);
|
||||
_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
|
||||
|
||||
pass++;
|
||||
|
||||
|
||||
for(typename List<typename Element::OctantOwner,AL>::Element *E=owners.front();E;) {
|
||||
|
||||
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);
|
||||
ERR_FAIL_COND(!E);
|
||||
|
||||
|
||||
Element &e = E->get();
|
||||
|
||||
if (p_pairable == e.pairable && e.pairable_type==p_pairable_type && e.pairable_mask==p_pairable_mask)
|
||||
return; // no changes, return
|
||||
|
||||
|
||||
if (!e.aabb.has_no_surface()) {
|
||||
_remove_element(&e);
|
||||
}
|
||||
|
||||
|
||||
e.pairable=p_pairable;
|
||||
e.pairable_type=p_pairable_type;
|
||||
e.pairable_mask=p_pairable_mask;
|
||||
e.common_parent=NULL;
|
||||
|
||||
|
||||
if (!e.aabb.has_no_surface()) {
|
||||
_ensure_valid_root(e.aabb);
|
||||
_insert_element(&e,root);
|
||||
if (use_pairs)
|
||||
_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);
|
||||
ERR_FAIL_COND(!E);
|
||||
|
||||
|
||||
Element &e = E->get();
|
||||
|
||||
if (!e.aabb.has_no_surface()) {
|
||||
|
||||
_remove_element(&e);
|
||||
|
||||
_remove_element(&e);
|
||||
}
|
||||
|
||||
|
||||
element_map.erase(p_id);
|
||||
_optimize();
|
||||
}
|
||||
|
||||
template<class T,bool use_pairs,class AL>
|
||||
void Octree<T,use_pairs,AL>::_cull_convex(Octant *p_octant,_CullConvexData *p_cull) {
|
||||
|
||||
|
||||
if (*p_cull->result_idx==p_cull->result_max)
|
||||
return; //pointless
|
||||
|
||||
|
||||
if (!p_octant->elements.empty()) {
|
||||
|
||||
|
||||
typename List< Element*,AL >::Element *I;
|
||||
I=p_octant->elements.front();
|
||||
|
||||
|
||||
for(;I;I=I->next()) {
|
||||
|
||||
|
||||
Element *e=I->get();
|
||||
|
||||
|
||||
if (e->last_pass==pass || (use_pairs && !(e->pairable_type&p_cull->mask)))
|
||||
continue;
|
||||
e->last_pass=pass;
|
||||
|
||||
|
||||
if (e->aabb.intersects_convex_shape(p_cull->planes,p_cull->plane_count)) {
|
||||
|
||||
|
||||
if (*p_cull->result_idx<p_cull->result_max) {
|
||||
p_cull->result_array[*p_cull->result_idx] = e->userdata;
|
||||
(*p_cull->result_idx)++;
|
||||
} else {
|
||||
|
||||
|
||||
return; // pointless to continue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (use_pairs && !p_octant->pairable_elements.empty()) {
|
||||
|
||||
|
||||
typename List< Element*,AL >::Element *I;
|
||||
I=p_octant->pairable_elements.front();
|
||||
|
||||
|
||||
for(;I;I=I->next()) {
|
||||
|
||||
|
||||
Element *e=I->get();
|
||||
|
||||
|
||||
if (e->last_pass==pass || (use_pairs && !(e->pairable_type&p_cull->mask)))
|
||||
continue;
|
||||
e->last_pass=pass;
|
||||
|
||||
|
||||
if (e->aabb.intersects_convex_shape(p_cull->planes,p_cull->plane_count)) {
|
||||
|
||||
|
||||
if (*p_cull->result_idx<p_cull->result_max) {
|
||||
|
||||
p_cull->result_array[*p_cull->result_idx] = e->userdata;
|
||||
(*p_cull->result_idx)++;
|
||||
} else {
|
||||
|
||||
|
||||
return; // pointless to continue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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)) {
|
||||
_cull_convex(p_octant->children[i],p_cull);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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) {
|
||||
|
||||
|
||||
if (*p_result_idx==p_result_max)
|
||||
return; //pointless
|
||||
|
||||
|
||||
if (!p_octant->elements.empty()) {
|
||||
|
||||
|
||||
typename List< Element*,AL >::Element *I;
|
||||
I=p_octant->elements.front();
|
||||
for(;I;I=I->next()) {
|
||||
|
||||
|
||||
Element *e=I->get();
|
||||
|
||||
|
||||
if (e->last_pass==pass || (use_pairs && !(e->pairable_type&p_mask)))
|
||||
continue;
|
||||
e->last_pass=pass;
|
||||
|
||||
|
||||
if (p_aabb.intersects_inclusive(e->aabb)) {
|
||||
|
||||
|
||||
if (*p_result_idx<p_result_max) {
|
||||
|
||||
|
||||
p_result_array[*p_result_idx] = e->userdata;
|
||||
if (p_subindex_array)
|
||||
p_subindex_array[*p_result_idx] = e->subindex;
|
||||
|
||||
(*p_result_idx)++;
|
||||
} else {
|
||||
|
||||
|
||||
return; // pointless to continue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (use_pairs && !p_octant->pairable_elements.empty()) {
|
||||
|
||||
|
||||
typename List< Element*,AL >::Element *I;
|
||||
I=p_octant->pairable_elements.front();
|
||||
for(;I;I=I->next()) {
|
||||
|
||||
|
||||
Element *e=I->get();
|
||||
|
||||
|
||||
if (e->last_pass==pass || (use_pairs && !(e->pairable_type&p_mask)))
|
||||
continue;
|
||||
e->last_pass=pass;
|
||||
|
||||
|
||||
if (p_aabb.intersects_inclusive(e->aabb)) {
|
||||
|
||||
|
||||
if (*p_result_idx<p_result_max) {
|
||||
|
||||
|
||||
p_result_array[*p_result_idx] = e->userdata;
|
||||
if (p_subindex_array)
|
||||
p_subindex_array[*p_result_idx] = e->subindex;
|
||||
(*p_result_idx)++;
|
||||
} else {
|
||||
|
||||
|
||||
return; // pointless to continue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i=0;i<8;i++) {
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
return; //pointless
|
||||
|
||||
|
||||
if (!p_octant->elements.empty()) {
|
||||
|
||||
|
||||
typename List< Element*,AL >::Element *I;
|
||||
I=p_octant->elements.front();
|
||||
for(;I;I=I->next()) {
|
||||
|
||||
|
||||
Element *e=I->get();
|
||||
|
||||
|
||||
if (e->last_pass==pass || (use_pairs && !(e->pairable_type&p_mask)))
|
||||
continue;
|
||||
e->last_pass=pass;
|
||||
|
||||
|
||||
if (e->aabb.intersects_segment(p_from,p_to)) {
|
||||
|
||||
|
||||
if (*p_result_idx<p_result_max) {
|
||||
|
||||
|
||||
p_result_array[*p_result_idx] = e->userdata;
|
||||
if (p_subindex_array)
|
||||
p_subindex_array[*p_result_idx] = e->subindex;
|
||||
(*p_result_idx)++;
|
||||
|
||||
} else {
|
||||
|
||||
|
||||
return; // pointless to continue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (use_pairs && !p_octant->pairable_elements.empty()) {
|
||||
|
||||
|
||||
typename List< Element*,AL >::Element *I;
|
||||
I=p_octant->pairable_elements.front();
|
||||
for(;I;I=I->next()) {
|
||||
|
||||
|
||||
Element *e=I->get();
|
||||
|
||||
|
||||
if (e->last_pass==pass || (use_pairs && !(e->pairable_type&p_mask)))
|
||||
continue;
|
||||
|
||||
|
||||
e->last_pass=pass;
|
||||
|
||||
|
||||
if (e->aabb.intersects_segment(p_from,p_to)) {
|
||||
|
||||
|
||||
if (*p_result_idx<p_result_max) {
|
||||
|
||||
|
||||
p_result_array[*p_result_idx] = e->userdata;
|
||||
if (p_subindex_array)
|
||||
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)++;
|
||||
|
||||
} else {
|
||||
|
||||
|
||||
return; // pointless to continue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
for (int i=0;i<8;i++) {
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1357,7 +1357,7 @@ int Octree<T,use_pairs,AL>::cull_convex(const Vector<Plane>& p_convex,T** p_resu
|
|||
|
||||
if (!root)
|
||||
return 0;
|
||||
|
||||
|
||||
int result_count=0;
|
||||
pass++;
|
||||
_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_idx=&result_count;
|
||||
cdata.mask=p_mask;
|
||||
|
||||
|
||||
_cull_convex(root,&cdata);
|
||||
|
||||
|
||||
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)
|
||||
return 0;
|
||||
|
||||
|
||||
int result_count=0;
|
||||
pass++;
|
||||
_cull_AABB(root,p_aabb,p_result_array,&result_count,p_result_max,p_subindex_array,p_mask);
|
||||
|
||||
|
||||
return result_count;
|
||||
}
|
||||
|
||||
|
@ -1395,11 +1395,11 @@ int Octree<T,use_pairs,AL>::cull_segment(const Vector3& p_from, const Vector3& p
|
|||
|
||||
if (!root)
|
||||
return 0;
|
||||
|
||||
|
||||
int result_count=0;
|
||||
pass++;
|
||||
_cull_segment(root,p_from,p_to,p_result_array,&result_count,p_result_max,p_subindex_array,p_mask);
|
||||
|
||||
|
||||
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>
|
||||
Octree<T,use_pairs,AL>::Octree(real_t p_unit_size) {
|
||||
|
||||
|
||||
last_element_id=1;
|
||||
pass=1;
|
||||
unit_size=p_unit_size;
|
||||
|
|
|
@ -50,7 +50,7 @@ void Plane::normalize() {
|
|||
}
|
||||
|
||||
Plane Plane::normalized() const {
|
||||
|
||||
|
||||
Plane p = *this;
|
||||
p.normalize();
|
||||
return p;
|
||||
|
@ -66,12 +66,12 @@ Vector3 Plane::get_any_perpendicular_normal() const {
|
|||
static const Vector3 p1 = Vector3(1,0,0);
|
||||
static const Vector3 p2 = Vector3(0,1,0);
|
||||
Vector3 p;
|
||||
|
||||
|
||||
if (ABS(normal.dot(p1)) > 0.99) // if too similar to p1
|
||||
p=p2; // use p2
|
||||
else
|
||||
p=p1; // use p1
|
||||
|
||||
|
||||
p-=normal * normal.dot(p);
|
||||
p.normalize();
|
||||
|
||||
|
|
|
@ -62,9 +62,9 @@ public:
|
|||
bool intersects_segment(Vector3 p_begin, Vector3 p_end, Vector3* p_intersection) const;
|
||||
|
||||
_FORCE_INLINE_ Vector3 project(const Vector3& p_point) const {
|
||||
|
||||
|
||||
return p_point - normal * distance_to(p_point);
|
||||
}
|
||||
}
|
||||
|
||||
/* misc */
|
||||
|
||||
|
|
|
@ -30,9 +30,9 @@
|
|||
#include "print_string.h"
|
||||
|
||||
void Quat::set_euler(const Vector3& p_euler) {
|
||||
real_t half_yaw = p_euler.x * 0.5;
|
||||
real_t half_pitch = p_euler.y * 0.5;
|
||||
real_t half_roll = p_euler.z * 0.5;
|
||||
real_t half_yaw = p_euler.x * 0.5;
|
||||
real_t half_pitch = p_euler.y * 0.5;
|
||||
real_t half_roll = p_euler.z * 0.5;
|
||||
real_t cos_yaw = Math::cos(half_yaw);
|
||||
real_t sin_yaw = Math::sin(half_yaw);
|
||||
real_t cos_pitch = Math::cos(half_pitch);
|
||||
|
@ -75,7 +75,7 @@ void Quat::normalize() {
|
|||
|
||||
Quat Quat::normalized() const {
|
||||
return *this / length();
|
||||
}
|
||||
}
|
||||
|
||||
Quat Quat::inverse() const {
|
||||
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 {
|
||||
|
||||
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) {
|
||||
|
@ -261,7 +261,7 @@ Quat::Quat(const Vector3& axis, const real_t& angle) {
|
|||
set(0,0,0,0);
|
||||
else {
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -89,18 +89,18 @@ public:
|
|||
_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_ bool operator==(const Quat& p_quat) const;
|
||||
_FORCE_INLINE_ bool operator!=(const Quat& p_quat) const;
|
||||
|
||||
|
||||
operator String() const;
|
||||
|
||||
|
||||
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) {
|
||||
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);
|
||||
|
||||
|
@ -127,7 +127,7 @@ public:
|
|||
}
|
||||
|
||||
inline Quat() {x=y=z=0; w=1; }
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
@ -141,7 +141,7 @@ real_t Quat::length_squared() const {
|
|||
}
|
||||
|
||||
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) {
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
#include "math_funcs.h"
|
||||
#include "os/copymem.h"
|
||||
#include "print_string.h"
|
||||
|
||||
|
||||
|
||||
void Transform::affine_invert() {
|
||||
|
||||
|
@ -50,7 +50,7 @@ Transform Transform::affine_inverse() const {
|
|||
void Transform::invert() {
|
||||
|
||||
basis.transpose();
|
||||
origin = basis.xform(-origin);
|
||||
origin = basis.xform(-origin);
|
||||
}
|
||||
|
||||
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
|
||||
Vector3 v_x, v_y, v_z;
|
||||
|
||||
|
||||
/* Make rotation matrix */
|
||||
|
||||
|
||||
/* Z vector */
|
||||
v_z = p_eye - p_target;
|
||||
|
||||
|
||||
v_z.normalize();
|
||||
|
||||
|
||||
v_y = p_up;
|
||||
|
||||
|
||||
|
||||
v_x=v_y.cross(v_z);
|
||||
|
||||
|
||||
/* Recompute Y = Z cross X */
|
||||
v_y=v_z.cross(v_x);
|
||||
|
||||
|
||||
v_x.normalize();
|
||||
v_y.normalize();
|
||||
|
||||
|
||||
basis.set_axis(0,v_x);
|
||||
basis.set_axis(1,v_y);
|
||||
basis.set_axis(2,v_z);
|
||||
origin=p_eye;
|
||||
|
||||
|
||||
}
|
||||
|
||||
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) {
|
||||
|
||||
origin=xform(p_transform.origin);
|
||||
basis*=p_transform.basis;
|
||||
basis*=p_transform.basis;
|
||||
}
|
||||
|
||||
Transform Transform::operator*(const Transform& p_transform) const {
|
||||
|
|
|
@ -40,9 +40,9 @@ public:
|
|||
|
||||
Matrix3 basis;
|
||||
Vector3 origin;
|
||||
|
||||
void invert();
|
||||
Transform inverse() const;
|
||||
|
||||
void invert();
|
||||
Transform inverse() const;
|
||||
|
||||
void affine_invert();
|
||||
Transform affine_inverse() const;
|
||||
|
@ -76,27 +76,27 @@ public:
|
|||
|
||||
_FORCE_INLINE_ Vector3 xform(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_inv(const Plane& p_plane) const;
|
||||
|
||||
_FORCE_INLINE_ AABB xform(const AABB& p_aabb) const;
|
||||
_FORCE_INLINE_ AABB xform_inv(const AABB& p_aabb) const;
|
||||
|
||||
|
||||
void operator*=(const Transform& p_transform);
|
||||
Transform operator*(const Transform& p_transform) const;
|
||||
|
||||
Transform interpolate_with(const Transform& p_transform, float p_c) const;
|
||||
|
||||
|
||||
_FORCE_INLINE_ Transform inverse_xform(const Transform& t) const {
|
||||
|
||||
|
||||
Vector3 v = t.origin - origin;
|
||||
return Transform(basis.transpose_xform(t.basis),
|
||||
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) {
|
||||
|
||||
|
||||
basis.elements[0][0]=xx;
|
||||
basis.elements[0][1]=xy;
|
||||
basis.elements[0][2]=xz;
|
||||
|
@ -105,14 +105,14 @@ public:
|
|||
basis.elements[1][2]=yz;
|
||||
basis.elements[2][0]=zx;
|
||||
basis.elements[2][1]=zy;
|
||||
basis.elements[2][2]=zz;
|
||||
basis.elements[2][2]=zz;
|
||||
origin.x=tx;
|
||||
origin.y=ty;
|
||||
origin.z=tz;
|
||||
}
|
||||
|
||||
|
||||
operator String() const;
|
||||
|
||||
|
||||
Transform(const Matrix3& p_basis, const Vector3& p_origin=Vector3());
|
||||
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 {
|
||||
|
||||
|
||||
Vector3 v = p_vector - origin;
|
||||
|
||||
|
||||
return Vector3(
|
||||
(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 ),
|
||||
|
@ -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 {
|
||||
|
||||
|
||||
|
||||
Vector3 point=p_plane.normal*p_plane.d;
|
||||
Vector3 point_dir=point+p_plane.normal;
|
||||
point=xform(point);
|
||||
point_dir=xform(point_dir);
|
||||
|
||||
|
||||
Vector3 normal=point_dir-point;
|
||||
normal.normalize();
|
||||
real_t d=normal.dot(point);
|
||||
|
||||
|
||||
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;
|
||||
xform_inv(point);
|
||||
xform_inv(point_dir);
|
||||
|
||||
|
||||
Vector3 normal=point_dir-point;
|
||||
normal.normalize();
|
||||
real_t d=normal.dot(point);
|
||||
|
||||
|
||||
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)
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
AABB ret;
|
||||
|
||||
|
||||
ret.pos=xform(vertices[0]);
|
||||
|
||||
|
||||
for (int i=1;i<8;i++) {
|
||||
|
||||
|
||||
ret.expand_to( xform(vertices[i]) );
|
||||
}
|
||||
|
||||
|
||||
return ret;
|
||||
#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)
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
AABB ret;
|
||||
|
||||
|
||||
ret.pos=xform_inv(vertices[0]);
|
||||
|
||||
|
||||
for (int i=1;i<8;i++) {
|
||||
|
||||
|
||||
ret.expand_to( xform_inv(vertices[i]) );
|
||||
}
|
||||
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
|
|
@ -320,7 +320,7 @@ void MessageQueue::_call_function(Object* p_target, const StringName& p_func, co
|
|||
void MessageQueue::flush() {
|
||||
|
||||
|
||||
if (buffer_max_used<buffer_end); {
|
||||
if (buffer_end > buffer_max_used) {
|
||||
buffer_max_used=buffer_end;
|
||||
//statistics();
|
||||
}
|
||||
|
|
|
@ -58,8 +58,8 @@ template<class T>
|
|||
struct VariantCaster {
|
||||
|
||||
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&> {
|
||||
|
||||
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&> {
|
||||
|
||||
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() {
|
||||
|
||||
|
||||
_predelete_ok=1;
|
||||
notification(NOTIFICATION_PREDELETE,true);
|
||||
if (_predelete_ok) {
|
||||
|
@ -269,16 +269,16 @@ void Object::_postinitialize() {
|
|||
_type_ptr=_get_type_namev();
|
||||
_initialize_typev();
|
||||
notification(NOTIFICATION_POSTINITIALIZE);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void Object::get_valid_parents_static(List<String> *p_parents) {
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
void Object::_get_valid_parents_static(List<String> *p_parents) {
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
#if 0
|
||||
//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) {
|
||||
|
||||
_setv(p_name,p_value);
|
||||
|
||||
|
||||
//if (!_use_builtin_script())
|
||||
// return;
|
||||
|
||||
|
@ -303,8 +303,8 @@ void Object::set(const String& p_name, const Variant& p_value) {
|
|||
} else if (script_instance) {
|
||||
script_instance->set(p_name,p_value);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -348,7 +348,7 @@ void Object::set(const StringName& p_name, const Variant& p_value, bool *r_valid
|
|||
*r_valid=true;
|
||||
return;
|
||||
} else {
|
||||
//something inside the object... :|
|
||||
//something inside the object... :|
|
||||
bool success = _setv(p_name,p_value);
|
||||
if (success) {
|
||||
if (r_valid)
|
||||
|
@ -420,7 +420,7 @@ Variant Object::get(const String& p_name) const {
|
|||
Variant ret=_getv(p_name);
|
||||
if (ret.get_type()!=Variant::NIL)
|
||||
return ret;
|
||||
|
||||
|
||||
bool success;
|
||||
ObjectTypeDB::get_property(const_cast<Object*>(this),p_name,ret,success);
|
||||
if (success) {
|
||||
|
@ -431,11 +431,11 @@ Variant Object::get(const String& p_name) const {
|
|||
return metadata;
|
||||
else if (p_name=="script/script")
|
||||
return script;
|
||||
|
||||
|
||||
if (script_instance) {
|
||||
return script_instance->get(p_name);
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
|
||||
|
||||
if (!_use_builtin_script())
|
||||
return;
|
||||
|
||||
|
||||
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));
|
||||
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) {
|
||||
p_list->push_back( PropertyInfo(Variant::NIL,"Script Variables",PROPERTY_HINT_NONE,String(),PROPERTY_USAGE_CATEGORY));
|
||||
script_instance->get_property_list(p_list);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
void Object::get_method_list(List<MethodInfo> *p_list) const {
|
||||
|
||||
ObjectTypeDB::get_method_list(get_type_name(),p_list);
|
||||
if (script_instance) {
|
||||
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) {
|
||||
|
||||
|
||||
|
||||
_notificationv(p_notification,p_reversed);
|
||||
|
||||
|
||||
if (script_instance) {
|
||||
script_instance->notification(p_notification);
|
||||
}
|
||||
}
|
||||
|
||||
void Object::_changed_callback(Object *p_changed,const char *p_prop) {
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
void Object::add_change_receptor( Object *p_receptor ) {
|
||||
|
||||
|
||||
change_receptors.insert(p_receptor);
|
||||
}
|
||||
|
||||
|
@ -941,8 +941,8 @@ void Object::set_script(const RefPtr& p_script) {
|
|||
memdelete(script_instance);
|
||||
script_instance=NULL;
|
||||
}
|
||||
|
||||
script=p_script;
|
||||
|
||||
script=p_script;
|
||||
Ref<Script> s(script);
|
||||
|
||||
if (!s.is_null() && s->can_instance() ) {
|
||||
|
@ -1760,7 +1760,7 @@ bool Object::is_edited() const {
|
|||
#endif
|
||||
|
||||
Object::Object() {
|
||||
|
||||
|
||||
_type_ptr=NULL;
|
||||
_block_signals=false;
|
||||
_predelete_ok=0;
|
||||
|
@ -1831,12 +1831,12 @@ Object::~Object() {
|
|||
|
||||
|
||||
bool predelete_handler(Object *p_object) {
|
||||
|
||||
|
||||
return p_object->_predelete();
|
||||
}
|
||||
|
||||
void postinitialize_handler(Object *p_object) {
|
||||
|
||||
|
||||
p_object->_postinitialize();
|
||||
}
|
||||
|
||||
|
@ -1900,8 +1900,8 @@ void ObjectDB::cleanup() {
|
|||
|
||||
GLOBAL_LOCK_FUNCTION;
|
||||
if (instances.size()) {
|
||||
|
||||
WARN_PRINT("ObjectDB Instances still exist!");
|
||||
|
||||
WARN_PRINT("ObjectDB Instances still exist!");
|
||||
if (OS::get_singleton()->is_stdout_verbose()) {
|
||||
const uint32_t *K=NULL;
|
||||
while((K=instances.next(K))) {
|
||||
|
|
|
@ -200,37 +200,37 @@ ObjectTypeDB::TypeInfo::TypeInfo() {
|
|||
disabled=false;
|
||||
}
|
||||
ObjectTypeDB::TypeInfo::~TypeInfo() {
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool ObjectTypeDB::is_type(const StringName &p_type,const StringName& p_inherits) {
|
||||
|
||||
|
||||
OBJTYPE_LOCK;
|
||||
|
||||
|
||||
StringName inherits=p_type;
|
||||
|
||||
|
||||
while (inherits.operator String().length()) {
|
||||
|
||||
|
||||
if (inherits==p_inherits)
|
||||
return true;
|
||||
inherits=type_inherits_from(inherits);
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
void ObjectTypeDB::get_type_list( List<StringName> *p_types) {
|
||||
|
||||
|
||||
OBJTYPE_LOCK;
|
||||
|
||||
|
||||
const StringName *k=NULL;
|
||||
|
||||
|
||||
while((k=types.next(k))) {
|
||||
|
||||
|
||||
p_types->push_back(*k);
|
||||
}
|
||||
|
||||
|
||||
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) {
|
||||
|
||||
OBJTYPE_LOCK;
|
||||
|
||||
|
||||
const StringName *k=NULL;
|
||||
|
||||
|
||||
while((k=types.next(k))) {
|
||||
|
||||
|
||||
if (*k!=p_type && is_type(*k,p_type))
|
||||
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) {
|
||||
|
||||
|
||||
OBJTYPE_LOCK;
|
||||
|
||||
|
||||
TypeInfo *ti = types.getptr(p_type);
|
||||
ERR_FAIL_COND_V(!ti,"");
|
||||
return ti->inherits;
|
||||
}
|
||||
|
||||
bool ObjectTypeDB::type_exists(const StringName &p_type) {
|
||||
|
||||
|
||||
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) {
|
||||
|
@ -270,7 +270,7 @@ void ObjectTypeDB::add_compatibility_type(const StringName& p_type,const StringN
|
|||
}
|
||||
|
||||
Object *ObjectTypeDB::instance(const StringName &p_type) {
|
||||
|
||||
|
||||
TypeInfo *ti;
|
||||
{
|
||||
OBJTYPE_LOCK;
|
||||
|
@ -288,9 +288,9 @@ Object *ObjectTypeDB::instance(const StringName &p_type) {
|
|||
return ti->creation_func();
|
||||
}
|
||||
bool ObjectTypeDB::can_instance(const StringName &p_type) {
|
||||
|
||||
|
||||
OBJTYPE_LOCK;
|
||||
|
||||
|
||||
TypeInfo *ti = types.getptr(p_type);
|
||||
ERR_FAIL_COND_V(!ti,false);
|
||||
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;
|
||||
|
||||
|
||||
TypeInfo *type=types.getptr(p_type);
|
||||
|
||||
|
||||
while(type) {
|
||||
|
||||
|
||||
if (type->disabled) {
|
||||
|
||||
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()) {
|
||||
|
||||
|
||||
MethodBind *method=type->method_map.get(E->get());
|
||||
MethodInfo minfo;
|
||||
minfo.name=E->get();
|
||||
minfo.id=method->get_method_id();
|
||||
|
||||
for (int i=0;i<method->get_argument_count();i++) {
|
||||
|
||||
|
||||
//Variant::Type t=method->get_argument_type(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
|
||||
|
||||
|
||||
if (p_no_inheritance)
|
||||
break;
|
||||
|
||||
|
||||
type=type->inherits_ptr;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
MethodBind *ObjectTypeDB::get_method(StringName p_type, StringName p_name) {
|
||||
|
||||
OBJTYPE_LOCK;
|
||||
|
||||
|
||||
TypeInfo *type=types.getptr(p_type);
|
||||
|
||||
|
||||
while(type) {
|
||||
|
||||
|
||||
MethodBind **method=type->method_map.getptr(p_name);
|
||||
if (method && *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) {
|
||||
|
||||
OBJTYPE_LOCK;
|
||||
|
||||
|
||||
TypeInfo *type=types.getptr(p_type);
|
||||
if (!type) {
|
||||
|
||||
ERR_FAIL_COND(!type);
|
||||
}
|
||||
|
||||
|
||||
if (type->constant_map.has(p_name)) {
|
||||
|
||||
ERR_FAIL();
|
||||
}
|
||||
|
||||
|
||||
type->constant_map[p_name]=p_constant;
|
||||
#ifdef DEBUG_METHODS_ENABLED
|
||||
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) {
|
||||
|
||||
OBJTYPE_LOCK;
|
||||
|
||||
|
||||
TypeInfo *type=types.getptr(p_type);
|
||||
|
||||
|
||||
while(type) {
|
||||
|
||||
|
||||
#ifdef DEBUG_METHODS_ENABLED
|
||||
for(List<StringName>::Element *E=type->constant_order.front();E;E=E->next())
|
||||
p_constants->push_back(E->get());
|
||||
|
@ -456,7 +456,7 @@ void ObjectTypeDB::get_integer_constant_list(const StringName& p_type, List<Stri
|
|||
#endif
|
||||
if (p_no_inheritance)
|
||||
break;
|
||||
|
||||
|
||||
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) {
|
||||
|
||||
OBJTYPE_LOCK;
|
||||
|
||||
|
||||
|
||||
|
||||
TypeInfo *type=types.getptr(p_type);
|
||||
|
||||
|
||||
while(type) {
|
||||
|
||||
|
||||
|
||||
int *constant=type->constant_map.getptr(p_name);
|
||||
if (constant) {
|
||||
|
||||
|
||||
if (p_success)
|
||||
*p_success=true;
|
||||
return *constant;
|
||||
}
|
||||
|
||||
|
||||
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) {
|
||||
|
@ -966,7 +966,7 @@ void ObjectTypeDB::init() {
|
|||
}
|
||||
|
||||
void ObjectTypeDB::cleanup() {
|
||||
|
||||
|
||||
|
||||
#ifndef NO_THREADS
|
||||
|
||||
|
@ -974,19 +974,19 @@ void ObjectTypeDB::cleanup() {
|
|||
#endif
|
||||
|
||||
//OBJTYPE_LOCK; hah not here
|
||||
|
||||
|
||||
const StringName *k=NULL;
|
||||
|
||||
|
||||
while((k=types.next(k))) {
|
||||
|
||||
|
||||
TypeInfo &ti=types[*k];
|
||||
|
||||
|
||||
const StringName *m=NULL;
|
||||
while((m=ti.method_map.next(m))) {
|
||||
|
||||
|
||||
memdelete( ti.method_map[*m] );
|
||||
}
|
||||
}
|
||||
}
|
||||
types.clear();
|
||||
resource_base_extensions.clear();
|
||||
compat_types.clear();
|
||||
|
|
|
@ -42,9 +42,9 @@ struct ParamHint {
|
|||
PropertyHint hint;
|
||||
String hint_text;
|
||||
Variant default_val;
|
||||
|
||||
|
||||
ParamHint(const String& p_name="", PropertyHint p_hint=PROPERTY_HINT_NONE, const String& p_hint_text="",Variant p_default_val=Variant()) {
|
||||
|
||||
|
||||
name=p_name;
|
||||
hint=p_hint;
|
||||
hint_text=p_hint_text;
|
||||
|
@ -73,9 +73,9 @@ struct MethodDefinition {
|
|||
|
||||
StringName name;
|
||||
Vector<StringName> args;
|
||||
MethodDefinition() {}
|
||||
MethodDefinition() {}
|
||||
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
|
||||
|
||||
class ObjectTypeDB {
|
||||
|
||||
|
||||
struct PropertySetGet {
|
||||
|
||||
int index;
|
||||
|
@ -121,7 +121,7 @@ class ObjectTypeDB {
|
|||
};
|
||||
|
||||
struct TypeInfo {
|
||||
|
||||
|
||||
TypeInfo *inherits_ptr;
|
||||
HashMap<StringName,MethodBind*,StringNameHasher> method_map;
|
||||
HashMap<StringName,int,StringNameHasher> constant_map;
|
||||
|
@ -143,12 +143,12 @@ class ObjectTypeDB {
|
|||
TypeInfo();
|
||||
~TypeInfo();
|
||||
};
|
||||
|
||||
|
||||
template<class T>
|
||||
static Object *creator() {
|
||||
return memnew( T );
|
||||
}
|
||||
|
||||
|
||||
static Mutex *lock;
|
||||
static HashMap<StringName,TypeInfo,StringNameHasher> types;
|
||||
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);
|
||||
public:
|
||||
|
||||
public:
|
||||
|
||||
// DO NOT USE THIS!!!!!! NEEDS TO BE PUBLIC BUT DO NOT USE NO MATTER WHAT!!!
|
||||
template<class T>
|
||||
static void _add_type() {
|
||||
|
@ -195,7 +195,7 @@ public:
|
|||
|
||||
template<class T>
|
||||
static void register_type() {
|
||||
|
||||
|
||||
GLOBAL_LOCK_FUNCTION;
|
||||
T::initialize_type();
|
||||
TypeInfo *t=types.getptr(T::get_type_static());
|
||||
|
@ -206,7 +206,7 @@ public:
|
|||
|
||||
template<class T>
|
||||
static void register_virtual_type() {
|
||||
|
||||
|
||||
GLOBAL_LOCK_FUNCTION;
|
||||
T::initialize_type();
|
||||
//nothing
|
||||
|
@ -247,9 +247,9 @@ public:
|
|||
ParamDef d4=ParamDef(),
|
||||
ParamDef d5=ParamDef()
|
||||
) {
|
||||
|
||||
|
||||
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 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 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);
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
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 * da = create_func[p_access]?create_func[p_access]():NULL;
|
||||
if (da) {
|
||||
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);
|
||||
if (!d)
|
||||
return p_path;
|
||||
|
||||
|
||||
d->change_dir(p_path);
|
||||
String full=d->get_current_dir();
|
||||
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) {
|
||||
|
||||
|
||||
//printf("copy %s -> %s\n",p_from.ascii().get_data(),p_to.ascii().get_data());
|
||||
Error err;
|
||||
FileAccess *fsrc = FileAccess::open(p_from, FileAccess::READ,&err);
|
||||
|
||||
|
||||
if (err) {
|
||||
|
||||
ERR_FAIL_COND_V( err, err );
|
||||
}
|
||||
|
||||
|
||||
|
||||
FileAccess *fdst = FileAccess::open(p_to, FileAccess::WRITE,&err );
|
||||
if (err) {
|
||||
|
||||
|
||||
fsrc->close();
|
||||
memdelete( fsrc );
|
||||
ERR_FAIL_COND_V( err, err );
|
||||
}
|
||||
|
||||
|
||||
fsrc->seek_end(0);
|
||||
int size = fsrc->get_pos();
|
||||
fsrc->seek(0);
|
||||
err = OK;
|
||||
while(size--) {
|
||||
|
||||
|
||||
if (fsrc->get_error()!=OK) {
|
||||
err= fsrc->get_error();
|
||||
break;
|
||||
|
@ -400,13 +400,13 @@ Error DirAccess::copy(String p_from,String p_to) {
|
|||
err= fdst->get_error();
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
fdst->store_8( fsrc->get_8() );
|
||||
}
|
||||
|
||||
|
||||
memdelete(fsrc);
|
||||
memdelete(fdst);
|
||||
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
|
@ -79,13 +79,13 @@ public:
|
|||
virtual String get_next()=0;
|
||||
virtual bool current_is_dir() 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 String get_drive(int p_drive)=0;
|
||||
virtual int get_current_drive();
|
||||
|
||||
|
||||
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 Error make_dir(String p_dir)=0;
|
||||
|
@ -100,7 +100,7 @@ public:
|
|||
virtual Error copy(String p_from,String p_to);
|
||||
virtual Error rename(String p_from, String p_to)=0;
|
||||
virtual Error remove(String p_name)=0;
|
||||
|
||||
|
||||
static String get_full_path(const String& p_path,AccessType p_access);
|
||||
static DirAccess *create_for_path(const String& p_path);
|
||||
|
||||
|
@ -111,7 +111,7 @@ public:
|
|||
FILE_TYPE_FILE,
|
||||
FILE_TYPE_DIR,
|
||||
};
|
||||
|
||||
|
||||
//virtual DirType get_file_type() const=0;
|
||||
*/
|
||||
static DirAccess *create(AccessType p_access);
|
||||
|
|
|
@ -169,69 +169,69 @@ String FileAccess::fix_path(const String& p_path) const {
|
|||
return r_path;
|
||||
} break;
|
||||
}
|
||||
|
||||
|
||||
return r_path;
|
||||
}
|
||||
|
||||
/* these are all implemented for ease of porting, then can later be optimized */
|
||||
|
||||
uint16_t FileAccess::get_16()const {
|
||||
|
||||
|
||||
uint16_t res;
|
||||
uint8_t a,b;
|
||||
|
||||
|
||||
a=get_8();
|
||||
b=get_8();
|
||||
|
||||
|
||||
if (endian_swap) {
|
||||
|
||||
|
||||
SWAP( a,b );
|
||||
}
|
||||
|
||||
|
||||
res=b;
|
||||
res<<=8;
|
||||
res|=a;
|
||||
|
||||
|
||||
return res;
|
||||
}
|
||||
uint32_t FileAccess::get_32() const{
|
||||
|
||||
|
||||
uint32_t res;
|
||||
uint16_t a,b;
|
||||
|
||||
|
||||
a=get_16();
|
||||
b=get_16();
|
||||
|
||||
|
||||
if (endian_swap) {
|
||||
|
||||
|
||||
SWAP( a,b );
|
||||
}
|
||||
|
||||
|
||||
res=b;
|
||||
res<<=16;
|
||||
res|=a;
|
||||
|
||||
return res;
|
||||
|
||||
return res;
|
||||
}
|
||||
uint64_t FileAccess::get_64()const {
|
||||
|
||||
|
||||
uint64_t res;
|
||||
uint32_t a,b;
|
||||
|
||||
|
||||
a=get_32();
|
||||
b=get_32();
|
||||
|
||||
|
||||
if (endian_swap) {
|
||||
|
||||
|
||||
SWAP( a,b );
|
||||
}
|
||||
|
||||
|
||||
res=b;
|
||||
res<<=32;
|
||||
res|=a;
|
||||
|
||||
return res;
|
||||
|
||||
|
||||
return res;
|
||||
|
||||
}
|
||||
|
||||
float FileAccess::get_float() const {
|
||||
|
@ -262,15 +262,15 @@ String FileAccess::get_line() const {
|
|||
CharString line;
|
||||
|
||||
CharType c=get_8();
|
||||
|
||||
|
||||
while(!eof_reached()) {
|
||||
|
||||
|
||||
if (c=='\n' || c=='\0') {
|
||||
line.push_back(0);
|
||||
return String::utf8(line.get_data());
|
||||
} else if (c!='\r')
|
||||
line.push_back(c);
|
||||
|
||||
|
||||
c=get_8();
|
||||
}
|
||||
line.push_back(0);
|
||||
|
@ -284,7 +284,7 @@ Vector<String> FileAccess::get_csv_line(String delim) const {
|
|||
String l;
|
||||
int qc=0;
|
||||
do {
|
||||
l+=get_line();
|
||||
l+=get_line()+"\n";
|
||||
qc=0;
|
||||
for(int i=0;i<l.length();i++) {
|
||||
|
||||
|
@ -295,6 +295,8 @@ Vector<String> FileAccess::get_csv_line(String delim) const {
|
|||
|
||||
} while (qc%2);
|
||||
|
||||
l=l.substr(0, l.length()-1);
|
||||
|
||||
Vector<String> strings;
|
||||
|
||||
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 i=0;
|
||||
for (i=0; i<p_length && !eof_reached(); i++)
|
||||
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) {
|
||||
|
||||
|
||||
uint8_t a,b;
|
||||
|
||||
|
||||
a=p_dest&0xFF;
|
||||
b=p_dest>>8;
|
||||
|
||||
|
||||
if (endian_swap) {
|
||||
|
||||
|
||||
SWAP( a,b );
|
||||
}
|
||||
|
||||
|
||||
store_8(a);
|
||||
store_8(b);
|
||||
|
||||
}
|
||||
void FileAccess::store_32(uint32_t p_dest) {
|
||||
|
||||
|
||||
|
||||
|
||||
uint16_t a,b;
|
||||
|
||||
|
||||
a=p_dest&0xFFFF;
|
||||
b=p_dest>>16;
|
||||
|
||||
|
||||
if (endian_swap) {
|
||||
|
||||
|
||||
SWAP( a,b );
|
||||
}
|
||||
|
||||
|
||||
store_16(a);
|
||||
store_16(b);
|
||||
|
||||
|
||||
}
|
||||
void FileAccess::store_64(uint64_t p_dest) {
|
||||
|
||||
|
||||
uint32_t a,b;
|
||||
|
||||
|
||||
a=p_dest&0xFFFFFFFF;
|
||||
b=p_dest>>32;
|
||||
|
||||
|
||||
if (endian_swap) {
|
||||
|
||||
|
||||
SWAP( a,b );
|
||||
}
|
||||
|
||||
|
||||
store_32(a);
|
||||
store_32(b);
|
||||
|
||||
|
||||
}
|
||||
|
||||
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) {
|
||||
|
||||
|
||||
for (int i=0;i<p_length;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