Compare commits

...

461 Commits
master ... 2.0

Author SHA1 Message Date
Rémi Verschelde 820dd1d001 Version 2.0.4.1, hotfix for #5620 2016-07-10 11:45:08 +02:00
George Marques 78883ea57d Fix builtin OpenSSL configuration
Fixes a bug that happens on Windows 64-bits.

(cherry picked from commit 2c6d0d4905)
2016-07-10 10:30:17 +02:00
Juan Linietsky 9cc9b45948 Finally fixes the infamous bug #4444, hoping to never see you again.
Closes #4444.

(cherry picked from commit b0f0ae0723)
2016-07-10 10:30:17 +02:00
eska 828fa9af11 Fix help search dialog titles
(cherry picked from commit af395cea42)
2016-07-10 10:30:17 +02:00
SuperUserNameMan 8a615b27ad fixes #5464 windows_joystick close_joystick bug
(cherry picked from commit 2511f48339)
2016-07-10 10:30:17 +02:00
Rémi Verschelde 5184b215a9 Revert "update EditorDirDialog on external change, closes #4629"
This reverts commit 257d370677.
Fixes #5620.
2016-07-10 10:30:05 +02:00
Rémi Verschelde 7ce99c23dd Version 2.0.4 stable 2016-07-09 01:05:23 +02:00
Rémi Verschelde af3cf7806e OSX export: Default to fat format, make it an enum
Since we want to distribute only the fat binary in the official templates, this should
make it work out of the box. 32 bits and 64 bits options are still available for people
that want them, but will throw an error if the binaries are not in the template zip.

(cherry picked from commit 02aeac12d1)
2016-07-09 01:01:31 +02:00
Ariel Manzur 687248bbf4 added "arch" parameter, made iphone use it to build isim
(cherry picked from commit 10c512e46d)
2016-07-09 00:54:22 +02:00
Rémi Verschelde 6d6b14d112 iOS simulator: merge into iphone detect.py
Fixes #4489

(cherry picked from commit dc8c145488)
2016-07-09 00:54:16 +02:00
Juan Linietsky 75cc8dc6b4 corrently parse utf8 from zip_io open, closes #1708
this probably failed when exporting or opening android apk files too, should fix that too.

(cherry picked from commit 1c541a2bee)
2016-07-09 00:08:33 +02:00
Rémi Verschelde 106199dfa7 classref: Add docs for InputEvent* and InputMap
(cherry picked from commit 69c8b583e7)
2016-07-08 23:45:31 +02:00
Rémi Verschelde 192688e7eb classref: Fix arg name for is_action_pressed/released
Also position TEXTURE_SPHERE constant properly.

(cherry picked from commit a15de80942)
2016-07-08 23:41:58 +02:00
eska a9a8bb281d Pass mouse position to Input singleton in web export
(cherry picked from commit 4beeff9433)
2016-07-08 21:27:00 +02:00
Franklin Sobrinho 90c8dbb890 Fix own world option of Viewport.
It happens when the viewport has WorldEnviroment child with a valid Enviroment

(cherry picked from commit 6b154c9706)
2016-07-08 20:47:19 +02:00
Juan Linietsky 6e7db99614 Avoid crash if setting modifiers fails, closes #5158
(cherry picked from commit 7e3044981e)
2016-07-08 19:28:54 +02:00
Juan Linietsky 3963f89ebd remove warnings if a script is missing and can't be opened
(cherry picked from commit d8c31e0e74)
2016-07-08 19:28:54 +02:00
Juan Linietsky f4a5963ca9 Fix several bugs related to node duplication and signals, closes #5405
(cherry picked from commit 17e4ead62a)
2016-07-08 19:18:09 +02:00
Pawel Kowal d4cb381ce0 Update String.capitalize() documentation
(cherry picked from commit fe49b71804)
2016-07-08 19:15:03 +02:00
Rémi Verschelde 2c3511a284 classref: Sync for new sorting of constants 2016-07-08 19:13:06 +02:00
George Marques 9420a1b6c1 Make sure builtin types' constants remain in order
This adds a list of constants for VariantCall to make sure the order of
register is kept when showing in the editor help and in the documentation.

This also remove the sorting of constants from the doctool, so it keeps
the natural order in classes.xml.

(cherry picked from commit 29b62ce5d0)
2016-07-08 19:01:59 +02:00
volzhs 8aeacd935c Fix crash when null value through jni on android
(cherry picked from commit b09dbaa78e)
2016-07-08 19:01:36 +02:00
Ignacio Etcheverry f9b7baa546 Prettier str() for arrays
(cherry picked from commit 38ed5d9c7d)
2016-07-08 18:56:50 +02:00
Andreas Haas 7589307911 Windows: prevent freeze while moving or resizing the game window.
When moving or resizing the window, Windows spins up a seperate event-loop, effectively blocking the normal one.
To work around this, we're starting a timer that will continue sending WM_TIMER messages which we can use to keep the mainloop running.

fixes #4695

(cherry picked from commit 6856c52491)
2016-07-08 18:56:28 +02:00
Juan Linietsky 6199efbc7e throw error if GridContainer::set_columns goes below 1, closes #5316
(cherry picked from commit f6725f9768)
2016-07-08 18:52:30 +02:00
Juan Linietsky 801db4c708 Make both signals be ordered and samplelibrary items too, fixes scenes changing for git, closes #5289
(cherry picked from commit b391306828)
2016-07-08 18:52:17 +02:00
Juan Linietsky 9b90d70ae7 Only emit item_selected once per Tree row, closes #5280
(cherry picked from commit 89bb72b2d3)
2016-07-08 18:48:46 +02:00
Juan Linietsky 242ceb1869 Remove error when getting dependencies from tscn files in some cases, closes #3897
(cherry picked from commit 519fce94e9)
2016-07-08 18:43:29 +02:00
Juan Linietsky de0b7b871b Fix bug in inner class reference, closes #1411
(cherry picked from commit cf6450043d)
2016-07-08 18:42:07 +02:00
Juan Linietsky eaca35adfe Fixed bug related to resolving constants in a class, closes #1110
(cherry picked from commit f4c6640827)
2016-07-08 18:42:02 +02:00
Juan Linietsky dffa1da012 Fix extends issue, closes #4026
(cherry picked from commit 565bb3afcc)
2016-07-08 18:41:37 +02:00
Juan Linietsky a2103bac7c Fixed bug in instance state ordering, closes #3904
(cherry picked from commit 8e1c0f287d)
2016-07-08 18:39:23 +02:00
Juan Linietsky a2d2eb9a63 Avoid recursion in filesystem scanning, closes #3838
(cherry picked from commit 41a26528e4)
2016-07-08 18:39:12 +02:00
Rémi Verschelde 3ce0380ba4 Fix style bug in event queue
Same fix as for 1f9812ab83
Not sure if this code actually does anything though, `buffer_max_used` seems unused.

(cherry picked from commit bd424d8f73)
2016-07-08 18:38:35 +02:00
Juan Linietsky 34e6e284db fix bug in reporting of message queue size
(cherry picked from commit 1f9812ab83)
2016-07-08 18:38:14 +02:00
Juan Linietsky 302abb1449 Properly complain when a scene file has not be selected, closes #3811
(cherry picked from commit d41b7a66e9)
2016-07-08 18:36:06 +02:00
Juan Linietsky c5fd6a3b69 Ability to rotate controls using tool, closes #3800
(cherry picked from commit e2d208f122)
2016-07-08 18:34:31 +02:00
Juan Linietsky 6813c89021 Properly deliver localized coordinates when passing gui events through parents, closes #4215
(cherry picked from commit 47d6cc08bb)
2016-07-08 18:34:10 +02:00
Ferdinand Thiessen 406daa8f7f Fix compiling for X11 on non-86, this fixes #5444
(cherry picked from commit 9e751178eb)
2016-07-08 18:33:27 +02:00
George Marques 694120210a Fix visual server error when minimizing the window
(cherry picked from commit bf44275b1a)
2016-07-08 18:33:13 +02:00
Juan Linietsky 9a7c310134 Avoid mirroring to go negative to fix crash, closes #4036
(cherry picked from commit 10f411b47b)
2016-07-08 18:23:22 +02:00
Juan Linietsky ea7da3bf08 remove the warning of instances in use at exit
(cherry picked from commit 8baa85d6b4)
2016-07-08 18:23:08 +02:00
Juan Linietsky 9592dd3e3b Fix error reporting when a scene is not imported properly, closes #3968
(cherry picked from commit 33f1204dc4)
2016-07-08 18:20:55 +02:00
Paulb23 9d85bfa00a Fixed selected text turning black, issue 5199
(cherry picked from commit 7f98f37f13)
2016-07-08 18:18:48 +02:00
Pedro J. Estébanez 5083e18b89 Optimize member access with self
Let the compiler take the fast path when a member is superfluously accessed with `self.`.

(cherry picked from commit d306b9bea5)
2016-07-08 18:18:00 +02:00
paper-pauper 3ff466770a Changes X11 res_name to "Godot_Engine"
Add additional/alternative WM_CLASS; only affects the game window, avoids redundancy and allows finer control in WMs (#5265)
(cherry picked from commit dd1ad31757)
2016-07-08 18:16:09 +02:00
volzhs 584deb807e Fix string array parameter check with jni
(cherry picked from commit 456b7733fc)
2016-07-08 18:07:11 +02:00
volzhs 6116174d49 Remove duplicated aidl for android
Tested IAP function on device.

(cherry picked from commit a5a5bdef25)
2016-07-08 18:06:59 +02:00
Rémi Verschelde 8a451e49e5 Revert "Fixed the order of events called by _input, closes #4384"
This reverts commit 299b0102f0.
2016-07-08 16:25:19 +02:00
Saracen b0aab53853 Dynamic property list for control margins allowing floating point properties to be used with ratio anchors.
(cherry picked from commit d8392dd117)
2016-07-08 16:25:19 +02:00
Juan Linietsky 10eedf62b8 Fixed bug using DirAccess in Android Marshmallow due to data dir being a symlink 2016-07-02 11:46:15 -03:00
Rémi Verschelde 673ef0cf88 Ignore some 2.1-specific files 2016-06-25 02:04:27 +02:00
Andreas Haas f7436c7d16 Add "bool" to GDScript reserverd keywords
Noticed that "bool" wasn't highlighted when used like `export(bool) var is_xy = false`

(cherry picked from commit c871cf6801)
2016-06-25 02:04:27 +02:00
George Marques c015341221 Fix bug in String==StrRange comparison
It was comparing the StrRange with itself, always return true if both
were the same length.

Fix #3843

(cherry picked from commit f4dfa37a23)
2016-06-25 02:04:27 +02:00
Juan Linietsky 6e49bc8210 Properly report a valid error instead of reporting as a bug, closes #3841
(cherry picked from commit 95e3279d34)
2016-06-25 02:04:27 +02:00
volzhs c2226d1199 Fix network IP setting change
Fix #5368

(cherry picked from commit 515472bc52)
2016-06-25 02:04:27 +02:00
George Marques 7fd9ff70f9 Add docs for String and CanvasItem
(cherry picked from commit 6776fa63de)
2016-06-25 02:04:27 +02:00
George Marques 1218d8f2a2 Rename CanvasItem.edit_get() to edit_get_state()
This makes more sense of what it does and correlates to edit_set_state()

(cherry picked from commit b06d235ce8)
2016-06-25 01:56:14 +02:00
Juan Linietsky cf300ace96 Fix issue saving flags (size fill expand), fixes #4176
(cherry picked from commit a8f8f52b19)
2016-06-25 01:55:39 +02:00
Rémi Verschelde 4e1dcd3d0b png: Do not output warnings as errors
(cherry picked from commit 9bf3ee7acc)
2016-06-25 01:55:31 +02:00
Paulb23 5907bddda5 Fixed save as not working with scripts
(cherry picked from commit c68e4e8cbe)
2016-06-25 01:54:13 +02:00
volzhs 39cc2cbfb9 fix android resource locale
(cherry picked from commit 591be5df25)
2016-06-25 01:54:00 +02:00
Juan Linietsky 140949e013 Fixed error using the same atlas rect for all images, closes #4139
(cherry picked from commit 3edf66477a)
2016-06-25 01:53:27 +02:00
Rémi Verschelde 5b3551a91f classref: Sync with the new sorting behaviour 2016-06-25 01:52:14 +02:00
George Marques 2389712638 Fix classes.xml sorting
Make methods, signals, theme items and constants sort correctly

(cherry picked from commit 9bde4e5652
+ a needed change from e8eb396d7cfec8a96efb78719c0556f1beccf68)
2016-06-25 01:50:58 +02:00
Rémi Verschelde 1a3d408f52 classref: Sync with backported patches 2016-06-25 01:50:55 +02:00
Bojidar Marinov 0ce2f76d5a Fix a inherited transform bug with Camera2D preview drawing
Closes #5339

(cherry picked from commit f3342eb72e)
2016-06-25 01:42:00 +02:00
George Marques 35c64c1824 Fix File.get_as_text() to return the whole file
It was returning only from the cursor forward.

(cherry picked from commit 0f20d8756e)
2016-06-25 01:42:00 +02:00
George Marques aa581a067d Add classref for File class
(cherry picked from commit 4d33eb01d7)
2016-06-25 01:42:00 +02:00
sunnystormy 418cd58d47 Renamed Trackpad Hint to Emulate 3 Button Mouse. (#5258)
(cherry picked from commit b3b1fdae85)
2016-06-25 01:42:00 +02:00
Juan Linietsky 0c71eb8a1e do not crash when generating preview of very large sound files, fixes #4123
(cherry picked from commit 9b8f2741ae)
2016-06-25 01:42:00 +02:00
Juan Linietsky 3318860539 fix CanvasItem.get_global_transform() and CanvasItem.get_local_transform(), closes #4075
(cherry picked from commit fa0d1cd27c)
2016-06-25 01:41:59 +02:00
Juan Linietsky d1dbc7fe93 fix bug decompressing bc texture, closes #4404
(cherry picked from commit 9d4cdc6d8a)
2016-06-25 01:41:59 +02:00
Juan Linietsky 299b0102f0 Fixed the order of events called by _input, closes #4384
(cherry picked from commit ad8d4a6b26)
2016-06-25 01:41:59 +02:00
Juan Linietsky fb255a69b6 Add quotes to .tscn keys, solves #4366
(cherry picked from commit 6872139300)
2016-06-25 01:41:59 +02:00
Juan Linietsky 1bfaea0d76 added missing status, closes #4361
(cherry picked from commit e9d2c9ad51)
2016-06-25 01:41:59 +02:00
Juan Linietsky ad01fa2248 Allow mouse wheel to go throuhgh so scroll containers work properly, fixes #4431
(cherry picked from commit 85d8000449)
2016-06-25 01:41:59 +02:00
Juan Linietsky b457b8ac89 Fix error storing path for children of instanced nodes in .tscn, fixes #4320 fixes #4579 fixes #4580
(cherry picked from commit 6bdd17f07c)
2016-06-25 01:41:59 +02:00
volzhs 5582d37af9 correct current Intent for android
(cherry picked from commit 780fa60072)
2016-06-25 01:41:59 +02:00
Juan Linietsky 8c5577e9e4 properly initialize loops to 0 in eventplayer
(cherry picked from commit 93441d6119)
2016-06-25 01:41:59 +02:00
Juan Linietsky 7076e98f40 fix loop counter for eventstream, closes #4493
(cherry picked from commit 8f7a1367fe)
2016-06-25 01:41:59 +02:00
Juan Linietsky a71ea0abc6 Make dure to only call drop_data if can_drop_data returned true, closes #4616
(cherry picked from commit 0e07f49a03)
2016-06-25 01:41:59 +02:00
George Marques edadb46bd4 Fix TextEdit cursor position after undo remove text
It was going to where the text started, now it goes to where the text
ends.

(cherry picked from commit 831ae2d510)
2016-06-25 01:41:58 +02:00
J08nY 86c4bbc031 libtheora: New version 1.1.1
(cherry picked from commit 214f316cf9)
2016-06-25 01:41:58 +02:00
J08nY 8d9121f0b0 libvorbis: New version 1.3.5
(cherry picked from commit 644e9076bb)
2016-06-25 01:41:58 +02:00
Mehmet Durgel c9716ebd00 Clarification about enter keys confusion
Some Languages threat KEY_RETURN and KEY_ENTER keys having the same keycode (eg: Javascript).
Added additional explanation about this issue.
Related to #4595

(cherry picked from commit 92fc3fa536)
2016-06-25 01:41:58 +02:00
J08nY a04be3e44b libogg: New version 1.3.2
(cherry picked from commit 98f23d27a4)
2016-06-25 01:41:58 +02:00
Juan Linietsky af41d7bffa Add function to get the color picker dialog from ColorPickerButton, closes #4415
(cherry picked from commit 400febf585)
2016-06-25 01:41:58 +02:00
J08nY 61b087dd66 Classref: Mutex, Semaphore, Thread, *Array (#5278)
(cherry picked from commit b587a13293)
2016-06-25 01:41:58 +02:00
Juan Linietsky 257d370677 update EditorDirDialog on external change, closes #4629
(cherry picked from commit 5e7f1fc79b)
2016-06-25 01:41:57 +02:00
Juan Linietsky beb2176399 Make ".." always appear even if dir is unlistable (likely lacking permissions), closes #1938
(cherry picked from commit adc13e9027)
2016-06-25 01:41:57 +02:00
Ignacio Etcheverry 18cb1f8e44 LineEdit: Fix and improve selection behaviour
(cherry picked from commit 99612207b7)
2016-06-25 01:41:57 +02:00
Dennis Brakhane a04a78c7f6 correctly parse floats in scientific notation
GDScript incorrectly parsed float values in scientific notation
when no decimal point was given. "1e-5" was parsed as "15".

Fix this by not requiring a decimal point when we found an exponent
for the number to be considered a float.

Fixes #5267

(cherry picked from commit c246931f03)
2016-06-25 01:41:57 +02:00
Juan Linietsky 8df46cddcb Fixed fractional offset not being reset in ringbuffer resamples, closes #4764
Probably fixes other streamplayer issues too.

(cherry picked from commit 3b5f1afb5c)
2016-06-25 01:41:57 +02:00
Juan Linietsky 775b089548 TabContainer now reports proper minimum size, closes #4896
(cherry picked from commit 65bcde0a7d)
2016-06-25 01:41:57 +02:00
Juan Linietsky 7b36595641 Send body inout notifications after state is applied, fixes #4683
(cherry picked from commit 95dc15b750)
2016-06-25 01:41:57 +02:00
J08nY f5d3d9cc5f Classref: added PacketPeer*
(cherry picked from commit 541a1226cd)
2016-06-25 01:41:57 +02:00
J08nY be4babccba Fixed PacketPeer.get_var() return type in docs
(cherry picked from commit 6bbc53ee18)
2016-06-25 01:41:57 +02:00
volzhs 6a1368d24d fix errors while exporting android
(cherry picked from commit e6bbe91994)
2016-06-25 01:41:57 +02:00
J08nY 109e58cf75 Classref: Added docs for StreamPeer* (#5216)
(cherry picked from commit cffdc52482)
2016-06-25 01:41:56 +02:00
George Marques 0b8cf7946e Fix javascript build in Windows
Fix #3438

(cherry picked from commit c48ffed87a)
2016-06-25 01:41:56 +02:00
J08nY c1e004ffca String documentation: .ord_at() returns int not String
fixes #5189

(cherry picked from commit 58a891265a)
2016-06-25 01:41:56 +02:00
Juan Linietsky d662f5aa63 does not fix the bug reported in #4326 and #4818,
but at least make sure it throws and error and does not crash

(cherry picked from commit 333de40180)
2016-06-25 01:41:56 +02:00
Juan Linietsky 85c6d1b37d correctly wrap lines longer than width in richtextlabel, fixes #4735
(cherry picked from commit c204170232)
2016-06-25 01:41:56 +02:00
Juan Linietsky fd4d666289 Better error text when trying to add/remove/move child nodes in a busy parent, closes #4838
(cherry picked from commit 37ed2bae69)
2016-06-25 01:41:56 +02:00
George Marques d8f9c95dbd Fix crash in code completion
Fix #4641

(cherry picked from commit 17b6cebcfe)
2016-06-25 01:41:56 +02:00
Juan Linietsky 56c5da8565 changed visual server free() to free_rid() like in the other servers. Fixes #4917
(cherry picked from commit 64b4253dbf)
2016-06-25 01:41:56 +02:00
Andreas Haas c2e09a21ac Update gamepad mappings.
Merge mappings from https://github.com/gabomdq/SDL_GameControllerDB

(cherry picked from commit 3d0b390457)
2016-06-25 01:41:56 +02:00
J08nY d8d926730c Dictionary: rename param in .has() .has_all() .erase()
fixes #5190, param should be named key, not value

(cherry picked from commit 7a19e3c6ae)
2016-06-25 01:22:42 +02:00
Juan Linietsky da45e32ef1 -Avoid negative zero from being saved to config files o resource files, fixes #4758
(cherry picked from commit 910151a361)
2016-06-25 01:22:41 +02:00
Juan Linietsky b075525e84 resolve numerical error when comparing instancing an inheritance to avoid saving changed properties when they didn't, closes 4759
(cherry picked from commit f0abda999e)
2016-06-25 01:22:41 +02:00
Juan Linietsky 6525e0017c Fixed ancient bug that prevented proper theme editing, closes #4924
(cherry picked from commit c1056a9bfb)
2016-06-25 01:22:41 +02:00
Ovnuniarchos c54744ce4d Documented many Physics2D* classes
(cherry picked from commit 471ab4e6ff)
2016-06-25 01:22:41 +02:00
Juan Linietsky acc552c447 Made error when signal calls a method with the wrong number of parameters more detailed, closes #4893
(cherry picked from commit 4bb93c976c)
2016-06-25 01:22:41 +02:00
Juan Linietsky d411cbe1d9 rewrote LineEdit window repositioning code so it does not eat the last character, closes #4992
(cherry picked from commit 83bf8036de)
2016-06-25 01:22:41 +02:00
Juan Linietsky 2212cc827c fix how some display values are shown, fixes #4953
(cherry picked from commit 1555608276)
2016-06-25 01:22:41 +02:00
Juan Linietsky cb37d1bb91 apply built-in scripts when running the game, closes #4987
(cherry picked from commit 482b21a5a4)
2016-06-25 01:22:41 +02:00
Juan Linietsky 7987147502 gdscript tokenizer will dislike use of case, closes #4991
(cherry picked from commit ceeb5453a8)
2016-06-25 01:22:41 +02:00
Juan Linietsky c22ac11afb fix crash in SamplePlayer, closes #5005
(cherry picked from commit ef9720c8f0)
2016-06-25 01:22:41 +02:00
Juan Linietsky d945dbdd0f remove unnecesary found bug? print, closes #5028
(cherry picked from commit fea9511bc6)
2016-06-25 01:22:40 +02:00
Juan Linietsky b06cf23c1a make sure tab is not visible in RichTextLabel, closes #5079
(cherry picked from commit ef2f6a18d2)
2016-06-25 01:22:40 +02:00
Juan Linietsky 51330b29ae do not allow picking in captured mode, closes #5134
(cherry picked from commit b75fb6674b)
2016-06-25 01:22:40 +02:00
Juan Linietsky 8289760227 Show descriptive errors when look_at is improperly used, closes #5131
(cherry picked from commit 375fbe5c7c
and db1e9bac79)
2016-06-25 01:22:40 +02:00
Juan Linietsky dd7e7c94c1 property output unix seconds since epoch in windows get_system_time_secs, fixes #5155
(cherry picked from commit fc7adf0b4c)
2016-06-25 01:22:40 +02:00
Nuno Donato 25244e9843 * fix messages when modifying on switching the active axis
(cherry picked from commit a713188388)
2016-06-25 00:37:19 +02:00
Juan Linietsky 6a83c87dda fixes wrong bool return, closes #5037
(cherry picked from commit c5a2aff6db)
2016-06-25 00:31:10 +02:00
Juan Linietsky 64ac2272ce If a resource is delete from fs dialog, but the resource is currently loaded,
clear the path of the resource. Fixes #5110

(cherry picked from commit f4ff30dff0)
2016-06-25 00:30:06 +02:00
volzhs 2998b7c486 add line spacing option to script and shader editor (#5105)
(cherry picked from commit 990956c4e0)
2016-06-25 00:29:25 +02:00
Paulb23 13d3d217b1 Fixed editor help focus issues and input propagation
(cherry picked from commit eb14373d69)
2016-06-25 00:27:49 +02:00
CowThing a94f6108a9 Filling in documentation
Documentation for BoneAttachment, KinematicBody, ParallaxBackground,
ParallaxLayer, and TestCube

(cherry picked from commit 50de99f050)
2016-06-25 00:26:18 +02:00
Paulb23 93616e41f9 Caret blink no longer updates when hidden, issue 5100
(cherry picked from commit e260e3872c)
2016-06-25 00:26:10 +02:00
J08nY 1475f8d318 RtAudio: proper under/overflow warning
fix #5102

(cherry picked from commit 39260f9dca)
2016-06-25 00:25:50 +02:00
Rémi Verschelde 9bb6a0852b GLEW: Update to upstream version 1.13.0 (pristine)
This removes a custom redefinition of glewGetProcAddress,
which was apparently necessary for older Macs with buggy OpenGL
(see #5087).

The added source files are as provided in the upstream tarball.

(cherry picked from commit 5bed0af65e)
2016-06-25 00:24:18 +02:00
Rémi Verschelde 66ce012ca6 GLEW: Define static + enabled and includes via SCons
This allows us not to have to hack our definitions in the upstream files,
making it easier to upgrade to newer versions in the future.

For the include paths to work, the headers are moved to a GL subfolder to
match their upstream location.

(cherry picked from commit 768e925271)
2016-06-25 00:24:09 +02:00
Rémi Verschelde 64507f0085 Haiku: Do not define GLEW_ENABLED to undefine it later
Partial revert of f61eb5fd8e.

(cherry picked from commit 4c658dc523)
2016-06-25 00:24:02 +02:00
Pawel Kowal 08c9e566bf Improved Blender/Collada shadeless->unshaded import
(cherry picked from commit 101e0c9ec6)
2016-06-25 00:23:48 +02:00
Paulb23 afbc9d550f Improved breakpoint marker position, and scales with font size
(cherry picked from commit d66b034bd1)
2016-06-25 00:22:36 +02:00
J08nY d16375d005 Classref for: ImageTexture, Image, LargeTexture
(cherry picked from commit ec96e36bc9)
2016-06-25 00:22:06 +02:00
J08nY 74d0f8b65b Exposed Image.INTERPOLATE_*
(cherry picked from commit 8a4eca8aa8)
2016-06-25 00:21:56 +02:00
Rémi Verschelde 9791d2ef6d Fix indentation issues in last commits
Ping @reduz.

(cherry picked from commit 0729c852b4)
2016-06-25 00:19:27 +02:00
Juan Linietsky cb94271e9f properly pass events to parent controls, closes #4701
(cherry picked from commit aec5506414)
2016-06-25 00:16:35 +02:00
Juan Linietsky bb8b57cbae -Fix small bug regarding to canvas layer detection, closes #4381
(cherry picked from commit 2b9cab25c0)
2016-06-25 00:16:08 +02:00
TheoXD 5a45b295ae fixed interactive_loader() not returning a cached scene
(cherry picked from commit 47bd1e8688)
2016-06-25 00:15:28 +02:00
Roberto a39eaf4c66 Add missing license information (ogg/vorbis/opus)
(cherry picked from commit c0a8c4f6e4)
2016-06-25 00:12:01 +02:00
Roberto 9ac954e2a4 Add missing license information (Theora)
(cherry picked from commit 18fc2ccbe1)
2016-06-25 00:11:33 +02:00
Pedro J. Estébanez 73e455c22f Keep the default environment variables as set by SCons
(cherry picked from commit ad0af9d273)
2016-06-25 00:11:26 +02:00
Roberto 840ad26069 Add missing license information (WebP)
(cherry picked from commit f97f8971e3)
2016-06-25 00:11:05 +02:00
Roberto b18000349e Add missing license information (MiniZip)
(cherry picked from commit 04fc62c4e3)
2016-06-25 00:10:59 +02:00
Andreas Haas 7bff33ea92 fix ui_* input events in Editor
`input/` is the category for these in globals ^^
fixes #5050

(cherry picked from commit a9779efe82)
2016-06-25 00:09:26 +02:00
Bojidar Marinov aad9cd3e22 Document Viewport and ViewportSprite classes
(cherry picked from commit 662e0cc411)
2016-06-25 00:06:48 +02:00
Juan Linietsky d5bed26e42 Make Input Actions config not affect the editor
(cherry picked from commit 64fd75d91a)
2016-06-25 00:05:40 +02:00
volzhs 356c35954a change invalid characters when get user data dir on Windows & Unix
Can't create user data folder when project name has ``\ / : * ? " < > |`` characters on OS_Windows & OS_Unix.
So, change it to ``-`` to be able to make folder.

fixes #4928 and it's altanative to #4986.

(cherry picked from commit 9073dc9963)
2016-06-25 00:05:00 +02:00
Rémi Verschelde ff91f409bf Merge pull request #5224 from zaps166/2.0-fix-theora-no-audio
Fix Theora video playback without a Vorbis stream
2016-06-17 19:58:39 +02:00
Błażej Szczygieł 763b29f34e Fix Theora video playback without a Vorbis stream
- prevent audio resampler errors when number of channels is 0,
- don't check for 'audio_done' when there is no audio data.
2016-06-17 13:38:47 +02:00
Rémi Verschelde d412cb65be Doc: Make rst files as UTF-8 2016-06-05 00:19:45 +02:00
Rémi Verschelde da8fb5de7a classref: Sync with source 2016-06-05 00:11:15 +02:00
J08nY 845a0e2566 Added InputMap.get_actions()
get_actions() lists all actions in the InputMap.

(cherry picked from commit 1a80b2a04a)
2016-06-05 00:03:48 +02:00
marcelofg55 bed17e98c8 Right click->Quit on the godot icon will now close the application on OSX.
Fixed get_window_position that missed a return on OSX.

(cherry picked from commit 76ab7d3886)
2016-06-05 00:03:30 +02:00
Warlaan c6ef223498 The create dialog starts collapsed now.
The original behavior can be reactivated in the editor settings.

(cherry picked from commit 987192775a)
2016-06-05 00:01:29 +02:00
J08nY 8a7c4c017f Fix typo in http_client.h
(cherry picked from commit b4fb4a131d)
2016-06-05 00:00:28 +02:00
volzhs f22e13d24e deselect in help when click somewhere
(cherry picked from commit bf22e69822)
2016-06-05 00:00:17 +02:00
George Marques 47f8da5409 Fix Color8 constructor using wrong value range
Fix #5015

(cherry picked from commit 43dad78209)
2016-06-05 00:00:08 +02:00
J08nY 8ea940e99b Added classref for HTTPClient and HTTPRequest
(cherry picked from commit 4c5439f8cd)
2016-06-04 23:59:45 +02:00
Rémi Verschelde f97cbdec8f Update to libpng 1.5.27
No security relevant fix as far as I can see, but the version bump
does not hurt either.

(cherry picked from commit bc25492e63)
2016-06-04 22:20:46 +02:00
Warlaan fc15a842af Added classes' short descriptions as tooltips in the create dialog.
(cherry picked from commit fe3a68c4c2)
2016-06-04 22:20:33 +02:00
George Marques 6d45fc0717 Remove Make-related flags from Android build
They were wrongly placed, creating a file named "-fpic" instead of
applying "-fpic" to the build. This file was in .gitignore, which made it
less noticiable.

This also adds build.gradle to .gitignore.

(cherry picked from commit 408c26ce0b)
2016-06-04 22:20:02 +02:00
P-GLEZ 298be3356f StaticBody documentation
Documented StaticBody. Also corrected an error in StaticBody2D
documentation

(cherry picked from commit 35cb75220d)
2016-06-04 22:20:02 +02:00
P-GLEZ 436e968b43 classref: Area documentation
One method was missing.

(cherry picked from commit 0325944ee4)
2016-06-04 22:20:02 +02:00
Andreas Haas 2b06d7e6f7 Make Color.{rgba}8 return int instead float
According to the class doc, these should be int.
Also fixed a little bug: the setter for 'r8' changed the green value

(cherry picked from commit da3247a500)
2016-06-04 22:20:02 +02:00
P-GLEZ 79e9917367 Area Documentation
Ported the Area2D documentation into its 3D counterpart. Also fixed some
typos

(cherry picked from commit 617530832b)
2016-06-04 22:20:02 +02:00
jmintb 3efe43fb8b Switched the space shooter demo from none fixed process to fixed process
(cherry picked from commit a9d246ea6c)
2016-06-04 22:20:02 +02:00
marcelofg55 331a0aed71 Key modifiers (Ctrl, Alt, Meta and Shift) may be used as Input keys now on OSX
(cherry picked from commit bb223869e0)
2016-06-04 22:20:02 +02:00
J08nY 39773b6b9a Added classref for RigidBody, and finished classref for Resource
(cherry picked from commit 063d507a15)
2016-06-04 22:20:02 +02:00
CowThing 566d751e39 Filling in documentation
VisibilityNotifier and VisibilityEnabler (2D and 3D).

(cherry picked from commit 3ba4e6b2ac)
2016-06-04 22:20:02 +02:00
Paulb23 7928b5fef6 Current line draws behind line numbers and breakpont gutter
(cherry picked from commit 6ae126ef9b)
2016-06-04 22:20:02 +02:00
Rémi Verschelde 8b8a1a0cbb Icon: Remove more grey capsules behind official logo
(cherry picked from commit e6e878e139)
2016-06-04 22:20:02 +02:00
Julian Murgia - StraToN 5c52f4437a Documented Light2D and LightOccluder2D
(cherry picked from commit 9ac4b29322)
2016-06-04 22:20:02 +02:00
Julian Murgia - StraToN e8b1744325 Documented BackBufferCopy. Need validation for the different copy modes (constants)
(cherry picked from commit defe7f18c2)
2016-06-04 22:20:02 +02:00
Aleksandar Danilovic 24e5755e72 Fix MS Visual Studio build settings
NMake was not setup by the vsproj=yes compilation
parameter. After attempting other possible options,
this is the best fix for our current requirements.
Compiling via NMake is implementing an alternative
to SCons, so this fix escapes out of NMake
environment while also supporting different target
builds and IDE error list integration.

Also sets -j setting to 2 so that it's easy for
people to change it to a propper value and speed it
up a bit for those that do not.

Adds two missing .gitignore Visual Studio temp files
present in Visual Studio's .gitignore.

(cherry picked from commit ca876191e5)
2016-06-04 22:20:02 +02:00
Rémi Verschelde 1787ec12be Editor: Fix base dir when going back to project manager
This caused the PM to load with the parameters of the previously loaded project.
Was a regression from ea751724a2. Closes #4045.

(cherry picked from commit 6fefcfd46a)
2016-06-04 22:20:02 +02:00
MarianoGNU c67b1888b5 Remove focus from Sprite Region Editor dialog. Fixes #4751
(cherry picked from commit e7b7dfefd3)
2016-06-04 22:20:02 +02:00
Paulb23 7029c96221 Added, goto next and previous breakpoint and remove all, issue 1690
(cherry picked from commit daf0ed646f)
2016-06-04 22:20:02 +02:00
Geequlim 178168aa8a Add spaces to macros in memory.h to make C++11 compilers happy
(cherry picked from commit 728ce570a5)
2016-06-04 22:20:02 +02:00
Paulb23 71487793df Fix crash when redoing backspace to clear selection
(cherry picked from commit 4a5997ec1c)
2016-06-04 22:20:02 +02:00
Paulb23 99c948ba56 Added breakpoint markers, issue 4750
(cherry picked from commit 72fda444d1)
2016-06-04 22:20:02 +02:00
Ignacio Etcheverry 211a6d01bc Debugger: show error message if description is not available
(cherry picked from commit ea9cde8842)
2016-06-04 22:20:02 +02:00
marcelofg55 280899ee43 Added application/fat_bits property for EditorExportPlatformOSX::EditorExportPlatformOSX
(cherry picked from commit ba0fbe4f79)
2016-06-04 22:20:02 +02:00
Paulb23 652f82dae8 Fixed caret color not changing though properties
(cherry picked from commit 6dd538a7ae)
2016-06-04 22:20:02 +02:00
Carter Anderson 6844b580f6 Remove noisy print
(cherry picked from commit 7df5249779)
2016-06-04 22:20:02 +02:00
Daniel J. Ramirez ef4ac86656 Modified damp ranges
(cherry picked from commit ba0baa3ca7)
2016-06-04 22:20:02 +02:00
Daniel J. Ramirez f346733d80 Clamped some light2D ranges
(cherry picked from commit c9350d7897)
2016-06-04 22:20:02 +02:00
volzhs bbf08a48df fix unexpected char: '\' error on windows
error occurred when register additional directory for android module on windows.

### config.py ###
```
def can_build(plat):
 return plat=="android"

def configure(env):
 if (env['platform'] == 'android'):
  env.android_add_res_dir("android/res")
```

(cherry picked from commit 5eb14d3af0)
2016-06-04 22:20:02 +02:00
volzhs 4478f8cfbb use node name as filename when save scene
fix #4723

(cherry picked from commit 9e1ee568a6)
2016-06-04 22:20:02 +02:00
Hugo Locurcio 5ad050be2b Change the default comment color to #676767 (#4763)
A neutral gray color, more readable than the old brown one.
(cherry picked from commit e75701e0b5)
2016-06-04 22:20:02 +02:00
anatoly techtonik a5007d0e7a README.md docs are not wiki (#4770)
(cherry picked from commit e56f05c690)
2016-06-04 22:20:02 +02:00
est31 88e512547b README: use https links to main website
Thanks @akien-mga for having given me the idea:
926df79a7c

(cherry picked from commit da54a4d693)
2016-06-04 22:20:02 +02:00
est31 85018e185a README: Improve Documentation section
The move was over three months ago, it is irritating
to still read "has been moved to".

(cherry picked from commit d3515a1ccb)
2016-06-04 22:20:02 +02:00
Calinou 9b03b9e989 Change low processor usage mode to cap to 60 FPS rather than 40 FPS
This results in smoother operation in the editor, without needing to
resort to the "Update Always" method which uses more resources than
needed.

(cherry picked from commit cc5a020afe)
2016-06-04 22:20:02 +02:00
Ariel Manzur 803438d448 SCons: using 1 env for all drivers
(cherry picked from commit 6cf2353305)
(cherry picked from commit 12bd9ee6f2)
(cherry picked from commit 4c4d79e3c9)
(cherry picked from commit dbb4c0c9b7)
2016-06-04 22:20:02 +02:00
marcelofg55 4dc2d78d2e Added 'fat' option for bits param on scons for osx, this will produce a fat binary that contains both 32 bits and 64 bits binaries
(cherry picked from commit eeb83982e2)
2016-06-04 22:20:02 +02:00
Geequlim c2f48421d1 Document the FileDialog and partial OS methods
(cherry picked from commit a92652d578)
2016-06-04 22:20:02 +02:00
captainwasabi 08fa7a0ff1 Fix for tooltip blinking (#4713)
Moved where active tooltips are canceled to wait until the mouse actually moves off the control.
(cherry picked from commit 4b80895082)
2016-06-04 22:20:02 +02:00
Bojidar Marinov bea5135518 Fix a XML error with the documentation
(cherry picked from commit d208572906)
2016-06-04 22:20:02 +02:00
Paulb23 e95eb4b1dc Multiline duplication, issue #4661
(cherry picked from commit 2eb4e7c103)
2016-06-04 22:20:02 +02:00
Rémi Verschelde 01bdfa4d22 Android buildsystem: Drop obsolete NDK_TOOLCHAIN argument
It was a duplicate of NDK_TARGET, and not used for anything.
(cherry picked from commit 5e0f0a962a)
2016-06-04 22:20:02 +02:00
Wilhem Barbier 16d38b199a Check the save path before importing a 3D Mesh
(cherry picked from commit f38473f65b)
2016-06-04 22:20:02 +02:00
Rémi Verschelde 1d85dcb1fa GDScript: Fix method info for is_nan and is_inf
As reported on https://godotengine.org/qa/4114/why-isnan-and-isinf-arent-implemented
(cherry picked from commit b58e261d41)
2016-06-04 22:20:02 +02:00
CowThing c6e2c0f01d Filling in documentation.
AABB, Color, Rect2, Transform, Vector2, and Vector3.

(cherry picked from commit 0749db2cf8)
2016-06-04 22:20:02 +02:00
Paulb23 481c076feb Fixed hex notation highlighting
(cherry picked from commit b2bf266ddc)
2016-06-04 22:20:02 +02:00
Paulb23 86c0438f9d Member variable syntax highlighting
(cherry picked from commit fc9f9adcb2)
2016-06-04 22:20:02 +02:00
Bojidar Marinov d7e4fb4365 Save member information in docdata
Closes #4609

(cherry picked from commit 4cbf74da71)
2016-06-04 22:20:02 +02:00
volzhs a3979cc928 Add SpinBox to Lossy Quality on Image Groups
fixes #3653

(cherry picked from commit 82600944bd)
2016-06-04 22:20:02 +02:00
Daniel J. Ramirez 1864745e2a Documented @GlobalScope singletons and some keys
(cherry picked from commit cb0be4adaa)
2016-06-04 22:20:02 +02:00
Rémi Verschelde 0a64059937 Merge pull request #5021 from zaps166/2.0-last_sample_playing-fix
SampleLibraryEditor: Initialize "is_playing" variable
2016-06-03 20:02:46 +02:00
Błażej Szczygieł 9acb666320 SampleLibraryEditor: Initialize "is_playing" variable
Fixes crash caused by jumping to wrong place due to uninitialized
variable.

Closes #4703
2016-06-03 19:54:25 +02:00
Rémi Verschelde 3a1e69f45c Travis: Install android *DKs in verbose mode
Builds tend to fail due to the 10 min limit for stalled builds.
Most likely because the download is done silently and takes more than
10 min depending on the Travis connection.
(cherry picked from commit 83913e86fe)
(cherry picked from commit dfb9ba877e)
(cherry picked from commit 1bdda9a922)
2016-05-18 08:22:21 +02:00
Daniel J. Ramirez 6a85acdffb Fix some errors in some rotation functions, also clarify that certain parameters are expressed in radians
(cherry picked from commit 70ec87ecd2)
2016-05-18 08:21:44 +02:00
volzhs 094a9c3bcc open directory or file when double click
fixes #4607

(cherry picked from commit 81b4d38fa7)
2016-05-18 08:21:38 +02:00
Rémi Verschelde 5d2a23d99c Revert "Revert "-make sure single select after multi select works better""
This reverts commit 9ed2084b42.
Will then add the proper fix.
2016-05-18 08:21:16 +02:00
Rémi Verschelde 9ed2084b42 Revert "-make sure single select after multi select works better"
This reverts commit f909634832.
It caused various regressions (#4556 and #4607).
2016-05-13 08:06:31 +02:00
Rémi Verschelde c0df7da2ca Version 2.0.3 2016-05-12 19:54:11 +02:00
Rémi Verschelde 49bf494eac classref: Readd String.strip_edges description 2016-05-12 19:47:26 +02:00
eska b8d8ec09ee Remove nocpuid.c from builtin OpenSSL
Since opensslconf.h no longer defines OPENSSL_CPUID_OBJ, OpenSSL defines
OPENSSL_cpuid_setup itself (with the same empty definition)

(cherry picked from commit 2392824dba)
2016-05-12 19:35:49 +02:00
MattUV f120514402 classref: Fixed return types in Area and Area2D (#4635)
(cherry picked from commit 91c85ff1f5)
2016-05-12 19:35:41 +02:00
Rémi Verschelde 77573a76d1 classref: Sync with current source 2016-05-12 09:16:37 +02:00
Rémi Verschelde c734a508c3 classref: Directory and ConfigFile
(cherry picked from commit 22d1385caf)
2016-05-12 09:07:43 +02:00
Rémi Verschelde d66b04921f Windows: Fix GCC/Clang argument being passed to MSVC
Fixes #4620

(cherry picked from commits 972b0f78b3
and c7292b1f3d)
2016-05-12 09:06:48 +02:00
Paulb23 f61f515872 Updated caret blink method documentation
(cherry picked from commit 997476777a)
2016-05-12 09:06:10 +02:00
Paulb23 c5e17d553e Bind caret blink to gdscript and properties
(cherry picked from commit dc90cba42e)
2016-05-12 09:05:46 +02:00
marcelofg55 2bd6e2402b OS.get_screen_size now returns the correct value on OSX
(cherry picked from commit b697de92ef)
2016-05-12 09:05:32 +02:00
Mattias Cibien c575f31d5d Added possibility to strip left and right to strip_edges (#4594)
(cherry picked from commit 49c473bb36)
2016-05-12 09:04:59 +02:00
Andreas Haas 6d50ccfd32 Joystick demo script cleanup
Removes a leftover variable and uses constants instead of magic numbers.

(cherry picked from commit 86b46c0b7e)
2016-05-12 09:04:41 +02:00
Paulb23 bd51dea8f6 Added caret blink in text editor
(cherry picked from commit e03e7deb1b)
2016-05-12 09:04:03 +02:00
Paulb23 abc97d3bb4 Fixed autocomplete truncate, issue 4554
(cherry picked from commit accc2a195b)
2016-05-12 09:03:59 +02:00
George Marques a5e54b83ec Add ignore error flag to OpenSSL driver
(cherry picked from commit 2e44e255ed)
2016-05-12 09:00:39 +02:00
Paulb23 18782aec61 Fixed autocomlete strings not appearing for function arguments
(cherry picked from commit 9e6234201b)
2016-05-12 09:00:22 +02:00
Alexander Holland f58cfaf585 fix percent decode utf8 error
(cherry picked from commit f86cffd8e6)
2016-05-12 08:59:30 +02:00
Paulb23 5d98718c28 Fixed animation player auto-queue duplication and undo/redo
(cherry picked from commit 488495852b)
2016-05-12 08:58:39 +02:00
Paulb23 7ab1c1ea3b Fixed code completion after opening bracket, issue 3977
(cherry picked from commit 0a2b341d0a)
2016-05-12 08:55:43 +02:00
Ariel Manzur f8debd8152 cloning env for builtin_openssl _and_ openssl :)
(cherry picked from commit baaa74f215)
2016-05-12 08:55:34 +02:00
Ariel Manzur ac06e3d4db clonning env for builtin ssl
(cherry picked from commit 62c17d65a8)
2016-05-12 08:55:28 +02:00
Rémi Verschelde b6be2f503d Rotation APIs: Better exposure for degrees methods
Made public the various set/getters for rotations in degrees.
For consistency, renamed the exposed method names to remove the leading
underscore, and kept the old names with a deprecation warning.

Fixes #4511.

(cherry picked from commit 4eab767a6f)
2016-05-12 08:55:14 +02:00
Daniel J. Ramirez b224407770 Partial documentation for OS methods
(cherry picked from commit ed7c0a6caf)
2016-05-06 11:14:59 +02:00
George Marques 7556391d20 Fix build for Windows 64-bits with GCC
(cherry picked from commit 81297f0fa1)
2016-05-06 11:14:53 +02:00
Juan Linietsky 23c659fc47 -make sure single select after multi select works better
-fixed some warnings for OSX

(cherry picked from commit f909634832)
2016-05-06 11:14:11 +02:00
George Marques 4832731477 Fix memory leak
As pointed out by @sanikoyes in #4541.

(cherry picked from commit 5930408746)
2016-05-06 11:13:41 +02:00
Ignacio Etcheverry 19f08eaa5b Fix wrong return and argument types in documentation
(cherry picked from commit 1e752c0120)
2016-05-06 11:13:35 +02:00
Ignacio Etcheverry 975b4d2927 Add missing Vector2Array case to Variant::operator String()
- Correcly display Vector2Array default arguments in the documentation

(cherry picked from commit 2060e6616c)
2016-05-06 11:13:25 +02:00
Hinsbart 913818a246 Fix ds3 gamepad mapping
(cherry picked from commit d6cd5108e3)
2016-05-06 11:12:44 +02:00
Daniel J. Ramirez 4a4999451b Changed barely visible PROPERTY_HINT_ALL_FLAGS buttons for checkboxes
(cherry picked from commit 723c0d730c)
2016-05-06 11:12:38 +02:00
George Marques 4f57e532b8 Fix windows 64-bits build.
The change in `tools/doc/doc_data.cpp` is needed because the MSVC
compiler does not support variable length arrays.

Fix #4113

(cherry picked from commit 9424c6c58f)
2016-05-06 11:12:31 +02:00
Aleksandar Danilovic 3449c81bdb Fixes 64 bit MSVC builds, disables bits parameter
Also Enables automatic detection of architecture for the MSVC compilers.
Builds without assembly optimisations for x64
Closes issue #3098

Signed-off-by: Aleksandar Danilovic <greatgames.alexandar@gmail.com>
(cherry picked from commit 7762e1afe6)
2016-05-06 11:12:23 +02:00
mrezai 05857a5472 Update OpenSSL to 1.0.2h
(cherry picked from commit ab623c923d)
2016-05-06 11:11:21 +02:00
Paulb23 ec3b50fd65 Autocomplete no longer shows duplicates, issue 1824
(cherry picked from commit 084d0bef96)
2016-05-06 11:11:14 +02:00
CowThing f95918e05a Input Documentation
Input Documentation

(cherry picked from commit f6ae5e41de)
2016-05-06 11:11:09 +02:00
Mattias Cibien b3404c8c44 Fixed behavior of OS.set_window_resizable
Should fix #4428.
 * Minimize button is not hidden anymore
(cherry picked from commit 8fb7280f39)
2016-05-06 11:10:57 +02:00
Daniel J. Ramirez 7e077258c5 Fixed documentation generator for polymorphic functions
(cherry picked from commit 57d0b78426)
2016-05-06 11:10:48 +02:00
Daniel J. Ramirez fb3d10c579 Documented bool methods
(cherry picked from commit 3ca1d0f1d5)
2016-05-06 11:10:41 +02:00
Daniel J. Ramirez 0b75c39c2b Documented float
(cherry picked from commit 520e6f5b09)
2016-05-06 11:10:34 +02:00
Daniel J. Ramirez e0a13981fc Documented int methods
(cherry picked from commit 4453284388)
2016-05-06 11:10:28 +02:00
CowThing bdbb831261 Finished AnimationPlayer Documentation
(cherry picked from commit abf5f8c586)
2016-05-06 11:09:51 +02:00
Ignacio Etcheverry 97e30f4cd7 Fix checking unsaved changes only in current scene
(cherry picked from commit 107e62be70)
2016-05-06 11:07:46 +02:00
CowThing 78dc8e79c4 Documented YSort (#4515)
Documented YSort
(cherry picked from commit 957c265f11)
2016-05-06 11:07:25 +02:00
Rémi Verschelde 40681d90e5 Debugger: Fix breaked signal binding (#4508)
Closes #4270.
(cherry picked from commit 8ceab5ddaf)
2016-05-06 11:07:17 +02:00
Daniel J. Ramirez fbb8a2170c Documented ColorRamp
(cherry picked from commit c2bdb3727b)
2016-05-06 11:07:03 +02:00
Daniel J. Ramirez e8a972197c Partial documentation for Particles2D
(cherry picked from commit 3cd58fe0ba)
2016-05-06 11:06:56 +02:00
Bojidar Marinov 047767b824 Document Popup, PopupDialog, PopupMenu, and PopupPanel
(cherry picked from commit 5cdf4a6379)
2016-05-06 11:06:49 +02:00
Rémi Verschelde ef2f1ae811 Tabs: Fix align issue with right/close buttons
The stylebox around the close button was badly centered.
There were also bad margins applied when using right buttons.

(cherry picked from commit 21c181bd3c)
2016-05-06 11:06:42 +02:00
Rémi Verschelde 7c419032c7 Tabs: cleanup code, no functional change
Some dead code removed, a few cosmetic changes.

(cherry picked from commit 8b32c80529)
2016-05-06 11:06:35 +02:00
Rémi Verschelde 9bdcc97e56 Tabs: Fix navigation buttons overlap when resizing
It was not taking into account the minimum width of the stylebox.
Fixed by factorizing some duplicate code.

(cherry picked from commit 8574489dd2)
2016-05-06 11:06:29 +02:00
Rémi Verschelde 7f80fce464 Tabs: Fix icon size not taken into account for offset
Fixes #4107.

(cherry picked from commit bbaf296948)
2016-05-06 11:06:22 +02:00
Rémi Verschelde ea9b552e27 Variant: readd Dict.has_all
Erroneously removed in 4bc494ae2e.
2016-05-06 10:56:39 +02:00
Juan Linietsky 21ab3a030e missing default value 2016-05-05 18:44:29 -03:00
Juan Linietsky a14ff27337 fix to avoid video texture scaling 2016-05-05 18:44:20 -03:00
Juan Linietsky d6e30256ad ability to shrink all images x2 on load
this is for extreme cases when running on devices with very low video
memory, so you can still retain compatibility.
2016-05-05 18:43:47 -03:00
Ariel Manzur 4bc494ae2e export fix_alpha_edges 2016-05-05 18:42:55 -03:00
Rémi Verschelde d49fff6246 FileDialog: reset mkdir label after use (#4500)
Closes #1686.
(cherry picked from commit ab7886ffc4)
2016-05-01 12:28:27 +02:00
Rémi Verschelde d29087cc53 OSX: Fix lib suffix for Android lib (#4499)
Fixes #1452.
(cherry picked from commit 94274b9ab5)
2016-05-01 12:28:20 +02:00
Rémi Verschelde 27461a79dc GridMap: Fix backwards rotate hotkeys (#4498)
Fixes #1237
(cherry picked from commit 8259c46707)
2016-05-01 12:28:14 +02:00
Rémi Verschelde a86cfc258e AnimationPlayer: Prevent resetting timeline when pinned (#4497)
Fixes #1019
(cherry picked from commit 0b4f277184)
2016-05-01 12:28:07 +02:00
Rémi Verschelde 26c2e0d09d math: Fix rounding error for 0 in Math::round (#4495)
Thus revert the previous workaround in commit b123bc4a2a.
Fixes #3221.
(cherry picked from commit 6883325f92)
2016-05-01 12:28:01 +02:00
Rémi Verschelde 0b49d78a3f Project manager: unescape project names (#4494)
Fixes #3609
(cherry picked from commit 78adbf4790)
2016-05-01 12:27:54 +02:00
volzhs 40b546fb83 Allow any directory for custom character set and gradient image file when import font
fix #4486

(cherry picked from commit b172cb524d)
2016-05-01 12:27:43 +02:00
Rémi Verschelde 3c453b7bd2 Ignore invalid folders in `platform`
Fixes #4479

(cherry picked from commit f938793e78)
2016-05-01 12:27:14 +02:00
George Marques f033763700 Implement OS.get_process_ID for Windows
Based on code by @ratsdiov.
Closes #1733

(cherry picked from commit 2cd8e86aa0)
2016-05-01 12:27:04 +02:00
Rémi Verschelde 944ac2500a classref: Sync with source 2016-04-29 18:12:33 +02:00
Geequlim b4adb0d338 Add more documentations for this classes:
* BoxContainer
* CenterContainer
* ScrollContainer
* SplitContainer
* Vector2
* StringArray
* FileDiloags

(cherry picked from commit a518792d89)
2016-04-29 18:06:09 +02:00
Ariel Manzur 227604a566 Fix launching from .app on OSX
(cherry picked from commit 6962fd91c6)
2016-04-29 18:05:39 +02:00
Bojidar Marinov 70644301dd Allow dragging on only one (global) axis when holding down shift
Closes #1723

(cherry picked from commit d82ff4ed09)
2016-04-29 18:02:27 +02:00
Paulb23 4228505cf0 Shader editor now uses text editor settings
(cherry picked from commit 64751e0a75)
2016-04-29 18:02:19 +02:00
Rémi Verschelde 9086a929b2 Specify the demos license
It was already under the MIT as the rest of the engine,
but some users seemed not convinced about it.
(cherry picked from commit fa3240a8e9)
2016-04-29 18:02:10 +02:00
Geequlim 5365ae9212 Add more documentations and fix AcceptDialog::add_cancel
(cherry picked from commit 5c61e17c10)
2016-04-29 18:02:03 +02:00
Geequlim a3fd381a4f Fill in the blank in the Array, CenterContainer and Dictionary class reference (#4476)
(cherry picked from commit 4de3f8944e)
2016-04-29 07:44:23 +02:00
Daniel J. Ramirez d81ffaf2ab Documentation for Canvas Modulate, ColorPicker, ColorPickerButton
(cherry picked from commit faf21b81e8)
2016-04-29 07:43:43 +02:00
Paulb23 c77a5f910e Fixed shader editor syntax coloring
(cherry picked from commit bda5ea0871)
2016-04-29 07:43:30 +02:00
eska 91461b588d Move export GUI debug toggle to export settings window
(cherry picked from commit ab4caa7953)
2016-04-29 07:43:23 +02:00
Hinsbart 3a3f56689e More precise InputMap Axis descriptions in project settings.
Now it's "Left Stick {Up, Down, Left, Right}" instead of just "Left Stick" repeated 4x.

(cherry picked from commit 418049b741)
2016-04-29 07:43:16 +02:00
Daniel Ramirez 35e05b092c Partial documentation for Polygon2D and Raycast2D (#4467)
(cherry picked from commit 9f29b4b26a)
2016-04-29 07:43:09 +02:00
Rémi Verschelde 238bbb6539 Classref: Document Button and ButtonArray
Also bind relevant constants and define some object types and better
argument names for the docs.

(cherry picked from commit 3a4ec88b37)
2016-04-29 07:42:59 +02:00
Daniel J. Ramirez 946ef8d478 GridContainer, CheckBox documentation, descriptions for Vector2 and CenterContainer.set_use_top_left
(cherry picked from commit a5b4c1d64f)
2016-04-29 07:42:48 +02:00
Alexander Holland d3ee8de754 fix - HTTPClient connection keep-alive duplicate Headers #4208
(cherry picked from commit 6ad226ac38)
2016-04-29 07:42:40 +02:00
Paulb23 517518ae9a Added scroll lines, issue 4243
(cherry picked from commit 54244e0e1d)
2016-04-29 07:42:08 +02:00
Rémi Verschelde 084ce221d7 NACL removal: fix leftover 2016-04-27 23:17:18 +02:00
Jan Heemstra e38666b76a fixed some mistakes in WeakRef documentation
(cherry picked from commit e301ca3544)
2016-04-27 20:19:52 +02:00
Jan Heemstra 6f76eca883 Documented WeakRef and member functions
(cherry picked from commit edff81c214)
2016-04-27 20:19:46 +02:00
Julian Murgia - StraToN d183a5361f Documented Node2D
(cherry picked from commit 87aa128228)
2016-04-27 20:19:37 +02:00
Rémi Verschelde 11aa0d1405 Various improvements to doc_status.py
- Make comments opt-in (smaller table in width)
- Reduce length of Brief Description and Description (also smaller table as output)
- Make names cyan (blue is too dark on black terminal)
- Drop some redundant synonyms for the flags

(cherry picked from commit 034d6e811f)
2016-04-27 20:19:30 +02:00
Julian Murgia 6efe8818a7 Edited classes.xml : GraphEdit finished (#4450)
(cherry picked from commit 81e405545b)
2016-04-27 20:19:20 +02:00
Rémi Verschelde 9023a84a93 Remove last NACL references
(cherry picked from commit d3811b490d)
2016-04-27 20:19:12 +02:00
Rémi Verschelde 1bd2145e34 Drop NACL platform
It's no longer maintained and Chrome-specific, so it's not a viable solution
to deploy Godot games in browsers. The current prefered alternative is asm.js
(platform/javascript), and we're looking forward to WebAssembly.

(cherry picked from commit ec606f94dc)
2016-04-27 20:18:59 +02:00
Rémi Verschelde 382a8250ba Drop obsolete WIP for Flash platform
It was apparently never fully functional and has not been maintained.
Flash itself is nowadays clearly a deprecated technology, so there will
not be further work on it. platform/javascript and the upcoming
WebAssembly technologies should have a brighter future.

(cherry picked from commit f368d380e7)
2016-04-27 20:17:37 +02:00
Paulb23 73296a9a6d Trim trailing white space on save, issue 4383
(cherry picked from commit f3e6569e00)
2016-04-27 20:17:25 +02:00
Hinsbart 93b1f60ca2 Encode axis_value in Variant for InputEvent::JOYSTICK_MOTION.
Fixes a bug that caused InputMap actions which have been set to joystick axes
not to work correctly on exported builds as the axis_value property wouldn't be serialized into engine.cfb.
See recent discussion in #49 (Post 121+)

(cherry picked from commit 9201b5a27c)
2016-04-27 20:17:13 +02:00
Bojidar Marinov 7f4387d21e Fix continious update with Camera2D
Closes #4406

(cherry picked from commit b2e0cedbf0)
2016-04-27 20:17:07 +02:00
Bojidar Marinov c0748bad06 Add a python script to check the current doc status
(cherry picked from commit c9340cdcc6)
2016-04-27 20:17:00 +02:00
Hinsbart 94b321822d add sign comparison for joystick axis events in InputMap::_find_event
fixes #4400

(cherry picked from commit 3b12f9ea82)
2016-04-27 20:16:51 +02:00
Bojidar Marinov c523749662 Fix Camera2D ignoring zoom when checking limits
Closes #1912

(cherry picked from commit 7a8aea0be9)
2016-04-27 20:16:08 +02:00
eska 0f47311610 Add fallback to legacy KeyboardEvent in web export
Fallback to KeyboardEvent property `charCode` is absence of both `key`
and `char` for retrieval of unicode value.

(cherry picked from commit 45b90f16ca)
2016-04-27 20:16:01 +02:00
Bojidar Marinov 4c358b7043 Add preview of the Camera2D's screen boundaries
Closes #3365

(cherry picked from commit e7f66a88d6)
2016-04-27 20:15:46 +02:00
eska 98b30e3aff Reimplement key input events in Emscripten export
Scancodes work, but unicode values are now completely broken in some
browser/OS combinations.

(cherry picked from commit 0e9eefb7d4)
2016-04-27 19:42:31 +02:00
volzhs 9f5c6cf950 remove unused resources and add korean locale for android
- remove unused resources in platform/android/java/res/values/strings.xml
- add korean language resource for apk expansion download screen

(cherry picked from commit e94e710893)
2016-04-27 19:42:22 +02:00
Zher Huei Lee 07fc330241 Fixed zero-length arrays in nrex. Fixes #4346
(cherry picked from commit 48b2dfab9f)
2016-04-27 08:50:36 +02:00
Alex c712e54b63 tiny fix to loop restart (#4358)
Closes #4355
(cherry picked from commit e566b17f91)
2016-04-27 08:50:28 +02:00
Ignacio Etcheverry 6a2efc48c5 Fix 'Quit to Project Manager' not stopping the running application
(cherry picked from commit e48c07750f)
2016-04-27 08:50:09 +02:00
Bojidar Marinov ff1d370b9f Fix File.get_csv_line not including quoted newlines in the output
Close #1232

(cherry picked from commit 7a18bb8ace)
2016-04-27 08:50:03 +02:00
eska e654184888 Always set default clear color
(cherry picked from commit 0ee8b74101)
2016-04-27 08:49:56 +02:00
mrezai cabb80ecf4 Add openssl=builtin to build command in .travis.yml
(cherry picked from commit 1db2759f5e)
2016-04-27 08:49:45 +02:00
mrezai 3efa0f130d Update OpenSSL to version 1.0.2g
(cherry picked from commit e97922f220)
2016-04-27 08:49:39 +02:00
Saracen 47c7b535d2 BoneAttachments now position themselves instantly during bind.
(cherry picked from commit bc5ee6c98f)
2016-04-27 08:49:30 +02:00
Hearto Lazor 5fac497aa2 Fixed curve baking, now always start at origin point
(cherry picked from commit 08b93da28a)
2016-04-27 08:49:23 +02:00
volzhs 4bfcd14a6a correct typo "overwrite"
(cherry picked from commit 86c6326057)
2016-04-27 08:48:43 +02:00
Ignacio Etcheverry dbcf969fbf Keep editable instances data when replacing tree root node
(cherry picked from commit 3029f5ee02)
2016-04-27 08:48:34 +02:00
Ignacio Etcheverry 52bf4a76b2 x11: Flush the X output buffer after changing mouse mode
(cherry picked from commit 5907a007dc)
2016-04-27 08:48:23 +02:00
Marc Gilleron f32a4dc516 Made trackpad behaviour optional in 3D mode (issue #4265)
(cherry picked from commit 84d706cb35)
2016-04-27 08:44:40 +02:00
Marc Gilleron a0b6645858 Fixed #4163 (intersect_shape crashes on results limit)
(cherry picked from commit d239e6bc0e)
2016-04-27 08:44:31 +02:00
mrezai b24c3be564 Update OpenSSL to version 1.0.1s
(cherry picked from commit c860574d8b
and commit 2cbd850979)
2016-04-27 08:43:39 +02:00
Saracen b2b5c495e1 Subclasses can now extend from other subclasses contained in scripts derived from relative paths.
(cherry picked from commit d643a40f95)
2016-04-27 08:42:48 +02:00
Paulb23 e367c6cdd8 Fixed undo redo interaction with find replace
(cherry picked from commit 189b306722)
2016-04-27 08:42:23 +02:00
Paulb23 b5a438413a Setting to change line number color
(cherry picked from commit 8c328474f2)
2016-04-27 08:42:18 +02:00
Zher Huei Lee f4ebba513a Updated nrex to v0.2
* Fixed capturing groups matching to invalid results
 * Fixed parents of recursive quantifiers not expanding properly
 * Fixed LookAhead sometimes adding to result

(cherry picked from commit 6207d56b95)
2016-04-27 08:42:12 +02:00
Ignacio Etcheverry 40d21117f9 Fix RayCast not updating when debugging collissions
(cherry picked from commit 6cf3bdcf76)
2016-04-27 08:42:01 +02:00
Ignacio Etcheverry e120e2265b CanvasItemEditorPlugin: Avoid selecting items from instanced scenes
- This behaviour is only applied to click selection. Rect selection and List selection can still select these items

(cherry picked from commit fab57f2fbc)
2016-04-27 08:41:51 +02:00
Rémi Verschelde 8746966194 Doc: fix type of stream object
(cherry picked from commit 7820e590ea)
2016-04-27 08:40:49 +02:00
sanikoyes 76eeb457d3 Fix warn print when hide an control does not inside_tree
(cherry picked from commit 5ec7d3f264)
2016-04-27 08:40:38 +02:00
sanikoyes 02afea1e4e Fix crash when tween control object previous freed
(cherry picked from commit da28a2f062)
2016-04-27 08:40:19 +02:00
Bojidar Marinov 692878b7f4 Fix Ctrl+LaunchMedia showing up as a shortcut for "Make Bones"
Close #4044

(cherry picked from commit 4af1839073)
2016-04-27 08:38:28 +02:00
Paulb23 b7f5418f8d Ability to change the caret color
(cherry picked from commit c7519f091d)
2016-04-27 08:37:20 +02:00
Alexander Holland d4d810faac dictionary has_all
(cherry picked from commit a8ebd43ab7)
2016-04-27 08:36:08 +02:00
punto- 3a390e9b44 Update vector.h
using non-templated neares_power_of_2
2016-04-11 03:34:10 -03:00
Rémi Verschelde 5d63f4e758 Sync classref with source 2016-04-07 21:30:22 +02:00
Rémi Verschelde cbac9a2ca3 Remove duplicate
(cherry picked from commit 473de561f8)
2016-04-07 21:28:28 +02:00
Rémi Verschelde 837d50714a Version 2.0.2 2016-04-07 08:34:27 +02:00
Paulb23 bb6cfc130b Option to toggle syntax highlighting
(cherry picked from commit d78e98e2a4)
2016-04-06 19:39:36 +02:00
Paulb23 b3891246e5 Fixed block indent inconsistency, fixes issue 3803
(cherry picked from commit 93700676b5)
2016-04-06 19:39:30 +02:00
Rémi Verschelde 00566a8592 Revert "free Material 'shadow_material_double_sided' on ::finish()"
This reverts commit 43c74056b1.
2016-04-06 19:37:16 +02:00
Bojidar Marinov 63e33cfdd2 Add a `sleeping_state_changed` signal to RigidBody and RigidBody2D classes
Closes #3911

(cherry picked from commit 6dcd1354c2)
2016-04-06 18:49:51 +02:00
Bojidar Marinov dea6671d58 Bind Z key (without modifiers) to toggle wireframe in 3D view
Fixed #4124

(cherry picked from commit 8ee8802cbe)
2016-04-06 18:49:26 +02:00
Paul Batty 7c6d2e7062 Fixed text edit undo and redo operation interaction
(cherry picked from commit 646e089782)
2016-04-06 18:48:31 +02:00
SaracenOne eb927383f2 Fixes errors occurring when switching to a new scene with a spatial editor from a canvas editor.
(cherry picked from commit f303e3483d)
2016-04-06 18:48:25 +02:00
sunnystormy 5c98674a8b Added rotation/panning support for trackpads in 3D mode #53
(cherry picked from commit 3ebde34d8f)
2016-04-06 18:48:05 +02:00
Paulb23 4bde902de1 Fixed 'complex' typo in method name
(cherry picked from commit 971c3be52d)
2016-04-06 18:47:34 +02:00
Paulb23 a5f07d18ec Fixed undoing twice when removing selection
(cherry picked from commit 15f43149e1)
2016-04-06 18:47:28 +02:00
Rémi Verschelde 71da9a1a23 Separate help pages from scripts by default
Fixes #4199
(cherry picked from commit 9c89d3e042)
2016-04-06 18:47:22 +02:00
Luiz Paulo de Vasconcellos 44daccc861 Change toggle comment behaviour. Fixes #4198
(cherry picked from commit 1b6f14d810)
2016-04-06 18:47:18 +02:00
MSC 4220ffbd8e memdelete 'joy_thread' + 'joy_mutex' on ::~joystick_linux()
(cherry picked from commit 391095e0ef)
2016-04-06 18:46:53 +02:00
MSC 43c74056b1 free Material 'shadow_material_double_sided' on ::finish()
(cherry picked from commit 7a9998370f)
2016-04-06 18:46:46 +02:00
Paulb23 48438e4f3b Fixed insert mode interaction with auto complete
(cherry picked from commit a984adb5a6)
2016-04-06 18:46:36 +02:00
Paulb23 5f901e2b27 Fixed insert mode removing first unselected character
(cherry picked from commit fe779d4386)
2016-04-06 18:46:32 +02:00
Paulb23 22ef9673dd Added insert mode to text editor
(cherry picked from commit 2b57cb94da)
2016-04-06 18:45:56 +02:00
Zher Huei Lee 5b1aa3a5cd Progress bar minsize now checks percent_visible
Allows for really thin progress bars such as for pixel-art styles.

(cherry picked from commit 0bba09c4cb)
2016-04-06 18:45:33 +02:00
Rémi Verschelde f06f574735 Fix building against 2.0 API
812de22 used a method from the new plugin API in master,
so it failed building.
2016-04-02 23:11:38 +02:00
blubee aac3b9db5c Add support for gnu-libstc++-4.9 needed by recent NDK versions
The 4.9 version is the default one, people can still build using 4.8
with older NDK versions by setting the (optional) NDK_TARGET
and NDK_TARGET_X86 environment variables.

(cherry picked from commit a0fb5b5f95)
2016-04-02 23:05:18 +02:00
Rémi Verschelde 9fdc1279cc Make hardcoded Mac version 2.0.x
To avoid having to bump it up every time.
2016-04-02 22:22:38 +02:00
Paul Batty 01471e4c09 Function syntax highlighting
(cherry picked from commit 50aa78210c)
2016-04-02 22:19:54 +02:00
Rémi Verschelde bac8248316 Remove trailing spaces
(cherry picked from commit 0a5472e697)
2016-04-02 22:19:40 +02:00
Rémi Verschelde 69e67d51c7 Port 2D demos to TSCN/TRES formats
Part of #4196.

(cherry picked from commit 23cf6a85bd)
2016-04-02 22:19:30 +02:00
Rémi Verschelde c6ccd05fed Fix last two bindings in input_mapping demo
Also connect the signal from script, as it makes it easier to understand
than by having to check the connected signals via the GUI.

(cherry picked from commit 4eb49cc732)
2016-04-02 22:15:58 +02:00
Paulb23 937a96b26b Option to toggle line numbers
(cherry picked from commit 474911c533)
2016-04-02 22:15:38 +02:00
Maxwell Huang-Hobbs a52b1e866d inherit PKG_CONFIG_PATH from environment
(cherry picked from commit 32391ffd73)
2016-04-02 22:15:32 +02:00
Josh Grams fed11a662a doc/base/classes.xml: String.match, Node.find_node
Clarify wildcard behavior.

(cherry picked from commit ef08fed277)
2016-04-02 22:15:20 +02:00
Paulb23 26f2b7415c Fixed numbers not highlighting after space
(cherry picked from commit cd07badee3)
2016-04-02 22:15:11 +02:00
Paulb23 729dc5da83 Stopped save scene flicker, issue 4118
(cherry picked from commit 9d74b76a69)
2016-04-02 22:15:06 +02:00
sanikoyes 54625bb771 Fix GDScript crash when call show/hide in func _exit_tree
(cherry picked from commit 0c6f089ce4)
2016-04-02 22:14:49 +02:00
Paulb23 523625a3d1 Syntax highlighting for numbers
(cherry picked from commit c844c2d604)
2016-04-02 22:14:27 +02:00
Rémi Verschelde 5caf6ad8b9 Expose android/shutdown_adb_on_exit parameter and default to true
It was added in 30d0ca9 for the Steam build but only enabled
when parsing a ._sc_ file that would define it.
It is now available for all users to toggle, in and outside of Steam.

Fixes #4073.

(cherry picked from commit c584940387)
2016-04-02 22:14:20 +02:00
Ignacio Etcheverry 7ddc17b18e BoxContainer: Bind method add_spacer(bool)
(cherry picked from commit 0571f961a8)
2016-04-02 22:13:58 +02:00
Ignacio Etcheverry cf0a586a3e TextEdit: Fix Shift+Delete shortcut not calling cut()
(cherry picked from commit abb720438f)
2016-04-02 22:13:26 +02:00
demolitions 41cc4ffe98 Fixes #3942 - Throws an error when exporting for X11 with no filename
(cherry picked from commit fb58bafc54)
2016-04-02 22:13:14 +02:00
Bojidar Marinov 0ea354c12a Fix issues with tilemap covering child nodes and old quadrants
Closes #4070

(cherry picked from commit 2a581835ca)
2016-04-02 22:12:53 +02:00
demolitions 2bc4049b9b Fix for #4014, changed to 2 instead of 3 chars to trigger search
(cherry picked from commit 4e59d1c51f)
2016-04-02 22:12:41 +02:00
Paulb23 64a8fe6ad7 Option to toggle tab drawing
(cherry picked from commit 0fc7be89d3)
2016-04-02 22:12:29 +02:00
sanikoyes 05c620b7ad Add -r flag to adb install for keep app user data
(cherry picked from commit 9e026fecef)
2016-04-02 22:12:12 +02:00
Saracen ca1ca6c7df Fix cursor getting locked on tree control if tree is cleared while modifying numerical element.
(cherry picked from commit 44fe74bfc3)
2016-04-02 22:12:02 +02:00
Paulb23 1369b38d85 Fixed highlighting when word occurs as substring first
(cherry picked from commit 9c0e1524e5)
2016-04-02 22:11:37 +02:00
Paulb23 68b7f9d87a Fixed highliting with shift and mouse
(cherry picked from commit 4cc3fbeaff)
2016-04-02 22:11:30 +02:00
Paulb23 8a78112e5b Highlight all occurrences of selected word
(cherry picked from commit b0488cacf2)
2016-04-02 22:10:41 +02:00
Franklin Sobrinho 41326781d2 Fix editors panels, of the bottom panel, not resizing in some cases
(cherry picked from commit 4a0f835ece)
2016-04-02 22:10:31 +02:00
Ignacio Etcheverry cacf7d136f LineEdit/TextEdit: Add Shift+Delete shortcut for cut
(cherry picked from commit fac027cb14)
2016-04-02 22:10:20 +02:00
Ignacio Etcheverry a701c6ff68 TextEdit: Fix inconsistent copy, cut and paste behaviour
(cherry picked from commit 4dfd0c1863)
2016-04-02 22:10:15 +02:00
Franklin Sobrinho 812de22194 Fix file dialog, of Particles2D plugin, showing "Error" icons
(cherry picked from commit 8d2a957e36)
2016-04-02 22:09:33 +02:00
Franklin Sobrinho 8de0405032 Automatically create input node when creating a ShaderGraph
(cherry picked from commit 5ee67ba498)
2016-04-02 22:09:26 +02:00
Franklin Sobrinho e59c0610ca Fix crash when importing sub-scenes
(cherry picked from commit cb7db2d430)
2016-04-02 22:09:01 +02:00
Paulb23 8fd4c78caf Added configuable tab size
(cherry picked from commit 9234bd3ff9)
2016-04-02 22:08:41 +02:00
Brandon DeRosier 85820434de Correct spot light size conversion in Blender exporter.
The collada falloff angle is the angle from the center of the spot
light projection, whereas Blender's point light size is the angle from
one side to the opposite, meaning it's twice as much.

(cherry picked from commit 1f4a214987)
2016-04-02 22:08:23 +02:00
Saracen d0151daa69 Undo and redo commands on text editor now affect internal version which fixes inconsistent file saving validation.
(cherry picked from commit b2e471fd7c)
2016-04-02 22:07:40 +02:00
Rémi Verschelde 763b29ed18 Remove redundant buttons
Now the Load button is alone on its line,
we probably need to find it a better place.

(cherry picked from commit d36333b648)
2016-04-02 22:06:37 +02:00
Rémi Verschelde 1d096471dc Add stop and delete buttons to sample library
Based on the work by @rdcklinux in #3339.
The play button becomes a stop button while playing.
A delete button is added in the last column.

(cherry picked from commit 533b9b7342)
2016-04-02 22:06:30 +02:00
sanikoyes 7c44cbee67 Fix link error when disable_3d=yes
(cherry picked from commit a638af886e)
2016-04-02 22:05:49 +02:00
Ignacio Etcheverry d950a13c10 TileSet Export: Avoid invalid error when merge is enabled but file does not exist
(cherry picked from commit 897b33ce77)
2016-04-02 22:05:36 +02:00
Ignacio Etcheverry 6ce273b329 Fix crash when resizing ConcavePolygonShape2D segments
(cherry picked from commit 3fc16d4025)
2016-04-02 22:04:41 +02:00
Josh Grams 0635a639e9 TimeScale node: return +inf remaining for 0 scale.
(cherry picked from commit 65b7791263)
2016-04-02 22:04:35 +02:00
Hubert Jarosz 424a104666 remove trailing whitespace
(cherry picked from commit 4a4f247914)
2016-04-02 22:03:48 +02:00
Josh Grams 830947feaf AnimationTreePlayer: distinguish value tracks.
If the node had a 3D Transform, the transform would always get written,
even if the tracks on that node were supposed to be value tracks.

(cherry picked from commit 2fa200ff53)
2016-04-02 22:00:40 +02:00
Josh Grams ee20365f7c Variant::blend: add Quat, fix Vector3.
(cherry picked from commit f7fad32188)
2016-04-02 22:00:18 +02:00
RegalMedia 0a24f562fb Update version in Info.plist
Getting info on Godot.app still shows version 1.0.0.  Would be nice to have this reflect the real version number via the build system.
(cherry picked from commit 3d9e26bfce)
2016-04-02 21:59:49 +02:00
Josh Grams 60e4cfbcb7 TimeScale node: scale return value (time remaining).
(cherry picked from commit 2e1b1234a3)
2016-04-02 21:59:07 +02:00
hondres 656aa0a501 fix InputMap::action_erase_event()
fixes #3976

(cherry picked from commit 9544042adb)
2016-04-02 21:58:26 +02:00
volzhs 7ad50eaea8 This will disable png arm neon optimizing for android template if compile on windows, but make compiling successful.
And arm neon opt is enabled if not on windows.

(cherry picked from commit db89a47e28)
2016-04-02 21:58:09 +02:00
Hubert Jarosz 83887ae16d migrate to container-based Travis CI
(cherry picked from commit 1f83ae9b5a)
2016-04-02 21:57:38 +02:00
hondres 827f4a895a osx: fix inverted horizontal scrolling
(cherry picked from commit 02eddbf7da)
2016-04-02 21:57:26 +02:00
Paulb23 da356eca0f Enabled scrolling past end of file
(cherry picked from commit f19eea2f2d)
2016-04-02 21:57:10 +02:00
Rémi Verschelde 53aa9cd51a Release 2.0.1 2016-03-06 19:05:45 +01:00
Rémi Verschelde 706d576f7b Add support for patch versions (2.0.x) 2016-03-06 19:05:27 +01:00
Franklin Sobrinho 226e0a7f4f Fix Project Settings dialog add/delete global variable
(cherry picked from commit 48524384d6)
2016-03-06 18:07:42 +01:00
hondres c44060bb82 doc: fix joystick left/right trigger axis description (index 6/7 instead of 4/5)
(cherry picked from commit 1b806ef54e)
2016-03-06 18:06:47 +01:00
Martin Chuckeles 4fee5f3915 Add more verbose build-in functions descriptions
Add descriptions for some global constants

(cherry picked from commit ff7c89ebaf)
2016-03-06 10:39:21 +01:00
Franklin Sobrinho e69c9021b5 The help page now show the entire object hierarchy
(cherry picked from commit fdd1209276)
2016-03-06 09:48:26 +01:00
Franklin Sobrinho edb3716da7 Fix Sprite doesn't updating region_rect value in certain conditions
(cherry picked from commit 1d188c1c7b)
2016-03-06 09:48:20 +01:00
Franklin Sobrinho 1bdd5d24cb Removed "__editor_plugin_screen__" metadata creation
(cherry picked from commit b79e83ad6f)
2016-03-06 09:48:15 +01:00
Franklin Sobrinho a1a1c0b9f6 Added search box in Class List dialog (Script Editor)
(cherry picked from commit cc6a6ef08c)
2016-03-06 09:48:06 +01:00
Martin Chuckeles 450a7a9120 Write GDScript documentation
(cherry picked from commit cd1184d56c)
2016-03-05 15:12:24 +01:00
Zher Huei Lee c850fa7331 Added relative paths for DirAccess::remove()
Follows similar behaviour to DirAccess::rename()

(cherry picked from commit d7052ddba3)
2016-03-05 13:35:48 +01:00
hondres afd75013f9 html5: workaround for echo key events.
(cherry picked from commit 352db6b17e)
2016-03-05 13:35:36 +01:00
Martin Chuckeles 848c7378fd Add editor settings for call hint placement
Added settings: text_editor/put_callhint_tooltip_below_current_line
and text_editor/callhint_tooltip_offset

(cherry picked from commit 47206b409d)
2016-03-05 12:58:01 +01:00
Martin Chuckeles 4b2fcabb74 Hide hint if completion is active
(cherry picked from commit 26cc14e839)
2016-03-05 12:57:56 +01:00
Martin Chuckeles cb7693c533 Move the call hint under the current line
(cherry picked from commit 03025f60b6)
2016-03-05 12:57:52 +01:00
Stabington 7fea990b1b set_time_scale docs
This is correct?

(cherry picked from commit 6b7ec5de69)
2016-03-05 12:56:27 +01:00
volzhs 95e46e6eac fix gradle build on windows
(cherry picked from commit d6cc887627)
2016-03-05 12:56:19 +01:00
Josh Grams bea8e1654e AnimationTreePlayer (Blend3): process all inputs.
Always call _process_node on all three inputs so that looped animations
don't get out of sync.

(cherry picked from commit b79351aa45)
2016-03-05 12:55:54 +01:00
Josh Grams cafcdb015d AnimationTreePlayer: blend value tracks (closes #2299)
Variant:
- zero() sets a Variant to the appropriate type of zero value
- blend() blends part of one Variant on top of another.

(cherry picked from commit 391ce81c5e)
2016-03-05 12:55:43 +01:00
Rémi Verschelde 459b914d9c Quick fixes to tween documentation formatting
Maybe the reST parser should be improved instead though ;)

(cherry picked from commit a12c63ef9e)
2016-03-01 08:38:23 +01:00
Rémi Verschelde 9ed3d21d5a Sync classes 2016-03-01 08:25:04 +01:00
hinsbart 82d06b0027 use joystick name from mapping-db if available 2016-03-01 08:16:27 +01:00
Ariel Manzur e0a66b6e56 deleted files added accidentally
(cherry picked from commit 96b60c281f)
2016-02-29 09:03:31 +01:00
Bojidar Marinov 186b82c350 Document Tween class
(cherry picked from commit 49e1cc6fa9)
2016-02-29 09:03:06 +01:00
Rémi Verschelde 1af2e1101d Remove grey capsule on official logo
It had been added by a contributor without prior discussion
with the rest of the team, but the grey capsule did not look
so good. Closes #3848.

Also renamed godot_{icon,logo} to just {icon,logo}.

(cherry picked from commit eb5f9ed89b)
2016-02-29 09:01:02 +01:00
Rémi Verschelde a55f41e3d9 screen_shaders: convert demo images to JPG
(cherry picked from commit a97c1ca8f9)
2016-02-29 09:00:55 +01:00
Rémi Verschelde 439e29ea95 normalmap demo: convert images to JPG
To make the demos lighter

(cherry picked from commit 2fd177b2a5)
2016-02-29 09:00:48 +01:00
Rémi Verschelde f5e8e89f50 Remove Noto Sans font from translation demo (heavy!)
(cherry picked from commit 0f087755cc)
2016-02-29 09:00:43 +01:00
Ariel Manzur f619b05751 added [presets] to ._sc_ and "android/shutdown_adb_on_exit" to editor_settings
(cherry picked from commit 30d0ca9766)
2016-02-29 09:00:35 +01:00
Juan Linietsky aa94ff6dae fix transform localization event in mouse motion
(cherry picked from commit 08e0e64a19)
2016-02-29 09:00:14 +01:00
Krzysztof Jankowski ee5c250b63 OUYA gamepad mappings fix
Fix gamepad mappings for OUYA revision 4
2016-02-27 15:28:34 +01:00
Ariel Manzur e4d367e7a1 theora on server build 2016-02-27 15:28:22 +01:00
Ariel Manzur 45a0bbe56e adds -pm and -project_manager command line options to start project manager
fixes bug where the user has an engine.cfg on the executable directory so it runs the game instead of opening the project manager
2016-02-27 15:27:33 +01:00
Julian Murgia - StraToN d86b12a397 Fixed closing a scene tab when it was not the CURRENT tab. Fixes #3810 2016-02-27 15:27:25 +01:00
hinsbart f0ba9c7e78 x11: fix joysticks not recognizing some buttons
dpad on x360 pads with kernel < 4.3 is working now
2016-02-27 15:27:15 +01:00
David 61f17fb1bb applied some typo fixes. see godotengine/godot-docs#18 2016-02-27 15:27:10 +01:00
Dana Olson a43af20f31 added more Android gamepad mappings 2016-02-27 15:26:59 +01:00
est31 7ba92ae9eb Fix typo in error 2016-02-27 15:26:27 +01:00
est31 b05c27a27f Fix allocation bug if compiled with modern clang or gcc
* Add overflow checked intrinsic abstractions that check on overflow.
* Use them for memory allocation code.
* Use size_t type for memory allocation code to support full platform dependent width.

Fixes #3756.
2016-02-27 15:26:18 +01:00
Dana Olson e30cbc3b36 added a couple more Linux mappings, tweaked Ouya Linux mapping 2016-02-27 15:25:51 +01:00
1975 changed files with 291540 additions and 379174 deletions

10
.gitignore vendored
View File

@ -1,10 +1,9 @@
# GoDot auto generated files # Godot auto generated files
platform/server/logo.h platform/server/logo.h
platform/android/logo.h platform/android/logo.h
platform/bb10/logo.h platform/bb10/logo.h
platform/iphone/logo.h platform/iphone/logo.h
platform/javascript/logo.h platform/javascript/logo.h
platform/nacl/logo.h
platform/osx/logo.h platform/osx/logo.h
platform/windows/logo.h platform/windows/logo.h
platform/x11/logo.h platform/x11/logo.h
@ -19,7 +18,9 @@ drivers/unix/os_unix_global_settings_path.cpp
tools/editor/register_exporters.cpp tools/editor/register_exporters.cpp
tools/editor/doc_data_compressed.h tools/editor/doc_data_compressed.h
tools/editor/editor_icons.cpp tools/editor/editor_icons.cpp
-fpic tools/editor/builtin_fonts.h
tools/editor/certs_compressed.h
tools/editor/translations.h
.fscache .fscache
make.bat make.bat
log.txt log.txt
@ -31,6 +32,7 @@ doc/_build/
*.bc *.bc
# Android specific # Android specific
platform/android/java/build.gradle
platform/android/java/.gradle platform/android/java/.gradle
platform/android/java/.gradletasknamecache platform/android/java/.gradletasknamecache
platform/android/java/local.properties platform/android/java/local.properties
@ -145,6 +147,8 @@ ipch/
*.opensdf *.opensdf
*.sdf *.sdf
*.cachefile *.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler # Visual Studio profiler
*.psess *.psess

View File

@ -1,7 +1,6 @@
language: cpp language: cpp
sudo: required sudo: false
dist: trusty
compiler: compiler:
- gcc - gcc
@ -41,12 +40,39 @@ matrix:
- compiler: clang - compiler: clang
env: GODOT_TARGET=x11 env: GODOT_TARGET=x11
addons:
apt:
packages:
- build-essential
- scons
- pkg-config
- libx11-dev
- libxcursor-dev
- libasound2-dev
- libfreetype6-dev
- libgl1-mesa-dev
- libglu1-mesa-dev
- libssl-dev
- libxinerama-dev
- libudev-dev
# For cross-compiling to Windows.
- binutils-mingw-w64-i686
- binutils-mingw-w64-x86-64
- gcc-mingw-w64-i686
- gcc-mingw-w64-x86-64
- g++-mingw-w64-i686
- g++-mingw-w64-x86-64
- mingw-w64
before_script: before_script:
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then sudo apt-get update -qq; sudo apt-get install -y scons pkg-config libx11-dev libxcursor-dev build-essential libasound2-dev libfreetype6-dev libgl1-mesa-dev libglu-dev libssl-dev libxinerama-dev libudev-dev; fi
- if [ "$TRAVIS_OS_NAME" = "linux" ] && [ "$GODOT_TARGET" = "windows" ]; then sudo apt-get update -qq; sudo apt-get install -y mingw32 mingw-w64; fi
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew update; brew install scons; fi - if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew update; brew install scons; fi
- if [ "$TRAVIS_OS_NAME" = "osx" ] && [ "$GODOT_TARGET" = "android" ]; then brew update; brew install android-sdk android-ndk; export ANDROID_HOME=/usr/local/opt/android-sdk; export ANDROID_NDK_ROOT=/usr/local/opt/android-ndk; fi - if [ "$TRAVIS_OS_NAME" = "osx" ] && [ "$GODOT_TARGET" = "android" ]; then
brew update; brew install -v android-sdk;
brew install -v android-ndk | grep -v "inflating:" | grep -v "creating:";
export ANDROID_HOME=/usr/local/opt/android-sdk; export ANDROID_NDK_ROOT=/usr/local/opt/android-ndk;
fi
script: script:
- scons platform=$GODOT_TARGET CXX=$CXX - scons platform=$GODOT_TARGET CXX=$CXX openssl=builtin

View File

@ -1,6 +1,6 @@
![GODOT](/logo.png) ![GODOT](/logo.png)
http://www.godotengine.org https://godotengine.org
### The Engine ### The Engine
@ -13,17 +13,17 @@ Godot has been developed by Juan Linietsky and Ariel Manzur for several years, a
### Documentation ### Documentation
Documentation has been moved to [ReadTheDocs](http://docs.godotengine.org). Documentation is hosted on [ReadTheDocs](http://docs.godotengine.org).
### Binary Downloads, Community, etc. ### Binary Downloads, Community, etc.
Binary downloads, community, etc. can be found in Godot homepage: Binary downloads, community, etc. can be found in Godot homepage:
http://www.godotengine.org https://godotengine.org
### Compiling from Source ### Compiling from Source
Compilation instructions for every platform can be found in the Wiki: See docs for compilation instructions for every platform:
http://docs.godotengine.org/en/latest/reference/_compiling.html http://docs.godotengine.org/en/latest/reference/_compiling.html
[![Build Status](https://travis-ci.org/godotengine/godot.svg?branch=master)](https://travis-ci.org/godotengine/godot) [![Build Status](https://travis-ci.org/godotengine/godot.svg?branch=master)](https://travis-ci.org/godotengine/godot)

View File

@ -23,7 +23,7 @@ platform_exporters=[]
global_defaults=[] global_defaults=[]
for x in glob.glob("platform/*"): for x in glob.glob("platform/*"):
if (not os.path.isdir(x)): if (not os.path.isdir(x) or not os.path.exists(x+"/detect.py")):
continue continue
tmppath="./"+x tmppath="./"+x
@ -63,9 +63,9 @@ elif (os.name=="nt"):
if (os.getenv("VSINSTALLDIR")==None or platform_arg=="android"): if (os.getenv("VSINSTALLDIR")==None or platform_arg=="android"):
custom_tools=['mingw'] custom_tools=['mingw']
env_base=Environment(tools=custom_tools,ENV = {'PATH' : os.environ['PATH']}); env_base=Environment(tools=custom_tools);
env_base.AppendENVPath('PATH', os.getenv('PATH'))
#env_base=Environment(tools=custom_tools); env_base.AppendENVPath('PKG_CONFIG_PATH', os.getenv('PKG_CONFIG_PATH'))
env_base.global_defaults=global_defaults env_base.global_defaults=global_defaults
env_base.android_maven_repos=[] env_base.android_maven_repos=[]
env_base.android_dependencies=[] env_base.android_dependencies=[]
@ -112,7 +112,8 @@ if profile:
opts=Variables(customs, ARGUMENTS) opts=Variables(customs, ARGUMENTS)
opts.Add('target', 'Compile Target (debug/release_debug/release).', "debug") opts.Add('target', 'Compile Target (debug/release_debug/release).', "debug")
opts.Add('bits', 'Compile Target Bits (default/32/64).', "default") opts.Add('arch', 'Platform dependent architecture (arm/arm64/x86/x64/mips/etc)', "")
opts.Add('bits', 'Compile Target Bits (default/32/64/fat).', "default")
opts.Add('platform','Platform: '+str(platform_list)+'.',"") opts.Add('platform','Platform: '+str(platform_list)+'.',"")
opts.Add('p','Platform (same as platform=).',"") opts.Add('p','Platform (same as platform=).',"")
opts.Add('tools','Build Tools (Including Editor): (yes/no)','yes') opts.Add('tools','Build Tools (Including Editor): (yes/no)','yes')
@ -267,10 +268,14 @@ if selected_platform in platform_list:
else: else:
suffix+=".debug" suffix+=".debug"
if (env["bits"]=="32"): if env["arch"] != "":
suffix += "."+env["arch"]
elif (env["bits"]=="32"):
suffix+=".32" suffix+=".32"
elif (env["bits"]=="64"): elif (env["bits"]=="64"):
suffix+=".64" suffix+=".64"
elif (env["bits"]=="fat"):
suffix+=".fat"
suffix+=env.extra_suffix suffix+=env.extra_suffix
@ -302,10 +307,10 @@ if selected_platform in platform_list:
if (env['musepack']=='yes'): if (env['musepack']=='yes'):
env.Append(CPPFLAGS=['-DMUSEPACK_ENABLED']); env.Append(CPPFLAGS=['-DMUSEPACK_ENABLED']);
if (env['openssl']!='no'): #if (env['openssl']!='no'):
env.Append(CPPFLAGS=['-DOPENSSL_ENABLED']); # env.Append(CPPFLAGS=['-DOPENSSL_ENABLED']);
if (env['openssl']=="builtin"): # if (env['openssl']=="builtin"):
env.Append(CPPPATH=['#drivers/builtin_openssl2']) # env.Append(CPPPATH=['#drivers/builtin_openssl2'])
if (env["builtin_zlib"]=='yes'): if (env["builtin_zlib"]=='yes'):
env.Append(CPPPATH=['#drivers/builtin_zlib/zlib']) env.Append(CPPPATH=['#drivers/builtin_zlib/zlib'])
@ -324,7 +329,7 @@ if selected_platform in platform_list:
if (env['theora']=='yes'): if (env['theora']=='yes'):
env['theoralib']='yes' env['theoralib']='yes'
env.Append(CPPFLAGS=['-DTHEORA_ENABLED']); env.Append(CPPFLAGS=['-DTHEORA_ENABLED']);
if (env['theoralib']=='yes'): if (env['theoralib']=='yes'):
env.Append(CPPFLAGS=['-DTHEORALIB_ENABLED']); env.Append(CPPFLAGS=['-DTHEORALIB_ENABLED']);
@ -389,14 +394,25 @@ if selected_platform in platform_list:
AddToVSProject(env.servers_sources) AddToVSProject(env.servers_sources)
AddToVSProject(env.tool_sources) AddToVSProject(env.tool_sources)
# this env flag won't work, it needs to be set in env_base=Environment(MSVC_VERSION='9.0')
# Even then, SCons still seems to ignore it and builds with the latest MSVC...
# That said, it's not needed to be set so far but I'm leaving it here so that this comment
# has a purpose.
#env['MSVS_VERSION']='9.0' #env['MSVS_VERSION']='9.0'
env['MSVSBUILDCOM'] = "scons platform=" + selected_platform + " target=" + env["target"] + " bits=" + env["bits"] + " tools=yes"
env['MSVSREBUILDCOM'] = "scons platform=" + selected_platform + " target=" + env["target"] + " bits=" + env["bits"] + " tools=yes vsproj=true"
env['MSVSCLEANCOM'] = "scons --clean platform=" + selected_platform + " target=" + env["target"] + " bits=" + env["bits"] + " tools=yes" # Calls a CMD with /C(lose) and /V(delayed environment variable expansion) options.
# And runs vcvarsall bat for the propper arhitecture and scons for propper configuration
debug_variants = ['Debug|Win32']+['Debug|x64'] env['MSVSBUILDCOM'] = 'cmd /V /C set "plat=$(PlatformTarget)" ^& (if "$(PlatformTarget)"=="x64" (set "plat=x86_amd64")) ^& set "tools=yes" ^& (if "$(Configuration)"=="release" (set "tools=no")) ^& call "$(VCInstallDir)vcvarsall.bat" !plat! ^& scons platform=windows target=$(Configuration) tools=!tools! -j2'
release_variants = ['Release|Win32']+['Release|x64'] env['MSVSREBUILDCOM'] = 'cmd /V /C set "plat=$(PlatformTarget)" ^& (if "$(PlatformTarget)"=="x64" (set "plat=x86_amd64")) ^& set "tools=yes" ^& (if "$(Configuration)"=="release" (set "tools=no")) & call "$(VCInstallDir)vcvarsall.bat" !plat! ^& scons platform=windows target=$(Configuration) tools=!tools! vsproj=yes -j2'
release_debug_variants = ['Release_Debug|Win32']+['Release_Debug|x64'] env['MSVSCLEANCOM'] = 'cmd /V /C set "plat=$(PlatformTarget)" ^& (if "$(PlatformTarget)"=="x64" (set "plat=x86_amd64")) ^& set "tools=yes" ^& (if "$(Configuration)"=="release" (set "tools=no")) ^& call "$(VCInstallDir)vcvarsall.bat" !plat! ^& scons --clean platform=windows target=$(Configuration) tools=!tools! -j2'
# This version information (Win32, x64, Debug, Release, Release_Debug seems to be
# required for Visual Studio to understand that it needs to generate an NMAKE
# project. Do not modify without knowing what you are doing.
debug_variants = ['debug|Win32']+['debug|x64']
release_variants = ['release|Win32']+['release|x64']
release_debug_variants = ['release_debug|Win32']+['release_debug|x64']
variants = debug_variants + release_variants + release_debug_variants variants = debug_variants + release_variants + release_debug_variants
debug_targets = ['Debug']+['Debug'] debug_targets = ['Debug']+['Debug']
release_targets = ['Release']+['Release'] release_targets = ['Release']+['Release']

View File

@ -44,9 +44,9 @@ MainLoop * test() {
/* /*
HashMap<int,int> int_map; HashMap<int,int> int_map;
for (int i=0;i<68000;i++) { for (int i=0;i<68000;i++) {
int num=(int)Math::random(0,1024); int num=(int)Math::random(0,1024);
int_map[i]=num; int_map[i]=num;
} }
@ -70,21 +70,21 @@ MainLoop * test() {
}; };
}; };
#if 0 #if 0
Set<int> set; Set<int> set;
print_line("Begin Insert"); print_line("Begin Insert");
for (int i=0;i<1100;i++) { for (int i=0;i<1100;i++) {
int num=i;//(int)Math::random(0,1024); int num=i;//(int)Math::random(0,1024);
// print_line("inserting "+itos(num)); // print_line("inserting "+itos(num));
set.insert( num ); set.insert( num );
} }
/* /*
for (int i=0;i<400;i++) { for (int i=0;i<400;i++) {
int num=(int)Math::random(0,1024); int num=(int)Math::random(0,1024);
set.erase(num); set.erase(num);
} }
@ -92,11 +92,11 @@ MainLoop * test() {
//set.print_tree(); //set.print_tree();
for(Set<int>::Element *I=set.front();I;I=I->next()) { for(Set<int>::Element *I=set.front();I;I=I->next()) {
print_line("inserted "+itos(I->get())+" prev is "+itos(I->prev()?I->prev()->get():-100)); print_line("inserted "+itos(I->get())+" prev is "+itos(I->prev()?I->prev()->get():-100));
} }
print_line("depth is "+itos(set.calculate_depth())); print_line("depth is "+itos(set.calculate_depth()));
print_line("Insert Success"); print_line("Insert Success");
#endif #endif

View File

@ -44,7 +44,7 @@ class TestMainLoop : public MainLoop {
RID light; RID light;
RID mesh; RID mesh;
RID scenario; RID scenario;
#define MULTIMESH_COUNT 1500 #define MULTIMESH_COUNT 1500
float ofs_x,ofs_y; float ofs_x,ofs_y;
@ -122,9 +122,9 @@ public:
} }
virtual void input_event(const InputEvent& p_event) { virtual void input_event(const InputEvent& p_event) {
if (p_event.type==InputEvent::MOUSE_MOTION && p_event.mouse_motion.button_mask&4) { if (p_event.type==InputEvent::MOUSE_MOTION && p_event.mouse_motion.button_mask&4) {
ofs_x+=p_event.mouse_motion.relative_y/200.0; ofs_x+=p_event.mouse_motion.relative_y/200.0;
ofs_y+=p_event.mouse_motion.relative_x/200.0; ofs_y+=p_event.mouse_motion.relative_x/200.0;
} }
@ -142,16 +142,16 @@ public:
} }
virtual void request_quit() { virtual void request_quit() {
quit=true; quit=true;
} }
virtual void init() { virtual void init() {
VisualServer *vs=VisualServer::get_singleton(); VisualServer *vs=VisualServer::get_singleton();
@ -163,13 +163,13 @@ public:
_update_qh(); _update_qh();
instance = vs->instance_create2(mesh,scenario); instance = vs->instance_create2(mesh,scenario);
camera = vs->camera_create(); camera = vs->camera_create();
vs->camera_set_perspective( camera, 60.0,0.1, 100.0 ); vs->camera_set_perspective( camera, 60.0,0.1, 100.0 );
viewport = vs->viewport_create(); viewport = vs->viewport_create();
vs->viewport_attach_camera( viewport, camera ); vs->viewport_attach_camera( viewport, camera );
vs->viewport_attach_to_screen(viewport); vs->viewport_attach_to_screen(viewport);
vs->viewport_set_scenario( viewport, scenario ); vs->viewport_set_scenario( viewport, scenario );
@ -179,7 +179,7 @@ public:
//vs->light_set_color( lightaux, VisualServer::LIGHT_COLOR_AMBIENT, Color(0.3,0.3,0.3) ); //vs->light_set_color( lightaux, VisualServer::LIGHT_COLOR_AMBIENT, Color(0.3,0.3,0.3) );
light = vs->instance_create2( lightaux,scenario ); light = vs->instance_create2( lightaux,scenario );
vs->instance_set_transform(light,Transform(Matrix3(Vector3(0.1,0.4,0.7).normalized(),0.9))); vs->instance_set_transform(light,Transform(Matrix3(Vector3(0.1,0.4,0.7).normalized(),0.9)));
ofs_x=0; ofs_x=0;
ofs_y=0; ofs_y=0;
quit=false; quit=false;
@ -190,20 +190,20 @@ public:
} }
virtual bool iteration(float p_time) { virtual bool iteration(float p_time) {
VisualServer *vs=VisualServer::get_singleton(); VisualServer *vs=VisualServer::get_singleton();
Transform tr_camera; Transform tr_camera;
tr_camera.rotate( Vector3(0,1,0), ofs_y ); tr_camera.rotate( Vector3(0,1,0), ofs_y );
tr_camera.rotate( Vector3(1,0,0),ofs_x ); tr_camera.rotate( Vector3(1,0,0),ofs_x );
tr_camera.translate(0,0,10); tr_camera.translate(0,0,10);
vs->camera_set_transform( camera, tr_camera ); vs->camera_set_transform( camera, tr_camera );
return quit; return quit;
} }
virtual void finish() { virtual void finish() {
} }
}; };

View File

@ -81,7 +81,7 @@ static String _parser_expr(const GDParser::Node *p_expr) {
case GDParser::Node::TYPE_IDENTIFIER: { case GDParser::Node::TYPE_IDENTIFIER: {
const GDParser::IdentifierNode *id_node = static_cast<const GDParser::IdentifierNode *>(p_expr); const GDParser::IdentifierNode *id_node = static_cast<const GDParser::IdentifierNode *>(p_expr);
txt=id_node->name; txt=id_node->name;
} break; } break;
case GDParser::Node::TYPE_CONSTANT: { case GDParser::Node::TYPE_CONSTANT: {

View File

@ -62,16 +62,16 @@ class TestMainLoop : public SceneTree {
Control *control; Control *control;
public: public:
virtual void request_quit() { virtual void request_quit() {
quit(); quit();
} }
virtual void init() { virtual void init() {
SceneTree::init(); SceneTree::init();
@ -112,7 +112,7 @@ public:
Ref<Theme> t = memnew( Theme ); Ref<Theme> t = memnew( Theme );
frame->set_theme(t); frame->set_theme(t);
get_root()->add_child( frame ); get_root()->add_child( frame );
Label *label = memnew( Label ); Label *label = memnew( Label );
@ -198,21 +198,21 @@ public:
//root->add_child( control ); //root->add_child( control );
LineEdit *line_edit = memnew( LineEdit ); LineEdit *line_edit = memnew( LineEdit );
line_edit->set_pos( Point2( 30,190 ) ); line_edit->set_pos( Point2( 30,190 ) );
line_edit->set_size( Point2( 180,1 ) ); line_edit->set_size( Point2( 180,1 ) );
frame->add_child(line_edit); frame->add_child(line_edit);
HScrollBar *hscroll = memnew( HScrollBar ); HScrollBar *hscroll = memnew( HScrollBar );
hscroll->set_pos( Point2( 30,290 ) ); hscroll->set_pos( Point2( 30,290 ) );
hscroll->set_size( Point2( 180,1 ) ); hscroll->set_size( Point2( 180,1 ) );
hscroll->set_max(10); hscroll->set_max(10);
hscroll->set_page(4); hscroll->set_page(4);
frame->add_child(hscroll); frame->add_child(hscroll);
@ -234,36 +234,36 @@ public:
hscroll->share(progress); hscroll->share(progress);
MenuButton *menu_button = memnew( MenuButton ); MenuButton *menu_button = memnew( MenuButton );
menu_button->set_text("I'm a menu!"); menu_button->set_text("I'm a menu!");
menu_button->set_pos( Point2( 30,380 ) ); menu_button->set_pos( Point2( 30,380 ) );
menu_button->set_size( Point2( 1,1 ) ); menu_button->set_size( Point2( 1,1 ) );
frame->add_child(menu_button); frame->add_child(menu_button);
PopupMenu *popup = menu_button->get_popup(); PopupMenu *popup = menu_button->get_popup();
popup->add_item("Hello, testing"); popup->add_item("Hello, testing");
popup->add_item("My Dearest"); popup->add_item("My Dearest");
popup->add_separator(); popup->add_separator();
popup->add_item("Popup"); popup->add_item("Popup");
popup->add_check_item("Check Popup"); popup->add_check_item("Check Popup");
popup->set_item_checked(4,true); popup->set_item_checked(4,true);
OptionButton *options = memnew( OptionButton ); OptionButton *options = memnew( OptionButton );
options->add_item("Hello, testing"); options->add_item("Hello, testing");
options->add_item("My Dearest"); options->add_item("My Dearest");
options->set_pos( Point2( 230,180 ) ); options->set_pos( Point2( 230,180 ) );
options->set_size( Point2( 1,1 ) ); options->set_size( Point2( 1,1 ) );
frame->add_child(options); frame->add_child(options);
/* /*
Tree * tree = memnew( Tree ); Tree * tree = memnew( Tree );
tree->set_columns(2); tree->set_columns(2);
tree->set_pos( Point2( 230,210 ) ); tree->set_pos( Point2( 230,210 ) );
tree->set_size( Point2( 150,250 ) ); tree->set_size( Point2( 150,250 ) );
@ -286,7 +286,7 @@ public:
item->set_editable(0,true); item->set_editable(0,true);
item->set_text(0,"Have,Many,Several,Options!"); item->set_text(0,"Have,Many,Several,Options!");
item->set_range(0,2); item->set_range(0,2);
frame->add_child(tree); frame->add_child(tree);
*/ */
@ -365,11 +365,11 @@ public:
tabc->add_child(ctl); tabc->add_child(ctl);
frame->add_child(tabc); frame->add_child(tabc);
tabc->set_pos( Point2( 400,210 ) ); tabc->set_pos( Point2( 400,210 ) );
tabc->set_size( Point2( 180,250 ) ); tabc->set_size( Point2( 180,250 ) );
Ref<ImageTexture> text = memnew( ImageTexture ); Ref<ImageTexture> text = memnew( ImageTexture );
text->load("test_data/concave.png"); text->load("test_data/concave.png");
@ -387,13 +387,13 @@ public:
} }
}; };
MainLoop* test() { MainLoop* test() {
return memnew( TestMainLoop ); return memnew( TestMainLoop );
} }

View File

@ -47,37 +47,37 @@ namespace TestIO {
class TestMainLoop : public MainLoop { class TestMainLoop : public MainLoop {
bool quit; bool quit;
public: public:
virtual void input_event(const InputEvent& p_event) { virtual void input_event(const InputEvent& p_event) {
} }
virtual bool idle(float p_time) { virtual bool idle(float p_time) {
return false; return false;
} }
virtual void request_quit() { virtual void request_quit() {
quit=true; quit=true;
} }
virtual void init() { virtual void init() {
quit=true; quit=true;
} }
virtual bool iteration(float p_time) { virtual bool iteration(float p_time) {
return quit; return quit;
} }
virtual void finish() { virtual void finish() {
} }
}; };

View File

@ -64,7 +64,7 @@ const char ** tests_get_names() {
"physics", "physics",
NULL NULL
}; };
return test_names; return test_names;
} }
@ -72,22 +72,22 @@ MainLoop* test_main(String p_test,const List<String>& p_args) {
if (p_test=="string") { if (p_test=="string") {
return TestString::test(); return TestString::test();
} }
if (p_test=="containers") { if (p_test=="containers") {
return TestContainers::test(); return TestContainers::test();
} }
if (p_test=="math") { if (p_test=="math") {
return TestMath::test(); return TestMath::test();
} }
if (p_test=="physics") { if (p_test=="physics") {
return TestPhysics::test(); return TestPhysics::test();
} }
@ -97,15 +97,15 @@ MainLoop* test_main(String p_test,const List<String>& p_args) {
} }
if (p_test=="misc") { if (p_test=="misc") {
return TestMisc::test(); return TestMisc::test();
} }
if (p_test=="render") { if (p_test=="render") {
return TestRender::test(); return TestRender::test();
} }
#ifndef _3D_DISABLED #ifndef _3D_DISABLED
if (p_test=="gui") { if (p_test=="gui") {
@ -119,17 +119,17 @@ MainLoop* test_main(String p_test,const List<String>& p_args) {
} }
if (p_test=="io") { if (p_test=="io") {
return TestIO::test(); return TestIO::test();
} }
if (p_test=="particles") { if (p_test=="particles") {
return TestParticles::test(); return TestParticles::test();
} }
if (p_test=="multimesh") { if (p_test=="multimesh") {
return TestMultiMesh::test(); return TestMultiMesh::test();
} }
@ -171,7 +171,7 @@ MainLoop* test_main(String p_test,const List<String>& p_args) {
#ifdef PYTHON_ENABLED #ifdef PYTHON_ENABLED
if (p_test=="python") { if (p_test=="python") {
return TestPython::test(); return TestPython::test();
} }
#endif #endif

View File

@ -70,7 +70,7 @@ fix: 0, 0, 49.949951, 50
v0: 0, 0, 100, 100 v0: 0, 0, 100, 100
v1: 0, 0, 100, 100 v1: 0, 0, 100, 100
fix: 0, 0, 100, 100 fix: 0, 0, 100, 100
*/ */
} }

View File

@ -43,38 +43,38 @@ class TestMainLoop : public MainLoop {
RID viewport; RID viewport;
RID light; RID light;
RID scenario; RID scenario;
struct InstanceInfo { struct InstanceInfo {
RID instance; RID instance;
Transform base; Transform base;
Vector3 rot_axis; Vector3 rot_axis;
}; };
List<InstanceInfo> instances; List<InstanceInfo> instances;
float ofs; float ofs;
bool quit; bool quit;
public: public:
virtual void input_event(const InputEvent& p_event) { virtual void input_event(const InputEvent& p_event) {
} }
virtual void request_quit() { virtual void request_quit() {
quit=true; quit=true;
} }
virtual void init() { virtual void init() {
VisualServer *vs=VisualServer::get_singleton(); VisualServer *vs=VisualServer::get_singleton();
particles = vs->particles_create(); particles = vs->particles_create();
vs->particles_set_amount(particles,1000); vs->particles_set_amount(particles,1000);
instance = vs->instance_create2(particles,scenario); instance = vs->instance_create2(particles,scenario);
camera = vs->camera_create(); camera = vs->camera_create();
// vs->camera_set_perspective( camera, 60.0,0.1, 100.0 ); // vs->camera_set_perspective( camera, 60.0,0.1, 100.0 );
viewport = vs->viewport_create(); viewport = vs->viewport_create();
vs->viewport_attach_camera( viewport, camera ); vs->viewport_attach_camera( viewport, camera );
@ -89,7 +89,7 @@ public:
RID lightaux = vs->light_create( VisualServer::LIGHT_DIRECTIONAL ); RID lightaux = vs->light_create( VisualServer::LIGHT_DIRECTIONAL );
// vs->light_set_color( lightaux, VisualServer::LIGHT_COLOR_AMBIENT, Color(0.0,0.0,0.0) ); // vs->light_set_color( lightaux, VisualServer::LIGHT_COLOR_AMBIENT, Color(0.0,0.0,0.0) );
light = vs->instance_create2( lightaux, scenario ); light = vs->instance_create2( lightaux, scenario );
ofs=0; ofs=0;
quit=false; quit=false;
} }
@ -99,14 +99,14 @@ public:
virtual bool iteration(float p_time) { virtual bool iteration(float p_time) {
// VisualServer *vs=VisualServer::get_singleton(); // VisualServer *vs=VisualServer::get_singleton();
ofs+=p_time; ofs+=p_time;
return quit; return quit;
} }
virtual void finish() { virtual void finish() {
} }
}; };

View File

@ -47,7 +47,7 @@ class TestPhysicsMainLoop : public MainLoop {
}; };
RID test_cube; RID test_cube;
RID plane; RID plane;
RID sphere; RID sphere;
RID light; RID light;
@ -74,13 +74,13 @@ class TestPhysicsMainLoop : public MainLoop {
//t.basis.scale( Vector3(1.0,0.5,0.2) ); //t.basis.scale( Vector3(1.0,0.5,0.2) );
vs->instance_set_transform(p_visual_instance,t); vs->instance_set_transform(p_visual_instance,t);
} }
bool quit; bool quit;
protected: protected:
static void _bind_methods() { static void _bind_methods() {
ObjectTypeDB::bind_method("body_changed_transform",&TestPhysicsMainLoop::body_changed_transform); ObjectTypeDB::bind_method("body_changed_transform",&TestPhysicsMainLoop::body_changed_transform);
} }
@ -90,11 +90,11 @@ protected:
PhysicsServer * ps = PhysicsServer::get_singleton(); PhysicsServer * ps = PhysicsServer::get_singleton();
RID mesh_instance = vs->instance_create2(type_mesh_map[p_shape],scenario); RID mesh_instance = vs->instance_create2(type_mesh_map[p_shape],scenario);
RID body = ps->body_create(p_body,!p_active_default); RID body = ps->body_create(p_body,!p_active_default);
ps->body_set_space(body,space); ps->body_set_space(body,space);
ps->body_set_param(body,PhysicsServer::BODY_PARAM_BOUNCE,0.0); ps->body_set_param(body,PhysicsServer::BODY_PARAM_BOUNCE,0.0);
//todo set space //todo set space
ps->body_add_shape(body,type_shape_map[p_shape]); ps->body_add_shape(body,type_shape_map[p_shape]);
ps->body_set_force_integration_callback(body,this,"body_changed_transform",mesh_instance); ps->body_set_force_integration_callback(body,this,"body_changed_transform",mesh_instance);
ps->body_set_state( body, PhysicsServer::BODY_STATE_TRANSFORM,p_location); ps->body_set_state( body, PhysicsServer::BODY_STATE_TRANSFORM,p_location);
@ -289,7 +289,7 @@ protected:
public: public:
virtual void input_event(const InputEvent& p_event) { virtual void input_event(const InputEvent& p_event) {
if (p_event.type==InputEvent::MOUSE_MOTION && p_event.mouse_motion.button_mask&4) { if (p_event.type==InputEvent::MOUSE_MOTION && p_event.mouse_motion.button_mask&4) {
ofs_y-=p_event.mouse_motion.relative_y/200.0; ofs_y-=p_event.mouse_motion.relative_y/200.0;
@ -329,7 +329,7 @@ public:
} }
virtual void request_quit() { virtual void request_quit() {
quit=true; quit=true;
} }
virtual void init() { virtual void init() {
@ -388,53 +388,53 @@ public:
/* Make Trimesh */ /* Make Trimesh */
quit=false; quit=false;
return; return;
#if 0 #if 0
#define GRID_SIZE 5 #define GRID_SIZE 5
float grid[GRID_SIZE][GRID_SIZE]; float grid[GRID_SIZE][GRID_SIZE];
for (int i=0;i<GRID_SIZE;i++) { for (int i=0;i<GRID_SIZE;i++) {
for (int j=0;j<GRID_SIZE;j++) { for (int j=0;j<GRID_SIZE;j++) {
grid[j][i]=Math::random(0.0, 1.0 ); grid[j][i]=Math::random(0.0, 1.0 );
} }
} }
Vector<Vector3> faces; Vector<Vector3> faces;
for (int i=1;i<GRID_SIZE;i++) { for (int i=1;i<GRID_SIZE;i++) {
for (int j=1;j<GRID_SIZE;j++) { for (int j=1;j<GRID_SIZE;j++) {
#define MAKE_VERTEX(m_x,m_z)\ #define MAKE_VERTEX(m_x,m_z)\
faces.push_back( Vector3( m_x-GRID_SIZE/2.0, grid[m_x][m_z], m_z-GRID_SIZE/2.0 )*3.0 ) faces.push_back( Vector3( m_x-GRID_SIZE/2.0, grid[m_x][m_z], m_z-GRID_SIZE/2.0 )*3.0 )
MAKE_VERTEX(i,j-1); MAKE_VERTEX(i,j-1);
MAKE_VERTEX(i,j); MAKE_VERTEX(i,j);
MAKE_VERTEX(i-1,j); MAKE_VERTEX(i-1,j);
MAKE_VERTEX(i-1,j-1); MAKE_VERTEX(i-1,j-1);
MAKE_VERTEX(i,j-1); MAKE_VERTEX(i,j-1);
MAKE_VERTEX(i-1,j); MAKE_VERTEX(i-1,j);
} }
} }
/* /*
faces.clear(); faces.clear();
faces.push_back( Vector3(0,0,-5) ); faces.push_back( Vector3(0,0,-5) );
faces.push_back( Vector3(1,0,-1) ); faces.push_back( Vector3(1,0,-1) );
faces.push_back( Vector3(-1,-0,-1) ); faces.push_back( Vector3(-1,-0,-1) );
*/ */
RID trimesh_shape = ps->shape_create(); RID trimesh_shape = ps->shape_create();
ps->shape_set_data(trimesh_shape, PhysicsServer::SHAPE_CONCAVE_POLYGON,faces); ps->shape_set_data(trimesh_shape, PhysicsServer::SHAPE_CONCAVE_POLYGON,faces);
faces=ps->shape_get_shape(trimesh_shape, 0); faces=ps->shape_get_shape(trimesh_shape, 0);
Vector<Vector3> normals; // for drawing Vector<Vector3> normals; // for drawing
for (int i=0;i<faces.size()/3;i++) { for (int i=0;i<faces.size()/3;i++) {
Plane p( faces[i*3+0],faces[i*3+1], faces[i*3+2] ); Plane p( faces[i*3+0],faces[i*3+1], faces[i*3+2] );
normals.push_back(p.normal); normals.push_back(p.normal);
normals.push_back(p.normal); normals.push_back(p.normal);
@ -448,11 +448,11 @@ public:
RID trimesh_mat = vs->fixed_material_create(); RID trimesh_mat = vs->fixed_material_create();
vs->material_generate( trimesh_mat, Color(1.0,0.5,0.3) ); vs->material_generate( trimesh_mat, Color(1.0,0.5,0.3) );
vs->mesh_surface_set_material( trimesh_mesh, 0, trimesh_mat ); vs->mesh_surface_set_material( trimesh_mesh, 0, trimesh_mat );
RID triins = vs->instance_create2(trimesh_mesh); RID triins = vs->instance_create2(trimesh_mesh);
RID tribody = ps->body_create( PhysicsServer::BODY_MODE_STATIC, trimesh_shape); RID tribody = ps->body_create( PhysicsServer::BODY_MODE_STATIC, trimesh_shape);
Transform tritrans = Transform( Matrix3(), Vector3(0,0,-2) ); Transform tritrans = Transform( Matrix3(), Vector3(0,0,-2) );
ps->body_set_state( tribody, PhysicsServer::BODY_STATE_TRANSFORM, tritrans ); ps->body_set_state( tribody, PhysicsServer::BODY_STATE_TRANSFORM, tritrans );
@ -483,7 +483,7 @@ public:
return quit; return quit;
} }
virtual void finish() { virtual void finish() {
} }
void test_joint() { void test_joint() {
@ -599,7 +599,7 @@ public:
PhysicsServer::ShapeType type=shape_idx[i%4]; PhysicsServer::ShapeType type=shape_idx[i%4];
//type=PhysicsServer::SHAPE_CONVEX_POLYGON; //type=PhysicsServer::SHAPE_CONVEX_POLYGON;
Transform t; Transform t;
t.origin=Vector3(0.0*i,3.5+1.1*i,0.7+0.0*i); t.origin=Vector3(0.0*i,3.5+1.1*i,0.7+0.0*i);
//t.origin=Vector3(-0.7+0.0*i,0.5+4.1*i,0); //t.origin=Vector3(-0.7+0.0*i,0.5+4.1*i,0);

View File

@ -47,7 +47,7 @@ void test() {
PyRun_SimpleString("b=Moch();\n"); PyRun_SimpleString("b=Moch();\n");
PyRun_SimpleString("b.mooch();\n"); PyRun_SimpleString("b.mooch();\n");
PyRun_SimpleString("b.meis();\n"); PyRun_SimpleString("b.meis();\n");
} }

View File

@ -49,16 +49,16 @@ class TestMainLoop : public MainLoop {
RID viewport; RID viewport;
RID light; RID light;
RID scenario; RID scenario;
struct InstanceInfo { struct InstanceInfo {
RID instance; RID instance;
Transform base; Transform base;
Vector3 rot_axis; Vector3 rot_axis;
}; };
List<InstanceInfo> instances; List<InstanceInfo> instances;
float ofs; float ofs;
bool quit; bool quit;
protected: protected:
@ -66,13 +66,13 @@ protected:
public: public:
virtual void input_event(const InputEvent& p_event) { virtual void input_event(const InputEvent& p_event) {
if (p_event.type==InputEvent::KEY && p_event.key.pressed) if (p_event.type==InputEvent::KEY && p_event.key.pressed)
quit=true; quit=true;
} }
virtual void init() { virtual void init() {
print_line("INITIALIZING TEST RENDER"); print_line("INITIALIZING TEST RENDER");
VisualServer *vs=VisualServer::get_singleton(); VisualServer *vs=VisualServer::get_singleton();
@ -150,26 +150,26 @@ public:
}; };
for (int i=0;i<object_count;i++) { for (int i=0;i<object_count;i++) {
InstanceInfo ii; InstanceInfo ii;
ii.instance = vs->instance_create2( test_cube, scenario ); ii.instance = vs->instance_create2( test_cube, scenario );
ii.base.translate( Math::random(-20,20), Math::random(-20,20),Math::random(-20,18) ); ii.base.translate( Math::random(-20,20), Math::random(-20,20),Math::random(-20,18) );
ii.base.rotate( Vector3(0,1,0), Math::randf() * Math_PI ); ii.base.rotate( Vector3(0,1,0), Math::randf() * Math_PI );
ii.base.rotate( Vector3(1,0,0), Math::randf() * Math_PI ); ii.base.rotate( Vector3(1,0,0), Math::randf() * Math_PI );
vs->instance_set_transform( ii.instance, ii.base ); vs->instance_set_transform( ii.instance, ii.base );
ii.rot_axis = Vector3( Math::random(-1,1), Math::random(-1,1), Math::random(-1,1) ).normalized(); ii.rot_axis = Vector3( Math::random(-1,1), Math::random(-1,1), Math::random(-1,1) ).normalized();
instances.push_back(ii); instances.push_back(ii);
} }
camera = vs->camera_create(); camera = vs->camera_create();
// vs->camera_set_perspective( camera, 60.0,0.1, 100.0 ); // vs->camera_set_perspective( camera, 60.0,0.1, 100.0 );
viewport = vs->viewport_create(); viewport = vs->viewport_create();
@ -226,9 +226,9 @@ public:
ofs+=p_time*0.05; ofs+=p_time*0.05;
//return quit; //return quit;
for(List<InstanceInfo>::Element *E=instances.front();E;E=E->next()) { for(List<InstanceInfo>::Element *E=instances.front();E;E=E->next()) {
Transform pre( Matrix3(E->get().rot_axis, ofs), Vector3() ); Transform pre( Matrix3(E->get().rot_axis, ofs), Vector3() );
vs->instance_set_transform( E->get().instance, pre * E->get().base ); vs->instance_set_transform( E->get().instance, pre * E->get().base );
/* /*
@ -238,7 +238,7 @@ public:
instances.erase(E ); instances.erase(E );
}*/ }*/
} }
return quit; return quit;
} }

View File

@ -290,7 +290,7 @@ MainLoop* test() {
FileAccess *fa = FileAccess::open(test,FileAccess::READ); FileAccess *fa = FileAccess::open(test,FileAccess::READ);
if (!fa) { if (!fa) {
ERR_FAIL_V(NULL); ERR_FAIL_V(NULL);
} }

View File

@ -38,145 +38,145 @@
namespace TestString { namespace TestString {
bool test_1() { bool test_1() {
OS::get_singleton()->print("\n\nTest 1: Assign from cstr\n"); OS::get_singleton()->print("\n\nTest 1: Assign from cstr\n");
String s = "Hello"; String s = "Hello";
OS::get_singleton()->print("\tExpected: Hello\n"); OS::get_singleton()->print("\tExpected: Hello\n");
OS::get_singleton()->print("\tResulted: %ls\n",s.c_str()); OS::get_singleton()->print("\tResulted: %ls\n",s.c_str());
return (wcscmp(s.c_str(),L"Hello")==0); return (wcscmp(s.c_str(),L"Hello")==0);
} }
bool test_2() { bool test_2() {
OS::get_singleton()->print("\n\nTest 2: Assign from string (operator=)\n"); OS::get_singleton()->print("\n\nTest 2: Assign from string (operator=)\n");
String s = "Dolly"; String s = "Dolly";
String t = s; String t = s;
OS::get_singleton()->print("\tExpected: Dolly\n"); OS::get_singleton()->print("\tExpected: Dolly\n");
OS::get_singleton()->print("\tResulted: %ls\n",t.c_str()); OS::get_singleton()->print("\tResulted: %ls\n",t.c_str());
return (wcscmp(t.c_str(),L"Dolly")==0); return (wcscmp(t.c_str(),L"Dolly")==0);
} }
bool test_3() { bool test_3() {
OS::get_singleton()->print("\n\nTest 3: Assign from c-string (copycon)\n"); OS::get_singleton()->print("\n\nTest 3: Assign from c-string (copycon)\n");
String s("Sheep"); String s("Sheep");
String t(s); String t(s);
OS::get_singleton()->print("\tExpected: Sheep\n"); OS::get_singleton()->print("\tExpected: Sheep\n");
OS::get_singleton()->print("\tResulted: %ls\n",t.c_str()); OS::get_singleton()->print("\tResulted: %ls\n",t.c_str());
return (wcscmp(t.c_str(),L"Sheep")==0); return (wcscmp(t.c_str(),L"Sheep")==0);
} }
bool test_4() { bool test_4() {
OS::get_singleton()->print("\n\nTest 4: Assign from c-widechar (operator=)\n"); OS::get_singleton()->print("\n\nTest 4: Assign from c-widechar (operator=)\n");
String s(L"Give me"); String s(L"Give me");
OS::get_singleton()->print("\tExpected: Give me\n"); OS::get_singleton()->print("\tExpected: Give me\n");
OS::get_singleton()->print("\tResulted: %ls\n",s.c_str()); OS::get_singleton()->print("\tResulted: %ls\n",s.c_str());
return (wcscmp(s.c_str(),L"Give me")==0); return (wcscmp(s.c_str(),L"Give me")==0);
} }
bool test_5() { bool test_5() {
OS::get_singleton()->print("\n\nTest 5: Assign from c-widechar (copycon)\n"); OS::get_singleton()->print("\n\nTest 5: Assign from c-widechar (copycon)\n");
String s(L"Wool"); String s(L"Wool");
OS::get_singleton()->print("\tExpected: Wool\n"); OS::get_singleton()->print("\tExpected: Wool\n");
OS::get_singleton()->print("\tResulted: %ls\n",s.c_str()); OS::get_singleton()->print("\tResulted: %ls\n",s.c_str());
return (wcscmp(s.c_str(),L"Wool")==0); return (wcscmp(s.c_str(),L"Wool")==0);
} }
bool test_6() { bool test_6() {
OS::get_singleton()->print("\n\nTest 6: comparisons (equal)\n"); OS::get_singleton()->print("\n\nTest 6: comparisons (equal)\n");
String s="Test Compare"; String s="Test Compare";
OS::get_singleton()->print("\tComparing to \"Test Compare\"\n"); OS::get_singleton()->print("\tComparing to \"Test Compare\"\n");
if (! ( s=="Test Compare" ) ) if (! ( s=="Test Compare" ) )
return false; return false;
if (! ( s==L"Test Compare" ) ) if (! ( s==L"Test Compare" ) )
return false; return false;
if (! ( s==String("Test Compare") ) ) if (! ( s==String("Test Compare") ) )
return false; return false;
return true; return true;
} }
bool test_7() { bool test_7() {
OS::get_singleton()->print("\n\nTest 7: comparisons (unequal)\n"); OS::get_singleton()->print("\n\nTest 7: comparisons (unequal)\n");
String s="Test Compare"; String s="Test Compare";
OS::get_singleton()->print("\tComparing to \"Test Compare\"\n"); OS::get_singleton()->print("\tComparing to \"Test Compare\"\n");
if (! ( s!="Peanut" ) ) if (! ( s!="Peanut" ) )
return false; return false;
if (! ( s!=L"Coconut" ) ) if (! ( s!=L"Coconut" ) )
return false; return false;
if (! ( s!=String("Butter") ) ) if (! ( s!=String("Butter") ) )
return false; return false;
return true; return true;
} }
bool test_8() { bool test_8() {
OS::get_singleton()->print("\n\nTest 8: comparisons (operator<)\n"); OS::get_singleton()->print("\n\nTest 8: comparisons (operator<)\n");
String s="Bees"; String s="Bees";
OS::get_singleton()->print("\tComparing to \"Bees\"\n"); OS::get_singleton()->print("\tComparing to \"Bees\"\n");
if ( ! (s < "Elephant") ) if ( ! (s < "Elephant") )
return false; return false;
if ( s < L"Amber" ) if ( s < L"Amber" )
return false; return false;
if ( s < String("Beatrix") ) if ( s < String("Beatrix") )
return false; return false;
return true; return true;
} }
bool test_9() { bool test_9() {
OS::get_singleton()->print("\n\nTest 9: Concatenation\n"); OS::get_singleton()->print("\n\nTest 9: Concatenation\n");
String s; String s;
s+="Have"; s+="Have";
s+=' '; s+=' ';
s+='a'; s+='a';
@ -184,279 +184,279 @@ bool test_9() {
s = s + L"Nice"; s = s + L"Nice";
s = s + " "; s = s + " ";
s = s + String("Day"); s = s + String("Day");
OS::get_singleton()->print("\tComparing to \"Have a Nice Day\"\n"); OS::get_singleton()->print("\tComparing to \"Have a Nice Day\"\n");
return (s == "Have a Nice Day"); return (s == "Have a Nice Day");
} }
bool test_10() { bool test_10() {
OS::get_singleton()->print("\n\nTest 10: Misc funcs (size/length/empty/etc)\n"); OS::get_singleton()->print("\n\nTest 10: Misc funcs (size/length/empty/etc)\n");
if (! String("").empty()) if (! String("").empty())
return false; return false;
if (String("Mellon").size() != 7) if (String("Mellon").size() != 7)
return false; return false;
if (String("Oranges").length() != 7) if (String("Oranges").length() != 7)
return false; return false;
return true; return true;
} }
bool test_11() { bool test_11() {
OS::get_singleton()->print("\n\nTest 11: Operator[]\n"); OS::get_singleton()->print("\n\nTest 11: Operator[]\n");
String a="Kugar Sane"; String a="Kugar Sane";
a[0]='S'; a[0]='S';
a[6]='C'; a[6]='C';
if (a != "Sugar Cane") if (a != "Sugar Cane")
return false; return false;
if (a[1]!='u') if (a[1]!='u')
return false; return false;
return true; return true;
} }
bool test_12() { bool test_12() {
OS::get_singleton()->print("\n\nTest 12: case functions\n"); OS::get_singleton()->print("\n\nTest 12: case functions\n");
String a="MoMoNgA"; String a="MoMoNgA";
if (a.to_upper() != "MOMONGA") if (a.to_upper() != "MOMONGA")
return false; return false;
if (a.nocasecmp_to("momonga")!=0) if (a.nocasecmp_to("momonga")!=0)
return false; return false;
return true; return true;
} }
bool test_13() { bool test_13() {
OS::get_singleton()->print("\n\nTest 13: UTF8\n"); OS::get_singleton()->print("\n\nTest 13: UTF8\n");
/* how can i embed UTF in here? */ /* how can i embed UTF in here? */
static const CharType ustr[] = { 0x304A , 0x360F, 0x3088, 0x3046, 0 }; static const CharType ustr[] = { 0x304A , 0x360F, 0x3088, 0x3046, 0 };
// static const wchar_t ustr[] = { 'P', 0xCE, 'p',0xD3, 0 }; // static const wchar_t ustr[] = { 'P', 0xCE, 'p',0xD3, 0 };
String s=ustr; String s=ustr;
OS::get_singleton()->print("\tUnicode: %ls\n",ustr); OS::get_singleton()->print("\tUnicode: %ls\n",ustr);
s.parse_utf8( s.utf8().get_data() ); s.parse_utf8( s.utf8().get_data() );
OS::get_singleton()->print("\tConvert/Parse UTF8: %ls\n",s.c_str()); OS::get_singleton()->print("\tConvert/Parse UTF8: %ls\n",s.c_str());
return (s==ustr); return (s==ustr);
} }
bool test_14() { bool test_14() {
OS::get_singleton()->print("\n\nTest 14: ASCII\n"); OS::get_singleton()->print("\n\nTest 14: ASCII\n");
String s = L"Primero Leche"; String s = L"Primero Leche";
OS::get_singleton()->print("\tAscii: %s\n",s.ascii().get_data()); OS::get_singleton()->print("\tAscii: %s\n",s.ascii().get_data());
String t=s.ascii().get_data(); String t=s.ascii().get_data();
return (s==t); return (s==t);
} }
bool test_15() { bool test_15() {
OS::get_singleton()->print("\n\nTest 15: substr\n"); OS::get_singleton()->print("\n\nTest 15: substr\n");
String s="Killer Baby"; String s="Killer Baby";
OS::get_singleton()->print("\tsubstr(3,4) of \"%ls\" is \"%ls\"\n",s.c_str(),s.substr(3,4).c_str()); OS::get_singleton()->print("\tsubstr(3,4) of \"%ls\" is \"%ls\"\n",s.c_str(),s.substr(3,4).c_str());
return (s.substr(3,4)=="ler "); return (s.substr(3,4)=="ler ");
} }
bool test_16() { bool test_16() {
OS::get_singleton()->print("\n\nTest 16: find\n"); OS::get_singleton()->print("\n\nTest 16: find\n");
String s="Pretty Woman"; String s="Pretty Woman";
OS::get_singleton()->print("\tString: %ls\n",s.c_str()); OS::get_singleton()->print("\tString: %ls\n",s.c_str());
OS::get_singleton()->print("\t\"tty\" is at %i pos.\n",s.find("tty")); OS::get_singleton()->print("\t\"tty\" is at %i pos.\n",s.find("tty"));
OS::get_singleton()->print("\t\"Revenge of the Monster Truck\" is at %i pos.\n",s.find("Revenge of the Monster Truck")); OS::get_singleton()->print("\t\"Revenge of the Monster Truck\" is at %i pos.\n",s.find("Revenge of the Monster Truck"));
if (s.find("tty")!=3) if (s.find("tty")!=3)
return false; return false;
if (s.find("Revenge of the Monster Truck")!=-1) if (s.find("Revenge of the Monster Truck")!=-1)
return false; return false;
return true; return true;
} }
bool test_17() { bool test_17() {
OS::get_singleton()->print("\n\nTest 17: find no case\n"); OS::get_singleton()->print("\n\nTest 17: find no case\n");
String s="Pretty Whale"; String s="Pretty Whale";
OS::get_singleton()->print("\tString: %ls\n",s.c_str()); OS::get_singleton()->print("\tString: %ls\n",s.c_str());
OS::get_singleton()->print("\t\"WHA\" is at %i pos.\n",s.findn("WHA")); OS::get_singleton()->print("\t\"WHA\" is at %i pos.\n",s.findn("WHA"));
OS::get_singleton()->print("\t\"Revenge of the Monster SawFish\" is at %i pos.\n",s.findn("Revenge of the Monster Truck")); OS::get_singleton()->print("\t\"Revenge of the Monster SawFish\" is at %i pos.\n",s.findn("Revenge of the Monster Truck"));
if (s.findn("WHA")!=7) if (s.findn("WHA")!=7)
return false; return false;
if (s.findn("Revenge of the Monster SawFish")!=-1) if (s.findn("Revenge of the Monster SawFish")!=-1)
return false; return false;
return true; return true;
} }
bool test_18() { bool test_18() {
OS::get_singleton()->print("\n\nTest 18: find no case\n"); OS::get_singleton()->print("\n\nTest 18: find no case\n");
String s="Pretty Whale"; String s="Pretty Whale";
OS::get_singleton()->print("\tString: %ls\n",s.c_str()); OS::get_singleton()->print("\tString: %ls\n",s.c_str());
OS::get_singleton()->print("\t\"WHA\" is at %i pos.\n",s.findn("WHA")); OS::get_singleton()->print("\t\"WHA\" is at %i pos.\n",s.findn("WHA"));
OS::get_singleton()->print("\t\"Revenge of the Monster SawFish\" is at %i pos.\n",s.findn("Revenge of the Monster Truck")); OS::get_singleton()->print("\t\"Revenge of the Monster SawFish\" is at %i pos.\n",s.findn("Revenge of the Monster Truck"));
if (s.findn("WHA")!=7) if (s.findn("WHA")!=7)
return false; return false;
if (s.findn("Revenge of the Monster SawFish")!=-1) if (s.findn("Revenge of the Monster SawFish")!=-1)
return false; return false;
return true; return true;
} }
bool test_19() { bool test_19() {
OS::get_singleton()->print("\n\nTest 19: Search & replace\n"); OS::get_singleton()->print("\n\nTest 19: Search & replace\n");
String s="Happy Birthday, Anna!"; String s="Happy Birthday, Anna!";
OS::get_singleton()->print("\tString: %ls\n",s.c_str()); OS::get_singleton()->print("\tString: %ls\n",s.c_str());
s=s.replace("Birthday","Halloween"); s=s.replace("Birthday","Halloween");
OS::get_singleton()->print("\tReplaced Birthday/Halloween: %ls.\n",s.c_str()); OS::get_singleton()->print("\tReplaced Birthday/Halloween: %ls.\n",s.c_str());
return (s=="Happy Halloween, Anna!"); return (s=="Happy Halloween, Anna!");
} }
bool test_20() { bool test_20() {
OS::get_singleton()->print("\n\nTest 20: Insertion\n"); OS::get_singleton()->print("\n\nTest 20: Insertion\n");
String s="Who is Frederic?"; String s="Who is Frederic?";
OS::get_singleton()->print("\tString: %ls\n",s.c_str()); OS::get_singleton()->print("\tString: %ls\n",s.c_str());
s=s.insert( s.find("?")," Chopin" ); s=s.insert( s.find("?")," Chopin" );
OS::get_singleton()->print("\tInserted Chopin: %ls.\n",s.c_str()); OS::get_singleton()->print("\tInserted Chopin: %ls.\n",s.c_str());
return (s=="Who is Frederic Chopin?"); return (s=="Who is Frederic Chopin?");
} }
bool test_21() { bool test_21() {
OS::get_singleton()->print("\n\nTest 21: Number -> String\n"); OS::get_singleton()->print("\n\nTest 21: Number -> String\n");
OS::get_singleton()->print("\tPi is %f\n",33.141593); OS::get_singleton()->print("\tPi is %f\n",33.141593);
OS::get_singleton()->print("\tPi String is %ls\n",String::num(3.141593).c_str()); OS::get_singleton()->print("\tPi String is %ls\n",String::num(3.141593).c_str());
return String::num(3.141593)=="3.141593"; return String::num(3.141593)=="3.141593";
} }
bool test_22() { bool test_22() {
OS::get_singleton()->print("\n\nTest 22: String -> Int\n"); OS::get_singleton()->print("\n\nTest 22: String -> Int\n");
static const char* nums[4]={ "1237461283", "- 22", "0", " - 1123412" }; static const char* nums[4]={ "1237461283", "- 22", "0", " - 1123412" };
static const int num[4]={ 1237461283, -22, 0, -1123412 }; static const int num[4]={ 1237461283, -22, 0, -1123412 };
for (int i=0;i<4;i++) { for (int i=0;i<4;i++) {
OS::get_singleton()->print("\tString: \"%s\" as Int is %i\n",nums[i],String(nums[i]).to_int()); OS::get_singleton()->print("\tString: \"%s\" as Int is %i\n",nums[i],String(nums[i]).to_int());
if (String(nums[i]).to_int()!=num[i]) if (String(nums[i]).to_int()!=num[i])
return false; return false;
} }
return true; return true;
} }
bool test_23() { bool test_23() {
OS::get_singleton()->print("\n\nTest 23: String -> Float\n"); OS::get_singleton()->print("\n\nTest 23: String -> Float\n");
static const char* nums[4]={ "-12348298412.2", "0.05", "2.0002", " -0.0001" }; static const char* nums[4]={ "-12348298412.2", "0.05", "2.0002", " -0.0001" };
static const double num[4]={ -12348298412.2, 0.05, 2.0002, -0.0001 }; static const double num[4]={ -12348298412.2, 0.05, 2.0002, -0.0001 };
for (int i=0;i<4;i++) { for (int i=0;i<4;i++) {
OS::get_singleton()->print("\tString: \"%s\" as Float is %f\n",nums[i],String(nums[i]).to_double()); OS::get_singleton()->print("\tString: \"%s\" as Float is %f\n",nums[i],String(nums[i]).to_double());
if ( ABS(String(nums[i]).to_double()-num[i])>0.00001) if ( ABS(String(nums[i]).to_double()-num[i])>0.00001)
return false; return false;
} }
return true; return true;
} }
bool test_24() { bool test_24() {
OS::get_singleton()->print("\n\nTest 24: Slicing\n"); OS::get_singleton()->print("\n\nTest 24: Slicing\n");
String s="Mars,Jupiter,Saturn,Uranus"; String s="Mars,Jupiter,Saturn,Uranus";
const char*slices[4]={"Mars","Jupiter","Saturn","Uranus"}; const char*slices[4]={"Mars","Jupiter","Saturn","Uranus"};
OS::get_singleton()->print("\tSlicing \"%ls\" by \"%s\"..\n",s.c_str(),","); OS::get_singleton()->print("\tSlicing \"%ls\" by \"%s\"..\n",s.c_str(),",");
for (int i=0;i<s.get_slice_count(",");i++) { for (int i=0;i<s.get_slice_count(",");i++) {
OS::get_singleton()->print("\t\t%i- %ls\n",i+1,s.get_slice(",",i).c_str()); OS::get_singleton()->print("\t\t%i- %ls\n",i+1,s.get_slice(",",i).c_str());
if (s.get_slice(",",i)!=slices[i]) if (s.get_slice(",",i)!=slices[i])
return false; return false;
} }
return true; return true;
} }
bool test_25() { bool test_25() {
OS::get_singleton()->print("\n\nTest 25: Erasing\n"); OS::get_singleton()->print("\n\nTest 25: Erasing\n");
String s="Josephine is such a cute girl!"; String s="Josephine is such a cute girl!";
OS::get_singleton()->print("\tString: %ls\n",s.c_str()); OS::get_singleton()->print("\tString: %ls\n",s.c_str());
OS::get_singleton()->print("\tRemoving \"cute\"\n"); OS::get_singleton()->print("\tRemoving \"cute\"\n");
s.erase(s.find("cute "),String("cute ").length()); s.erase(s.find("cute "),String("cute ").length());
OS::get_singleton()->print("\tResult: %ls\n",s.c_str()); OS::get_singleton()->print("\tResult: %ls\n",s.c_str());
return (s=="Josephine is such a girl!"); return (s=="Josephine is such a girl!");
} }
bool test_26() { bool test_26() {
@ -516,7 +516,7 @@ bool test_28() {
String format, output; String format, output;
Array args; Array args;
bool error; bool error;
// %% // %%
format = "fish %% frog"; format = "fish %% frog";
args.clear(); args.clear();
@ -846,7 +846,7 @@ bool test_28() {
typedef bool (*TestFunc)(void); typedef bool (*TestFunc)(void);
TestFunc test_funcs[] = { TestFunc test_funcs[] = {
test_1, test_1,
test_2, test_2,
test_3, test_3,
@ -876,18 +876,18 @@ TestFunc test_funcs[] = {
test_27, test_27,
test_28, test_28,
0 0
}; };
MainLoop* test() { MainLoop* test() {
/** A character length != wchar_t may be forced, so the tests wont work */ /** A character length != wchar_t may be forced, so the tests wont work */
ERR_FAIL_COND_V( sizeof(CharType) != sizeof(wchar_t), NULL ); ERR_FAIL_COND_V( sizeof(CharType) != sizeof(wchar_t), NULL );
int count=0; int count=0;
int passed=0; int passed=0;
while(true) { while(true) {
if (!test_funcs[count]) if (!test_funcs[count])
break; break;
@ -895,17 +895,17 @@ MainLoop* test() {
if (pass) if (pass)
passed++; passed++;
OS::get_singleton()->print("\t%s\n",pass?"PASS":"FAILED"); OS::get_singleton()->print("\t%s\n",pass?"PASS":"FAILED");
count++; count++;
} }
OS::get_singleton()->print("\n\n\n"); OS::get_singleton()->print("\n\n\n");
OS::get_singleton()->print("*************\n"); OS::get_singleton()->print("*************\n");
OS::get_singleton()->print("***TOTALS!***\n"); OS::get_singleton()->print("***TOTALS!***\n");
OS::get_singleton()->print("*************\n"); OS::get_singleton()->print("*************\n");
OS::get_singleton()->print("Passed %i of %i tests\n", passed, count); OS::get_singleton()->print("Passed %i of %i tests\n", passed, count);
return NULL; return NULL;
} }

View File

@ -1307,7 +1307,12 @@ DVector<uint8_t> _File::get_buffer(int p_length) const{
String _File::get_as_text() const { String _File::get_as_text() const {
ERR_FAIL_COND_V(!f, String());
String text; String text;
size_t original_pos = f->get_pos();
f->seek(0);
String l = get_line(); String l = get_line();
while(!eof_reached()) { while(!eof_reached()) {
text+=l+"\n"; text+=l+"\n";
@ -1315,6 +1320,8 @@ String _File::get_as_text() const {
} }
text+=l; text+=l;
f->seek(original_pos);
return text; return text;
@ -1669,15 +1676,15 @@ void _Directory::_bind_methods() {
ObjectTypeDB::bind_method(_MD("get_drive","idx"),&_Directory::get_drive); ObjectTypeDB::bind_method(_MD("get_drive","idx"),&_Directory::get_drive);
ObjectTypeDB::bind_method(_MD("change_dir:Error","todir"),&_Directory::change_dir); ObjectTypeDB::bind_method(_MD("change_dir:Error","todir"),&_Directory::change_dir);
ObjectTypeDB::bind_method(_MD("get_current_dir"),&_Directory::get_current_dir); ObjectTypeDB::bind_method(_MD("get_current_dir"),&_Directory::get_current_dir);
ObjectTypeDB::bind_method(_MD("make_dir:Error","name"),&_Directory::make_dir); ObjectTypeDB::bind_method(_MD("make_dir:Error","path"),&_Directory::make_dir);
ObjectTypeDB::bind_method(_MD("make_dir_recursive:Error","name"),&_Directory::make_dir_recursive); ObjectTypeDB::bind_method(_MD("make_dir_recursive:Error","path"),&_Directory::make_dir_recursive);
ObjectTypeDB::bind_method(_MD("file_exists","name"),&_Directory::file_exists); ObjectTypeDB::bind_method(_MD("file_exists","path"),&_Directory::file_exists);
ObjectTypeDB::bind_method(_MD("dir_exists","name"),&_Directory::dir_exists); ObjectTypeDB::bind_method(_MD("dir_exists","path"),&_Directory::dir_exists);
// ObjectTypeDB::bind_method(_MD("get_modified_time","file"),&_Directory::get_modified_time); // ObjectTypeDB::bind_method(_MD("get_modified_time","file"),&_Directory::get_modified_time);
ObjectTypeDB::bind_method(_MD("get_space_left"),&_Directory::get_space_left); ObjectTypeDB::bind_method(_MD("get_space_left"),&_Directory::get_space_left);
ObjectTypeDB::bind_method(_MD("copy:Error","from","to"),&_Directory::copy); ObjectTypeDB::bind_method(_MD("copy:Error","from","to"),&_Directory::copy);
ObjectTypeDB::bind_method(_MD("rename:Error","from","to"),&_Directory::rename); ObjectTypeDB::bind_method(_MD("rename:Error","from","to"),&_Directory::rename);
ObjectTypeDB::bind_method(_MD("remove:Error","file"),&_Directory::remove); ObjectTypeDB::bind_method(_MD("remove:Error","path"),&_Directory::remove);
} }

View File

@ -75,11 +75,11 @@ float Color::get_h() const {
h = 2 + ( b - r ) / delta; // between cyan & yellow h = 2 + ( b - r ) / delta; // between cyan & yellow
else else
h = 4 + ( r - g ) / delta; // between magenta & cyan h = 4 + ( r - g ) / delta; // between magenta & cyan
h/=6.0; h/=6.0;
if (h<0) if (h<0)
h+=1.0; h+=1.0;
return h; return h;
} }
@ -119,7 +119,7 @@ void Color::set_hsv(float p_h, float p_s, float p_v, float p_alpha) {
p_h *=6.0; p_h *=6.0;
p_h = Math::fmod(p_h,6); p_h = Math::fmod(p_h,6);
i = Math::floor( p_h ); i = Math::floor( p_h );
f = p_h - i; f = p_h - i;
p = p_v * ( 1 - p_s ); p = p_v * ( 1 - p_s );
q = p_v * ( 1 - p_s * f ); q = p_v * ( 1 - p_s * f );
@ -136,7 +136,7 @@ void Color::set_hsv(float p_h, float p_s, float p_v, float p_alpha) {
g = p_v; g = p_v;
b = p; b = p;
break; break;
case 2: case 2:
r = p; r = p;
g = p_v; g = p_v;
b = t; b = t;
@ -162,8 +162,8 @@ void Color::set_hsv(float p_h, float p_s, float p_v, float p_alpha) {
void Color::invert() { void Color::invert() {
r=1.0-r; r=1.0-r;
g=1.0-g; g=1.0-g;
b=1.0-b; b=1.0-b;
} }
void Color::contrast() { void Color::contrast() {
@ -368,7 +368,7 @@ String Color::to_html(bool p_alpha) const {
float Color::gray() const { float Color::gray() const {
return (r+g+b)/3.0; return (r+g+b)/3.0;
} }
Color::operator String() const { Color::operator String() const {

View File

@ -37,13 +37,13 @@
struct Color { struct Color {
union { union {
struct { struct {
float r; float r;
float g; float g;
float b; float b;
float a; float a;
}; };
float components[4]; float components[4];
}; };
@ -58,28 +58,28 @@ struct Color {
float get_v() const; float get_v() const;
void set_hsv(float p_h, float p_s, float p_v, float p_alpha=1.0); void set_hsv(float p_h, float p_s, float p_v, float p_alpha=1.0);
_FORCE_INLINE_ float& operator[](int idx) { _FORCE_INLINE_ float& operator[](int idx) {
return components[idx]; return components[idx];
} }
_FORCE_INLINE_ const float& operator[](int idx) const { _FORCE_INLINE_ const float& operator[](int idx) const {
return components[idx]; return components[idx];
} }
void invert(); void invert();
void contrast(); void contrast();
Color inverted() const; Color inverted() const;
Color contrasted() const; Color contrasted() const;
_FORCE_INLINE_ Color linear_interpolate(const Color& p_b, float p_t) const { _FORCE_INLINE_ Color linear_interpolate(const Color& p_b, float p_t) const {
Color res=*this; Color res=*this;
res.r+= (p_t * (p_b.r-r)); res.r+= (p_t * (p_b.r-r));
res.g+= (p_t * (p_b.g-g)); res.g+= (p_t * (p_b.g-g));
res.b+= (p_t * (p_b.b-b)); res.b+= (p_t * (p_b.b-b));
res.a+= (p_t * (p_b.a-a)); res.a+= (p_t * (p_b.a-a));
return res; return res;
} }
_FORCE_INLINE_ Color blend(const Color& p_over) const { _FORCE_INLINE_ Color blend(const Color& p_over) const {

View File

@ -76,7 +76,7 @@ CommandQueueMT::SyncSemaphore* CommandQueueMT::_alloc_sync_sem() {
CommandQueueMT::CommandQueueMT(bool p_sync){ CommandQueueMT::CommandQueueMT(bool p_sync){
read_ptr=0; read_ptr=0;
write_ptr=0; write_ptr=0;
mutex = Mutex::create(); mutex = Mutex::create();
for(int i=0;i<SYNC_SEMAPHORES;i++) { for(int i=0;i<SYNC_SEMAPHORES;i++) {

View File

@ -47,69 +47,69 @@ class CommandQueueMT {
}; };
struct CommandBase { struct CommandBase {
virtual void call()=0; virtual void call()=0;
virtual ~CommandBase() {}; virtual ~CommandBase() {};
}; };
template<class T,class M> template<class T,class M>
struct Command0 : public CommandBase { struct Command0 : public CommandBase {
T*instance; T*instance;
M method; M method;
virtual void call() { (instance->*method)(); } virtual void call() { (instance->*method)(); }
}; };
template<class T,class M,class P1> template<class T,class M,class P1>
struct Command1 : public CommandBase { struct Command1 : public CommandBase {
T*instance; T*instance;
M method; M method;
typename GetSimpleTypeT<P1>::type_t p1; typename GetSimpleTypeT<P1>::type_t p1;
virtual void call() { (instance->*method)(p1); } virtual void call() { (instance->*method)(p1); }
}; };
template<class T,class M,class P1,class P2> template<class T,class M,class P1,class P2>
struct Command2 : public CommandBase { struct Command2 : public CommandBase {
T*instance; T*instance;
M method; M method;
typename GetSimpleTypeT<P1>::type_t p1; typename GetSimpleTypeT<P1>::type_t p1;
typename GetSimpleTypeT<P2>::type_t p2; typename GetSimpleTypeT<P2>::type_t p2;
virtual void call() { (instance->*method)(p1,p2); } virtual void call() { (instance->*method)(p1,p2); }
}; };
template<class T,class M,class P1,class P2,class P3> template<class T,class M,class P1,class P2,class P3>
struct Command3 : public CommandBase { struct Command3 : public CommandBase {
T*instance; T*instance;
M method; M method;
typename GetSimpleTypeT<P1>::type_t p1; typename GetSimpleTypeT<P1>::type_t p1;
typename GetSimpleTypeT<P2>::type_t p2; typename GetSimpleTypeT<P2>::type_t p2;
typename GetSimpleTypeT<P3>::type_t p3; typename GetSimpleTypeT<P3>::type_t p3;
virtual void call() { (instance->*method)(p1,p2,p3); } virtual void call() { (instance->*method)(p1,p2,p3); }
}; };
template<class T,class M,class P1,class P2,class P3,class P4> template<class T,class M,class P1,class P2,class P3,class P4>
struct Command4 : public CommandBase { struct Command4 : public CommandBase {
T*instance; T*instance;
M method; M method;
typename GetSimpleTypeT<P1>::type_t p1; typename GetSimpleTypeT<P1>::type_t p1;
typename GetSimpleTypeT<P2>::type_t p2; typename GetSimpleTypeT<P2>::type_t p2;
typename GetSimpleTypeT<P3>::type_t p3; typename GetSimpleTypeT<P3>::type_t p3;
typename GetSimpleTypeT<P4>::type_t p4; typename GetSimpleTypeT<P4>::type_t p4;
virtual void call() { (instance->*method)(p1,p2,p3,p4); } virtual void call() { (instance->*method)(p1,p2,p3,p4); }
}; };
template<class T,class M,class P1,class P2,class P3,class P4,class P5> template<class T,class M,class P1,class P2,class P3,class P4,class P5>
struct Command5 : public CommandBase { struct Command5 : public CommandBase {
T*instance; T*instance;
M method; M method;
typename GetSimpleTypeT<P1>::type_t p1; typename GetSimpleTypeT<P1>::type_t p1;
@ -117,13 +117,13 @@ class CommandQueueMT {
typename GetSimpleTypeT<P3>::type_t p3; typename GetSimpleTypeT<P3>::type_t p3;
typename GetSimpleTypeT<P4>::type_t p4; typename GetSimpleTypeT<P4>::type_t p4;
typename GetSimpleTypeT<P5>::type_t p5; typename GetSimpleTypeT<P5>::type_t p5;
virtual void call() { (instance->*method)(p1,p2,p3,p4,p5); } virtual void call() { (instance->*method)(p1,p2,p3,p4,p5); }
}; };
template<class T,class M,class P1,class P2,class P3,class P4,class P5,class P6> template<class T,class M,class P1,class P2,class P3,class P4,class P5,class P6>
struct Command6 : public CommandBase { struct Command6 : public CommandBase {
T*instance; T*instance;
M method; M method;
typename GetSimpleTypeT<P1>::type_t p1; typename GetSimpleTypeT<P1>::type_t p1;
@ -132,13 +132,13 @@ class CommandQueueMT {
typename GetSimpleTypeT<P4>::type_t p4; typename GetSimpleTypeT<P4>::type_t p4;
typename GetSimpleTypeT<P5>::type_t p5; typename GetSimpleTypeT<P5>::type_t p5;
typename GetSimpleTypeT<P6>::type_t p6; typename GetSimpleTypeT<P6>::type_t p6;
virtual void call() { (instance->*method)(p1,p2,p3,p4,p5,p6); } virtual void call() { (instance->*method)(p1,p2,p3,p4,p5,p6); }
}; };
template<class T,class M,class P1,class P2,class P3,class P4,class P5,class P6,class P7> template<class T,class M,class P1,class P2,class P3,class P4,class P5,class P6,class P7>
struct Command7 : public CommandBase { struct Command7 : public CommandBase {
T*instance; T*instance;
M method; M method;
typename GetSimpleTypeT<P1>::type_t p1; typename GetSimpleTypeT<P1>::type_t p1;
@ -148,12 +148,12 @@ class CommandQueueMT {
typename GetSimpleTypeT<P5>::type_t p5; typename GetSimpleTypeT<P5>::type_t p5;
typename GetSimpleTypeT<P6>::type_t p6; typename GetSimpleTypeT<P6>::type_t p6;
typename GetSimpleTypeT<P7>::type_t p7; typename GetSimpleTypeT<P7>::type_t p7;
virtual void call() { (instance->*method)(p1,p2,p3,p4,p5,p6,p7); } virtual void call() { (instance->*method)(p1,p2,p3,p4,p5,p6,p7); }
}; };
/* comands that return */ /* comands that return */
template<class T,class M,class R> template<class T,class M,class R>
struct CommandRet0 : public CommandBase { struct CommandRet0 : public CommandBase {
@ -161,38 +161,38 @@ class CommandQueueMT {
M method; M method;
R* ret; R* ret;
SyncSemaphore *sync; SyncSemaphore *sync;
virtual void call() { *ret = (instance->*method)(); sync->sem->post(); sync->in_use=false; ; } virtual void call() { *ret = (instance->*method)(); sync->sem->post(); sync->in_use=false; ; }
}; };
template<class T,class M,class P1,class R> template<class T,class M,class P1,class R>
struct CommandRet1 : public CommandBase { struct CommandRet1 : public CommandBase {
T*instance; T*instance;
M method; M method;
typename GetSimpleTypeT<P1>::type_t p1; typename GetSimpleTypeT<P1>::type_t p1;
R* ret; R* ret;
SyncSemaphore *sync; SyncSemaphore *sync;
virtual void call() { *ret = (instance->*method)(p1); sync->sem->post(); sync->in_use=false; } virtual void call() { *ret = (instance->*method)(p1); sync->sem->post(); sync->in_use=false; }
}; };
template<class T,class M,class P1,class P2,class R> template<class T,class M,class P1,class P2,class R>
struct CommandRet2 : public CommandBase { struct CommandRet2 : public CommandBase {
T*instance; T*instance;
M method; M method;
typename GetSimpleTypeT<P1>::type_t p1; typename GetSimpleTypeT<P1>::type_t p1;
typename GetSimpleTypeT<P2>::type_t p2; typename GetSimpleTypeT<P2>::type_t p2;
R* ret; R* ret;
SyncSemaphore *sync; SyncSemaphore *sync;
virtual void call() { *ret = (instance->*method)(p1,p2); sync->sem->post(); sync->in_use=false; ; } virtual void call() { *ret = (instance->*method)(p1,p2); sync->sem->post(); sync->in_use=false; ; }
}; };
template<class T,class M,class P1,class P2,class P3,class R> template<class T,class M,class P1,class P2,class P3,class R>
struct CommandRet3 : public CommandBase { struct CommandRet3 : public CommandBase {
T*instance; T*instance;
M method; M method;
typename GetSimpleTypeT<P1>::type_t p1; typename GetSimpleTypeT<P1>::type_t p1;
@ -200,13 +200,13 @@ class CommandQueueMT {
typename GetSimpleTypeT<P3>::type_t p3; typename GetSimpleTypeT<P3>::type_t p3;
R* ret; R* ret;
SyncSemaphore *sync; SyncSemaphore *sync;
virtual void call() { *ret = (instance->*method)(p1,p2,p3); sync->sem->post(); sync->in_use=false; ; } virtual void call() { *ret = (instance->*method)(p1,p2,p3); sync->sem->post(); sync->in_use=false; ; }
}; };
template<class T,class M,class P1,class P2,class P3,class P4,class R> template<class T,class M,class P1,class P2,class P3,class P4,class R>
struct CommandRet4 : public CommandBase { struct CommandRet4 : public CommandBase {
T*instance; T*instance;
M method; M method;
typename GetSimpleTypeT<P1>::type_t p1; typename GetSimpleTypeT<P1>::type_t p1;
@ -215,13 +215,13 @@ class CommandQueueMT {
typename GetSimpleTypeT<P4>::type_t p4; typename GetSimpleTypeT<P4>::type_t p4;
R* ret; R* ret;
SyncSemaphore *sync; SyncSemaphore *sync;
virtual void call() { *ret = (instance->*method)(p1,p2,p3,p4); sync->sem->post(); sync->in_use=false; ; } virtual void call() { *ret = (instance->*method)(p1,p2,p3,p4); sync->sem->post(); sync->in_use=false; ; }
}; };
template<class T,class M,class P1,class P2,class P3,class P4,class P5,class R> template<class T,class M,class P1,class P2,class P3,class P4,class P5,class R>
struct CommandRet5 : public CommandBase { struct CommandRet5 : public CommandBase {
T*instance; T*instance;
M method; M method;
typename GetSimpleTypeT<P1>::type_t p1; typename GetSimpleTypeT<P1>::type_t p1;
@ -231,13 +231,13 @@ class CommandQueueMT {
typename GetSimpleTypeT<P5>::type_t p5; typename GetSimpleTypeT<P5>::type_t p5;
R* ret; R* ret;
SyncSemaphore *sync; SyncSemaphore *sync;
virtual void call() { *ret = (instance->*method)(p1,p2,p3,p4,p5); sync->sem->post(); sync->in_use=false; ; } virtual void call() { *ret = (instance->*method)(p1,p2,p3,p4,p5); sync->sem->post(); sync->in_use=false; ; }
}; };
template<class T,class M,class P1,class P2,class P3,class P4,class P5,class P6,class R> template<class T,class M,class P1,class P2,class P3,class P4,class P5,class P6,class R>
struct CommandRet6 : public CommandBase { struct CommandRet6 : public CommandBase {
T*instance; T*instance;
M method; M method;
typename GetSimpleTypeT<P1>::type_t p1; typename GetSimpleTypeT<P1>::type_t p1;
@ -248,13 +248,13 @@ class CommandQueueMT {
typename GetSimpleTypeT<P6>::type_t p6; typename GetSimpleTypeT<P6>::type_t p6;
R* ret; R* ret;
SyncSemaphore *sync; SyncSemaphore *sync;
virtual void call() { *ret = (instance->*method)(p1,p2,p3,p4,p5,p6); sync->sem->post(); sync->in_use=false; ; } virtual void call() { *ret = (instance->*method)(p1,p2,p3,p4,p5,p6); sync->sem->post(); sync->in_use=false; ; }
}; };
template<class T,class M,class P1,class P2,class P3,class P4,class P5,class P6,class P7,class R> template<class T,class M,class P1,class P2,class P3,class P4,class P5,class P6,class P7,class R>
struct CommandRet7 : public CommandBase { struct CommandRet7 : public CommandBase {
T*instance; T*instance;
M method; M method;
typename GetSimpleTypeT<P1>::type_t p1; typename GetSimpleTypeT<P1>::type_t p1;
@ -266,9 +266,9 @@ class CommandQueueMT {
typename GetSimpleTypeT<P7>::type_t p7; typename GetSimpleTypeT<P7>::type_t p7;
R* ret; R* ret;
SyncSemaphore *sync; SyncSemaphore *sync;
virtual void call() { *ret = (instance->*method)(p1,p2,p3,p4,p5,p6,p7); sync->sem->post(); sync->in_use=false; ; } virtual void call() { *ret = (instance->*method)(p1,p2,p3,p4,p5,p6,p7); sync->sem->post(); sync->in_use=false; ; }
}; };
/** commands that don't return but sync */ /** commands that don't return but sync */
@ -392,7 +392,7 @@ class CommandQueueMT {
/***** BASE *******/ /***** BASE *******/
enum { enum {
COMMAND_MEM_SIZE_KB=256, COMMAND_MEM_SIZE_KB=256,
COMMAND_MEM_SIZE=COMMAND_MEM_SIZE_KB*1024, COMMAND_MEM_SIZE=COMMAND_MEM_SIZE_KB*1024,
SYNC_SEMAPHORES=8 SYNC_SEMAPHORES=8
@ -405,30 +405,30 @@ class CommandQueueMT {
SyncSemaphore sync_sems[SYNC_SEMAPHORES]; SyncSemaphore sync_sems[SYNC_SEMAPHORES];
Mutex *mutex; Mutex *mutex;
Semaphore *sync; Semaphore *sync;
template<class T> template<class T>
T* allocate() { T* allocate() {
// alloc size is size+T+safeguard // alloc size is size+T+safeguard
uint32_t alloc_size=sizeof(T)+sizeof(uint32_t); uint32_t alloc_size=sizeof(T)+sizeof(uint32_t);
tryagain: tryagain:
if (write_ptr < read_ptr) { if (write_ptr < read_ptr) {
// behind read_ptr, check that there is room // behind read_ptr, check that there is room
if ( (read_ptr-write_ptr) <= alloc_size ) if ( (read_ptr-write_ptr) <= alloc_size )
return NULL; return NULL;
} else if (write_ptr >= read_ptr) { } else if (write_ptr >= read_ptr) {
// ahead of read_ptr, check that there is room // ahead of read_ptr, check that there is room
if ( (COMMAND_MEM_SIZE-write_ptr) < alloc_size+4 ) { if ( (COMMAND_MEM_SIZE-write_ptr) < alloc_size+4 ) {
// no room at the end, wrap down; // no room at the end, wrap down;
if (read_ptr==0) // dont want write_ptr to become read_ptr if (read_ptr==0) // dont want write_ptr to become read_ptr
return NULL; return NULL;
// if this happens, it's a bug // if this happens, it's a bug
ERR_FAIL_COND_V( (COMMAND_MEM_SIZE-write_ptr) < sizeof(uint32_t), NULL ); ERR_FAIL_COND_V( (COMMAND_MEM_SIZE-write_ptr) < sizeof(uint32_t), NULL );
// zero means, wrap to begining // zero means, wrap to begining
@ -447,147 +447,147 @@ class CommandQueueMT {
T* cmd = memnew_placement( &command_mem[write_ptr], T ); T* cmd = memnew_placement( &command_mem[write_ptr], T );
write_ptr+=sizeof(T); write_ptr+=sizeof(T);
return cmd; return cmd;
} }
template<class T> template<class T>
T* allocate_and_lock() { T* allocate_and_lock() {
lock(); lock();
T* ret; T* ret;
while ( (ret=allocate<T>())==NULL ) { while ( (ret=allocate<T>())==NULL ) {
unlock(); unlock();
// sleep a little until fetch happened and some room is made // sleep a little until fetch happened and some room is made
wait_for_flush(); wait_for_flush();
lock(); lock();
} }
return ret; return ret;
} }
bool flush_one() { bool flush_one() {
tryagain: tryagain:
// tried to read an empty queue // tried to read an empty queue
if (read_ptr == write_ptr ) if (read_ptr == write_ptr )
return false; return false;
uint32_t size = *(uint32_t*)( &command_mem[read_ptr] ); uint32_t size = *(uint32_t*)( &command_mem[read_ptr] );
if (size==0) { if (size==0) {
//end of ringbuffer, wrap //end of ringbuffer, wrap
read_ptr=0; read_ptr=0;
goto tryagain; goto tryagain;
} }
read_ptr+=sizeof(uint32_t); read_ptr+=sizeof(uint32_t);
CommandBase *cmd = reinterpret_cast<CommandBase*>( &command_mem[read_ptr] ); CommandBase *cmd = reinterpret_cast<CommandBase*>( &command_mem[read_ptr] );
cmd->call(); cmd->call();
cmd->~CommandBase(); cmd->~CommandBase();
read_ptr+=size; read_ptr+=size;
return true; return true;
} }
void lock(); void lock();
void unlock(); void unlock();
void wait_for_flush(); void wait_for_flush();
SyncSemaphore* _alloc_sync_sem(); SyncSemaphore* _alloc_sync_sem();
public: public:
/* NORMAL PUSH COMMANDS */ /* NORMAL PUSH COMMANDS */
template<class T, class M> template<class T, class M>
void push( T * p_instance, M p_method ) { void push( T * p_instance, M p_method ) {
Command0<T,M> * cmd = allocate_and_lock< Command0<T,M> >(); Command0<T,M> * cmd = allocate_and_lock< Command0<T,M> >();
cmd->instance=p_instance; cmd->instance=p_instance;
cmd->method=p_method; cmd->method=p_method;
unlock(); unlock();
if (sync) sync->post(); if (sync) sync->post();
} }
template<class T, class M, class P1> template<class T, class M, class P1>
void push( T * p_instance, M p_method, P1 p1 ) { void push( T * p_instance, M p_method, P1 p1 ) {
Command1<T,M,P1> * cmd = allocate_and_lock< Command1<T,M,P1> >(); Command1<T,M,P1> * cmd = allocate_and_lock< Command1<T,M,P1> >();
cmd->instance=p_instance; cmd->instance=p_instance;
cmd->method=p_method; cmd->method=p_method;
cmd->p1=p1; cmd->p1=p1;
unlock(); unlock();
if (sync) sync->post(); if (sync) sync->post();
} }
template<class T, class M, class P1, class P2> template<class T, class M, class P1, class P2>
void push( T * p_instance, M p_method, P1 p1, P2 p2 ) { void push( T * p_instance, M p_method, P1 p1, P2 p2 ) {
Command2<T,M,P1,P2> * cmd = allocate_and_lock< Command2<T,M,P1,P2> >(); Command2<T,M,P1,P2> * cmd = allocate_and_lock< Command2<T,M,P1,P2> >();
cmd->instance=p_instance; cmd->instance=p_instance;
cmd->method=p_method; cmd->method=p_method;
cmd->p1=p1; cmd->p1=p1;
cmd->p2=p2; cmd->p2=p2;
unlock(); unlock();
if (sync) sync->post(); if (sync) sync->post();
} }
template<class T, class M, class P1, class P2, class P3> template<class T, class M, class P1, class P2, class P3>
void push( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3 ) { void push( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3 ) {
Command3<T,M,P1,P2,P3> * cmd = allocate_and_lock< Command3<T,M,P1,P2,P3> >(); Command3<T,M,P1,P2,P3> * cmd = allocate_and_lock< Command3<T,M,P1,P2,P3> >();
cmd->instance=p_instance; cmd->instance=p_instance;
cmd->method=p_method; cmd->method=p_method;
cmd->p1=p1; cmd->p1=p1;
cmd->p2=p2; cmd->p2=p2;
cmd->p3=p3; cmd->p3=p3;
unlock(); unlock();
if (sync) sync->post(); if (sync) sync->post();
} }
template<class T, class M, class P1, class P2, class P3, class P4> template<class T, class M, class P1, class P2, class P3, class P4>
void push( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4 ) { void push( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4 ) {
Command4<T,M,P1,P2,P3,P4> * cmd = allocate_and_lock< Command4<T,M,P1,P2,P3,P4> >(); Command4<T,M,P1,P2,P3,P4> * cmd = allocate_and_lock< Command4<T,M,P1,P2,P3,P4> >();
cmd->instance=p_instance; cmd->instance=p_instance;
cmd->method=p_method; cmd->method=p_method;
cmd->p1=p1; cmd->p1=p1;
cmd->p2=p2; cmd->p2=p2;
cmd->p3=p3; cmd->p3=p3;
cmd->p4=p4; cmd->p4=p4;
unlock(); unlock();
if (sync) sync->post(); if (sync) sync->post();
} }
template<class T, class M, class P1, class P2, class P3, class P4, class P5> template<class T, class M, class P1, class P2, class P3, class P4, class P5>
void push( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5 ) { void push( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5 ) {
Command5<T,M,P1,P2,P3,P4,P5> * cmd = allocate_and_lock< Command5<T,M,P1,P2,P3,P4,P5> >(); Command5<T,M,P1,P2,P3,P4,P5> * cmd = allocate_and_lock< Command5<T,M,P1,P2,P3,P4,P5> >();
cmd->instance=p_instance; cmd->instance=p_instance;
cmd->method=p_method; cmd->method=p_method;
cmd->p1=p1; cmd->p1=p1;
@ -595,17 +595,17 @@ public:
cmd->p3=p3; cmd->p3=p3;
cmd->p4=p4; cmd->p4=p4;
cmd->p5=p5; cmd->p5=p5;
unlock(); unlock();
if (sync) sync->post(); if (sync) sync->post();
} }
template<class T, class M, class P1, class P2, class P3, class P4, class P5, class P6> template<class T, class M, class P1, class P2, class P3, class P4, class P5, class P6>
void push( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6 ) { void push( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6 ) {
Command6<T,M,P1,P2,P3,P4,P5,P6> * cmd = allocate_and_lock< Command6<T,M,P1,P2,P3,P4,P5,P6> >(); Command6<T,M,P1,P2,P3,P4,P5,P6> * cmd = allocate_and_lock< Command6<T,M,P1,P2,P3,P4,P5,P6> >();
cmd->instance=p_instance; cmd->instance=p_instance;
cmd->method=p_method; cmd->method=p_method;
cmd->p1=p1; cmd->p1=p1;
@ -614,17 +614,17 @@ public:
cmd->p4=p4; cmd->p4=p4;
cmd->p5=p5; cmd->p5=p5;
cmd->p6=p6; cmd->p6=p6;
unlock(); unlock();
if (sync) sync->post(); if (sync) sync->post();
} }
template<class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7> template<class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7>
void push( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7 ) { void push( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7 ) {
Command7<T,M,P1,P2,P3,P4,P5,P6,P7> * cmd = allocate_and_lock< Command7<T,M,P1,P2,P3,P4,P5,P6,P7> >(); Command7<T,M,P1,P2,P3,P4,P5,P6,P7> * cmd = allocate_and_lock< Command7<T,M,P1,P2,P3,P4,P5,P6,P7> >();
cmd->instance=p_instance; cmd->instance=p_instance;
cmd->method=p_method; cmd->method=p_method;
cmd->p1=p1; cmd->p1=p1;
@ -634,19 +634,19 @@ public:
cmd->p5=p5; cmd->p5=p5;
cmd->p6=p6; cmd->p6=p6;
cmd->p7=p7; cmd->p7=p7;
unlock(); unlock();
if (sync) sync->post(); if (sync) sync->post();
} }
/*** PUSH AND RET COMMANDS ***/ /*** PUSH AND RET COMMANDS ***/
template<class T, class M,class R> template<class T, class M,class R>
void push_and_ret( T * p_instance, M p_method, R* r_ret) { void push_and_ret( T * p_instance, M p_method, R* r_ret) {
CommandRet0<T,M,R> * cmd = allocate_and_lock< CommandRet0<T,M,R> >(); CommandRet0<T,M,R> * cmd = allocate_and_lock< CommandRet0<T,M,R> >();
cmd->instance=p_instance; cmd->instance=p_instance;
cmd->method=p_method; cmd->method=p_method;
cmd->ret=r_ret; cmd->ret=r_ret;
@ -654,34 +654,34 @@ public:
cmd->sync=ss; cmd->sync=ss;
unlock(); unlock();
if (sync) sync->post(); if (sync) sync->post();
ss->sem->wait(); ss->sem->wait();
} }
template<class T, class M, class P1,class R> template<class T, class M, class P1,class R>
void push_and_ret( T * p_instance, M p_method, P1 p1, R* r_ret) { void push_and_ret( T * p_instance, M p_method, P1 p1, R* r_ret) {
CommandRet1<T,M,P1,R> * cmd = allocate_and_lock< CommandRet1<T,M,P1,R> >(); CommandRet1<T,M,P1,R> * cmd = allocate_and_lock< CommandRet1<T,M,P1,R> >();
cmd->instance=p_instance; cmd->instance=p_instance;
cmd->method=p_method; cmd->method=p_method;
cmd->p1=p1; cmd->p1=p1;
cmd->ret=r_ret; cmd->ret=r_ret;
SyncSemaphore *ss=_alloc_sync_sem(); SyncSemaphore *ss=_alloc_sync_sem();
cmd->sync=ss; cmd->sync=ss;
unlock(); unlock();
if (sync) sync->post(); if (sync) sync->post();
ss->sem->wait(); ss->sem->wait();
} }
template<class T, class M, class P1, class P2,class R> template<class T, class M, class P1, class P2,class R>
void push_and_ret( T * p_instance, M p_method, P1 p1, P2 p2, R* r_ret) { void push_and_ret( T * p_instance, M p_method, P1 p1, P2 p2, R* r_ret) {
CommandRet2<T,M,P1,P2,R> * cmd = allocate_and_lock< CommandRet2<T,M,P1,P2,R> >(); CommandRet2<T,M,P1,P2,R> * cmd = allocate_and_lock< CommandRet2<T,M,P1,P2,R> >();
cmd->instance=p_instance; cmd->instance=p_instance;
cmd->method=p_method; cmd->method=p_method;
cmd->p1=p1; cmd->p1=p1;
@ -691,16 +691,16 @@ public:
cmd->sync=ss; cmd->sync=ss;
unlock(); unlock();
if (sync) sync->post(); if (sync) sync->post();
ss->sem->wait(); ss->sem->wait();
} }
template<class T, class M, class P1, class P2, class P3,class R> template<class T, class M, class P1, class P2, class P3,class R>
void push_and_ret( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, R* r_ret ) { void push_and_ret( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, R* r_ret ) {
CommandRet3<T,M,P1,P2,P3,R> * cmd = allocate_and_lock< CommandRet3<T,M,P1,P2,P3,R> >(); CommandRet3<T,M,P1,P2,P3,R> * cmd = allocate_and_lock< CommandRet3<T,M,P1,P2,P3,R> >();
cmd->instance=p_instance; cmd->instance=p_instance;
cmd->method=p_method; cmd->method=p_method;
cmd->p1=p1; cmd->p1=p1;
@ -711,16 +711,16 @@ public:
cmd->sync=ss; cmd->sync=ss;
unlock(); unlock();
if (sync) sync->post(); if (sync) sync->post();
ss->sem->wait(); ss->sem->wait();
} }
template<class T, class M, class P1, class P2, class P3, class P4,class R> template<class T, class M, class P1, class P2, class P3, class P4,class R>
void push_and_ret( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, R* r_ret ) { void push_and_ret( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, R* r_ret ) {
CommandRet4<T,M,P1,P2,P3,P4,R> * cmd = allocate_and_lock< CommandRet4<T,M,P1,P2,P3,P4,R> >(); CommandRet4<T,M,P1,P2,P3,P4,R> * cmd = allocate_and_lock< CommandRet4<T,M,P1,P2,P3,P4,R> >();
cmd->instance=p_instance; cmd->instance=p_instance;
cmd->method=p_method; cmd->method=p_method;
cmd->p1=p1; cmd->p1=p1;
@ -732,16 +732,16 @@ public:
cmd->sync=ss; cmd->sync=ss;
unlock(); unlock();
if (sync) sync->post(); if (sync) sync->post();
ss->sem->wait(); ss->sem->wait();
} }
template<class T, class M, class P1, class P2, class P3, class P4, class P5,class R> template<class T, class M, class P1, class P2, class P3, class P4, class P5,class R>
void push_and_ret( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, R* r_ret ) { void push_and_ret( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, R* r_ret ) {
CommandRet5<T,M,P1,P2,P3,P4,P5,R> * cmd = allocate_and_lock< CommandRet5<T,M,P1,P2,P3,P4,P5,R> >(); CommandRet5<T,M,P1,P2,P3,P4,P5,R> * cmd = allocate_and_lock< CommandRet5<T,M,P1,P2,P3,P4,P5,R> >();
cmd->instance=p_instance; cmd->instance=p_instance;
cmd->method=p_method; cmd->method=p_method;
cmd->p1=p1; cmd->p1=p1;
@ -754,16 +754,16 @@ public:
cmd->sync=ss; cmd->sync=ss;
unlock(); unlock();
if (sync) sync->post(); if (sync) sync->post();
ss->sem->wait(); ss->sem->wait();
} }
template<class T, class M, class P1, class P2, class P3, class P4, class P5, class P6,class R> template<class T, class M, class P1, class P2, class P3, class P4, class P5, class P6,class R>
void push_and_ret( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, R* r_ret ) { void push_and_ret( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, R* r_ret ) {
CommandRet6<T,M,P1,P2,P3,P4,P5,P6,R> * cmd = allocate_and_lock< CommandRet6<T,M,P1,P2,P3,P4,P5,P6,R> >(); CommandRet6<T,M,P1,P2,P3,P4,P5,P6,R> * cmd = allocate_and_lock< CommandRet6<T,M,P1,P2,P3,P4,P5,P6,R> >();
cmd->instance=p_instance; cmd->instance=p_instance;
cmd->method=p_method; cmd->method=p_method;
cmd->p1=p1; cmd->p1=p1;
@ -777,16 +777,16 @@ public:
cmd->sync=ss; cmd->sync=ss;
unlock(); unlock();
if (sync) sync->post(); if (sync) sync->post();
ss->sem->wait(); ss->sem->wait();
} }
template<class T, class M, class P1, class P2, class P3, class P4, class P5, class P6,class P7,class R> template<class T, class M, class P1, class P2, class P3, class P4, class P5, class P6,class P7,class R>
void push_and_ret( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6,P7 p7, R* r_ret ) { void push_and_ret( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6,P7 p7, R* r_ret ) {
CommandRet7<T,M,P1,P2,P3,P4,P5,P6,P7,R> * cmd = allocate_and_lock< CommandRet7<T,M,P1,P2,P3,P4,P5,P6,P7,R> >(); CommandRet7<T,M,P1,P2,P3,P4,P5,P6,P7,R> * cmd = allocate_and_lock< CommandRet7<T,M,P1,P2,P3,P4,P5,P6,P7,R> >();
cmd->instance=p_instance; cmd->instance=p_instance;
cmd->method=p_method; cmd->method=p_method;
cmd->p1=p1; cmd->p1=p1;
@ -801,7 +801,7 @@ public:
cmd->sync=ss; cmd->sync=ss;
unlock(); unlock();
if (sync) sync->post(); if (sync) sync->post();
ss->sem->wait(); ss->sem->wait();
} }
@ -975,12 +975,12 @@ public:
ERR_FAIL_COND(!sync); ERR_FAIL_COND(!sync);
sync->wait(); sync->wait();
lock(); lock();
flush_one(); flush_one();
unlock(); unlock();
} }
void flush_all() { void flush_all() {
//ERR_FAIL_COND(sync); //ERR_FAIL_COND(sync);
lock(); lock();
while (true) { while (true) {
@ -990,10 +990,10 @@ public:
} }
unlock(); unlock();
} }
CommandQueueMT(bool p_sync); CommandQueueMT(bool p_sync);
~CommandQueueMT(); ~CommandQueueMT();
}; };
#endif #endif

View File

@ -110,6 +110,16 @@ bool Dictionary::has(const Variant& p_key) const {
return _p->variant_map.has(p_key); return _p->variant_map.has(p_key);
} }
bool Dictionary::has_all(const Array& p_keys) const {
for (int i=0;i<p_keys.size();i++) {
if( !has(p_keys[i]) ) {
return false;
}
}
return true;
}
void Dictionary::erase(const Variant& p_key) { void Dictionary::erase(const Variant& p_key) {
_copy_on_write(); _copy_on_write();
_p->variant_map.erase(p_key); _p->variant_map.erase(p_key);

View File

@ -69,6 +69,8 @@ public:
bool is_shared() const; bool is_shared() const;
bool has(const Variant& p_key) const; bool has(const Variant& p_key) const;
bool has_all(const Array& p_keys) const;
void erase(const Variant& p_key); void erase(const Variant& p_key);
bool operator==(const Dictionary& p_dictionary) const; bool operator==(const Dictionary& p_dictionary) const;

View File

@ -43,18 +43,18 @@ template<class T>
class DVector { class DVector {
mutable MID mem; mutable MID mem;
void copy_on_write() { void copy_on_write() {
if (!mem.is_valid()) if (!mem.is_valid())
return; return;
if (dvector_lock) if (dvector_lock)
dvector_lock->lock(); dvector_lock->lock();
MID_Lock lock( mem ); MID_Lock lock( mem );
if ( *(int*)lock.data() == 1 ) { if ( *(int*)lock.data() == 1 ) {
// one reference, means no refcount changes // one reference, means no refcount changes
@ -62,114 +62,114 @@ class DVector {
dvector_lock->unlock(); dvector_lock->unlock();
return; return;
} }
MID new_mem= dynalloc( mem.get_size() ); MID new_mem= dynalloc( mem.get_size() );
if (!new_mem.is_valid()) { if (!new_mem.is_valid()) {
if (dvector_lock) if (dvector_lock)
dvector_lock->unlock(); dvector_lock->unlock();
ERR_FAIL_COND( new_mem.is_valid() ); // out of memory ERR_FAIL_COND( new_mem.is_valid() ); // out of memory
} }
MID_Lock dst_lock( new_mem ); MID_Lock dst_lock( new_mem );
int *rc = (int*)dst_lock.data(); int *rc = (int*)dst_lock.data();
*rc=1; *rc=1;
T * dst = (T*)(rc + 1 ); T * dst = (T*)(rc + 1 );
T * src =(T*) ((int*)lock.data() + 1 ); T * src =(T*) ((int*)lock.data() + 1 );
int count = (mem.get_size() - sizeof(int)) / sizeof(T); int count = (mem.get_size() - sizeof(int)) / sizeof(T);
for (int i=0;i<count;i++) { for (int i=0;i<count;i++) {
memnew_placement( &dst[i], T(src[i]) ); memnew_placement( &dst[i], T(src[i]) );
} }
(*(int*)lock.data())--; (*(int*)lock.data())--;
// unlock all // unlock all
dst_lock=MID_Lock(); dst_lock=MID_Lock();
lock=MID_Lock(); lock=MID_Lock();
mem=new_mem; mem=new_mem;
if (dvector_lock) if (dvector_lock)
dvector_lock->unlock(); dvector_lock->unlock();
} }
void reference( const DVector& p_dvector ) { void reference( const DVector& p_dvector ) {
unreference(); unreference();
if (dvector_lock) if (dvector_lock)
dvector_lock->lock(); dvector_lock->lock();
if (!p_dvector.mem.is_valid()) { if (!p_dvector.mem.is_valid()) {
if (dvector_lock) if (dvector_lock)
dvector_lock->unlock(); dvector_lock->unlock();
return; return;
} }
MID_Lock lock(p_dvector.mem); MID_Lock lock(p_dvector.mem);
int * rc = (int*)lock.data(); int * rc = (int*)lock.data();
(*rc)++; (*rc)++;
lock = MID_Lock(); lock = MID_Lock();
mem=p_dvector.mem; mem=p_dvector.mem;
if (dvector_lock) if (dvector_lock)
dvector_lock->unlock(); dvector_lock->unlock();
} }
void unreference() { void unreference() {
if (dvector_lock) if (dvector_lock)
dvector_lock->lock(); dvector_lock->lock();
if (!mem.is_valid()) { if (!mem.is_valid()) {
if (dvector_lock) if (dvector_lock)
dvector_lock->unlock(); dvector_lock->unlock();
return; return;
} }
MID_Lock lock(mem); MID_Lock lock(mem);
int * rc = (int*)lock.data(); int * rc = (int*)lock.data();
(*rc)--; (*rc)--;
if (*rc==0) { if (*rc==0) {
// no one else using it, destruct // no one else using it, destruct
T * t= (T*)(rc+1); T * t= (T*)(rc+1);
int count = (mem.get_size() - sizeof(int)) / sizeof(T); int count = (mem.get_size() - sizeof(int)) / sizeof(T);
for (int i=0;i<count;i++) { for (int i=0;i<count;i++) {
t[i].~T(); t[i].~T();
} }
} }
lock = MID_Lock(); lock = MID_Lock();
mem = MID (); mem = MID ();
if (dvector_lock) if (dvector_lock)
dvector_lock->unlock(); dvector_lock->unlock();
} }
public: public:
class Read { class Read {
@ -177,10 +177,10 @@ public:
MID_Lock lock; MID_Lock lock;
const T * mem; const T * mem;
public: public:
_FORCE_INLINE_ const T& operator[](int p_index) const { return mem[p_index]; } _FORCE_INLINE_ const T& operator[](int p_index) const { return mem[p_index]; }
_FORCE_INLINE_ const T *ptr() const { return mem; } _FORCE_INLINE_ const T *ptr() const { return mem; }
Read() { mem=NULL; } Read() { mem=NULL; }
}; };
@ -189,32 +189,32 @@ public:
MID_Lock lock; MID_Lock lock;
T * mem; T * mem;
public: public:
_FORCE_INLINE_ T& operator[](int p_index) { return mem[p_index]; } _FORCE_INLINE_ T& operator[](int p_index) { return mem[p_index]; }
_FORCE_INLINE_ T *ptr() { return mem; } _FORCE_INLINE_ T *ptr() { return mem; }
Write() { mem=NULL; } Write() { mem=NULL; }
}; };
Read read() const { Read read() const {
Read r; Read r;
if (mem.is_valid()) { if (mem.is_valid()) {
r.lock = MID_Lock( mem ); r.lock = MID_Lock( mem );
r.mem = (const T*)((int*)r.lock.data()+1); r.mem = (const T*)((int*)r.lock.data()+1);
} }
return r; return r;
} }
Write write() { Write write() {
Write w; Write w;
if (mem.is_valid()) { if (mem.is_valid()) {
copy_on_write(); copy_on_write();
w.lock = MID_Lock( mem ); w.lock = MID_Lock( mem );
w.mem = (T*)((int*)w.lock.data()+1); w.mem = (T*)((int*)w.lock.data()+1);
} }
return w; return w;
} }
template<class MC> template<class MC>
@ -280,12 +280,12 @@ public:
bool is_locked() const { return mem.is_locked(); } bool is_locked() const { return mem.is_locked(); }
inline const T operator[](int p_index) const; inline const T operator[](int p_index) const;
Error resize(int p_size); Error resize(int p_size);
void operator=(const DVector& p_dvector) { reference(p_dvector); } void operator=(const DVector& p_dvector) { reference(p_dvector); }
DVector() {} DVector() {}
DVector(const DVector& p_dvector) { reference(p_dvector); } DVector(const DVector& p_dvector) { reference(p_dvector); }
@ -308,7 +308,7 @@ T DVector<T>::get(int p_index) const {
template<class T> template<class T>
void DVector<T>::set(int p_index, const T& p_val) { void DVector<T>::set(int p_index, const T& p_val) {
if (p_index<0 || p_index>=size()) { if (p_index<0 || p_index>=size()) {
ERR_FAIL_COND(p_index<0 || p_index>=size()); ERR_FAIL_COND(p_index<0 || p_index>=size());
} }
@ -332,7 +332,7 @@ const T DVector<T>::operator[](int p_index) const {
} }
Read r = read(); Read r = read();
return r[p_index]; return r[p_index];
} }
@ -344,83 +344,83 @@ Error DVector<T>::resize(int p_size) {
dvector_lock->lock(); dvector_lock->lock();
bool same = p_size==size(); bool same = p_size==size();
if (dvector_lock) if (dvector_lock)
dvector_lock->unlock(); dvector_lock->unlock();
// no further locking is necesary because we are supposed to own the only copy of this (using copy on write) // no further locking is necesary because we are supposed to own the only copy of this (using copy on write)
if (same) if (same)
return OK; return OK;
if (p_size == 0 ) { if (p_size == 0 ) {
unreference(); unreference();
return OK; return OK;
} }
copy_on_write(); // make it unique copy_on_write(); // make it unique
ERR_FAIL_COND_V( mem.is_locked(), ERR_LOCKED ); // if after copy on write, memory is locked, fail. ERR_FAIL_COND_V( mem.is_locked(), ERR_LOCKED ); // if after copy on write, memory is locked, fail.
if (p_size > size() ) { if (p_size > size() ) {
int oldsize=size(); int oldsize=size();
MID_Lock lock; MID_Lock lock;
if (oldsize==0) { if (oldsize==0) {
mem = dynalloc( p_size * sizeof(T) + sizeof(int) ); mem = dynalloc( p_size * sizeof(T) + sizeof(int) );
lock=MID_Lock(mem); lock=MID_Lock(mem);
int *rc = ((int*)lock.data()); int *rc = ((int*)lock.data());
*rc=1; *rc=1;
} else { } else {
if (dynrealloc( mem, p_size * sizeof(T) + sizeof(int) )!=OK ) { if (dynrealloc( mem, p_size * sizeof(T) + sizeof(int) )!=OK ) {
ERR_FAIL_V(ERR_OUT_OF_MEMORY); // out of memory ERR_FAIL_V(ERR_OUT_OF_MEMORY); // out of memory
} }
lock=MID_Lock(mem); lock=MID_Lock(mem);
} }
T *t = (T*)((int*)lock.data() + 1); T *t = (T*)((int*)lock.data() + 1);
for (int i=oldsize;i<p_size;i++) { for (int i=oldsize;i<p_size;i++) {
memnew_placement(&t[i], T ); memnew_placement(&t[i], T );
} }
lock = MID_Lock(); // clear lock = MID_Lock(); // clear
} else { } else {
int oldsize=size(); int oldsize=size();
MID_Lock lock(mem); MID_Lock lock(mem);
T *t = (T*)((int*)lock.data() + 1); T *t = (T*)((int*)lock.data() + 1);
for (int i=p_size;i<oldsize;i++) { for (int i=p_size;i<oldsize;i++) {
t[i].~T(); t[i].~T();
} }
lock = MID_Lock(); // clear lock = MID_Lock(); // clear
if (dynrealloc( mem, p_size * sizeof(T) + sizeof(int) )!=OK ) { if (dynrealloc( mem, p_size * sizeof(T) + sizeof(int) )!=OK ) {
ERR_FAIL_V(ERR_OUT_OF_MEMORY); // wtf error ERR_FAIL_V(ERR_OUT_OF_MEMORY); // wtf error
} }
} }
return OK; return OK;
} }

View File

@ -33,12 +33,12 @@
/** /**
* Error macros. Unlike exceptions and asserts, these macros try to mantain consistency and stability * Error macros. Unlike exceptions and asserts, these macros try to mantain consistency and stability
* inside the code. It is recommended to always return processable data, so in case of an error, the * inside the code. It is recommended to always return processable data, so in case of an error, the
* engine can stay working well. * engine can stay working well.
* In most cases, bugs and/or invalid data are not fatal and should never allow a perfectly running application * In most cases, bugs and/or invalid data are not fatal and should never allow a perfectly running application
* to fail or crash. * to fail or crash.
*/ */
/** /**
* Pointer to the error macro priting function. Reassign to any function to have errors printed * Pointer to the error macro priting function. Reassign to any function to have errors printed
*/ */
@ -136,7 +136,7 @@ extern bool _err_error_exists;
return m_retval; \ return m_retval; \
}else _err_error_exists=false; } \ }else _err_error_exists=false; } \
/** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert(). /** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert().
* the function will exit. * the function will exit.
*/ */
@ -146,7 +146,7 @@ extern bool _err_error_exists;
return; \ return; \
}else _err_error_exists=false; } \ }else _err_error_exists=false; } \
/** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert(). /** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert().
* the function will exit. * the function will exit.
* This function returns an error value, if returning Error, please select the most * This function returns an error value, if returning Error, please select the most
* appropriate error condition from error_macros.h * appropriate error condition from error_macros.h
@ -158,7 +158,7 @@ extern bool _err_error_exists;
return m_retval; \ return m_retval; \
}else _err_error_exists=false; } \ }else _err_error_exists=false; } \
/** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert(). /** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert().
* the loop will skip to the next iteration. * the loop will skip to the next iteration.
*/ */
@ -168,7 +168,7 @@ extern bool _err_error_exists;
continue;\ continue;\
} else _err_error_exists=false;} \ } else _err_error_exists=false;} \
/** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert(). /** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert().
* the loop will break * the loop will break
*/ */

View File

@ -43,118 +43,118 @@ Error EventQueue::push_call(uint32_t p_instance_ID, const StringName& p_method,
args=2; args=2;
else if (p_arg1.get_type()!=Variant::NIL) else if (p_arg1.get_type()!=Variant::NIL)
args=1; args=1;
else else
args=0; args=0;
room_needed+=sizeof(Variant)*args; room_needed+=sizeof(Variant)*args;
ERR_FAIL_COND_V( (buffer_end+room_needed) >= buffer_size , ERR_OUT_OF_MEMORY ); ERR_FAIL_COND_V( (buffer_end+room_needed) >= buffer_size , ERR_OUT_OF_MEMORY );
Event * ev = memnew_placement( &event_buffer[ buffer_end ], Event ); Event * ev = memnew_placement( &event_buffer[ buffer_end ], Event );
ev->args=args; ev->args=args;
ev->instance_ID=p_instance_ID; ev->instance_ID=p_instance_ID;
ev->method=p_method; ev->method=p_method;
buffer_end+=sizeof(Event); buffer_end+=sizeof(Event);
if (args>=1) { if (args>=1) {
Variant * v = memnew_placement( &event_buffer[ buffer_end ], Variant ); Variant * v = memnew_placement( &event_buffer[ buffer_end ], Variant );
buffer_end+=sizeof(Variant); buffer_end+=sizeof(Variant);
*v=p_arg1; *v=p_arg1;
} }
if (args>=2) { if (args>=2) {
Variant * v = memnew_placement( &event_buffer[ buffer_end ], Variant ); Variant * v = memnew_placement( &event_buffer[ buffer_end ], Variant );
buffer_end+=sizeof(Variant); buffer_end+=sizeof(Variant);
*v=p_arg2; *v=p_arg2;
} }
if (args>=3) { if (args>=3) {
Variant * v = memnew_placement( &event_buffer[ buffer_end ], Variant ); Variant * v = memnew_placement( &event_buffer[ buffer_end ], Variant );
buffer_end+=sizeof(Variant); buffer_end+=sizeof(Variant);
*v=p_arg3; *v=p_arg3;
} }
if (args>=4) { if (args>=4) {
Variant * v = memnew_placement( &event_buffer[ buffer_end ], Variant ); Variant * v = memnew_placement( &event_buffer[ buffer_end ], Variant );
buffer_end+=sizeof(Variant); buffer_end+=sizeof(Variant);
*v=p_arg4; *v=p_arg4;
} }
if (args>=5) { if (args>=5) {
Variant * v = memnew_placement( &event_buffer[ buffer_end ], Variant ); Variant * v = memnew_placement( &event_buffer[ buffer_end ], Variant );
buffer_end+=sizeof(Variant); buffer_end+=sizeof(Variant);
*v=p_arg5; *v=p_arg5;
} }
if (buffer_max_used>buffer_end); if (buffer_end > buffer_max_used)
buffer_max_used=buffer_end; buffer_max_used=buffer_end;
return OK; return OK;
} }
void EventQueue::flush_events() { void EventQueue::flush_events() {
uint32_t read_pos=0; uint32_t read_pos=0;
while (read_pos < buffer_end ) { while (read_pos < buffer_end ) {
Event *event = (Event*)&event_buffer[ read_pos ]; Event *event = (Event*)&event_buffer[ read_pos ];
Variant *args= (Variant*)(event+1); Variant *args= (Variant*)(event+1);
Object *obj = ObjectDB::get_instance(event->instance_ID); Object *obj = ObjectDB::get_instance(event->instance_ID);
if (obj) { if (obj) {
// events don't expect a return value // events don't expect a return value
obj->call( event->method, obj->call( event->method,
(event->args>=1) ? args[0] : Variant(), (event->args>=1) ? args[0] : Variant(),
(event->args>=2) ? args[1] : Variant(), (event->args>=2) ? args[1] : Variant(),
(event->args>=3) ? args[2] : Variant(), (event->args>=3) ? args[2] : Variant(),
(event->args>=4) ? args[3] : Variant(), (event->args>=4) ? args[3] : Variant(),
(event->args>=5) ? args[4] : Variant() ); (event->args>=5) ? args[4] : Variant() );
} }
if (event->args>=1) args[0].~Variant(); if (event->args>=1) args[0].~Variant();
if (event->args>=2) args[1].~Variant(); if (event->args>=2) args[1].~Variant();
if (event->args>=3) args[2].~Variant(); if (event->args>=3) args[2].~Variant();
if (event->args>=4) args[3].~Variant(); if (event->args>=4) args[3].~Variant();
if (event->args>=5) args[4].~Variant(); if (event->args>=5) args[4].~Variant();
event->~Event(); event->~Event();
read_pos+=sizeof(Event)+sizeof(Variant)*event->args; read_pos+=sizeof(Event)+sizeof(Variant)*event->args;
} }
buffer_end=0; // reset buffer buffer_end=0; // reset buffer
} }
EventQueue::EventQueue(uint32_t p_buffer_size) { EventQueue::EventQueue(uint32_t p_buffer_size) {
buffer_end=0; buffer_end=0;
buffer_max_used=0; buffer_max_used=0;
buffer_size=p_buffer_size; buffer_size=p_buffer_size;
event_buffer = memnew_arr( uint8_t, buffer_size ); event_buffer = memnew_arr( uint8_t, buffer_size );
} }
EventQueue::~EventQueue() { EventQueue::~EventQueue() {
uint32_t read_pos=0; uint32_t read_pos=0;
while (read_pos < buffer_end ) { while (read_pos < buffer_end ) {
Event *event = (Event*)&event_buffer[ read_pos ]; Event *event = (Event*)&event_buffer[ read_pos ];
Variant *args= (Variant*)(event+1); Variant *args= (Variant*)(event+1);
for (int i=0;i<event->args;i++) for (int i=0;i<event->args;i++)
args[i].~Variant(); args[i].~Variant();
event->~Event(); event->~Event();
read_pos+=sizeof(Event)+sizeof(Variant)*event->args; read_pos+=sizeof(Event)+sizeof(Variant)*event->args;
} }
memdelete_arr(event_buffer); memdelete_arr(event_buffer);
event_buffer=NULL; event_buffer=NULL;
} }

View File

@ -36,18 +36,18 @@
class EventQueue { class EventQueue {
enum { enum {
DEFAULT_EVENT_QUEUE_SIZE_KB=256 DEFAULT_EVENT_QUEUE_SIZE_KB=256
}; };
struct Event { struct Event {
uint32_t instance_ID; uint32_t instance_ID;
StringName method; StringName method;
int args; int args;
}; };
uint8_t *event_buffer; uint8_t *event_buffer;
uint32_t buffer_end; uint32_t buffer_end;
uint32_t buffer_max_used; uint32_t buffer_max_used;
@ -57,7 +57,7 @@ public:
Error push_call(uint32_t p_instance_ID, const StringName& p_method, VARIANT_ARG_LIST); Error push_call(uint32_t p_instance_ID, const StringName& p_method, VARIANT_ARG_LIST);
void flush_events(); void flush_events();
EventQueue(uint32_t p_buffer_size=DEFAULT_EVENT_QUEUE_SIZE_KB*1024); EventQueue(uint32_t p_buffer_size=DEFAULT_EVENT_QUEUE_SIZE_KB*1024);
~EventQueue(); ~EventQueue();

View File

@ -474,7 +474,6 @@ static _GlobalConstant _global_constants[]={
BIND_GLOBAL_CONSTANT( PROPERTY_HINT_IMAGE_COMPRESS_LOSSLESS ), BIND_GLOBAL_CONSTANT( PROPERTY_HINT_IMAGE_COMPRESS_LOSSLESS ),
BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_STORAGE ),
BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_STORAGE ), BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_STORAGE ),
BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_EDITOR ), BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_EDITOR ),
BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_NETWORK ), BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_NETWORK ),

View File

@ -40,7 +40,7 @@
Globals *Globals::singleton=NULL; Globals *Globals::singleton=NULL;
Globals *Globals::get_singleton() { Globals *Globals::get_singleton() {
return singleton; return singleton;
} }
@ -108,7 +108,7 @@ bool Globals::is_persisting(const String& p_name) const {
String Globals::globalize_path(const String& p_path) const { String Globals::globalize_path(const String& p_path) const {
if (p_path.begins_with("res://")) { if (p_path.begins_with("res://")) {
if (resource_path != "") { if (resource_path != "") {
@ -125,7 +125,7 @@ String Globals::globalize_path(const String& p_path) const {
bool Globals::_set(const StringName& p_name, const Variant& p_value) { bool Globals::_set(const StringName& p_name, const Variant& p_value) {
_THREAD_SAFE_METHOD_ _THREAD_SAFE_METHOD_
if (p_value.get_type()==Variant::NIL) if (p_value.get_type()==Variant::NIL)
props.erase(p_name); props.erase(p_name);
else { else {
@ -174,7 +174,7 @@ bool Globals::_get(const StringName& p_name,Variant &r_ret) const {
return false; return false;
r_ret=props[p_name].variant; r_ret=props[p_name].variant;
return true; return true;
} }
struct _VCSort { struct _VCSort {
@ -188,13 +188,13 @@ struct _VCSort {
}; };
void Globals::_get_property_list(List<PropertyInfo> *p_list) const { void Globals::_get_property_list(List<PropertyInfo> *p_list) const {
_THREAD_SAFE_METHOD_ _THREAD_SAFE_METHOD_
Set<_VCSort> vclist; Set<_VCSort> vclist;
for(Map<StringName,VariantContainer>::Element *E=props.front();E;E=E->next()) { for(Map<StringName,VariantContainer>::Element *E=props.front();E;E=E->next()) {
const VariantContainer *v=&E->get(); const VariantContainer *v=&E->get();
if (v->hide_from_editor) if (v->hide_from_editor)
@ -250,7 +250,7 @@ bool Globals::_load_resource_pack(const String& p_pack) {
Error Globals::setup(const String& p_path,const String & p_main_pack) { Error Globals::setup(const String& p_path,const String & p_main_pack) {
//an absolute mess of a function, must be cleaned up and reorganized somehow at some point //an absolute mess of a function, must be cleaned up and reorganized somehow at some point
//_load_settings(p_path+"/override.cfg"); //_load_settings(p_path+"/override.cfg");
if (p_main_pack!="") { if (p_main_pack!="") {
@ -292,7 +292,7 @@ Error Globals::setup(const String& p_path,const String & p_main_pack) {
} }
} }
if (FileAccessNetworkClient::get_singleton()) { if (FileAccessNetworkClient::get_singleton()) {
@ -332,7 +332,7 @@ Error Globals::setup(const String& p_path,const String & p_main_pack) {
resource_path = p_path; resource_path = p_path;
} else { } else {
d->change_dir(p_path); d->change_dir(p_path);
String candidate = d->get_current_dir(); String candidate = d->get_current_dir();
@ -395,7 +395,7 @@ Error Globals::setup(const String& p_path,const String & p_main_pack) {
} }
bool Globals::has(String p_var) const { bool Globals::has(String p_var) const {
_THREAD_SAFE_METHOD_ _THREAD_SAFE_METHOD_
return props.has(p_var); return props.has(p_var);
@ -1410,7 +1410,7 @@ void Globals::_bind_methods() {
} }
Globals::Globals() { Globals::Globals() {
singleton=this; singleton=this;
last_order=0; last_order=0;
@ -1531,7 +1531,7 @@ Globals::Globals() {
Globals::~Globals() { Globals::~Globals() {
singleton=NULL; singleton=NULL;
} }

View File

@ -38,7 +38,7 @@
class Globals : public Object { class Globals : public Object {
OBJ_TYPE( Globals, Object ); OBJ_TYPE( Globals, Object );
_THREAD_SAFE_CLASS_ _THREAD_SAFE_CLASS_
@ -77,13 +77,13 @@ protected:
bool using_datapack; bool using_datapack;
List<String> input_presets; List<String> input_presets;
bool _set(const StringName& p_name, const Variant& p_value); bool _set(const StringName& p_name, const Variant& p_value);
bool _get(const StringName& p_name,Variant &r_ret) const; bool _get(const StringName& p_name,Variant &r_ret) const;
void _get_property_list(List<PropertyInfo> *p_list) const; void _get_property_list(List<PropertyInfo> *p_list) const;
static Globals *singleton; static Globals *singleton;
Error _load_settings(const String p_path); Error _load_settings(const String p_path);
Error _load_settings_binary(const String p_path); Error _load_settings_binary(const String p_path);
@ -101,7 +101,7 @@ protected:
static void _bind_methods(); static void _bind_methods();
public: public:
bool has(String p_var) const; bool has(String p_var) const;
String localize_path(const String& p_path) const; String localize_path(const String& p_path) const;
String globalize_path(const String& p_path) const; String globalize_path(const String& p_path) const;
@ -110,13 +110,13 @@ public:
bool is_persisting(const String& p_name) const; bool is_persisting(const String& p_name) const;
String get_resource_path() const; String get_resource_path() const;
static Globals *get_singleton(); static Globals *get_singleton();
void clear(const String& p_name); void clear(const String& p_name);
int get_order(const String& p_name) const; int get_order(const String& p_name) const;
void set_order(const String& p_name, int p_order); void set_order(const String& p_name, int p_order);
Error setup(const String& p_path, const String &p_main_pack); Error setup(const String& p_path, const String &p_main_pack);
Error save_custom(const String& p_path="",const CustomMap& p_custom=CustomMap(),const Set<String>& p_ignore_masks=Set<String>()); Error save_custom(const String& p_path="",const CustomMap& p_custom=CustomMap(),const Set<String>& p_ignore_masks=Set<String>());
@ -141,7 +141,7 @@ public:
void set_registering_order(bool p_registering); void set_registering_order(bool p_registering);
Globals(); Globals();
~Globals(); ~Globals();
}; };

View File

@ -38,7 +38,7 @@
class HashMapHahserDefault { class HashMapHahserDefault {
public: public:
static _FORCE_INLINE_ uint32_t hash(const String &p_string) { return p_string.hash(); } static _FORCE_INLINE_ uint32_t hash(const String &p_string) { return p_string.hash(); }
static _FORCE_INLINE_ uint32_t hash(const char *p_cstr) { return hash_djb2(p_cstr); } static _FORCE_INLINE_ uint32_t hash(const char *p_cstr) { return hash_djb2(p_cstr); }
static _FORCE_INLINE_ uint32_t hash(const uint64_t p_int) { static _FORCE_INLINE_ uint32_t hash(const uint64_t p_int) {
@ -66,8 +66,8 @@ public:
/** /**
* @class HashMap * @class HashMap
* @author Juan Linietsky <reduzio@gmail.com> * @author Juan Linietsky <reduzio@gmail.com>
* *
* Implementation of a standard Hashing HashMap, for quick lookups of Data associated with a Key. * Implementation of a standard Hashing HashMap, for quick lookups of Data associated with a Key.
* The implementation provides hashers for the default types, if you need a special kind of hasher, provide * The implementation provides hashers for the default types, if you need a special kind of hasher, provide
* your own. * your own.
@ -77,213 +77,213 @@ public:
* @param MIN_HASH_TABLE_POWER Miminum size of the hash table, as a power of two. You rarely need to change this parameter. * @param MIN_HASH_TABLE_POWER Miminum size of the hash table, as a power of two. You rarely need to change this parameter.
* @param RELATIONSHIP Relationship at which the hash table is resized. if amount of elements is RELATIONSHIP * @param RELATIONSHIP Relationship at which the hash table is resized. if amount of elements is RELATIONSHIP
* times bigger than the hash table, table is resized to solve this condition. if RELATIONSHIP is zero, table is always MIN_HASH_TABLE_POWER. * times bigger than the hash table, table is resized to solve this condition. if RELATIONSHIP is zero, table is always MIN_HASH_TABLE_POWER.
* *
*/ */
template<class TKey, class TData, class Hasher=HashMapHahserDefault,uint8_t MIN_HASH_TABLE_POWER=3,uint8_t RELATIONSHIP=8> template<class TKey, class TData, class Hasher=HashMapHahserDefault,uint8_t MIN_HASH_TABLE_POWER=3,uint8_t RELATIONSHIP=8>
class HashMap { class HashMap {
public: public:
struct Pair { struct Pair {
TKey key; TKey key;
TData data; TData data;
Pair() {} Pair() {}
Pair(const TKey& p_key, const TData& p_data) { key=p_key; data=p_data; } Pair(const TKey& p_key, const TData& p_data) { key=p_key; data=p_data; }
}; };
private: private:
struct Entry { struct Entry {
uint32_t hash; uint32_t hash;
Entry *next; Entry *next;
Pair pair; Pair pair;
Entry() { next=0; } Entry() { next=0; }
}; };
Entry **hash_table; Entry **hash_table;
uint8_t hash_table_power; uint8_t hash_table_power;
uint32_t elements; uint32_t elements;
void make_hash_table() { void make_hash_table() {
ERR_FAIL_COND( hash_table ); ERR_FAIL_COND( hash_table );
hash_table = memnew_arr( Entry*, (1<<MIN_HASH_TABLE_POWER) ); hash_table = memnew_arr( Entry*, (1<<MIN_HASH_TABLE_POWER) );
hash_table_power = MIN_HASH_TABLE_POWER; hash_table_power = MIN_HASH_TABLE_POWER;
elements=0; elements=0;
for (int i=0;i<(1<<MIN_HASH_TABLE_POWER);i++) for (int i=0;i<(1<<MIN_HASH_TABLE_POWER);i++)
hash_table[i]=0; hash_table[i]=0;
} }
void erase_hash_table() { void erase_hash_table() {
ERR_FAIL_COND(elements); ERR_FAIL_COND(elements);
memdelete_arr( hash_table ); memdelete_arr( hash_table );
hash_table=0; hash_table=0;
hash_table_power=0; hash_table_power=0;
elements=0; elements=0;
} }
void check_hash_table() { void check_hash_table() {
int new_hash_table_power=-1; int new_hash_table_power=-1;
if ((int)elements > ( (1<<hash_table_power) * RELATIONSHIP ) ) { if ((int)elements > ( (1<<hash_table_power) * RELATIONSHIP ) ) {
/* rehash up */ /* rehash up */
new_hash_table_power=hash_table_power+1; new_hash_table_power=hash_table_power+1;
while( (int)elements > ( (1<<new_hash_table_power) * RELATIONSHIP ) ) { while( (int)elements > ( (1<<new_hash_table_power) * RELATIONSHIP ) ) {
new_hash_table_power++; new_hash_table_power++;
} }
} else if ( (hash_table_power>(int)MIN_HASH_TABLE_POWER) && ((int)elements < ( (1<<(hash_table_power-1)) * RELATIONSHIP ) ) ) { } else if ( (hash_table_power>(int)MIN_HASH_TABLE_POWER) && ((int)elements < ( (1<<(hash_table_power-1)) * RELATIONSHIP ) ) ) {
/* rehash down */ /* rehash down */
new_hash_table_power=hash_table_power-1; new_hash_table_power=hash_table_power-1;
while( (int)elements < ( (1<<(new_hash_table_power-1)) * RELATIONSHIP ) ) { while( (int)elements < ( (1<<(new_hash_table_power-1)) * RELATIONSHIP ) ) {
new_hash_table_power--; new_hash_table_power--;
} }
if (new_hash_table_power<(int)MIN_HASH_TABLE_POWER) if (new_hash_table_power<(int)MIN_HASH_TABLE_POWER)
new_hash_table_power=MIN_HASH_TABLE_POWER; new_hash_table_power=MIN_HASH_TABLE_POWER;
} }
if (new_hash_table_power==-1) if (new_hash_table_power==-1)
return; return;
Entry ** new_hash_table = memnew_arr( Entry*, (1<<new_hash_table_power) ); Entry ** new_hash_table = memnew_arr( Entry*, (1<<new_hash_table_power) );
if (!new_hash_table) { if (!new_hash_table) {
ERR_PRINT("Out of Memory"); ERR_PRINT("Out of Memory");
return; return;
} }
for (int i=0;i<(1<<new_hash_table_power);i++) { for (int i=0;i<(1<<new_hash_table_power);i++) {
new_hash_table[i]=0; new_hash_table[i]=0;
} }
for (int i=0;i<(1<<hash_table_power);i++) { for (int i=0;i<(1<<hash_table_power);i++) {
while( hash_table[i] ) { while( hash_table[i] ) {
Entry *se=hash_table[i]; Entry *se=hash_table[i];
hash_table[i]=se->next; hash_table[i]=se->next;
int new_pos = se->hash & ((1<<new_hash_table_power)-1); int new_pos = se->hash & ((1<<new_hash_table_power)-1);
se->next=new_hash_table[new_pos]; se->next=new_hash_table[new_pos];
new_hash_table[new_pos]=se; new_hash_table[new_pos]=se;
} }
} }
if (hash_table) if (hash_table)
memdelete_arr( hash_table ); memdelete_arr( hash_table );
hash_table=new_hash_table; hash_table=new_hash_table;
hash_table_power=new_hash_table_power; hash_table_power=new_hash_table_power;
} }
/* I want to have only one function.. */ /* I want to have only one function.. */
_FORCE_INLINE_ const Entry * get_entry( const TKey& p_key ) const { _FORCE_INLINE_ const Entry * get_entry( const TKey& p_key ) const {
uint32_t hash = Hasher::hash( p_key ); uint32_t hash = Hasher::hash( p_key );
uint32_t index = hash&((1<<hash_table_power)-1); uint32_t index = hash&((1<<hash_table_power)-1);
Entry *e = hash_table[index]; Entry *e = hash_table[index];
while (e) { while (e) {
/* checking hash first avoids comparing key, which may take longer */ /* checking hash first avoids comparing key, which may take longer */
if (e->hash == hash && e->pair.key == p_key ) { if (e->hash == hash && e->pair.key == p_key ) {
/* the pair exists in this hashtable, so just update data */ /* the pair exists in this hashtable, so just update data */
return e; return e;
} }
e=e->next; e=e->next;
} }
return NULL; return NULL;
} }
Entry * create_entry(const TKey& p_key) { Entry * create_entry(const TKey& p_key) {
/* if entry doesn't exist, create it */ /* if entry doesn't exist, create it */
Entry *e = memnew( Entry ); Entry *e = memnew( Entry );
ERR_FAIL_COND_V(!e,NULL); /* out of memory */ ERR_FAIL_COND_V(!e,NULL); /* out of memory */
uint32_t hash = Hasher::hash( p_key ); uint32_t hash = Hasher::hash( p_key );
uint32_t index = hash&((1<<hash_table_power)-1); uint32_t index = hash&((1<<hash_table_power)-1);
e->next = hash_table[index]; e->next = hash_table[index];
e->hash = hash; e->hash = hash;
e->pair.key=p_key; e->pair.key=p_key;
hash_table[index]=e; hash_table[index]=e;
elements++; elements++;
return e; return e;
} }
void copy_from(const HashMap& p_t) { void copy_from(const HashMap& p_t) {
if (&p_t==this) if (&p_t==this)
return; /* much less bother with that */ return; /* much less bother with that */
clear(); clear();
if (!p_t.hash_table || p_t.hash_table_power==0) if (!p_t.hash_table || p_t.hash_table_power==0)
return; /* not copying from empty table */ return; /* not copying from empty table */
hash_table = memnew_arr(Entry*,1<<p_t.hash_table_power); hash_table = memnew_arr(Entry*,1<<p_t.hash_table_power);
hash_table_power=p_t.hash_table_power; hash_table_power=p_t.hash_table_power;
elements=p_t.elements; elements=p_t.elements;
for (int i=0;i<( 1<<p_t.hash_table_power );i++) { for (int i=0;i<( 1<<p_t.hash_table_power );i++) {
hash_table[i]=NULL; hash_table[i]=NULL;
/* elements will be in the reverse order, but it doesn't matter */ /* elements will be in the reverse order, but it doesn't matter */
const Entry *e = p_t.hash_table[i]; const Entry *e = p_t.hash_table[i];
while(e) { while(e) {
Entry *le = memnew( Entry ); /* local entry */ Entry *le = memnew( Entry ); /* local entry */
*le=*e; /* copy data */ *le=*e; /* copy data */
/* add to list and reassign pointers */ /* add to list and reassign pointers */
le->next=hash_table[i]; le->next=hash_table[i];
hash_table[i]=le; hash_table[i]=le;
e=e->next; e=e->next;
} }
} }
} }
public: public:
void set( const TKey& p_key, const TData& p_data ) { void set( const TKey& p_key, const TData& p_data ) {
set( Pair( p_key, p_data ) ); set( Pair( p_key, p_data ) );
} }
void set( const Pair& p_pair ) { void set( const Pair& p_pair ) {
Entry *e=NULL; Entry *e=NULL;
@ -291,63 +291,63 @@ public:
make_hash_table(); // if no table, make one make_hash_table(); // if no table, make one
else else
e = const_cast<Entry*>( get_entry(p_pair.key) ); e = const_cast<Entry*>( get_entry(p_pair.key) );
/* if we made it up to here, the pair doesn't exist, create and assign */ /* if we made it up to here, the pair doesn't exist, create and assign */
if (!e) { if (!e) {
e=create_entry(p_pair.key); e=create_entry(p_pair.key);
if (!e) if (!e)
return; return;
check_hash_table(); // perform mantenience routine check_hash_table(); // perform mantenience routine
} }
e->pair.data = p_pair.data; e->pair.data = p_pair.data;
} }
bool has( const TKey& p_key ) const { bool has( const TKey& p_key ) const {
return getptr(p_key)!=NULL; return getptr(p_key)!=NULL;
} }
/** /**
* Get a key from data, return a const reference. * Get a key from data, return a const reference.
* WARNING: this doesn't check errors, use either getptr and check NULL, or check * WARNING: this doesn't check errors, use either getptr and check NULL, or check
* first with has(key) * first with has(key)
*/ */
const TData& get( const TKey& p_key ) const { const TData& get( const TKey& p_key ) const {
const TData* res = getptr(p_key); const TData* res = getptr(p_key);
ERR_FAIL_COND_V(!res,*res); ERR_FAIL_COND_V(!res,*res);
return *res; return *res;
} }
TData& get( const TKey& p_key ) { TData& get( const TKey& p_key ) {
TData* res = getptr(p_key); TData* res = getptr(p_key);
ERR_FAIL_COND_V(!res,*res); ERR_FAIL_COND_V(!res,*res);
return *res; return *res;
} }
/** /**
* Same as get, except it can return NULL when item was not found. * Same as get, except it can return NULL when item was not found.
* This is mainly used for speed purposes. * This is mainly used for speed purposes.
*/ */
_FORCE_INLINE_ TData* getptr( const TKey& p_key ) { _FORCE_INLINE_ TData* getptr( const TKey& p_key ) {
if (!hash_table) if (!hash_table)
return NULL; return NULL;
Entry *e=const_cast<Entry*>(get_entry(p_key )); Entry *e=const_cast<Entry*>(get_entry(p_key ));
if (e) if (e)
return &e->pair.data; return &e->pair.data;
return NULL; return NULL;
} }
@ -427,108 +427,108 @@ public:
/** /**
* Erase an item, return true if erasing was succesful * Erase an item, return true if erasing was succesful
*/ */
bool erase( const TKey& p_key ) { bool erase( const TKey& p_key ) {
if (!hash_table) if (!hash_table)
return false; return false;
uint32_t hash = Hasher::hash( p_key ); uint32_t hash = Hasher::hash( p_key );
uint32_t index = hash&((1<<hash_table_power)-1); uint32_t index = hash&((1<<hash_table_power)-1);
Entry *e = hash_table[index]; Entry *e = hash_table[index];
Entry *p=NULL; Entry *p=NULL;
while (e) { while (e) {
/* checking hash first avoids comparing key, which may take longer */ /* checking hash first avoids comparing key, which may take longer */
if (e->hash == hash && e->pair.key == p_key ) { if (e->hash == hash && e->pair.key == p_key ) {
if (p) { if (p) {
p->next=e->next; p->next=e->next;
} else { } else {
//begin of list //begin of list
hash_table[index]=e->next; hash_table[index]=e->next;
} }
memdelete(e); memdelete(e);
elements--; elements--;
if (elements==0) if (elements==0)
erase_hash_table(); erase_hash_table();
else else
check_hash_table(); check_hash_table();
return true; return true;
} }
p=e; p=e;
e=e->next; e=e->next;
} }
return false; return false;
} }
inline const TData& operator[](const TKey& p_key) const { //constref inline const TData& operator[](const TKey& p_key) const { //constref
return get(p_key); return get(p_key);
} }
inline TData& operator[](const TKey& p_key ) { //assignment inline TData& operator[](const TKey& p_key ) { //assignment
Entry *e=NULL; Entry *e=NULL;
if (!hash_table) if (!hash_table)
make_hash_table(); // if no table, make one make_hash_table(); // if no table, make one
else else
e = const_cast<Entry*>( get_entry(p_key) ); e = const_cast<Entry*>( get_entry(p_key) );
/* if we made it up to here, the pair doesn't exist, create */ /* if we made it up to here, the pair doesn't exist, create */
if (!e) { if (!e) {
e=create_entry(p_key); e=create_entry(p_key);
if (!e) if (!e)
return *(TData*)NULL; /* panic! */ return *(TData*)NULL; /* panic! */
check_hash_table(); // perform mantenience routine check_hash_table(); // perform mantenience routine
} }
return e->pair.data; return e->pair.data;
} }
/** /**
* Get the next key to p_key, and the first key if p_key is null. * Get the next key to p_key, and the first key if p_key is null.
* Returns a pointer to the next key if found, NULL otherwise. * Returns a pointer to the next key if found, NULL otherwise.
* Adding/Removing elements while iterating will, of course, have unexpected results, don't do it. * Adding/Removing elements while iterating will, of course, have unexpected results, don't do it.
* *
* Example: * Example:
* *
* const TKey *k=NULL; * const TKey *k=NULL;
* *
* while( (k=table.next(k)) ) { * while( (k=table.next(k)) ) {
* *
* print( *k ); * print( *k );
* } * }
* *
*/ */
const TKey* next(const TKey* p_key) const { const TKey* next(const TKey* p_key) const {
if (!hash_table) return NULL; if (!hash_table) return NULL;
if (!p_key) { /* get the first key */ if (!p_key) { /* get the first key */
for (int i=0;i<(1<<hash_table_power);i++) { for (int i=0;i<(1<<hash_table_power);i++) {
if (hash_table[i]) { if (hash_table[i]) {
return &hash_table[i]->pair.key; return &hash_table[i]->pair.key;
} }
} }
} else { /* get the next key */ } else { /* get the next key */
const Entry *e = get_entry( *p_key ); const Entry *e = get_entry( *p_key );
ERR_FAIL_COND_V( !e, NULL ); /* invalid key supplied */ ERR_FAIL_COND_V( !e, NULL ); /* invalid key supplied */
if (e->next) { if (e->next) {
/* if there is a "next" in the list, return that */ /* if there is a "next" in the list, return that */
return &e->next->pair.key; return &e->next->pair.key;
@ -537,60 +537,60 @@ public:
uint32_t index = e->hash&((1<<hash_table_power)-1); uint32_t index = e->hash&((1<<hash_table_power)-1);
index++; index++;
for (int i=index;i<(1<<hash_table_power);i++) { for (int i=index;i<(1<<hash_table_power);i++) {
if (hash_table[i]) { if (hash_table[i]) {
return &hash_table[i]->pair.key; return &hash_table[i]->pair.key;
} }
} }
} }
/* nothing found, was at end */ /* nothing found, was at end */
} }
return NULL; /* nothing found */ return NULL; /* nothing found */
} }
inline unsigned int size() const { inline unsigned int size() const {
return elements; return elements;
} }
inline bool empty() const { inline bool empty() const {
return elements==0; return elements==0;
} }
void clear() { void clear() {
/* clean up */ /* clean up */
if (hash_table) { if (hash_table) {
for (int i=0;i<(1<<hash_table_power);i++) { for (int i=0;i<(1<<hash_table_power);i++) {
while (hash_table[i]) { while (hash_table[i]) {
Entry *e=hash_table[i]; Entry *e=hash_table[i];
hash_table[i]=e->next; hash_table[i]=e->next;
memdelete( e ); memdelete( e );
} }
} }
memdelete_arr( hash_table ); memdelete_arr( hash_table );
} }
hash_table=0; hash_table=0;
hash_table_power=0; hash_table_power=0;
elements=0; elements=0;
} }
void operator=(const HashMap& p_table) { void operator=(const HashMap& p_table) {
copy_from(p_table); copy_from(p_table);
} }
HashMap() { HashMap() {
hash_table=NULL; hash_table=NULL;
elements=0; elements=0;
hash_table_power=0; hash_table_power=0;
@ -609,18 +609,18 @@ public:
} }
} }
HashMap(const HashMap& p_table) { HashMap(const HashMap& p_table) {
hash_table=NULL; hash_table=NULL;
elements=0; elements=0;
hash_table_power=0; hash_table_power=0;
copy_from(p_table); copy_from(p_table);
} }
~HashMap() { ~HashMap() {
clear(); clear();
} }

View File

@ -47,10 +47,10 @@ static inline uint32_t hash_djb2(const char *p_cstr) {
const unsigned char* chr=(const unsigned char*)p_cstr; const unsigned char* chr=(const unsigned char*)p_cstr;
uint32_t hash = 5381; uint32_t hash = 5381;
uint32_t c; uint32_t c;
while ((c = *chr++)) while ((c = *chr++))
hash = ((hash << 5) + hash) + c; /* hash * 33 + c */ hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
return hash; return hash;
} }
@ -86,7 +86,7 @@ static inline uint32_t make_uint32_t(T p_in) {
T t; T t;
uint32_t _u32; uint32_t _u32;
} _u; } _u;
_u._u32=0; _u._u32=0;
_u.t=p_in; _u.t=p_in;
return _u._u32; return _u._u32;
} }
@ -106,7 +106,7 @@ static inline uint64_t make_uint64_t(T p_in) {
uint64_t _u64; uint64_t _u64;
} _u; } _u;
_u._u64=0; // in case p_in is smaller _u._u64=0; // in case p_in is smaller
_u.t=p_in; _u.t=p_in;
return _u._u64; return _u._u64;
} }

View File

@ -382,7 +382,7 @@ void Image::convert( Format p_new_format ){
Image new_img(width,height,0,p_new_format); Image new_img(width,height,0,p_new_format);
int len=data.size(); int len=data.size();
DVector<uint8_t>::Read r = data.read(); DVector<uint8_t>::Read r = data.read();
@ -413,7 +413,7 @@ void Image::convert( Format p_new_format ){
w = DVector<uint8_t>::Write(); w = DVector<uint8_t>::Write();
bool gen_mipmaps=mipmaps>0; bool gen_mipmaps=mipmaps>0;
*this=new_img; *this=new_img;
if (gen_mipmaps) if (gen_mipmaps)
@ -643,13 +643,13 @@ void Image::resize( int p_width, int p_height, Interpolation p_interpolation ) {
ERR_FAIL_COND(p_height<=0); ERR_FAIL_COND(p_height<=0);
ERR_FAIL_COND(p_width>MAX_WIDTH); ERR_FAIL_COND(p_width>MAX_WIDTH);
ERR_FAIL_COND(p_height>MAX_HEIGHT); ERR_FAIL_COND(p_height>MAX_HEIGHT);
if (p_width==width && p_height==height) if (p_width==width && p_height==height)
return; return;
Image dst( p_width, p_height, 0, format ); Image dst( p_width, p_height, 0, format );
if (format==FORMAT_INDEXED) if (format==FORMAT_INDEXED)
p_interpolation=INTERPOLATE_NEAREST; p_interpolation=INTERPOLATE_NEAREST;
@ -714,34 +714,34 @@ void Image::crop( int p_width, int p_height ) {
ERR_FAIL_COND(p_height<=0); ERR_FAIL_COND(p_height<=0);
ERR_FAIL_COND(p_width>MAX_WIDTH); ERR_FAIL_COND(p_width>MAX_WIDTH);
ERR_FAIL_COND(p_height>MAX_HEIGHT); ERR_FAIL_COND(p_height>MAX_HEIGHT);
/* to save memory, cropping should be done in-place, however, since this function /* to save memory, cropping should be done in-place, however, since this function
will most likely either not be used much, or in critical areas, for now it wont, because will most likely either not be used much, or in critical areas, for now it wont, because
it's a waste of time. */ it's a waste of time. */
if (p_width==width && p_height==height) if (p_width==width && p_height==height)
return; return;
Image dst( p_width, p_height,0, format ); Image dst( p_width, p_height,0, format );
for (int y=0;y<p_height;y++) { for (int y=0;y<p_height;y++) {
for (int x=0;x<p_width;x++) { for (int x=0;x<p_width;x++) {
Color col = (x>=width || y>=height)? Color() : get_pixel(x,y); Color col = (x>=width || y>=height)? Color() : get_pixel(x,y);
dst.put_pixel(x,y,col); dst.put_pixel(x,y,col);
} }
} }
if (mipmaps>0) if (mipmaps>0)
dst.generate_mipmaps(); dst.generate_mipmaps();
*this=dst; *this=dst;
} }
void Image::flip_y() { void Image::flip_y() {
if (!_can_modify(format)) { if (!_can_modify(format)) {
ERR_EXPLAIN("Cannot flip_y in indexed, compressed or custom image formats."); ERR_EXPLAIN("Cannot flip_y in indexed, compressed or custom image formats.");
ERR_FAIL(); ERR_FAIL();
@ -756,12 +756,12 @@ void Image::flip_y() {
for (int y=0;y<(height/2);y++) { for (int y=0;y<(height/2);y++) {
for (int x=0;x<width;x++) { for (int x=0;x<width;x++) {
Color up = get_pixel(x,y); Color up = get_pixel(x,y);
Color down = get_pixel(x,height-y-1); Color down = get_pixel(x,height-y-1);
put_pixel(x,y,down); put_pixel(x,y,down);
put_pixel(x,height-y-1,up); put_pixel(x,height-y-1,up);
} }
@ -783,12 +783,12 @@ void Image::flip_x() {
clear_mipmaps();; clear_mipmaps();;
for (int y=0;y<(height/2);y++) { for (int y=0;y<(height/2);y++) {
for (int x=0;x<width;x++) { for (int x=0;x<width;x++) {
Color up = get_pixel(x,y); Color up = get_pixel(x,y);
Color down = get_pixel(width-x-1,y); Color down = get_pixel(width-x-1,y);
put_pixel(x,y,down); put_pixel(x,y,down);
put_pixel(width-x-1,y,up); put_pixel(width-x-1,y,up);
} }
@ -901,6 +901,66 @@ static void _generate_po2_mipmap(const uint8_t* p_src, uint8_t* p_dst, uint32_t
} }
void Image::shrink_x2() {
ERR_FAIL_COND(format==FORMAT_INDEXED || format==FORMAT_INDEXED_ALPHA);
ERR_FAIL_COND( data.size()==0 );
if (mipmaps) {
//just use the lower mipmap as base and copy all
DVector<uint8_t> new_img;
int ofs = get_mipmap_offset(1);
int new_size = data.size()-ofs;
new_img.resize(new_size);
{
DVector<uint8_t>::Write w=new_img.write();
DVector<uint8_t>::Read r=data.read();
copymem(w.ptr(),&r[ofs],new_size);
}
mipmaps--;
width/=2;
height/=2;
data=new_img;
} else {
DVector<uint8_t> new_img;
ERR_FAIL_COND( format>=FORMAT_INDEXED );
int ps = get_format_pixel_size(format);
new_img.resize((width/2)*(height/2)*ps);
{
DVector<uint8_t>::Write w=new_img.write();
DVector<uint8_t>::Read r=data.read();
switch(format) {
case FORMAT_GRAYSCALE:
case FORMAT_INTENSITY: _generate_po2_mipmap<1>(r.ptr(), w.ptr(), width,height); break;
case FORMAT_GRAYSCALE_ALPHA: _generate_po2_mipmap<2>(r.ptr(), w.ptr(), width,height); break;
case FORMAT_RGB: _generate_po2_mipmap<3>(r.ptr(), w.ptr(), width,height); break;
case FORMAT_RGBA: _generate_po2_mipmap<4>(r.ptr(), w.ptr(), width,height); break;
default: {}
}
}
width/=2;
height/=2;
data=new_img;
}
}
Error Image::generate_mipmaps(int p_mipmaps,bool p_keep_existing) { Error Image::generate_mipmaps(int p_mipmaps,bool p_keep_existing) {
if (!_can_modify(format)) { if (!_can_modify(format)) {
@ -1040,26 +1100,26 @@ void Image::make_normalmap(float p_height_scale) {
} }
ERR_FAIL_COND( empty() ); ERR_FAIL_COND( empty() );
Image normalmap(width,height,0, FORMAT_RGB); Image normalmap(width,height,0, FORMAT_RGB);
/* /*
for (int y=0;y<height;y++) { for (int y=0;y<height;y++) {
for (int x=0;x<width;x++) { for (int x=0;x<width;x++) {
float center=get_pixel(x,y).gray()/255.0; float center=get_pixel(x,y).gray()/255.0;
float up=(y>0)?get_pixel(x,y-1).gray()/255.0:center; float up=(y>0)?get_pixel(x,y-1).gray()/255.0:center;
float down=(y<(height-1))?get_pixel(x,y+1).gray()/255.0:center; float down=(y<(height-1))?get_pixel(x,y+1).gray()/255.0:center;
float left=(x>0)?get_pixel(x-1,y).gray()/255.0:center; float left=(x>0)?get_pixel(x-1,y).gray()/255.0:center;
float right=(x<(width-1))?get_pixel(x+1,y).gray()/255.0:center; float right=(x<(width-1))?get_pixel(x+1,y).gray()/255.0:center;
// uhm, how do i do this? .... // uhm, how do i do this? ....
Color result( (uint8_t)((normal.x+1.0)*127.0), (uint8_t)((normal.y+1.0)*127.0), (uint8_t)((normal.z+1.0)*127.0) ); Color result( (uint8_t)((normal.x+1.0)*127.0), (uint8_t)((normal.y+1.0)*127.0), (uint8_t)((normal.z+1.0)*127.0) );
normalmap.put_pixel( x, y, result ); normalmap.put_pixel( x, y, result );
} }
} }
*/ */
*this=normalmap; *this=normalmap;
@ -1071,14 +1131,14 @@ bool Image::empty() const {
} }
DVector<uint8_t> Image::get_data() const { DVector<uint8_t> Image::get_data() const {
return data; return data;
} }
void Image::create(int p_width, int p_height, bool p_use_mipmaps,Format p_format) { void Image::create(int p_width, int p_height, bool p_use_mipmaps,Format p_format) {
int mm=0; int mm=0;
int size = _get_dst_image_size(p_width,p_height,p_format,mm,p_use_mipmaps?-1:0); int size = _get_dst_image_size(p_width,p_height,p_format,mm,p_use_mipmaps?-1:0);
data.resize( size ); data.resize( size );
{ {
@ -1095,7 +1155,7 @@ void Image::create(int p_width, int p_height, bool p_use_mipmaps,Format p_format
} }
void Image::create(int p_width, int p_height, int p_mipmaps, Format p_format, const DVector<uint8_t>& p_data) { void Image::create(int p_width, int p_height, int p_mipmaps, Format p_format, const DVector<uint8_t>& p_data) {
ERR_FAIL_INDEX(p_width-1,MAX_WIDTH); ERR_FAIL_INDEX(p_width-1,MAX_WIDTH);
ERR_FAIL_INDEX(p_height-1,MAX_HEIGHT); ERR_FAIL_INDEX(p_height-1,MAX_HEIGHT);
@ -1108,48 +1168,48 @@ void Image::create(int p_width, int p_height, int p_mipmaps, Format p_format, co
ERR_FAIL_COND(p_data.size()!=size); ERR_FAIL_COND(p_data.size()!=size);
} }
}; };
height=p_height; height=p_height;
width=p_width; width=p_width;
format=p_format; format=p_format;
data=p_data; data=p_data;
mipmaps=p_mipmaps; mipmaps=p_mipmaps;
} }
void Image::create( const char ** p_xpm ) { void Image::create( const char ** p_xpm ) {
int size_width,size_height; int size_width,size_height;
int pixelchars=0; int pixelchars=0;
mipmaps=0; mipmaps=0;
bool has_alpha=false; bool has_alpha=false;
enum Status { enum Status {
READING_HEADER, READING_HEADER,
READING_COLORS, READING_COLORS,
READING_PIXELS, READING_PIXELS,
DONE DONE
}; };
Status status = READING_HEADER; Status status = READING_HEADER;
int line=0; int line=0;
HashMap<String,Color> colormap; HashMap<String,Color> colormap;
int colormap_size; int colormap_size;
while (status!=DONE) { while (status!=DONE) {
const char * line_ptr = p_xpm[line]; const char * line_ptr = p_xpm[line];
switch (status) { switch (status) {
case READING_HEADER: { case READING_HEADER: {
String line_str=line_ptr; String line_str=line_ptr;
line_str.replace("\t"," "); line_str.replace("\t"," ");
size_width=line_str.get_slicec(' ',0).to_int(); size_width=line_str.get_slicec(' ',0).to_int();
size_height=line_str.get_slicec(' ',1).to_int(); size_height=line_str.get_slicec(' ',1).to_int();
colormap_size=line_str.get_slicec(' ',2).to_int(); colormap_size=line_str.get_slicec(' ',2).to_int();
@ -1161,10 +1221,10 @@ void Image::create( const char ** p_xpm ) {
status=READING_COLORS; status=READING_COLORS;
} break; } break;
case READING_COLORS: { case READING_COLORS: {
String colorstring; String colorstring;
for (int i=0;i<pixelchars;i++) { for (int i=0;i<pixelchars;i++) {
colorstring+=*line_ptr; colorstring+=*line_ptr;
line_ptr++; line_ptr++;
} }
@ -1175,25 +1235,25 @@ void Image::create( const char ** p_xpm ) {
line_ptr++; line_ptr++;
} }
if (*line_ptr=='c') { if (*line_ptr=='c') {
line_ptr++; line_ptr++;
while (*line_ptr==' ' || *line_ptr=='\t' || *line_ptr==0) { while (*line_ptr==' ' || *line_ptr=='\t' || *line_ptr==0) {
if (*line_ptr==0) if (*line_ptr==0)
break; break;
line_ptr++; line_ptr++;
} }
if (*line_ptr=='#') { if (*line_ptr=='#') {
line_ptr++; line_ptr++;
uint8_t col_r; uint8_t col_r;
uint8_t col_g; uint8_t col_g;
uint8_t col_b; uint8_t col_b;
// uint8_t col_a=255; // uint8_t col_a=255;
for (int i=0;i<6;i++) { for (int i=0;i<6;i++) {
char v = line_ptr[i]; char v = line_ptr[i];
if (v>='0' && v<='9') if (v>='0' && v<='9')
v-='0'; v-='0';
else if (v>='A' && v<='F') else if (v>='A' && v<='F')
@ -1202,7 +1262,7 @@ void Image::create( const char ** p_xpm ) {
v=(v-'a')+10; v=(v-'a')+10;
else else
break; break;
switch(i) { switch(i) {
case 0: col_r=v<<4; break; case 0: col_r=v<<4; break;
case 1: col_r|=v; break; case 1: col_r|=v; break;
@ -1211,48 +1271,48 @@ void Image::create( const char ** p_xpm ) {
case 4: col_b=v<<4; break; case 4: col_b=v<<4; break;
case 5: col_b|=v; break; case 5: col_b|=v; break;
}; };
} }
// magenta mask // magenta mask
if (col_r==255 && col_g==0 && col_b==255) { if (col_r==255 && col_g==0 && col_b==255) {
colormap[colorstring]=Color(0,0,0,0); colormap[colorstring]=Color(0,0,0,0);
has_alpha=true; has_alpha=true;
} else { } else {
colormap[colorstring]=Color(col_r/255.0,col_g/255.0,col_b/255.0,1.0); colormap[colorstring]=Color(col_r/255.0,col_g/255.0,col_b/255.0,1.0);
} }
} }
} }
if (line==colormap_size) { if (line==colormap_size) {
status=READING_PIXELS; status=READING_PIXELS;
create(size_width,size_height,0,has_alpha?FORMAT_RGBA:FORMAT_RGB); create(size_width,size_height,0,has_alpha?FORMAT_RGBA:FORMAT_RGB);
} }
} break; } break;
case READING_PIXELS: { case READING_PIXELS: {
int y=line-colormap_size-1; int y=line-colormap_size-1;
for (int x=0;x<size_width;x++) { for (int x=0;x<size_width;x++) {
char pixelstr[6]={0,0,0,0,0,0}; char pixelstr[6]={0,0,0,0,0,0};
for (int i=0;i<pixelchars;i++) for (int i=0;i<pixelchars;i++)
pixelstr[i]=line_ptr[x*pixelchars+i]; pixelstr[i]=line_ptr[x*pixelchars+i];
Color *colorptr = colormap.getptr(pixelstr); Color *colorptr = colormap.getptr(pixelstr);
ERR_FAIL_COND(!colorptr); ERR_FAIL_COND(!colorptr);
put_pixel(x,y,*colorptr); put_pixel(x,y,*colorptr);
} }
if (y==(size_height-1)) if (y==(size_height-1))
status=DONE; status=DONE;
} break; } break;
default:{} default:{}
} }
line++; line++;
} }
} }
@ -1637,8 +1697,17 @@ Error Image::_decompress_bc() {
print_line("decompressing bc"); print_line("decompressing bc");
int wd=width,ht=height;
if (wd%4!=0) {
wd+=4-(wd%4);
}
if (ht%4!=0) {
ht+=4-(ht%4);
}
int mm; int mm;
int size = _get_dst_image_size(width,height,FORMAT_RGBA,mm,mipmaps); int size = _get_dst_image_size(wd,ht,FORMAT_RGBA,mm,mipmaps);
DVector<uint8_t> newdata; DVector<uint8_t> newdata;
newdata.resize(size); newdata.resize(size);
@ -1648,7 +1717,8 @@ Error Image::_decompress_bc() {
int rofs=0; int rofs=0;
int wofs=0; int wofs=0;
int wd=width,ht=height;
//print_line("width: "+itos(wd)+" height: "+itos(ht));
for(int i=0;i<=mm;i++) { for(int i=0;i<=mm;i++) {
@ -1953,6 +2023,11 @@ Error Image::_decompress_bc() {
data=newdata; data=newdata;
format=FORMAT_RGBA; format=FORMAT_RGBA;
if (wd!=width || ht!=height) {
//todo, crop
width=wd;
height=ht;
}
return OK; return OK;
} }
@ -2022,7 +2097,7 @@ Image Image::compressed(int p_mode) {
}; };
Image::Image(const char **p_xpm) { Image::Image(const char **p_xpm) {
width=0; width=0;
height=0; height=0;
mipmaps=0; mipmaps=0;

View File

@ -46,7 +46,7 @@ typedef Error (*SavePNGFunc)(const String &p_path, Image& p_img);
class Image { class Image {
enum { enum {
MAX_WIDTH=16384, // force a limit somehow MAX_WIDTH=16384, // force a limit somehow
MAX_HEIGHT=16384// force a limit somehow MAX_HEIGHT=16384// force a limit somehow
}; };
@ -55,12 +55,12 @@ public:
static SavePNGFunc save_png_func; static SavePNGFunc save_png_func;
enum Format { enum Format {
FORMAT_GRAYSCALE, ///< one byte per pixel, 0-255 FORMAT_GRAYSCALE, ///< one byte per pixel, 0-255
FORMAT_INTENSITY, ///< one byte per pixel, 0-255 FORMAT_INTENSITY, ///< one byte per pixel, 0-255
FORMAT_GRAYSCALE_ALPHA, ///< two bytes per pixel, 0-255. alpha 0-255 FORMAT_GRAYSCALE_ALPHA, ///< two bytes per pixel, 0-255. alpha 0-255
FORMAT_RGB, ///< one byte R, one byte G, one byte B FORMAT_RGB, ///< one byte R, one byte G, one byte B
FORMAT_RGBA, ///< one byte R, one byte G, one byte B, one byte A FORMAT_RGBA, ///< one byte R, one byte G, one byte B, one byte A
FORMAT_INDEXED, ///< index byte 0-256, and after image end, 256*3 bytes of palette FORMAT_INDEXED, ///< index byte 0-256, and after image end, 256*3 bytes of palette
FORMAT_INDEXED_ALPHA, ///< index byte 0-256, and after image end, 256*4 bytes of palette (alpha) FORMAT_INDEXED_ALPHA, ///< index byte 0-256, and after image end, 256*4 bytes of palette (alpha)
FORMAT_YUV_422, FORMAT_YUV_422,
FORMAT_YUV_444, FORMAT_YUV_444,
@ -89,7 +89,7 @@ public:
static const char* format_names[FORMAT_MAX]; static const char* format_names[FORMAT_MAX];
enum Interpolation { enum Interpolation {
INTERPOLATE_NEAREST, INTERPOLATE_NEAREST,
INTERPOLATE_BILINEAR, INTERPOLATE_BILINEAR,
INTERPOLATE_CUBIC, INTERPOLATE_CUBIC,
@ -186,7 +186,7 @@ private:
DVector<uint8_t> data; DVector<uint8_t> data;
int width,height,mipmaps; int width,height,mipmaps;
_FORCE_INLINE_ BColor _get_pixel(int p_x,int p_y,const unsigned char *p_data,int p_data_size) const; _FORCE_INLINE_ BColor _get_pixel(int p_x,int p_y,const unsigned char *p_data,int p_data_size) const;
_FORCE_INLINE_ BColor _get_pixelw(int p_x,int p_y,int p_width,const unsigned char *p_data,int p_data_size) const; _FORCE_INLINE_ BColor _get_pixelw(int p_x,int p_y,int p_width,const unsigned char *p_data,int p_data_size) const;
@ -207,7 +207,7 @@ public:
int get_width() const; ///< Get image width int get_width() const; ///< Get image width
int get_height() const; ///< Get image height int get_height() const; ///< Get image height
int get_mipmaps() const; int get_mipmaps() const;
/** /**
* Get a pixel from the image. for grayscale or indexed formats, use Color::gray to obtain the actual * Get a pixel from the image. for grayscale or indexed formats, use Color::gray to obtain the actual
* value. * value.
@ -217,7 +217,7 @@ public:
* Set a pixel into the image. for grayscale or indexed formats, a suitable Color constructor. * Set a pixel into the image. for grayscale or indexed formats, a suitable Color constructor.
*/ */
void put_pixel(int p_x,int p_y, const Color& p_color,int p_mipmap=0); /* alpha and index are averaged */ void put_pixel(int p_x,int p_y, const Color& p_color,int p_mipmap=0); /* alpha and index are averaged */
/** /**
* Convert the image to another format, as close as it can be done. * Convert the image to another format, as close as it can be done.
*/ */
@ -230,7 +230,7 @@ public:
ret.convert((Format)p_new_format); ret.convert((Format)p_new_format);
return ret; return ret;
}; };
/** /**
* Get the current image format. * Get the current image format.
*/ */
@ -243,31 +243,32 @@ public:
/** /**
* Resize the image, using the prefered interpolation method. * Resize the image, using the prefered interpolation method.
* Indexed-Color images always use INTERPOLATE_NEAREST. * Indexed-Color images always use INTERPOLATE_NEAREST.
*/ */
void resize_to_po2(bool p_square=false); void resize_to_po2(bool p_square=false);
void resize( int p_width, int p_height, Interpolation p_interpolation=INTERPOLATE_BILINEAR ); void resize( int p_width, int p_height, Interpolation p_interpolation=INTERPOLATE_BILINEAR );
Image resized( int p_width, int p_height, int p_interpolation=INTERPOLATE_BILINEAR ); Image resized( int p_width, int p_height, int p_interpolation=INTERPOLATE_BILINEAR );
void shrink_x2();
/** /**
* Crop the image to a specific size, if larger, then the image is filled by black * Crop the image to a specific size, if larger, then the image is filled by black
*/ */
void crop( int p_width, int p_height ); void crop( int p_width, int p_height );
void flip_x(); void flip_x();
void flip_y(); void flip_y();
/** /**
* Generate a mipmap to an image (creates an image 1/4 the size, with averaging of 4->1) * Generate a mipmap to an image (creates an image 1/4 the size, with averaging of 4->1)
*/ */
Error generate_mipmaps(int p_amount=-1,bool p_keep_existing=false); Error generate_mipmaps(int p_amount=-1,bool p_keep_existing=false);
void clear_mipmaps(); void clear_mipmaps();
/** /**
* Generate a normal map from a grayscale image * Generate a normal map from a grayscale image
*/ */
void make_normalmap(float p_height_scale=1.0); void make_normalmap(float p_height_scale=1.0);
/** /**
@ -276,26 +277,26 @@ public:
void create(int p_width, int p_height, bool p_use_mipmaps, Format p_format); void create(int p_width, int p_height, bool p_use_mipmaps, Format p_format);
void create(int p_width, int p_height, int p_mipmaps, Format p_format, const DVector<uint8_t>& p_data); void create(int p_width, int p_height, int p_mipmaps, Format p_format, const DVector<uint8_t>& p_data);
void create( const char ** p_xpm ); void create( const char ** p_xpm );
/** /**
* returns true when the image is empty (0,0) in size * returns true when the image is empty (0,0) in size
*/ */
bool empty() const; bool empty() const;
DVector<uint8_t> get_data() const; DVector<uint8_t> get_data() const;
Error load(const String& p_path); Error load(const String& p_path);
Error save_png(const String& p_path); Error save_png(const String& p_path);
/** /**
* create an empty image * create an empty image
*/ */
Image(); Image();
/** /**
* create an empty image of a specific size and format * create an empty image of a specific size and format
*/ */
Image(int p_width, int p_height, bool p_use_mipmaps, Format p_format); Image(int p_width, int p_height, bool p_use_mipmaps, Format p_format);
/** /**
* import an image of a specific size and format from a pointer * import an image of a specific size and format from a pointer
*/ */
Image(int p_width, int p_height, int p_mipmaps, Format p_format, const DVector<uint8_t>& p_data); Image(int p_width, int p_height, int p_mipmaps, Format p_format, const DVector<uint8_t>& p_data);
@ -313,7 +314,7 @@ public:
uint8_t get_indexed_pixel(int p_x, int p_y,int p_mipmap=0) const; uint8_t get_indexed_pixel(int p_x, int p_y,int p_mipmap=0) const;
void set_pallete(const DVector<uint8_t>& p_data); void set_pallete(const DVector<uint8_t>& p_data);
static int get_format_pixel_size(Format p_format); static int get_format_pixel_size(Format p_format);
static int get_format_pixel_rshift(Format p_format); static int get_format_pixel_rshift(Format p_format);
static int get_format_pallete_size(Format p_format); static int get_format_pallete_size(Format p_format);

View File

@ -28,6 +28,7 @@
/*************************************************************************/ /*************************************************************************/
#include "input_map.h" #include "input_map.h"
#include "globals.h" #include "globals.h"
#include "os/keyboard.h"
InputMap *InputMap::singleton=NULL; InputMap *InputMap::singleton=NULL;
@ -36,9 +37,10 @@ void InputMap::_bind_methods() {
ObjectTypeDB::bind_method(_MD("has_action","action"),&InputMap::has_action); ObjectTypeDB::bind_method(_MD("has_action","action"),&InputMap::has_action);
ObjectTypeDB::bind_method(_MD("get_action_id","action"),&InputMap::get_action_id); ObjectTypeDB::bind_method(_MD("get_action_id","action"),&InputMap::get_action_id);
ObjectTypeDB::bind_method(_MD("get_action_from_id","id"),&InputMap::get_action_from_id); ObjectTypeDB::bind_method(_MD("get_action_from_id","id"),&InputMap::get_action_from_id);
ObjectTypeDB::bind_method(_MD("get_actions"),&InputMap::_get_actions);
ObjectTypeDB::bind_method(_MD("add_action","action"),&InputMap::add_action); ObjectTypeDB::bind_method(_MD("add_action","action"),&InputMap::add_action);
ObjectTypeDB::bind_method(_MD("erase_action","action"),&InputMap::erase_action); ObjectTypeDB::bind_method(_MD("erase_action","action"),&InputMap::erase_action);
ObjectTypeDB::bind_method(_MD("action_add_event","action","event"),&InputMap::action_add_event); ObjectTypeDB::bind_method(_MD("action_add_event","action","event"),&InputMap::action_add_event);
ObjectTypeDB::bind_method(_MD("action_has_event","action","event"),&InputMap::action_has_event); ObjectTypeDB::bind_method(_MD("action_has_event","action","event"),&InputMap::action_has_event);
ObjectTypeDB::bind_method(_MD("action_erase_event","action","event"),&InputMap::action_erase_event); ObjectTypeDB::bind_method(_MD("action_erase_event","action","event"),&InputMap::action_erase_event);
@ -75,6 +77,35 @@ StringName InputMap::get_action_from_id(int p_id) const {
return input_id_map[p_id]; return input_id_map[p_id];
} }
Array InputMap::_get_actions() {
Array ret;
List<StringName> actions = get_actions();
if(actions.empty())
return ret;
for(const List<StringName>::Element *E=actions.front();E;E=E->next()) {
ret.push_back(E->get());
}
return ret;
}
List<StringName> InputMap::get_actions() const {
List<StringName> actions = List<StringName>();
if(input_map.empty()){
return actions;
}
for (Map<StringName, Action>::Element *E=input_map.front();E;E=E->next()) {
actions.push_back(E->key());
}
return actions;
}
List<InputEvent>::Element *InputMap::_find_event(List<InputEvent> &p_list,const InputEvent& p_event) const { List<InputEvent>::Element *InputMap::_find_event(List<InputEvent> &p_list,const InputEvent& p_event) const {
for (List<InputEvent>::Element *E=p_list.front();E;E=E->next()) { for (List<InputEvent>::Element *E=p_list.front();E;E=E->next()) {
@ -106,7 +137,7 @@ List<InputEvent>::Element *InputMap::_find_event(List<InputEvent> &p_list,const
} break; } break;
case InputEvent::JOYSTICK_MOTION: { case InputEvent::JOYSTICK_MOTION: {
same=(e.joy_motion.axis==p_event.joy_motion.axis); same=(e.joy_motion.axis==p_event.joy_motion.axis && (e.joy_motion.axis_value < 0) == (p_event.joy_motion.axis_value < 0));
} break; } break;
} }
@ -156,10 +187,7 @@ void InputMap::action_erase_event(const StringName& p_action,const InputEvent& p
List<InputEvent>::Element *E=_find_event(input_map[p_action].inputs,p_event); List<InputEvent>::Element *E=_find_event(input_map[p_action].inputs,p_event);
if (E) if (E)
return; //already gots input_map[p_action].inputs.erase(E);
input_map[p_action].inputs.erase(E);
} }
@ -292,6 +320,67 @@ void InputMap::load_from_globals() {
} }
}
void InputMap::load_default() {
InputEvent key;
key.type=InputEvent::KEY;
add_action("ui_accept");
key.key.scancode=KEY_RETURN;
action_add_event("ui_accept",key);
key.key.scancode=KEY_ENTER;
action_add_event("ui_accept",key);
key.key.scancode=KEY_SPACE;
action_add_event("ui_accept",key);
add_action("ui_select");
key.key.scancode=KEY_SPACE;
action_add_event("ui_select",key);
add_action("ui_cancel");
key.key.scancode=KEY_ESCAPE;
action_add_event("ui_cancel",key);
add_action("ui_focus_next");
key.key.scancode=KEY_TAB;
action_add_event("ui_focus_next",key);
add_action("ui_focus_prev");
key.key.scancode=KEY_TAB;
key.key.mod.shift=true;
action_add_event("ui_focus_prev",key);
key.key.mod.shift=false;
add_action("ui_left");
key.key.scancode=KEY_LEFT;
action_add_event("ui_left",key);
add_action("ui_right");
key.key.scancode=KEY_RIGHT;
action_add_event("ui_right",key);
add_action("ui_up");
key.key.scancode=KEY_UP;
action_add_event("ui_up",key);
add_action("ui_down");
key.key.scancode=KEY_DOWN;
action_add_event("ui_down",key);
add_action("ui_page_up");
key.key.scancode=KEY_PAGEUP;
action_add_event("ui_page_up",key);
add_action("ui_page_down");
key.key.scancode=KEY_PAGEDOWN;
action_add_event("ui_page_down",key);
// set("display/orientation", "landscape");
} }
InputMap::InputMap() { InputMap::InputMap() {

View File

@ -47,6 +47,7 @@ class InputMap : public Object {
List<InputEvent>::Element *_find_event(List<InputEvent> &p_list,const InputEvent& p_event) const; List<InputEvent>::Element *_find_event(List<InputEvent> &p_list,const InputEvent& p_event) const;
Array _get_action_list(const StringName& p_action); Array _get_action_list(const StringName& p_action);
Array _get_actions();
protected: protected:
@ -59,6 +60,7 @@ public:
bool has_action(const StringName& p_action) const; bool has_action(const StringName& p_action) const;
int get_action_id(const StringName& p_action) const; int get_action_id(const StringName& p_action) const;
StringName get_action_from_id(int p_id) const; StringName get_action_from_id(int p_id) const;
List<StringName> get_actions() const;
void add_action(const StringName& p_action); void add_action(const StringName& p_action);
void erase_action(const StringName& p_action); void erase_action(const StringName& p_action);
@ -72,6 +74,7 @@ public:
void load_from_globals(); void load_from_globals();
void load_default();
InputMap(); InputMap();
}; };

View File

@ -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.

View File

@ -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.
----------------------------------------------------------------------------

View File

@ -1,6 +1,6 @@
/* /*
* Byte-oriented AES-256 implementation. * Byte-oriented AES-256 implementation.
* All lookup tables replaced with 'on the fly' calculations. * All lookup tables replaced with 'on the fly' calculations.
* *
* Copyright (c) 2007-2009 Ilya O. Levin, http://www.literatecode.com * Copyright (c) 2007-2009 Ilya O. Levin, http://www.literatecode.com
* Other contributors: Hal Finney * Other contributors: Hal Finney
@ -24,14 +24,14 @@
#include "typedefs.h" #include "typedefs.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
typedef struct { typedef struct {
uint8_t key[32]; uint8_t key[32];
uint8_t enckey[32]; uint8_t enckey[32];
uint8_t deckey[32]; uint8_t deckey[32];
} aes256_context; } aes256_context;
void aes256_init(aes256_context *, uint8_t * /* key */); void aes256_init(aes256_context *, uint8_t * /* key */);

View File

@ -207,7 +207,7 @@ Error ConfigFile::load(const String& p_path) {
void ConfigFile::_bind_methods(){ void ConfigFile::_bind_methods(){
ObjectTypeDB::bind_method(_MD("set_value","section","key","value"),&ConfigFile::set_value); ObjectTypeDB::bind_method(_MD("set_value","section","key","value"),&ConfigFile::set_value);
ObjectTypeDB::bind_method(_MD("get_value","section","key","default"),&ConfigFile::get_value,DEFVAL(Variant())); ObjectTypeDB::bind_method(_MD("get_value:Variant","section","key","default"),&ConfigFile::get_value,DEFVAL(Variant()));
ObjectTypeDB::bind_method(_MD("has_section","section"),&ConfigFile::has_section); ObjectTypeDB::bind_method(_MD("has_section","section"),&ConfigFile::has_section);
ObjectTypeDB::bind_method(_MD("has_section_key","section","key"),&ConfigFile::has_section_key); ObjectTypeDB::bind_method(_MD("has_section_key","section","key"),&ConfigFile::has_section_key);

View File

@ -1,4 +1,4 @@
/* /*
FastLZ - lightning-fast lossless compression library FastLZ - lightning-fast lossless compression library
Copyright (C) 2007 Ariya Hidayat (ariya@kde.org) Copyright (C) 2007 Ariya Hidayat (ariya@kde.org)
@ -40,11 +40,11 @@ extern "C" {
#endif #endif
/** /**
Compress a block of data in the input buffer and returns the size of Compress a block of data in the input buffer and returns the size of
compressed block. The size of input buffer is specified by length. The compressed block. The size of input buffer is specified by length. The
minimum input buffer size is 16. minimum input buffer size is 16.
The output buffer must be at least 5% larger than the input buffer The output buffer must be at least 5% larger than the input buffer
and can not be smaller than 66 bytes. and can not be smaller than 66 bytes.
If the input is not compressible, the return value might be larger than If the input is not compressible, the return value might be larger than
@ -56,9 +56,9 @@ extern "C" {
int fastlz_compress(const void* input, int length, void* output); int fastlz_compress(const void* input, int length, void* output);
/** /**
Decompress a block of compressed data and returns the size of the Decompress a block of compressed data and returns the size of the
decompressed block. If error occurs, e.g. the compressed data is decompressed block. If error occurs, e.g. the compressed data is
corrupted or the output buffer is not large enough, then 0 (zero) corrupted or the output buffer is not large enough, then 0 (zero)
will be returned instead. will be returned instead.
The input buffer and the output buffer can not overlap. The input buffer and the output buffer can not overlap.
@ -67,14 +67,14 @@ int fastlz_compress(const void* input, int length, void* output);
more than what is specified in maxout. more than what is specified in maxout.
*/ */
int fastlz_decompress(const void* input, int length, void* output, int maxout); int fastlz_decompress(const void* input, int length, void* output, int maxout);
/** /**
Compress a block of data in the input buffer and returns the size of Compress a block of data in the input buffer and returns the size of
compressed block. The size of input buffer is specified by length. The compressed block. The size of input buffer is specified by length. The
minimum input buffer size is 16. minimum input buffer size is 16.
The output buffer must be at least 5% larger than the input buffer The output buffer must be at least 5% larger than the input buffer
and can not be smaller than 66 bytes. and can not be smaller than 66 bytes.
If the input is not compressible, the return value might be larger than If the input is not compressible, the return value might be larger than
@ -82,14 +82,14 @@ int fastlz_decompress(const void* input, int length, void* output, int maxout);
The input buffer and the output buffer can not overlap. The input buffer and the output buffer can not overlap.
Compression level can be specified in parameter level. At the moment, Compression level can be specified in parameter level. At the moment,
only level 1 and level 2 are supported. only level 1 and level 2 are supported.
Level 1 is the fastest compression and generally useful for short data. Level 1 is the fastest compression and generally useful for short data.
Level 2 is slightly slower but it gives better compression ratio. Level 2 is slightly slower but it gives better compression ratio.
Note that the compressed data, regardless of the level, can always be Note that the compressed data, regardless of the level, can always be
decompressed using the function fastlz_decompress above. decompressed using the function fastlz_decompress above.
*/ */
int fastlz_compress_level(int level, const void* input, int length, void* output); int fastlz_compress_level(int level, const void* input, int length, void* output);

View File

@ -33,17 +33,17 @@
#include "error_macros.h" #include "error_macros.h"
Error FileAccessBuffered::set_error(Error p_error) const { Error FileAccessBuffered::set_error(Error p_error) const {
return (last_error = p_error); return (last_error = p_error);
}; };
void FileAccessBuffered::set_cache_size(int p_size) { void FileAccessBuffered::set_cache_size(int p_size) {
cache_size = p_size; cache_size = p_size;
}; };
int FileAccessBuffered::get_cache_size() { int FileAccessBuffered::get_cache_size() {
return cache_size; return cache_size;
}; };
@ -66,27 +66,27 @@ int FileAccessBuffered::cache_data_left() const {
}; };
void FileAccessBuffered::seek(size_t p_position) { void FileAccessBuffered::seek(size_t p_position) {
file.offset = p_position; file.offset = p_position;
}; };
void FileAccessBuffered::seek_end(int64_t p_position) { void FileAccessBuffered::seek_end(int64_t p_position) {
file.offset = file.size + p_position; file.offset = file.size + p_position;
}; };
size_t FileAccessBuffered::get_pos() const { size_t FileAccessBuffered::get_pos() const {
return file.offset; return file.offset;
}; };
size_t FileAccessBuffered::get_len() const { size_t FileAccessBuffered::get_len() const {
return file.size; return file.size;
}; };
bool FileAccessBuffered::eof_reached() const { bool FileAccessBuffered::eof_reached() const {
return file.offset > file.size; return file.offset > file.size;
}; };
@ -165,12 +165,12 @@ int FileAccessBuffered::get_buffer(uint8_t *p_dest,int p_elements) const {
}; };
bool FileAccessBuffered::is_open() const { bool FileAccessBuffered::is_open() const {
return file.open; return file.open;
}; };
Error FileAccessBuffered::get_error() const { Error FileAccessBuffered::get_error() const {
return last_error; return last_error;
}; };
@ -180,5 +180,5 @@ FileAccessBuffered::FileAccessBuffered() {
}; };
FileAccessBuffered::~FileAccessBuffered(){ FileAccessBuffered::~FileAccessBuffered(){
} }

View File

@ -60,9 +60,9 @@ protected:
String name; String name;
int access_flags; int access_flags;
} file; } file;
mutable struct Cache { mutable struct Cache {
Vector<uint8_t> buffer; Vector<uint8_t> buffer;
int offset; int offset;
} cache; } cache;
@ -71,7 +71,7 @@ protected:
void set_cache_size(int p_size); void set_cache_size(int p_size);
int get_cache_size(); int get_cache_size();
public: public:
virtual size_t get_pos() const; ///< get position in the file virtual size_t get_pos() const; ///< get position in the file

View File

@ -217,7 +217,7 @@ Error FileAccessNetworkClient::connect(const String& p_host,int p_port,const Str
return ERR_CANT_CONNECT; return ERR_CANT_CONNECT;
} }
CharString cs = p_password.utf8(); CharString cs = p_password.utf8();
put_32(cs.length()); put_32(cs.length());
client->put_data((const uint8_t*)cs.ptr(),cs.length()); client->put_data((const uint8_t*)cs.ptr(),cs.length());

View File

@ -81,6 +81,7 @@ void HTTPClient::set_connection(const Ref<StreamPeer>& p_connection){
close(); close();
connection=p_connection; connection=p_connection;
status=STATUS_CONNECTED;
} }
@ -301,6 +302,7 @@ Error HTTPClient::poll(){
chunked=false; chunked=false;
body_left=0; body_left=0;
chunk_left=0; chunk_left=0;
response_str.clear();
response_headers.clear(); response_headers.clear();
response_num = RESPONSE_OK; response_num = RESPONSE_OK;
@ -309,7 +311,7 @@ Error HTTPClient::poll(){
String header = responses[i].strip_edges(); String header = responses[i].strip_edges();
String s = header.to_lower(); String s = header.to_lower();
if (s.length()==0) if (s.length()==0)
continue; continue;
if (s.begins_with("content-length:")) { if (s.begins_with("content-length:")) {
body_size = s.substr(s.find(":")+1,s.length()).strip_edges().to_int(); body_size = s.substr(s.find(":")+1,s.length()).strip_edges().to_int();
body_left=body_size; body_left=body_size;

View File

@ -40,7 +40,7 @@ class HTTPClient : public Reference {
OBJ_TYPE(HTTPClient,Reference); OBJ_TYPE(HTTPClient,Reference);
public: public:
enum RespondeCode { enum ResponseCode {
// 1xx informational // 1xx informational
RESPONSE_CONTINUE = 100, RESPONSE_CONTINUE = 100,

View File

@ -30,16 +30,16 @@
#include "print_string.h" #include "print_string.h"
bool ImageFormatLoader::recognize(const String& p_extension) const { bool ImageFormatLoader::recognize(const String& p_extension) const {
List<String> extensions; List<String> extensions;
get_recognized_extensions(&extensions); get_recognized_extensions(&extensions);
for (List<String>::Element *E=extensions.front();E;E=E->next()) { for (List<String>::Element *E=extensions.front();E;E=E->next()) {
if (E->get().nocasecmp_to(p_extension.extension())==0) if (E->get().nocasecmp_to(p_extension.extension())==0)
return true; return true;
} }
return false; return false;
} }
@ -55,12 +55,12 @@ Error ImageLoader::load_image(String p_file,Image *p_image, FileAccess *p_custom
return err; return err;
} }
} }
String extension = p_file.extension(); String extension = p_file.extension();
for (int i=0;i<loader_count;i++) { for (int i=0;i<loader_count;i++) {
if (!loader[i]->recognize(extension)) if (!loader[i]->recognize(extension))
continue; continue;
Error err = loader[i]->load_image(p_image,f); Error err = loader[i]->load_image(p_image,f);
@ -73,25 +73,25 @@ Error ImageLoader::load_image(String p_file,Image *p_image, FileAccess *p_custom
return err; return err;
} }
} }
print_line("NO LOADER?"); print_line("NO LOADER?");
if (!p_custom) if (!p_custom)
memdelete(f); memdelete(f);
return ERR_FILE_UNRECOGNIZED; return ERR_FILE_UNRECOGNIZED;
} }
void ImageLoader::get_recognized_extensions(List<String> *p_extensions) { void ImageLoader::get_recognized_extensions(List<String> *p_extensions) {
for (int i=0;i<loader_count;i++) { for (int i=0;i<loader_count;i++) {
loader[i]->get_recognized_extensions(p_extensions); loader[i]->get_recognized_extensions(p_extensions);
} }
} }
bool ImageLoader::recognize(const String& p_extension) { bool ImageLoader::recognize(const String& p_extension) {

View File

@ -41,11 +41,11 @@
/** /**
* @class ImageScanLineLoader * @class ImageScanLineLoader
* @author Juan Linietsky <reduzio@gmail.com> * @author Juan Linietsky <reduzio@gmail.com>
* *
*/ */
class ImageLoader; class ImageLoader;
/** /**
* @class ImageLoader * @class ImageLoader
@ -60,8 +60,8 @@ protected:
virtual Error load_image(Image *p_image,FileAccess *p_fileaccess)=0; virtual Error load_image(Image *p_image,FileAccess *p_fileaccess)=0;
virtual void get_recognized_extensions(List<String> *p_extensions) const=0; virtual void get_recognized_extensions(List<String> *p_extensions) const=0;
bool recognize(const String& p_extension) const; bool recognize(const String& p_extension) const;
public: public:
virtual ~ImageFormatLoader() {} virtual ~ImageFormatLoader() {}
}; };
@ -79,11 +79,11 @@ protected:
public: public:
static Error load_image(String p_file,Image *p_image, FileAccess *p_custom=NULL); static Error load_image(String p_file,Image *p_image, FileAccess *p_custom=NULL);
static void get_recognized_extensions(List<String> *p_extensions) ; static void get_recognized_extensions(List<String> *p_extensions) ;
static bool recognize(const String& p_extension) ; static bool recognize(const String& p_extension) ;
static void add_image_format_loader(ImageFormatLoader *p_loader); static void add_image_format_loader(ImageFormatLoader *p_loader);
}; };

View File

@ -6,7 +6,7 @@
Modifications for Zip64 support Modifications for Zip64 support
Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
For more info read MiniZip_info.txt For more info read LICENSE-MiniZip.txt
*/ */

View File

@ -5,7 +5,7 @@
Modifications for Zip64 support Modifications for Zip64 support
Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
For more info read MiniZip_info.txt For more info read LICENSE-MiniZip.txt
Changes Changes

View File

@ -49,7 +49,7 @@ struct _IP_ResolverPrivate {
response = IP_Address(); response = IP_Address();
hostname=""; hostname="";
}; };
QueueItem() { QueueItem() {
clear(); clear();
}; };

View File

@ -95,7 +95,7 @@ Error decode_variant(Variant& r_variant,const uint8_t *p_buffer, int p_len,int *
str.parse_utf8((const char*)buf,strlen); str.parse_utf8((const char*)buf,strlen);
r_variant=str; r_variant=str;
if (r_len) { if (r_len) {
if (strlen%4) if (strlen%4)
(*r_len)+=4-strlen%4; (*r_len)+=4-strlen%4;
(*r_len)+=4+strlen; (*r_len)+=4+strlen;
@ -294,7 +294,7 @@ Error decode_variant(Variant& r_variant,const uint8_t *p_buffer, int p_len,int *
} break; } break;
case Variant::NODE_PATH: { case Variant::NODE_PATH: {
ERR_FAIL_COND_V(len<4,ERR_INVALID_DATA); ERR_FAIL_COND_V(len<4,ERR_INVALID_DATA);
uint32_t strlen = decode_uint32(buf); uint32_t strlen = decode_uint32(buf);
if (strlen&0x80000000) { if (strlen&0x80000000) {
@ -438,8 +438,9 @@ Error decode_variant(Variant& r_variant,const uint8_t *p_buffer, int p_len,int *
case InputEvent::JOYSTICK_MOTION: { case InputEvent::JOYSTICK_MOTION: {
ie.joy_motion.axis=decode_uint32(&buf[12]); ie.joy_motion.axis=decode_uint32(&buf[12]);
ie.joy_motion.axis_value=decode_float(&buf[16]);
if (r_len) if (r_len)
(*r_len)+=4; (*r_len)+=8;
} break; } break;
} }
@ -1077,7 +1078,7 @@ Error encode_variant(const Variant& p_variant, uint8_t *r_buffer, int &r_len) {
r_len+=data.size()+5*4+pad; r_len+=data.size()+5*4+pad;
} break; } break;
/*case Variant::RESOURCE: { /*case Variant::RESOURCE: {
ERR_EXPLAIN("Can't marshallize resources"); ERR_EXPLAIN("Can't marshallize resources");
@ -1154,8 +1155,9 @@ Error encode_variant(const Variant& p_variant, uint8_t *r_buffer, int &r_len) {
int axis = ie.joy_motion.axis; int axis = ie.joy_motion.axis;
encode_uint32(axis,&buf[llen]); encode_uint32(axis,&buf[llen]);
encode_float(ie.joy_motion.axis_value, &buf[llen+4]);
} }
llen+=4; llen+=8;
} break; } break;
} }
@ -1238,7 +1240,7 @@ Error encode_variant(const Variant& p_variant, uint8_t *r_buffer, int &r_len) {
DVector<uint8_t> data = p_variant; DVector<uint8_t> data = p_variant;
int datalen=data.size(); int datalen=data.size();
int datasize=sizeof(uint8_t); int datasize=sizeof(uint8_t);
if (buf) { if (buf) {
encode_uint32(datalen,buf); encode_uint32(datalen,buf);
buf+=4; buf+=4;

View File

@ -37,7 +37,7 @@
* Miscelaneous helpers for marshalling data types, and encoding * Miscelaneous helpers for marshalling data types, and encoding
* in an endian independent way * in an endian independent way
*/ */
union MarshallFloat { union MarshallFloat {
@ -54,22 +54,22 @@ union MarshallDouble {
static inline unsigned int encode_uint16(uint16_t p_uint, uint8_t *p_arr) { static inline unsigned int encode_uint16(uint16_t p_uint, uint8_t *p_arr) {
for (int i=0;i<2;i++) { for (int i=0;i<2;i++) {
*p_arr=p_uint&0xFF; *p_arr=p_uint&0xFF;
p_arr++; p_uint>>=8; p_arr++; p_uint>>=8;
} }
return sizeof( uint16_t ); return sizeof( uint16_t );
} }
static inline unsigned int encode_uint32(uint32_t p_uint, uint8_t *p_arr) { static inline unsigned int encode_uint32(uint32_t p_uint, uint8_t *p_arr) {
for (int i=0;i<4;i++) { for (int i=0;i<4;i++) {
*p_arr=p_uint&0xFF; *p_arr=p_uint&0xFF;
p_arr++; p_uint>>=8; p_arr++; p_uint>>=8;
} }
return sizeof( uint32_t ); return sizeof( uint32_t );
} }
@ -85,11 +85,11 @@ static inline unsigned int encode_float(float p_float, uint8_t *p_arr) {
static inline unsigned int encode_uint64(uint64_t p_uint, uint8_t *p_arr) { static inline unsigned int encode_uint64(uint64_t p_uint, uint8_t *p_arr) {
for (int i=0;i<8;i++) { for (int i=0;i<8;i++) {
*p_arr=p_uint&0xFF; *p_arr=p_uint&0xFF;
p_arr++; p_uint>>=8; p_arr++; p_uint>>=8;
} }
return sizeof(uint64_t); return sizeof(uint64_t);
} }
@ -100,25 +100,25 @@ static inline unsigned int encode_double(double p_double, uint8_t *p_arr) {
encode_uint64( md.l, p_arr ); encode_uint64( md.l, p_arr );
return sizeof(uint64_t); return sizeof(uint64_t);
} }
static inline int encode_cstring(const char *p_string, uint8_t * p_data) { static inline int encode_cstring(const char *p_string, uint8_t * p_data) {
int len=0; int len=0;
while (*p_string) { while (*p_string) {
if (p_data) { if (p_data) {
*p_data=(uint8_t)*p_string; *p_data=(uint8_t)*p_string;
p_data++; p_data++;
} }
p_string++; p_string++;
len++; len++;
}; };
if (p_data) *p_data = 0; if (p_data) *p_data = 0;
return len+1; return len+1;
} }
@ -126,35 +126,35 @@ static inline int encode_cstring(const char *p_string, uint8_t * p_data) {
static inline uint16_t decode_uint16(const uint8_t *p_arr) { static inline uint16_t decode_uint16(const uint8_t *p_arr) {
uint16_t u=0; uint16_t u=0;
for (int i=0;i<2;i++) { for (int i=0;i<2;i++) {
uint16_t b = *p_arr; uint16_t b = *p_arr;
b<<=(i*8); b<<=(i*8);
u|=b; u|=b;
p_arr++; p_arr++;
} }
return u; return u;
} }
static inline uint32_t decode_uint32(const uint8_t *p_arr) { static inline uint32_t decode_uint32(const uint8_t *p_arr) {
uint32_t u=0; uint32_t u=0;
for (int i=0;i<4;i++) { for (int i=0;i<4;i++) {
uint32_t b = *p_arr; uint32_t b = *p_arr;
b<<=(i*8); b<<=(i*8);
u|=b; u|=b;
p_arr++; p_arr++;
} }
return u; return u;
} }
static inline float decode_float(const uint8_t *p_arr) { static inline float decode_float(const uint8_t *p_arr) {
MarshallFloat mf; MarshallFloat mf;
mf.i = decode_uint32(p_arr); mf.i = decode_uint32(p_arr);
return mf.f; return mf.f;
@ -163,15 +163,15 @@ static inline float decode_float(const uint8_t *p_arr) {
static inline uint64_t decode_uint64(const uint8_t *p_arr) { static inline uint64_t decode_uint64(const uint8_t *p_arr) {
uint64_t u=0; uint64_t u=0;
for (int i=0;i<8;i++) { for (int i=0;i<8;i++) {
uint64_t b = (*p_arr)&0xFF; uint64_t b = (*p_arr)&0xFF;
b<<=(i*8); b<<=(i*8);
u|=b; u|=b;
p_arr++; p_arr++;
} }
return u; return u;
} }

View File

@ -126,7 +126,7 @@ Error PacketPeer::_get_packet_error() const {
void PacketPeer::_bind_methods() { void PacketPeer::_bind_methods() {
ObjectTypeDB::bind_method(_MD("get_var"),&PacketPeer::_bnd_get_var); ObjectTypeDB::bind_method(_MD("get_var:Variant"),&PacketPeer::_bnd_get_var);
ObjectTypeDB::bind_method(_MD("put_var", "var:Variant"),&PacketPeer::put_var); ObjectTypeDB::bind_method(_MD("put_var", "var:Variant"),&PacketPeer::put_var);
ObjectTypeDB::bind_method(_MD("get_packet"),&PacketPeer::_get_packet); ObjectTypeDB::bind_method(_MD("get_packet"),&PacketPeer::_get_packet);
ObjectTypeDB::bind_method(_MD("put_packet:Error", "buffer"),&PacketPeer::_put_packet); ObjectTypeDB::bind_method(_MD("put_packet:Error", "buffer"),&PacketPeer::_put_packet);
@ -180,10 +180,10 @@ int PacketPeerStream::get_available_packet_count() const {
ring_buffer.copy(lbuf,ofs,4); ring_buffer.copy(lbuf,ofs,4);
uint32_t len = decode_uint32(lbuf); uint32_t len = decode_uint32(lbuf);
remaining-=4; remaining-=4;
ofs+=4; ofs+=4;
if (len>remaining) if (len>remaining)
break; break;
remaining-=len; remaining-=len;
ofs+=len; ofs+=len;
count++; count++;
} }
@ -201,7 +201,7 @@ Error PacketPeerStream::get_packet(const uint8_t **r_buffer,int &r_buffer_size)
uint8_t lbuf[4]; uint8_t lbuf[4];
ring_buffer.copy(lbuf,0,4); ring_buffer.copy(lbuf,0,4);
remaining-=4; remaining-=4;
uint32_t len = decode_uint32(lbuf); uint32_t len = decode_uint32(lbuf);
ERR_FAIL_COND_V(remaining<(int)len,ERR_UNAVAILABLE); ERR_FAIL_COND_V(remaining<(int)len,ERR_UNAVAILABLE);
ring_buffer.read(lbuf,4); //get rid of first 4 bytes ring_buffer.read(lbuf,4); //get rid of first 4 bytes

View File

@ -378,7 +378,7 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant& r_v) {
} break; } break;
case OBJECT_INTERNAL_RESOURCE: { case OBJECT_INTERNAL_RESOURCE: {
uint32_t index=f->get_32(); uint32_t index=f->get_32();
String path = res_path+"::"+itos(index); String path = res_path+"::"+itos(index);
RES res = ResourceLoader::load(path); RES res = ResourceLoader::load(path);
if (res.is_null()) { if (res.is_null()) {
WARN_PRINT(String("Couldn't load resource: "+path).utf8().get_data()); WARN_PRINT(String("Couldn't load resource: "+path).utf8().get_data());
@ -2100,7 +2100,7 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path,const RES& p_
p.value=E->get()->get(F->get().name); p.value=E->get()->get(F->get().name);
if ((F->get().usage&PROPERTY_USAGE_STORE_IF_NONZERO && p.value.is_zero())||(F->get().usage&PROPERTY_USAGE_STORE_IF_NONONE && p.value.is_one()) ) if ((F->get().usage&PROPERTY_USAGE_STORE_IF_NONZERO && p.value.is_zero())||(F->get().usage&PROPERTY_USAGE_STORE_IF_NONONE && p.value.is_one()) )
continue; continue;
p.pi=F->get(); p.pi=F->get();
rd.properties.push_back(p); rd.properties.push_back(p);

View File

@ -1818,7 +1818,7 @@ Error ResourceInteractiveLoaderXML::rename_dependencies(FileAccess *p_f, const S
void ResourceInteractiveLoaderXML::open(FileAccess *p_f) { void ResourceInteractiveLoaderXML::open(FileAccess *p_f) {
error=OK; error=OK;
lines=1; lines=1;
f=p_f; f=p_f;

View File

@ -49,16 +49,16 @@ Error ResourceInteractiveLoader::wait() {
bool ResourceFormatLoader::recognize(const String& p_extension) const { bool ResourceFormatLoader::recognize(const String& p_extension) const {
List<String> extensions; List<String> extensions;
get_recognized_extensions(&extensions); get_recognized_extensions(&extensions);
for (List<String>::Element *E=extensions.front();E;E=E->next()) { for (List<String>::Element *E=extensions.front();E;E=E->next()) {
if (E->get().nocasecmp_to(p_extension.extension())==0) if (E->get().nocasecmp_to(p_extension.extension())==0)
return true; return true;
} }
return false; return false;
} }
@ -184,9 +184,9 @@ RES ResourceLoader::load(const String &p_path, const String& p_type_hint, bool p
String extension=remapped_path.extension(); String extension=remapped_path.extension();
bool found=false; bool found=false;
for (int i=0;i<loader_count;i++) { for (int i=0;i<loader_count;i++) {
if (!loader[i]->recognize(extension)) if (!loader[i]->recognize(extension))
continue; continue;
if (p_type_hint!="" && !loader[i]->handles_type(p_type_hint)) if (p_type_hint!="" && !loader[i]->handles_type(p_type_hint))
@ -318,7 +318,11 @@ Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(const String &p_
if (OS::get_singleton()->is_stdout_verbose()) if (OS::get_singleton()->is_stdout_verbose())
print_line("load resource: "+local_path+" (cached)"); print_line("load resource: "+local_path+" (cached)");
return RES( ResourceCache::get(local_path ) ); Ref<Resource> res_cached = ResourceCache::get(local_path);
Ref<ResourceInteractiveLoaderDefault> ril = Ref<ResourceInteractiveLoaderDefault>(memnew(ResourceInteractiveLoaderDefault));
ril->resource = res_cached;
return ril;
} }
if (OS::get_singleton()->is_stdout_verbose()) if (OS::get_singleton()->is_stdout_verbose())
@ -356,7 +360,7 @@ Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(const String &p_
} }
void ResourceLoader::add_resource_format_loader(ResourceFormatLoader *p_format_loader) { void ResourceLoader::add_resource_format_loader(ResourceFormatLoader *p_format_loader) {
ERR_FAIL_COND( loader_count >= MAX_LOADERS ); ERR_FAIL_COND( loader_count >= MAX_LOADERS );
loader[loader_count++]=p_format_loader; loader[loader_count++]=p_format_loader;
} }

View File

@ -47,7 +47,7 @@ public:
virtual Ref<Resource> get_resource()=0; virtual Ref<Resource> get_resource()=0;
virtual Error poll()=0; virtual Error poll()=0;
virtual int get_stage() const=0; virtual int get_stage() const=0;
virtual int get_stage_count() const=0; virtual int get_stage_count() const=0;
virtual Error wait(); virtual Error wait();
ResourceInteractiveLoader() {} ResourceInteractiveLoader() {}
@ -76,12 +76,12 @@ typedef void (*ResourceLoadErrorNotify)(void *p_ud,const String& p_text);
typedef void (*DependencyErrorNotify)(void *p_ud,const String& p_loading,const String& p_which,const String& p_type); typedef void (*DependencyErrorNotify)(void *p_ud,const String& p_loading,const String& p_which,const String& p_type);
class ResourceLoader { class ResourceLoader {
enum { enum {
MAX_LOADERS=64 MAX_LOADERS=64
}; };
static ResourceFormatLoader *loader[MAX_LOADERS]; static ResourceFormatLoader *loader[MAX_LOADERS];
static int loader_count; static int loader_count;
static bool timestamp_on_load; static bool timestamp_on_load;
@ -96,7 +96,7 @@ class ResourceLoader {
public: public:
static Ref<ResourceInteractiveLoader> load_interactive(const String &p_path,const String& p_type_hint="",bool p_no_cache=false,Error *r_error=NULL); static Ref<ResourceInteractiveLoader> load_interactive(const String &p_path,const String& p_type_hint="",bool p_no_cache=false,Error *r_error=NULL);
static RES load(const String &p_path,const String& p_type_hint="",bool p_no_cache=false,Error *r_error=NULL); static RES load(const String &p_path,const String& p_type_hint="",bool p_no_cache=false,Error *r_error=NULL);
static Ref<ResourceImportMetadata> load_import_metadata(const String &p_path); static Ref<ResourceImportMetadata> load_import_metadata(const String &p_path);

View File

@ -39,30 +39,30 @@ bool ResourceSaver::timestamp_on_save=false;
ResourceSavedCallback ResourceSaver::save_callback=0; ResourceSavedCallback ResourceSaver::save_callback=0;
Error ResourceSaver::save(const String &p_path,const RES& p_resource,uint32_t p_flags) { Error ResourceSaver::save(const String &p_path,const RES& p_resource,uint32_t p_flags) {
String extension=p_path.extension(); String extension=p_path.extension();
Error err=ERR_FILE_UNRECOGNIZED; Error err=ERR_FILE_UNRECOGNIZED;
for (int i=0;i<saver_count;i++) { for (int i=0;i<saver_count;i++) {
if (!saver[i]->recognize(p_resource)) if (!saver[i]->recognize(p_resource))
continue; continue;
List<String> extensions; List<String> extensions;
bool recognized=false; bool recognized=false;
saver[i]->get_recognized_extensions(p_resource,&extensions); saver[i]->get_recognized_extensions(p_resource,&extensions);
for (List<String>::Element *E=extensions.front();E;E=E->next()) { for (List<String>::Element *E=extensions.front();E;E=E->next()) {
if (E->get().nocasecmp_to(extension.extension())==0) if (E->get().nocasecmp_to(extension.extension())==0)
recognized=true; recognized=true;
} }
if (!recognized) if (!recognized)
continue; continue;
String old_path=p_resource->get_path(); String old_path=p_resource->get_path();
String local_path=Globals::get_singleton()->localize_path(p_path); String local_path=Globals::get_singleton()->localize_path(p_path);
@ -92,10 +92,10 @@ Error ResourceSaver::save(const String &p_path,const RES& p_resource,uint32_t p_
return OK; return OK;
} else { } else {
} }
} }
return err; return err;
} }
@ -108,16 +108,16 @@ void ResourceSaver::set_save_callback(ResourceSavedCallback p_callback) {
void ResourceSaver::get_recognized_extensions(const RES& p_resource,List<String> *p_extensions) { void ResourceSaver::get_recognized_extensions(const RES& p_resource,List<String> *p_extensions) {
for (int i=0;i<saver_count;i++) { for (int i=0;i<saver_count;i++) {
saver[i]->get_recognized_extensions(p_resource,p_extensions); saver[i]->get_recognized_extensions(p_resource,p_extensions);
} }
} }
void ResourceSaver::add_resource_format_saver(ResourceFormatSaver *p_format_saver) { void ResourceSaver::add_resource_format_saver(ResourceFormatSaver *p_format_saver) {
ERR_FAIL_COND( saver_count >= MAX_SAVERS ); ERR_FAIL_COND( saver_count >= MAX_SAVERS );
saver[saver_count++]=p_format_saver; saver[saver_count++]=p_format_saver;
} }

View File

@ -42,7 +42,7 @@
class ResourceFormatSaver { class ResourceFormatSaver {
public: public:
virtual Error save(const String &p_path,const RES& p_resource,uint32_t p_flags=0)=0; virtual Error save(const String &p_path,const RES& p_resource,uint32_t p_flags=0)=0;
virtual bool recognize(const RES& p_resource) const=0; virtual bool recognize(const RES& p_resource) const=0;
virtual void get_recognized_extensions(const RES& p_resource,List<String> *p_extensions) const=0; virtual void get_recognized_extensions(const RES& p_resource,List<String> *p_extensions) const=0;
@ -52,12 +52,12 @@ public:
typedef void (*ResourceSavedCallback)(const String& p_path); typedef void (*ResourceSavedCallback)(const String& p_path);
class ResourceSaver { class ResourceSaver {
enum { enum {
MAX_SAVERS=64 MAX_SAVERS=64
}; };
static ResourceFormatSaver *saver[MAX_SAVERS]; static ResourceFormatSaver *saver[MAX_SAVERS];
static int saver_count; static int saver_count;
static bool timestamp_on_save; static bool timestamp_on_save;
@ -86,7 +86,7 @@ public:
static void set_save_callback(ResourceSavedCallback p_callback); static void set_save_callback(ResourceSavedCallback p_callback);
}; };

View File

@ -357,7 +357,6 @@ String StreamPeer::get_string(int p_bytes){
String StreamPeer::get_utf8_string(int p_bytes){ String StreamPeer::get_utf8_string(int p_bytes){
ERR_FAIL_COND_V(p_bytes<0,String()); ERR_FAIL_COND_V(p_bytes<0,String());
ERR_FAIL_COND_V(p_bytes<0,String());
Vector<uint8_t> buf; Vector<uint8_t> buf;
buf.resize(p_bytes); buf.resize(p_bytes);

View File

@ -10,7 +10,7 @@
Modifications for Zip64 support on both zip and unzip Modifications for Zip64 support on both zip and unzip
Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
For more info read MiniZip_info.txt For more info read LICENSE-MiniZip.txt
------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------

View File

@ -10,7 +10,7 @@
Modifications for Zip64 support on both zip and unzip Modifications for Zip64 support on both zip and unzip
Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
For more info read MiniZip_info.txt For more info read LICENSE-MiniZip.txt
--------------------------------------------------------------------------------- ---------------------------------------------------------------------------------

View File

@ -7,7 +7,7 @@
Modifications for Zip64 support Modifications for Zip64 support
Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
For more info read MiniZip_info.txt For more info read LICENSE-MiniZip.txt
Changes Changes
Oct-2009 - Mathias Svensson - Remove old C style function prototypes Oct-2009 - Mathias Svensson - Remove old C style function prototypes

View File

@ -6,7 +6,7 @@
Modifications for Zip64 support Modifications for Zip64 support
Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
For more info read MiniZip_info.txt For more info read LICENSE-MiniZip.txt
--------------------------------------------------------------------------- ---------------------------------------------------------------------------

View File

@ -39,11 +39,14 @@ static void* zipio_open(void* data, const char* p_fname, int mode) {
FileAccess *&f = *(FileAccess**)data; FileAccess *&f = *(FileAccess**)data;
String fname;
fname.parse_utf8(p_fname);
if (mode & ZLIB_FILEFUNC_MODE_WRITE) { if (mode & ZLIB_FILEFUNC_MODE_WRITE) {
f = FileAccess::open(p_fname,FileAccess::WRITE); f = FileAccess::open(fname,FileAccess::WRITE);
} else { } else {
f = FileAccess::open(p_fname,FileAccess::READ); f = FileAccess::open(fname,FileAccess::READ);
} }
if (!f) if (!f)

View File

@ -245,7 +245,7 @@ public:
_data->first=n; _data->first=n;
_data->size_cache++; _data->size_cache++;
return n; return n;
}; };
@ -285,7 +285,7 @@ public:
_data->last=n; _data->last=n;
_data->size_cache++; _data->size_cache++;
return n; return n;
}; };
@ -363,30 +363,30 @@ public:
} }
void swap(Element* p_A, Element *p_B) { void swap(Element* p_A, Element *p_B) {
ERR_FAIL_COND(!p_A || !p_B); ERR_FAIL_COND(!p_A || !p_B);
ERR_FAIL_COND(p_A->data!=_data); ERR_FAIL_COND(p_A->data!=_data);
ERR_FAIL_COND(p_B->data!=_data); ERR_FAIL_COND(p_B->data!=_data);
Element* A_prev=p_A->prev_ptr; Element* A_prev=p_A->prev_ptr;
Element* A_next=p_A->next_ptr; Element* A_next=p_A->next_ptr;
p_A->next_ptr=p_B->next_ptr; p_A->next_ptr=p_B->next_ptr;
p_A->prev_ptr=p_B->prev_ptr; p_A->prev_ptr=p_B->prev_ptr;
p_B->next_ptr=A_next; p_B->next_ptr=A_next;
p_B->prev_ptr=A_prev; p_B->prev_ptr=A_prev;
if (p_A->prev_ptr) if (p_A->prev_ptr)
p_A->prev_ptr->next_ptr=p_A; p_A->prev_ptr->next_ptr=p_A;
if (p_A->next_ptr) if (p_A->next_ptr)
p_A->next_ptr->prev_ptr=p_A; p_A->next_ptr->prev_ptr=p_A;
if (p_B->prev_ptr) if (p_B->prev_ptr)
p_B->prev_ptr->next_ptr=p_B; p_B->prev_ptr->next_ptr=p_B;
if (p_B->next_ptr) if (p_B->next_ptr)
p_B->next_ptr->prev_ptr=p_B; p_B->next_ptr->prev_ptr=p_B;
} }
/** /**
* copy the list * copy the list
@ -552,10 +552,10 @@ public:
*/ */
void sort() { void sort() {
sort_custom< Comparator<T> >(); sort_custom< Comparator<T> >();
} }
template<class C> template<class C>
void sort_custom_inplace() { void sort_custom_inplace() {
@ -565,44 +565,44 @@ public:
Element *from=front(); Element *from=front();
Element *current=from; Element *current=from;
Element *to=from; Element *to=from;
while(current) { while(current) {
Element *next=current->next_ptr; Element *next=current->next_ptr;
//disconnect //disconnect
current->next_ptr=NULL; current->next_ptr=NULL;
if (from!=current) { if (from!=current) {
current->prev_ptr=NULL; current->prev_ptr=NULL;
current->next_ptr=from; current->next_ptr=from;
Element *find=from; Element *find=from;
C less; C less;
while( find && less(find->value,current->value) ) { while( find && less(find->value,current->value) ) {
current->prev_ptr=find; current->prev_ptr=find;
current->next_ptr=find->next_ptr; current->next_ptr=find->next_ptr;
find=find->next_ptr; find=find->next_ptr;
} }
if (current->prev_ptr) if (current->prev_ptr)
current->prev_ptr->next_ptr=current; current->prev_ptr->next_ptr=current;
else else
from=current; from=current;
if (current->next_ptr) if (current->next_ptr)
current->next_ptr->prev_ptr=current; current->next_ptr->prev_ptr=current;
else else
to=current; to=current;
} else { } else {
current->prev_ptr=NULL; current->prev_ptr=NULL;
current->next_ptr=NULL; current->next_ptr=NULL;
} }
current=next; current=next;
} }
_data->first=from; _data->first=from;

View File

@ -6,7 +6,7 @@ template_typed="""
template<class T $ifret ,class R$ $ifargs ,$ $arg, class P@$> template<class T $ifret ,class R$ $ifargs ,$ $arg, class P@$>
class MethodBind$argc$$ifret R$$ifconst C$ : public MethodBind { class MethodBind$argc$$ifret R$$ifconst C$ : public MethodBind {
public: public:
$ifret R$ $ifnoret void$ (T::*method)($arg, P@$) $ifconst const$; $ifret R$ $ifnoret void$ (T::*method)($arg, P@$) $ifconst const$;
#ifdef DEBUG_METHODS_ENABLED #ifdef DEBUG_METHODS_ENABLED
virtual Variant::Type _gen_argument_type(int p_arg) const { return _get_argument_type(p_arg); } virtual Variant::Type _gen_argument_type(int p_arg) const { return _get_argument_type(p_arg); }
@ -16,13 +16,13 @@ public:
$ $
return Variant::NIL; return Variant::NIL;
} }
#endif #endif
virtual String get_instance_type() const { virtual String get_instance_type() const {
return T::get_type_static(); return T::get_type_static();
} }
virtual Variant call(Object* p_object,const Variant** p_args,int p_arg_count, Variant::CallError& r_error) { virtual Variant call(Object* p_object,const Variant** p_args,int p_arg_count, Variant::CallError& r_error) {
T *instance=p_object->cast_to<T>(); T *instance=p_object->cast_to<T>();
r_error.error=Variant::CallError::CALL_OK; r_error.error=Variant::CallError::CALL_OK;
#ifdef DEBUG_METHODS_ENABLED #ifdef DEBUG_METHODS_ENABLED
@ -47,7 +47,7 @@ public:
$ifret return Variant(ret);$ $ifret return Variant(ret);$
$ifnoret return Variant();$ $ifnoret return Variant();$
} }
MethodBind$argc$$ifret R$$ifconst C$ () { MethodBind$argc$$ifret R$$ifconst C$ () {
#ifdef DEBUG_METHODS_ENABLED #ifdef DEBUG_METHODS_ENABLED
@ -55,14 +55,14 @@ public:
_generate_argument_types($argc$); _generate_argument_types($argc$);
#else #else
set_argument_count($argc$); set_argument_count($argc$);
#endif #endif
}; };
}; };
template<class T $ifret ,class R$ $ifargs ,$ $arg, class P@$> template<class T $ifret ,class R$ $ifargs ,$ $arg, class P@$>
MethodBind* create_method_bind($ifret R$ $ifnoret void$ (T::*p_method)($arg, P@$) $ifconst const$ ) { MethodBind* create_method_bind($ifret R$ $ifnoret void$ (T::*p_method)($arg, P@$) $ifconst const$ ) {
MethodBind$argc$$ifret R$$ifconst C$<T $ifret ,R$ $ifargs ,$ $arg, P@$> * a = memnew( (MethodBind$argc$$ifret R$$ifconst C$<T $ifret ,R$ $ifargs ,$ $arg, P@$>) ); MethodBind$argc$$ifret R$$ifconst C$<T $ifret ,R$ $ifargs ,$ $arg, P@$> * a = memnew( (MethodBind$argc$$ifret R$$ifconst C$<T $ifret ,R$ $ifargs ,$ $arg, P@$>) );
a->method=p_method; a->method=p_method;
return a; return a;
} }
@ -88,7 +88,7 @@ public:
$ $
return Variant::NIL; return Variant::NIL;
} }
#endif #endif
virtual String get_instance_type() const { virtual String get_instance_type() const {
return type_name; return type_name;
} }
@ -105,15 +105,15 @@ public:
r_error.error=Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS; r_error.error=Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
r_error.argument=get_argument_count(); r_error.argument=get_argument_count();
return Variant(); return Variant();
} }
if (p_arg_count<(get_argument_count()-get_default_argument_count())) { if (p_arg_count<(get_argument_count()-get_default_argument_count())) {
r_error.error=Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; r_error.error=Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
r_error.argument=get_argument_count()-get_default_argument_count(); r_error.argument=get_argument_count()-get_default_argument_count();
return Variant(); return Variant();
} }
$arg CHECK_ARG(@); $arg CHECK_ARG(@);
$ $
#endif #endif
@ -128,7 +128,7 @@ public:
_generate_argument_types($argc$); _generate_argument_types($argc$);
#else #else
set_argument_count($argc$); set_argument_count($argc$);
#endif #endif
}; };
}; };
@ -151,12 +151,12 @@ MethodBind* create_method_bind($ifret R$ $ifnoret void$ (T::*p_method)($arg, P@$
def make_version(template,nargs,argmax,const,ret): def make_version(template,nargs,argmax,const,ret):
intext=template intext=template
from_pos=0 from_pos=0
outtext="" outtext=""
while(True): while(True):
to_pos=intext.find("$",from_pos) to_pos=intext.find("$",from_pos)
if (to_pos==-1): if (to_pos==-1):
outtext+=intext[from_pos:] outtext+=intext[from_pos:]
@ -169,13 +169,13 @@ def make_version(template,nargs,argmax,const,ret):
macro=intext[to_pos+1:end] macro=intext[to_pos+1:end]
cmd="" cmd=""
data="" data=""
if (macro.find(" ")!=-1): if (macro.find(" ")!=-1):
cmd=macro[0:macro.find(" ")] cmd=macro[0:macro.find(" ")]
data=macro[macro.find(" ")+1:] data=macro[macro.find(" ")+1:]
else: else:
cmd=macro cmd=macro
if (cmd=="argc"): if (cmd=="argc"):
outtext+=str(nargs) outtext+=str(nargs)
if (cmd=="ifret" and ret): if (cmd=="ifret" and ret):
@ -206,11 +206,11 @@ def make_version(template,nargs,argmax,const,ret):
elif (cmd=="noarg"): elif (cmd=="noarg"):
for i in range(nargs+1,argmax+1): for i in range(nargs+1,argmax+1):
outtext+=data.replace("@",str(i)) outtext+=data.replace("@",str(i))
from_pos=end+1 from_pos=end+1
return outtext return outtext
def run(target, source, env): def run(target, source, env):
@ -244,9 +244,9 @@ def run(target, source, env):
f.write(text_ext) f.write(text_ext)
f.close() f.close()

View File

@ -39,12 +39,12 @@
template <class K,class V,class C=Comparator<K>,class A=DefaultAllocator> template <class K,class V,class C=Comparator<K>,class A=DefaultAllocator>
class Map { class Map {
enum Color { enum Color {
RED, RED,
BLACK BLACK
}; };
struct _Data; struct _Data;
public: public:
class Element { class Element {
@ -66,34 +66,34 @@ public:
public: public:
const Element *next() const { const Element *next() const {
return _next; return _next;
} }
Element *next() { Element *next() {
return _next; return _next;
} }
const Element *prev() const { const Element *prev() const {
return _prev; return _prev;
} }
Element *prev() { Element *prev() {
return _prev; return _prev;
} }
const K& key() const { const K& key() const {
return _key; return _key;
}; };
V& value() { V& value() {
return _value; return _value;
}; };
const V& value() const { const V& value() const {
return _value; return _value;
}; };
V& get() { V& get() {
return _value; return _value;
}; };
const V& get() const { const V& get() const {
return _value; return _value;
}; };
Element() { Element() {
@ -106,15 +106,15 @@ public:
}; };
}; };
private: private:
struct _Data { struct _Data {
Element* _root; Element* _root;
Element* _nil; Element* _nil;
int size_cache; int size_cache;
_FORCE_INLINE_ _Data() { _FORCE_INLINE_ _Data() {
#ifdef GLOBALNIL_DISABLED #ifdef GLOBALNIL_DISABLED
_nil = memnew_allocator( Element, A ); _nil = memnew_allocator( Element, A );
@ -126,7 +126,7 @@ private:
_root=NULL; _root=NULL;
size_cache=0; size_cache=0;
} }
void _create_root() { void _create_root() {
_root = memnew_allocator( Element,A ); _root = memnew_allocator( Element,A );
@ -145,23 +145,23 @@ private:
~_Data() { ~_Data() {
_free_root(); _free_root();
#ifdef GLOBALNIL_DISABLED #ifdef GLOBALNIL_DISABLED
memdelete_allocator<Element,A>(_nil); memdelete_allocator<Element,A>(_nil);
#endif #endif
// memdelete_allocator<Element,A>(_root); // memdelete_allocator<Element,A>(_root);
} }
}; };
_Data _data; _Data _data;
inline void _set_color(Element *p_node, int p_color) { inline void _set_color(Element *p_node, int p_color) {
ERR_FAIL_COND( p_node == _data._nil && p_color == RED ); ERR_FAIL_COND( p_node == _data._nil && p_color == RED );
p_node->color=p_color; p_node->color=p_color;
} }
inline void _rotate_left(Element *p_node) { inline void _rotate_left(Element *p_node) {
Element *r=p_node->right; Element *r=p_node->right;
p_node->right=r->left; p_node->right=r->left;
if (r->left != _data._nil ) if (r->left != _data._nil )
@ -171,14 +171,14 @@ private:
p_node->parent->left=r; p_node->parent->left=r;
else else
p_node->parent->right=r; p_node->parent->right=r;
r->left=p_node; r->left=p_node;
p_node->parent=r; p_node->parent=r;
} }
inline void _rotate_right(Element *p_node) { inline void _rotate_right(Element *p_node) {
Element *l=p_node->left; Element *l=p_node->left;
p_node->left=l->right; p_node->left=l->right;
if (l->right != _data._nil) if (l->right != _data._nil)
@ -188,25 +188,25 @@ private:
p_node->parent->right=l; p_node->parent->right=l;
else else
p_node->parent->left=l; p_node->parent->left=l;
l->right=p_node; l->right=p_node;
p_node->parent=l; p_node->parent=l;
} }
inline Element* _successor(Element *p_node) const { inline Element* _successor(Element *p_node) const {
Element *node=p_node; Element *node=p_node;
if (node->right != _data._nil) { if (node->right != _data._nil) {
node=node->right; node=node->right;
while(node->left != _data._nil) { /* returns the minium of the right subtree of node */ while(node->left != _data._nil) { /* returns the minium of the right subtree of node */
node=node->left; node=node->left;
} }
return node; return node;
} else { } else {
while(node == node->parent->right) { while(node == node->parent->right) {
node=node->parent; node=node->parent;
} }
@ -215,44 +215,44 @@ private:
return node->parent; return node->parent;
} }
} }
inline Element* _predecessor(Element *p_node) const { inline Element* _predecessor(Element *p_node) const {
Element *node=p_node; Element *node=p_node;
if (node->left != _data._nil) { if (node->left != _data._nil) {
node=node->left; node=node->left;
while(node->right != _data._nil) { /* returns the minium of the left subtree of node */ while(node->right != _data._nil) { /* returns the minium of the left subtree of node */
node=node->right; node=node->right;
} }
return node; return node;
} else { } else {
while(node == node->parent->left) { while(node == node->parent->left) {
if (node->parent == _data._root) if (node->parent == _data._root)
return NULL; return NULL;
node=node->parent; node=node->parent;
} }
return node->parent; return node->parent;
} }
} }
Element *_find(const K& p_key) const { Element *_find(const K& p_key) const {
Element *node = _data._root->left; Element *node = _data._root->left;
C less; C less;
while(node!=_data._nil) { while(node!=_data._nil) {
if (less(p_key,node->_key)) if (less(p_key,node->_key))
node=node->left; node=node->left;
else if (less(node->_key,p_key)) else if (less(node->_key,p_key))
node=node->right; node=node->right;
else else
break; // found break; // found
} }
return (node!=_data._nil)?node:NULL; return (node!=_data._nil)?node:NULL;
} }
@ -289,73 +289,73 @@ private:
} }
Element *_insert(const K& p_key, bool& r_exists) { Element *_insert(const K& p_key, bool& r_exists) {
Element *new_parent=_data._root; Element *new_parent=_data._root;
Element *node = _data._root->left; Element *node = _data._root->left;
C less; C less;
while (node!=_data._nil) { while (node!=_data._nil) {
new_parent=node; new_parent=node;
if (less(p_key,node->_key)) if (less(p_key,node->_key))
node=node->left; node=node->left;
else if (less(node->_key,p_key)) else if (less(node->_key,p_key))
node=node->right; node=node->right;
else { else {
r_exists=true; r_exists=true;
return node; return node;
} }
} }
Element *new_node = memnew_allocator( Element, A ); Element *new_node = memnew_allocator( Element, A );
new_node->parent=new_parent; new_node->parent=new_parent;
new_node->right=_data._nil; new_node->right=_data._nil;
new_node->left=_data._nil; new_node->left=_data._nil;
new_node->_key=p_key; new_node->_key=p_key;
//new_node->data=_data; //new_node->data=_data;
if (new_parent==_data._root || less(p_key,new_parent->_key)) { if (new_parent==_data._root || less(p_key,new_parent->_key)) {
new_parent->left=new_node; new_parent->left=new_node;
} else { } else {
new_parent->right=new_node; new_parent->right=new_node;
} }
r_exists=false; r_exists=false;
new_node->_next=_successor(new_node); new_node->_next=_successor(new_node);
new_node->_prev=_predecessor(new_node); new_node->_prev=_predecessor(new_node);
if (new_node->_next) if (new_node->_next)
new_node->_next->_prev=new_node; new_node->_next->_prev=new_node;
if (new_node->_prev) if (new_node->_prev)
new_node->_prev->_next=new_node; new_node->_prev->_next=new_node;
return new_node; return new_node;
} }
Element * _insert_rb(const K& p_key, const V& p_value) { Element * _insert_rb(const K& p_key, const V& p_value) {
bool exists=false; bool exists=false;
Element *new_node = _insert(p_key,exists); Element *new_node = _insert(p_key,exists);
if (new_node) { if (new_node) {
new_node->_value=p_value; new_node->_value=p_value;
} }
if (exists) if (exists)
return new_node; return new_node;
Element *node=new_node; Element *node=new_node;
_data.size_cache++; _data.size_cache++;
while(node->parent->color==RED) { while(node->parent->color==RED) {
if (node->parent == node->parent->parent->left) { if (node->parent == node->parent->parent->left) {
Element *aux=node->parent->parent->right; Element *aux=node->parent->parent->right;
if (aux->color==RED) { if (aux->color==RED) {
_set_color(node->parent,BLACK); _set_color(node->parent,BLACK);
_set_color(aux,BLACK); _set_color(aux,BLACK);
@ -369,10 +369,10 @@ private:
_set_color(node->parent,BLACK); _set_color(node->parent,BLACK);
_set_color(node->parent->parent,RED); _set_color(node->parent->parent,RED);
_rotate_right(node->parent->parent); _rotate_right(node->parent->parent);
} }
} else { } else {
Element *aux=node->parent->parent->left; Element *aux=node->parent->parent->left;
if (aux->color==RED) { if (aux->color==RED) {
_set_color(node->parent,BLACK); _set_color(node->parent,BLACK);
_set_color(aux,BLACK); _set_color(aux,BLACK);
@ -386,19 +386,19 @@ private:
_set_color(node->parent,BLACK); _set_color(node->parent,BLACK);
_set_color(node->parent->parent,RED); _set_color(node->parent->parent,RED);
_rotate_left(node->parent->parent); _rotate_left(node->parent->parent);
} }
} }
} }
_set_color(_data._root->left,BLACK); _set_color(_data._root->left,BLACK);
return new_node; return new_node;
} }
void _erase_fix(Element *p_node) { void _erase_fix(Element *p_node) {
Element *root = _data._root->left; Element *root = _data._root->left;
Element *node=p_node; Element *node=p_node;
while( (node->color==BLACK) && (root != node)) { while( (node->color==BLACK) && (root != node)) {
if (node == node->parent->left) { if (node == node->parent->left) {
Element *aux=node->parent->right; Element *aux=node->parent->right;
@ -408,7 +408,7 @@ private:
_rotate_left(node->parent); _rotate_left(node->parent);
aux=node->parent->right; aux=node->parent->right;
} }
if ( (aux->right->color==BLACK) && (aux->left->color==BLACK) ) { if ( (aux->right->color==BLACK) && (aux->left->color==BLACK) ) {
_set_color(aux,RED); _set_color(aux,RED);
node=node->parent; node=node->parent;
} else { } else {
@ -432,7 +432,7 @@ private:
_rotate_right(node->parent); _rotate_right(node->parent);
aux=node->parent->left; aux=node->parent->left;
} }
if ( (aux->right->color==BLACK) && (aux->left->color==BLACK) ) { if ( (aux->right->color==BLACK) && (aux->left->color==BLACK) ) {
_set_color(aux,RED); _set_color(aux,RED);
node=node->parent; node=node->parent;
} else { } else {
@ -446,24 +446,24 @@ private:
_set_color(node->parent,BLACK); _set_color(node->parent,BLACK);
_set_color(aux->left,BLACK); _set_color(aux->left,BLACK);
_rotate_right(node->parent); _rotate_right(node->parent);
node=root; node=root;
} }
} }
} }
_set_color(node,BLACK); _set_color(node,BLACK);
ERR_FAIL_COND(_data._nil->color!=BLACK); ERR_FAIL_COND(_data._nil->color!=BLACK);
} }
void _erase(Element *p_node) { void _erase(Element *p_node) {
Element *rp= ((p_node->left == _data._nil) || (p_node->right == _data._nil)) ? p_node : _successor(p_node); Element *rp= ((p_node->left == _data._nil) || (p_node->right == _data._nil)) ? p_node : _successor(p_node);
if (!rp) if (!rp)
rp=_data._nil; rp=_data._nil;
Element *node= (rp->left == _data._nil) ? rp->right : rp->left; Element *node= (rp->left == _data._nil) ? rp->right : rp->left;
if (_data._root == (node->parent=rp->parent) ) { if (_data._root == (node->parent=rp->parent) ) {
_data._root->left=node; _data._root->left=node;
} else { } else {
@ -473,47 +473,47 @@ private:
rp->parent->right=node; rp->parent->right=node;
} }
} }
if (rp != p_node) { if (rp != p_node) {
ERR_FAIL_COND( rp == _data._nil ); ERR_FAIL_COND( rp == _data._nil );
if (rp->color==BLACK) if (rp->color==BLACK)
_erase_fix(node); _erase_fix(node);
rp->left=p_node->left; rp->left=p_node->left;
rp->right=p_node->right; rp->right=p_node->right;
rp->parent=p_node->parent; rp->parent=p_node->parent;
rp->color=p_node->color; rp->color=p_node->color;
p_node->left->parent=rp; p_node->left->parent=rp;
p_node->right->parent=rp; p_node->right->parent=rp;
if (p_node == p_node->parent->left) { if (p_node == p_node->parent->left) {
p_node->parent->left=rp; p_node->parent->left=rp;
} else { } else {
p_node->parent->right=rp; p_node->parent->right=rp;
} }
} else { } else {
if (p_node->color==BLACK) if (p_node->color==BLACK)
_erase_fix(node); _erase_fix(node);
} }
if (p_node->_next) if (p_node->_next)
p_node->_next->_prev=p_node->_prev; p_node->_next->_prev=p_node->_prev;
if (p_node->_prev) if (p_node->_prev)
p_node->_prev->_next=p_node->_next; p_node->_prev->_next=p_node->_next;
memdelete_allocator<Element,A>(p_node); memdelete_allocator<Element,A>(p_node);
_data.size_cache--; _data.size_cache--;
ERR_FAIL_COND( _data._nil->color==RED ); ERR_FAIL_COND( _data._nil->color==RED );
} }
void _calculate_depth(Element *p_element,int &max_d,int d) const { void _calculate_depth(Element *p_element,int &max_d,int d) const {
if (p_element==_data._nil) { if (p_element==_data._nil) {
return; return;
} }
@ -522,23 +522,23 @@ private:
if (d>max_d) if (d>max_d)
max_d=d; max_d=d;
} }
void _cleanup_tree(Element *p_element) { void _cleanup_tree(Element *p_element) {
if (p_element==_data._nil) if (p_element==_data._nil)
return; return;
_cleanup_tree(p_element->left); _cleanup_tree(p_element->left);
_cleanup_tree(p_element->right); _cleanup_tree(p_element->right);
memdelete_allocator<Element,A>( p_element ); memdelete_allocator<Element,A>( p_element );
} }
void _copy_from( const Map& p_map) { void _copy_from( const Map& p_map) {
clear(); clear();
// not the fastest way, but safeset to write. // not the fastest way, but safeset to write.
for(Element *I=p_map.front();I;I=I->next()) { for(Element *I=p_map.front();I;I=I->next()) {
insert(I->key(),I->value()); insert(I->key(),I->value());
} }
} }
@ -554,7 +554,7 @@ public:
} }
Element *find(const K& p_key) { Element *find(const K& p_key) {
if (!_data._root) if (!_data._root)
return NULL; return NULL;
Element *res=_find(p_key); Element *res=_find(p_key);
@ -578,15 +578,15 @@ public:
} }
Element *insert(const K& p_key,const V& p_value) { Element *insert(const K& p_key,const V& p_value) {
if (!_data._root) if (!_data._root)
_data._create_root(); _data._create_root();
return _insert_rb(p_key,p_value); return _insert_rb(p_key,p_value);
} }
void erase(Element* p_element) { void erase(Element* p_element) {
if (!_data._root) if (!_data._root)
return; return;
_erase(p_element); _erase(p_element);
@ -595,72 +595,72 @@ public:
} }
bool erase(const K& p_key) { bool erase(const K& p_key) {
if (!_data._root) if (!_data._root)
return false; return false;
Element *e=find(p_key); Element *e=find(p_key);
if (!e) if (!e)
return false; return false;
_erase(e); _erase(e);
return true; return true;
} }
bool has(const K& p_key) const { bool has(const K& p_key) const {
if (!_data._root) if (!_data._root)
return false; return false;
return find(p_key) != NULL; return find(p_key) != NULL;
} }
const V& operator[](const K& p_key) const { const V& operator[](const K& p_key) const {
ERR_FAIL_COND_V(!_data._root, *(V*)NULL); // crash on purpose ERR_FAIL_COND_V(!_data._root, *(V*)NULL); // crash on purpose
const Element *e=find(p_key); const Element *e=find(p_key);
ERR_FAIL_COND_V(!e, *(V*)NULL); // crash on purpose ERR_FAIL_COND_V(!e, *(V*)NULL); // crash on purpose
return e->_value; return e->_value;
} }
V& operator[](const K& p_key) { V& operator[](const K& p_key) {
if (!_data._root) if (!_data._root)
_data._create_root(); _data._create_root();
Element *e=find(p_key); Element *e=find(p_key);
if (!e) if (!e)
e=insert(p_key,V()); e=insert(p_key,V());
ERR_FAIL_COND_V(!e, *(V*)NULL); // crash on purpose ERR_FAIL_COND_V(!e, *(V*)NULL); // crash on purpose
return e->_value; return e->_value;
} }
Element *front() const { Element *front() const {
if (!_data._root) if (!_data._root)
return NULL; return NULL;
Element *e=_data._root->left; Element *e=_data._root->left;
if (e==_data._nil) if (e==_data._nil)
return NULL; return NULL;
while(e->left!=_data._nil) while(e->left!=_data._nil)
e=e->left; e=e->left;
return e; return e;
} }
Element *back() const { Element *back() const {
if (!_data._root) if (!_data._root)
return NULL; return NULL;
Element *e=_data._root->left; Element *e=_data._root->left;
if (e==_data._nil) if (e==_data._nil)
return NULL; return NULL;
while(e->right!=_data._nil) while(e->right!=_data._nil)
e=e->right; e=e->right;
return e; return e;
} }
inline bool empty() const { return _data.size_cache==0; } inline bool empty() const { return _data.size_cache==0; }
inline int size() const { return _data.size_cache; } inline int size() const { return _data.size_cache; }
int calculate_depth() const { int calculate_depth() const {
@ -671,9 +671,9 @@ public:
_calculate_depth(_data._root->left,max_d,0); _calculate_depth(_data._root->left,max_d,0);
return max_d; return max_d;
} }
void clear() { void clear() {
if (!_data._root) if (!_data._root)
return; return;
_cleanup_tree(_data._root->left); _cleanup_tree(_data._root->left);
@ -682,25 +682,25 @@ public:
_data._nil->parent=_data._nil; _data._nil->parent=_data._nil;
_data._free_root(); _data._free_root();
} }
void operator=(const Map& p_map) { void operator=(const Map& p_map) {
_copy_from( p_map ); _copy_from( p_map );
} }
Map(const Map& p_map) { Map(const Map& p_map) {
_copy_from( p_map ); _copy_from( p_map );
} }
_FORCE_INLINE_ Map() { _FORCE_INLINE_ Map() {
} }
~Map() { ~Map() {
clear(); clear();
} }
}; };

View File

@ -47,21 +47,21 @@ public:
float get_area() const; /// get area float get_area() const; /// get area
_FORCE_INLINE_ bool has_no_area() const { _FORCE_INLINE_ bool has_no_area() const {
return (size.x<=CMP_EPSILON || size.y<=CMP_EPSILON || size.z<=CMP_EPSILON); return (size.x<=CMP_EPSILON || size.y<=CMP_EPSILON || size.z<=CMP_EPSILON);
} }
_FORCE_INLINE_ bool has_no_surface() const { _FORCE_INLINE_ bool has_no_surface() const {
return (size.x<=CMP_EPSILON && size.y<=CMP_EPSILON && size.z<=CMP_EPSILON); return (size.x<=CMP_EPSILON && size.y<=CMP_EPSILON && size.z<=CMP_EPSILON);
} }
const Vector3& get_pos() const { return pos; } const Vector3& get_pos() const { return pos; }
void set_pos(const Vector3& p_pos) { pos=p_pos; } void set_pos(const Vector3& p_pos) { pos=p_pos; }
const Vector3& get_size() const { return size; } const Vector3& get_size() const { return size; }
void set_size(const Vector3& p_size) { size=p_size; } void set_size(const Vector3& p_size) { size=p_size; }
bool operator==(const AABB& p_rval) const; bool operator==(const AABB& p_rval) const;
bool operator!=(const AABB& p_rval) const; bool operator!=(const AABB& p_rval) const;
@ -265,7 +265,7 @@ bool AABB::has_point(const Vector3& p_point) const {
return false; return false;
if (p_point.z>pos.z+size.z) if (p_point.z>pos.z+size.z)
return false; return false;
return true; return true;
} }
@ -297,11 +297,11 @@ void AABB::project_range_in_plane(const Plane& p_plane,float &r_min,float& r_max
Vector3 half_extents( size.x * 0.5, size.y * 0.5, size.z * 0.5 ); Vector3 half_extents( size.x * 0.5, size.y * 0.5, size.z * 0.5 );
Vector3 center( pos.x + half_extents.x, pos.y + half_extents.y, pos.z + half_extents.z ); Vector3 center( pos.x + half_extents.x, pos.y + half_extents.y, pos.z + half_extents.z );
float length = p_plane.normal.abs().dot(half_extents); float length = p_plane.normal.abs().dot(half_extents);
float distance = p_plane.distance_to( center ); float distance = p_plane.distance_to( center );
r_min = distance - length; r_min = distance - length;
r_max = distance + length; r_max = distance + length;
} }
inline real_t AABB::get_longest_axis_size() const { inline real_t AABB::get_longest_axis_size() const {

View File

@ -66,12 +66,12 @@ Vector<Plane> BSP_Tree::get_planes() const {
return planes; return planes;
} }
AABB BSP_Tree::get_aabb() const { AABB BSP_Tree::get_aabb() const {
return aabb; return aabb;
} }
int BSP_Tree::_get_points_inside(int p_node,const Vector3* p_points,int *p_indices, const Vector3& p_center,const Vector3& p_half_extents,int p_indices_count) const { int BSP_Tree::_get_points_inside(int p_node,const Vector3* p_points,int *p_indices, const Vector3& p_center,const Vector3& p_half_extents,int p_indices_count) const {
@ -245,22 +245,22 @@ bool BSP_Tree::point_is_inside(const Vector3& p_point) const {
if (!aabb.has_point(p_point)) { if (!aabb.has_point(p_point)) {
return false; return false;
} }
int node_count=nodes.size(); int node_count=nodes.size();
if (node_count==0) // no nodes! if (node_count==0) // no nodes!
return false; return false;
const Node *nodesptr=&nodes[0]; const Node *nodesptr=&nodes[0];
const Plane *planesptr=&planes[0]; const Plane *planesptr=&planes[0];
int plane_count=planes.size(); int plane_count=planes.size();
int idx=node_count-1; int idx=node_count-1;
int steps=0; int steps=0;
while(true) { while(true) {
if (idx==OVER_LEAF) { if (idx==OVER_LEAF) {
return false; return false;
} }
@ -268,28 +268,28 @@ bool BSP_Tree::point_is_inside(const Vector3& p_point) const {
return true; return true;
} }
uint16_t plane=nodesptr[ idx ].plane; uint16_t plane=nodesptr[ idx ].plane;
#ifdef DEBUG_ENABLED #ifdef DEBUG_ENABLED
ERR_FAIL_INDEX_V( plane, plane_count, false ); ERR_FAIL_INDEX_V( plane, plane_count, false );
#endif #endif
bool over = planesptr[ nodesptr[ idx ].plane ].is_point_over(p_point); bool over = planesptr[ nodesptr[ idx ].plane ].is_point_over(p_point);
idx = over ? nodes[ idx ].over : nodes[ idx ].under; idx = over ? nodes[ idx ].over : nodes[ idx ].under;
#ifdef DEBUG_ENABLED #ifdef DEBUG_ENABLED
ERR_FAIL_COND_V( idx<MAX_NODES && idx>=node_count, false ); ERR_FAIL_COND_V( idx<MAX_NODES && idx>=node_count, false );
#endif #endif
steps++; steps++;
} }
return false; return false;
} }
static int _bsp_find_best_half_plane(const Face3* p_faces,const Vector<int>& p_indices,float p_tolerance) { static int _bsp_find_best_half_plane(const Face3* p_faces,const Vector<int>& p_indices,float p_tolerance) {
int ic = p_indices.size(); int ic = p_indices.size();
@ -304,7 +304,7 @@ static int _bsp_find_best_half_plane(const Face3* p_faces,const Vector<int>& p_i
const Face3& f=p_faces[ indices[i] ]; const Face3& f=p_faces[ indices[i] ];
Plane p = f.get_plane(); Plane p = f.get_plane();
int num_over=0,num_under=0,num_spanning=0; int num_over=0,num_under=0,num_spanning=0;
for(int j=0;j<ic;j++) { for(int j=0;j<ic;j++) {
@ -335,17 +335,17 @@ static int _bsp_find_best_half_plane(const Face3* p_faces,const Vector<int>& p_i
num_over++; num_over++;
else else
num_under++; num_under++;
} }
//double split_cost = num_spanning / (double) face_count; //double split_cost = num_spanning / (double) face_count;
double relation = Math::abs(num_over-num_under) / (double) ic; double relation = Math::abs(num_over-num_under) / (double) ic;
// being honest, i never found a way to add split cost to the mix in a meaninguful way // being honest, i never found a way to add split cost to the mix in a meaninguful way
// in this engine, also, will likely be ignored anyway // in this engine, also, will likely be ignored anyway
double plane_cost = /*split_cost +*/ relation; double plane_cost = /*split_cost +*/ relation;
//printf("plane %i, %i over, %i under, %i spanning, cost is %g\n",i,num_over,num_under,num_spanning,plane_cost); //printf("plane %i, %i over, %i under, %i spanning, cost is %g\n",i,num_over,num_under,num_spanning,plane_cost);
@ -360,10 +360,10 @@ static int _bsp_find_best_half_plane(const Face3* p_faces,const Vector<int>& p_i
return best_plane; return best_plane;
} }
static int _bsp_create_node(const Face3 *p_faces,const Vector<int>& p_indices,Vector<Plane> &p_planes, Vector<BSP_Tree::Node> &p_nodes,float p_tolerance) { static int _bsp_create_node(const Face3 *p_faces,const Vector<int>& p_indices,Vector<Plane> &p_planes, Vector<BSP_Tree::Node> &p_nodes,float p_tolerance) {
ERR_FAIL_COND_V( p_nodes.size() == BSP_Tree::MAX_NODES, -1 ); ERR_FAIL_COND_V( p_nodes.size() == BSP_Tree::MAX_NODES, -1 );
// should not reach here // should not reach here
@ -387,7 +387,7 @@ static int _bsp_create_node(const Face3 *p_faces,const Vector<int>& p_indices,Ve
if (i==divisor_idx) if (i==divisor_idx)
continue; continue;
const Face3& f=p_faces[ indices[i] ]; const Face3& f=p_faces[ indices[i] ];
//if (f.get_plane().is_almost_like(divisor_plane)) //if (f.get_plane().is_almost_like(divisor_plane))
@ -416,7 +416,7 @@ static int _bsp_create_node(const Face3 *p_faces,const Vector<int>& p_indices,Ve
} }
uint16_t over_idx=BSP_Tree::OVER_LEAF,under_idx=BSP_Tree::UNDER_LEAF; uint16_t over_idx=BSP_Tree::OVER_LEAF,under_idx=BSP_Tree::UNDER_LEAF;
if (faces_over.size()>0) { //have facess above? if (faces_over.size()>0) { //have facess above?
@ -434,13 +434,13 @@ static int _bsp_create_node(const Face3 *p_faces,const Vector<int>& p_indices,Ve
} }
/* Create the node */ /* Create the node */
// find existing divisor plane // find existing divisor plane
int divisor_plane_idx=-1; int divisor_plane_idx=-1;
for (int i=0;i<p_planes.size();i++) { for (int i=0;i<p_planes.size();i++) {
if (p_planes[i].is_almost_like( divisor_plane )) { if (p_planes[i].is_almost_like( divisor_plane )) {
divisor_plane_idx=i; divisor_plane_idx=i;
break; break;
@ -448,22 +448,22 @@ static int _bsp_create_node(const Face3 *p_faces,const Vector<int>& p_indices,Ve
} }
if (divisor_plane_idx==-1) { if (divisor_plane_idx==-1) {
ERR_FAIL_COND_V( p_planes.size() == BSP_Tree::MAX_PLANES, -1 ); ERR_FAIL_COND_V( p_planes.size() == BSP_Tree::MAX_PLANES, -1 );
divisor_plane_idx=p_planes.size(); divisor_plane_idx=p_planes.size();
p_planes.push_back( divisor_plane ); p_planes.push_back( divisor_plane );
} }
BSP_Tree::Node node; BSP_Tree::Node node;
node.plane=divisor_plane_idx; node.plane=divisor_plane_idx;
node.under=under_idx; node.under=under_idx;
node.over=over_idx; node.over=over_idx;
p_nodes.push_back(node); p_nodes.push_back(node);
return p_nodes.size()-1; return p_nodes.size()-1;
} }
BSP_Tree::operator Variant() const { BSP_Tree::operator Variant() const {
@ -563,7 +563,7 @@ BSP_Tree::BSP_Tree(const Variant& p_variant) {
BSP_Tree::BSP_Tree(const DVector<Face3>& p_faces,float p_error_radius) { BSP_Tree::BSP_Tree(const DVector<Face3>& p_faces,float p_error_radius) {
// compute aabb // compute aabb
int face_count=p_faces.size(); int face_count=p_faces.size();
DVector<Face3>::Read faces_r=p_faces.read(); DVector<Face3>::Read faces_r=p_faces.read();
const Face3 *facesptr = faces_r.ptr(); const Face3 *facesptr = faces_r.ptr();
@ -574,26 +574,26 @@ BSP_Tree::BSP_Tree(const DVector<Face3>& p_faces,float p_error_radius) {
Vector<int> indices; Vector<int> indices;
for (int i=0;i<face_count;i++) { for (int i=0;i<face_count;i++) {
const Face3& f=facesptr[i]; const Face3& f=facesptr[i];
if (f.is_degenerate()) if (f.is_degenerate())
continue; continue;
for (int j=0;j<3;j++) { for (int j=0;j<3;j++) {
if (first) { if (first) {
aabb.pos=f.vertex[0]; aabb.pos=f.vertex[0];
first=false; first=false;
} else { } else {
aabb.expand_to(f.vertex[j]); aabb.expand_to(f.vertex[j]);
} }
} }
indices.push_back(i); indices.push_back(i);
} }
ERR_FAIL_COND( aabb.has_no_area() ); ERR_FAIL_COND( aabb.has_no_area() );
@ -609,7 +609,7 @@ BSP_Tree::BSP_Tree(const DVector<Face3>& p_faces,float p_error_radius) {
error_radius=p_error_radius; error_radius=p_error_radius;
} }

View File

@ -43,7 +43,7 @@ class BSP_Tree {
public: public:
enum { enum {
UNDER_LEAF=0xFFFF, UNDER_LEAF=0xFFFF,
OVER_LEAF=0xFFFE, OVER_LEAF=0xFFFE,
MAX_NODES=0xFFFE, MAX_NODES=0xFFFE,
@ -51,22 +51,22 @@ public:
}; };
struct Node { struct Node {
uint16_t plane; uint16_t plane;
uint16_t under; uint16_t under;
uint16_t over; uint16_t over;
}; };
private: private:
// thanks to the properties of Vector, // thanks to the properties of Vector,
// this class can be assigned and passed around between threads // this class can be assigned and passed around between threads
// with no cost. // with no cost.
Vector<Node> nodes; Vector<Node> nodes;
Vector<Plane> planes; Vector<Plane> planes;
AABB aabb; AABB aabb;
float error_radius; float error_radius;
int _get_points_inside(int p_node,const Vector3* p_points,int *p_indices, const Vector3& p_center,const Vector3& p_half_extents,int p_indices_count) const; int _get_points_inside(int p_node,const Vector3* p_points,int *p_indices, const Vector3& p_center,const Vector3& p_half_extents,int p_indices_count) const;
@ -79,8 +79,8 @@ public:
Vector<Node> get_nodes() const; Vector<Node> get_nodes() const;
Vector<Plane> get_planes() const; Vector<Plane> get_planes() const;
AABB get_aabb() const; AABB get_aabb() const;
bool point_is_inside(const Vector3& p_point) const; bool point_is_inside(const Vector3& p_point) const;
int get_points_inside(const Vector3* p_points, int p_point_count) const; int get_points_inside(const Vector3* p_points, int p_point_count) const;
template<class T> template<class T>
bool convex_is_inside(const T& p_convex) const; bool convex_is_inside(const T& p_convex) const;
@ -91,8 +91,8 @@ public:
BSP_Tree(); BSP_Tree();
BSP_Tree(const Variant& p_variant); BSP_Tree(const Variant& p_variant);
BSP_Tree(const DVector<Face3>& p_faces,float p_error_radius=0); BSP_Tree(const DVector<Face3>& p_faces,float p_error_radius=0);
BSP_Tree(const Vector<Node> &p_nodes, const Vector<Plane> &p_planes, const AABB& p_aabb,float p_error_radius=0); BSP_Tree(const Vector<Node> &p_nodes, const Vector<Plane> &p_planes, const AABB& p_aabb,float p_error_radius=0);
~BSP_Tree(); ~BSP_Tree();
}; };

View File

@ -33,9 +33,9 @@
void CameraMatrix::set_identity() { void CameraMatrix::set_identity() {
for (int i=0;i<4;i++) { for (int i=0;i<4;i++) {
for (int j=0;j<4;j++) { for (int j=0;j<4;j++) {
matrix[i][j]=(i==j)?1:0; matrix[i][j]=(i==j)?1:0;
} }
} }
@ -90,7 +90,7 @@ void CameraMatrix::set_perspective(float p_fovy_degrees, float p_aspect, float p
matrix[2][2] = -(p_z_far + p_z_near) / deltaZ; matrix[2][2] = -(p_z_far + p_z_near) / deltaZ;
matrix[2][3] = -1; matrix[2][3] = -1;
matrix[3][2] = -2 * p_z_near * p_z_far / deltaZ; matrix[3][2] = -2 * p_z_near * p_z_far / deltaZ;
matrix[3][3] = 0; matrix[3][3] = 0;
} }
@ -155,95 +155,95 @@ void CameraMatrix::set_frustum(float p_left, float p_right, float p_bottom, floa
float CameraMatrix::get_z_far() const { float CameraMatrix::get_z_far() const {
const float * matrix = (const float*)this->matrix; const float * matrix = (const float*)this->matrix;
Plane new_plane=Plane(matrix[ 3] - matrix[ 2], Plane new_plane=Plane(matrix[ 3] - matrix[ 2],
matrix[ 7] - matrix[ 6], matrix[ 7] - matrix[ 6],
matrix[11] - matrix[10], matrix[11] - matrix[10],
matrix[15] - matrix[14]); matrix[15] - matrix[14]);
new_plane.normal=-new_plane.normal; new_plane.normal=-new_plane.normal;
new_plane.normalize(); new_plane.normalize();
return new_plane.d; return new_plane.d;
} }
float CameraMatrix::get_z_near() const { float CameraMatrix::get_z_near() const {
const float * matrix = (const float*)this->matrix; const float * matrix = (const float*)this->matrix;
Plane new_plane=Plane(matrix[ 3] + matrix[ 2], Plane new_plane=Plane(matrix[ 3] + matrix[ 2],
matrix[ 7] + matrix[ 6], matrix[ 7] + matrix[ 6],
matrix[11] + matrix[10], matrix[11] + matrix[10],
-matrix[15] - matrix[14]); -matrix[15] - matrix[14]);
new_plane.normalize(); new_plane.normalize();
return new_plane.d; return new_plane.d;
} }
void CameraMatrix::get_viewport_size(float& r_width, float& r_height) const { void CameraMatrix::get_viewport_size(float& r_width, float& r_height) const {
const float * matrix = (const float*)this->matrix; const float * matrix = (const float*)this->matrix;
///////--- Near Plane ---/////// ///////--- Near Plane ---///////
Plane near_plane=Plane(matrix[ 3] + matrix[ 2], Plane near_plane=Plane(matrix[ 3] + matrix[ 2],
matrix[ 7] + matrix[ 6], matrix[ 7] + matrix[ 6],
matrix[11] + matrix[10], matrix[11] + matrix[10],
-matrix[15] - matrix[14]).normalized(); -matrix[15] - matrix[14]).normalized();
///////--- Right Plane ---/////// ///////--- Right Plane ---///////
Plane right_plane=Plane(matrix[ 3] - matrix[ 0], Plane right_plane=Plane(matrix[ 3] - matrix[ 0],
matrix[ 7] - matrix[ 4], matrix[ 7] - matrix[ 4],
matrix[11] - matrix[ 8], matrix[11] - matrix[ 8],
- matrix[15] + matrix[12]).normalized(); - matrix[15] + matrix[12]).normalized();
Plane top_plane=Plane(matrix[ 3] - matrix[ 1], Plane top_plane=Plane(matrix[ 3] - matrix[ 1],
matrix[ 7] - matrix[ 5], matrix[ 7] - matrix[ 5],
matrix[11] - matrix[ 9], matrix[11] - matrix[ 9],
-matrix[15] + matrix[13]).normalized(); -matrix[15] + matrix[13]).normalized();
Vector3 res; Vector3 res;
near_plane.intersect_3(right_plane,top_plane,&res); near_plane.intersect_3(right_plane,top_plane,&res);
r_width=res.x; r_width=res.x;
r_height=res.y; r_height=res.y;
} }
bool CameraMatrix::get_endpoints(const Transform& p_transform, Vector3 *p_8points) const { bool CameraMatrix::get_endpoints(const Transform& p_transform, Vector3 *p_8points) const {
const float * matrix = (const float*)this->matrix; const float * matrix = (const float*)this->matrix;
///////--- Near Plane ---/////// ///////--- Near Plane ---///////
Plane near_plane=Plane(matrix[ 3] + matrix[ 2], Plane near_plane=Plane(matrix[ 3] + matrix[ 2],
matrix[ 7] + matrix[ 6], matrix[ 7] + matrix[ 6],
matrix[11] + matrix[10], matrix[11] + matrix[10],
-matrix[15] - matrix[14]).normalized(); -matrix[15] - matrix[14]).normalized();
///////--- Far Plane ---/////// ///////--- Far Plane ---///////
Plane far_plane=Plane(matrix[ 2] - matrix[ 3], Plane far_plane=Plane(matrix[ 2] - matrix[ 3],
matrix[ 6] - matrix[ 7], matrix[ 6] - matrix[ 7],
matrix[10] - matrix[11], matrix[10] - matrix[11],
matrix[15] - matrix[14]).normalized(); matrix[15] - matrix[14]).normalized();
///////--- Right Plane ---/////// ///////--- Right Plane ---///////
Plane right_plane=Plane(matrix[ 0] - matrix[ 3], Plane right_plane=Plane(matrix[ 0] - matrix[ 3],
matrix[ 4] - matrix[ 7], matrix[ 4] - matrix[ 7],
matrix[8] - matrix[ 11], matrix[8] - matrix[ 11],
- matrix[15] + matrix[12]).normalized(); - matrix[15] + matrix[12]).normalized();
///////--- Top Plane ---/////// ///////--- Top Plane ---///////
Plane top_plane=Plane(matrix[ 1] - matrix[ 3], Plane top_plane=Plane(matrix[ 1] - matrix[ 3],
matrix[ 5] - matrix[ 7], matrix[ 5] - matrix[ 7],
matrix[9] - matrix[ 11], matrix[9] - matrix[ 11],
-matrix[15] + matrix[13]).normalized(); -matrix[15] + matrix[13]).normalized();
Vector3 near_endpoint; Vector3 near_endpoint;
Vector3 far_endpoint; Vector3 far_endpoint;
bool res=near_plane.intersect_3(right_plane,top_plane,&near_endpoint); bool res=near_plane.intersect_3(right_plane,top_plane,&near_endpoint);
ERR_FAIL_COND_V(!res,false); ERR_FAIL_COND_V(!res,false);
res=far_plane.intersect_3(right_plane,top_plane,&far_endpoint); res=far_plane.intersect_3(right_plane,top_plane,&far_endpoint);
ERR_FAIL_COND_V(!res,false); ERR_FAIL_COND_V(!res,false);
p_8points[0]=p_transform.xform( Vector3( near_endpoint.x, near_endpoint.y, near_endpoint.z ) ); p_8points[0]=p_transform.xform( Vector3( near_endpoint.x, near_endpoint.y, near_endpoint.z ) );
p_8points[1]=p_transform.xform( Vector3( near_endpoint.x,-near_endpoint.y, near_endpoint.z ) ); p_8points[1]=p_transform.xform( Vector3( near_endpoint.x,-near_endpoint.y, near_endpoint.z ) );
p_8points[2]=p_transform.xform( Vector3(-near_endpoint.x, near_endpoint.y, near_endpoint.z ) ); p_8points[2]=p_transform.xform( Vector3(-near_endpoint.x, near_endpoint.y, near_endpoint.z ) );
@ -252,7 +252,7 @@ bool CameraMatrix::get_endpoints(const Transform& p_transform, Vector3 *p_8point
p_8points[5]=p_transform.xform( Vector3( far_endpoint.x,-far_endpoint.y, far_endpoint.z ) ); p_8points[5]=p_transform.xform( Vector3( far_endpoint.x,-far_endpoint.y, far_endpoint.z ) );
p_8points[6]=p_transform.xform( Vector3(-far_endpoint.x, far_endpoint.y, far_endpoint.z ) ); p_8points[6]=p_transform.xform( Vector3(-far_endpoint.x, far_endpoint.y, far_endpoint.z ) );
p_8points[7]=p_transform.xform( Vector3(-far_endpoint.x,-far_endpoint.y, far_endpoint.z ) ); p_8points[7]=p_transform.xform( Vector3(-far_endpoint.x,-far_endpoint.y, far_endpoint.z ) );
return true; return true;
} }
@ -263,10 +263,10 @@ Vector<Plane> CameraMatrix::get_projection_planes(const Transform& p_transform)
* http://www.markmorley.com/opengl/frustumculling.html * http://www.markmorley.com/opengl/frustumculling.html
* http://www2.ravensoft.com/users/ggribb/plane%20extraction.pdf * http://www2.ravensoft.com/users/ggribb/plane%20extraction.pdf
*/ */
Vector<Plane> planes; Vector<Plane> planes;
const float * matrix = (const float*)this->matrix; const float * matrix = (const float*)this->matrix;
Plane new_plane; Plane new_plane;
@ -275,7 +275,7 @@ Vector<Plane> CameraMatrix::get_projection_planes(const Transform& p_transform)
matrix[ 7] + matrix[ 6], matrix[ 7] + matrix[ 6],
matrix[11] + matrix[10], matrix[11] + matrix[10],
matrix[15] + matrix[14]); matrix[15] + matrix[14]);
new_plane.normal=-new_plane.normal; new_plane.normal=-new_plane.normal;
new_plane.normalize(); new_plane.normalize();
@ -298,7 +298,7 @@ Vector<Plane> CameraMatrix::get_projection_planes(const Transform& p_transform)
matrix[ 7] + matrix[ 4], matrix[ 7] + matrix[ 4],
matrix[11] + matrix[ 8], matrix[11] + matrix[ 8],
matrix[15] + matrix[12]); matrix[15] + matrix[12]);
new_plane.normal=-new_plane.normal; new_plane.normal=-new_plane.normal;
new_plane.normalize(); new_plane.normalize();
@ -310,8 +310,8 @@ Vector<Plane> CameraMatrix::get_projection_planes(const Transform& p_transform)
matrix[ 7] - matrix[ 5], matrix[ 7] - matrix[ 5],
matrix[11] - matrix[ 9], matrix[11] - matrix[ 9],
matrix[15] - matrix[13]); matrix[15] - matrix[13]);
new_plane.normal=-new_plane.normal; new_plane.normal=-new_plane.normal;
new_plane.normalize(); new_plane.normalize();
@ -324,10 +324,10 @@ Vector<Plane> CameraMatrix::get_projection_planes(const Transform& p_transform)
matrix[11] - matrix[ 8], matrix[11] - matrix[ 8],
matrix[15] - matrix[12]); matrix[15] - matrix[12]);
new_plane.normal=-new_plane.normal; new_plane.normal=-new_plane.normal;
new_plane.normalize(); new_plane.normalize();
planes.push_back( p_transform.xform(new_plane) ); planes.push_back( p_transform.xform(new_plane) );
@ -337,12 +337,12 @@ Vector<Plane> CameraMatrix::get_projection_planes(const Transform& p_transform)
matrix[11] + matrix[ 9], matrix[11] + matrix[ 9],
matrix[15] + matrix[13]); matrix[15] + matrix[13]);
new_plane.normal=-new_plane.normal; new_plane.normal=-new_plane.normal;
new_plane.normalize(); new_plane.normalize();
planes.push_back( p_transform.xform(new_plane) ); planes.push_back( p_transform.xform(new_plane) );
return planes; return planes;
} }
@ -356,7 +356,7 @@ CameraMatrix CameraMatrix::inverse() const {
} }
void CameraMatrix::invert() { void CameraMatrix::invert() {
int i,j,k; int i,j,k;
int pvt_i[4], pvt_j[4]; /* Locations of pivot matrix */ int pvt_i[4], pvt_j[4]; /* Locations of pivot matrix */
float pvt_val; /* Value of current pivot element */ float pvt_val; /* Value of current pivot element */
@ -448,7 +448,7 @@ void CameraMatrix::invert() {
} }
} }
} }
CameraMatrix::CameraMatrix() { CameraMatrix::CameraMatrix() {
@ -475,31 +475,31 @@ CameraMatrix CameraMatrix::operator*(const CameraMatrix& p_matrix) const {
void CameraMatrix::set_light_bias() { void CameraMatrix::set_light_bias() {
float *m=&matrix[0][0]; float *m=&matrix[0][0];
m[0]=0.5, m[0]=0.5,
m[1]=0.0, m[1]=0.0,
m[2]=0.0, m[2]=0.0,
m[3]=0.0, m[3]=0.0,
m[4]=0.0, m[4]=0.0,
m[5]=0.5, m[5]=0.5,
m[6]=0.0, m[6]=0.0,
m[7]=0.0, m[7]=0.0,
m[8]=0.0, m[8]=0.0,
m[9]=0.0, m[9]=0.0,
m[10]=0.5, m[10]=0.5,
m[11]=0.0, m[11]=0.0,
m[12]=0.5, m[12]=0.5,
m[13]=0.5, m[13]=0.5,
m[14]=0.5, m[14]=0.5,
m[15]=1.0; m[15]=1.0;
} }
CameraMatrix::operator String() const { CameraMatrix::operator String() const {
String str; String str;
for (int i=0;i<4;i++) for (int i=0;i<4;i++)
for (int j=0;j<4;j++) for (int j=0;j<4;j++)
str+=String((j>0)?", ":"\n")+rtos(matrix[i][j]); str+=String((j>0)?", ":"\n")+rtos(matrix[i][j]);
return str; return str;
@ -513,7 +513,7 @@ float CameraMatrix::get_aspect() const {
} }
float CameraMatrix::get_fov() const { float CameraMatrix::get_fov() const {
const float * matrix = (const float*)this->matrix; const float * matrix = (const float*)this->matrix;
Plane right_plane=Plane(matrix[ 3] - matrix[ 0], Plane right_plane=Plane(matrix[ 3] - matrix[ 0],
matrix[ 7] - matrix[ 4], matrix[ 7] - matrix[ 4],
@ -588,7 +588,7 @@ CameraMatrix::CameraMatrix(const Transform& p_transform) {
const Transform &tr = p_transform; const Transform &tr = p_transform;
float *m=&matrix[0][0]; float *m=&matrix[0][0];
m[0]=tr.basis.elements[0][0]; m[0]=tr.basis.elements[0][0];
m[1]=tr.basis.elements[1][0]; m[1]=tr.basis.elements[1][0];
m[2]=tr.basis.elements[2][0]; m[2]=tr.basis.elements[2][0];
@ -604,7 +604,7 @@ CameraMatrix::CameraMatrix(const Transform& p_transform) {
m[12]=tr.origin.x; m[12]=tr.origin.x;
m[13]=tr.origin.y; m[13]=tr.origin.y;
m[14]=tr.origin.z; m[14]=tr.origin.z;
m[15]=1.0; m[15]=1.0;
} }
CameraMatrix::~CameraMatrix() CameraMatrix::~CameraMatrix()

View File

@ -48,8 +48,8 @@ struct CameraMatrix {
}; };
float matrix[4][4]; float matrix[4][4];
void set_identity(); void set_identity();
void set_zero(); void set_zero();
void set_light_bias(); void set_light_bias();
@ -67,12 +67,12 @@ struct CameraMatrix {
float get_z_near() const; float get_z_near() const;
float get_aspect() const; float get_aspect() const;
float get_fov() const; float get_fov() const;
Vector<Plane> get_projection_planes(const Transform& p_transform) const; Vector<Plane> get_projection_planes(const Transform& p_transform) const;
bool get_endpoints(const Transform& p_transform,Vector3 *p_8points) const; bool get_endpoints(const Transform& p_transform,Vector3 *p_8points) const;
void get_viewport_size(float& r_width, float& r_height) const; void get_viewport_size(float& r_width, float& r_height) const;
void invert(); void invert();
CameraMatrix inverse() const; CameraMatrix inverse() const;
@ -80,15 +80,15 @@ struct CameraMatrix {
Plane xform4(const Plane& p_vec4); Plane xform4(const Plane& p_vec4);
_FORCE_INLINE_ Vector3 xform(const Vector3& p_vec3) const; _FORCE_INLINE_ Vector3 xform(const Vector3& p_vec3) const;
operator String() const; operator String() const;
void scale_translate_to_fit(const AABB& p_aabb); void scale_translate_to_fit(const AABB& p_aabb);
void make_scale(const Vector3 &p_scale); void make_scale(const Vector3 &p_scale);
operator Transform() const; operator Transform() const;
CameraMatrix(); CameraMatrix();
CameraMatrix(const Transform& p_transform); CameraMatrix(const Transform& p_transform);
~CameraMatrix(); ~CameraMatrix();
}; };

View File

@ -55,7 +55,7 @@ public:
* @param _epsilon constant used for numerical error rounding, to add "thickness" to the plane (so coplanar points can happen) * @param _epsilon constant used for numerical error rounding, to add "thickness" to the plane (so coplanar points can happen)
* @return amount of faces generated by the split, either 0 (means no split possible), 2 or 3 * @return amount of faces generated by the split, either 0 (means no split possible), 2 or 3
*/ */
int split_by_plane(const Plane& p_plane,Face3 *p_res,bool *p_is_point_over) const; int split_by_plane(const Plane& p_plane,Face3 *p_res,bool *p_is_point_over) const;
Plane get_plane(ClockDirection p_dir=CLOCKWISE) const; Plane get_plane(ClockDirection p_dir=CLOCKWISE) const;
@ -77,7 +77,7 @@ public:
void get_support(const Vector3& p_normal,const Transform& p_transform,Vector3 *p_vertices,int* p_count,int p_max) const; void get_support(const Vector3& p_normal,const Transform& p_transform,Vector3 *p_vertices,int* p_count,int p_max) const;
void project_range(const Vector3& p_normal,const Transform& p_transform,float& r_min, float& r_max) const; void project_range(const Vector3& p_normal,const Transform& p_transform,float& r_min, float& r_max) const;
AABB get_aabb() const { AABB get_aabb() const {
AABB aabb( vertex[0], Vector3() ); AABB aabb( vertex[0], Vector3() );

View File

@ -211,7 +211,7 @@ DVector< DVector< Face3 > > Geometry::separate_objects( DVector< Face3 > p_array
int len = p_array.size(); int len = p_array.size();
DVector<Face3>::Read r=p_array.read(); DVector<Face3>::Read r=p_array.read();
const Face3* arrayptr = r.ptr(); const Face3* arrayptr = r.ptr();
DVector< _FaceClassify> fc; DVector< _FaceClassify> fc;
@ -219,7 +219,7 @@ DVector< DVector< Face3 > > Geometry::separate_objects( DVector< Face3 > p_array
fc.resize( len ); fc.resize( len );
DVector< _FaceClassify >::Write fcw=fc.write(); DVector< _FaceClassify >::Write fcw=fc.write();
_FaceClassify * _fcptr = fcw.ptr(); _FaceClassify * _fcptr = fcw.ptr();
for (int i=0;i<len;i++) { for (int i=0;i<len;i++) {
@ -278,7 +278,7 @@ DVector< DVector< Face3 > > Geometry::separate_objects( DVector< Face3 > p_array
/*** GEOMETRY WRAPPER ***/ /*** GEOMETRY WRAPPER ***/
enum _CellFlags { enum _CellFlags {
_CELL_SOLID=1, _CELL_SOLID=1,
_CELL_EXTERIOR=2, _CELL_EXTERIOR=2,
_CELL_STEP_MASK=0x1C, _CELL_STEP_MASK=0x1C,
@ -299,7 +299,7 @@ enum _CellFlags {
_CELL_PREV_Z_POS=5<<5, _CELL_PREV_Z_POS=5<<5,
_CELL_PREV_Z_NEG=6<<5, _CELL_PREV_Z_NEG=6<<5,
_CELL_PREV_FIRST=7<<5, _CELL_PREV_FIRST=7<<5,
}; };
static inline void _plot_face(uint8_t*** p_cell_status,int x,int y,int z,int len_x,int len_y,int len_z,const Vector3& voxelsize,const Face3& p_face) { static inline void _plot_face(uint8_t*** p_cell_status,int x,int y,int z,int len_x,int len_y,int len_z,const Vector3& voxelsize,const Face3& p_face) {
@ -316,9 +316,9 @@ static inline void _plot_face(uint8_t*** p_cell_status,int x,int y,int z,int len
p_cell_status[x][y][z]=_CELL_SOLID; p_cell_status[x][y][z]=_CELL_SOLID;
return; return;
} }
int div_x=len_x>1?2:1; int div_x=len_x>1?2:1;
int div_y=len_y>1?2:1; int div_y=len_y>1?2:1;
int div_z=len_z>1?2:1; int div_z=len_z>1?2:1;
@ -343,14 +343,14 @@ static inline void _plot_face(uint8_t*** p_cell_status,int x,int y,int z,int len
int new_len_z; int new_len_z;
for (int i=0;i<div_x;i++) { for (int i=0;i<div_x;i++) {
_SPLIT(i,div_x,x,len_x,new_x,new_len_x); _SPLIT(i,div_x,x,len_x,new_x,new_len_x);
for (int j=0;j<div_y;j++) { for (int j=0;j<div_y;j++) {
_SPLIT(j,div_y,y,len_y,new_y,new_len_y); _SPLIT(j,div_y,y,len_y,new_y,new_len_y);
for (int k=0;k<div_z;k++) { for (int k=0;k<div_z;k++) {
_SPLIT(k,div_z,z,len_z,new_z,new_len_z); _SPLIT(k,div_z,z,len_z,new_z,new_len_z);
@ -365,39 +365,39 @@ static inline void _mark_outside(uint8_t*** p_cell_status,int x,int y,int z,int
if (p_cell_status[x][y][z]&3) if (p_cell_status[x][y][z]&3)
return; // nothing to do, already used and/or visited return; // nothing to do, already used and/or visited
p_cell_status[x][y][z]=_CELL_PREV_FIRST; p_cell_status[x][y][z]=_CELL_PREV_FIRST;
while(true) { while(true) {
uint8_t &c = p_cell_status[x][y][z]; uint8_t &c = p_cell_status[x][y][z];
//printf("at %i,%i,%i\n",x,y,z); //printf("at %i,%i,%i\n",x,y,z);
if ( (c&_CELL_STEP_MASK)==_CELL_STEP_NONE) { if ( (c&_CELL_STEP_MASK)==_CELL_STEP_NONE) {
/* Haven't been in here, mark as outside */ /* Haven't been in here, mark as outside */
p_cell_status[x][y][z]|=_CELL_EXTERIOR; p_cell_status[x][y][z]|=_CELL_EXTERIOR;
//printf("not marked as anything, marking exterior\n"); //printf("not marked as anything, marking exterior\n");
} }
//printf("cell step is %i\n",(c&_CELL_STEP_MASK)); //printf("cell step is %i\n",(c&_CELL_STEP_MASK));
if ( (c&_CELL_STEP_MASK)!=_CELL_STEP_DONE) { if ( (c&_CELL_STEP_MASK)!=_CELL_STEP_DONE) {
/* if not done, increase step */ /* if not done, increase step */
c+=1<<2; c+=1<<2;
//printf("incrementing cell step\n"); //printf("incrementing cell step\n");
} }
if ( (c&_CELL_STEP_MASK)==_CELL_STEP_DONE) { if ( (c&_CELL_STEP_MASK)==_CELL_STEP_DONE) {
/* Go back */ /* Go back */
//printf("done, going back a cell\n"); //printf("done, going back a cell\n");
switch(c&_CELL_PREV_MASK) { switch(c&_CELL_PREV_MASK) {
case _CELL_PREV_FIRST: { case _CELL_PREV_FIRST: {
//printf("at end, finished marking\n"); //printf("at end, finished marking\n");
return; return;
} break; } break;
case _CELL_PREV_Y_POS: { case _CELL_PREV_Y_POS: {
y++; y++;
ERR_FAIL_COND(y>=len_y); ERR_FAIL_COND(y>=len_y);
} break; } break;
@ -427,16 +427,16 @@ static inline void _mark_outside(uint8_t*** p_cell_status,int x,int y,int z,int
} }
continue; continue;
} }
//printf("attempting new cell!\n"); //printf("attempting new cell!\n");
int next_x=x,next_y=y,next_z=z; int next_x=x,next_y=y,next_z=z;
uint8_t prev=0; uint8_t prev=0;
switch(c&_CELL_STEP_MASK) { switch(c&_CELL_STEP_MASK) {
case _CELL_STEP_Y_POS: { case _CELL_STEP_Y_POS: {
next_y++; next_y++;
prev=_CELL_PREV_Y_NEG; prev=_CELL_PREV_Y_NEG;
} break; } break;
@ -454,32 +454,32 @@ static inline void _mark_outside(uint8_t*** p_cell_status,int x,int y,int z,int
} break; } break;
case _CELL_STEP_Z_POS: { case _CELL_STEP_Z_POS: {
next_z++; next_z++;
prev=_CELL_PREV_Z_NEG; prev=_CELL_PREV_Z_NEG;
} break; } break;
case _CELL_STEP_Z_NEG: { case _CELL_STEP_Z_NEG: {
next_z--; next_z--;
prev=_CELL_PREV_Z_POS; prev=_CELL_PREV_Z_POS;
} break; } break;
default: ERR_FAIL(); default: ERR_FAIL();
} }
//printf("testing if new cell will be ok...!\n"); //printf("testing if new cell will be ok...!\n");
if (next_x<0 || next_x>=len_x) if (next_x<0 || next_x>=len_x)
continue; continue;
if (next_y<0 || next_y>=len_y) if (next_y<0 || next_y>=len_y)
continue; continue;
if (next_z<0 || next_z>=len_z) if (next_z<0 || next_z>=len_z)
continue; continue;
//printf("testing if new cell is traversable\n"); //printf("testing if new cell is traversable\n");
if (p_cell_status[next_x][next_y][next_z]&3) if (p_cell_status[next_x][next_y][next_z]&3)
continue; continue;
//printf("move to it\n"); //printf("move to it\n");
x=next_x; x=next_x;
y=next_y; y=next_y;
z=next_z; z=next_z;
@ -488,14 +488,14 @@ static inline void _mark_outside(uint8_t*** p_cell_status,int x,int y,int z,int
} }
static inline void _build_faces(uint8_t*** p_cell_status,int x,int y,int z,int len_x,int len_y,int len_z,DVector<Face3>& p_faces) { static inline void _build_faces(uint8_t*** p_cell_status,int x,int y,int z,int len_x,int len_y,int len_z,DVector<Face3>& p_faces) {
ERR_FAIL_INDEX(x,len_x); ERR_FAIL_INDEX(x,len_x);
ERR_FAIL_INDEX(y,len_y); ERR_FAIL_INDEX(y,len_y);
ERR_FAIL_INDEX(z,len_z); ERR_FAIL_INDEX(z,len_z);
if (p_cell_status[x][y][z]&_CELL_EXTERIOR) if (p_cell_status[x][y][z]&_CELL_EXTERIOR)
return; return;
/* static const Vector3 vertices[8]={ /* static const Vector3 vertices[8]={
Vector3(0,0,0), Vector3(0,0,0),
Vector3(0,0,1), Vector3(0,0,1),
@ -510,73 +510,73 @@ static inline void _build_faces(uint8_t*** p_cell_status,int x,int y,int z,int l
#define vert(m_idx) Vector3( (m_idx&4)>>2, (m_idx&2)>>1, m_idx&1 ) #define vert(m_idx) Vector3( (m_idx&4)>>2, (m_idx&2)>>1, m_idx&1 )
static const uint8_t indices[6][4]={ static const uint8_t indices[6][4]={
{7,6,4,5}, {7,6,4,5},
{7,3,2,6}, {7,3,2,6},
{7,5,1,3}, {7,5,1,3},
{0,2,3,1}, {0,2,3,1},
{0,1,5,4}, {0,1,5,4},
{0,4,6,2}, {0,4,6,2},
}; };
/* /*
{0,1,2,3}, {0,1,2,3},
{0,1,4,5}, {0,1,4,5},
{0,2,4,6}, {0,2,4,6},
{4,5,6,7}, {4,5,6,7},
{2,3,7,6}, {2,3,7,6},
{1,3,5,7}, {1,3,5,7},
{0,2,3,1}, {0,2,3,1},
{0,1,5,4}, {0,1,5,4},
{0,4,6,2}, {0,4,6,2},
{7,6,4,5}, {7,6,4,5},
{7,3,2,6}, {7,3,2,6},
{7,5,1,3}, {7,5,1,3},
*/ */
for (int i=0;i<6;i++) { for (int i=0;i<6;i++) {
Vector3 face_points[4]; Vector3 face_points[4];
int disp_x=x+((i%3)==0?((i<3)?1:-1):0); int disp_x=x+((i%3)==0?((i<3)?1:-1):0);
int disp_y=y+(((i-1)%3)==0?((i<3)?1:-1):0); int disp_y=y+(((i-1)%3)==0?((i<3)?1:-1):0);
int disp_z=z+(((i-2)%3)==0?((i<3)?1:-1):0); int disp_z=z+(((i-2)%3)==0?((i<3)?1:-1):0);
bool plot=false; bool plot=false;
if (disp_x<0 || disp_x>=len_x) if (disp_x<0 || disp_x>=len_x)
plot=true; plot=true;
if (disp_y<0 || disp_y>=len_y) if (disp_y<0 || disp_y>=len_y)
plot=true; plot=true;
if (disp_z<0 || disp_z>=len_z) if (disp_z<0 || disp_z>=len_z)
plot=true; plot=true;
if (!plot && (p_cell_status[disp_x][disp_y][disp_z]&_CELL_EXTERIOR)) if (!plot && (p_cell_status[disp_x][disp_y][disp_z]&_CELL_EXTERIOR))
plot=true; plot=true;
if (!plot) if (!plot)
continue; continue;
for (int j=0;j<4;j++) for (int j=0;j<4;j++)
face_points[j]=vert( indices[i][j] ) + Vector3(x,y,z); face_points[j]=vert( indices[i][j] ) + Vector3(x,y,z);
p_faces.push_back( p_faces.push_back(
Face3( Face3(
face_points[0], face_points[0],
face_points[1], face_points[1],
face_points[2] face_points[2]
) )
); );
p_faces.push_back( p_faces.push_back(
Face3( Face3(
face_points[2], face_points[2],
face_points[3], face_points[3],
face_points[0] face_points[0]
) )
); );
} }
} }
@ -601,7 +601,7 @@ DVector< Face3 > Geometry::wrap_geometry( DVector< Face3 > p_array,float *p_erro
global_aabb.merge_with( faces[i].get_aabb() ); global_aabb.merge_with( faces[i].get_aabb() );
} }
} }
global_aabb.grow_by(0.01); // avoid numerical error global_aabb.grow_by(0.01); // avoid numerical error
// determine amount of cells in grid axis // determine amount of cells in grid axis
@ -649,7 +649,7 @@ DVector< Face3 > Geometry::wrap_geometry( DVector< Face3 > p_array,float *p_erro
// plot faces into cells // plot faces into cells
print_line("Wrapper (1/6): Plotting Faces"); print_line("Wrapper (1/6): Plotting Faces");
for (int i=0;i<face_count;i++) { for (int i=0;i<face_count;i++) {
Face3 f=faces[i]; Face3 f=faces[i];
@ -666,68 +666,68 @@ DVector< Face3 > Geometry::wrap_geometry( DVector< Face3 > p_array,float *p_erro
print_line("Wrapper (2/6) Flood Filling"); print_line("Wrapper (2/6) Flood Filling");
for (int i=0;i<div_x;i++) { for (int i=0;i<div_x;i++) {
for (int j=0;j<div_y;j++) { for (int j=0;j<div_y;j++) {
_mark_outside(cell_status,i,j,0,div_x,div_y,div_z); _mark_outside(cell_status,i,j,0,div_x,div_y,div_z);
_mark_outside(cell_status,i,j,div_z-1,div_x,div_y,div_z); _mark_outside(cell_status,i,j,div_z-1,div_x,div_y,div_z);
} }
} }
for (int i=0;i<div_z;i++) { for (int i=0;i<div_z;i++) {
for (int j=0;j<div_y;j++) { for (int j=0;j<div_y;j++) {
_mark_outside(cell_status,0,j,i,div_x,div_y,div_z); _mark_outside(cell_status,0,j,i,div_x,div_y,div_z);
_mark_outside(cell_status,div_x-1,j,i,div_x,div_y,div_z); _mark_outside(cell_status,div_x-1,j,i,div_x,div_y,div_z);
} }
} }
for (int i=0;i<div_x;i++) { for (int i=0;i<div_x;i++) {
for (int j=0;j<div_z;j++) { for (int j=0;j<div_z;j++) {
_mark_outside(cell_status,i,0,j,div_x,div_y,div_z); _mark_outside(cell_status,i,0,j,div_x,div_y,div_z);
_mark_outside(cell_status,i,div_y-1,j,div_x,div_y,div_z); _mark_outside(cell_status,i,div_y-1,j,div_x,div_y,div_z);
} }
} }
// build faces for the inside-outside cell divisors // build faces for the inside-outside cell divisors
print_line("Wrapper (3/6): Building Faces"); print_line("Wrapper (3/6): Building Faces");
DVector<Face3> wrapped_faces; DVector<Face3> wrapped_faces;
for (int i=0;i<div_x;i++) { for (int i=0;i<div_x;i++) {
for (int j=0;j<div_y;j++) { for (int j=0;j<div_y;j++) {
for (int k=0;k<div_z;k++) { for (int k=0;k<div_z;k++) {
_build_faces(cell_status,i,j,k,div_x,div_y,div_z,wrapped_faces); _build_faces(cell_status,i,j,k,div_x,div_y,div_z,wrapped_faces);
} }
} }
} }
print_line("Wrapper (4/6): Transforming Back Vertices"); print_line("Wrapper (4/6): Transforming Back Vertices");
// transform face vertices to global coords // transform face vertices to global coords
int wrapped_faces_count=wrapped_faces.size(); int wrapped_faces_count=wrapped_faces.size();
DVector<Face3>::Write wrapped_facesw=wrapped_faces.write(); DVector<Face3>::Write wrapped_facesw=wrapped_faces.write();
Face3* wrapped_faces_ptr=wrapped_facesw.ptr(); Face3* wrapped_faces_ptr=wrapped_facesw.ptr();
for(int i=0;i<wrapped_faces_count;i++) { for(int i=0;i<wrapped_faces_count;i++) {
for(int j=0;j<3;j++) { for(int j=0;j<3;j++) {
Vector3& v = wrapped_faces_ptr[i].vertex[j]; Vector3& v = wrapped_faces_ptr[i].vertex[j];
v=v*voxelsize; v=v*voxelsize;
v+=global_aabb.pos; v+=global_aabb.pos;
} }
} }
// clean up grid // clean up grid
print_line("Wrapper (5/6): Grid Cleanup"); print_line("Wrapper (5/6): Grid Cleanup");
for(int i=0;i<div_x;i++) { for(int i=0;i<div_x;i++) {
@ -736,14 +736,14 @@ DVector< Face3 > Geometry::wrap_geometry( DVector< Face3 > p_array,float *p_erro
memdelete_arr( cell_status[i][j] ); memdelete_arr( cell_status[i][j] );
} }
memdelete_arr( cell_status[i] ); memdelete_arr( cell_status[i] );
} }
memdelete_arr(cell_status); memdelete_arr(cell_status);
if (p_error) if (p_error)
*p_error=voxelsize.length(); *p_error=voxelsize.length();
print_line("Wrapper (6/6): Finished."); print_line("Wrapper (6/6): Finished.");
return wrapped_faces; return wrapped_faces;
} }
@ -751,67 +751,67 @@ DVector< Face3 > Geometry::wrap_geometry( DVector< Face3 > p_array,float *p_erro
Geometry::MeshData Geometry::build_convex_mesh(const DVector<Plane> &p_planes) { Geometry::MeshData Geometry::build_convex_mesh(const DVector<Plane> &p_planes) {
MeshData mesh; MeshData mesh;
#define SUBPLANE_SIZE 1024.0 #define SUBPLANE_SIZE 1024.0
float subplane_size = 1024.0; // should compute this from the actual plane float subplane_size = 1024.0; // should compute this from the actual plane
for (int i=0;i<p_planes.size();i++) { for (int i=0;i<p_planes.size();i++) {
Plane p =p_planes[i]; Plane p =p_planes[i];
Vector3 ref=Vector3(0.0,1.0,0.0); Vector3 ref=Vector3(0.0,1.0,0.0);
if (ABS(p.normal.dot(ref))>0.95) if (ABS(p.normal.dot(ref))>0.95)
ref=Vector3(0.0,0.0,1.0); // change axis ref=Vector3(0.0,0.0,1.0); // change axis
Vector3 right = p.normal.cross(ref).normalized(); Vector3 right = p.normal.cross(ref).normalized();
Vector3 up = p.normal.cross( right ).normalized(); Vector3 up = p.normal.cross( right ).normalized();
Vector< Vector3 > vertices; Vector< Vector3 > vertices;
Vector3 center = p.get_any_point(); Vector3 center = p.get_any_point();
// make a quad clockwise // make a quad clockwise
vertices.push_back( center - up * subplane_size + right * subplane_size ); vertices.push_back( center - up * subplane_size + right * subplane_size );
vertices.push_back( center - up * subplane_size - right * subplane_size ); vertices.push_back( center - up * subplane_size - right * subplane_size );
vertices.push_back( center + up * subplane_size - right * subplane_size ); vertices.push_back( center + up * subplane_size - right * subplane_size );
vertices.push_back( center + up * subplane_size + right * subplane_size ); vertices.push_back( center + up * subplane_size + right * subplane_size );
for (int j=0;j<p_planes.size();j++) { for (int j=0;j<p_planes.size();j++) {
if (j==i) if (j==i)
continue; continue;
Vector< Vector3 > new_vertices; Vector< Vector3 > new_vertices;
Plane clip=p_planes[j]; Plane clip=p_planes[j];
if (clip.normal.dot(p.normal)>0.95) if (clip.normal.dot(p.normal)>0.95)
continue; continue;
if (vertices.size()<3) if (vertices.size()<3)
break; break;
for(int k=0;k<vertices.size();k++) { for(int k=0;k<vertices.size();k++) {
int k_n=(k+1)%vertices.size(); int k_n=(k+1)%vertices.size();
Vector3 edge0_A=vertices[k]; Vector3 edge0_A=vertices[k];
Vector3 edge1_A=vertices[k_n]; Vector3 edge1_A=vertices[k_n];
real_t dist0 = clip.distance_to(edge0_A); real_t dist0 = clip.distance_to(edge0_A);
real_t dist1 = clip.distance_to(edge1_A); real_t dist1 = clip.distance_to(edge1_A);
if ( dist0 <= 0 ) { // behind plane if ( dist0 <= 0 ) { // behind plane
new_vertices.push_back(vertices[k]); new_vertices.push_back(vertices[k]);
} }
// check for different sides and non coplanar // check for different sides and non coplanar
if ( (dist0*dist1) < 0) { if ( (dist0*dist1) < 0) {
// calculate intersection // calculate intersection
Vector3 rel = edge1_A - edge0_A; Vector3 rel = edge1_A - edge0_A;
@ -822,55 +822,55 @@ Geometry::MeshData Geometry::build_convex_mesh(const DVector<Plane> &p_planes) {
real_t dist=-(clip.normal.dot( edge0_A )-clip.d)/den; real_t dist=-(clip.normal.dot( edge0_A )-clip.d)/den;
Vector3 inters = edge0_A+rel*dist; Vector3 inters = edge0_A+rel*dist;
new_vertices.push_back(inters); new_vertices.push_back(inters);
} }
} }
vertices=new_vertices; vertices=new_vertices;
} }
if (vertices.size()<3) if (vertices.size()<3)
continue; continue;
//result is a clockwise face //result is a clockwise face
MeshData::Face face; MeshData::Face face;
// add face indices // add face indices
for (int j=0;j<vertices.size();j++) { for (int j=0;j<vertices.size();j++) {
int idx=-1; int idx=-1;
for (int k=0;k<mesh.vertices.size();k++) { for (int k=0;k<mesh.vertices.size();k++) {
if (mesh.vertices[k].distance_to(vertices[j])<0.001) { if (mesh.vertices[k].distance_to(vertices[j])<0.001) {
idx=k; idx=k;
break; break;
} }
} }
if (idx==-1) { if (idx==-1) {
idx=mesh.vertices.size(); idx=mesh.vertices.size();
mesh.vertices.push_back(vertices[j]); mesh.vertices.push_back(vertices[j]);
} }
face.indices.push_back(idx); face.indices.push_back(idx);
} }
face.plane=p; face.plane=p;
mesh.faces.push_back(face); mesh.faces.push_back(face);
//add edge //add edge
for(int j=0;j<face.indices.size();j++) { for(int j=0;j<face.indices.size();j++) {
int a=face.indices[j]; int a=face.indices[j];
int b=face.indices[(j+1)%face.indices.size()]; int b=face.indices[(j+1)%face.indices.size()];
bool found=false; bool found=false;
for(int k=0;k<mesh.edges.size();k++) { for(int k=0;k<mesh.edges.size();k++) {
if (mesh.edges[k].a==a && mesh.edges[k].b==b) { if (mesh.edges[k].a==a && mesh.edges[k].b==b) {
found=true; found=true;
break; break;
@ -878,9 +878,9 @@ Geometry::MeshData Geometry::build_convex_mesh(const DVector<Plane> &p_planes) {
if (mesh.edges[k].b==a && mesh.edges[k].a==b) { if (mesh.edges[k].b==a && mesh.edges[k].a==b) {
found=true; found=true;
break; break;
} }
} }
if (found) if (found)
continue; continue;
MeshData::Edge edge; MeshData::Edge edge;
@ -888,8 +888,8 @@ Geometry::MeshData Geometry::build_convex_mesh(const DVector<Plane> &p_planes) {
edge.b=b; edge.b=b;
mesh.edges.push_back(edge); mesh.edges.push_back(edge);
} }
} }
return mesh; return mesh;
@ -899,36 +899,36 @@ Geometry::MeshData Geometry::build_convex_mesh(const DVector<Plane> &p_planes) {
DVector<Plane> Geometry::build_box_planes(const Vector3& p_extents) { DVector<Plane> Geometry::build_box_planes(const Vector3& p_extents) {
DVector<Plane> planes; DVector<Plane> planes;
planes.push_back( Plane( Vector3(1,0,0), p_extents.x ) ); planes.push_back( Plane( Vector3(1,0,0), p_extents.x ) );
planes.push_back( Plane( Vector3(-1,0,0), p_extents.x ) ); planes.push_back( Plane( Vector3(-1,0,0), p_extents.x ) );
planes.push_back( Plane( Vector3(0,1,0), p_extents.y ) ); planes.push_back( Plane( Vector3(0,1,0), p_extents.y ) );
planes.push_back( Plane( Vector3(0,-1,0), p_extents.y ) ); planes.push_back( Plane( Vector3(0,-1,0), p_extents.y ) );
planes.push_back( Plane( Vector3(0,0,1), p_extents.z ) ); planes.push_back( Plane( Vector3(0,0,1), p_extents.z ) );
planes.push_back( Plane( Vector3(0,0,-1), p_extents.z ) ); planes.push_back( Plane( Vector3(0,0,-1), p_extents.z ) );
return planes; return planes;
} }
DVector<Plane> Geometry::build_cylinder_planes(float p_radius, float p_height, int p_sides, Vector3::Axis p_axis) { DVector<Plane> Geometry::build_cylinder_planes(float p_radius, float p_height, int p_sides, Vector3::Axis p_axis) {
DVector<Plane> planes; DVector<Plane> planes;
for (int i=0;i<p_sides;i++) { for (int i=0;i<p_sides;i++) {
Vector3 normal; Vector3 normal;
normal[(p_axis+1)%3]=Math::cos(i*(2.0*Math_PI)/p_sides); normal[(p_axis+1)%3]=Math::cos(i*(2.0*Math_PI)/p_sides);
normal[(p_axis+2)%3]=Math::sin(i*(2.0*Math_PI)/p_sides); normal[(p_axis+2)%3]=Math::sin(i*(2.0*Math_PI)/p_sides);
planes.push_back( Plane( normal, p_radius ) ); planes.push_back( Plane( normal, p_radius ) );
} }
Vector3 axis; Vector3 axis;
axis[p_axis]=1.0; axis[p_axis]=1.0;
planes.push_back( Plane( axis, p_height*0.5 ) ); planes.push_back( Plane( axis, p_height*0.5 ) );
planes.push_back( Plane( -axis, p_height*0.5 ) ); planes.push_back( Plane( -axis, p_height*0.5 ) );
return planes; return planes;
} }
@ -972,34 +972,34 @@ DVector<Plane> Geometry::build_sphere_planes(float p_radius, int p_lats,int p_lo
DVector<Plane> Geometry::build_capsule_planes(float p_radius, float p_height, int p_sides, int p_lats, Vector3::Axis p_axis) { DVector<Plane> Geometry::build_capsule_planes(float p_radius, float p_height, int p_sides, int p_lats, Vector3::Axis p_axis) {
DVector<Plane> planes; DVector<Plane> planes;
Vector3 axis; Vector3 axis;
axis[p_axis]=1.0; axis[p_axis]=1.0;
Vector3 axis_neg; Vector3 axis_neg;
axis_neg[(p_axis+1)%3]=1.0; axis_neg[(p_axis+1)%3]=1.0;
axis_neg[(p_axis+2)%3]=1.0; axis_neg[(p_axis+2)%3]=1.0;
axis_neg[p_axis]=-1.0; axis_neg[p_axis]=-1.0;
for (int i=0;i<p_sides;i++) { for (int i=0;i<p_sides;i++) {
Vector3 normal; Vector3 normal;
normal[(p_axis+1)%3]=Math::cos(i*(2.0*Math_PI)/p_sides); normal[(p_axis+1)%3]=Math::cos(i*(2.0*Math_PI)/p_sides);
normal[(p_axis+2)%3]=Math::sin(i*(2.0*Math_PI)/p_sides); normal[(p_axis+2)%3]=Math::sin(i*(2.0*Math_PI)/p_sides);
planes.push_back( Plane( normal, p_radius ) ); planes.push_back( Plane( normal, p_radius ) );
for (int j=1;j<=p_lats;j++) { for (int j=1;j<=p_lats;j++) {
Vector3 angle = normal.linear_interpolate(axis,j/(float)p_lats).normalized(); Vector3 angle = normal.linear_interpolate(axis,j/(float)p_lats).normalized();
Vector3 pos = axis*p_height*0.5 + angle*p_radius; Vector3 pos = axis*p_height*0.5 + angle*p_radius;
planes.push_back( Plane( pos, angle ) ); planes.push_back( Plane( pos, angle ) );
planes.push_back( Plane( pos * axis_neg, angle * axis_neg) ); planes.push_back( Plane( pos * axis_neg, angle * axis_neg) );
} }
} }
return planes; return planes;
} }

View File

@ -44,7 +44,7 @@
class Geometry { class Geometry {
Geometry(); Geometry();
public: public:
@ -201,37 +201,37 @@ public:
real_t a =e1.dot(h); real_t a =e1.dot(h);
if (a>-CMP_EPSILON && a < CMP_EPSILON) // parallel test if (a>-CMP_EPSILON && a < CMP_EPSILON) // parallel test
return false; return false;
real_t f=1.0/a; real_t f=1.0/a;
Vector3 s=p_from-p_v0; Vector3 s=p_from-p_v0;
real_t u = f * s.dot(h); real_t u = f * s.dot(h);
if ( u< 0.0 || u > 1.0) if ( u< 0.0 || u > 1.0)
return false; return false;
Vector3 q=s.cross(e1); Vector3 q=s.cross(e1);
real_t v = f * p_dir.dot(q); real_t v = f * p_dir.dot(q);
if (v < 0.0 || u + v > 1.0) if (v < 0.0 || u + v > 1.0)
return false; return false;
// at this stage we can compute t to find out where // at this stage we can compute t to find out where
// the intersection point is on the line // the intersection point is on the line
real_t t = f * e2.dot(q); real_t t = f * e2.dot(q);
if (t > 0.00001) {// ray intersection if (t > 0.00001) {// ray intersection
if (r_res) if (r_res)
*r_res=p_from+p_dir*t; *r_res=p_from+p_dir*t;
return true; return true;
} else // this means that there is a line intersection } else // this means that there is a line intersection
// but not a ray intersection // but not a ray intersection
return false; return false;
} }
static inline bool segment_intersects_triangle( const Vector3& p_from, const Vector3& p_to, const Vector3& p_v0,const Vector3& p_v1,const Vector3& p_v2,Vector3* r_res=0) { static inline bool segment_intersects_triangle( const Vector3& p_from, const Vector3& p_to, const Vector3& p_v0,const Vector3& p_v1,const Vector3& p_v2,Vector3* r_res=0) {
Vector3 rel=p_to-p_from; Vector3 rel=p_to-p_from;
Vector3 e1=p_v1-p_v0; Vector3 e1=p_v1-p_v0;
Vector3 e2=p_v2-p_v0; Vector3 e2=p_v2-p_v0;
@ -239,34 +239,34 @@ public:
real_t a =e1.dot(h); real_t a =e1.dot(h);
if (a>-CMP_EPSILON && a < CMP_EPSILON) // parallel test if (a>-CMP_EPSILON && a < CMP_EPSILON) // parallel test
return false; return false;
real_t f=1.0/a; real_t f=1.0/a;
Vector3 s=p_from-p_v0; Vector3 s=p_from-p_v0;
real_t u = f * s.dot(h); real_t u = f * s.dot(h);
if ( u< 0.0 || u > 1.0) if ( u< 0.0 || u > 1.0)
return false; return false;
Vector3 q=s.cross(e1); Vector3 q=s.cross(e1);
real_t v = f * rel.dot(q); real_t v = f * rel.dot(q);
if (v < 0.0 || u + v > 1.0) if (v < 0.0 || u + v > 1.0)
return false; return false;
// at this stage we can compute t to find out where // at this stage we can compute t to find out where
// the intersection point is on the line // the intersection point is on the line
real_t t = f * e2.dot(q); real_t t = f * e2.dot(q);
if (t > CMP_EPSILON && t<=1.0) {// ray intersection if (t > CMP_EPSILON && t<=1.0) {// ray intersection
if (r_res) if (r_res)
*r_res=p_from+rel*t; *r_res=p_from+rel*t;
return true; return true;
} else // this means that there is a line intersection } else // this means that there is a line intersection
// but not a ray intersection // but not a ray intersection
return false; return false;
} }
static inline bool segment_intersects_sphere( const Vector3& p_from, const Vector3& p_to, const Vector3& p_sphere_pos,real_t p_sphere_radius,Vector3* r_res=0,Vector3 *r_norm=0) { static inline bool segment_intersects_sphere( const Vector3& p_from, const Vector3& p_to, const Vector3& p_sphere_pos,real_t p_sphere_radius,Vector3* r_res=0,Vector3 *r_norm=0) {
@ -356,24 +356,24 @@ public:
real_t box_end=size[i]; real_t box_end=size[i];
real_t cmin,cmax; real_t cmin,cmax;
if (seg_from < seg_to) { if (seg_from < seg_to) {
if (seg_from > box_end || seg_to < box_begin) if (seg_from > box_end || seg_to < box_begin)
return false; return false;
real_t length=seg_to-seg_from; real_t length=seg_to-seg_from;
cmin = (seg_from < box_begin)?((box_begin - seg_from)/length):0; cmin = (seg_from < box_begin)?((box_begin - seg_from)/length):0;
cmax = (seg_to > box_end)?((box_end - seg_from)/length):1; cmax = (seg_to > box_end)?((box_end - seg_from)/length):1;
} else { } else {
if (seg_to > box_end || seg_from < box_begin) if (seg_to > box_end || seg_from < box_begin)
return false; return false;
real_t length=seg_to-seg_from; real_t length=seg_to-seg_from;
cmin = (seg_from > box_end)?(box_end - seg_from)/length:0; cmin = (seg_from > box_end)?(box_end - seg_from)/length:0;
cmax = (seg_to < box_begin)?(box_begin - seg_from)/length:1; cmax = (seg_to < box_begin)?(box_begin - seg_from)/length:1;
} }
if (cmin > min) { if (cmin > min) {
min = cmin; min = cmin;
axis=i; axis=i;
@ -468,9 +468,9 @@ public:
if (l<1e-10) if (l<1e-10)
return p_segment[0]; // both points are the same, just give any return p_segment[0]; // both points are the same, just give any
n/=l; n/=l;
float d=n.dot(p); float d=n.dot(p);
if (d<=0.0) if (d<=0.0)
return p_segment[0]; // before first point return p_segment[0]; // before first point
else if (d>=l) else if (d>=l)
@ -570,27 +570,27 @@ public:
static inline bool point_in_projected_triangle(const Vector3& p_point,const Vector3& p_v1,const Vector3& p_v2,const Vector3& p_v3) { static inline bool point_in_projected_triangle(const Vector3& p_point,const Vector3& p_v1,const Vector3& p_v2,const Vector3& p_v3) {
Vector3 face_n = (p_v1-p_v3).cross(p_v1-p_v2); Vector3 face_n = (p_v1-p_v3).cross(p_v1-p_v2);
Vector3 n1 = (p_point-p_v3).cross(p_point-p_v2); Vector3 n1 = (p_point-p_v3).cross(p_point-p_v2);
if (face_n.dot(n1)<0) if (face_n.dot(n1)<0)
return false; return false;
Vector3 n2 = (p_v1-p_v3).cross(p_v1-p_point); Vector3 n2 = (p_v1-p_v3).cross(p_v1-p_point);
if (face_n.dot(n2)<0) if (face_n.dot(n2)<0)
return false; return false;
Vector3 n3 = (p_v1-p_point).cross(p_v1-p_v2); Vector3 n3 = (p_v1-p_point).cross(p_v1-p_v2);
if (face_n.dot(n3)<0) if (face_n.dot(n3)<0)
return false; return false;
return true; return true;
} }
static inline bool triangle_sphere_intersection_test(const Vector3 *p_triangle,const Vector3& p_normal,const Vector3& p_sphere_pos, real_t p_sphere_radius,Vector3& r_triangle_contact,Vector3& r_sphere_contact) { static inline bool triangle_sphere_intersection_test(const Vector3 *p_triangle,const Vector3& p_normal,const Vector3& p_sphere_pos, real_t p_sphere_radius,Vector3& r_triangle_contact,Vector3& r_sphere_contact) {
@ -814,21 +814,21 @@ public:
struct MeshData { struct MeshData {
struct Face { struct Face {
Plane plane; Plane plane;
Vector<int> indices; Vector<int> indices;
}; };
Vector<Face> faces; Vector<Face> faces;
struct Edge { struct Edge {
int a,b; int a,b;
}; };
Vector<Edge> edges; Vector<Edge> edges;
Vector< Vector3 > vertices; Vector< Vector3 > vertices;
void optimize_vertices(); void optimize_vertices();
@ -927,7 +927,7 @@ public:
static void make_atlas(const Vector<Size2i>& p_rects,Vector<Point2i>& r_result, Size2i& r_size); static void make_atlas(const Vector<Size2i>& p_rects,Vector<Point2i>& r_result, Size2i& r_size);
}; };

View File

@ -45,10 +45,10 @@ float Vector2::length_squared() const {
} }
void Vector2::normalize() { void Vector2::normalize() {
float l = x*x + y*y; float l = x*x + y*y;
if (l!=0) { if (l!=0) {
l=Math::sqrt(l); l=Math::sqrt(l);
x/=l; x/=l;
y/=l; y/=l;
@ -56,14 +56,14 @@ void Vector2::normalize() {
} }
Vector2 Vector2::normalized() const { Vector2 Vector2::normalized() const {
Vector2 v=*this; Vector2 v=*this;
v.normalize(); v.normalize();
return v; return v;
} }
float Vector2::distance_to(const Vector2& p_vector2) const { float Vector2::distance_to(const Vector2& p_vector2) const {
return Math::sqrt( (x-p_vector2.x)*(x-p_vector2.x) + (y-p_vector2.y)*(y-p_vector2.y)); return Math::sqrt( (x-p_vector2.x)*(x-p_vector2.x) + (y-p_vector2.y)*(y-p_vector2.y));
} }
@ -73,7 +73,7 @@ float Vector2::distance_squared_to(const Vector2& p_vector2) const {
} }
float Vector2::angle_to(const Vector2& p_vector2) const { float Vector2::angle_to(const Vector2& p_vector2) const {
return Math::atan2( tangent().dot(p_vector2), dot(p_vector2) ); return Math::atan2( tangent().dot(p_vector2), dot(p_vector2) );
} }
@ -83,7 +83,7 @@ float Vector2::angle_to_point(const Vector2& p_vector2) const {
} }
float Vector2::dot(const Vector2& p_other) const { float Vector2::dot(const Vector2& p_other) const {
return x*p_other.x + y*p_other.y; return x*p_other.x + y*p_other.y;
} }
@ -99,62 +99,62 @@ Vector2 Vector2::cross(real_t p_other) const {
Vector2 Vector2::operator+(const Vector2& p_v) const { Vector2 Vector2::operator+(const Vector2& p_v) const {
return Vector2(x+p_v.x,y+p_v.y); return Vector2(x+p_v.x,y+p_v.y);
} }
void Vector2::operator+=(const Vector2& p_v) { void Vector2::operator+=(const Vector2& p_v) {
x+=p_v.x; y+=p_v.y; x+=p_v.x; y+=p_v.y;
} }
Vector2 Vector2::operator-(const Vector2& p_v) const { Vector2 Vector2::operator-(const Vector2& p_v) const {
return Vector2(x-p_v.x,y-p_v.y); return Vector2(x-p_v.x,y-p_v.y);
} }
void Vector2::operator-=(const Vector2& p_v) { void Vector2::operator-=(const Vector2& p_v) {
x-=p_v.x; y-=p_v.y; x-=p_v.x; y-=p_v.y;
} }
Vector2 Vector2::operator*(const Vector2 &p_v1) const { Vector2 Vector2::operator*(const Vector2 &p_v1) const {
return Vector2(x * p_v1.x, y * p_v1.y); return Vector2(x * p_v1.x, y * p_v1.y);
}; };
Vector2 Vector2::operator*(const float &rvalue) const { Vector2 Vector2::operator*(const float &rvalue) const {
return Vector2(x * rvalue, y * rvalue); return Vector2(x * rvalue, y * rvalue);
}; };
void Vector2::operator*=(const float &rvalue) { void Vector2::operator*=(const float &rvalue) {
x *= rvalue; y *= rvalue; x *= rvalue; y *= rvalue;
}; };
Vector2 Vector2::operator/(const Vector2 &p_v1) const { Vector2 Vector2::operator/(const Vector2 &p_v1) const {
return Vector2(x / p_v1.x, y / p_v1.y); return Vector2(x / p_v1.x, y / p_v1.y);
}; };
Vector2 Vector2::operator/(const float &rvalue) const { Vector2 Vector2::operator/(const float &rvalue) const {
return Vector2(x / rvalue, y / rvalue); return Vector2(x / rvalue, y / rvalue);
}; };
void Vector2::operator/=(const float &rvalue) { void Vector2::operator/=(const float &rvalue) {
x /= rvalue; y /= rvalue; x /= rvalue; y /= rvalue;
}; };
Vector2 Vector2::operator-() const { Vector2 Vector2::operator-() const {
return Vector2(-x,-y); return Vector2(-x,-y);
} }
bool Vector2::operator==(const Vector2& p_vec2) const { bool Vector2::operator==(const Vector2& p_vec2) const {
return x==p_vec2.x && y==p_vec2.y; return x==p_vec2.x && y==p_vec2.y;
} }
bool Vector2::operator!=(const Vector2& p_vec2) const { bool Vector2::operator!=(const Vector2& p_vec2) const {
return x!=p_vec2.x || y!=p_vec2.y; return x!=p_vec2.x || y!=p_vec2.y;
} }
Vector2 Vector2::floor() const { Vector2 Vector2::floor() const {
@ -621,25 +621,25 @@ float Matrix32::basis_determinant() const {
} }
Matrix32 Matrix32::interpolate_with(const Matrix32& p_transform, float p_c) const { Matrix32 Matrix32::interpolate_with(const Matrix32& p_transform, float p_c) const {
//extract parameters //extract parameters
Vector2 p1 = get_origin(); Vector2 p1 = get_origin();
Vector2 p2 = p_transform.get_origin(); Vector2 p2 = p_transform.get_origin();
real_t r1 = get_rotation(); real_t r1 = get_rotation();
real_t r2 = p_transform.get_rotation(); real_t r2 = p_transform.get_rotation();
Vector2 s1 = get_scale(); Vector2 s1 = get_scale();
Vector2 s2 = p_transform.get_scale(); Vector2 s2 = p_transform.get_scale();
//slerp rotation //slerp rotation
Vector2 v1(Math::cos(r1), Math::sin(r1)); Vector2 v1(Math::cos(r1), Math::sin(r1));
Vector2 v2(Math::cos(r2), Math::sin(r2)); Vector2 v2(Math::cos(r2), Math::sin(r2));
real_t dot = v1.dot(v2); real_t dot = v1.dot(v2);
dot = (dot < -1.0) ? -1.0 : ((dot > 1.0) ? 1.0 : dot); //clamp dot to [-1,1] dot = (dot < -1.0) ? -1.0 : ((dot > 1.0) ? 1.0 : dot); //clamp dot to [-1,1]
Vector2 v; Vector2 v;
if (dot > 0.9995) { if (dot > 0.9995) {
@ -649,7 +649,7 @@ Matrix32 Matrix32::interpolate_with(const Matrix32& p_transform, float p_c) cons
Vector2 v3 = (v2 - v1*dot).normalized(); Vector2 v3 = (v2 - v1*dot).normalized();
v = v1*Math::cos(angle) + v3*Math::sin(angle); v = v1*Math::cos(angle) + v3*Math::sin(angle);
} }
//construct matrix //construct matrix
Matrix32 res(Math::atan2(v.y, v.x), Vector2::linear_interpolate(p1, p2, p_c)); Matrix32 res(Math::atan2(v.y, v.x), Vector2::linear_interpolate(p1, p2, p_c));
res.scale_basis(Vector2::linear_interpolate(s1, s2, p_c)); res.scale_basis(Vector2::linear_interpolate(s1, s2, p_c));

View File

@ -35,15 +35,15 @@
@author Juan Linietsky <reduzio@gmail.com> @author Juan Linietsky <reduzio@gmail.com>
*/ */
enum Margin { enum Margin {
MARGIN_LEFT, MARGIN_LEFT,
MARGIN_TOP, MARGIN_TOP,
MARGIN_RIGHT, MARGIN_RIGHT,
MARGIN_BOTTOM MARGIN_BOTTOM
}; };
enum Orientation { enum Orientation {
HORIZONTAL, HORIZONTAL,
VERTICAL VERTICAL
}; };
@ -63,7 +63,7 @@ enum VAlign {
}; };
struct Vector2 { struct Vector2 {
union { union {
float x; float x;
float width; float width;
@ -87,7 +87,7 @@ struct Vector2 {
float length() const; float length() const;
float length_squared() const; float length_squared() const;
float distance_to(const Vector2& p_vector2) const; float distance_to(const Vector2& p_vector2) const;
float distance_squared_to(const Vector2& p_vector2) const; float distance_squared_to(const Vector2& p_vector2) const;
float angle_to(const Vector2& p_vector2) const; float angle_to(const Vector2& p_vector2) const;
float angle_to_point(const Vector2& p_vector2) const; float angle_to_point(const Vector2& p_vector2) const;
@ -114,19 +114,19 @@ struct Vector2 {
Vector2 operator-(const Vector2& p_v) const; Vector2 operator-(const Vector2& p_v) const;
void operator-=(const Vector2& p_v); void operator-=(const Vector2& p_v);
Vector2 operator*(const Vector2 &p_v1) const; Vector2 operator*(const Vector2 &p_v1) const;
Vector2 operator*(const float &rvalue) const; Vector2 operator*(const float &rvalue) const;
void operator*=(const float &rvalue); void operator*=(const float &rvalue);
void operator*=(const Vector2 &rvalue) { *this = *this * rvalue; } void operator*=(const Vector2 &rvalue) { *this = *this * rvalue; }
Vector2 operator/(const Vector2 &p_v1) const; Vector2 operator/(const Vector2 &p_v1) const;
Vector2 operator/(const float &rvalue) const; Vector2 operator/(const float &rvalue) const;
void operator/=(const float &rvalue); void operator/=(const float &rvalue);
Vector2 operator-() const; Vector2 operator-() const;
bool operator==(const Vector2& p_vec2) const; bool operator==(const Vector2& p_vec2) const;
bool operator!=(const Vector2& p_vec2) const; bool operator!=(const Vector2& p_vec2) const;
@ -151,14 +151,14 @@ struct Vector2 {
return Vector2(y,-x); return Vector2(y,-x);
} }
Vector2 floor() const; Vector2 floor() const;
Vector2 snapped(const Vector2& p_by) const; Vector2 snapped(const Vector2& p_by) const;
float get_aspect() const { return width/height; } float get_aspect() const { return width/height; }
operator String() const { return String::num(x)+","+String::num(y); } operator String() const { return String::num(x)+","+String::num(y); }
_FORCE_INLINE_ Vector2(float p_x,float p_y) { x=p_x; y=p_y; } _FORCE_INLINE_ Vector2(float p_x,float p_y) { x=p_x; y=p_y; }
_FORCE_INLINE_ Vector2() { x=0; y=0; } _FORCE_INLINE_ Vector2() { x=0; y=0; }
}; };
@ -202,7 +202,7 @@ struct Matrix32;
struct Rect2 { struct Rect2 {
Point2 pos; Point2 pos;
Size2 size; Size2 size;
@ -213,7 +213,7 @@ struct Rect2 {
float get_area() const { return size.width*size.height; } float get_area() const { return size.width*size.height; }
inline bool intersects(const Rect2& p_rect) const { inline bool intersects(const Rect2& p_rect) const {
if ( pos.x >= (p_rect.pos.x + p_rect.size.width) ) if ( pos.x >= (p_rect.pos.x + p_rect.size.width) )
return false; return false;
if ( (pos.x+size.width) <= p_rect.pos.x ) if ( (pos.x+size.width) <= p_rect.pos.x )
@ -222,7 +222,7 @@ struct Rect2 {
return false; return false;
if ( (pos.y+size.height) <= p_rect.pos.y ) if ( (pos.y+size.height) <= p_rect.pos.y )
return false; return false;
return true; return true;
} }
@ -254,73 +254,73 @@ struct Rect2 {
bool intersects_segment(const Point2& p_from, const Point2& p_to, Point2* r_pos=NULL, Point2* r_normal=NULL) const; bool intersects_segment(const Point2& p_from, const Point2& p_to, Point2* r_pos=NULL, Point2* r_normal=NULL) const;
inline bool encloses(const Rect2& p_rect) const { inline bool encloses(const Rect2& p_rect) const {
return (p_rect.pos.x>=pos.x) && (p_rect.pos.y>=pos.y) && return (p_rect.pos.x>=pos.x) && (p_rect.pos.y>=pos.y) &&
((p_rect.pos.x+p_rect.size.x)<(pos.x+size.x)) && ((p_rect.pos.x+p_rect.size.x)<(pos.x+size.x)) &&
((p_rect.pos.y+p_rect.size.y)<(pos.y+size.y)); ((p_rect.pos.y+p_rect.size.y)<(pos.y+size.y));
} }
inline bool has_no_area() const { inline bool has_no_area() const {
return (size.x<=0 || size.y<=0); return (size.x<=0 || size.y<=0);
} }
inline Rect2 clip(const Rect2& p_rect) const { /// return a clipped rect inline Rect2 clip(const Rect2& p_rect) const { /// return a clipped rect
Rect2 new_rect=p_rect; Rect2 new_rect=p_rect;
if (!intersects( new_rect )) if (!intersects( new_rect ))
return Rect2(); return Rect2();
new_rect.pos.x = MAX( p_rect.pos.x , pos.x ); new_rect.pos.x = MAX( p_rect.pos.x , pos.x );
new_rect.pos.y = MAX( p_rect.pos.y , pos.y ); new_rect.pos.y = MAX( p_rect.pos.y , pos.y );
Point2 p_rect_end=p_rect.pos+p_rect.size; Point2 p_rect_end=p_rect.pos+p_rect.size;
Point2 end=pos+size; Point2 end=pos+size;
new_rect.size.x=MIN(p_rect_end.x,end.x) - new_rect.pos.x; new_rect.size.x=MIN(p_rect_end.x,end.x) - new_rect.pos.x;
new_rect.size.y=MIN(p_rect_end.y,end.y) - new_rect.pos.y; new_rect.size.y=MIN(p_rect_end.y,end.y) - new_rect.pos.y;
return new_rect; return new_rect;
} }
inline Rect2 merge(const Rect2& p_rect) const { ///< return a merged rect inline Rect2 merge(const Rect2& p_rect) const { ///< return a merged rect
Rect2 new_rect; Rect2 new_rect;
new_rect.pos.x=MIN( p_rect.pos.x , pos.x ); new_rect.pos.x=MIN( p_rect.pos.x , pos.x );
new_rect.pos.y=MIN( p_rect.pos.y , pos.y ); new_rect.pos.y=MIN( p_rect.pos.y , pos.y );
new_rect.size.x = MAX( p_rect.pos.x+p_rect.size.x , pos.x+size.x ); new_rect.size.x = MAX( p_rect.pos.x+p_rect.size.x , pos.x+size.x );
new_rect.size.y = MAX( p_rect.pos.y+p_rect.size.y , pos.y+size.y ); new_rect.size.y = MAX( p_rect.pos.y+p_rect.size.y , pos.y+size.y );
new_rect.size = new_rect.size - new_rect.pos; //make relative again new_rect.size = new_rect.size - new_rect.pos; //make relative again
return new_rect; return new_rect;
}; };
inline bool has_point(const Point2& p_point) const { inline bool has_point(const Point2& p_point) const {
if (p_point.x < pos.x) if (p_point.x < pos.x)
return false; return false;
if (p_point.y < pos.y) if (p_point.y < pos.y)
return false; return false;
if (p_point.x >= (pos.x+size.x) ) if (p_point.x >= (pos.x+size.x) )
return false; return false;
if (p_point.y >= (pos.y+size.y) ) if (p_point.y >= (pos.y+size.y) )
return false; return false;
return true; return true;
} }
inline bool no_area() const { return (size.width<=0 || size.height<=0 ); } inline bool no_area() const { return (size.width<=0 || size.height<=0 ); }
bool operator==(const Rect2& p_rect) const { return pos==p_rect.pos && size==p_rect.size; } bool operator==(const Rect2& p_rect) const { return pos==p_rect.pos && size==p_rect.size; }
bool operator!=(const Rect2& p_rect) const { return pos!=p_rect.pos || size!=p_rect.size; } bool operator!=(const Rect2& p_rect) const { return pos!=p_rect.pos || size!=p_rect.size; }
inline Rect2 grow(real_t p_by) const { inline Rect2 grow(real_t p_by) const {
Rect2 g=*this; Rect2 g=*this;
g.pos.x-=p_by; g.pos.x-=p_by;
g.pos.y-=p_by; g.pos.y-=p_by;
@ -357,9 +357,9 @@ struct Rect2 {
operator String() const { return String(pos)+","+String(size); } operator String() const { return String(pos)+","+String(size); }
Rect2() {} Rect2() {}
Rect2( float p_x, float p_y, float p_width, float p_height) { pos=Point2(p_x,p_y); size=Size2( p_width, p_height ); } Rect2( float p_x, float p_y, float p_width, float p_height) { pos=Point2(p_x,p_y); size=Size2( p_width, p_height ); }
Rect2( const Point2& p_pos, const Size2& p_size ) { pos=p_pos; size=p_size; } Rect2( const Point2& p_pos, const Size2& p_size ) { pos=p_pos; size=p_size; }
}; };

View File

@ -135,18 +135,20 @@ double Math::rad2deg(double p_y) {
double Math::round(double p_val) { double Math::round(double p_val) {
if (p_val>0) { if (p_val>=0) {
return ::floor(p_val+0.5); return ::floor(p_val+0.5);
} else { } else {
p_val=-p_val; p_val=-p_val;
return -::floor(p_val+0.5); return -::floor(p_val+0.5);
} }
} }
double Math::asin(double p_x) { double Math::asin(double p_x) {
return ::asin(p_x); return ::asin(p_x);
} }
double Math::acos(double p_x) { double Math::acos(double p_x) {
return ::acos(p_x); return ::acos(p_x);
@ -185,12 +187,12 @@ double Math::fmod(double p_x,double p_y) {
double Math::fposmod(double p_x,double p_y) { double Math::fposmod(double p_x,double p_y) {
if (p_x>=0) { if (p_x>=0) {
return Math::fmod(p_x,p_y); return Math::fmod(p_x,p_y);
} else { } else {
return p_y-Math::fmod(-p_x,p_y); return p_y-Math::fmod(-p_x,p_y);
} }
} }
@ -205,7 +207,7 @@ double Math::ceil(double p_x) {
} }
int Math::decimals(double p_step) { int Math::decimals(double p_step) {
int max=4; int max=4;
double llimit = Math::pow(0.1,max); double llimit = Math::pow(0.1,max);
double ulimit = 1.0-llimit; double ulimit = 1.0-llimit;
@ -220,7 +222,7 @@ int Math::decimals(double p_step) {
max--; max--;
i++; i++;
} }
return i; return i;
} }
@ -251,11 +253,11 @@ double Math::ease(double p_x, double p_c) {
} }
double Math::stepify(double p_value,double p_step) { double Math::stepify(double p_value,double p_step) {
if (p_step!=0) { if (p_step!=0) {
p_value=floor( p_value / p_step + 0.5 ) * p_step; p_value=floor( p_value / p_step + 0.5 ) * p_step;
} }
return p_value; return p_value;
} }

View File

@ -91,25 +91,25 @@ public:
static uint32_t rand(); static uint32_t rand();
static double randf(); static double randf();
static double round(double p_val); static double round(double p_val);
static double random(double from, double to); static double random(double from, double to);
static _FORCE_INLINE_ real_t abs(real_t g) { static _FORCE_INLINE_ real_t abs(real_t g) {
#ifdef REAL_T_IS_DOUBLE #ifdef REAL_T_IS_DOUBLE
return absd(g); return absd(g);
#else #else
return absf(g); return absf(g);
#endif #endif
} }
static _FORCE_INLINE_ float absf(float g) { static _FORCE_INLINE_ float absf(float g) {
union { union {
float f; float f;
uint32_t i; uint32_t i;
@ -174,7 +174,7 @@ public:
static double pow(double x, double y); static double pow(double x, double y);
static double log(double x); static double log(double x);
static double exp(double x); static double exp(double x);
}; };

View File

@ -62,11 +62,11 @@ void Matrix3::invert() {
real_t det = elements[0][0] * co[0]+ real_t det = elements[0][0] * co[0]+
elements[0][1] * co[1]+ elements[0][1] * co[1]+
elements[0][2] * co[2]; elements[0][2] * co[2];
ERR_FAIL_COND( det == 0 ); ERR_FAIL_COND( det == 0 );
real_t s = 1.0/det; real_t s = 1.0/det;
set( co[0]*s, cofac(0, 2, 2, 1) * s, cofac(0, 1, 1, 2) * s, set( co[0]*s, cofac(0, 2, 2, 1) * s, cofac(0, 1, 1, 2) * s,
co[1]*s, cofac(0, 0, 2, 2) * s, cofac(0, 2, 1, 0) * s, co[1]*s, cofac(0, 0, 2, 2) * s, cofac(0, 2, 1, 0) * s,
co[2]*s, cofac(0, 1, 2, 0) * s, cofac(0, 0, 1, 1) * s ); co[2]*s, cofac(0, 1, 2, 0) * s, cofac(0, 0, 1, 1) * s );
@ -148,7 +148,7 @@ Vector3 Matrix3::get_scale() const {
Vector3(elements[0][1],elements[1][1],elements[2][1]).length(), Vector3(elements[0][1],elements[1][1],elements[2][1]).length(),
Vector3(elements[0][2],elements[1][2],elements[2][2]).length() Vector3(elements[0][2],elements[1][2],elements[2][2]).length()
); );
} }
void Matrix3::rotate(const Vector3& p_axis, real_t p_phi) { void Matrix3::rotate(const Vector3& p_axis, real_t p_phi) {
@ -223,7 +223,7 @@ bool Matrix3::operator==(const Matrix3& p_matrix) const {
return false; return false;
} }
} }
return true; return true;
} }
bool Matrix3::operator!=(const Matrix3& p_matrix) const { bool Matrix3::operator!=(const Matrix3& p_matrix) const {
@ -235,16 +235,16 @@ Matrix3::operator String() const {
String mtx; String mtx;
for (int i=0;i<3;i++) { for (int i=0;i<3;i++) {
for (int j=0;j<3;j++) { for (int j=0;j<3;j++) {
if (i!=0 || j!=0) if (i!=0 || j!=0)
mtx+=", "; mtx+=", ";
mtx+=rtos( elements[i][j] ); mtx+=rtos( elements[i][j] );
} }
} }
return mtx; return mtx;
} }
@ -255,34 +255,34 @@ Matrix3::operator Quat() const {
real_t trace = m.elements[0][0] + m.elements[1][1] + m.elements[2][2]; real_t trace = m.elements[0][0] + m.elements[1][1] + m.elements[2][2];
real_t temp[4]; real_t temp[4];
if (trace > 0.0) if (trace > 0.0)
{ {
real_t s = Math::sqrt(trace + 1.0); real_t s = Math::sqrt(trace + 1.0);
temp[3]=(s * 0.5); temp[3]=(s * 0.5);
s = 0.5 / s; s = 0.5 / s;
temp[0]=((m.elements[2][1] - m.elements[1][2]) * s); temp[0]=((m.elements[2][1] - m.elements[1][2]) * s);
temp[1]=((m.elements[0][2] - m.elements[2][0]) * s); temp[1]=((m.elements[0][2] - m.elements[2][0]) * s);
temp[2]=((m.elements[1][0] - m.elements[0][1]) * s); temp[2]=((m.elements[1][0] - m.elements[0][1]) * s);
} }
else else
{ {
int i = m.elements[0][0] < m.elements[1][1] ? int i = m.elements[0][0] < m.elements[1][1] ?
(m.elements[1][1] < m.elements[2][2] ? 2 : 1) : (m.elements[1][1] < m.elements[2][2] ? 2 : 1) :
(m.elements[0][0] < m.elements[2][2] ? 2 : 0); (m.elements[0][0] < m.elements[2][2] ? 2 : 0);
int j = (i + 1) % 3; int j = (i + 1) % 3;
int k = (i + 2) % 3; int k = (i + 2) % 3;
real_t s = Math::sqrt(m.elements[i][i] - m.elements[j][j] - m.elements[k][k] + 1.0); real_t s = Math::sqrt(m.elements[i][i] - m.elements[j][j] - m.elements[k][k] + 1.0);
temp[i] = s * 0.5; temp[i] = s * 0.5;
s = 0.5 / s; s = 0.5 / s;
temp[3] = (m.elements[k][j] - m.elements[j][k]) * s; temp[3] = (m.elements[k][j] - m.elements[j][k]) * s;
temp[j] = (m.elements[j][i] + m.elements[i][j]) * s; temp[j] = (m.elements[j][i] + m.elements[i][j]) * s;
temp[k] = (m.elements[k][i] + m.elements[i][k]) * s; temp[k] = (m.elements[k][i] + m.elements[i][k]) * s;
} }
return Quat(temp[0],temp[1],temp[2],temp[3]); return Quat(temp[0],temp[1],temp[2],temp[3]);
} }
@ -439,7 +439,7 @@ void Matrix3::get_axis_and_angle(Vector3 &r_axis,real_t& r_angle) const {
Matrix3::Matrix3(const Vector3& p_euler) { Matrix3::Matrix3(const Vector3& p_euler) {
set_euler( p_euler ); set_euler( p_euler );
} }
Matrix3::Matrix3(const Quat& p_quat) { Matrix3::Matrix3(const Quat& p_quat) {
@ -450,8 +450,8 @@ Matrix3::Matrix3(const Quat& p_quat) {
real_t wx = p_quat.w * xs, wy = p_quat.w * ys, wz = p_quat.w * zs; real_t wx = p_quat.w * xs, wy = p_quat.w * ys, wz = p_quat.w * zs;
real_t xx = p_quat.x * xs, xy = p_quat.x * ys, xz = p_quat.x * zs; real_t xx = p_quat.x * xs, xy = p_quat.x * ys, xz = p_quat.x * zs;
real_t yy = p_quat.y * ys, yz = p_quat.y * zs, zz = p_quat.z * zs; real_t yy = p_quat.y * ys, yz = p_quat.y * zs, zz = p_quat.z * zs;
set( 1.0 - (yy + zz), xy - wz, xz + wy, set( 1.0 - (yy + zz), xy - wz, xz + wy,
xy + wz, 1.0 - (xx + zz), yz - wx, xy + wz, 1.0 - (xx + zz), yz - wx,
xz - wy, yz + wx, 1.0 - (xx + yy)) ; xz - wy, yz + wx, 1.0 - (xx + yy)) ;
} }

View File

@ -39,20 +39,20 @@ class Matrix3 {
public: public:
Vector3 elements[3]; Vector3 elements[3];
_FORCE_INLINE_ const Vector3& operator[](int axis) const { _FORCE_INLINE_ const Vector3& operator[](int axis) const {
return elements[axis]; return elements[axis];
} }
_FORCE_INLINE_ Vector3& operator[](int axis) { _FORCE_INLINE_ Vector3& operator[](int axis) {
return elements[axis]; return elements[axis];
} }
void invert(); void invert();
void transpose(); void transpose();
Matrix3 inverse() const; Matrix3 inverse() const;
Matrix3 transposed() const; Matrix3 transposed() const;
_FORCE_INLINE_ float determinant() const; _FORCE_INLINE_ float determinant() const;
@ -90,7 +90,7 @@ public:
_FORCE_INLINE_ real_t tdotz(const Vector3& v) const { _FORCE_INLINE_ real_t tdotz(const Vector3& v) const {
return elements[0][2] * v[0] + elements[1][2] * v[1] + elements[2][2] * v[2]; return elements[0][2] * v[0] + elements[1][2] * v[1] + elements[2][2] * v[2];
} }
bool operator==(const Matrix3& p_matrix) const; bool operator==(const Matrix3& p_matrix) const;
bool operator!=(const Matrix3& p_matrix) const; bool operator!=(const Matrix3& p_matrix) const;
@ -110,7 +110,7 @@ public:
_FORCE_INLINE_ void set(real_t xx, real_t xy, real_t xz, real_t yx, real_t yy, real_t yz, real_t zx, real_t zy, real_t zz) { _FORCE_INLINE_ void set(real_t xx, real_t xy, real_t xz, real_t yx, real_t yy, real_t yz, real_t zx, real_t zy, real_t zz) {
elements[0][0]=xx; elements[0][0]=xx;
elements[0][1]=xy; elements[0][1]=xy;
elements[0][2]=xz; elements[0][2]=xz;
@ -119,15 +119,15 @@ public:
elements[1][2]=yz; elements[1][2]=yz;
elements[2][0]=zx; elements[2][0]=zx;
elements[2][1]=zy; elements[2][1]=zy;
elements[2][2]=zz; elements[2][2]=zz;
} }
_FORCE_INLINE_ Vector3 get_column(int i) const { _FORCE_INLINE_ Vector3 get_column(int i) const {
return Vector3(elements[0][i],elements[1][i],elements[2][i]); return Vector3(elements[0][i],elements[1][i],elements[2][i]);
} }
_FORCE_INLINE_ Vector3 get_row(int i) const { _FORCE_INLINE_ Vector3 get_row(int i) const {
return Vector3(elements[i][0],elements[i][1],elements[i][2]); return Vector3(elements[i][0],elements[i][1],elements[i][2]);
} }
_FORCE_INLINE_ void set_row(int i, const Vector3& p_row) { _FORCE_INLINE_ void set_row(int i, const Vector3& p_row) {
@ -155,8 +155,8 @@ public:
elements[0].z * m[0].y + elements[1].z * m[1].y + elements[2].z * m[2].y, elements[0].z * m[0].y + elements[1].z * m[1].y + elements[2].z * m[2].y,
elements[0].z * m[0].z + elements[1].z * m[1].z + elements[2].z * m[2].z); elements[0].z * m[0].z + elements[1].z * m[1].z + elements[2].z * m[2].z);
} }
Matrix3(real_t xx, real_t xy, real_t xz, real_t yx, real_t yy, real_t yz, real_t zx, real_t zy, real_t zz) { Matrix3(real_t xx, real_t xy, real_t xz, real_t yx, real_t yy, real_t yz, real_t zx, real_t zy, real_t zz) {
set(xx, xy, xz, yx, yy, yz, zx, zy, zz); set(xx, xy, xz, yx, yy, yz, zx, zy, zz);
} }
@ -170,7 +170,7 @@ public:
Matrix3(const Vector3& p_axis, real_t p_phi); Matrix3(const Vector3& p_axis, real_t p_phi);
_FORCE_INLINE_ Matrix3() { _FORCE_INLINE_ Matrix3() {
elements[0][0]=1; elements[0][0]=1;
elements[0][1]=0; elements[0][1]=0;
elements[0][2]=0; elements[0][2]=0;
@ -191,7 +191,7 @@ _FORCE_INLINE_ void Matrix3::operator*=(const Matrix3& p_matrix) {
p_matrix.tdotx(elements[0]), p_matrix.tdoty(elements[0]), p_matrix.tdotz(elements[0]), p_matrix.tdotx(elements[0]), p_matrix.tdoty(elements[0]), p_matrix.tdotz(elements[0]),
p_matrix.tdotx(elements[1]), p_matrix.tdoty(elements[1]), p_matrix.tdotz(elements[1]), p_matrix.tdotx(elements[1]), p_matrix.tdoty(elements[1]), p_matrix.tdotz(elements[1]),
p_matrix.tdotx(elements[2]), p_matrix.tdoty(elements[2]), p_matrix.tdotz(elements[2])); p_matrix.tdotx(elements[2]), p_matrix.tdoty(elements[2]), p_matrix.tdotz(elements[2]));
} }
_FORCE_INLINE_ Matrix3 Matrix3::operator*(const Matrix3& p_matrix) const { _FORCE_INLINE_ Matrix3 Matrix3::operator*(const Matrix3& p_matrix) const {

View File

@ -52,11 +52,11 @@ public:
typedef void* (*PairCallback)(void*,OctreeElementID, T*,int,OctreeElementID, T*,int); typedef void* (*PairCallback)(void*,OctreeElementID, T*,int,OctreeElementID, T*,int);
typedef void (*UnpairCallback)(void*,OctreeElementID, T*,int,OctreeElementID, T*,int,void*); typedef void (*UnpairCallback)(void*,OctreeElementID, T*,int,OctreeElementID, T*,int,void*);
private: private:
enum { enum {
NEG=0, NEG=0,
POS=1, POS=1,
}; };
enum { enum {
@ -72,7 +72,7 @@ private:
struct PairKey { struct PairKey {
union { union {
struct { struct {
OctreeElementID A; OctreeElementID A;
@ -80,66 +80,66 @@ private:
}; };
uint64_t key; uint64_t key;
}; };
_FORCE_INLINE_ bool operator<(const PairKey& p_pair) const { _FORCE_INLINE_ bool operator<(const PairKey& p_pair) const {
return key<p_pair.key; return key<p_pair.key;
} }
_FORCE_INLINE_ PairKey( OctreeElementID p_A, OctreeElementID p_B) { _FORCE_INLINE_ PairKey( OctreeElementID p_A, OctreeElementID p_B) {
if (p_A<p_B) { if (p_A<p_B) {
A=p_A; A=p_A;
B=p_B; B=p_B;
} else { } else {
B=p_A; B=p_A;
A=p_B; A=p_B;
} }
} }
_FORCE_INLINE_ PairKey() {} _FORCE_INLINE_ PairKey() {}
}; };
struct Element; struct Element;
struct Octant { struct Octant {
// cached for FAST plane check // cached for FAST plane check
AABB aabb; AABB aabb;
uint64_t last_pass; uint64_t last_pass;
Octant *parent; Octant *parent;
Octant *children[8]; Octant *children[8];
int children_count; // cache for amount of childrens (fast check for removal) int children_count; // cache for amount of childrens (fast check for removal)
int parent_index; // cache for parent index (fast check for removal) int parent_index; // cache for parent index (fast check for removal)
List<Element*,AL> pairable_elements; List<Element*,AL> pairable_elements;
List<Element*,AL> elements; List<Element*,AL> elements;
Octant() { Octant() {
children_count=0; children_count=0;
parent_index=-1; parent_index=-1;
last_pass=0; last_pass=0;
parent=NULL; parent=NULL;
for (int i=0;i<8;i++) for (int i=0;i<8;i++)
children[i]=NULL; children[i]=NULL;
} }
~Octant() { ~Octant() {
//for (int i=0;i<8;i++) //for (int i=0;i<8;i++)
// memdelete_notnull(children[i]); // memdelete_notnull(children[i]);
} }
}; };
struct PairData; struct PairData;
struct Element { struct Element {
Octree *octree; Octree *octree;
T *userdata; T *userdata;
@ -147,28 +147,28 @@ private:
bool pairable; bool pairable;
uint32_t pairable_mask; uint32_t pairable_mask;
uint32_t pairable_type; uint32_t pairable_type;
uint64_t last_pass; uint64_t last_pass;
OctreeElementID _id; OctreeElementID _id;
Octant *common_parent; Octant *common_parent;
AABB aabb; AABB aabb;
AABB container_aabb; AABB container_aabb;
List<PairData*,AL> pair_list; List<PairData*,AL> pair_list;
struct OctantOwner { struct OctantOwner {
Octant *octant; Octant *octant;
typename List<Element*,AL>::Element *E; typename List<Element*,AL>::Element *E;
}; // an element can be in max 8 octants }; // an element can be in max 8 octants
List<OctantOwner,AL> octant_owners; List<OctantOwner,AL> octant_owners;
Element() { last_pass=0; _id=0; pairable=false; subindex=0; userdata=0; octree=0; pairable_mask=0; pairable_type=0; common_parent=NULL; } Element() { last_pass=0; _id=0; pairable=false; subindex=0; userdata=0; octree=0; pairable_mask=0; pairable_type=0; common_parent=NULL; }
}; };
struct PairData { struct PairData {
@ -181,15 +181,15 @@ private:
typedef Map<OctreeElementID, Element, Comparator<OctreeElementID>, AL> ElementMap; typedef Map<OctreeElementID, Element, Comparator<OctreeElementID>, AL> ElementMap;
typedef Map<PairKey, PairData, Comparator<PairKey>, AL> PairMap; typedef Map<PairKey, PairData, Comparator<PairKey>, AL> PairMap;
ElementMap element_map; ElementMap element_map;
PairMap pair_map; PairMap pair_map;
PairCallback pair_callback; PairCallback pair_callback;
UnpairCallback unpair_callback; UnpairCallback unpair_callback;
void *pair_callback_userdata; void *pair_callback_userdata;
void *unpair_callback_userdata; void *unpair_callback_userdata;
OctreeElementID last_element_id; OctreeElementID last_element_id;
uint64_t pass; uint64_t pass;
real_t unit_size; real_t unit_size;
@ -231,7 +231,7 @@ private:
if (p_A==p_B || (p_A->userdata==p_B->userdata && p_A->userdata)) if (p_A==p_B || (p_A->userdata==p_B->userdata && p_A->userdata))
return; return;
if ( !(p_A->pairable_type&p_B->pairable_mask) && if ( !(p_A->pairable_type&p_B->pairable_mask) &&
!(p_B->pairable_type&p_A->pairable_mask) ) !(p_B->pairable_type&p_A->pairable_mask) )
return; // none can pair with none return; // none can pair with none
@ -253,17 +253,17 @@ private:
// if (pair_callback) // if (pair_callback)
// pair_callback(pair_callback_userdata,p_A->userdata,p_B->userdata); // pair_callback(pair_callback_userdata,p_A->userdata,p_B->userdata);
} else { } else {
E->get().refcount++; E->get().refcount++;
} }
} }
_FORCE_INLINE_ void _pair_unreference(Element* p_A,Element* p_B) { _FORCE_INLINE_ void _pair_unreference(Element* p_A,Element* p_B) {
if (p_A==p_B) if (p_A==p_B)
return; return;
PairKey key(p_A->_id, p_B->_id); PairKey key(p_A->_id, p_B->_id);
typename PairMap::Element *E=pair_map.find(key); typename PairMap::Element *E=pair_map.find(key);
if (!E) { if (!E) {
@ -293,7 +293,7 @@ private:
p_B->pair_list.erase( E->get().eB ); p_B->pair_list.erase( E->get().eB );
pair_map.erase(E); pair_map.erase(E);
} }
} }
_FORCE_INLINE_ void _element_check_pairs(Element *p_element) { _FORCE_INLINE_ void _element_check_pairs(Element *p_element) {
@ -341,7 +341,7 @@ private:
void _ensure_valid_root(const AABB& p_aabb); void _ensure_valid_root(const AABB& p_aabb);
bool _remove_element_from_octant(Element *p_element,Octant *p_octant,Octant *p_limit=NULL); bool _remove_element_from_octant(Element *p_element,Octant *p_octant,Octant *p_limit=NULL);
void _remove_element(Element *p_element); void _remove_element(Element *p_element);
void _pair_element(Element *p_element,Octant *p_octant); void _pair_element(Element *p_element,Octant *p_octant);
void _unpair_element(Element *p_element,Octant *p_octant); void _unpair_element(Element *p_element,Octant *p_octant);
@ -361,16 +361,16 @@ private:
void _cull_point(Octant *p_octant,const Vector3& p_point,T** p_result_array,int *p_result_idx,int p_result_max,int *p_subindex_array,uint32_t p_mask); void _cull_point(Octant *p_octant,const Vector3& p_point,T** p_result_array,int *p_result_idx,int p_result_max,int *p_subindex_array,uint32_t p_mask);
void _remove_tree(Octant *p_octant) { void _remove_tree(Octant *p_octant) {
if (!p_octant) if (!p_octant)
return; return;
for(int i=0;i<8;i++) { for(int i=0;i<8;i++) {
if (p_octant->children[i]) if (p_octant->children[i])
_remove_tree(p_octant->children[i]); _remove_tree(p_octant->children[i]);
} }
memdelete_allocator<Octant,AL>(p_octant); memdelete_allocator<Octant,AL>(p_octant);
} }
public: public:
@ -432,24 +432,24 @@ template<class T,bool use_pairs,class AL>
void Octree<T,use_pairs,AL>::_insert_element(Element *p_element,Octant *p_octant) { void Octree<T,use_pairs,AL>::_insert_element(Element *p_element,Octant *p_octant) {
float element_size = p_element->aabb.get_longest_axis_size() * 1.01; // avoid precision issues float element_size = p_element->aabb.get_longest_axis_size() * 1.01; // avoid precision issues
if (p_octant->aabb.size.x/OCTREE_DIVISOR < element_size) { if (p_octant->aabb.size.x/OCTREE_DIVISOR < element_size) {
//if (p_octant->aabb.size.x*0.5 < element_size) { //if (p_octant->aabb.size.x*0.5 < element_size) {
/* at smallest possible size for the element */ /* at smallest possible size for the element */
typename Element::OctantOwner owner; typename Element::OctantOwner owner;
owner.octant=p_octant; owner.octant=p_octant;
if (use_pairs && p_element->pairable) { if (use_pairs && p_element->pairable) {
p_octant->pairable_elements.push_back(p_element); p_octant->pairable_elements.push_back(p_element);
owner.E = p_octant->pairable_elements.back(); owner.E = p_octant->pairable_elements.back();
} else { } else {
p_octant->elements.push_back(p_element); p_octant->elements.push_back(p_element);
owner.E = p_octant->elements.back(); owner.E = p_octant->elements.back();
} }
p_element->octant_owners.push_back( owner ); p_element->octant_owners.push_back( owner );
if (p_element->common_parent==NULL) { if (p_element->common_parent==NULL) {
@ -461,13 +461,13 @@ void Octree<T,use_pairs,AL>::_insert_element(Element *p_element,Octant *p_octant
if (use_pairs && p_octant->children_count>0) { if (use_pairs && p_octant->children_count>0) {
pass++; //elements below this only get ONE reference added pass++; //elements below this only get ONE reference added
for (int i=0;i<8;i++) { for (int i=0;i<8;i++) {
if (p_octant->children[i]) { if (p_octant->children[i]) {
_pair_element(p_element,p_octant->children[i]); _pair_element(p_element,p_octant->children[i]);
} }
} }
} }
@ -477,7 +477,7 @@ void Octree<T,use_pairs,AL>::_insert_element(Element *p_element,Octant *p_octant
bool candidate=p_element->common_parent==NULL; bool candidate=p_element->common_parent==NULL;
for (int i=0;i<8;i++) { for (int i=0;i<8;i++) {
if (p_octant->children[i]) { if (p_octant->children[i]) {
/* element exists, go straight to it */ /* element exists, go straight to it */
if (p_octant->children[i]->aabb.intersects_inclusive( p_element->aabb ) ) { if (p_octant->children[i]->aabb.intersects_inclusive( p_element->aabb ) ) {
@ -486,20 +486,20 @@ void Octree<T,use_pairs,AL>::_insert_element(Element *p_element,Octant *p_octant
} }
} else { } else {
/* check againt AABB where child should be */ /* check againt AABB where child should be */
AABB aabb=p_octant->aabb; AABB aabb=p_octant->aabb;
aabb.size*=0.5; aabb.size*=0.5;
if (i&1) if (i&1)
aabb.pos.x+=aabb.size.x; aabb.pos.x+=aabb.size.x;
if (i&2) if (i&2)
aabb.pos.y+=aabb.size.y; aabb.pos.y+=aabb.size.y;
if (i&4) if (i&4)
aabb.pos.z+=aabb.size.z; aabb.pos.z+=aabb.size.z;
if (aabb.intersects_inclusive( p_element->aabb) ) { if (aabb.intersects_inclusive( p_element->aabb) ) {
/* if actually intersects, create the child */ /* if actually intersects, create the child */
Octant *child = memnew_allocator( Octant, AL ); Octant *child = memnew_allocator( Octant, AL );
p_octant->children[i]=child; p_octant->children[i]=child;
child->parent=p_octant; child->parent=p_octant;
@ -517,14 +517,14 @@ void Octree<T,use_pairs,AL>::_insert_element(Element *p_element,Octant *p_octant
} }
} }
if (candidate && splits>1) { if (candidate && splits>1) {
p_element->common_parent=p_octant; p_element->common_parent=p_octant;
} }
} }
if (use_pairs) { if (use_pairs) {
typename List<Element*,AL>::Element *E=p_octant->pairable_elements.front(); typename List<Element*,AL>::Element *E=p_octant->pairable_elements.front();
@ -532,8 +532,8 @@ void Octree<T,use_pairs,AL>::_insert_element(Element *p_element,Octant *p_octant
while(E) { while(E) {
_pair_reference( p_element,E->get() ); _pair_reference( p_element,E->get() );
E=E->next(); E=E->next();
} }
if (p_element->pairable) { if (p_element->pairable) {
// and always test non-pairable if element is pairable // and always test non-pairable if element is pairable
E=p_octant->elements.front(); E=p_octant->elements.front();
@ -541,9 +541,9 @@ void Octree<T,use_pairs,AL>::_insert_element(Element *p_element,Octant *p_octant
_pair_reference( p_element,E->get() ); _pair_reference( p_element,E->get() );
E=E->next(); E=E->next();
} }
} }
} }
} }
@ -553,35 +553,35 @@ void Octree<T,use_pairs,AL>::_ensure_valid_root(const AABB& p_aabb) {
if (!root) { if (!root) {
// octre is empty // octre is empty
AABB base( Vector3(), Vector3(1.0,1.0,1.0) * unit_size); AABB base( Vector3(), Vector3(1.0,1.0,1.0) * unit_size);
while ( !base.encloses(p_aabb) ) { while ( !base.encloses(p_aabb) ) {
if ( ABS(base.pos.x+base.size.x) <= ABS(base.pos.x) ) { if ( ABS(base.pos.x+base.size.x) <= ABS(base.pos.x) ) {
/* grow towards positive */ /* grow towards positive */
base.size*=2.0; base.size*=2.0;
} else { } else {
base.pos-=base.size; base.pos-=base.size;
base.size*=2.0; base.size*=2.0;
} }
} }
root = memnew_allocator( Octant, AL ); root = memnew_allocator( Octant, AL );
root->parent=NULL; root->parent=NULL;
root->parent_index=-1; root->parent_index=-1;
root->aabb=base; root->aabb=base;
octant_count++; octant_count++;
} else { } else {
AABB base=root->aabb; AABB base=root->aabb;
while( !base.encloses( p_aabb ) ) { while( !base.encloses( p_aabb ) ) {
if (base.size.x > OCTREE_SIZE_LIMIT) { if (base.size.x > OCTREE_SIZE_LIMIT) {
ERR_EXPLAIN("Octree upper size limit reeached, does the AABB supplied contain NAN?"); ERR_EXPLAIN("Octree upper size limit reeached, does the AABB supplied contain NAN?");
ERR_FAIL(); ERR_FAIL();
@ -590,7 +590,7 @@ void Octree<T,use_pairs,AL>::_ensure_valid_root(const AABB& p_aabb) {
Octant * gp = memnew_allocator( Octant, AL ); Octant * gp = memnew_allocator( Octant, AL );
octant_count++; octant_count++;
root->parent=gp; root->parent=gp;
if ( ABS(base.pos.x+base.size.x) <= ABS(base.pos.x) ) { if ( ABS(base.pos.x+base.size.x) <= ABS(base.pos.x) ) {
/* grow towards positive */ /* grow towards positive */
base.size*=2.0; base.size*=2.0;
@ -598,16 +598,16 @@ void Octree<T,use_pairs,AL>::_ensure_valid_root(const AABB& p_aabb) {
gp->children[0]=root; gp->children[0]=root;
root->parent_index=0; root->parent_index=0;
} else { } else {
base.pos-=base.size; base.pos-=base.size;
base.size*=2.0; base.size*=2.0;
gp->aabb=base; gp->aabb=base;
gp->children[(1<<0)|(1<<1)|(1<<2)]=root; // add at all-positive gp->children[(1<<0)|(1<<1)|(1<<2)]=root; // add at all-positive
root->parent_index=(1<<0)|(1<<1)|(1<<2); root->parent_index=(1<<0)|(1<<1)|(1<<2);
} }
gp->children_count=1; gp->children_count=1;
root=gp; root=gp;
} }
} }
} }
@ -615,16 +615,16 @@ template<class T,bool use_pairs,class AL>
bool Octree<T,use_pairs,AL>::_remove_element_from_octant(Element *p_element,Octant *p_octant,Octant *p_limit) { bool Octree<T,use_pairs,AL>::_remove_element_from_octant(Element *p_element,Octant *p_octant,Octant *p_limit) {
bool octant_removed=false; bool octant_removed=false;
while(true) { while(true) {
// check all exit conditions // check all exit conditions
if (p_octant==p_limit) // reached limit, nothing to erase, exit if (p_octant==p_limit) // reached limit, nothing to erase, exit
return octant_removed; return octant_removed;
bool unpaired=false; bool unpaired=false;
if (use_pairs && p_octant->last_pass!=pass) { if (use_pairs && p_octant->last_pass!=pass) {
// check wether we should unpair stuff // check wether we should unpair stuff
// always test pairable // always test pairable
@ -644,21 +644,21 @@ bool Octree<T,use_pairs,AL>::_remove_element_from_octant(Element *p_element,Octa
p_octant->last_pass=pass; p_octant->last_pass=pass;
unpaired=true; unpaired=true;
} }
bool removed=false; bool removed=false;
Octant *parent=p_octant->parent; Octant *parent=p_octant->parent;
if (p_octant->children_count==0 && p_octant->elements.empty() && p_octant->pairable_elements.empty()) { if (p_octant->children_count==0 && p_octant->elements.empty() && p_octant->pairable_elements.empty()) {
// erase octant // erase octant
if (p_octant==root) { // won't have a parent, just erase if (p_octant==root) { // won't have a parent, just erase
root=NULL; root=NULL;
} else { } else {
ERR_FAIL_INDEX_V(p_octant->parent_index,8,octant_removed); ERR_FAIL_INDEX_V(p_octant->parent_index,8,octant_removed);
parent->children[ p_octant->parent_index ]=NULL; parent->children[ p_octant->parent_index ]=NULL;
parent->children_count--; parent->children_count--;
} }
@ -668,12 +668,12 @@ bool Octree<T,use_pairs,AL>::_remove_element_from_octant(Element *p_element,Octa
removed=true; removed=true;
octant_removed=true; octant_removed=true;
} }
if (!removed && !unpaired) if (!removed && !unpaired)
return octant_removed; // no reason to keep going up anymore! was already visited and was not removed return octant_removed; // no reason to keep going up anymore! was already visited and was not removed
p_octant=parent; p_octant=parent;
} }
return octant_removed; return octant_removed;
@ -682,8 +682,8 @@ bool Octree<T,use_pairs,AL>::_remove_element_from_octant(Element *p_element,Octa
template<class T,bool use_pairs,class AL> template<class T,bool use_pairs,class AL>
void Octree<T,use_pairs,AL>::_unpair_element(Element *p_element,Octant *p_octant) { void Octree<T,use_pairs,AL>::_unpair_element(Element *p_element,Octant *p_octant) {
// always test pairable // always test pairable
typename List<Element*,AL>::Element *E=p_octant->pairable_elements.front(); typename List<Element*,AL>::Element *E=p_octant->pairable_elements.front();
while(E) { while(E) {
if (E->get()->last_pass!=pass) { // only remove ONE reference if (E->get()->last_pass!=pass) { // only remove ONE reference
@ -692,7 +692,7 @@ void Octree<T,use_pairs,AL>::_unpair_element(Element *p_element,Octant *p_octant
} }
E=E->next(); E=E->next();
} }
if (p_element->pairable) { if (p_element->pairable) {
// and always test non-pairable if element is pairable // and always test non-pairable if element is pairable
E=p_octant->elements.front(); E=p_octant->elements.front();
@ -704,14 +704,14 @@ void Octree<T,use_pairs,AL>::_unpair_element(Element *p_element,Octant *p_octant
E=E->next(); E=E->next();
} }
} }
p_octant->last_pass=pass; p_octant->last_pass=pass;
if (p_octant->children_count==0) if (p_octant->children_count==0)
return; // small optimization for leafs return; // small optimization for leafs
for (int i=0;i<8;i++) { for (int i=0;i<8;i++) {
if (p_octant->children[i]) if (p_octant->children[i])
_unpair_element(p_element,p_octant->children[i]); _unpair_element(p_element,p_octant->children[i]);
} }
@ -732,7 +732,7 @@ void Octree<T,use_pairs,AL>::_pair_element(Element *p_element,Octant *p_octant)
} }
E=E->next(); E=E->next();
} }
if (p_element->pairable) { if (p_element->pairable) {
// and always test non-pairable if element is pairable // and always test non-pairable if element is pairable
E=p_octant->elements.front(); E=p_octant->elements.front();
@ -745,12 +745,12 @@ void Octree<T,use_pairs,AL>::_pair_element(Element *p_element,Octant *p_octant)
} }
} }
p_octant->last_pass=pass; p_octant->last_pass=pass;
if (p_octant->children_count==0) if (p_octant->children_count==0)
return; // small optimization for leafs return; // small optimization for leafs
for (int i=0;i<8;i++) { for (int i=0;i<8;i++) {
if (p_octant->children[i]) if (p_octant->children[i])
_pair_element(p_element,p_octant->children[i]); _pair_element(p_element,p_octant->children[i]);
} }
@ -760,13 +760,13 @@ template<class T,bool use_pairs,class AL>
void Octree<T,use_pairs,AL>::_remove_element(Element *p_element) { void Octree<T,use_pairs,AL>::_remove_element(Element *p_element) {
pass++; // will do a new pass for this pass++; // will do a new pass for this
typename List< typename Element::OctantOwner,AL >::Element *I=p_element->octant_owners.front(); typename List< typename Element::OctantOwner,AL >::Element *I=p_element->octant_owners.front();
/* FIRST remove going up normally */ /* FIRST remove going up normally */
for(;I;I=I->next()) { for(;I;I=I->next()) {
Octant *o=I->get().octant; Octant *o=I->get().octant;
if (!use_pairs) // small speedup if (!use_pairs) // small speedup
@ -809,14 +809,14 @@ void Octree<T,use_pairs,AL>::_remove_element(Element *p_element) {
int remaining=p_element->pair_list.size(); int remaining=p_element->pair_list.size();
//p_element->pair_list.clear(); //p_element->pair_list.clear();
ERR_FAIL_COND( remaining ); ERR_FAIL_COND( remaining );
} }
} }
template<class T,bool use_pairs,class AL> template<class T,bool use_pairs,class AL>
OctreeElementID Octree<T,use_pairs,AL>::create(T* p_userdata, const AABB& p_aabb, int p_subindex,bool p_pairable,uint32_t p_pairable_type,uint32_t p_pairable_mask) { OctreeElementID Octree<T,use_pairs,AL>::create(T* p_userdata, const AABB& p_aabb, int p_subindex,bool p_pairable,uint32_t p_pairable_type,uint32_t p_pairable_mask) {
// check for AABB validity // check for AABB validity
#ifdef DEBUG_ENABLED #ifdef DEBUG_ENABLED
ERR_FAIL_COND_V( p_aabb.pos.x > 1e15 || p_aabb.pos.x < -1e15, 0 ); ERR_FAIL_COND_V( p_aabb.pos.x > 1e15 || p_aabb.pos.x < -1e15, 0 );
ERR_FAIL_COND_V( p_aabb.pos.y > 1e15 || p_aabb.pos.y < -1e15, 0 ); ERR_FAIL_COND_V( p_aabb.pos.y > 1e15 || p_aabb.pos.y < -1e15, 0 );
@ -828,12 +828,12 @@ OctreeElementID Octree<T,use_pairs,AL>::create(T* p_userdata, const AABB& p_aabb
ERR_FAIL_COND_V( Math::is_nan(p_aabb.size.y) , 0 ); ERR_FAIL_COND_V( Math::is_nan(p_aabb.size.y) , 0 );
ERR_FAIL_COND_V( Math::is_nan(p_aabb.size.z) , 0 ); ERR_FAIL_COND_V( Math::is_nan(p_aabb.size.z) , 0 );
#endif #endif
typename ElementMap::Element *E = element_map.insert(last_element_id++, typename ElementMap::Element *E = element_map.insert(last_element_id++,
Element()); Element());
Element &e = E->get(); Element &e = E->get();
e.aabb=p_aabb; e.aabb=p_aabb;
e.userdata=p_userdata; e.userdata=p_userdata;
e.subindex=p_subindex; e.subindex=p_subindex;
@ -843,7 +843,7 @@ OctreeElementID Octree<T,use_pairs,AL>::create(T* p_userdata, const AABB& p_aabb
e.pairable_type=p_pairable_type; e.pairable_type=p_pairable_type;
e.pairable_mask=p_pairable_mask; e.pairable_mask=p_pairable_mask;
e._id=last_element_id-1; e._id=last_element_id-1;
if (!e.aabb.has_no_surface()) { if (!e.aabb.has_no_surface()) {
_ensure_valid_root(p_aabb); _ensure_valid_root(p_aabb);
_insert_element(&e,root); _insert_element(&e,root);
@ -964,7 +964,7 @@ void Octree<T,use_pairs,AL>::move(OctreeElementID p_id, const AABB& p_aabb) {
_insert_element(&e,common_parent); // reinsert from this point _insert_element(&e,common_parent); // reinsert from this point
pass++; pass++;
for(typename List<typename Element::OctantOwner,AL>::Element *E=owners.front();E;) { for(typename List<typename Element::OctantOwner,AL>::Element *E=owners.front();E;) {
Octant *o=E->get().octant; Octant *o=E->get().octant;
@ -1018,28 +1018,28 @@ void Octree<T,use_pairs,AL>::set_pairable(OctreeElementID p_id,bool p_pairable,u
typename ElementMap::Element *E = element_map.find(p_id); typename ElementMap::Element *E = element_map.find(p_id);
ERR_FAIL_COND(!E); ERR_FAIL_COND(!E);
Element &e = E->get(); Element &e = E->get();
if (p_pairable == e.pairable && e.pairable_type==p_pairable_type && e.pairable_mask==p_pairable_mask) if (p_pairable == e.pairable && e.pairable_type==p_pairable_type && e.pairable_mask==p_pairable_mask)
return; // no changes, return return; // no changes, return
if (!e.aabb.has_no_surface()) { if (!e.aabb.has_no_surface()) {
_remove_element(&e); _remove_element(&e);
} }
e.pairable=p_pairable; e.pairable=p_pairable;
e.pairable_type=p_pairable_type; e.pairable_type=p_pairable_type;
e.pairable_mask=p_pairable_mask; e.pairable_mask=p_pairable_mask;
e.common_parent=NULL; e.common_parent=NULL;
if (!e.aabb.has_no_surface()) { if (!e.aabb.has_no_surface()) {
_ensure_valid_root(e.aabb); _ensure_valid_root(e.aabb);
_insert_element(&e,root); _insert_element(&e,root);
if (use_pairs) if (use_pairs)
_element_check_pairs(&e); _element_check_pairs(&e);
} }
} }
@ -1048,155 +1048,155 @@ void Octree<T,use_pairs,AL>::erase(OctreeElementID p_id) {
typename ElementMap::Element *E = element_map.find(p_id); typename ElementMap::Element *E = element_map.find(p_id);
ERR_FAIL_COND(!E); ERR_FAIL_COND(!E);
Element &e = E->get(); Element &e = E->get();
if (!e.aabb.has_no_surface()) { if (!e.aabb.has_no_surface()) {
_remove_element(&e); _remove_element(&e);
} }
element_map.erase(p_id); element_map.erase(p_id);
_optimize(); _optimize();
} }
template<class T,bool use_pairs,class AL> template<class T,bool use_pairs,class AL>
void Octree<T,use_pairs,AL>::_cull_convex(Octant *p_octant,_CullConvexData *p_cull) { void Octree<T,use_pairs,AL>::_cull_convex(Octant *p_octant,_CullConvexData *p_cull) {
if (*p_cull->result_idx==p_cull->result_max) if (*p_cull->result_idx==p_cull->result_max)
return; //pointless return; //pointless
if (!p_octant->elements.empty()) { if (!p_octant->elements.empty()) {
typename List< Element*,AL >::Element *I; typename List< Element*,AL >::Element *I;
I=p_octant->elements.front(); I=p_octant->elements.front();
for(;I;I=I->next()) { for(;I;I=I->next()) {
Element *e=I->get(); Element *e=I->get();
if (e->last_pass==pass || (use_pairs && !(e->pairable_type&p_cull->mask))) if (e->last_pass==pass || (use_pairs && !(e->pairable_type&p_cull->mask)))
continue; continue;
e->last_pass=pass; e->last_pass=pass;
if (e->aabb.intersects_convex_shape(p_cull->planes,p_cull->plane_count)) { if (e->aabb.intersects_convex_shape(p_cull->planes,p_cull->plane_count)) {
if (*p_cull->result_idx<p_cull->result_max) { if (*p_cull->result_idx<p_cull->result_max) {
p_cull->result_array[*p_cull->result_idx] = e->userdata; p_cull->result_array[*p_cull->result_idx] = e->userdata;
(*p_cull->result_idx)++; (*p_cull->result_idx)++;
} else { } else {
return; // pointless to continue return; // pointless to continue
} }
} }
} }
} }
if (use_pairs && !p_octant->pairable_elements.empty()) { if (use_pairs && !p_octant->pairable_elements.empty()) {
typename List< Element*,AL >::Element *I; typename List< Element*,AL >::Element *I;
I=p_octant->pairable_elements.front(); I=p_octant->pairable_elements.front();
for(;I;I=I->next()) { for(;I;I=I->next()) {
Element *e=I->get(); Element *e=I->get();
if (e->last_pass==pass || (use_pairs && !(e->pairable_type&p_cull->mask))) if (e->last_pass==pass || (use_pairs && !(e->pairable_type&p_cull->mask)))
continue; continue;
e->last_pass=pass; e->last_pass=pass;
if (e->aabb.intersects_convex_shape(p_cull->planes,p_cull->plane_count)) { if (e->aabb.intersects_convex_shape(p_cull->planes,p_cull->plane_count)) {
if (*p_cull->result_idx<p_cull->result_max) { if (*p_cull->result_idx<p_cull->result_max) {
p_cull->result_array[*p_cull->result_idx] = e->userdata; p_cull->result_array[*p_cull->result_idx] = e->userdata;
(*p_cull->result_idx)++; (*p_cull->result_idx)++;
} else { } else {
return; // pointless to continue return; // pointless to continue
} }
} }
} }
} }
for (int i=0;i<8;i++) { for (int i=0;i<8;i++) {
if (p_octant->children[i] && p_octant->children[i]->aabb.intersects_convex_shape(p_cull->planes,p_cull->plane_count)) { if (p_octant->children[i] && p_octant->children[i]->aabb.intersects_convex_shape(p_cull->planes,p_cull->plane_count)) {
_cull_convex(p_octant->children[i],p_cull); _cull_convex(p_octant->children[i],p_cull);
} }
} }
} }
template<class T,bool use_pairs,class AL> template<class T,bool use_pairs,class AL>
void Octree<T,use_pairs,AL>::_cull_AABB(Octant *p_octant,const AABB& p_aabb, T** p_result_array,int *p_result_idx,int p_result_max,int *p_subindex_array,uint32_t p_mask) { void Octree<T,use_pairs,AL>::_cull_AABB(Octant *p_octant,const AABB& p_aabb, T** p_result_array,int *p_result_idx,int p_result_max,int *p_subindex_array,uint32_t p_mask) {
if (*p_result_idx==p_result_max) if (*p_result_idx==p_result_max)
return; //pointless return; //pointless
if (!p_octant->elements.empty()) { if (!p_octant->elements.empty()) {
typename List< Element*,AL >::Element *I; typename List< Element*,AL >::Element *I;
I=p_octant->elements.front(); I=p_octant->elements.front();
for(;I;I=I->next()) { for(;I;I=I->next()) {
Element *e=I->get(); Element *e=I->get();
if (e->last_pass==pass || (use_pairs && !(e->pairable_type&p_mask))) if (e->last_pass==pass || (use_pairs && !(e->pairable_type&p_mask)))
continue; continue;
e->last_pass=pass; e->last_pass=pass;
if (p_aabb.intersects_inclusive(e->aabb)) { if (p_aabb.intersects_inclusive(e->aabb)) {
if (*p_result_idx<p_result_max) { if (*p_result_idx<p_result_max) {
p_result_array[*p_result_idx] = e->userdata; p_result_array[*p_result_idx] = e->userdata;
if (p_subindex_array) if (p_subindex_array)
p_subindex_array[*p_result_idx] = e->subindex; p_subindex_array[*p_result_idx] = e->subindex;
(*p_result_idx)++; (*p_result_idx)++;
} else { } else {
return; // pointless to continue return; // pointless to continue
} }
} }
} }
} }
if (use_pairs && !p_octant->pairable_elements.empty()) { if (use_pairs && !p_octant->pairable_elements.empty()) {
typename List< Element*,AL >::Element *I; typename List< Element*,AL >::Element *I;
I=p_octant->pairable_elements.front(); I=p_octant->pairable_elements.front();
for(;I;I=I->next()) { for(;I;I=I->next()) {
Element *e=I->get(); Element *e=I->get();
if (e->last_pass==pass || (use_pairs && !(e->pairable_type&p_mask))) if (e->last_pass==pass || (use_pairs && !(e->pairable_type&p_mask)))
continue; continue;
e->last_pass=pass; e->last_pass=pass;
if (p_aabb.intersects_inclusive(e->aabb)) { if (p_aabb.intersects_inclusive(e->aabb)) {
if (*p_result_idx<p_result_max) { if (*p_result_idx<p_result_max) {
p_result_array[*p_result_idx] = e->userdata; p_result_array[*p_result_idx] = e->userdata;
if (p_subindex_array) if (p_subindex_array)
p_subindex_array[*p_result_idx] = e->subindex; p_subindex_array[*p_result_idx] = e->subindex;
(*p_result_idx)++; (*p_result_idx)++;
} else { } else {
return; // pointless to continue return; // pointless to continue
} }
} }
} }
} }
for (int i=0;i<8;i++) { for (int i=0;i<8;i++) {
if (p_octant->children[i] && p_octant->children[i]->aabb.intersects_inclusive(p_aabb)) { if (p_octant->children[i] && p_octant->children[i]->aabb.intersects_inclusive(p_aabb)) {
_cull_AABB(p_octant->children[i],p_aabb, p_result_array,p_result_idx,p_result_max,p_subindex_array,p_mask); _cull_AABB(p_octant->children[i],p_aabb, p_result_array,p_result_idx,p_result_max,p_subindex_array,p_mask);
} }
} }
} }
@ -1205,53 +1205,53 @@ void Octree<T,use_pairs,AL>::_cull_segment(Octant *p_octant,const Vector3& p_fro
if (*p_result_idx==p_result_max) if (*p_result_idx==p_result_max)
return; //pointless return; //pointless
if (!p_octant->elements.empty()) { if (!p_octant->elements.empty()) {
typename List< Element*,AL >::Element *I; typename List< Element*,AL >::Element *I;
I=p_octant->elements.front(); I=p_octant->elements.front();
for(;I;I=I->next()) { for(;I;I=I->next()) {
Element *e=I->get(); Element *e=I->get();
if (e->last_pass==pass || (use_pairs && !(e->pairable_type&p_mask))) if (e->last_pass==pass || (use_pairs && !(e->pairable_type&p_mask)))
continue; continue;
e->last_pass=pass; e->last_pass=pass;
if (e->aabb.intersects_segment(p_from,p_to)) { if (e->aabb.intersects_segment(p_from,p_to)) {
if (*p_result_idx<p_result_max) { if (*p_result_idx<p_result_max) {
p_result_array[*p_result_idx] = e->userdata; p_result_array[*p_result_idx] = e->userdata;
if (p_subindex_array) if (p_subindex_array)
p_subindex_array[*p_result_idx] = e->subindex; p_subindex_array[*p_result_idx] = e->subindex;
(*p_result_idx)++; (*p_result_idx)++;
} else { } else {
return; // pointless to continue return; // pointless to continue
} }
} }
} }
} }
if (use_pairs && !p_octant->pairable_elements.empty()) { if (use_pairs && !p_octant->pairable_elements.empty()) {
typename List< Element*,AL >::Element *I; typename List< Element*,AL >::Element *I;
I=p_octant->pairable_elements.front(); I=p_octant->pairable_elements.front();
for(;I;I=I->next()) { for(;I;I=I->next()) {
Element *e=I->get(); Element *e=I->get();
if (e->last_pass==pass || (use_pairs && !(e->pairable_type&p_mask))) if (e->last_pass==pass || (use_pairs && !(e->pairable_type&p_mask)))
continue; continue;
e->last_pass=pass; e->last_pass=pass;
if (e->aabb.intersects_segment(p_from,p_to)) { if (e->aabb.intersects_segment(p_from,p_to)) {
if (*p_result_idx<p_result_max) { if (*p_result_idx<p_result_max) {
p_result_array[*p_result_idx] = e->userdata; p_result_array[*p_result_idx] = e->userdata;
if (p_subindex_array) if (p_subindex_array)
p_subindex_array[*p_result_idx] = e->subindex; p_subindex_array[*p_result_idx] = e->subindex;
@ -1259,20 +1259,20 @@ void Octree<T,use_pairs,AL>::_cull_segment(Octant *p_octant,const Vector3& p_fro
(*p_result_idx)++; (*p_result_idx)++;
} else { } else {
return; // pointless to continue return; // pointless to continue
} }
} }
} }
} }
for (int i=0;i<8;i++) { for (int i=0;i<8;i++) {
if (p_octant->children[i] && p_octant->children[i]->aabb.intersects_segment(p_from,p_to)) { if (p_octant->children[i] && p_octant->children[i]->aabb.intersects_segment(p_from,p_to)) {
_cull_segment(p_octant->children[i],p_from,p_to, p_result_array,p_result_idx,p_result_max,p_subindex_array,p_mask); _cull_segment(p_octant->children[i],p_from,p_to, p_result_array,p_result_idx,p_result_max,p_subindex_array,p_mask);
} }
} }
} }
@ -1357,7 +1357,7 @@ int Octree<T,use_pairs,AL>::cull_convex(const Vector<Plane>& p_convex,T** p_resu
if (!root) if (!root)
return 0; return 0;
int result_count=0; int result_count=0;
pass++; pass++;
_CullConvexData cdata; _CullConvexData cdata;
@ -1367,9 +1367,9 @@ int Octree<T,use_pairs,AL>::cull_convex(const Vector<Plane>& p_convex,T** p_resu
cdata.result_max=p_result_max; cdata.result_max=p_result_max;
cdata.result_idx=&result_count; cdata.result_idx=&result_count;
cdata.mask=p_mask; cdata.mask=p_mask;
_cull_convex(root,&cdata); _cull_convex(root,&cdata);
return result_count; return result_count;
} }
@ -1381,11 +1381,11 @@ int Octree<T,use_pairs,AL>::cull_AABB(const AABB& p_aabb,T** p_result_array,int
if (!root) if (!root)
return 0; return 0;
int result_count=0; int result_count=0;
pass++; pass++;
_cull_AABB(root,p_aabb,p_result_array,&result_count,p_result_max,p_subindex_array,p_mask); _cull_AABB(root,p_aabb,p_result_array,&result_count,p_result_max,p_subindex_array,p_mask);
return result_count; return result_count;
} }
@ -1395,11 +1395,11 @@ int Octree<T,use_pairs,AL>::cull_segment(const Vector3& p_from, const Vector3& p
if (!root) if (!root)
return 0; return 0;
int result_count=0; int result_count=0;
pass++; pass++;
_cull_segment(root,p_from,p_to,p_result_array,&result_count,p_result_max,p_subindex_array,p_mask); _cull_segment(root,p_from,p_to,p_result_array,&result_count,p_result_max,p_subindex_array,p_mask);
return result_count; return result_count;
} }
@ -1436,7 +1436,7 @@ void Octree<T,use_pairs,AL>::set_unpair_callback( UnpairCallback p_callback, voi
template<class T,bool use_pairs,class AL> template<class T,bool use_pairs,class AL>
Octree<T,use_pairs,AL>::Octree(real_t p_unit_size) { Octree<T,use_pairs,AL>::Octree(real_t p_unit_size) {
last_element_id=1; last_element_id=1;
pass=1; pass=1;
unit_size=p_unit_size; unit_size=p_unit_size;

View File

@ -50,7 +50,7 @@ void Plane::normalize() {
} }
Plane Plane::normalized() const { Plane Plane::normalized() const {
Plane p = *this; Plane p = *this;
p.normalize(); p.normalize();
return p; return p;
@ -66,12 +66,12 @@ Vector3 Plane::get_any_perpendicular_normal() const {
static const Vector3 p1 = Vector3(1,0,0); static const Vector3 p1 = Vector3(1,0,0);
static const Vector3 p2 = Vector3(0,1,0); static const Vector3 p2 = Vector3(0,1,0);
Vector3 p; Vector3 p;
if (ABS(normal.dot(p1)) > 0.99) // if too similar to p1 if (ABS(normal.dot(p1)) > 0.99) // if too similar to p1
p=p2; // use p2 p=p2; // use p2
else else
p=p1; // use p1 p=p1; // use p1
p-=normal * normal.dot(p); p-=normal * normal.dot(p);
p.normalize(); p.normalize();

View File

@ -62,9 +62,9 @@ public:
bool intersects_segment(Vector3 p_begin, Vector3 p_end, Vector3* p_intersection) const; bool intersects_segment(Vector3 p_begin, Vector3 p_end, Vector3* p_intersection) const;
_FORCE_INLINE_ Vector3 project(const Vector3& p_point) const { _FORCE_INLINE_ Vector3 project(const Vector3& p_point) const {
return p_point - normal * distance_to(p_point); return p_point - normal * distance_to(p_point);
} }
/* misc */ /* misc */

View File

@ -30,9 +30,9 @@
#include "print_string.h" #include "print_string.h"
void Quat::set_euler(const Vector3& p_euler) { void Quat::set_euler(const Vector3& p_euler) {
real_t half_yaw = p_euler.x * 0.5; real_t half_yaw = p_euler.x * 0.5;
real_t half_pitch = p_euler.y * 0.5; real_t half_pitch = p_euler.y * 0.5;
real_t half_roll = p_euler.z * 0.5; real_t half_roll = p_euler.z * 0.5;
real_t cos_yaw = Math::cos(half_yaw); real_t cos_yaw = Math::cos(half_yaw);
real_t sin_yaw = Math::sin(half_yaw); real_t sin_yaw = Math::sin(half_yaw);
real_t cos_pitch = Math::cos(half_pitch); real_t cos_pitch = Math::cos(half_pitch);
@ -75,7 +75,7 @@ void Quat::normalize() {
Quat Quat::normalized() const { Quat Quat::normalized() const {
return *this / length(); return *this / length();
} }
Quat Quat::inverse() const { Quat Quat::inverse() const {
return Quat( -x, -y, -z, w ); return Quat( -x, -y, -z, w );
@ -252,7 +252,7 @@ Quat Quat::cubic_slerp(const Quat& q, const Quat& prep, const Quat& postq,const
Quat::operator String() const { Quat::operator String() const {
return String::num(x)+","+String::num(y)+","+ String::num(z)+","+ String::num(w); return String::num(x)+","+String::num(y)+","+ String::num(z)+","+ String::num(w);
} }
Quat::Quat(const Vector3& axis, const real_t& angle) { Quat::Quat(const Vector3& axis, const real_t& angle) {
@ -261,7 +261,7 @@ Quat::Quat(const Vector3& axis, const real_t& angle) {
set(0,0,0,0); set(0,0,0,0);
else { else {
real_t s = Math::sin(-angle * 0.5) / d; real_t s = Math::sin(-angle * 0.5) / d;
set(axis.x * s, axis.y * s, axis.z * s, set(axis.x * s, axis.y * s, axis.z * s,
Math::cos(-angle * 0.5)); Math::cos(-angle * 0.5));
} }
} }

View File

@ -89,18 +89,18 @@ public:
_FORCE_INLINE_ Quat operator-() const; _FORCE_INLINE_ Quat operator-() const;
_FORCE_INLINE_ Quat operator*(const real_t& s) const; _FORCE_INLINE_ Quat operator*(const real_t& s) const;
_FORCE_INLINE_ Quat operator/(const real_t& s) const; _FORCE_INLINE_ Quat operator/(const real_t& s) const;
_FORCE_INLINE_ bool operator==(const Quat& p_quat) const; _FORCE_INLINE_ bool operator==(const Quat& p_quat) const;
_FORCE_INLINE_ bool operator!=(const Quat& p_quat) const; _FORCE_INLINE_ bool operator!=(const Quat& p_quat) const;
operator String() const; operator String() const;
inline void set( real_t p_x, real_t p_y, real_t p_z, real_t p_w) { inline void set( real_t p_x, real_t p_y, real_t p_z, real_t p_w) {
x=p_x; y=p_y; z=p_z; w=p_w; x=p_x; y=p_y; z=p_z; w=p_w;
} }
inline Quat(real_t p_x, real_t p_y, real_t p_z, real_t p_w) { inline Quat(real_t p_x, real_t p_y, real_t p_z, real_t p_w) {
x=p_x; y=p_y; z=p_z; w=p_w; x=p_x; y=p_y; z=p_z; w=p_w;
} }
Quat(const Vector3& axis, const real_t& angle); Quat(const Vector3& axis, const real_t& angle);
@ -127,7 +127,7 @@ public:
} }
inline Quat() {x=y=z=0; w=1; } inline Quat() {x=y=z=0; w=1; }
}; };
@ -141,7 +141,7 @@ real_t Quat::length_squared() const {
} }
void Quat::operator+=(const Quat& q) { void Quat::operator+=(const Quat& q) {
x += q.x; y += q.y; z += q.z; w += q.w; x += q.x; y += q.y; z += q.z; w += q.w;
} }
void Quat::operator-=(const Quat& q) { void Quat::operator-=(const Quat& q) {

View File

@ -30,7 +30,7 @@
#include "math_funcs.h" #include "math_funcs.h"
#include "os/copymem.h" #include "os/copymem.h"
#include "print_string.h" #include "print_string.h"
void Transform::affine_invert() { void Transform::affine_invert() {
@ -50,7 +50,7 @@ Transform Transform::affine_inverse() const {
void Transform::invert() { void Transform::invert() {
basis.transpose(); basis.transpose();
origin = basis.xform(-origin); origin = basis.xform(-origin);
} }
Transform Transform::inverse() const { Transform Transform::inverse() const {
@ -87,30 +87,30 @@ void Transform::set_look_at( const Vector3& p_eye, const Vector3& p_target, cons
// Reference: MESA source code // Reference: MESA source code
Vector3 v_x, v_y, v_z; Vector3 v_x, v_y, v_z;
/* Make rotation matrix */ /* Make rotation matrix */
/* Z vector */ /* Z vector */
v_z = p_eye - p_target; v_z = p_eye - p_target;
v_z.normalize(); v_z.normalize();
v_y = p_up; v_y = p_up;
v_x=v_y.cross(v_z); v_x=v_y.cross(v_z);
/* Recompute Y = Z cross X */ /* Recompute Y = Z cross X */
v_y=v_z.cross(v_x); v_y=v_z.cross(v_x);
v_x.normalize(); v_x.normalize();
v_y.normalize(); v_y.normalize();
basis.set_axis(0,v_x); basis.set_axis(0,v_x);
basis.set_axis(1,v_y); basis.set_axis(1,v_y);
basis.set_axis(2,v_z); basis.set_axis(2,v_z);
origin=p_eye; origin=p_eye;
} }
Transform Transform::interpolate_with(const Transform& p_transform, float p_c) const { Transform Transform::interpolate_with(const Transform& p_transform, float p_c) const {
@ -193,7 +193,7 @@ bool Transform::operator!=(const Transform& p_transform) const {
void Transform::operator*=(const Transform& p_transform) { void Transform::operator*=(const Transform& p_transform) {
origin=xform(p_transform.origin); origin=xform(p_transform.origin);
basis*=p_transform.basis; basis*=p_transform.basis;
} }
Transform Transform::operator*(const Transform& p_transform) const { Transform Transform::operator*(const Transform& p_transform) const {

View File

@ -40,9 +40,9 @@ public:
Matrix3 basis; Matrix3 basis;
Vector3 origin; Vector3 origin;
void invert(); void invert();
Transform inverse() const; Transform inverse() const;
void affine_invert(); void affine_invert();
Transform affine_inverse() const; Transform affine_inverse() const;
@ -76,27 +76,27 @@ public:
_FORCE_INLINE_ Vector3 xform(const Vector3& p_vector) const; _FORCE_INLINE_ Vector3 xform(const Vector3& p_vector) const;
_FORCE_INLINE_ Vector3 xform_inv(const Vector3& p_vector) const; _FORCE_INLINE_ Vector3 xform_inv(const Vector3& p_vector) const;
_FORCE_INLINE_ Plane xform(const Plane& p_plane) const; _FORCE_INLINE_ Plane xform(const Plane& p_plane) const;
_FORCE_INLINE_ Plane xform_inv(const Plane& p_plane) const; _FORCE_INLINE_ Plane xform_inv(const Plane& p_plane) const;
_FORCE_INLINE_ AABB xform(const AABB& p_aabb) const; _FORCE_INLINE_ AABB xform(const AABB& p_aabb) const;
_FORCE_INLINE_ AABB xform_inv(const AABB& p_aabb) const; _FORCE_INLINE_ AABB xform_inv(const AABB& p_aabb) const;
void operator*=(const Transform& p_transform); void operator*=(const Transform& p_transform);
Transform operator*(const Transform& p_transform) const; Transform operator*(const Transform& p_transform) const;
Transform interpolate_with(const Transform& p_transform, float p_c) const; Transform interpolate_with(const Transform& p_transform, float p_c) const;
_FORCE_INLINE_ Transform inverse_xform(const Transform& t) const { _FORCE_INLINE_ Transform inverse_xform(const Transform& t) const {
Vector3 v = t.origin - origin; Vector3 v = t.origin - origin;
return Transform(basis.transpose_xform(t.basis), return Transform(basis.transpose_xform(t.basis),
basis.xform(v)); basis.xform(v));
} }
void set(real_t xx, real_t xy, real_t xz, real_t yx, real_t yy, real_t yz, real_t zx, real_t zy, real_t zz,real_t tx, real_t ty, real_t tz) { void set(real_t xx, real_t xy, real_t xz, real_t yx, real_t yy, real_t yz, real_t zx, real_t zy, real_t zz,real_t tx, real_t ty, real_t tz) {
basis.elements[0][0]=xx; basis.elements[0][0]=xx;
basis.elements[0][1]=xy; basis.elements[0][1]=xy;
basis.elements[0][2]=xz; basis.elements[0][2]=xz;
@ -105,14 +105,14 @@ public:
basis.elements[1][2]=yz; basis.elements[1][2]=yz;
basis.elements[2][0]=zx; basis.elements[2][0]=zx;
basis.elements[2][1]=zy; basis.elements[2][1]=zy;
basis.elements[2][2]=zz; basis.elements[2][2]=zz;
origin.x=tx; origin.x=tx;
origin.y=ty; origin.y=ty;
origin.z=tz; origin.z=tz;
} }
operator String() const; operator String() const;
Transform(const Matrix3& p_basis, const Vector3& p_origin=Vector3()); Transform(const Matrix3& p_basis, const Vector3& p_origin=Vector3());
Transform() {} Transform() {}
@ -128,9 +128,9 @@ _FORCE_INLINE_ Vector3 Transform::xform(const Vector3& p_vector) const {
); );
} }
_FORCE_INLINE_ Vector3 Transform::xform_inv(const Vector3& p_vector) const { _FORCE_INLINE_ Vector3 Transform::xform_inv(const Vector3& p_vector) const {
Vector3 v = p_vector - origin; Vector3 v = p_vector - origin;
return Vector3( return Vector3(
(basis.elements[0][0]*v.x ) + ( basis.elements[1][0]*v.y ) + ( basis.elements[2][0]*v.z ), (basis.elements[0][0]*v.x ) + ( basis.elements[1][0]*v.y ) + ( basis.elements[2][0]*v.z ),
(basis.elements[0][1]*v.x ) + ( basis.elements[1][1]*v.y ) + ( basis.elements[2][1]*v.z ), (basis.elements[0][1]*v.x ) + ( basis.elements[1][1]*v.y ) + ( basis.elements[2][1]*v.z ),
@ -140,16 +140,16 @@ _FORCE_INLINE_ Vector3 Transform::xform_inv(const Vector3& p_vector) const {
_FORCE_INLINE_ Plane Transform::xform(const Plane& p_plane) const { _FORCE_INLINE_ Plane Transform::xform(const Plane& p_plane) const {
Vector3 point=p_plane.normal*p_plane.d; Vector3 point=p_plane.normal*p_plane.d;
Vector3 point_dir=point+p_plane.normal; Vector3 point_dir=point+p_plane.normal;
point=xform(point); point=xform(point);
point_dir=xform(point_dir); point_dir=xform(point_dir);
Vector3 normal=point_dir-point; Vector3 normal=point_dir-point;
normal.normalize(); normal.normalize();
real_t d=normal.dot(point); real_t d=normal.dot(point);
return Plane(normal,d); return Plane(normal,d);
} }
@ -159,11 +159,11 @@ _FORCE_INLINE_ Plane Transform::xform_inv(const Plane& p_plane) const {
Vector3 point_dir=point+p_plane.normal; Vector3 point_dir=point+p_plane.normal;
xform_inv(point); xform_inv(point);
xform_inv(point_dir); xform_inv(point_dir);
Vector3 normal=point_dir-point; Vector3 normal=point_dir-point;
normal.normalize(); normal.normalize();
real_t d=normal.dot(point); real_t d=normal.dot(point);
return Plane(normal,d); return Plane(normal,d);
} }
@ -199,17 +199,17 @@ _FORCE_INLINE_ AABB Transform::xform(const AABB& p_aabb) const {
Vector3(p_aabb.pos.x, p_aabb.pos.y, p_aabb.pos.z+p_aabb.size.z), Vector3(p_aabb.pos.x, p_aabb.pos.y, p_aabb.pos.z+p_aabb.size.z),
Vector3(p_aabb.pos.x, p_aabb.pos.y, p_aabb.pos.z) Vector3(p_aabb.pos.x, p_aabb.pos.y, p_aabb.pos.z)
}; };
AABB ret; AABB ret;
ret.pos=xform(vertices[0]); ret.pos=xform(vertices[0]);
for (int i=1;i<8;i++) { for (int i=1;i<8;i++) {
ret.expand_to( xform(vertices[i]) ); ret.expand_to( xform(vertices[i]) );
} }
return ret; return ret;
#endif #endif
@ -227,17 +227,17 @@ _FORCE_INLINE_ AABB Transform::xform_inv(const AABB& p_aabb) const {
Vector3(p_aabb.pos.x, p_aabb.pos.y, p_aabb.pos.z+p_aabb.size.z), Vector3(p_aabb.pos.x, p_aabb.pos.y, p_aabb.pos.z+p_aabb.size.z),
Vector3(p_aabb.pos.x, p_aabb.pos.y, p_aabb.pos.z) Vector3(p_aabb.pos.x, p_aabb.pos.y, p_aabb.pos.z)
}; };
AABB ret; AABB ret;
ret.pos=xform_inv(vertices[0]); ret.pos=xform_inv(vertices[0]);
for (int i=1;i<8;i++) { for (int i=1;i<8;i++) {
ret.expand_to( xform_inv(vertices[i]) ); ret.expand_to( xform_inv(vertices[i]) );
} }
return ret; return ret;
} }

View File

@ -320,7 +320,7 @@ void MessageQueue::_call_function(Object* p_target, const StringName& p_func, co
void MessageQueue::flush() { void MessageQueue::flush() {
if (buffer_max_used<buffer_end); { if (buffer_end > buffer_max_used) {
buffer_max_used=buffer_end; buffer_max_used=buffer_end;
//statistics(); //statistics();
} }

View File

@ -58,8 +58,8 @@ template<class T>
struct VariantCaster { struct VariantCaster {
static _FORCE_INLINE_ T cast(const Variant& p_variant) { static _FORCE_INLINE_ T cast(const Variant& p_variant) {
return p_variant; return p_variant;
} }
}; };
@ -67,8 +67,8 @@ template<class T>
struct VariantCaster<T&> { struct VariantCaster<T&> {
static _FORCE_INLINE_ T cast(const Variant& p_variant) { static _FORCE_INLINE_ T cast(const Variant& p_variant) {
return p_variant; return p_variant;
} }
}; };
@ -76,8 +76,8 @@ template<class T>
struct VariantCaster<const T&> { struct VariantCaster<const T&> {
static _FORCE_INLINE_ T cast(const Variant& p_variant) { static _FORCE_INLINE_ T cast(const Variant& p_variant) {
return p_variant; return p_variant;
} }
}; };

View File

@ -255,7 +255,7 @@ Object::Connection::Connection(const Variant& p_variant) {
bool Object::_predelete() { bool Object::_predelete() {
_predelete_ok=1; _predelete_ok=1;
notification(NOTIFICATION_PREDELETE,true); notification(NOTIFICATION_PREDELETE,true);
if (_predelete_ok) { if (_predelete_ok) {
@ -269,16 +269,16 @@ void Object::_postinitialize() {
_type_ptr=_get_type_namev(); _type_ptr=_get_type_namev();
_initialize_typev(); _initialize_typev();
notification(NOTIFICATION_POSTINITIALIZE); notification(NOTIFICATION_POSTINITIALIZE);
} }
void Object::get_valid_parents_static(List<String> *p_parents) { void Object::get_valid_parents_static(List<String> *p_parents) {
} }
void Object::_get_valid_parents_static(List<String> *p_parents) { void Object::_get_valid_parents_static(List<String> *p_parents) {
} }
#if 0 #if 0
//old style set, deprecated //old style set, deprecated
@ -286,7 +286,7 @@ void Object::_get_valid_parents_static(List<String> *p_parents) {
void Object::set(const String& p_name, const Variant& p_value) { void Object::set(const String& p_name, const Variant& p_value) {
_setv(p_name,p_value); _setv(p_name,p_value);
//if (!_use_builtin_script()) //if (!_use_builtin_script())
// return; // return;
@ -303,8 +303,8 @@ void Object::set(const String& p_name, const Variant& p_value) {
} else if (script_instance) { } else if (script_instance) {
script_instance->set(p_name,p_value); script_instance->set(p_name,p_value);
} }
} }
#endif #endif
@ -348,7 +348,7 @@ void Object::set(const StringName& p_name, const Variant& p_value, bool *r_valid
*r_valid=true; *r_valid=true;
return; return;
} else { } else {
//something inside the object... :| //something inside the object... :|
bool success = _setv(p_name,p_value); bool success = _setv(p_name,p_value);
if (success) { if (success) {
if (r_valid) if (r_valid)
@ -420,7 +420,7 @@ Variant Object::get(const String& p_name) const {
Variant ret=_getv(p_name); Variant ret=_getv(p_name);
if (ret.get_type()!=Variant::NIL) if (ret.get_type()!=Variant::NIL)
return ret; return ret;
bool success; bool success;
ObjectTypeDB::get_property(const_cast<Object*>(this),p_name,ret,success); ObjectTypeDB::get_property(const_cast<Object*>(this),p_name,ret,success);
if (success) { if (success) {
@ -431,11 +431,11 @@ Variant Object::get(const String& p_name) const {
return metadata; return metadata;
else if (p_name=="script/script") else if (p_name=="script/script")
return script; return script;
if (script_instance) { if (script_instance) {
return script_instance->get(p_name); return script_instance->get(p_name);
} }
return Variant(); return Variant();
} }
@ -449,10 +449,10 @@ void Object::get_property_list(List<PropertyInfo> *p_list,bool p_reversed) const
} }
_get_property_listv(p_list,p_reversed); _get_property_listv(p_list,p_reversed);
if (!_use_builtin_script()) if (!_use_builtin_script())
return; return;
if (!is_type("Script")) // can still be set, but this is for userfriendlyness if (!is_type("Script")) // can still be set, but this is for userfriendlyness
p_list->push_back( PropertyInfo( Variant::OBJECT, "script/script", PROPERTY_HINT_RESOURCE_TYPE, "Script",PROPERTY_USAGE_DEFAULT|PROPERTY_USAGE_STORE_IF_NONZERO)); p_list->push_back( PropertyInfo( Variant::OBJECT, "script/script", PROPERTY_HINT_RESOURCE_TYPE, "Script",PROPERTY_USAGE_DEFAULT|PROPERTY_USAGE_STORE_IF_NONZERO));
if (!metadata.empty()) if (!metadata.empty())
@ -460,15 +460,15 @@ void Object::get_property_list(List<PropertyInfo> *p_list,bool p_reversed) const
if (script_instance && !p_reversed) { if (script_instance && !p_reversed) {
p_list->push_back( PropertyInfo(Variant::NIL,"Script Variables",PROPERTY_HINT_NONE,String(),PROPERTY_USAGE_CATEGORY)); p_list->push_back( PropertyInfo(Variant::NIL,"Script Variables",PROPERTY_HINT_NONE,String(),PROPERTY_USAGE_CATEGORY));
script_instance->get_property_list(p_list); script_instance->get_property_list(p_list);
} }
} }
void Object::get_method_list(List<MethodInfo> *p_list) const { void Object::get_method_list(List<MethodInfo> *p_list) const {
ObjectTypeDB::get_method_list(get_type_name(),p_list); ObjectTypeDB::get_method_list(get_type_name(),p_list);
if (script_instance) { if (script_instance) {
script_instance->get_method_list(p_list); script_instance->get_method_list(p_list);
} }
} }
@ -898,22 +898,22 @@ Variant Object::call(const StringName& p_method,const Variant** p_args,int p_arg
void Object::notification(int p_notification,bool p_reversed) { void Object::notification(int p_notification,bool p_reversed) {
_notificationv(p_notification,p_reversed); _notificationv(p_notification,p_reversed);
if (script_instance) { if (script_instance) {
script_instance->notification(p_notification); script_instance->notification(p_notification);
} }
} }
void Object::_changed_callback(Object *p_changed,const char *p_prop) { void Object::_changed_callback(Object *p_changed,const char *p_prop) {
} }
void Object::add_change_receptor( Object *p_receptor ) { void Object::add_change_receptor( Object *p_receptor ) {
change_receptors.insert(p_receptor); change_receptors.insert(p_receptor);
} }
@ -941,8 +941,8 @@ void Object::set_script(const RefPtr& p_script) {
memdelete(script_instance); memdelete(script_instance);
script_instance=NULL; script_instance=NULL;
} }
script=p_script; script=p_script;
Ref<Script> s(script); Ref<Script> s(script);
if (!s.is_null() && s->can_instance() ) { if (!s.is_null() && s->can_instance() ) {
@ -1760,7 +1760,7 @@ bool Object::is_edited() const {
#endif #endif
Object::Object() { Object::Object() {
_type_ptr=NULL; _type_ptr=NULL;
_block_signals=false; _block_signals=false;
_predelete_ok=0; _predelete_ok=0;
@ -1831,12 +1831,12 @@ Object::~Object() {
bool predelete_handler(Object *p_object) { bool predelete_handler(Object *p_object) {
return p_object->_predelete(); return p_object->_predelete();
} }
void postinitialize_handler(Object *p_object) { void postinitialize_handler(Object *p_object) {
p_object->_postinitialize(); p_object->_postinitialize();
} }
@ -1900,8 +1900,8 @@ void ObjectDB::cleanup() {
GLOBAL_LOCK_FUNCTION; GLOBAL_LOCK_FUNCTION;
if (instances.size()) { if (instances.size()) {
WARN_PRINT("ObjectDB Instances still exist!"); WARN_PRINT("ObjectDB Instances still exist!");
if (OS::get_singleton()->is_stdout_verbose()) { if (OS::get_singleton()->is_stdout_verbose()) {
const uint32_t *K=NULL; const uint32_t *K=NULL;
while((K=instances.next(K))) { while((K=instances.next(K))) {

View File

@ -200,37 +200,37 @@ ObjectTypeDB::TypeInfo::TypeInfo() {
disabled=false; disabled=false;
} }
ObjectTypeDB::TypeInfo::~TypeInfo() { ObjectTypeDB::TypeInfo::~TypeInfo() {
} }
bool ObjectTypeDB::is_type(const StringName &p_type,const StringName& p_inherits) { bool ObjectTypeDB::is_type(const StringName &p_type,const StringName& p_inherits) {
OBJTYPE_LOCK; OBJTYPE_LOCK;
StringName inherits=p_type; StringName inherits=p_type;
while (inherits.operator String().length()) { while (inherits.operator String().length()) {
if (inherits==p_inherits) if (inherits==p_inherits)
return true; return true;
inherits=type_inherits_from(inherits); inherits=type_inherits_from(inherits);
} }
return false; return false;
} }
void ObjectTypeDB::get_type_list( List<StringName> *p_types) { void ObjectTypeDB::get_type_list( List<StringName> *p_types) {
OBJTYPE_LOCK; OBJTYPE_LOCK;
const StringName *k=NULL; const StringName *k=NULL;
while((k=types.next(k))) { while((k=types.next(k))) {
p_types->push_back(*k); p_types->push_back(*k);
} }
p_types->sort(); p_types->sort();
} }
@ -238,11 +238,11 @@ void ObjectTypeDB::get_type_list( List<StringName> *p_types) {
void ObjectTypeDB::get_inheriters_from( const StringName& p_type,List<StringName> *p_types) { void ObjectTypeDB::get_inheriters_from( const StringName& p_type,List<StringName> *p_types) {
OBJTYPE_LOCK; OBJTYPE_LOCK;
const StringName *k=NULL; const StringName *k=NULL;
while((k=types.next(k))) { while((k=types.next(k))) {
if (*k!=p_type && is_type(*k,p_type)) if (*k!=p_type && is_type(*k,p_type))
p_types->push_back(*k); p_types->push_back(*k);
} }
@ -250,18 +250,18 @@ void ObjectTypeDB::get_inheriters_from( const StringName& p_type,List<StringName
} }
StringName ObjectTypeDB::type_inherits_from(const StringName& p_type) { StringName ObjectTypeDB::type_inherits_from(const StringName& p_type) {
OBJTYPE_LOCK; OBJTYPE_LOCK;
TypeInfo *ti = types.getptr(p_type); TypeInfo *ti = types.getptr(p_type);
ERR_FAIL_COND_V(!ti,""); ERR_FAIL_COND_V(!ti,"");
return ti->inherits; return ti->inherits;
} }
bool ObjectTypeDB::type_exists(const StringName &p_type) { bool ObjectTypeDB::type_exists(const StringName &p_type) {
OBJTYPE_LOCK; OBJTYPE_LOCK;
return types.has(p_type); return types.has(p_type);
} }
void ObjectTypeDB::add_compatibility_type(const StringName& p_type,const StringName& p_fallback) { void ObjectTypeDB::add_compatibility_type(const StringName& p_type,const StringName& p_fallback) {
@ -270,7 +270,7 @@ void ObjectTypeDB::add_compatibility_type(const StringName& p_type,const StringN
} }
Object *ObjectTypeDB::instance(const StringName &p_type) { Object *ObjectTypeDB::instance(const StringName &p_type) {
TypeInfo *ti; TypeInfo *ti;
{ {
OBJTYPE_LOCK; OBJTYPE_LOCK;
@ -288,9 +288,9 @@ Object *ObjectTypeDB::instance(const StringName &p_type) {
return ti->creation_func(); return ti->creation_func();
} }
bool ObjectTypeDB::can_instance(const StringName &p_type) { bool ObjectTypeDB::can_instance(const StringName &p_type) {
OBJTYPE_LOCK; OBJTYPE_LOCK;
TypeInfo *ti = types.getptr(p_type); TypeInfo *ti = types.getptr(p_type);
ERR_FAIL_COND_V(!ti,false); ERR_FAIL_COND_V(!ti,false);
return (!ti->disabled && ti->creation_func!=NULL); return (!ti->disabled && ti->creation_func!=NULL);
@ -326,11 +326,11 @@ void ObjectTypeDB::get_method_list(StringName p_type,List<MethodInfo> *p_methods
OBJTYPE_LOCK; OBJTYPE_LOCK;
TypeInfo *type=types.getptr(p_type); TypeInfo *type=types.getptr(p_type);
while(type) { while(type) {
if (type->disabled) { if (type->disabled) {
if (p_no_inheritance) if (p_no_inheritance)
@ -348,14 +348,14 @@ void ObjectTypeDB::get_method_list(StringName p_type,List<MethodInfo> *p_methods
} }
for( List<StringName>::Element *E=type->method_order.front();E;E=E->next()) { for( List<StringName>::Element *E=type->method_order.front();E;E=E->next()) {
MethodBind *method=type->method_map.get(E->get()); MethodBind *method=type->method_map.get(E->get());
MethodInfo minfo; MethodInfo minfo;
minfo.name=E->get(); minfo.name=E->get();
minfo.id=method->get_method_id(); minfo.id=method->get_method_id();
for (int i=0;i<method->get_argument_count();i++) { for (int i=0;i<method->get_argument_count();i++) {
//Variant::Type t=method->get_argument_type(i); //Variant::Type t=method->get_argument_type(i);
minfo.arguments.push_back(method->get_argument_info(i)); minfo.arguments.push_back(method->get_argument_info(i));
@ -386,24 +386,24 @@ void ObjectTypeDB::get_method_list(StringName p_type,List<MethodInfo> *p_methods
#endif #endif
if (p_no_inheritance) if (p_no_inheritance)
break; break;
type=type->inherits_ptr; type=type->inherits_ptr;
} }
} }
MethodBind *ObjectTypeDB::get_method(StringName p_type, StringName p_name) { MethodBind *ObjectTypeDB::get_method(StringName p_type, StringName p_name) {
OBJTYPE_LOCK; OBJTYPE_LOCK;
TypeInfo *type=types.getptr(p_type); TypeInfo *type=types.getptr(p_type);
while(type) { while(type) {
MethodBind **method=type->method_map.getptr(p_name); MethodBind **method=type->method_map.getptr(p_name);
if (method && *method) if (method && *method)
return *method; return *method;
@ -416,18 +416,18 @@ MethodBind *ObjectTypeDB::get_method(StringName p_type, StringName p_name) {
void ObjectTypeDB::bind_integer_constant(const StringName& p_type, const StringName &p_name, int p_constant) { void ObjectTypeDB::bind_integer_constant(const StringName& p_type, const StringName &p_name, int p_constant) {
OBJTYPE_LOCK; OBJTYPE_LOCK;
TypeInfo *type=types.getptr(p_type); TypeInfo *type=types.getptr(p_type);
if (!type) { if (!type) {
ERR_FAIL_COND(!type); ERR_FAIL_COND(!type);
} }
if (type->constant_map.has(p_name)) { if (type->constant_map.has(p_name)) {
ERR_FAIL(); ERR_FAIL();
} }
type->constant_map[p_name]=p_constant; type->constant_map[p_name]=p_constant;
#ifdef DEBUG_METHODS_ENABLED #ifdef DEBUG_METHODS_ENABLED
type->constant_order.push_back(p_name); type->constant_order.push_back(p_name);
@ -438,11 +438,11 @@ void ObjectTypeDB::bind_integer_constant(const StringName& p_type, const StringN
void ObjectTypeDB::get_integer_constant_list(const StringName& p_type, List<String> *p_constants, bool p_no_inheritance) { void ObjectTypeDB::get_integer_constant_list(const StringName& p_type, List<String> *p_constants, bool p_no_inheritance) {
OBJTYPE_LOCK; OBJTYPE_LOCK;
TypeInfo *type=types.getptr(p_type); TypeInfo *type=types.getptr(p_type);
while(type) { while(type) {
#ifdef DEBUG_METHODS_ENABLED #ifdef DEBUG_METHODS_ENABLED
for(List<StringName>::Element *E=type->constant_order.front();E;E=E->next()) for(List<StringName>::Element *E=type->constant_order.front();E;E=E->next())
p_constants->push_back(E->get()); p_constants->push_back(E->get());
@ -456,7 +456,7 @@ void ObjectTypeDB::get_integer_constant_list(const StringName& p_type, List<Stri
#endif #endif
if (p_no_inheritance) if (p_no_inheritance)
break; break;
type=type->inherits_ptr; type=type->inherits_ptr;
} }
@ -466,28 +466,28 @@ void ObjectTypeDB::get_integer_constant_list(const StringName& p_type, List<Stri
int ObjectTypeDB::get_integer_constant(const StringName& p_type, const StringName &p_name, bool *p_success) { int ObjectTypeDB::get_integer_constant(const StringName& p_type, const StringName &p_name, bool *p_success) {
OBJTYPE_LOCK; OBJTYPE_LOCK;
TypeInfo *type=types.getptr(p_type); TypeInfo *type=types.getptr(p_type);
while(type) { while(type) {
int *constant=type->constant_map.getptr(p_name); int *constant=type->constant_map.getptr(p_name);
if (constant) { if (constant) {
if (p_success) if (p_success)
*p_success=true; *p_success=true;
return *constant; return *constant;
} }
type=type->inherits_ptr; type=type->inherits_ptr;
} }
if (p_success)
*p_success=false;
return 0; if (p_success)
*p_success=false;
return 0;
} }
void ObjectTypeDB::add_signal(StringName p_type,const MethodInfo& p_signal) { void ObjectTypeDB::add_signal(StringName p_type,const MethodInfo& p_signal) {
@ -966,7 +966,7 @@ void ObjectTypeDB::init() {
} }
void ObjectTypeDB::cleanup() { void ObjectTypeDB::cleanup() {
#ifndef NO_THREADS #ifndef NO_THREADS
@ -974,19 +974,19 @@ void ObjectTypeDB::cleanup() {
#endif #endif
//OBJTYPE_LOCK; hah not here //OBJTYPE_LOCK; hah not here
const StringName *k=NULL; const StringName *k=NULL;
while((k=types.next(k))) { while((k=types.next(k))) {
TypeInfo &ti=types[*k]; TypeInfo &ti=types[*k];
const StringName *m=NULL; const StringName *m=NULL;
while((m=ti.method_map.next(m))) { while((m=ti.method_map.next(m))) {
memdelete( ti.method_map[*m] ); memdelete( ti.method_map[*m] );
} }
} }
types.clear(); types.clear();
resource_base_extensions.clear(); resource_base_extensions.clear();
compat_types.clear(); compat_types.clear();

View File

@ -42,9 +42,9 @@ struct ParamHint {
PropertyHint hint; PropertyHint hint;
String hint_text; String hint_text;
Variant default_val; Variant default_val;
ParamHint(const String& p_name="", PropertyHint p_hint=PROPERTY_HINT_NONE, const String& p_hint_text="",Variant p_default_val=Variant()) { ParamHint(const String& p_name="", PropertyHint p_hint=PROPERTY_HINT_NONE, const String& p_hint_text="",Variant p_default_val=Variant()) {
name=p_name; name=p_name;
hint=p_hint; hint=p_hint;
hint_text=p_hint_text; hint_text=p_hint_text;
@ -73,9 +73,9 @@ struct MethodDefinition {
StringName name; StringName name;
Vector<StringName> args; Vector<StringName> args;
MethodDefinition() {} MethodDefinition() {}
MethodDefinition(const char *p_name) { name=p_name; } MethodDefinition(const char *p_name) { name=p_name; }
MethodDefinition(const StringName& p_name) { name=p_name; } MethodDefinition(const StringName& p_name) { name=p_name; }
}; };
@ -109,7 +109,7 @@ static _FORCE_INLINE_ const char* _MD(const char* m_name, ...) { return m_name;
#endif #endif
class ObjectTypeDB { class ObjectTypeDB {
struct PropertySetGet { struct PropertySetGet {
int index; int index;
@ -121,7 +121,7 @@ class ObjectTypeDB {
}; };
struct TypeInfo { struct TypeInfo {
TypeInfo *inherits_ptr; TypeInfo *inherits_ptr;
HashMap<StringName,MethodBind*,StringNameHasher> method_map; HashMap<StringName,MethodBind*,StringNameHasher> method_map;
HashMap<StringName,int,StringNameHasher> constant_map; HashMap<StringName,int,StringNameHasher> constant_map;
@ -143,12 +143,12 @@ class ObjectTypeDB {
TypeInfo(); TypeInfo();
~TypeInfo(); ~TypeInfo();
}; };
template<class T> template<class T>
static Object *creator() { static Object *creator() {
return memnew( T ); return memnew( T );
} }
static Mutex *lock; static Mutex *lock;
static HashMap<StringName,TypeInfo,StringNameHasher> types; static HashMap<StringName,TypeInfo,StringNameHasher> types;
static HashMap<StringName,StringName,StringNameHasher> resource_base_extensions; static HashMap<StringName,StringName,StringNameHasher> resource_base_extensions;
@ -163,8 +163,8 @@ class ObjectTypeDB {
static void _add_type2(const StringName& p_type, const StringName& p_inherits); static void _add_type2(const StringName& p_type, const StringName& p_inherits);
public: public:
// DO NOT USE THIS!!!!!! NEEDS TO BE PUBLIC BUT DO NOT USE NO MATTER WHAT!!! // DO NOT USE THIS!!!!!! NEEDS TO BE PUBLIC BUT DO NOT USE NO MATTER WHAT!!!
template<class T> template<class T>
static void _add_type() { static void _add_type() {
@ -195,7 +195,7 @@ public:
template<class T> template<class T>
static void register_type() { static void register_type() {
GLOBAL_LOCK_FUNCTION; GLOBAL_LOCK_FUNCTION;
T::initialize_type(); T::initialize_type();
TypeInfo *t=types.getptr(T::get_type_static()); TypeInfo *t=types.getptr(T::get_type_static());
@ -206,7 +206,7 @@ public:
template<class T> template<class T>
static void register_virtual_type() { static void register_virtual_type() {
GLOBAL_LOCK_FUNCTION; GLOBAL_LOCK_FUNCTION;
T::initialize_type(); T::initialize_type();
//nothing //nothing
@ -247,9 +247,9 @@ public:
ParamDef d4=ParamDef(), ParamDef d4=ParamDef(),
ParamDef d5=ParamDef() ParamDef d5=ParamDef()
) { ) {
return bind_methodf(METHOD_FLAGS_DEFAULT,p_method_name, p_method, d1,d2,d3,d4,d5); return bind_methodf(METHOD_FLAGS_DEFAULT,p_method_name, p_method, d1,d2,d3,d4,d5);
} }
@ -472,7 +472,7 @@ public:
static void add_virtual_method(const StringName& p_type,const MethodInfo& p_method,bool p_virtual=true ); static void add_virtual_method(const StringName& p_type,const MethodInfo& p_method,bool p_virtual=true );
static void get_virtual_methods(const StringName& p_type,List<MethodInfo> * p_methods,bool p_no_inheritance=false ); static void get_virtual_methods(const StringName& p_type,List<MethodInfo> * p_methods,bool p_no_inheritance=false );
static void bind_integer_constant(const StringName& p_type, const StringName &p_name, int p_constant); static void bind_integer_constant(const StringName& p_type, const StringName &p_name, int p_constant);
static void get_integer_constant_list(const StringName& p_type, List<String> *p_constants, bool p_no_inheritance=false); static void get_integer_constant_list(const StringName& p_type, List<String> *p_constants, bool p_no_inheritance=false);
static int get_integer_constant(const StringName& p_type, const StringName &p_name, bool *p_success=NULL); static int get_integer_constant(const StringName& p_type, const StringName &p_name, bool *p_success=NULL);

View File

@ -32,7 +32,7 @@
void movemem_system(void *to, void *from,int amount) { void movemem_system(void *to, void *from,int amount) {
memmove(to,from,amount); memmove(to,from,amount);
} }

View File

@ -344,7 +344,7 @@ DirAccess *DirAccess::open(const String& p_path,Error *r_error) {
} }
DirAccess *DirAccess::create(AccessType p_access) { DirAccess *DirAccess::create(AccessType p_access) {
DirAccess * da = create_func[p_access]?create_func[p_access]():NULL; DirAccess * da = create_func[p_access]?create_func[p_access]():NULL;
if (da) { if (da) {
da->_access_type=p_access; da->_access_type=p_access;
@ -359,7 +359,7 @@ String DirAccess::get_full_path(const String& p_path,AccessType p_access) {
DirAccess *d=DirAccess::create(p_access); DirAccess *d=DirAccess::create(p_access);
if (!d) if (!d)
return p_path; return p_path;
d->change_dir(p_path); d->change_dir(p_path);
String full=d->get_current_dir(); String full=d->get_current_dir();
memdelete(d); memdelete(d);
@ -367,31 +367,31 @@ String DirAccess::get_full_path(const String& p_path,AccessType p_access) {
} }
Error DirAccess::copy(String p_from,String p_to) { Error DirAccess::copy(String p_from,String p_to) {
//printf("copy %s -> %s\n",p_from.ascii().get_data(),p_to.ascii().get_data()); //printf("copy %s -> %s\n",p_from.ascii().get_data(),p_to.ascii().get_data());
Error err; Error err;
FileAccess *fsrc = FileAccess::open(p_from, FileAccess::READ,&err); FileAccess *fsrc = FileAccess::open(p_from, FileAccess::READ,&err);
if (err) { if (err) {
ERR_FAIL_COND_V( err, err ); ERR_FAIL_COND_V( err, err );
} }
FileAccess *fdst = FileAccess::open(p_to, FileAccess::WRITE,&err ); FileAccess *fdst = FileAccess::open(p_to, FileAccess::WRITE,&err );
if (err) { if (err) {
fsrc->close(); fsrc->close();
memdelete( fsrc ); memdelete( fsrc );
ERR_FAIL_COND_V( err, err ); ERR_FAIL_COND_V( err, err );
} }
fsrc->seek_end(0); fsrc->seek_end(0);
int size = fsrc->get_pos(); int size = fsrc->get_pos();
fsrc->seek(0); fsrc->seek(0);
err = OK; err = OK;
while(size--) { while(size--) {
if (fsrc->get_error()!=OK) { if (fsrc->get_error()!=OK) {
err= fsrc->get_error(); err= fsrc->get_error();
break; break;
@ -400,13 +400,13 @@ Error DirAccess::copy(String p_from,String p_to) {
err= fdst->get_error(); err= fdst->get_error();
break; break;
} }
fdst->store_8( fsrc->get_8() ); fdst->store_8( fsrc->get_8() );
} }
memdelete(fsrc); memdelete(fsrc);
memdelete(fdst); memdelete(fdst);
return err; return err;
} }

View File

@ -79,13 +79,13 @@ public:
virtual String get_next()=0; virtual String get_next()=0;
virtual bool current_is_dir() const=0; virtual bool current_is_dir() const=0;
virtual bool current_is_hidden() const=0; virtual bool current_is_hidden() const=0;
virtual void list_dir_end()=0; ///< virtual void list_dir_end()=0; ///<
virtual int get_drive_count()=0; virtual int get_drive_count()=0;
virtual String get_drive(int p_drive)=0; virtual String get_drive(int p_drive)=0;
virtual int get_current_drive(); virtual int get_current_drive();
virtual Error change_dir(String p_dir)=0; ///< can be relative or absolute, return false on success virtual Error change_dir(String p_dir)=0; ///< can be relative or absolute, return false on success
virtual String get_current_dir()=0; ///< return current dir location virtual String get_current_dir()=0; ///< return current dir location
virtual Error make_dir(String p_dir)=0; virtual Error make_dir(String p_dir)=0;
@ -100,7 +100,7 @@ public:
virtual Error copy(String p_from,String p_to); virtual Error copy(String p_from,String p_to);
virtual Error rename(String p_from, String p_to)=0; virtual Error rename(String p_from, String p_to)=0;
virtual Error remove(String p_name)=0; virtual Error remove(String p_name)=0;
static String get_full_path(const String& p_path,AccessType p_access); static String get_full_path(const String& p_path,AccessType p_access);
static DirAccess *create_for_path(const String& p_path); static DirAccess *create_for_path(const String& p_path);
@ -111,7 +111,7 @@ public:
FILE_TYPE_FILE, FILE_TYPE_FILE,
FILE_TYPE_DIR, FILE_TYPE_DIR,
}; };
//virtual DirType get_file_type() const=0; //virtual DirType get_file_type() const=0;
*/ */
static DirAccess *create(AccessType p_access); static DirAccess *create(AccessType p_access);

View File

@ -169,69 +169,69 @@ String FileAccess::fix_path(const String& p_path) const {
return r_path; return r_path;
} break; } break;
} }
return r_path; return r_path;
} }
/* these are all implemented for ease of porting, then can later be optimized */ /* these are all implemented for ease of porting, then can later be optimized */
uint16_t FileAccess::get_16()const { uint16_t FileAccess::get_16()const {
uint16_t res; uint16_t res;
uint8_t a,b; uint8_t a,b;
a=get_8(); a=get_8();
b=get_8(); b=get_8();
if (endian_swap) { if (endian_swap) {
SWAP( a,b ); SWAP( a,b );
} }
res=b; res=b;
res<<=8; res<<=8;
res|=a; res|=a;
return res; return res;
} }
uint32_t FileAccess::get_32() const{ uint32_t FileAccess::get_32() const{
uint32_t res; uint32_t res;
uint16_t a,b; uint16_t a,b;
a=get_16(); a=get_16();
b=get_16(); b=get_16();
if (endian_swap) { if (endian_swap) {
SWAP( a,b ); SWAP( a,b );
} }
res=b; res=b;
res<<=16; res<<=16;
res|=a; res|=a;
return res; return res;
} }
uint64_t FileAccess::get_64()const { uint64_t FileAccess::get_64()const {
uint64_t res; uint64_t res;
uint32_t a,b; uint32_t a,b;
a=get_32(); a=get_32();
b=get_32(); b=get_32();
if (endian_swap) { if (endian_swap) {
SWAP( a,b ); SWAP( a,b );
} }
res=b; res=b;
res<<=32; res<<=32;
res|=a; res|=a;
return res; return res;
} }
float FileAccess::get_float() const { float FileAccess::get_float() const {
@ -262,15 +262,15 @@ String FileAccess::get_line() const {
CharString line; CharString line;
CharType c=get_8(); CharType c=get_8();
while(!eof_reached()) { while(!eof_reached()) {
if (c=='\n' || c=='\0') { if (c=='\n' || c=='\0') {
line.push_back(0); line.push_back(0);
return String::utf8(line.get_data()); return String::utf8(line.get_data());
} else if (c!='\r') } else if (c!='\r')
line.push_back(c); line.push_back(c);
c=get_8(); c=get_8();
} }
line.push_back(0); line.push_back(0);
@ -284,7 +284,7 @@ Vector<String> FileAccess::get_csv_line(String delim) const {
String l; String l;
int qc=0; int qc=0;
do { do {
l+=get_line(); l+=get_line()+"\n";
qc=0; qc=0;
for(int i=0;i<l.length();i++) { for(int i=0;i<l.length();i++) {
@ -295,6 +295,8 @@ Vector<String> FileAccess::get_csv_line(String delim) const {
} while (qc%2); } while (qc%2);
l=l.substr(0, l.length()-1);
Vector<String> strings; Vector<String> strings;
bool in_quote=false; bool in_quote=false;
@ -331,7 +333,7 @@ Vector<String> FileAccess::get_csv_line(String delim) const {
int FileAccess::get_buffer(uint8_t *p_dst,int p_length) const{ int FileAccess::get_buffer(uint8_t *p_dst,int p_length) const{
int i=0; int i=0;
for (i=0; i<p_length && !eof_reached(); i++) for (i=0; i<p_length && !eof_reached(); i++)
p_dst[i]=get_8(); p_dst[i]=get_8();
@ -340,53 +342,53 @@ int FileAccess::get_buffer(uint8_t *p_dst,int p_length) const{
} }
void FileAccess::store_16(uint16_t p_dest) { void FileAccess::store_16(uint16_t p_dest) {
uint8_t a,b; uint8_t a,b;
a=p_dest&0xFF; a=p_dest&0xFF;
b=p_dest>>8; b=p_dest>>8;
if (endian_swap) { if (endian_swap) {
SWAP( a,b ); SWAP( a,b );
} }
store_8(a); store_8(a);
store_8(b); store_8(b);
} }
void FileAccess::store_32(uint32_t p_dest) { void FileAccess::store_32(uint32_t p_dest) {
uint16_t a,b; uint16_t a,b;
a=p_dest&0xFFFF; a=p_dest&0xFFFF;
b=p_dest>>16; b=p_dest>>16;
if (endian_swap) { if (endian_swap) {
SWAP( a,b ); SWAP( a,b );
} }
store_16(a); store_16(a);
store_16(b); store_16(b);
} }
void FileAccess::store_64(uint64_t p_dest) { void FileAccess::store_64(uint64_t p_dest) {
uint32_t a,b; uint32_t a,b;
a=p_dest&0xFFFFFFFF; a=p_dest&0xFFFFFFFF;
b=p_dest>>32; b=p_dest>>32;
if (endian_swap) { if (endian_swap) {
SWAP( a,b ); SWAP( a,b );
} }
store_32(a); store_32(a);
store_32(b); store_32(b);
} }
void FileAccess::store_real(real_t p_real) { void FileAccess::store_real(real_t p_real) {
@ -461,7 +463,7 @@ void FileAccess::store_line(const String& p_line) {
} }
void FileAccess::store_buffer(const uint8_t *p_src,int p_length) { void FileAccess::store_buffer(const uint8_t *p_src,int p_length) {
for (int i=0;i<p_length;i++) for (int i=0;i<p_length;i++)
store_8(p_src[i]); store_8(p_src[i]);
} }

Some files were not shown because too many files have changed in this diff Show More