summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml6
-rw-r--r--AUTHORS.md4
-rw-r--r--DONORS.md34
-rw-r--r--SConstruct32
-rw-r--r--core/array.cpp1
-rw-r--r--core/bind/core_bind.cpp2
-rw-r--r--core/class_db.cpp4
-rw-r--r--core/cowdata.h5
-rw-r--r--core/dictionary.cpp5
-rw-r--r--core/dictionary.h1
-rw-r--r--core/dvector.h4
-rw-r--r--core/engine.h1
-rw-r--r--core/image.cpp46
-rw-r--r--core/io/compression.cpp2
-rw-r--r--core/io/file_access_pack.cpp4
-rw-r--r--core/io/image_loader.cpp1
-rw-r--r--core/io/marshalls.cpp2
-rw-r--r--core/io/multiplayer_api.cpp4
-rw-r--r--core/io/resource_loader.cpp2
-rw-r--r--core/io/resource_loader.h4
-rw-r--r--core/math/bsp_tree.cpp5
-rw-r--r--core/math/face3.cpp9
-rw-r--r--core/math/math_funcs.h2
-rw-r--r--core/math/matrix3.cpp20
-rw-r--r--core/math/quat.cpp18
-rw-r--r--core/math/quat.h2
-rw-r--r--core/math/vector2.cpp4
-rw-r--r--core/math/vector2.h2
-rw-r--r--core/math/vector3.h6
-rw-r--r--core/os/input.cpp2
-rw-r--r--core/os/memory.cpp2
-rw-r--r--core/rid.h1
-rw-r--r--core/typedefs.h8
-rw-r--r--core/ustring.cpp4
-rw-r--r--core/variant.cpp2
-rw-r--r--core/variant_op.cpp7
-rw-r--r--doc/classes/Animation.xml11
-rw-r--r--doc/classes/ArrayMesh.xml2
-rw-r--r--doc/classes/AudioEffectBandLimitFilter.xml2
-rw-r--r--doc/classes/AudioEffectBandPassFilter.xml2
-rw-r--r--doc/classes/AudioEffectHighPassFilter.xml2
-rw-r--r--doc/classes/AudioEffectLowPassFilter.xml2
-rw-r--r--doc/classes/AudioEffectNotchFilter.xml2
-rw-r--r--doc/classes/CollisionShape.xml2
-rw-r--r--doc/classes/CollisionShape2D.xml2
-rw-r--r--doc/classes/Color.xml58
-rw-r--r--doc/classes/Control.xml2
-rw-r--r--doc/classes/Input.xml1
-rw-r--r--doc/classes/ItemList.xml2
-rw-r--r--doc/classes/KinematicBody.xml2
-rw-r--r--doc/classes/Node.xml3
-rw-r--r--doc/classes/OS.xml1
-rw-r--r--doc/classes/PackedScene.xml2
-rw-r--r--doc/classes/ParallaxLayer.xml1
-rw-r--r--doc/classes/RigidBody.xml38
-rw-r--r--doc/classes/RigidBody2D.xml4
-rw-r--r--doc/classes/SpatialMaterial.xml70
-rw-r--r--doc/classes/TextureProgress.xml10
-rw-r--r--doc/classes/Tree.xml2
-rw-r--r--doc/classes/TreeItem.xml1
-rwxr-xr-xdoc/tools/makerst.py6
-rw-r--r--drivers/coreaudio/audio_driver_coreaudio.cpp6
-rw-r--r--drivers/coremidi/core_midi.cpp6
-rw-r--r--drivers/dummy/rasterizer_dummy.h1
-rw-r--r--drivers/gles2/rasterizer_canvas_gles2.cpp42
-rw-r--r--drivers/gles2/rasterizer_canvas_gles2.h3
-rw-r--r--drivers/gles2/rasterizer_gles2.cpp57
-rw-r--r--drivers/gles2/rasterizer_gles2.h1
-rw-r--r--drivers/gles2/rasterizer_scene_gles2.cpp104
-rw-r--r--drivers/gles2/rasterizer_scene_gles2.h33
-rw-r--r--drivers/gles2/rasterizer_storage_gles2.cpp31
-rw-r--r--drivers/gles2/shaders/SCsub1
-rw-r--r--drivers/gles2/shaders/canvas.glsl11
-rw-r--r--drivers/gles2/shaders/lens_distorted.glsl62
-rw-r--r--drivers/gles2/shaders/scene.glsl317
-rw-r--r--drivers/gles3/rasterizer_canvas_gles3.cpp34
-rw-r--r--drivers/gles3/rasterizer_canvas_gles3.h3
-rw-r--r--drivers/gles3/rasterizer_gles3.cpp23
-rw-r--r--drivers/gles3/rasterizer_gles3.h1
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.cpp6
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.cpp9
-rw-r--r--drivers/gles3/shader_gles3.h12
-rw-r--r--drivers/gles3/shaders/SCsub1
-rw-r--r--drivers/gles3/shaders/canvas.glsl1
-rw-r--r--drivers/gles3/shaders/lens_distorted.glsl (renamed from modules/mobile_vr/shaders/lens_distorted.glsl)10
-rw-r--r--drivers/gles3/shaders/scene.glsl48
-rw-r--r--drivers/gles3/shaders/tonemap.glsl28
-rw-r--r--drivers/png/image_loader_png.cpp5
-rw-r--r--drivers/unix/dir_access_unix.cpp2
-rw-r--r--drivers/unix/net_socket_posix.cpp4
-rw-r--r--drivers/unix/thread_posix.cpp3
-rw-r--r--drivers/wasapi/audio_driver_wasapi.cpp13
-rw-r--r--editor/audio_stream_preview.cpp4
-rw-r--r--editor/create_dialog.cpp2
-rw-r--r--editor/doc/doc_dump.cpp2
-rw-r--r--editor/editor_export.cpp1
-rw-r--r--editor/editor_file_dialog.cpp2
-rw-r--r--editor/editor_file_system.cpp12
-rw-r--r--editor/editor_file_system.h2
-rw-r--r--editor/editor_help.cpp9
-rw-r--r--editor/editor_help.h6
-rw-r--r--editor/editor_inspector.cpp23
-rw-r--r--editor/editor_node.cpp14
-rw-r--r--editor/editor_profiler.cpp2
-rw-r--r--editor/editor_settings.cpp1
-rw-r--r--editor/editor_themes.cpp5
-rw-r--r--editor/filesystem_dock.cpp2
-rw-r--r--editor/icons/icon_noise_texture.svg3
-rw-r--r--editor/import/editor_scene_importer_gltf.cpp12
-rw-r--r--editor/inspector_dock.cpp15
-rw-r--r--editor/inspector_dock.h1
-rw-r--r--editor/plugin_config_dialog.cpp7
-rw-r--r--editor/plugins/animation_blend_space_2d_editor.cpp4
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp16
-rw-r--r--editor/plugins/canvas_item_editor_plugin.h5
-rw-r--r--editor/plugins/curve_editor_plugin.cpp3
-rw-r--r--editor/plugins/curve_editor_plugin.h6
-rw-r--r--editor/plugins/resource_preloader_editor_plugin.cpp71
-rw-r--r--editor/plugins/resource_preloader_editor_plugin.h8
-rw-r--r--editor/plugins/script_editor_plugin.cpp18
-rw-r--r--editor/plugins/script_editor_plugin.h2
-rw-r--r--editor/plugins/script_text_editor.cpp2
-rw-r--r--editor/plugins/spatial_editor_plugin.cpp13
-rw-r--r--editor/plugins/tile_map_editor_plugin.cpp93
-rw-r--r--editor/plugins/tile_map_editor_plugin.h2
-rw-r--r--editor/project_export.cpp6
-rw-r--r--editor/quick_open.cpp2
-rw-r--r--editor/quick_open.h2
-rw-r--r--editor/scene_tree_dock.cpp35
-rw-r--r--editor/scene_tree_dock.h1
-rw-r--r--editor/spatial_editor_gizmos.cpp25
-rw-r--r--main/main.cpp8
-rw-r--r--main/tests/test_io.cpp2
-rw-r--r--main/tests/test_oa_hash_map.cpp2
-rw-r--r--methods.py4
-rwxr-xr-xmisc/hooks/pre-commit-clang-format2
-rwxr-xr-xmisc/travis/android-tools-linux.sh10
-rw-r--r--modules/bmp/image_loader_bmp.cpp9
-rw-r--r--modules/bullet/area_bullet.cpp10
-rw-r--r--modules/bullet/area_bullet.h3
-rw-r--r--modules/bullet/bullet_physics_server.cpp22
-rw-r--r--modules/bullet/bullet_physics_server.h7
-rw-r--r--modules/bullet/collision_object_bullet.cpp166
-rw-r--r--modules/bullet/collision_object_bullet.h40
-rw-r--r--modules/bullet/godot_motion_state.h2
-rw-r--r--modules/bullet/rigid_body_bullet.cpp42
-rw-r--r--modules/bullet/rigid_body_bullet.h11
-rw-r--r--modules/bullet/shape_bullet.cpp17
-rw-r--r--modules/bullet/shape_owner_bullet.h9
-rw-r--r--modules/bullet/soft_body_bullet.cpp6
-rw-r--r--modules/bullet/soft_body_bullet.h7
-rw-r--r--modules/bullet/space_bullet.cpp29
-rw-r--r--modules/csg/csg.cpp4
-rw-r--r--modules/csg/csg_gizmos.cpp2
-rw-r--r--modules/csg/csg_shape.cpp2
-rw-r--r--modules/dds/texture_loader_dds.cpp2
-rw-r--r--modules/enet/doc_classes/NetworkedMultiplayerENet.xml2
-rw-r--r--modules/gdnative/include/gdnative/gdnative.h4
-rw-r--r--modules/gdnative/nativescript/api_generator.cpp1
-rw-r--r--modules/gdnative/nativescript/nativescript.cpp10
-rw-r--r--modules/gdnative/nativescript/nativescript.h23
-rw-r--r--modules/gdscript/gdscript_function.cpp43
-rw-r--r--modules/gdscript/gdscript_parser.cpp6
-rw-r--r--modules/mobile_vr/SCsub2
-rw-r--r--modules/mobile_vr/mobile_vr_interface.cpp93
-rw-r--r--modules/mobile_vr/mobile_vr_interface.h12
-rw-r--r--modules/mobile_vr/shaders/SCsub6
-rw-r--r--modules/mono/SCsub23
-rw-r--r--modules/mono/config.py180
-rw-r--r--modules/mono/csharp_script.cpp6
-rw-r--r--modules/mono/editor/GodotSharpTools/Editor/GodotSharpExport.cs72
-rw-r--r--modules/mono/editor/GodotSharpTools/GodotSharpTools.csproj1
-rw-r--r--modules/mono/editor/bindings_generator.cpp12
-rw-r--r--modules/mono/editor/csharp_project.cpp8
-rw-r--r--modules/mono/editor/godotsharp_builds.cpp75
-rw-r--r--modules/mono/editor/godotsharp_editor.cpp1
-rw-r--r--modules/mono/editor/godotsharp_export.cpp146
-rw-r--r--modules/mono/editor/godotsharp_export.h4
-rw-r--r--modules/mono/editor/mono_bottom_panel.cpp8
-rw-r--r--modules/mono/glue/Managed/Files/Extensions/NodeExtensions.cs24
-rw-r--r--modules/mono/glue/Managed/Files/Extensions/ResourceLoaderExtensions.cs4
-rw-r--r--modules/mono/glue/Managed/Files/GD.cs4
-rw-r--r--modules/mono/glue/nodepath_glue.cpp2
-rw-r--r--modules/mono/glue/rid_glue.cpp2
-rw-r--r--modules/mono/godotsharp_dirs.cpp89
-rw-r--r--modules/mono/godotsharp_dirs.h11
-rw-r--r--modules/mono/mono_gd/gd_mono.cpp185
-rw-r--r--modules/mono/mono_gd/gd_mono.h46
-rw-r--r--modules/mono/mono_gd/gd_mono_assembly.cpp148
-rw-r--r--modules/mono/mono_gd/gd_mono_assembly.h3
-rw-r--r--modules/mono/utils/mono_reg_utils.cpp2
-rw-r--r--modules/mono/utils/thread_local.h20
-rw-r--r--modules/opensimplex/config.py2
-rw-r--r--modules/opensimplex/doc_classes/NoiseTexture.xml7
-rw-r--r--modules/opensimplex/noise_texture.cpp15
-rw-r--r--modules/opensimplex/noise_texture.h3
-rw-r--r--modules/thekla_unwrap/config.py3
-rw-r--r--modules/theora/video_stream_theora.cpp1
-rw-r--r--modules/visual_script/visual_script_editor.cpp8
-rw-r--r--modules/visual_script/visual_script_nodes.cpp4
-rw-r--r--modules/visual_script/visual_script_property_selector.cpp6
-rw-r--r--modules/webm/video_stream_webm.cpp1
-rw-r--r--modules/xatlas_unwrap/config.py4
-rw-r--r--modules/xatlas_unwrap/register_types.cpp18
-rw-r--r--platform/android/SCsub14
-rw-r--r--platform/android/audio_driver_opensl.cpp17
-rw-r--r--platform/android/audio_driver_opensl.h11
-rw-r--r--platform/android/export/export.cpp5
-rw-r--r--platform/android/godot_android.cpp2
-rw-r--r--platform/android/java/src/org/godotengine/godot/Godot.java5
-rw-r--r--platform/android/java/src/org/godotengine/godot/GodotView.java20
-rw-r--r--platform/android/java_glue.cpp14
-rw-r--r--platform/android/os_android.cpp5
-rw-r--r--platform/android/os_android.h4
-rw-r--r--platform/haiku/context_gl_haiku.h6
-rw-r--r--platform/haiku/haiku_direct_window.cpp2
-rw-r--r--platform/iphone/gl_view.mm12
-rw-r--r--platform/osx/os_osx.mm31
-rw-r--r--platform/server/os_server.cpp2
-rw-r--r--platform/uwp/gl_context_egl.h6
-rw-r--r--platform/uwp/os_uwp.cpp2
-rw-r--r--platform/windows/context_gl_win.h2
-rw-r--r--platform/windows/os_windows.cpp4
-rw-r--r--platform/x11/context_gl_x11.h2
-rw-r--r--platform/x11/os_x11.cpp6
-rw-r--r--scene/2d/animated_sprite.cpp10
-rw-r--r--scene/2d/animated_sprite.h1
-rw-r--r--scene/2d/camera_2d.cpp8
-rw-r--r--scene/2d/collision_polygon_2d.cpp2
-rw-r--r--scene/2d/tile_map.cpp2
-rw-r--r--scene/2d/visibility_notifier_2d.h2
-rw-r--r--scene/3d/audio_stream_player_3d.cpp2
-rw-r--r--scene/3d/baked_lightmap.cpp71
-rw-r--r--scene/3d/physics_body.h2
-rw-r--r--scene/3d/visibility_notifier.h2
-rw-r--r--scene/3d/voxel_light_baker.cpp11
-rw-r--r--scene/3d/voxel_light_baker.h10
-rw-r--r--scene/animation/animation_blend_space_2d.cpp2
-rw-r--r--scene/gui/base_button.cpp2
-rw-r--r--scene/gui/color_picker.cpp3
-rw-r--r--scene/gui/control.cpp16
-rw-r--r--scene/gui/gradient_edit.cpp10
-rw-r--r--scene/gui/graph_edit.cpp2
-rw-r--r--scene/gui/grid_container.cpp17
-rw-r--r--scene/gui/grid_container.h1
-rw-r--r--scene/gui/label.cpp4
-rw-r--r--scene/gui/line_edit.cpp2
-rw-r--r--scene/gui/nine_patch_rect.cpp4
-rw-r--r--scene/gui/text_edit.cpp9
-rw-r--r--scene/gui/texture_progress.cpp10
-rw-r--r--scene/main/node.cpp15
-rw-r--r--scene/resources/animation.cpp2
-rw-r--r--scene/resources/dynamic_font.cpp11
-rw-r--r--scene/resources/environment.cpp2
-rw-r--r--scene/resources/material.h4
-rw-r--r--scene/resources/shape.cpp2
-rw-r--r--scene/resources/style_box.cpp6
-rw-r--r--servers/audio/effects/audio_effect_record.cpp2
-rw-r--r--servers/audio/effects/audio_effect_record.h2
-rw-r--r--servers/physics/joints/generic_6dof_joint_sw.cpp2
-rw-r--r--servers/physics/joints/generic_6dof_joint_sw.h6
-rw-r--r--servers/physics/shape_sw.cpp2
-rw-r--r--servers/physics_2d/body_pair_2d_sw.cpp2
-rw-r--r--servers/physics_2d/step_2d_sw.cpp2
-rw-r--r--servers/visual/rasterizer.h1
-rw-r--r--servers/visual/visual_server_scene.cpp10
-rw-r--r--servers/visual/visual_server_scene.h7
-rw-r--r--servers/visual/visual_server_viewport.h1
-rw-r--r--servers/visual_server.cpp2
-rw-r--r--servers/visual_server.h2
270 files changed, 2533 insertions, 1500 deletions
diff --git a/.travis.yml b/.travis.yml
index 7161a3e029..a5217c1d9c 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -29,7 +29,7 @@ matrix:
- clang-format-6.0
- libstdc++6 # >= 4.9 needed for clang-format-6.0
- - env: PLATFORM=x11 TOOLS=yes TARGET=debug CACHE_NAME=${PLATFORM}-tools-mono-gcc EXTRA_ARGS="module_mono_enabled=yes mono_glue=no"
+ - env: PLATFORM=x11 TOOLS=yes TARGET=debug CACHE_NAME=${PLATFORM}-tools-mono-gcc EXTRA_ARGS="module_mono_enabled=yes mono_glue=no werror=yes"
os: linux
compiler: gcc
addons:
@@ -49,7 +49,7 @@ matrix:
build_command: "scons p=x11 -j2 $OPTIONS"
branch_pattern: coverity_scan
- - env: PLATFORM=x11 TOOLS=no TARGET=release CACHE_NAME=${PLATFORM}-clang
+ - env: PLATFORM=x11 TOOLS=no TARGET=release CACHE_NAME=${PLATFORM}-clang EXTRA_ARGS="werror=yes"
os: linux
compiler: clang
addons:
@@ -57,7 +57,7 @@ matrix:
packages:
- *linux_deps
- - env: PLATFORM=android TOOLS=no TARGET=release_debug CACHE_NAME=${PLATFORM}-clang
+ - env: PLATFORM=android TOOLS=no TARGET=release_debug CACHE_NAME=${PLATFORM}-clang EXTRA_ARGS="werror=yes"
os: linux
compiler: clang
diff --git a/AUTHORS.md b/AUTHORS.md
index 9666145582..13a67ce3f5 100644
--- a/AUTHORS.md
+++ b/AUTHORS.md
@@ -45,9 +45,11 @@ name is available.
Bojidar Marinov (bojidar-bg)
bruvzg
Carl Olsson (not-surt)
+ Chris Bradfield (cbscribe)
Dana Olson (adolson)
Daniel J. Ramirez (djrm)
Dmitry Koteroff (Krakean)
+ DualMatrix
Emmanuel Leblond (touilleMan)
Eric Lasota (elasota)
est31
@@ -111,9 +113,9 @@ name is available.
Ramesh Ravone (RameshRavone)
Ray Koopa (RayKoopa)
Rémi Verschelde (akien-mga)
+ Rhody Lugo (rraallvv)
Roberto F. Arroyo (robfram)
romulox-x
- rraallvv
Ruslan Mustakov (endragor)
Saniko (sanikoyes)
SaracenOne
diff --git a/DONORS.md b/DONORS.md
index 41d24c5fbb..6fdb02e3fa 100644
--- a/DONORS.md
+++ b/DONORS.md
@@ -21,40 +21,43 @@ generous deed immortalized in the next stable release of Godot Engine.
## Mini sponsors
+ Andrew Dunai
Brandon Lamb
Christian Uldall Pedersen
Christopher Igoe
Christoph Woinke
GameDev.net
Hein-Pieter van Braam
+ iDev.Network Studios
Jamal Alyafei
Jay Sistar
+ Leona Eden
Matthieu Huvé
Mike King
Nathan Warden
Neal Gompa (Conan Kudo)
Pascal Julien
Patrick Aarstad
- rottis
Ruslan Mustakov
Slobodan Milnovic
Stephan Lanfermann
Stoney Meyerhoeffer
+ thechris
Thomas Mathews
VilliHaukka
## Gold donors
- 3Dexplorer
Asdf
cheese65536
K9Kraken
- Kris Michael
Manuele Finocchiaro
Nathanael Beisiegel
Officine Pixel S.n.c.
+ Retro Village
Zaven Muradyan
+ 13MHz
Allen Schade
Andreas Schüle
Austen McRae
@@ -62,12 +65,14 @@ generous deed immortalized in the next stable release of Godot Engine.
David Gehrig
Florian Breisch
Gary Oberbrunner
+ Jay Horton
Johannes Wuensch
Josep G. Camarasa
Joshua Lesperance
Krzysztof Dluzniewski
Kyle Szklenski
Mohammad Taleb
+ Moonwards
Paul LaMotte
Ranoller
Sergey
@@ -91,7 +96,6 @@ generous deed immortalized in the next stable release of Godot Engine.
Rami
Robert Willes
Robin Arys
- Rodrigo Loli
Ronnie Ashlock
ScottMakesGames
Thomas Bjarnelöf
@@ -102,8 +106,8 @@ generous deed immortalized in the next stable release of Godot Engine.
Alessandra Pereyra
Alexey Dyadchenko
Amanda Haldy
- Anthony Ryan
Branwen Danielle Zakariasen
+ Chau Siu Hung
Chris Brown
Chris Petrich
Cody Parker
@@ -112,15 +116,16 @@ generous deed immortalized in the next stable release of Godot Engine.
E.G.
Eric
Eric Monson
+ Ethan Bennis
Fidget Sinner
flesk
G Barnes
+ Gero
GGGames.org
Giovanni Solimeno
Guilherme Felipe de C. G. da Silva
Hasen Judy
Heath Hayes
- Jay Horton
Jeppe Zapp
joe513
Juraj Móza
@@ -130,10 +135,8 @@ generous deed immortalized in the next stable release of Godot Engine.
Markus Wiesner
Marvin
Nahuel Sacchetti
- Neal Barry
Nick Nikitin
Pablo Cholaky
- Patrick Schnorbus
Pete Goodwin
ray-tracer
Ruben Soares Luis
@@ -141,10 +144,9 @@ generous deed immortalized in the next stable release of Godot Engine.
Sindre Sømme
Sofox
Stoned Xander
- Tim Dalporto
Trent McPheron
- Wilfrid ARNOLD
WytRabbit
+ Zachariah Gibbons
## Silver donors
@@ -177,7 +179,6 @@ generous deed immortalized in the next stable release of Godot Engine.
Christian Baune
Christian Winter
Christopher Schmitt
- Chris Wilson
Collin Shooltz
Daniel Johnson
Daniel Kaplan
@@ -187,16 +188,14 @@ generous deed immortalized in the next stable release of Godot Engine.
David May
Disktra
Dominik Wetzel
- dRez Games
Duy Kevin Nguyen
Edward Herbert
Elias Nykrem
Eric Martini
Eugenio Hugo Salgüero Jáñez
- Extarys
Fabian Becker
fengjiongmax
- Francesco Lisi
+ Foomf
G3Dev sàrl
Gerrit Großkopf
Gilberto K. Otubo
@@ -207,7 +206,6 @@ generous deed immortalized in the next stable release of Godot Engine.
ialex32x
Jahn Johansen
Jaime Ruiz-Borau Vizárraga
- Jed
Jeff Hungerford
Joel Fivat
Johan Lindberg
@@ -237,7 +235,6 @@ generous deed immortalized in the next stable release of Godot Engine.
magodev
Manolis Makris
Martin Eigel
- Martins Odabi
Max R.R. Collada
Maxwell
Mertcan Mermerkaya
@@ -256,14 +253,15 @@ generous deed immortalized in the next stable release of Godot Engine.
Nicolas SAN AGUSTIN
Niko Leopold
Noi Sek
- Pablo Seibelt
Pan Ip
Pascal Grüter
Pat LaBine
Patrick Nafarrete
Paul E Hansen
+ Paul Gieske
Paul Mason
Paweł Kowal
+ Phillip Ryals
Pierre-Igor Berthet
Pietro Vertechi
Piotr Kaczmarski
@@ -287,9 +285,11 @@ generous deed immortalized in the next stable release of Godot Engine.
Tim
Tom Larrow
Tristan Crawford
+ Tryggve Sollid
Trym Nilsen
Tyler Stafos
UltyX
+ Vaiktorg
Victor
Viktor Ferenczi
waka nya
diff --git a/SConstruct b/SConstruct
index a056a0c3ae..f8c1c82961 100644
--- a/SConstruct
+++ b/SConstruct
@@ -159,15 +159,16 @@ opts.Add(BoolVariable('minizip', "Enable ZIP archive support using minizip", Tru
opts.Add(BoolVariable('xaudio2', "Enable the XAudio2 audio driver", False))
# Advanced options
-opts.Add(BoolVariable('disable_3d', "Disable 3D nodes for a smaller executable", False))
-opts.Add(BoolVariable('disable_advanced_gui', "Disable advanced 3D GUI nodes and behaviors", False))
-opts.Add('extra_suffix', "Custom extra suffix added to the base filename of all generated binary files", '')
opts.Add(BoolVariable('verbose', "Enable verbose output for the compilation", False))
-opts.Add(BoolVariable('vsproj', "Generate a Visual Studio solution", False))
-opts.Add(EnumVariable('warnings', "Set the level of warnings emitted during compilation", 'no', ('extra', 'all', 'moderate', 'no')))
opts.Add(BoolVariable('progress', "Show a progress indicator during compilation", True))
+opts.Add(EnumVariable('warnings', "Set the level of warnings emitted during compilation", 'all', ('extra', 'all', 'moderate', 'no')))
+opts.Add(BoolVariable('werror', "Treat compiler warnings as errors. Depends on the level of warnings set with 'warnings'", False))
opts.Add(BoolVariable('dev', "If yes, alias for verbose=yes warnings=all", False))
+opts.Add('extra_suffix', "Custom extra suffix added to the base filename of all generated binary files", '')
+opts.Add(BoolVariable('vsproj', "Generate a Visual Studio solution", False))
opts.Add(EnumVariable('macports_clang', "Build using Clang from MacPorts", 'no', ('no', '5.0', 'devel')))
+opts.Add(BoolVariable('disable_3d', "Disable 3D nodes for a smaller executable", False))
+opts.Add(BoolVariable('disable_advanced_gui', "Disable advanced 3D GUI nodes and behaviors", False))
opts.Add(BoolVariable('no_editor_splash', "Don't use the custom splash screen for the editor", False))
opts.Add('system_certs_path', "Use this path as SSL certificates default for editor (for package maintainers)", '')
@@ -234,7 +235,7 @@ env_base.platform_exporters = platform_exporters
env_base.platform_apis = platform_apis
if (env_base['target'] == 'debug'):
- env_base.Append(CPPDEFINES=['DEBUG_MEMORY_ALLOC'])
+ env_base.Append(CPPDEFINES=['DEBUG_MEMORY_ALLOC','DISABLE_FORCED_INLINE'])
if (env_base['no_editor_splash']):
env_base.Append(CPPDEFINES=['NO_EDITOR_SPLASH'])
@@ -317,33 +318,36 @@ if selected_platform in platform_list:
# must happen after the flags, so when flags are used by configure, stuff happens (ie, ssl on x11)
detect.configure(env)
- if (env["warnings"] == 'yes'):
- print("WARNING: warnings=yes is deprecated; assuming warnings=all")
-
+ # Configure compiler warnings
if env.msvc:
- disable_nonessential_warnings = ['/wd4267', '/wd4244', '/wd4305', '/wd4800'] # Truncations, narrowing conversions...
+ # Truncations, narrowing conversions, signed/unsigned comparisons...
+ disable_nonessential_warnings = ['/wd4267', '/wd4244', '/wd4305', '/wd4018', '/wd4800']
if (env["warnings"] == 'extra'):
env.Append(CCFLAGS=['/Wall']) # Implies /W4
- elif (env["warnings"] == 'all' or env["warnings"] == 'yes'):
+ elif (env["warnings"] == 'all'):
env.Append(CCFLAGS=['/W3'] + disable_nonessential_warnings)
elif (env["warnings"] == 'moderate'):
- # C4244 shouldn't be needed here being a level-3 warning, but it is
env.Append(CCFLAGS=['/W2'] + disable_nonessential_warnings)
else: # 'no'
env.Append(CCFLAGS=['/w'])
# Set exception handling model to avoid warnings caused by Windows system headers.
env.Append(CCFLAGS=['/EHsc'])
+ if (env["werror"]):
+ env.Append(CCFLAGS=['/WX'])
else: # Rest of the world
disable_nonessential_warnings = ['-Wno-sign-compare']
if (env["warnings"] == 'extra'):
env.Append(CCFLAGS=['-Wall', '-Wextra'])
- elif (env["warnings"] == 'all' or env["warnings"] == 'yes'):
+ elif (env["warnings"] == 'all'):
env.Append(CCFLAGS=['-Wall'] + disable_nonessential_warnings)
elif (env["warnings"] == 'moderate'):
env.Append(CCFLAGS=['-Wall', '-Wno-unused'] + disable_nonessential_warnings)
else: # 'no'
env.Append(CCFLAGS=['-w'])
- env.Append(CCFLAGS=['-Werror=return-type'])
+ if (env["werror"]):
+ env.Append(CCFLAGS=['-Werror'])
+ else: # always enable those errors
+ env.Append(CCFLAGS=['-Werror=return-type'])
suffix = "." + selected_platform
diff --git a/core/array.cpp b/core/array.cpp
index 9708452850..9f09ddbe15 100644
--- a/core/array.cpp
+++ b/core/array.cpp
@@ -258,6 +258,7 @@ struct _ArrayVariantSortCustom {
Array &Array::sort_custom(Object *p_obj, const StringName &p_function) {
ERR_FAIL_NULL_V(p_obj, *this);
+ ERR_FAIL_COND_V(!p_obj->has_method(p_function), *this);
SortArray<Variant, _ArrayVariantSortCustom, true> avs;
avs.compare.obj = p_obj;
diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp
index 57654e96dc..02b8c71465 100644
--- a/core/bind/core_bind.cpp
+++ b/core/bind/core_bind.cpp
@@ -2487,7 +2487,7 @@ _Thread::~_Thread() {
if (active) {
ERR_EXPLAIN("Reference to a Thread object object was lost while the thread is still running...");
}
- ERR_FAIL_COND(active == true);
+ ERR_FAIL_COND(active);
}
/////////////////////////////////////
diff --git a/core/class_db.cpp b/core/class_db.cpp
index dcc07f8f41..71809d5454 100644
--- a/core/class_db.cpp
+++ b/core/class_db.cpp
@@ -809,10 +809,10 @@ void ClassDB::add_signal(StringName p_class, const MethodInfo &p_signal) {
ClassInfo *type = classes.getptr(p_class);
ERR_FAIL_COND(!type);
- ClassInfo *check = type;
StringName sname = p_signal.name;
-#ifdef DEBUG_METHODS_ENABLED
+#ifdef DEBUG_METHODS_ENABLED
+ ClassInfo *check = type;
while (check) {
if (check->signal_map.has(sname)) {
ERR_EXPLAIN("Type " + String(p_class) + " already has signal: " + String(sname));
diff --git a/core/cowdata.h b/core/cowdata.h
index 9e75d4ed55..54ece4c856 100644
--- a/core/cowdata.h
+++ b/core/cowdata.h
@@ -87,7 +87,10 @@ private:
#if defined(_add_overflow) && defined(_mul_overflow)
size_t o;
size_t p;
- if (_mul_overflow(p_elements, sizeof(T), &o)) return false;
+ if (_mul_overflow(p_elements, sizeof(T), &o)) {
+ *out = 0;
+ return false;
+ }
*out = next_power_of_2(o);
if (_add_overflow(o, static_cast<size_t>(32), &p)) return false; //no longer allocated here
return true;
diff --git a/core/dictionary.cpp b/core/dictionary.cpp
index ba32606819..ccbdff3816 100644
--- a/core/dictionary.cpp
+++ b/core/dictionary.cpp
@@ -145,6 +145,11 @@ bool Dictionary::operator==(const Dictionary &p_dictionary) const {
return _p == p_dictionary._p;
}
+bool Dictionary::operator!=(const Dictionary &p_dictionary) const {
+
+ return _p != p_dictionary._p;
+}
+
void Dictionary::_ref(const Dictionary &p_from) const {
//make a copy first (thread safe)
diff --git a/core/dictionary.h b/core/dictionary.h
index 9950fb6361..d3b98c2f63 100644
--- a/core/dictionary.h
+++ b/core/dictionary.h
@@ -69,6 +69,7 @@ public:
bool erase(const Variant &p_key);
bool operator==(const Dictionary &p_dictionary) const;
+ bool operator!=(const Dictionary &p_dictionary) const;
uint32_t hash() const;
void operator=(const Dictionary &p_dictionary);
diff --git a/core/dvector.h b/core/dvector.h
index 0d0848a19a..2830c57ec0 100644
--- a/core/dvector.h
+++ b/core/dvector.h
@@ -149,7 +149,7 @@ class PoolVector {
}
}
- if (old_alloc->refcount.unref() == true) {
+ if (old_alloc->refcount.unref()) {
//this should never happen but..
#ifdef DEBUG_ENABLED
@@ -209,7 +209,7 @@ class PoolVector {
if (!alloc)
return;
- if (alloc->refcount.unref() == false) {
+ if (!alloc->refcount.unref()) {
alloc = NULL;
return;
}
diff --git a/core/engine.h b/core/engine.h
index b3c385c9f8..82b1e5d681 100644
--- a/core/engine.h
+++ b/core/engine.h
@@ -125,6 +125,7 @@ public:
String get_license_text() const;
Engine();
+ virtual ~Engine() {}
};
#endif // ENGINE_H
diff --git a/core/image.cpp b/core/image.cpp
index c0002e0cd6..172f5e517a 100644
--- a/core/image.cpp
+++ b/core/image.cpp
@@ -307,6 +307,7 @@ void Image::_get_mipmap_offset_and_size(int p_mipmap, int &r_offset, int &r_widt
r_width = w;
r_height = h;
}
+
int Image::get_mipmap_offset(int p_mipmap) const {
ERR_FAIL_INDEX_V(p_mipmap, get_mipmap_count() + 1, -1);
@@ -499,8 +500,6 @@ void Image::convert(Format p_new_format) {
bool gen_mipmaps = mipmaps;
- //mipmaps=false;
-
_copy_internals_from(new_img);
if (gen_mipmaps)
@@ -781,9 +780,9 @@ void Image::resize(int p_width, int p_height, Interpolation p_interpolation) {
// Setup mipmap-aware scaling
Image dst2;
- int mip1;
- int mip2;
- float mip1_weight;
+ int mip1 = 0;
+ int mip2 = 0;
+ float mip1_weight = 0;
if (mipmap_aware) {
float avg_scale = ((float)p_width / width + (float)p_height / height) * 0.5f;
if (avg_scale >= 1.0f) {
@@ -799,6 +798,7 @@ void Image::resize(int p_width, int p_height, Interpolation p_interpolation) {
if (interpolate_mipmaps) {
dst2.create(p_width, p_height, 0, format);
}
+
bool had_mipmaps = mipmaps;
if (interpolate_mipmaps && !had_mipmaps) {
generate_mipmaps();
@@ -951,6 +951,7 @@ void Image::resize(int p_width, int p_height, Interpolation p_interpolation) {
}
void Image::crop_from_point(int p_x, int p_y, int p_width, int p_height) {
+
if (!_can_modify(format)) {
ERR_EXPLAIN("Cannot crop in indexed, compressed or custom image formats.");
ERR_FAIL();
@@ -996,7 +997,7 @@ void Image::crop_from_point(int p_x, int p_y, int p_width, int p_height) {
}
}
- if (mipmaps > 0)
+ if (has_mipmaps())
dst.generate_mipmaps();
_copy_internals_from(dst);
}
@@ -1013,10 +1014,10 @@ void Image::flip_y() {
ERR_FAIL();
}
- bool gm = mipmaps;
-
- if (gm)
+ bool used_mipmaps = has_mipmaps();
+ if (used_mipmaps) {
clear_mipmaps();
+ }
{
PoolVector<uint8_t>::Write w = data.write();
@@ -1037,8 +1038,9 @@ void Image::flip_y() {
}
}
- if (gm)
+ if (used_mipmaps) {
generate_mipmaps();
+ }
}
void Image::flip_x() {
@@ -1048,9 +1050,10 @@ void Image::flip_x() {
ERR_FAIL();
}
- bool gm = mipmaps;
- if (gm)
+ bool used_mipmaps = has_mipmaps();
+ if (used_mipmaps) {
clear_mipmaps();
+ }
{
PoolVector<uint8_t>::Write w = data.write();
@@ -1071,8 +1074,9 @@ void Image::flip_x() {
}
}
- if (gm)
+ if (used_mipmaps) {
generate_mipmaps();
+ }
}
int Image::_get_dst_image_size(int p_width, int p_height, Format p_format, int &r_mipmaps, int p_mipmaps) {
@@ -1167,12 +1171,13 @@ void Image::expand_x2_hq2x() {
ERR_FAIL_COND(!_can_modify(format));
- Format current = format;
- bool mm = has_mipmaps();
- if (mm) {
+ bool used_mipmaps = has_mipmaps();
+ if (used_mipmaps) {
clear_mipmaps();
}
+ Format current = format;
+
if (current != FORMAT_RGBA8)
convert(FORMAT_RGBA8);
@@ -1193,6 +1198,8 @@ void Image::expand_x2_hq2x() {
if (current != FORMAT_RGBA8)
convert(current);
+ // FIXME: This is likely meant to use "used_mipmaps" as defined above, but if we do,
+ // we end up with a regression: GH-22747
if (mipmaps) {
generate_mipmaps();
}
@@ -1466,7 +1473,8 @@ void Image::create(int p_width, int p_height, bool p_use_mipmaps, Format p_forma
void Image::create(const char **p_xpm) {
- int size_width, size_height;
+ int size_width = 0;
+ int size_height = 0;
int pixelchars = 0;
mipmaps = false;
bool has_alpha = false;
@@ -1482,8 +1490,8 @@ void Image::create(const char **p_xpm) {
int line = 0;
HashMap<String, Color> colormap;
- int colormap_size;
- uint32_t pixel_size;
+ int colormap_size = 0;
+ uint32_t pixel_size = 0;
PoolVector<uint8_t>::Write w;
while (status != DONE) {
diff --git a/core/io/compression.cpp b/core/io/compression.cpp
index e456a85c65..3c0b6541bd 100644
--- a/core/io/compression.cpp
+++ b/core/io/compression.cpp
@@ -175,7 +175,7 @@ int Compression::decompress(uint8_t *p_dst, int p_dst_max_size, const uint8_t *p
} break;
case MODE_ZSTD: {
ZSTD_DCtx *dctx = ZSTD_createDCtx();
- if (zstd_long_distance_matching) ZSTD_DCtx_setMaxWindowSize(dctx, 1 << zstd_window_log_size);
+ if (zstd_long_distance_matching) ZSTD_DCtx_setMaxWindowSize(dctx, (size_t)1 << zstd_window_log_size);
int ret = ZSTD_decompressDCtx(dctx, p_dst, p_dst_max_size, p_src, p_src_size);
ZSTD_freeDCtx(dctx);
return ret;
diff --git a/core/io/file_access_pack.cpp b/core/io/file_access_pack.cpp
index e3c8fb9eb8..40f756ba9a 100644
--- a/core/io/file_access_pack.cpp
+++ b/core/io/file_access_pack.cpp
@@ -169,11 +169,11 @@ bool PackedSourcePCK::try_open_pack(const String &p_path) {
uint32_t version = f->get_32();
uint32_t ver_major = f->get_32();
uint32_t ver_minor = f->get_32();
- uint32_t ver_rev = f->get_32();
+ f->get_32(); // ver_rev
ERR_EXPLAIN("Pack version unsupported: " + itos(version));
ERR_FAIL_COND_V(version != PACK_VERSION, false);
- ERR_EXPLAIN("Pack created with a newer version of the engine: " + itos(ver_major) + "." + itos(ver_minor) + "." + itos(ver_rev));
+ ERR_EXPLAIN("Pack created with a newer version of the engine: " + itos(ver_major) + "." + itos(ver_minor));
ERR_FAIL_COND_V(ver_major > VERSION_MAJOR || (ver_major == VERSION_MAJOR && ver_minor > VERSION_MINOR), false);
for (int i = 0; i < 16; i++) {
diff --git a/core/io/image_loader.cpp b/core/io/image_loader.cpp
index f202320043..3ae9ff676c 100644
--- a/core/io/image_loader.cpp
+++ b/core/io/image_loader.cpp
@@ -118,7 +118,6 @@ RES ResourceFormatLoaderImage::load(const String &p_path, const String &p_origin
if (r_error) {
*r_error = ERR_CANT_OPEN;
}
- memdelete(f);
return RES();
}
diff --git a/core/io/marshalls.cpp b/core/io/marshalls.cpp
index 628019ef7f..ec430d41a9 100644
--- a/core/io/marshalls.cpp
+++ b/core/io/marshalls.cpp
@@ -868,8 +868,6 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
} break;
case Variant::REAL: {
- double d = p_variant;
- float f = d;
if (flags & ENCODE_FLAG_64) {
if (buf) {
encode_double(p_variant.operator double(), buf);
diff --git a/core/io/multiplayer_api.cpp b/core/io/multiplayer_api.cpp
index 17b77bc535..b3f0a76a80 100644
--- a/core/io/multiplayer_api.cpp
+++ b/core/io/multiplayer_api.cpp
@@ -416,7 +416,7 @@ bool MultiplayerAPI::_send_confirm_path(NodePath p_path, PathSentCache *psc, int
Map<int, bool>::Element *F = psc->confirmed_peers.find(E->get());
- if (!F || F->get() == false) {
+ if (!F || !F->get()) {
// Path was not cached, or was cached but is unconfirmed.
if (!F) {
// Not cached at all, take note.
@@ -578,7 +578,7 @@ void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p
network_peer->set_target_peer(E->get()); // To this one specifically.
- if (F->get() == true) {
+ if (F->get()) {
// This one confirmed path, so use id.
encode_uint32(psc->id, &(packet_cache.write[1]));
network_peer->put_packet(packet_cache.ptr(), ofs);
diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp
index 8c56d55e85..d156a9f4bd 100644
--- a/core/io/resource_loader.cpp
+++ b/core/io/resource_loader.cpp
@@ -647,3 +647,5 @@ bool ResourceLoader::timestamp_on_load = false;
SelfList<Resource>::List ResourceLoader::remapped_list;
HashMap<String, Vector<String> > ResourceLoader::translation_remaps;
HashMap<String, String> ResourceLoader::path_remaps;
+
+ResourceLoaderImport ResourceLoader::import = NULL;
diff --git a/core/io/resource_loader.h b/core/io/resource_loader.h
index de0981350d..96bc6fa8dd 100644
--- a/core/io/resource_loader.h
+++ b/core/io/resource_loader.h
@@ -77,6 +77,8 @@ public:
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 Error (*ResourceLoaderImport)(const String &p_path);
+
class ResourceLoader {
enum {
@@ -147,6 +149,8 @@ public:
static void reload_translation_remaps();
static void load_translation_remaps();
static void clear_translation_remaps();
+
+ static ResourceLoaderImport import;
};
#endif
diff --git a/core/math/bsp_tree.cpp b/core/math/bsp_tree.cpp
index 6e51c56357..6ffc963783 100644
--- a/core/math/bsp_tree.cpp
+++ b/core/math/bsp_tree.cpp
@@ -165,7 +165,6 @@ int BSP_Tree::get_points_inside(const Vector3 *p_points, int p_point_count) cons
int pass_count = 0;
const Node *nodesptr = &nodes[0];
const Plane *planesptr = &planes[0];
- int plane_count = planes.size();
int node_count = nodes.size();
if (node_count == 0) // no nodes!
@@ -192,9 +191,9 @@ int BSP_Tree::get_points_inside(const Vector3 *p_points, int p_point_count) cons
break;
}
- uint16_t plane = nodesptr[idx].plane;
#ifdef DEBUG_ENABLED
-
+ int plane_count = planes.size();
+ uint16_t plane = nodesptr[idx].plane;
ERR_FAIL_INDEX_V(plane, plane_count, false);
#endif
diff --git a/core/math/face3.cpp b/core/math/face3.cpp
index aa46fde7f7..8366137131 100644
--- a/core/math/face3.cpp
+++ b/core/math/face3.cpp
@@ -202,11 +202,12 @@ bool Face3::intersects_aabb(const AABB &p_aabb) const {
{ \
real_t aabb_min = p_aabb.position.m_ax; \
real_t aabb_max = p_aabb.position.m_ax + p_aabb.size.m_ax; \
- real_t tri_min, tri_max; \
- for (int i = 0; i < 3; i++) { \
- if (i == 0 || vertex[i].m_ax > tri_max) \
+ real_t tri_min = vertex[0].m_ax; \
+ real_t tri_max = vertex[0].m_ax; \
+ for (int i = 1; i < 3; i++) { \
+ if (vertex[i].m_ax > tri_max) \
tri_max = vertex[i].m_ax; \
- if (i == 0 || vertex[i].m_ax < tri_min) \
+ if (vertex[i].m_ax < tri_min) \
tri_min = vertex[i].m_ax; \
} \
\
diff --git a/core/math/math_funcs.h b/core/math/math_funcs.h
index 472baf0484..9a486a49d0 100644
--- a/core/math/math_funcs.h
+++ b/core/math/math_funcs.h
@@ -46,7 +46,7 @@ class Math {
public:
Math() {} // useless to instance
- static const uint64_t RANDOM_MAX = 4294967295;
+ static const uint64_t RANDOM_MAX = 0xFFFFFFFF;
static _ALWAYS_INLINE_ double sin(double p_x) { return ::sin(p_x); }
static _ALWAYS_INLINE_ float sin(float p_x) { return ::sinf(p_x); }
diff --git a/core/math/matrix3.cpp b/core/math/matrix3.cpp
index fca54b1556..925a7b3f1e 100644
--- a/core/math/matrix3.cpp
+++ b/core/math/matrix3.cpp
@@ -299,14 +299,14 @@ Vector3 Basis::rotref_posscale_decomposition(Basis &rotref) const {
ERR_FAIL_COND_V(determinant() == 0, Vector3());
Basis m = transposed() * (*this);
- ERR_FAIL_COND_V(m.is_diagonal() == false, Vector3());
+ ERR_FAIL_COND_V(!m.is_diagonal(), Vector3());
#endif
Vector3 scale = get_scale();
Basis inv_scale = Basis().scaled(scale.inverse()); // this will also absorb the sign of scale
rotref = (*this) * inv_scale;
#ifdef MATH_CHECKS
- ERR_FAIL_COND_V(rotref.is_orthogonal() == false, Vector3());
+ ERR_FAIL_COND_V(!rotref.is_orthogonal(), Vector3());
#endif
return scale.abs();
}
@@ -430,7 +430,7 @@ Vector3 Basis::get_euler_xyz() const {
Vector3 euler;
#ifdef MATH_CHECKS
- ERR_FAIL_COND_V(is_rotation() == false, euler);
+ ERR_FAIL_COND_V(!is_rotation(), euler);
#endif
real_t sy = elements[0][2];
if (sy < 1.0) {
@@ -497,7 +497,7 @@ Vector3 Basis::get_euler_yxz() const {
Vector3 euler;
#ifdef MATH_CHECKS
- ERR_FAIL_COND_V(is_rotation() == false, euler);
+ ERR_FAIL_COND_V(!is_rotation(), euler);
#endif
real_t m12 = elements[1][2];
@@ -556,7 +556,7 @@ bool Basis::is_equal_approx(const Basis &a, const Basis &b) const {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
- if (Math::is_equal_approx(a.elements[i][j], b.elements[i][j]) == false)
+ if (!Math::is_equal_approx(a.elements[i][j], b.elements[i][j]))
return false;
}
}
@@ -600,7 +600,7 @@ Basis::operator String() const {
Quat Basis::get_quat() const {
#ifdef MATH_CHECKS
- ERR_FAIL_COND_V(is_rotation() == false, Quat());
+ ERR_FAIL_COND_V(!is_rotation(), Quat());
#endif
real_t trace = elements[0][0] + elements[1][1] + elements[2][2];
real_t temp[4];
@@ -697,7 +697,7 @@ void Basis::set_orthogonal_index(int p_index) {
void Basis::get_axis_angle(Vector3 &r_axis, real_t &r_angle) const {
#ifdef MATH_CHECKS
- ERR_FAIL_COND(is_rotation() == false);
+ ERR_FAIL_COND(!is_rotation());
#endif
real_t angle, x, y, z; // variables for result
real_t epsilon = 0.01; // margin to allow for rounding errors
@@ -785,7 +785,7 @@ void Basis::set_quat(const Quat &p_quat) {
void Basis::set_axis_angle(const Vector3 &p_axis, real_t p_phi) {
// Rotation matrix from axis and angle, see https://en.wikipedia.org/wiki/Rotation_matrix#Rotation_matrix_from_axis_angle
#ifdef MATH_CHECKS
- ERR_FAIL_COND(p_axis.is_normalized() == false);
+ ERR_FAIL_COND(!p_axis.is_normalized());
#endif
Vector3 axis_sq(p_axis.x * p_axis.x, p_axis.y * p_axis.y, p_axis.z * p_axis.z);
@@ -837,8 +837,8 @@ void Basis::set_diagonal(const Vector3 p_diag) {
Basis Basis::slerp(const Basis &target, const real_t &t) const {
// TODO: implement this directly without using quaternions to make it more efficient
#ifdef MATH_CHECKS
- ERR_FAIL_COND_V(is_rotation() == false, Basis());
- ERR_FAIL_COND_V(target.is_rotation() == false, Basis());
+ ERR_FAIL_COND_V(!is_rotation(), Basis());
+ ERR_FAIL_COND_V(!target.is_rotation(), Basis());
#endif
Quat from(*this);
diff --git a/core/math/quat.cpp b/core/math/quat.cpp
index d660ce4553..791e84f089 100644
--- a/core/math/quat.cpp
+++ b/core/math/quat.cpp
@@ -100,7 +100,7 @@ void Quat::set_euler_yxz(const Vector3 &p_euler) {
// This implementation uses YXZ convention (Z is the first rotation).
Vector3 Quat::get_euler_yxz() const {
#ifdef MATH_CHECKS
- ERR_FAIL_COND_V(is_normalized() == false, Vector3(0, 0, 0));
+ ERR_FAIL_COND_V(!is_normalized(), Vector3(0, 0, 0));
#endif
Basis m(*this);
return m.get_euler_yxz();
@@ -140,15 +140,15 @@ bool Quat::is_normalized() const {
Quat Quat::inverse() const {
#ifdef MATH_CHECKS
- ERR_FAIL_COND_V(is_normalized() == false, Quat());
+ ERR_FAIL_COND_V(!is_normalized(), Quat());
#endif
return Quat(-x, -y, -z, w);
}
Quat Quat::slerp(const Quat &q, const real_t &t) const {
#ifdef MATH_CHECKS
- ERR_FAIL_COND_V(is_normalized() == false, Quat());
- ERR_FAIL_COND_V(q.is_normalized() == false, Quat());
+ ERR_FAIL_COND_V(!is_normalized(), Quat());
+ ERR_FAIL_COND_V(!q.is_normalized(), Quat());
#endif
Quat to1;
real_t omega, cosom, sinom, scale0, scale1;
@@ -194,8 +194,8 @@ Quat Quat::slerp(const Quat &q, const real_t &t) const {
Quat Quat::slerpni(const Quat &q, const real_t &t) const {
#ifdef MATH_CHECKS
- ERR_FAIL_COND_V(is_normalized() == false, Quat());
- ERR_FAIL_COND_V(q.is_normalized() == false, Quat());
+ ERR_FAIL_COND_V(!is_normalized(), Quat());
+ ERR_FAIL_COND_V(!q.is_normalized(), Quat());
#endif
const Quat &from = *this;
@@ -216,8 +216,8 @@ Quat Quat::slerpni(const Quat &q, const real_t &t) const {
Quat Quat::cubic_slerp(const Quat &q, const Quat &prep, const Quat &postq, const real_t &t) const {
#ifdef MATH_CHECKS
- ERR_FAIL_COND_V(is_normalized() == false, Quat());
- ERR_FAIL_COND_V(q.is_normalized() == false, Quat());
+ ERR_FAIL_COND_V(!is_normalized(), Quat());
+ ERR_FAIL_COND_V(!q.is_normalized(), Quat());
#endif
//the only way to do slerp :|
real_t t2 = (1.0 - t) * t * 2;
@@ -233,7 +233,7 @@ Quat::operator String() const {
void Quat::set_axis_angle(const Vector3 &axis, const real_t &angle) {
#ifdef MATH_CHECKS
- ERR_FAIL_COND(axis.is_normalized() == false);
+ ERR_FAIL_COND(!axis.is_normalized());
#endif
real_t d = axis.length();
if (d == 0)
diff --git a/core/math/quat.h b/core/math/quat.h
index 10d3846c87..c4f9b3a732 100644
--- a/core/math/quat.h
+++ b/core/math/quat.h
@@ -87,7 +87,7 @@ public:
_FORCE_INLINE_ Vector3 xform(const Vector3 &v) const {
#ifdef MATH_CHECKS
- ERR_FAIL_COND_V(is_normalized() == false, v);
+ ERR_FAIL_COND_V(!is_normalized(), v);
#endif
Vector3 u(x, y, z);
Vector3 uv = u.cross(v);
diff --git a/core/math/vector2.cpp b/core/math/vector2.cpp
index 84c9f0fca6..7c6f056f09 100644
--- a/core/math/vector2.cpp
+++ b/core/math/vector2.cpp
@@ -167,7 +167,7 @@ Vector2 Vector2::cubic_interpolate(const Vector2 &p_b, const Vector2 &p_pre_a, c
// slide returns the component of the vector along the given plane, specified by its normal vector.
Vector2 Vector2::slide(const Vector2 &p_normal) const {
#ifdef MATH_CHECKS
- ERR_FAIL_COND_V(p_normal.is_normalized() == false, Vector2());
+ ERR_FAIL_COND_V(!p_normal.is_normalized(), Vector2());
#endif
return *this - p_normal * this->dot(p_normal);
}
@@ -178,7 +178,7 @@ Vector2 Vector2::bounce(const Vector2 &p_normal) const {
Vector2 Vector2::reflect(const Vector2 &p_normal) const {
#ifdef MATH_CHECKS
- ERR_FAIL_COND_V(p_normal.is_normalized() == false, Vector2());
+ ERR_FAIL_COND_V(!p_normal.is_normalized(), Vector2());
#endif
return 2.0 * p_normal * this->dot(p_normal) - *this;
}
diff --git a/core/math/vector2.h b/core/math/vector2.h
index df49484aaf..e5e555597d 100644
--- a/core/math/vector2.h
+++ b/core/math/vector2.h
@@ -230,7 +230,7 @@ Vector2 Vector2::linear_interpolate(const Vector2 &p_b, real_t p_t) const {
Vector2 Vector2::slerp(const Vector2 &p_b, real_t p_t) const {
#ifdef MATH_CHECKS
- ERR_FAIL_COND_V(is_normalized() == false, Vector2());
+ ERR_FAIL_COND_V(!is_normalized(), Vector2());
#endif
real_t theta = angle_to(p_b);
return rotated(theta * p_t);
diff --git a/core/math/vector3.h b/core/math/vector3.h
index 5302832eeb..16feba6a0c 100644
--- a/core/math/vector3.h
+++ b/core/math/vector3.h
@@ -218,7 +218,7 @@ Vector3 Vector3::linear_interpolate(const Vector3 &p_b, real_t p_t) const {
Vector3 Vector3::slerp(const Vector3 &p_b, real_t p_t) const {
#ifdef MATH_CHECKS
- ERR_FAIL_COND_V(is_normalized() == false, Vector3());
+ ERR_FAIL_COND_V(!is_normalized(), Vector3());
#endif
real_t theta = angle_to(p_b);
@@ -430,7 +430,7 @@ void Vector3::zero() {
// slide returns the component of the vector along the given plane, specified by its normal vector.
Vector3 Vector3::slide(const Vector3 &p_normal) const {
#ifdef MATH_CHECKS
- ERR_FAIL_COND_V(p_normal.is_normalized() == false, Vector3());
+ ERR_FAIL_COND_V(!p_normal.is_normalized(), Vector3());
#endif
return *this - p_normal * this->dot(p_normal);
}
@@ -441,7 +441,7 @@ Vector3 Vector3::bounce(const Vector3 &p_normal) const {
Vector3 Vector3::reflect(const Vector3 &p_normal) const {
#ifdef MATH_CHECKS
- ERR_FAIL_COND_V(p_normal.is_normalized() == false, Vector3());
+ ERR_FAIL_COND_V(!p_normal.is_normalized(), Vector3());
#endif
return 2.0 * p_normal * this->dot(p_normal) - *this;
}
diff --git a/core/os/input.cpp b/core/os/input.cpp
index 6830df7e81..4cd1f0b24a 100644
--- a/core/os/input.cpp
+++ b/core/os/input.cpp
@@ -42,7 +42,7 @@ Input *Input::get_singleton() {
}
void Input::set_mouse_mode(MouseMode p_mode) {
- ERR_FAIL_INDEX(p_mode, 4);
+ ERR_FAIL_INDEX((int)p_mode, 4);
OS::get_singleton()->set_mouse_mode((OS::MouseMode)p_mode);
}
diff --git a/core/os/memory.cpp b/core/os/memory.cpp
index 041371a6e2..f25e40ef78 100644
--- a/core/os/memory.cpp
+++ b/core/os/memory.cpp
@@ -172,9 +172,9 @@ void Memory::free_static(void *p_ptr, bool p_pad_align) {
if (prepad) {
mem -= PAD_ALIGN;
- uint64_t *s = (uint64_t *)mem;
#ifdef DEBUG_ENABLED
+ uint64_t *s = (uint64_t *)mem;
atomic_sub(&mem_usage, *s);
#endif
diff --git a/core/rid.h b/core/rid.h
index fbb3e443fc..81d5b45d21 100644
--- a/core/rid.h
+++ b/core/rid.h
@@ -118,7 +118,6 @@ protected:
p_rid._data->_owner = NULL;
}
-#
#endif
public:
diff --git a/core/typedefs.h b/core/typedefs.h
index 2b26bf08f7..5c15da9c2d 100644
--- a/core/typedefs.h
+++ b/core/typedefs.h
@@ -44,6 +44,7 @@
#define _MKSTR(m_x) _STR(m_x)
#endif
+//should always inline no matter what
#ifndef _ALWAYS_INLINE_
#if defined(__GNUC__) && (__GNUC__ >= 4)
@@ -58,10 +59,17 @@
#endif
+//should always inline, except in some cases because it makes debugging harder
#ifndef _FORCE_INLINE_
+
+#ifdef DISABLE_FORCED_INLINE
+#define _FORCE_INLINE_ inline
+#else
#define _FORCE_INLINE_ _ALWAYS_INLINE_
#endif
+#endif
+
//custom, gcc-safe offsetof, because gcc complains a lot.
template <class T>
T *_nullptr() {
diff --git a/core/ustring.cpp b/core/ustring.cpp
index e46896ca85..3f073b181f 100644
--- a/core/ustring.cpp
+++ b/core/ustring.cpp
@@ -1828,8 +1828,8 @@ static double built_in_strtod(const C *string, /* A decimal ASCII floating-point
int sign, expSign = false;
double fraction, dblExp;
const double *d;
- register const C *p;
- register int c;
+ const C *p;
+ int c;
int exp = 0; /* Exponent read from "EX" field. */
int fracExp = 0; /* Exponent that derives from the fractional
* part. Under normal circumstances, it is
diff --git a/core/variant.cpp b/core/variant.cpp
index 7d75c2243b..edbe66ba31 100644
--- a/core/variant.cpp
+++ b/core/variant.cpp
@@ -858,7 +858,7 @@ bool Variant::is_one() const {
// atomic types
case BOOL: {
- return _data._bool == true;
+ return _data._bool;
} break;
case INT: {
diff --git a/core/variant_op.cpp b/core/variant_op.cpp
index 9afc31a772..f230f12b5d 100644
--- a/core/variant_op.cpp
+++ b/core/variant_op.cpp
@@ -521,7 +521,7 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
const Dictionary *arr_a = reinterpret_cast<const Dictionary *>(p_a._data._mem);
const Dictionary *arr_b = reinterpret_cast<const Dictionary *>(p_b._data._mem);
- _RETURN((*arr_a == *arr_b) == false);
+ _RETURN(*arr_a != *arr_b);
}
CASE_TYPE(math, OP_NOT_EQUAL, ARRAY) {
@@ -3542,7 +3542,10 @@ void Variant::interpolate(const Variant &a, const Variant &b, float c, Variant &
case INT: {
int64_t va = a._data._int;
int64_t vb = b._data._int;
- r_dst = int((1.0 - c) * va + vb * c);
+ if (va != vb)
+ r_dst = int((1.0 - c) * va + vb * c);
+ else //avoid int casting issues
+ r_dst = a;
}
return;
case REAL: {
diff --git a/doc/classes/Animation.xml b/doc/classes/Animation.xml
index 74c6796b06..bb161cd87c 100644
--- a/doc/classes/Animation.xml
+++ b/doc/classes/Animation.xml
@@ -5,7 +5,16 @@
</brief_description>
<description>
An Animation resource contains data used to animate everything in the engine. Animations are divided into tracks, and each track must be linked to a node. The state of that node can be changed through time, by adding timed keys (events) to the track.
- Animations are just data containers, and must be added to odes such as an [AnimationPlayer] or [AnimationTreePlayer] to be played back.
+ [codeblock]
+ # This creates an animation that makes the node "Enemy" move to the right by
+ # 100 pixels in 1 second.
+ var animation = Animation.new()
+ var track_index = animation.add_track(Animation.TYPE_VALUE)
+ animation.track_set_path(track_index, "Enemy:position.x")
+ animation.track_insert_key(track_index, 0.0, 0)
+ animation.track_insert_key(track_index, 0.5, 100)
+ [/codeblock]
+ Animations are just data containers, and must be added to nodes such as an [AnimationPlayer] or [AnimationTreePlayer] to be played back.
</description>
<tutorials>
<link>http://docs.godotengine.org/en/3.0/tutorials/animation/index.html</link>
diff --git a/doc/classes/ArrayMesh.xml b/doc/classes/ArrayMesh.xml
index ed3d2d2205..7806cf4ce4 100644
--- a/doc/classes/ArrayMesh.xml
+++ b/doc/classes/ArrayMesh.xml
@@ -47,7 +47,7 @@
</argument>
<description>
Creates a new surface.
- Surfaces are created to be rendered using a "primitive", which may be PRIMITIVE_POINTS, PRIMITIVE_LINES, PRIMITIVE_LINE_STRIP, PRIMITIVE_LINE_LOOP, PRIMITIVE_TRIANGLES, PRIMITIVE_TRIANGLE_STRIP, PRIMITIVE_TRIANGLE_FAN. See [Mesh] for details. (As a note, when using indices, it is recommended to only use points, lines or triangles). [method get_surface_count] will become the surf_idx for this new surface.
+ Surfaces are created to be rendered using a "primitive", which may be PRIMITIVE_POINTS, PRIMITIVE_LINES, PRIMITIVE_LINE_STRIP, PRIMITIVE_LINE_LOOP, PRIMITIVE_TRIANGLES, PRIMITIVE_TRIANGLE_STRIP, PRIMITIVE_TRIANGLE_FAN. See [Mesh] for details. (As a note, when using indices, it is recommended to only use points, lines or triangles). [method Mesh.get_surface_count] will become the [code]surf_idx[/code] for this new surface.
The [code]arrays[/code] argument is an array of arrays. See [enum ArrayType] for the values used in this array. For example, [code]arrays[0][/code] is the array of vertices. That first vertex sub-array is always required; the others are optional. Adding an index array puts this function into "index mode" where the vertex and other arrays become the sources of data and the index array defines the vertex order. All sub-arrays must have the same length as the vertex array or be empty, except for [code]ARRAY_INDEX[/code] if it is used.
Adding an index array puts this function into "index mode" where the vertex and other arrays become the sources of data, and the index array defines the order of the vertices.
Godot uses clockwise winding order for front faces of triangle primitive modes.
diff --git a/doc/classes/AudioEffectBandLimitFilter.xml b/doc/classes/AudioEffectBandLimitFilter.xml
index 9eba806ad5..c9ddbd5b9a 100644
--- a/doc/classes/AudioEffectBandLimitFilter.xml
+++ b/doc/classes/AudioEffectBandLimitFilter.xml
@@ -4,7 +4,7 @@
Adds a band limit filter to the Audio Bus.
</brief_description>
<description>
- Limits the frequencies in a range around the [member cutoff_hz] and allows frequencies outside of this range to pass.
+ Limits the frequencies in a range around the [member AudioEffectFilter.cutoff_hz] and allows frequencies outside of this range to pass.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/AudioEffectBandPassFilter.xml b/doc/classes/AudioEffectBandPassFilter.xml
index 11aab3e86d..7f4c9f4632 100644
--- a/doc/classes/AudioEffectBandPassFilter.xml
+++ b/doc/classes/AudioEffectBandPassFilter.xml
@@ -4,7 +4,7 @@
Adds a band pass filter to the Audio Bus.
</brief_description>
<description>
- Attenuates the frequencies inside of a range around the [member cutoff_hz] and cuts frequencies outside of this band.
+ Attenuates the frequencies inside of a range around the [member AudioEffectFilter.cutoff_hz] and cuts frequencies outside of this band.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/AudioEffectHighPassFilter.xml b/doc/classes/AudioEffectHighPassFilter.xml
index 3d487fc783..6c97199cb9 100644
--- a/doc/classes/AudioEffectHighPassFilter.xml
+++ b/doc/classes/AudioEffectHighPassFilter.xml
@@ -4,7 +4,7 @@
Adds a high pass filter to the Audio Bus.
</brief_description>
<description>
- Cuts frequencies lower than the [member cutoff_hz] and allows higher frequencies to pass.
+ Cuts frequencies lower than the [member AudioEffectFilter.cutoff_hz] and allows higher frequencies to pass.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/AudioEffectLowPassFilter.xml b/doc/classes/AudioEffectLowPassFilter.xml
index 3facd8b665..7048a56e6c 100644
--- a/doc/classes/AudioEffectLowPassFilter.xml
+++ b/doc/classes/AudioEffectLowPassFilter.xml
@@ -4,7 +4,7 @@
Adds a low pass filter to the Audio Bus.
</brief_description>
<description>
- Cuts frequencies higher than the [member cutoff_hz] and allows lower frequencies to pass.
+ Cuts frequencies higher than the [member AudioEffectFilter.cutoff_hz] and allows lower frequencies to pass.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/AudioEffectNotchFilter.xml b/doc/classes/AudioEffectNotchFilter.xml
index 741931f262..0378934890 100644
--- a/doc/classes/AudioEffectNotchFilter.xml
+++ b/doc/classes/AudioEffectNotchFilter.xml
@@ -4,7 +4,7 @@
Adds a notch filter to the Audio Bus.
</brief_description>
<description>
- Attenuates frequencies in a narrow band around the [member cutoff_hz] and cuts frequencies outside of this range.
+ Attenuates frequencies in a narrow band around the [member AudioEffectFilter.cutoff_hz] and cuts frequencies outside of this range.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/CollisionShape.xml b/doc/classes/CollisionShape.xml
index 682c9340df..5639c14192 100644
--- a/doc/classes/CollisionShape.xml
+++ b/doc/classes/CollisionShape.xml
@@ -4,7 +4,7 @@
Node that represents collision shape data in 3D space.
</brief_description>
<description>
- Editor facility for creating and editing collision shapes in 3D space. You can use this node to represent all sorts of collision shapes, for example, add this to an [Area] to give it a detection shape, or add it to a [PhysicsBody] to create a solid object. [b]IMPORTANT[/b]: this is an Editor-only helper to create shapes, use [method get_shape] to get the actual shape.
+ Editor facility for creating and editing collision shapes in 3D space. You can use this node to represent all sorts of collision shapes, for example, add this to an [Area] to give it a detection shape, or add it to a [PhysicsBody] to create a solid object. [b]IMPORTANT[/b]: this is an Editor-only helper to create shapes, use [method CollisionObject.shape_owner_get_shape] to get the actual shape.
</description>
<tutorials>
<link>http://docs.godotengine.org/en/3.0/tutorials/physics/physics_introduction.html</link>
diff --git a/doc/classes/CollisionShape2D.xml b/doc/classes/CollisionShape2D.xml
index 3312fad99c..713cb8d098 100644
--- a/doc/classes/CollisionShape2D.xml
+++ b/doc/classes/CollisionShape2D.xml
@@ -4,7 +4,7 @@
Node that represents collision shape data in 2D space.
</brief_description>
<description>
- Editor facility for creating and editing collision shapes in 2D space. You can use this node to represent all sorts of collision shapes, for example, add this to an [Area2D] to give it a detection shape, or add it to a [PhysicsBody2D] to create a solid object. [b]IMPORTANT[/b]: this is an Editor-only helper to create shapes, use [method get_shape] to get the actual shape.
+ Editor facility for creating and editing collision shapes in 2D space. You can use this node to represent all sorts of collision shapes, for example, add this to an [Area2D] to give it a detection shape, or add it to a [PhysicsBody2D] to create a solid object. [b]IMPORTANT[/b]: this is an Editor-only helper to create shapes, use [method CollisionObject2D.shape_owner_get_shape] to get the actual shape.
</description>
<tutorials>
<link>http://docs.godotengine.org/en/3.0/tutorials/physics/physics_introduction.html</link>
diff --git a/doc/classes/Color.xml b/doc/classes/Color.xml
index 2e3cc2e5d1..82a10fbaa4 100644
--- a/doc/classes/Color.xml
+++ b/doc/classes/Color.xml
@@ -4,8 +4,8 @@
Color in RGBA format with some support for ARGB format.
</brief_description>
<description>
- A color is represented as red, green and blue (r,g,b) components. Additionally, "a" represents the alpha component, often used for transparency. Values are in floating point and usually range from 0 to 1. Some methods (such as set_modulate(color)) may accept values &gt; 1.
- You can also create a color from standardised color names with Color.ColorN (e.g. Color.green) or [method @GDScript.ColorN].
+ A color is represented by red, green, and blue [code](r, g, b)[/code] components. Additionally, [code]a[/code] represents the alpha component, often used for transparency. Values are in floating point and usually range from 0 to 1. Some properties (such as [member CanvasItem.modulate]) may accept values &gt; 1.
+ You can also create a color from standardized color names by using [method @GDScript.ColorN].
</description>
<tutorials>
</tutorials>
@@ -25,7 +25,7 @@
[code]"#ff00ff"[/code] - RGB format with '#'
[code]"ff00ff"[/code] - RGB format
[codeblock]
- # The following code creates the same color of an RGBA(178, 217, 10, 255)
+ # Each of the following creates the same color RGBA(178, 217, 10, 255)
var c1 = Color("#ffb2d90a") # ARGB format with '#'
var c2 = Color("ffb2d90a") # ARGB format
var c3 = Color("#b2d90a") # RGB format with '#'
@@ -41,7 +41,7 @@
<description>
Constructs a color from a 32-bit integer (each byte represents a component of the RGBA profile).
[codeblock]
- var c = Color(274) # a color of an RGBA(0, 0, 1, 18)
+ var c = Color(274) # Equivalent to RGBA(0, 0, 1, 18)
[/codeblock]
</description>
</method>
@@ -55,9 +55,9 @@
<argument index="2" name="b" type="float">
</argument>
<description>
- Constructs a color from an RGB profile using values between 0 and 1 (float). Alpha will always be 1.
+ Constructs a color from an RGB profile using values between 0 and 1. Alpha will always be 1.
[codeblock]
- var c = Color(0.2, 1.0, .7) # a color of an RGBA(51, 255, 178, 255)
+ var c = Color(0.2, 1.0, .7) # Equivalent to RGBA(51, 255, 178, 255)
[/codeblock]
</description>
</method>
@@ -73,9 +73,9 @@
<argument index="3" name="a" type="float">
</argument>
<description>
- Constructs a color from an RGBA profile using values between 0 and 1 (float).
+ Constructs a color from an RGBA profile using values between 0 and 1.
[codeblock]
- var c = Color(0.2, 1.0, .7, .8) # a color of an RGBA(51, 255, 178, 204)
+ var c = Color(0.2, 1.0, .7, .8) # Equivalent to RGBA(51, 255, 178, 204)
[/codeblock]
</description>
</method>
@@ -85,7 +85,7 @@
<argument index="0" name="over" type="Color">
</argument>
<description>
- Returns a new color resulting from blending this color over another color. If the color is opaque, the result would also be opaque. The other color could then take a range of values with different alpha values.
+ Returns a new color resulting from blending this color over another. If the color is opaque, the result is also opaque. The second color may have a range of alpha values.
[codeblock]
var bg = Color(0.0, 1.0, 0.0, 0.5) # Green with alpha of 50%
var fg = Color(1.0, 0.0, 0.0, .5) # Red with alpha of 50%
@@ -100,7 +100,7 @@
Returns the most contrasting color.
[codeblock]
var c = Color(.3, .4, .9)
- var contrastedColor = c.contrasted() # a color of an RGBA(204, 229, 102, 255)
+ var contrastedColor = c.contrasted() # Equivalent to RGBA(204, 229, 102, 255)
[/codeblock]
</description>
</method>
@@ -131,7 +131,7 @@
<description>
Constructs a color from an HSV profile. [code]h[/code], [code]s[/code], and [code]v[/code] are values between 0 and 1.
[codeblock]
- var c = Color.from_hsv(0.58, 0.5, 0.79, 0.8) # equivalent to HSV(210, 50, 79, 0.8) or Color8(100, 151, 201, 0.8)
+ var c = Color.from_hsv(0.58, 0.5, 0.79, 0.8) # Equivalent to HSV(210, 50, 79, 0.8) or Color8(100, 151, 201, 0.8)
[/codeblock]
</description>
</method>
@@ -139,8 +139,8 @@
<return type="float">
</return>
<description>
- Returns the color's grayscale.
- The gray is calculated by (r + g + b) / 3.
+ Returns the color's grayscale representation.
+ The gray is calculated by [code](r + g + b) / 3[/code].
[codeblock]
var c = Color(0.2, 0.45, 0.82)
var gray = c.gray() # a value of 0.466667
@@ -151,7 +151,7 @@
<return type="Color">
</return>
<description>
- Returns the inverted color (1-r, 1-g, 1-b, 1-a).
+ Returns the inverted color [code](1 - r, 1 - g, 1 - b, 1 - a)[/code].
[codeblock]
var c = Color(.3, .4, .9)
var invertedColor = c.inverted() # a color of an RGBA(178, 153, 26, 255)
@@ -179,7 +179,7 @@
<argument index="1" name="t" type="float">
</argument>
<description>
- Returns the color of the linear interpolation with another color. The value t is between 0 and 1 (float).
+ Returns the linear interpolation with another color. The value t is between 0 and 1.
[codeblock]
var c1 = Color(1.0, 0.0, 0.0)
var c2 = Color(0.0, 1.0, 0.0)
@@ -238,7 +238,7 @@
</argument>
<description>
Returns the color's HTML hexadecimal color string in ARGB format (ex: [code]ff34f822[/code]).
- Optionally flag 'false' to not include alpha in hexadecimal string.
+ Setting [code]with_alpha[/code] to [code]false[/code] excludes alpha from the hexadecimal string.
[codeblock]
var c = Color(1, 1, 1, .5)
var s1 = c.to_html() # Results "7fffffff"
@@ -250,7 +250,7 @@
<return type="int">
</return>
<description>
- Returns the color's 32-bit integer in RGBA format (each byte represents a component of the RGBA profile). RGBA is the format that Godot uses by default.
+ Returns the color's 32-bit integer in RGBA format (each byte represents a component of the RGBA profile). RGBA is Godot's default format.
[codeblock]
var c = Color(1, .5, .2)
print(c.to_rgba32()) # Prints 4286526463
@@ -261,7 +261,7 @@
<return type="int">
</return>
<description>
- Returns the color's 64-bit integer in RGBA format (each word represents a component of the RGBA profile). RGBA is the format that Godot uses by default.
+ Returns the color's 64-bit integer in RGBA format (each word represents a component of the RGBA profile). RGBA is Godot's default format.
[codeblock]
var c = Color(1, .5, .2)
print(c.to_rgba64()) # Prints -140736629309441
@@ -271,37 +271,37 @@
</methods>
<members>
<member name="a" type="float" setter="" getter="">
- Alpha (0 to 1)
+ Alpha value (range 0 to 1).
</member>
<member name="a8" type="int" setter="" getter="">
- Alpha (0 to 255)
+ Alpha value (range 0 to 255).
</member>
<member name="b" type="float" setter="" getter="">
- Blue (0 to 1)
+ Blue value (range 0 to 1).
</member>
<member name="b8" type="int" setter="" getter="">
- Blue (0 to 255)
+ Blue value (range 0 to 255).
</member>
<member name="g" type="float" setter="" getter="">
- Green (0 to 1)
+ Green value (range 0 to 1).
</member>
<member name="g8" type="int" setter="" getter="">
- Green (0 to 255)
+ Green value (range 0 to 255).
</member>
<member name="h" type="float" setter="" getter="">
- Hue (0 to 1)
+ HSV hue value (range 0 to 1).
</member>
<member name="r" type="float" setter="" getter="">
- Red (0 to 1)
+ Red value (range 0 to 1).
</member>
<member name="r8" type="int" setter="" getter="">
- Red (0 to 255)
+ Red value (range 0 to 255).
</member>
<member name="s" type="float" setter="" getter="">
- Saturation (0 to 1)
+ HSV saturation value (range 0 to 1).
</member>
<member name="v" type="float" setter="" getter="">
- Value (0 to 1)
+ HSV value (range 0 to 1).
</member>
</members>
<constants>
diff --git a/doc/classes/Control.xml b/doc/classes/Control.xml
index 1a27aea23f..ee82afd592 100644
--- a/doc/classes/Control.xml
+++ b/doc/classes/Control.xml
@@ -76,7 +76,7 @@
<argument index="1" name="constant" type="int">
</argument>
<description>
- Overrides an integer constant in the [member theme] resource the node uses. If the [code]constant[/code] is invalid, Godot clears the override. See [member Theme.INVALID_CONSTANT] for more information.
+ Overrides an integer constant in the [member theme] resource the node uses. If the [code]constant[/code] is invalid, Godot clears the override.
</description>
</method>
<method name="add_font_override">
diff --git a/doc/classes/Input.xml b/doc/classes/Input.xml
index 338d01ae5f..10ec15b99d 100644
--- a/doc/classes/Input.xml
+++ b/doc/classes/Input.xml
@@ -55,6 +55,7 @@
<argument index="0" name="action" type="String">
</argument>
<description>
+ Returns a value between 0 and 1 representing the intensity of the given action. In a joypad, for example, the further away the axis (analog sticks or L2, R2 triggers) is from the dead zone, the closer the value will be to 1. If the action is mapped to a control that has no axis as the keyboard, the value returned will be 0 or 1.
</description>
</method>
<method name="get_connected_joypads">
diff --git a/doc/classes/ItemList.xml b/doc/classes/ItemList.xml
index 38d32fe7c8..4e4947de6c 100644
--- a/doc/classes/ItemList.xml
+++ b/doc/classes/ItemList.xml
@@ -412,6 +412,7 @@
Fired when specified list item has been selected via right mouse clicking.
The click position is also provided to allow appropriate popup of context menus
at the correct location.
+ [member allow_rmb_select] must be enabled.
</description>
</signal>
<signal name="item_selected">
@@ -419,6 +420,7 @@
</argument>
<description>
Fired when specified item has been selected.
+ [member allow_reselect] must be enabled to reselect an item.
</description>
</signal>
<signal name="multi_selected">
diff --git a/doc/classes/KinematicBody.xml b/doc/classes/KinematicBody.xml
index 17310ab4dc..82638fc57a 100644
--- a/doc/classes/KinematicBody.xml
+++ b/doc/classes/KinematicBody.xml
@@ -69,7 +69,7 @@
</argument>
<description>
Moves the body along the vector [code]rel_vec[/code]. The body will stop if it collides. Returns a [KinematicCollision], which contains information about the collision.
- If [code]test_only[/code] is [code]true[/true], the body does not move but the would-be collision information is given.
+ If [code]test_only[/code] is [code]true[/code], the body does not move but the would-be collision information is given.
</description>
</method>
<method name="move_and_slide">
diff --git a/doc/classes/Node.xml b/doc/classes/Node.xml
index 90e9436307..a33ee5c363 100644
--- a/doc/classes/Node.xml
+++ b/doc/classes/Node.xml
@@ -12,7 +12,7 @@
[b]Processing:[/b] Nodes can override the "process" state, so that they receive a callback on each frame requesting them to process (do something). Normal processing (callback [method _process], toggled with [method set_process]) happens as fast as possible and is dependent on the frame rate, so the processing time [i]delta[/i] is passed as an argument. Physics processing (callback [method _physics_process], toggled with [method set_physics_process]) happens a fixed number of times per second (60 by default) and is useful for code related to the physics engine.
Nodes can also process input events. When present, the [method _input] function will be called for each input that the program receives. In many cases, this can be overkill (unless used for simple projects), and the [method _unhandled_input] function might be preferred; it is called when the input event was not handled by anyone else (typically, GUI [Control] nodes), ensuring that the node only receives the events that were meant for it.
To keep track of the scene hierarchy (especially when instancing scenes into other scenes), an "owner" can be set for the node with [method set_owner]. This keeps track of who instanced what. This is mostly useful when writing editors and tools, though.
- Finally, when a node is freed with [method free] or [method queue_free], it will also free all its children.
+ Finally, when a node is freed with [method Object.free] or [method queue_free], it will also free all its children.
[b]Groups:[/b] Nodes can be added to as many groups as you want to be easy to manage, you could create groups like "enemies" or "collectables" for example, depending on your game. See [method add_to_group], [method is_in_group] and [method remove_from_group]. You can then retrieve all nodes in these groups, iterate them and even call methods on groups via the methods on [SceneTree].
[b]Networking with nodes:[/b] After connecting to a server (or making one, see [NetworkedMultiplayerENet]) it is possible to use the built-in RPC (remote procedure call) system to communicate over the network. By calling [method rpc] with a method name, it will be called locally and in all connected peers (peers = clients and the server that accepts connections). To identify which node receives the RPC call Godot will use its [NodePath] (make sure node names are the same on all peers). Also take a look at the high-level networking tutorial and corresponding demos.
</description>
@@ -176,6 +176,7 @@
</argument>
<description>
Finds a descendant of this node whose name matches [code]mask[/code] as in [method String.match] (i.e. case sensitive, but '*' matches zero or more characters and '?' matches any single character except '.'). Note that it does not match against the full path, just against individual node names.
+ If [code]owned[/code] is [code]true[/code], this method only finds nodes whose owner is this node. This is especially important for scenes instantiated through script, because those scenes don't have an owner.
</description>
</method>
<method name="get_child" qualifiers="const">
diff --git a/doc/classes/OS.xml b/doc/classes/OS.xml
index dad4ce898d..26684836ea 100644
--- a/doc/classes/OS.xml
+++ b/doc/classes/OS.xml
@@ -583,6 +583,7 @@
</argument>
<description>
Plays native video from the specified path, at the given volume and with audio and subtitle tracks.
+ Note: This method is only implemented on Android and iOS, and the current Android implementation does not support the [code]volume[/code], [code]audio_track[/code] and [code]subtitle_track[/code] options.
</description>
</method>
<method name="native_video_stop">
diff --git a/doc/classes/PackedScene.xml b/doc/classes/PackedScene.xml
index 0d58e61c3a..08df3f0ad6 100644
--- a/doc/classes/PackedScene.xml
+++ b/doc/classes/PackedScene.xml
@@ -39,7 +39,7 @@
<argument index="0" name="edit_state" type="int" enum="PackedScene.GenEditState" default="0">
</argument>
<description>
- Instantiates the scene's node hierarchy. Triggers child scene instantiation(s). Triggers the [enum Object.NOTIFICATION_INSTANCED] notification on the root node.
+ Instantiates the scene's node hierarchy. Triggers child scene instantiation(s). Triggers the [enum Node.NOTIFICATION_INSTANCED] notification on the root node.
</description>
</method>
<method name="pack">
diff --git a/doc/classes/ParallaxLayer.xml b/doc/classes/ParallaxLayer.xml
index 662a15e043..e6ea166282 100644
--- a/doc/classes/ParallaxLayer.xml
+++ b/doc/classes/ParallaxLayer.xml
@@ -6,6 +6,7 @@
<description>
A ParallaxLayer must be the child of a [ParallaxBackground] node. Each ParallaxLayer can be set to move at different speeds relative to the camera movement or the [member ParallaxBackground.scroll_offset] value.
This node's children will be affected by its scroll offset.
+ Note that any changes to this node's position and scale made after it enters the scene will be ignored.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/RigidBody.xml b/doc/classes/RigidBody.xml
index f9e0f821a9..0977b7ea01 100644
--- a/doc/classes/RigidBody.xml
+++ b/doc/classes/RigidBody.xml
@@ -60,8 +60,8 @@
<argument index="0" name="impulse" type="Vector3">
</argument>
<description>
- Applies a single directional impulse without affecting rotation.
- This is equivalent to ``apply_impulse(Vector3(0,0,0), impulse)``.
+ Applies a directional impulse without affecting rotation.
+ This is equivalent to [code]apply_impulse(Vector3(0,0,0), impulse)[/code].
</description>
</method>
<method name="apply_impulse">
@@ -72,7 +72,7 @@
<argument index="1" name="impulse" type="Vector3">
</argument>
<description>
- Apply a positioned impulse (which will be affected by the body mass and shape). This is the equivalent of hitting a billiard ball with a cue: a force that is applied once, and only once. Both the impulse and the position are in global coordinates, and the position is relative to the object's origin.
+ Applies a positioned impulse which will be affected by the body mass and shape. This is the equivalent of hitting a billiard ball with a cue: a force that is applied once, and only once. Both the impulse and the position are in global coordinates, and the position is relative to the object's origin.
</description>
</method>
<method name="apply_torque_impulse">
@@ -81,14 +81,14 @@
<argument index="0" name="impulse" type="Vector3">
</argument>
<description>
- Apply a torque impulse (which will be affected by the body mass and shape). This will rotate the body around the passed in vector.
+ Applies a torque impulse which will be affected by the body mass and shape. This will rotate the body around the passed in vector.
</description>
</method>
<method name="get_colliding_bodies" qualifiers="const">
<return type="Array">
</return>
<description>
- Return a list of the bodies colliding with this one. By default, number of max contacts reported is at 0 , see [method set_max_contacts_reported] to increase it. Note that the result of this test is not immediate after moving objects. For performance, list of collisions is updated once per frame and before the physics step. Consider using signals instead.
+ Return a list of the bodies colliding with this one. By default, number of max contacts reported is at 0 , see [method set_max_contacts_reported] to increase it. Note that the result of this test is not immediate after moving objects. For performance, list of collisions is updated once per frame and before the physics step. Consider using signals instead.
</description>
</method>
<method name="set_axis_velocity">
@@ -97,7 +97,7 @@
<argument index="0" name="axis_velocity" type="Vector3">
</argument>
<description>
- Set an axis velocity. The velocity in the given vector axis will be set as the given vector length. This is useful for jumping behavior.
+ Sets an axis velocity. The velocity in the given vector axis will be set as the given vector length. This is useful for jumping behavior.
</description>
</method>
</methods>
@@ -109,16 +109,22 @@
RigidBody's rotational velocity.
</member>
<member name="axis_lock_angular_x" type="bool" setter="set_axis_lock" getter="get_axis_lock">
+ Lock the body's rotation in the x-axis.
</member>
<member name="axis_lock_angular_y" type="bool" setter="set_axis_lock" getter="get_axis_lock">
+ Lock the body's rotation in the y-axis.
</member>
<member name="axis_lock_angular_z" type="bool" setter="set_axis_lock" getter="get_axis_lock">
+ Lock the body's rotation in the z-axis.
</member>
<member name="axis_lock_linear_x" type="bool" setter="set_axis_lock" getter="get_axis_lock">
+ Lock the body's movement in the x-axis.
</member>
<member name="axis_lock_linear_y" type="bool" setter="set_axis_lock" getter="get_axis_lock">
+ Lock the body's movement in the x-axis.
</member>
<member name="axis_lock_linear_z" type="bool" setter="set_axis_lock" getter="get_axis_lock">
+ Lock the body's movement in the x-axis.
</member>
<member name="bounce" type="float" setter="set_bounce" getter="get_bounce">
RigidBody's bounciness.
@@ -127,7 +133,7 @@
If [code]true[/code] the RigidBody will not calculate forces and will act as a static body while there is no movement. It will wake up when forces are applied through other collisions or when the [code]apply_impulse[/code] method is used.
</member>
<member name="contact_monitor" type="bool" setter="set_contact_monitor" getter="is_contact_monitor_enabled">
- If true, the RigidBody will emit signals when it collides with another RigidBody.
+ If [code]true[/code] the RigidBody will emit signals when it collides with another RigidBody.
</member>
<member name="contacts_reported" type="int" setter="set_max_contacts_reported" getter="get_max_contacts_reported">
The maximum contacts to report. Bodies can keep a log of the contacts with other bodies, this is enabled by setting the maximum amount of contacts reported to a number greater than 0.
@@ -140,19 +146,19 @@
If [code]true[/code] internal force integration will be disabled (like gravity or air friction) for this body. Other than collision response, the body will only move as determined by the [method _integrate_forces] function, if defined.
</member>
<member name="friction" type="float" setter="set_friction" getter="get_friction">
- The body friction, from 0 (frictionless) to 1 (max friction).
+ The body's friction, from 0 (frictionless) to 1 (max friction).
</member>
<member name="gravity_scale" type="float" setter="set_gravity_scale" getter="get_gravity_scale">
This is multiplied by the global 3D gravity setting found in "Project &gt; Project Settings &gt; Physics &gt; 3d" to produce RigidBody's gravity. E.g. a value of 1 will be normal gravity, 2 will apply double gravity, and 0.5 will apply half gravity to this object.
</member>
<member name="linear_damp" type="float" setter="set_linear_damp" getter="get_linear_damp">
- RigidBody's linear damp. Default value: -1, cannot be less than -1. If this value is different from -1, any linear damp derived from the world or areas will be overridden.
+ The body's linear damp. Default value: -1, cannot be less than -1. If this value is different from -1, any linear damp derived from the world or areas will be overridden.
</member>
<member name="linear_velocity" type="Vector3" setter="set_linear_velocity" getter="get_linear_velocity">
- RigidBody's linear velocity. Can be used sporadically, but [b]DON'T SET THIS IN EVERY FRAME[/b], because physics may run in another thread and runs at a different granularity. Use [method _integrate_forces] as your process loop for precise control of the body state.
+ The body's linear velocity. Can be used sporadically, but [b]DON'T SET THIS IN EVERY FRAME[/b], because physics may run in another thread and runs at a different granularity. Use [method _integrate_forces] as your process loop for precise control of the body state.
</member>
<member name="mass" type="float" setter="set_mass" getter="get_mass">
- RigidBody's mass.
+ The body's mass.
</member>
<member name="mode" type="int" setter="set_mode" getter="get_mode" enum="RigidBody.Mode">
The body mode from the MODE_* enum. Modes include: MODE_STATIC, MODE_KINEMATIC, MODE_RIGID, and MODE_CHARACTER.
@@ -160,10 +166,10 @@
<member name="physics_material_override" type="PhysicsMaterial" setter="set_physics_material_override" getter="get_physics_material_override">
</member>
<member name="sleeping" type="bool" setter="set_sleeping" getter="is_sleeping">
- If [code]true[/code] RigidBody is sleeping and will not calculate forces until woken up by a collision or the [code]apply_impulse[/code] method.
+ If [code]true[/code] the body is sleeping and will not calculate forces until woken up by a collision or the [code]apply_impulse[/code] method.
</member>
<member name="weight" type="float" setter="set_weight" getter="get_weight">
- RigidBody's weight based on its mass and the global 3D gravity. Global values are set in "Project &gt; Project Settings &gt; Physics &gt; 3d".
+ The body's weight based on its mass and the global 3D gravity. Global values are set in "Project &gt; Project Settings &gt; Physics &gt; 3d".
</member>
</members>
<signals>
@@ -217,16 +223,16 @@
</signals>
<constants>
<constant name="MODE_RIGID" value="0" enum="Mode">
- Rigid body. This is the "natural" state of a rigid body. It is affected by forces, and can move, rotate, and be affected by user code.
+ Rigid body mode. This is the "natural" state of a rigid body. It is affected by forces, and can move, rotate, and be affected by user code.
</constant>
<constant name="MODE_STATIC" value="1" enum="Mode">
Static mode. The body behaves like a [StaticBody], and can only move by user code.
</constant>
<constant name="MODE_CHARACTER" value="2" enum="Mode">
- Character body. This behaves like a rigid body, but can not rotate.
+ Character body mode. This behaves like a rigid body, but can not rotate.
</constant>
<constant name="MODE_KINEMATIC" value="3" enum="Mode">
- Kinematic body. The body behaves like a [KinematicBody], and can only move by user code.
+ Kinematic body mode. The body behaves like a [KinematicBody], and can only move by user code.
</constant>
</constants>
</class>
diff --git a/doc/classes/RigidBody2D.xml b/doc/classes/RigidBody2D.xml
index 1f6b3934c2..079440ab8b 100644
--- a/doc/classes/RigidBody2D.xml
+++ b/doc/classes/RigidBody2D.xml
@@ -29,6 +29,7 @@
<argument index="0" name="force" type="Vector2">
</argument>
<description>
+ Adds a constant directional force without affecting rotation.
</description>
</method>
<method name="add_force">
@@ -48,6 +49,7 @@
<argument index="0" name="torque" type="float">
</argument>
<description>
+ Adds a constant rotational force.
</description>
</method>
<method name="apply_central_impulse">
@@ -56,6 +58,7 @@
<argument index="0" name="impulse" type="Vector2">
</argument>
<description>
+ Applies a directional impulse without affecting rotation.
</description>
</method>
<method name="apply_impulse">
@@ -75,6 +78,7 @@
<argument index="0" name="torque" type="float">
</argument>
<description>
+ Applies a rotational impulse to the body.
</description>
</method>
<method name="get_colliding_bodies" qualifiers="const">
diff --git a/doc/classes/SpatialMaterial.xml b/doc/classes/SpatialMaterial.xml
index 354c6686bb..57fb267e91 100644
--- a/doc/classes/SpatialMaterial.xml
+++ b/doc/classes/SpatialMaterial.xml
@@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="SpatialMaterial" inherits="Material" category="Core" version="3.1">
<brief_description>
+ Default 3D rendering material.
</brief_description>
<description>
+ This provides a default material with a wide variety of rendering features and properties without the need to write shader code. See the tutorial below for details.
</description>
<tutorials>
<link>http://docs.godotengine.org/en/3.0/tutorials/3d/spatial_material.html</link>
@@ -13,16 +15,20 @@
</methods>
<members>
<member name="albedo_color" type="Color" setter="set_albedo" getter="get_albedo">
+ The material's base color.
</member>
<member name="albedo_texture" type="Texture" setter="set_texture" getter="get_texture">
</member>
<member name="anisotropy" type="float" setter="set_anisotropy" getter="get_anisotropy">
+ The strength of the anisotropy effect.
</member>
<member name="anisotropy_enabled" type="bool" setter="set_feature" getter="get_feature">
+ If [code]true[/code] anisotropy is enabled. Changes the shape of the specular blob and aligns it to tangent space. Default value: [code]false[/code].
</member>
<member name="anisotropy_flowmap" type="Texture" setter="set_texture" getter="get_texture">
</member>
<member name="ao_enabled" type="bool" setter="set_feature" getter="get_feature">
+ If [code]true[/code] ambient occlusion is enabled.
</member>
<member name="ao_light_affect" type="float" setter="set_ao_light_affect" getter="get_ao_light_affect">
</member>
@@ -35,6 +41,7 @@
<member name="clearcoat" type="float" setter="set_clearcoat" getter="get_clearcoat">
</member>
<member name="clearcoat_enabled" type="bool" setter="set_feature" getter="get_feature">
+ If [code]true[/code] clearcoat rendering is enabled. Adds a secondary transparent pass to the material. Default value: [code]false[/code].
</member>
<member name="clearcoat_gloss" type="float" setter="set_clearcoat_gloss" getter="get_clearcoat_gloss">
</member>
@@ -43,6 +50,7 @@
<member name="depth_deep_parallax" type="bool" setter="set_depth_deep_parallax" getter="is_depth_deep_parallax_enabled">
</member>
<member name="depth_enabled" type="bool" setter="set_feature" getter="get_feature">
+ If [code]true[/code] Depth mapping is enabled. See also [member normal_enabled].
</member>
<member name="depth_max_layers" type="int" setter="set_depth_deep_parallax_max_layers" getter="get_depth_deep_parallax_max_layers">
</member>
@@ -71,10 +79,13 @@
<member name="distance_fade_mode" type="int" setter="set_distance_fade" getter="get_distance_fade" enum="SpatialMaterial.DistanceFadeMode">
</member>
<member name="emission" type="Color" setter="set_emission" getter="get_emission">
+ The emitted light's color. See [member emission_enabled].
</member>
<member name="emission_enabled" type="bool" setter="set_feature" getter="get_feature">
+ If [code]true[/code] the body emits light.
</member>
<member name="emission_energy" type="float" setter="set_emission_energy" getter="get_emission_energy">
+ The emitted light's strength. See [member emission_enabled].
</member>
<member name="emission_on_uv2" type="bool" setter="set_flag" getter="get_flag">
</member>
@@ -85,36 +96,49 @@
<member name="flags_albedo_tex_force_srgb" type="bool" setter="set_flag" getter="get_flag">
</member>
<member name="flags_disable_ambient_light" type="bool" setter="set_flag" getter="get_flag">
+ If [code]true[/code] the object receives no ambient light. Default value: [code]false[/code].
</member>
<member name="flags_do_not_receive_shadows" type="bool" setter="set_flag" getter="get_flag">
+ If [code]true[/code] the object receives no shadow that would otherwise be cast onto it. Default value: [code]false[/code].
</member>
<member name="flags_ensure_correct_normals" type="bool" setter="set_flag" getter="get_flag">
</member>
<member name="flags_fixed_size" type="bool" setter="set_flag" getter="get_flag">
+ If [code]true[/code] the object is rendered at the same size regardless of distance. Default value: [code]false[/code].
</member>
<member name="flags_no_depth_test" type="bool" setter="set_flag" getter="get_flag">
+ If [code]true[/code] depth testing is disabled and the object will be drawn in render order.
</member>
<member name="flags_transparent" type="bool" setter="set_feature" getter="get_feature">
+ If [code]true[/code] transparency is enabled on the body. Default value: [code]false[/code]. See also [member params_blend_mode].
</member>
<member name="flags_unshaded" type="bool" setter="set_flag" getter="get_flag">
+ If [code]true[/code] the object is unaffected by lighting. Default value: [code]false[/code].
</member>
<member name="flags_use_point_size" type="bool" setter="set_flag" getter="get_flag">
+ If [code]true[/code] render point size can be changed. Note: this is only effective for objects whose geometry is point-based rather than triangle-based. See also [member params_point_size].
</member>
<member name="flags_vertex_lighting" type="bool" setter="set_flag" getter="get_flag">
+ If [code]true[/code] lighting is calculated per vertex rather than per pixel. This may increase performance on low-end devices. Default value: [code]false[/code].
</member>
<member name="flags_world_triplanar" type="bool" setter="set_flag" getter="get_flag">
+ If [code]true[/code] triplanar mapping is calculated in world space rather than object local space. See also [member uv1_triplanar]. Default value: [code]false[/code].
</member>
<member name="metallic" type="float" setter="set_metallic" getter="get_metallic">
+ The reflectivity of the object's surface. The higher the value the more light is reflected.
</member>
<member name="metallic_specular" type="float" setter="set_specular" getter="get_specular">
+ General reflectivity amount. Note: unlike [member metallic], this is not energy-conserving, so it should be left at [code]0.5[/code] in most cases. See also [member roughness].
</member>
<member name="metallic_texture" type="Texture" setter="set_texture" getter="get_texture">
</member>
<member name="metallic_texture_channel" type="int" setter="set_metallic_texture_channel" getter="get_metallic_texture_channel" enum="SpatialMaterial.TextureChannel">
</member>
<member name="normal_enabled" type="bool" setter="set_feature" getter="get_feature">
+ If [code]true[/code] normal mapping is enabled.
</member>
<member name="normal_scale" type="float" setter="set_normal_scale" getter="get_normal_scale">
+ The strength of the normal map's effect.
</member>
<member name="normal_texture" type="Texture" setter="set_texture" getter="get_texture">
</member>
@@ -123,40 +147,55 @@
<member name="params_billboard_keep_scale" type="bool" setter="set_flag" getter="get_flag">
</member>
<member name="params_billboard_mode" type="int" setter="set_billboard_mode" getter="get_billboard_mode" enum="SpatialMaterial.BillboardMode">
+ Controls how the object faces the camera. See [enum BillboardMode].
</member>
<member name="params_blend_mode" type="int" setter="set_blend_mode" getter="get_blend_mode" enum="SpatialMaterial.BlendMode">
+ The material's blend mode. Note that values other than [code]Mix[/code] force the object into the transparent pipeline. See [enum BlendMode].
</member>
<member name="params_cull_mode" type="int" setter="set_cull_mode" getter="get_cull_mode" enum="SpatialMaterial.CullMode">
+ Which side of the object is not drawn when backfaces are rendered. See [enum CullMode].
</member>
<member name="params_depth_draw_mode" type="int" setter="set_depth_draw_mode" getter="get_depth_draw_mode" enum="SpatialMaterial.DepthDrawMode">
+ Determines when depth rendering takes place. See [enum DepthDrawMode]. See also [member flags_transparent].
</member>
<member name="params_diffuse_mode" type="int" setter="set_diffuse_mode" getter="get_diffuse_mode" enum="SpatialMaterial.DiffuseMode">
+ The algorithm used for diffuse light scattering. See [enum DiffuseMode].
</member>
<member name="params_grow" type="bool" setter="set_grow_enabled" getter="is_grow_enabled">
+ If [code]true[/code] enables the vertex grow setting. See [member params_grow_amount].
</member>
<member name="params_grow_amount" type="float" setter="set_grow" getter="get_grow">
+ Grows object vertices in the direction of their normals.
</member>
<member name="params_line_width" type="float" setter="set_line_width" getter="get_line_width">
</member>
<member name="params_point_size" type="float" setter="set_point_size" getter="get_point_size">
+ The point size in pixels. See [member flags_use_point_size].
</member>
<member name="params_specular_mode" type="int" setter="set_specular_mode" getter="get_specular_mode" enum="SpatialMaterial.SpecularMode">
+ The method for rendering the specular blob. See [enum SpecularMode].
</member>
<member name="params_use_alpha_scissor" type="bool" setter="set_flag" getter="get_flag">
</member>
<member name="particles_anim_h_frames" type="int" setter="set_particles_anim_h_frames" getter="get_particles_anim_h_frames">
+ The number of horizontal frames in the particle spritesheet. Only enabled when using [code]BillboardMode.BILLBOARD_PARTICLES[/code]. See [member params_billboard_mode].
</member>
<member name="particles_anim_loop" type="int" setter="set_particles_anim_loop" getter="get_particles_anim_loop">
+ If [code]true[/code] particle animations are looped. Only enabled when using [code]BillboardMode.BILLBOARD_PARTICLES[/code]. See [member params_billboard_mode].
</member>
<member name="particles_anim_v_frames" type="int" setter="set_particles_anim_v_frames" getter="get_particles_anim_v_frames">
+ The number of vertical frames in the particle spritesheet. Only enabled when using [code]BillboardMode.BILLBOARD_PARTICLES[/code]. See [member params_billboard_mode].
</member>
<member name="proximity_fade_distance" type="float" setter="set_proximity_fade_distance" getter="get_proximity_fade_distance">
</member>
<member name="proximity_fade_enable" type="bool" setter="set_proximity_fade" getter="is_proximity_fade_enabled">
+ If [code]true[/code] the proximity and distance fade effect is enabled. Default value: [code]false[/code].
</member>
<member name="refraction_enabled" type="bool" setter="set_feature" getter="get_feature">
+ If [code]true[/code] the refraction effect is enabled. Distorts transparency based on light from behind the object. Default value: [code]false[/code].
</member>
<member name="refraction_scale" type="float" setter="set_refraction" getter="get_refraction">
+ The strength of the refraction effect.
</member>
<member name="refraction_texture" type="Texture" setter="set_texture" getter="get_texture">
</member>
@@ -165,26 +204,33 @@
<member name="rim" type="float" setter="set_rim" getter="get_rim">
</member>
<member name="rim_enabled" type="bool" setter="set_feature" getter="get_feature">
+ If [code]true[/code] rim effect is enabled. Default value: [code]false[/code].
</member>
<member name="rim_texture" type="Texture" setter="set_texture" getter="get_texture">
</member>
<member name="rim_tint" type="float" setter="set_rim_tint" getter="get_rim_tint">
+ The amount of to blend light and albedo color when rendering rim effect. If [code]0[/code] the light color is used, while [code]1[/code] means albedo color is used. An intermediate value generally works best.
</member>
<member name="roughness" type="float" setter="set_roughness" getter="get_roughness">
+ Surface reflection. A value of [code]0[/code] represents a perfect mirror while a value of [code]1[/code] completely blurs the reflection. See also [member metallic].
</member>
<member name="roughness_texture" type="Texture" setter="set_texture" getter="get_texture">
</member>
<member name="roughness_texture_channel" type="int" setter="set_roughness_texture_channel" getter="get_roughness_texture_channel" enum="SpatialMaterial.TextureChannel">
</member>
<member name="subsurf_scatter_enabled" type="bool" setter="set_feature" getter="get_feature">
+ If [code]true[/code] subsurface scattering is enabled. Emulates light that penetrates an object's surface, is scattered, and then emerges.
</member>
<member name="subsurf_scatter_strength" type="float" setter="set_subsurface_scattering_strength" getter="get_subsurface_scattering_strength">
+ The strength of the subsurface scattering effect.
</member>
<member name="subsurf_scatter_texture" type="Texture" setter="set_texture" getter="get_texture">
</member>
<member name="transmission" type="Color" setter="set_transmission" getter="get_transmission">
+ The color used by the transmission effect. Represents the light passing through an object.
</member>
<member name="transmission_enabled" type="bool" setter="set_feature" getter="get_feature">
+ If [code]true[/code] the transmission effect is enabled. Default value: [code]false[/code].
</member>
<member name="transmission_texture" type="Texture" setter="set_texture" getter="get_texture">
</member>
@@ -205,8 +251,10 @@
<member name="uv2_triplanar_sharpness" type="float" setter="set_uv2_triplanar_blend_sharpness" getter="get_uv2_triplanar_blend_sharpness">
</member>
<member name="vertex_color_is_srgb" type="bool" setter="set_flag" getter="get_flag">
+ If [code]true[/code] the model's vertex colors are processed as sRGB mode. Default value: [code]false[/code].
</member>
<member name="vertex_color_use_as_albedo" type="bool" setter="set_flag" getter="get_flag">
+ If [code]true[/code] the vertex color is used as albedo color. Default value: [code]false[/code].
</member>
</members>
<constants>
@@ -275,6 +323,7 @@
<constant name="FEATURE_MAX" value="12" enum="Feature">
</constant>
<constant name="BLEND_MODE_MIX" value="0" enum="BlendMode">
+ Default blend mode.
</constant>
<constant name="BLEND_MODE_ADD" value="1" enum="BlendMode">
</constant>
@@ -283,18 +332,25 @@
<constant name="BLEND_MODE_MUL" value="3" enum="BlendMode">
</constant>
<constant name="DEPTH_DRAW_OPAQUE_ONLY" value="0" enum="DepthDrawMode">
+ Default depth draw mode. Depth is drawn only for opaque objects.
</constant>
<constant name="DEPTH_DRAW_ALWAYS" value="1" enum="DepthDrawMode">
+ Depth draw is calculated for both opaque and transparent objects.
</constant>
<constant name="DEPTH_DRAW_DISABLED" value="2" enum="DepthDrawMode">
+ No depth draw.
</constant>
<constant name="DEPTH_DRAW_ALPHA_OPAQUE_PREPASS" value="3" enum="DepthDrawMode">
+ For transparent objects, an opaque pass is made first with the opaque parts, then transparency is drawn.
</constant>
<constant name="CULL_BACK" value="0" enum="CullMode">
+ Default cull mode. The back of the object is culled when not visible.
</constant>
<constant name="CULL_FRONT" value="1" enum="CullMode">
+ The front of the object is culled when not visible.
</constant>
<constant name="CULL_DISABLED" value="2" enum="CullMode">
+ No culling is performed.
</constant>
<constant name="FLAG_UNSHADED" value="0" enum="Flags">
</constant>
@@ -335,32 +391,46 @@
<constant name="FLAG_MAX" value="18" enum="Flags">
</constant>
<constant name="DIFFUSE_BURLEY" value="0" enum="DiffuseMode">
+ Default diffuse scattering algorithm.
</constant>
<constant name="DIFFUSE_LAMBERT" value="1" enum="DiffuseMode">
+ Diffuse scattering ignores roughness.
</constant>
<constant name="DIFFUSE_LAMBERT_WRAP" value="2" enum="DiffuseMode">
+ Extends Lambert to cover more than 90 degrees when roughness increases.
</constant>
<constant name="DIFFUSE_OREN_NAYAR" value="3" enum="DiffuseMode">
+ Attempts to use roughness to emulate microsurfacing.
</constant>
<constant name="DIFFUSE_TOON" value="4" enum="DiffuseMode">
+ Uses a hard cut for lighting, with smoothing affected by roughness.
</constant>
<constant name="SPECULAR_SCHLICK_GGX" value="0" enum="SpecularMode">
+ Default specular blob.
</constant>
<constant name="SPECULAR_BLINN" value="1" enum="SpecularMode">
+ Older specular algorithm, included for compatibility.
</constant>
<constant name="SPECULAR_PHONG" value="2" enum="SpecularMode">
+ Older specular algorithm, included for compatibility.
</constant>
<constant name="SPECULAR_TOON" value="3" enum="SpecularMode">
+ Toon blob which changes size based on roughness.
</constant>
<constant name="SPECULAR_DISABLED" value="4" enum="SpecularMode">
+ No specular blob.
</constant>
<constant name="BILLBOARD_DISABLED" value="0" enum="BillboardMode">
+ Default value.
</constant>
<constant name="BILLBOARD_ENABLED" value="1" enum="BillboardMode">
+ The object's z-axis will always face the camera.
</constant>
<constant name="BILLBOARD_FIXED_Y" value="2" enum="BillboardMode">
+ The object's x-axis will always face the camera.
</constant>
<constant name="BILLBOARD_PARTICLES" value="3" enum="BillboardMode">
+ Used for particle systems. Enables particle animation options.
</constant>
<constant name="TEXTURE_CHANNEL_RED" value="0" enum="TextureChannel">
</constant>
diff --git a/doc/classes/TextureProgress.xml b/doc/classes/TextureProgress.xml
index f74420e8b1..3cbaf0429c 100644
--- a/doc/classes/TextureProgress.xml
+++ b/doc/classes/TextureProgress.xml
@@ -52,10 +52,13 @@
[Texture] that draws under the progress bar. The bar's background.
</member>
<member name="tint_over" type="Color" setter="set_tint_over" getter="get_tint_over">
+ Multiplies the color of the bar's [code]texture_over[/code] texture. The effect is similar to [member CanvasItem.modulate], except it only affects this specific texture instead of the entire node.
</member>
<member name="tint_progress" type="Color" setter="set_tint_progress" getter="get_tint_progress">
+ Multiplies the color of the bar's [code]texture_progress[/code] texture.
</member>
<member name="tint_under" type="Color" setter="set_tint_under" getter="get_tint_under">
+ Multiplies the color of the bar's [code]texture_under[/code] texture.
</member>
</members>
<constants>
@@ -72,16 +75,19 @@
The [member texture_progress] fills from bottom to top.
</constant>
<constant name="FILL_CLOCKWISE" value="4" enum="FillMode">
- Turns the node into a radial bar. The [member texture_progress] fills clockwise. See [member radial_center_offset], [member radial_initial_angle] and [member radial_fill_degrees] to refine its behavior.
+ Turns the node into a radial bar. The [member texture_progress] fills clockwise. See [member radial_center_offset], [member radial_initial_angle] and [member radial_fill_degrees] to control the way the bar fills up.
</constant>
<constant name="FILL_COUNTER_CLOCKWISE" value="5" enum="FillMode">
- Turns the node into a radial bar. The [member texture_progress] fills counter-clockwise. See [member radial_center_offset], [member radial_initial_angle] and [member radial_fill_degrees] to refine its behavior.
+ Turns the node into a radial bar. The [member texture_progress] fills counter-clockwise. See [member radial_center_offset], [member radial_initial_angle] and [member radial_fill_degrees] to control the way the bar fills up.
</constant>
<constant name="FILL_BILINEAR_LEFT_AND_RIGHT" value="6" enum="FillMode">
+ The [member texture_progress] fills from the center, expanding both towards the left and the right.
</constant>
<constant name="FILL_BILINEAR_TOP_AND_BOTTOM" value="7" enum="FillMode">
+ The [member texture_progress] fills from the center, expanding both towards the top and the bottom.
</constant>
<constant name="FILL_CLOCKWISE_AND_COUNTER_CLOCKWISE" value="8" enum="FillMode">
+ Turns the node into a radial bar. The [member texture_progress] fills radially from the center, expanding both clockwise and counter-clockwise. See [member radial_center_offset], [member radial_initial_angle] and [member radial_fill_degrees] to control the way the bar fills up.
</constant>
</constants>
</class>
diff --git a/doc/classes/Tree.xml b/doc/classes/Tree.xml
index 0431718066..8051062fc4 100644
--- a/doc/classes/Tree.xml
+++ b/doc/classes/Tree.xml
@@ -230,7 +230,7 @@
The amount of columns.
</member>
<member name="drop_mode_flags" type="int" setter="set_drop_mode_flags" getter="get_drop_mode_flags">
- The drop mode as an OR combination of flags. See [code]DROP_MODE_*[/code] constants. Once dropping is done, reverts to [code]DROP_MODE_DISABLED[/code]. Setting this during [method can_drop_data] is recommended.
+ The drop mode as an OR combination of flags. See [code]DROP_MODE_*[/code] constants. Once dropping is done, reverts to [code]DROP_MODE_DISABLED[/code]. Setting this during [method Control.can_drop_data] is recommended.
</member>
<member name="hide_folding" type="bool" setter="set_hide_folding" getter="is_folding_hidden">
If [code]true[/code] the folding arrow is hidden.
diff --git a/doc/classes/TreeItem.xml b/doc/classes/TreeItem.xml
index 57e0f2825a..c5a63b1acb 100644
--- a/doc/classes/TreeItem.xml
+++ b/doc/classes/TreeItem.xml
@@ -400,6 +400,7 @@
</argument>
<description>
Sets the given column's custom draw callback to [code]callback[/code] method on [code]object[/code].
+ The [code]callback[/code] should accept two arguments: the [TreeItem] that is drawn and its position and size as a [Rect2].
</description>
</method>
<method name="set_editable">
diff --git a/doc/tools/makerst.py b/doc/tools/makerst.py
index 63a5c8cbbf..b3d6d32c26 100755
--- a/doc/tools/makerst.py
+++ b/doc/tools/makerst.py
@@ -610,8 +610,7 @@ def make_rst_class(node):
s += ' = **' + c.attrib['value'] + '**'
if c.text.strip() != '':
s += ' --- ' + rstize_text(c.text.strip(), name)
- f.write(s + '\n')
- f.write('\n')
+ f.write(s + '\n\n')
# Constants
if len(consts) > 0:
@@ -623,8 +622,7 @@ def make_rst_class(node):
s += ' = **' + c.attrib['value'] + '**'
if c.text.strip() != '':
s += ' --- ' + rstize_text(c.text.strip(), name)
- f.write(s + '\n')
- f.write('\n')
+ f.write(s + '\n\n')
# Class description
descr = node.find('description')
diff --git a/drivers/coreaudio/audio_driver_coreaudio.cpp b/drivers/coreaudio/audio_driver_coreaudio.cpp
index 09e50e4aaa..cf8fb08f76 100644
--- a/drivers/coreaudio/audio_driver_coreaudio.cpp
+++ b/drivers/coreaudio/audio_driver_coreaudio.cpp
@@ -277,7 +277,7 @@ OSStatus AudioDriverCoreAudio::input_callback(void *inRefCon,
}
}
} else {
- ERR_PRINT(("AudioUnitRender failed, code: " + itos(result)).utf8().get_data());
+ ERR_PRINTS("AudioUnitRender failed, code: " + itos(result));
}
ad->unlock();
@@ -289,7 +289,7 @@ void AudioDriverCoreAudio::start() {
if (!active) {
OSStatus result = AudioOutputUnitStart(audio_unit);
if (result != noErr) {
- ERR_PRINT(("AudioOutputUnitStart failed, code: " + itos(result)).utf8().get_data());
+ ERR_PRINTS("AudioOutputUnitStart failed, code: " + itos(result));
} else {
active = true;
}
@@ -300,7 +300,7 @@ void AudioDriverCoreAudio::stop() {
if (active) {
OSStatus result = AudioOutputUnitStop(audio_unit);
if (result != noErr) {
- ERR_PRINT(("AudioOutputUnitStop failed, code: " + itos(result)).utf8().get_data());
+ ERR_PRINTS("AudioOutputUnitStop failed, code: " + itos(result));
} else {
active = false;
}
diff --git a/drivers/coremidi/core_midi.cpp b/drivers/coremidi/core_midi.cpp
index e8106c4543..2ebbabaa38 100644
--- a/drivers/coremidi/core_midi.cpp
+++ b/drivers/coremidi/core_midi.cpp
@@ -51,13 +51,13 @@ Error MIDIDriverCoreMidi::open() {
OSStatus result = MIDIClientCreate(name, NULL, NULL, &client);
CFRelease(name);
if (result != noErr) {
- ERR_PRINTS("MIDIClientCreate failed: " + String(GetMacOSStatusErrorString(result)));
+ ERR_PRINTS("MIDIClientCreate failed, code: " + itos(result));
return ERR_CANT_OPEN;
}
result = MIDIInputPortCreate(client, CFSTR("Godot Input"), MIDIDriverCoreMidi::read, (void *)this, &port_in);
if (result != noErr) {
- ERR_PRINTS("MIDIInputPortCreate failed: " + String(GetMacOSStatusErrorString(result)));
+ ERR_PRINTS("MIDIInputPortCreate failed, code: " + itos(result));
return ERR_CANT_OPEN;
}
@@ -65,7 +65,7 @@ Error MIDIDriverCoreMidi::open() {
for (int i = 0; i < sources; i++) {
MIDIEndpointRef source = MIDIGetSource(i);
- if (source != NULL) {
+ if (source) {
MIDIPortConnectSource(port_in, source, (void *)this);
connected_sources.insert(i, source);
}
diff --git a/drivers/dummy/rasterizer_dummy.h b/drivers/dummy/rasterizer_dummy.h
index 9315026623..d109ef7b91 100644
--- a/drivers/dummy/rasterizer_dummy.h
+++ b/drivers/dummy/rasterizer_dummy.h
@@ -788,6 +788,7 @@ public:
void restore_render_target() {}
void clear_render_target(const Color &p_color) {}
void blit_render_target_to_screen(RID p_render_target, const Rect2 &p_screen_rect, int p_screen = 0) {}
+ void output_lens_distorted_to_screen(RID p_render_target, const Rect2 &p_screen_rect, float p_k1, float p_k2, const Vector2 &p_eye_center, float p_oversample) {}
void end_frame(bool p_swap_buffers) {}
void finalize() {}
diff --git a/drivers/gles2/rasterizer_canvas_gles2.cpp b/drivers/gles2/rasterizer_canvas_gles2.cpp
index 263f210fa2..18b5dd3483 100644
--- a/drivers/gles2/rasterizer_canvas_gles2.cpp
+++ b/drivers/gles2/rasterizer_canvas_gles2.cpp
@@ -1049,6 +1049,43 @@ void RasterizerCanvasGLES2::draw_generic_textured_rect(const Rect2 &p_rect, cons
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
}
+void RasterizerCanvasGLES2::draw_lens_distortion_rect(const Rect2 &p_rect, float p_k1, float p_k2, const Vector2 &p_eye_center, float p_oversample) {
+ Vector2 half_size;
+ if (storage->frame.current_rt) {
+ half_size = Vector2(storage->frame.current_rt->width, storage->frame.current_rt->height);
+ } else {
+ half_size = OS::get_singleton()->get_window_size();
+ }
+ half_size *= 0.5;
+ Vector2 offset((p_rect.position.x - half_size.x) / half_size.x, (p_rect.position.y - half_size.y) / half_size.y);
+ Vector2 scale(p_rect.size.x / half_size.x, p_rect.size.y / half_size.y);
+
+ float aspect_ratio = p_rect.size.x / p_rect.size.y;
+
+ // setup our lens shader
+ state.lens_shader.bind();
+ state.lens_shader.set_uniform(LensDistortedShaderGLES2::OFFSET, offset);
+ state.lens_shader.set_uniform(LensDistortedShaderGLES2::SCALE, scale);
+ state.lens_shader.set_uniform(LensDistortedShaderGLES2::K1, p_k1);
+ state.lens_shader.set_uniform(LensDistortedShaderGLES2::K2, p_k2);
+ state.lens_shader.set_uniform(LensDistortedShaderGLES2::EYE_CENTER, p_eye_center);
+ state.lens_shader.set_uniform(LensDistortedShaderGLES2::UPSCALE, p_oversample);
+ state.lens_shader.set_uniform(LensDistortedShaderGLES2::ASPECT_RATIO, aspect_ratio);
+
+ // bind our quad buffer
+ _bind_quad_buffer();
+
+ // and draw
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+ // and cleanup
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+ for (int i = 0; i < VS::ARRAY_MAX; i++) {
+ glDisableVertexAttribArray(i);
+ }
+}
+
void RasterizerCanvasGLES2::draw_window_margins(int *black_margin, RID *black_image) {
}
@@ -1148,7 +1185,6 @@ void RasterizerCanvasGLES2::initialize() {
_EIDX(1, 1), _EIDX(1, 2), _EIDX(2, 2),
_EIDX(2, 2), _EIDX(2, 1), _EIDX(1, 1)
};
- ;
#undef _EIDX
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elems), elems, GL_STATIC_DRAW);
@@ -1161,6 +1197,10 @@ void RasterizerCanvasGLES2::initialize() {
state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_TEXTURE_RECT, true);
state.canvas_shader.bind();
+
+ state.lens_shader.init();
+
+ state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_PIXEL_SNAP, GLOBAL_DEF("rendering/quality/2d/use_pixel_snap", false));
}
void RasterizerCanvasGLES2::finalize() {
diff --git a/drivers/gles2/rasterizer_canvas_gles2.h b/drivers/gles2/rasterizer_canvas_gles2.h
index cda3ec79e7..cf1c239b6e 100644
--- a/drivers/gles2/rasterizer_canvas_gles2.h
+++ b/drivers/gles2/rasterizer_canvas_gles2.h
@@ -34,6 +34,7 @@
#include "servers/visual/rasterizer.h"
#include "shaders/canvas.glsl.gen.h"
+#include "shaders/lens_distorted.glsl.gen.h"
// #include "shaders/canvas_shadow.glsl.gen.h"
@@ -70,6 +71,7 @@ public:
bool canvas_texscreen_used;
CanvasShaderGLES2 canvas_shader;
// CanvasShadowShaderGLES3 canvas_shadow_shader;
+ LensDistortedShaderGLES2 lens_shader;
bool using_texture_rect;
bool using_ninepatch;
@@ -117,6 +119,7 @@ public:
void _bind_quad_buffer();
void draw_generic_textured_rect(const Rect2 &p_rect, const Rect2 &p_src);
+ void draw_lens_distortion_rect(const Rect2 &p_rect, float p_k1, float p_k2, const Vector2 &p_eye_center, float p_oversample);
void initialize();
void finalize();
diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp
index 1dd594cc20..848ac8b78f 100644
--- a/drivers/gles2/rasterizer_gles2.cpp
+++ b/drivers/gles2/rasterizer_gles2.cpp
@@ -64,6 +64,17 @@
#define GLAPIENTRY
#endif
+#if !defined(GLES_OVER_GL) && !defined(IPHONE_ENABLED)
+// Used for debugging on mobile, but not iOS as EGL is not available
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#include <GLES2/gl2platform.h>
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#endif
+
+#ifndef IPHONE_ENABLED
static void GLAPIENTRY _gl_debug_print(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const GLvoid *userParam) {
if (type == _EXT_DEBUG_TYPE_OTHER_ARB)
@@ -110,6 +121,7 @@ static void GLAPIENTRY _gl_debug_print(GLenum source, GLenum type, GLuint id, GL
ERR_PRINTS(output);
}
+#endif // IPHONE_ENABLED
typedef void (*DEBUGPROCARB)(GLenum source,
GLenum type,
@@ -179,7 +191,7 @@ Error RasterizerGLES2::is_viable() {
return ERR_UNAVAILABLE;
}
}
-#endif
+#endif // GLES_OVER_GL
#endif // GLAD_ENABLED
@@ -191,7 +203,7 @@ void RasterizerGLES2::initialize() {
print_verbose("Using GLES2 video driver");
#ifdef GLAD_ENABLED
- if (true || OS::get_singleton()->is_stdout_verbose()) {
+ if (OS::get_singleton()->is_stdout_verbose()) {
if (GLAD_GL_ARB_debug_output) {
glEnable(_EXT_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
glDebugMessageCallbackARB(_gl_debug_print, NULL);
@@ -204,7 +216,7 @@ void RasterizerGLES2::initialize() {
// For debugging
#ifdef GLES_OVER_GL
- if (GLAD_GL_ARB_debug_output) {
+ if (OS::get_singleton()->is_stdout_verbose() && GLAD_GL_ARB_debug_output) {
glDebugMessageControlARB(_EXT_DEBUG_SOURCE_API_ARB, _EXT_DEBUG_TYPE_ERROR_ARB, _EXT_DEBUG_SEVERITY_HIGH_ARB, 0, NULL, GL_TRUE);
glDebugMessageControlARB(_EXT_DEBUG_SOURCE_API_ARB, _EXT_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB, _EXT_DEBUG_SEVERITY_HIGH_ARB, 0, NULL, GL_TRUE);
glDebugMessageControlARB(_EXT_DEBUG_SOURCE_API_ARB, _EXT_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB, _EXT_DEBUG_SEVERITY_HIGH_ARB, 0, NULL, GL_TRUE);
@@ -217,7 +229,24 @@ void RasterizerGLES2::initialize() {
GL_DEBUG_SEVERITY_HIGH_ARB, 5, "hello");
*/
}
-#endif
+#else
+#ifndef IPHONE_ENABLED
+ if (OS::get_singleton()->is_stdout_verbose()) {
+ DebugMessageCallbackARB callback = (DebugMessageCallbackARB)eglGetProcAddress("glDebugMessageCallback");
+ if (!callback) {
+ callback = (DebugMessageCallbackARB)eglGetProcAddress("glDebugMessageCallbackKHR");
+ }
+
+ if (callback) {
+
+ print_line("godot: ENABLING GL DEBUG");
+ glEnable(_EXT_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
+ callback(_gl_debug_print, NULL);
+ glEnable(_EXT_DEBUG_OUTPUT);
+ }
+ }
+#endif // !IPHONE_ENABLED
+#endif // GLES_OVER_GL
const GLubyte *renderer = glGetString(GL_RENDERER);
print_line("OpenGL ES 2.0 Renderer: " + String((const char *)renderer));
@@ -380,6 +409,26 @@ void RasterizerGLES2::blit_render_target_to_screen(RID p_render_target, const Re
canvas->canvas_end();
}
+void RasterizerGLES2::output_lens_distorted_to_screen(RID p_render_target, const Rect2 &p_screen_rect, float p_k1, float p_k2, const Vector2 &p_eye_center, float p_oversample) {
+ ERR_FAIL_COND(storage->frame.current_rt);
+
+ RasterizerStorageGLES2::RenderTarget *rt = storage->render_target_owner.getornull(p_render_target);
+ ERR_FAIL_COND(!rt);
+
+ glDisable(GL_BLEND);
+
+ // render to our framebuffer
+ glBindFramebuffer(GL_FRAMEBUFFER, RasterizerStorageGLES2::system_fbo);
+
+ // output our texture
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, rt->color);
+
+ canvas->draw_lens_distortion_rect(p_screen_rect, p_k1, p_k2, p_eye_center, p_oversample);
+
+ glBindTexture(GL_TEXTURE_2D, 0);
+}
+
void RasterizerGLES2::end_frame(bool p_swap_buffers) {
if (OS::get_singleton()->is_layered_allowed()) {
diff --git a/drivers/gles2/rasterizer_gles2.h b/drivers/gles2/rasterizer_gles2.h
index 45a9db73f2..97f8ee7c1c 100644
--- a/drivers/gles2/rasterizer_gles2.h
+++ b/drivers/gles2/rasterizer_gles2.h
@@ -59,6 +59,7 @@ public:
virtual void restore_render_target();
virtual void clear_render_target(const Color &p_color);
virtual void blit_render_target_to_screen(RID p_render_target, const Rect2 &p_screen_rect, int p_screen = 0);
+ virtual void output_lens_distorted_to_screen(RID p_render_target, const Rect2 &p_screen_rect, float p_k1, float p_k2, const Vector2 &p_eye_center, float p_oversample);
virtual void end_frame(bool p_swap_buffers);
virtual void finalize();
diff --git a/drivers/gles2/rasterizer_scene_gles2.cpp b/drivers/gles2/rasterizer_scene_gles2.cpp
index 22cc45a0f6..fbcbebc88c 100644
--- a/drivers/gles2/rasterizer_scene_gles2.cpp
+++ b/drivers/gles2/rasterizer_scene_gles2.cpp
@@ -42,6 +42,8 @@
#define glClearDepth glClearDepthf
#endif
+#define _DEPTH_COMPONENT24_OES 0x81A6
+
static const GLenum _cube_side_enum[6] = {
GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
@@ -461,7 +463,8 @@ RID RasterizerSceneGLES2::reflection_probe_instance_create(RID p_probe) {
glGenFramebuffers(1, &rpi->fbo_blur);
glGenRenderbuffers(1, &rpi->depth);
- glGenTextures(1, &rpi->cubemap);
+ rpi->cubemap = 0;
+ //glGenTextures(1, &rpi->cubemap);
return rpi->self;
}
@@ -502,14 +505,37 @@ bool RasterizerSceneGLES2::reflection_probe_instance_begin_render(RID p_instance
int size = rpi->probe_ptr->resolution;
rpi->current_resolution = size;
- int lod = 0;
-
- GLenum internal_format = GL_RGBA;
- GLenum format = GL_RGBA;
+ GLenum internal_format = GL_RGB;
+ GLenum format = GL_RGB;
GLenum type = GL_UNSIGNED_BYTE;
glActiveTexture(GL_TEXTURE0);
+ if (rpi->cubemap != 0) {
+ glDeleteTextures(1, &rpi->cubemap);
+ }
+ glGenTextures(1, &rpi->cubemap);
glBindTexture(GL_TEXTURE_CUBE_MAP, rpi->cubemap);
+#if 1
+ //Mobile hardware (PowerVR specially) prefers this approach, the other one kills the game
+ for (int i = 0; i < 6; i++) {
+ glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, internal_format, size, size, 0, format, type, NULL);
+ }
+
+ glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
+
+ glBindRenderbuffer(GL_RENDERBUFFER, rpi->depth); //resize depth buffer
+ glRenderbufferStorage(GL_RENDERBUFFER, _DEPTH_COMPONENT24_OES, size, size);
+
+ for (int i = 0; i < 6; i++) {
+ glBindFramebuffer(GL_FRAMEBUFFER, rpi->fbo[i]);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, _cube_side_enum[i], rpi->cubemap, 0);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rpi->depth);
+ }
+
+#else
+ int lod = 0;
+
+ //the approach below is fatal for powervr
// Set the initial (empty) mipmaps, all need to be set for this to work in GLES2, even if later wont be used.
while (size >= 1) {
@@ -521,7 +547,7 @@ bool RasterizerSceneGLES2::reflection_probe_instance_begin_render(RID p_instance
glBindFramebuffer(GL_FRAMEBUFFER, rpi->fbo[i]);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, _cube_side_enum[i], rpi->cubemap, 0);
glBindRenderbuffer(GL_RENDERBUFFER, rpi->depth);
- glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, size, size);
+ glRenderbufferStorage(GL_RENDERBUFFER, _DEPTH_COMPONENT24_OES, size, size);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rpi->depth);
#ifdef DEBUG_ENABLED
@@ -535,7 +561,7 @@ bool RasterizerSceneGLES2::reflection_probe_instance_begin_render(RID p_instance
size >>= 1;
}
-
+#endif
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
@@ -716,20 +742,38 @@ void RasterizerSceneGLES2::environment_set_adjustment(RID p_env, bool p_enable,
}
void RasterizerSceneGLES2::environment_set_fog(RID p_env, bool p_enable, const Color &p_color, const Color &p_sun_color, float p_sun_amount) {
+
Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
+
+ env->fog_enabled = p_enable;
+ env->fog_color = p_color;
+ env->fog_sun_color = p_sun_color;
+ env->fog_sun_amount = p_sun_amount;
}
void RasterizerSceneGLES2::environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_curve, bool p_transmit, float p_transmit_curve) {
+
Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
+
+ env->fog_depth_enabled = p_enable;
+ env->fog_depth_begin = p_depth_begin;
+ env->fog_depth_curve = p_depth_curve;
+ env->fog_transmit_enabled = p_transmit;
+ env->fog_transmit_curve = p_transmit_curve;
}
void RasterizerSceneGLES2::environment_set_fog_height(RID p_env, bool p_enable, float p_min_height, float p_max_height, float p_height_curve) {
+
Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
-}
+ env->fog_height_enabled = p_enable;
+ env->fog_height_min = p_min_height;
+ env->fog_height_max = p_max_height;
+ env->fog_height_curve = p_height_curve;
+}
bool RasterizerSceneGLES2::is_environment(RID p_env) {
return environment_owner.owns(p_env);
}
@@ -2005,6 +2049,15 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
glDisable(GL_BLEND);
}
+ float fog_max_distance = 0;
+ bool using_fog = false;
+ if (p_env && !p_shadow && p_env->fog_enabled && (p_env->fog_depth_enabled || p_env->fog_height_enabled)) {
+ state.scene_shader.set_conditional(SceneShaderGLES2::FOG_DEPTH_ENABLED, p_env->fog_depth_enabled);
+ state.scene_shader.set_conditional(SceneShaderGLES2::FOG_HEIGHT_ENABLED, p_env->fog_height_enabled);
+ fog_max_distance = p_projection.get_z_far();
+ using_fog = true;
+ }
+
RasterizerStorageGLES2::Texture *prev_lightmap = NULL;
float lightmap_energy = 1.0;
bool prev_use_lightmap_capture = false;
@@ -2116,7 +2169,7 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
}
//condition to enable vertex lighting on this object
- bool vertex_lit = light && (material->shader->spatial.uses_vertex_lighting || storage->config.force_vertex_shading) && !unshaded;
+ bool vertex_lit = (material->shader->spatial.uses_vertex_lighting || storage->config.force_vertex_shading) && ((!unshaded && light) || using_fog); //fog forces vertex lighting because it still applies even if unshaded or no fog
if (vertex_lit != prev_vertex_lit) {
state.scene_shader.set_conditional(SceneShaderGLES2::USE_VERTEX_LIGHTING, vertex_lit);
@@ -2242,10 +2295,34 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
rebind_light = true;
rebind_reflection = true;
rebind_lightmap = true;
+
+ if (using_fog) {
+
+ state.scene_shader.set_uniform(SceneShaderGLES2::FOG_COLOR_BASE, p_env->fog_color);
+ Color sun_color_amount = p_env->fog_sun_color;
+ sun_color_amount.a = p_env->fog_sun_amount;
+
+ state.scene_shader.set_uniform(SceneShaderGLES2::FOG_SUN_COLOR_AMOUNT, sun_color_amount);
+ state.scene_shader.set_uniform(SceneShaderGLES2::FOG_TRANSMIT_ENABLED, p_env->fog_transmit_enabled);
+ state.scene_shader.set_uniform(SceneShaderGLES2::FOG_TRANSMIT_CURVE, p_env->fog_transmit_curve);
+
+ if (p_env->fog_depth_enabled) {
+ state.scene_shader.set_uniform(SceneShaderGLES2::FOG_DEPTH_BEGIN, p_env->fog_depth_begin);
+ state.scene_shader.set_uniform(SceneShaderGLES2::FOG_DEPTH_CURVE, p_env->fog_depth_curve);
+ state.scene_shader.set_uniform(SceneShaderGLES2::FOG_MAX_DISTANCE, fog_max_distance);
+ }
+
+ if (p_env->fog_height_enabled) {
+ state.scene_shader.set_uniform(SceneShaderGLES2::FOG_HEIGHT_MIN, p_env->fog_height_min);
+ state.scene_shader.set_uniform(SceneShaderGLES2::FOG_HEIGHT_MAX, p_env->fog_height_max);
+ state.scene_shader.set_uniform(SceneShaderGLES2::FOG_HEIGHT_MAX, p_env->fog_height_max);
+ state.scene_shader.set_uniform(SceneShaderGLES2::FOG_HEIGHT_CURVE, p_env->fog_height_curve);
+ }
+ }
}
- state.scene_shader.set_uniform(SceneShaderGLES2::CAMERA_MATRIX, view_transform_inverse);
- state.scene_shader.set_uniform(SceneShaderGLES2::CAMERA_INVERSE_MATRIX, p_view_transform);
+ state.scene_shader.set_uniform(SceneShaderGLES2::CAMERA_MATRIX, p_view_transform);
+ state.scene_shader.set_uniform(SceneShaderGLES2::CAMERA_INVERSE_MATRIX, view_transform_inverse);
state.scene_shader.set_uniform(SceneShaderGLES2::PROJECTION_MATRIX, p_projection);
state.scene_shader.set_uniform(SceneShaderGLES2::PROJECTION_INVERSE_MATRIX, projection_inverse);
@@ -2302,6 +2379,8 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
state.scene_shader.set_conditional(SceneShaderGLES2::USE_REFLECTION_PROBE2, false);
state.scene_shader.set_conditional(SceneShaderGLES2::USE_LIGHTMAP, false);
state.scene_shader.set_conditional(SceneShaderGLES2::USE_LIGHTMAP_CAPTURE, false);
+ state.scene_shader.set_conditional(SceneShaderGLES2::FOG_DEPTH_ENABLED, false);
+ state.scene_shader.set_conditional(SceneShaderGLES2::FOG_HEIGHT_ENABLED, false);
}
void RasterizerSceneGLES2::_draw_sky(RasterizerStorageGLES2::Sky *p_sky, const CameraMatrix &p_projection, const Transform &p_transform, bool p_vflip, float p_custom_fov, float p_energy) {
@@ -2540,7 +2619,6 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const
_render_render_list(&render_list.elements[render_list.max_elements - render_list.alpha_element_count], render_list.alpha_element_count, p_cam_transform, p_cam_projection, p_shadow_atlas, env, env_radiance_tex, 0.0, 0.0, false, true, false);
- glDepthMask(GL_FALSE);
glDisable(GL_DEPTH_TEST);
//#define GLES2_SHADOW_ATLAS_DEBUG_VIEW
@@ -2984,7 +3062,7 @@ void RasterizerSceneGLES2::initialize() {
glBindTexture(GL_TEXTURE_CUBE_MAP, cube.cubemap);
for (int i = 0; i < 6; i++) {
- glTexImage2D(_cube_side_enum[i], 0, GL_DEPTH_COMPONENT, cube_size, cube_size, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, NULL);
+ glTexImage2D(_cube_side_enum[i], 0, GL_DEPTH_COMPONENT, cube_size, cube_size, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
}
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
diff --git a/drivers/gles2/rasterizer_scene_gles2.h b/drivers/gles2/rasterizer_scene_gles2.h
index 14b9116952..33ac99366d 100644
--- a/drivers/gles2/rasterizer_scene_gles2.h
+++ b/drivers/gles2/rasterizer_scene_gles2.h
@@ -353,6 +353,21 @@ public:
int canvas_max_layer;
+ bool fog_enabled;
+ Color fog_color;
+ Color fog_sun_color;
+ float fog_sun_amount;
+
+ bool fog_depth_enabled;
+ float fog_depth_begin;
+ float fog_depth_curve;
+ bool fog_transmit_enabled;
+ float fog_transmit_curve;
+ bool fog_height_enabled;
+ float fog_height_min;
+ float fog_height_max;
+ float fog_height_curve;
+
Environment() {
bg_mode = VS::ENV_BG_CLEAR_COLOR;
sky_custom_fov = 0.0;
@@ -361,6 +376,24 @@ public:
ambient_energy = 1.0;
ambient_sky_contribution = 0.0;
canvas_max_layer = 0;
+
+ fog_enabled = false;
+ fog_color = Color(0.5, 0.5, 0.5);
+ fog_sun_color = Color(0.8, 0.8, 0.0);
+ fog_sun_amount = 0;
+
+ fog_depth_enabled = true;
+
+ fog_depth_begin = 10;
+ fog_depth_curve = 1;
+
+ fog_transmit_enabled = true;
+ fog_transmit_curve = 1;
+
+ fog_height_enabled = false;
+ fog_height_min = 0;
+ fog_height_max = 100;
+ fog_height_curve = 1;
}
};
diff --git a/drivers/gles2/rasterizer_storage_gles2.cpp b/drivers/gles2/rasterizer_storage_gles2.cpp
index 6314a69a90..d5865064cf 100644
--- a/drivers/gles2/rasterizer_storage_gles2.cpp
+++ b/drivers/gles2/rasterizer_storage_gles2.cpp
@@ -901,26 +901,27 @@ void RasterizerStorageGLES2::sky_set_texture(RID p_sky, RID p_panorama, int p_ra
// attachements for it, so we can fill them by issuing draw calls.
GLuint tmp_fb;
- glGenFramebuffers(1, &tmp_fb);
- glBindFramebuffer(GL_FRAMEBUFFER, tmp_fb);
-
int size = p_radiance_size;
int lod = 0;
- shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES2::USE_SOURCE_PANORAMA, texture->target == GL_TEXTURE_2D);
-
- shaders.cubemap_filter.bind();
-
int mipmaps = 6;
int mm_level = mipmaps;
- GLenum internal_format = GL_RGBA;
- GLenum format = GL_RGBA;
- GLenum type = GL_UNSIGNED_BYTE; // This is suboptimal... TODO other format for FBO?
+ GLenum internal_format = GL_RGB;
+ GLenum format = GL_RGB;
+ GLenum type = GL_UNSIGNED_BYTE;
// Set the initial (empty) mipmaps
+#if 1
+ //Mobile hardware (PowerVR specially) prefers this approach, the other one kills the game
+ for (int i = 0; i < 6; i++) {
+ glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, internal_format, size, size, 0, format, type, NULL);
+ }
+
+ glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
+#else
while (size >= 1) {
for (int i = 0; i < 6; i++) {
@@ -931,7 +932,14 @@ void RasterizerStorageGLES2::sky_set_texture(RID p_sky, RID p_panorama, int p_ra
size >>= 1;
}
+#endif
+ //framebuffer
+ glGenFramebuffers(1, &tmp_fb);
+ glBindFramebuffer(GL_FRAMEBUFFER, tmp_fb);
+
+ shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES2::USE_SOURCE_PANORAMA, texture->target == GL_TEXTURE_2D);
+ shaders.cubemap_filter.bind();
lod = 0;
mm_level = mipmaps;
@@ -3154,6 +3162,9 @@ void RasterizerStorageGLES2::light_set_reverse_cull_face_mode(RID p_light, bool
ERR_FAIL_COND(!light);
light->reverse_cull = p_enabled;
+
+ light->version++;
+ light->instance_change_notify();
}
void RasterizerStorageGLES2::light_omni_set_shadow_mode(RID p_light, VS::LightOmniShadowMode p_mode) {
diff --git a/drivers/gles2/shaders/SCsub b/drivers/gles2/shaders/SCsub
index acb93fff8f..d959d3f740 100644
--- a/drivers/gles2/shaders/SCsub
+++ b/drivers/gles2/shaders/SCsub
@@ -20,3 +20,4 @@ if 'GLES2_GLSL' in env['BUILDERS']:
# env.GLES2_GLSL('exposure.glsl');
# env.GLES2_GLSL('tonemap.glsl');
# env.GLES2_GLSL('particles.glsl');
+ env.GLES2_GLSL('lens_distorted.glsl');
diff --git a/drivers/gles2/shaders/canvas.glsl b/drivers/gles2/shaders/canvas.glsl
index ba69ca9b6e..b990384949 100644
--- a/drivers/gles2/shaders/canvas.glsl
+++ b/drivers/gles2/shaders/canvas.glsl
@@ -89,9 +89,18 @@ VERTEX_SHADER_CODE
/* clang-format on */
}
+#if !defined(SKIP_TRANSFORM_USED)
+ outvec = extra_matrix * outvec;
+ outvec = modelview_matrix * outvec;
+#endif
+
color_interp = color;
- gl_Position = projection_matrix * modelview_matrix * outvec;
+#ifdef USE_PIXEL_SNAP
+ outvec.xy = floor(outvec + 0.5).xy;
+#endif
+
+ gl_Position = projection_matrix * outvec;
}
/* clang-format off */
diff --git a/drivers/gles2/shaders/lens_distorted.glsl b/drivers/gles2/shaders/lens_distorted.glsl
new file mode 100644
index 0000000000..d541db9bf9
--- /dev/null
+++ b/drivers/gles2/shaders/lens_distorted.glsl
@@ -0,0 +1,62 @@
+/* clang-format off */
+[vertex]
+
+attribute highp vec2 vertex; // attrib:0
+/* clang-format on */
+
+uniform vec2 offset;
+uniform vec2 scale;
+
+varying vec2 uv_interp;
+
+void main() {
+
+ uv_interp = vertex.xy * 2.0 - 1.0;
+
+ vec2 v = vertex.xy * scale + offset;
+ gl_Position = vec4(v, 0.0, 1.0);
+}
+
+/* clang-format off */
+[fragment]
+
+uniform sampler2D source; //texunit:0
+/* clang-format on */
+
+uniform vec2 eye_center;
+uniform float k1;
+uniform float k2;
+uniform float upscale;
+uniform float aspect_ratio;
+
+varying vec2 uv_interp;
+
+void main() {
+ vec2 coords = uv_interp;
+ vec2 offset = coords - eye_center;
+
+ // take aspect ratio into account
+ offset.y /= aspect_ratio;
+
+ // distort
+ vec2 offset_sq = offset * offset;
+ float radius_sq = offset_sq.x + offset_sq.y;
+ float radius_s4 = radius_sq * radius_sq;
+ float distortion_scale = 1.0 + (k1 * radius_sq) + (k2 * radius_s4);
+ offset *= distortion_scale;
+
+ // reapply aspect ratio
+ offset.y *= aspect_ratio;
+
+ // add our eye center back in
+ coords = offset + eye_center;
+ coords /= upscale;
+
+ // and check our color
+ if (coords.x < -1.0 || coords.y < -1.0 || coords.x > 1.0 || coords.y > 1.0) {
+ gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
+ } else {
+ coords = (coords + vec2(1.0)) / vec2(2.0);
+ gl_FragColor = texture2D(source, coords);
+ }
+}
diff --git a/drivers/gles2/shaders/scene.glsl b/drivers/gles2/shaders/scene.glsl
index 958de94485..7b57f5d497 100644
--- a/drivers/gles2/shaders/scene.glsl
+++ b/drivers/gles2/shaders/scene.glsl
@@ -75,12 +75,12 @@ attribute highp vec4 instance_custom_data; // attrib:12
// uniforms
//
-uniform mat4 camera_matrix;
-uniform mat4 camera_inverse_matrix;
-uniform mat4 projection_matrix;
-uniform mat4 projection_inverse_matrix;
+uniform highp mat4 camera_matrix;
+uniform highp mat4 camera_inverse_matrix;
+uniform highp mat4 projection_matrix;
+uniform highp mat4 projection_inverse_matrix;
-uniform mat4 world_transform;
+uniform highp mat4 world_transform;
uniform highp float time;
@@ -156,22 +156,22 @@ varying highp vec3 diffuse_interp;
varying highp vec3 specular_interp;
// general for all lights
-uniform vec4 light_color;
-uniform float light_specular;
+uniform highp vec4 light_color;
+uniform highp float light_specular;
// directional
-uniform vec3 light_direction;
+uniform highp vec3 light_direction;
// omni
-uniform vec3 light_position;
+uniform highp vec3 light_position;
-uniform float light_range;
-uniform float light_attenuation;
+uniform highp float light_range;
+uniform highp float light_attenuation;
// spot
-uniform float light_spot_attenuation;
-uniform float light_spot_range;
-uniform float light_spot_angle;
+uniform highp float light_spot_attenuation;
+uniform highp float light_spot_range;
+uniform highp float light_spot_angle;
void light_compute(
vec3 N,
@@ -262,9 +262,9 @@ void light_compute(
#ifdef USE_REFLECTION_PROBE1
-uniform mat4 refprobe1_local_matrix;
+uniform highp mat4 refprobe1_local_matrix;
varying mediump vec4 refprobe1_reflection_normal_blend;
-uniform vec3 refprobe1_box_extents;
+uniform highp vec3 refprobe1_box_extents;
#ifndef USE_LIGHTMAP
varying mediump vec3 refprobe1_ambient_normal;
@@ -274,9 +274,9 @@ varying mediump vec3 refprobe1_ambient_normal;
#ifdef USE_REFLECTION_PROBE2
-uniform mat4 refprobe2_local_matrix;
+uniform highp mat4 refprobe2_local_matrix;
varying mediump vec4 refprobe2_reflection_normal_blend;
-uniform vec3 refprobe2_box_extents;
+uniform highp vec3 refprobe2_box_extents;
#ifndef USE_LIGHTMAP
varying mediump vec3 refprobe2_ambient_normal;
@@ -286,6 +286,32 @@ varying mediump vec3 refprobe2_ambient_normal;
#endif //vertex lighting for refprobes
+#if defined(FOG_DEPTH_ENABLED) || defined(FOG_HEIGHT_ENABLED)
+
+varying vec4 fog_interp;
+
+uniform mediump vec4 fog_color_base;
+#ifdef LIGHT_MODE_DIRECTIONAL
+uniform mediump vec4 fog_sun_color_amount;
+#endif
+
+uniform bool fog_transmit_enabled;
+uniform mediump float fog_transmit_curve;
+
+#ifdef FOG_DEPTH_ENABLED
+uniform highp float fog_depth_begin;
+uniform mediump float fog_depth_curve;
+uniform mediump float fog_max_distance;
+#endif
+
+#ifdef FOG_HEIGHT_ENABLED
+uniform highp float fog_height_min;
+uniform highp float fog_height_max;
+uniform mediump float fog_height_curve;
+#endif
+
+#endif //fog
+
void main() {
highp vec4 vertex = vertex_attrib;
@@ -379,7 +405,7 @@ void main() {
#endif
- mat4 modelview = camera_matrix * world_matrix;
+ mat4 modelview = camera_inverse_matrix * world_matrix;
float roughness = 1.0;
#define world_transform world_matrix
@@ -406,11 +432,11 @@ VERTEX_SHADER_CODE
#endif
#if !defined(SKIP_TRANSFORM_USED) && defined(VERTEX_WORLD_COORDS_USED)
- vertex = camera_matrix * vertex;
- normal = normalize((camera_matrix * vec4(normal, 0.0)).xyz);
+ vertex = camera_inverse_matrix * vertex;
+ normal = normalize((camera_inverse_matrix * vec4(normal, 0.0)).xyz);
#if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP)
- tangent = normalize((camera_matrix * vec4(tangent, 0.0)).xyz);
- binormal = normalize((camera_matrix * vec4(binormal, 0.0)).xyz);
+ tangent = normalize((camera_inverse_matrix * vec4(tangent, 0.0)).xyz);
+ binormal = normalize((camera_inverse_matrix * vec4(binormal, 0.0)).xyz);
#endif
#endif
@@ -583,6 +609,37 @@ VERTEX_SHADER_CODE
#endif //USE_REFLECTION_PROBE2
+#if defined(FOG_DEPTH_ENABLED) || defined(FOG_HEIGHT_ENABLED)
+
+ float fog_amount = 0.0;
+
+#ifdef LIGHT_MODE_DIRECTIONAL
+
+ vec3 fog_color = mix(fog_color_base.rgb, fog_sun_color_amount.rgb, fog_sun_color_amount.a * pow(max(dot(normalize(vertex_interp), light_direction), 0.0), 8.0));
+#else
+ vec3 fog_color = fog_color_base.rgb;
+#endif
+
+#ifdef FOG_DEPTH_ENABLED
+
+ {
+
+ float fog_z = smoothstep(fog_depth_begin, fog_max_distance, length(vertex));
+
+ fog_amount = pow(fog_z, fog_depth_curve);
+ }
+#endif
+
+#ifdef FOG_HEIGHT_ENABLED
+ {
+ float y = (camera_matrix * vec4(vertex_interp, 1.0)).y;
+ fog_amount = max(fog_amount, pow(smoothstep(fog_height_min, fog_height_max, y), fog_height_curve));
+ }
+#endif
+ fog_interp = vec4(fog_color, fog_amount);
+
+#endif //fog
+
#endif //use vertex lighting
gl_Position = projection_matrix * vec4(vertex_interp, 1.0);
}
@@ -613,13 +670,13 @@ precision highp int;
// uniforms
//
-uniform mat4 camera_matrix;
+uniform highp mat4 camera_matrix;
/* clang-format on */
-uniform mat4 camera_inverse_matrix;
-uniform mat4 projection_matrix;
-uniform mat4 projection_inverse_matrix;
+uniform highp mat4 camera_inverse_matrix;
+uniform highp mat4 projection_matrix;
+uniform highp mat4 projection_inverse_matrix;
-uniform mat4 world_transform;
+uniform highp mat4 world_transform;
uniform highp float time;
@@ -646,9 +703,9 @@ varying mediump vec3 refprobe1_ambient_normal;
#else
uniform bool refprobe1_use_box_project;
-uniform vec3 refprobe1_box_extents;
+uniform highp vec3 refprobe1_box_extents;
uniform vec3 refprobe1_box_offset;
-uniform mat4 refprobe1_local_matrix;
+uniform highp mat4 refprobe1_local_matrix;
#endif //use vertex lighting
@@ -673,9 +730,9 @@ varying mediump vec3 refprobe2_ambient_normal;
#else
uniform bool refprobe2_use_box_project;
-uniform vec3 refprobe2_box_extents;
+uniform highp vec3 refprobe2_box_extents;
uniform vec3 refprobe2_box_offset;
-uniform mat4 refprobe2_local_matrix;
+uniform highp mat4 refprobe2_local_matrix;
#endif //use vertex lighting
@@ -816,27 +873,29 @@ uniform float ambient_energy;
varying highp vec3 diffuse_interp;
varying highp vec3 specular_interp;
+uniform highp vec3 light_direction; //may be used by fog, so leave here
+
#else
//done in fragment
// general for all lights
-uniform vec4 light_color;
-uniform float light_specular;
+uniform highp vec4 light_color;
+uniform highp float light_specular;
// directional
-uniform vec3 light_direction;
+uniform highp vec3 light_direction;
// omni
-uniform vec3 light_position;
+uniform highp vec3 light_position;
-uniform float light_attenuation;
+uniform highp float light_attenuation;
// spot
-uniform float light_spot_attenuation;
-uniform float light_spot_range;
-uniform float light_spot_angle;
+uniform highp float light_spot_attenuation;
+uniform highp float light_spot_range;
+uniform highp float light_spot_angle;
#endif
//this is needed outside above if because dual paraboloid wants it
-uniform float light_range;
+uniform highp float light_range;
#ifdef USE_SHADOW
@@ -898,10 +957,11 @@ varying vec2 uv2_interp;
varying vec3 view_interp;
-vec3 metallic_to_specular_color(float metallic, float specular, vec3 albedo) {
- float dielectric = (0.034 * 2.0) * specular;
- // energy conservation
- return mix(vec3(dielectric), albedo, metallic); // TODO: reference?
+vec3 F0(float metallic, float specular, vec3 albedo) {
+ float dielectric = 0.16 * specular * specular;
+ // use albedo * metallic as colored specular reflectance at 0 angle for metallic materials;
+ // see https://google.github.io/filament/Filament.md.html
+ return mix(vec3(dielectric), albedo, vec3(metallic));
}
/* clang-format off */
@@ -934,6 +994,7 @@ varying highp float dp_clip;
// E. Heitz, "Understanding the Masking-Shadowing Function in Microfacet-Based BRDFs", J. Comp. Graph. Tech. 3 (2) (2014).
// Eqns 71-72 and 85-86 (see also Eqns 43 and 80).
+/*
float G_GGX_2cos(float cos_theta_m, float alpha) {
// Schlick's approximation
// C. Schlick, "An Inexpensive BRDF Model for Physically-based Rendering", Computer Graphics Forum. 13 (3): 233 (1994)
@@ -946,6 +1007,15 @@ float G_GGX_2cos(float cos_theta_m, float alpha) {
// float sin2 = (1.0 - cos2);
// return 1.0 / (cos_theta_m + sqrt(cos2 + alpha * alpha * sin2));
}
+*/
+
+// This approximates G_GGX_2cos(cos_theta_l, alpha) * G_GGX_2cos(cos_theta_v, alpha)
+// See Filament docs, Specular G section.
+float V_GGX(float cos_theta_l, float cos_theta_v, float alpha) {
+ float v = cos_theta_l * (cos_theta_v * (1.0 - alpha) + alpha);
+ float l = cos_theta_v * (cos_theta_l * (1.0 - alpha) + alpha);
+ return 0.5 / (v + l);
+}
float D_GGX(float cos_theta_m, float alpha) {
float alpha2 = alpha * alpha;
@@ -953,6 +1023,7 @@ float D_GGX(float cos_theta_m, float alpha) {
return alpha2 / (M_PI * d * d);
}
+/*
float G_GGX_anisotropic_2cos(float cos_theta_m, float alpha_x, float alpha_y, float cos_phi, float sin_phi) {
float cos2 = cos_theta_m * cos_theta_m;
float sin2 = (1.0 - cos2);
@@ -960,14 +1031,30 @@ float G_GGX_anisotropic_2cos(float cos_theta_m, float alpha_x, float alpha_y, fl
float s_y = alpha_y * sin_phi;
return 1.0 / max(cos_theta_m + sqrt(cos2 + (s_x * s_x + s_y * s_y) * sin2), 0.001);
}
+*/
-float D_GGX_anisotropic(float cos_theta_m, float alpha_x, float alpha_y, float cos_phi, float sin_phi) {
- float cos2 = cos_theta_m * cos_theta_m;
+// This approximates G_GGX_anisotropic_2cos(cos_theta_l, ...) * G_GGX_anisotropic_2cos(cos_theta_v, ...)
+// See Filament docs, Anisotropic specular BRDF section.
+float V_GGX_anisotropic(float alpha_x, float alpha_y, float TdotV, float TdotL, float BdotV, float BdotL, float NdotV, float NdotL) {
+ float Lambda_V = NdotL * length(vec3(alpha_x * TdotV, alpha_y * BdotV, NdotV));
+ float Lambda_L = NdotV * length(vec3(alpha_x * TdotL, alpha_y * BdotL, NdotL));
+ return 0.5 / (Lambda_V + Lambda_L);
+}
+
+float D_GGX_anisotropic(float cos_theta_m, float alpha_x, float alpha_y, float cos_phi, float sin_phi, float NdotH) {
+ float alpha2 = alpha_x * alpha_y;
+ highp vec3 v = vec3(alpha_y * cos_phi, alpha_x * sin_phi, alpha2 * NdotH);
+ highp float v2 = dot(v, v);
+ float w2 = alpha2 / v2;
+ float D = alpha2 * w2 * w2 * (1.0 / M_PI);
+ return D;
+
+ /* float cos2 = cos_theta_m * cos_theta_m;
float sin2 = (1.0 - cos2);
float r_x = cos_phi / alpha_x;
float r_y = sin_phi / alpha_y;
float d = cos2 + sin2 * (r_x * r_x + r_y * r_y);
- return 1.0 / max(M_PI * alpha_x * alpha_y * d * d, 0.001);
+ return 1.0 / max(M_PI * alpha_x * alpha_y * d * d, 0.001); */
}
float SchlickFresnel(float u) {
@@ -996,6 +1083,7 @@ void light_compute(
float specular_blob_intensity,
float roughness,
float metallic,
+ float specular,
float rim,
float rim_tint,
float clearcoat,
@@ -1112,9 +1200,11 @@ LIGHT_SHADER_CODE
if (roughness > 0.0) {
- // D
-
- float specular_brdf_NL;
+#if defined(SPECULAR_SCHLICK_GGX)
+ vec3 specular_brdf_NL = vec3(0.0);
+#else
+ float specular_brdf_NL = 0.0;
+#endif
#if defined(SPECULAR_BLINN)
@@ -1147,7 +1237,6 @@ LIGHT_SHADER_CODE
#elif defined(SPECULAR_DISABLED)
// none..
- specular_brdf_NL = 0.0;
#elif defined(SPECULAR_SCHLICK_GGX)
// shlick+ggx as default
@@ -1157,28 +1246,28 @@ LIGHT_SHADER_CODE
float cLdotH = max(dot(L, H), 0.0);
#if defined(LIGHT_USE_ANISOTROPY)
-
+ float alpha = roughness * roughness;
float aspect = sqrt(1.0 - anisotropy * 0.9);
- float rx = roughness / aspect;
- float ry = roughness * aspect;
- float ax = rx * rx;
- float ay = ry * ry;
+ float ax = alpha / aspect;
+ float ay = alpha * aspect;
float XdotH = dot(T, H);
float YdotH = dot(B, H);
- float D = D_GGX_anisotropic(cNdotH, ax, ay, XdotH, YdotH);
- float G = G_GGX_anisotropic_2cos(cNdotL, ax, ay, XdotH, YdotH) * G_GGX_anisotropic_2cos(cNdotV, ax, ay, XdotH, YdotH);
+ float D = D_GGX_anisotropic(cNdotH, ax, ay, XdotH, YdotH, cNdotH);
+ //float G = G_GGX_anisotropic_2cos(cNdotL, ax, ay, XdotH, YdotH) * G_GGX_anisotropic_2cos(cNdotV, ax, ay, XdotH, YdotH);
+ float G = V_GGX_anisotropic(ax, ay, dot(T, V), dot(T, L), dot(B, V), dot(B, L), cNdotV, cNdotL))
#else
float alpha = roughness * roughness;
float D = D_GGX(cNdotH, alpha);
- float G = G_GGX_2cos(cNdotL, alpha) * G_GGX_2cos(cNdotV, alpha);
+ //float G = G_GGX_2cos(cNdotL, alpha) * G_GGX_2cos(cNdotV, alpha);
+ float G = V_GGX(cNdotL, cNdotV, alpha);
#endif
// F
- //float F0 = 1.0;
- //float cLdotH5 = SchlickFresnel(cLdotH);
- //float F = mix(cLdotH5, 1.0, F0);
+ vec3 f0 = F0(metallic, specular, diffuse_color);
+ float cLdotH5 = SchlickFresnel(cLdotH);
+ vec3 F = mix(vec3(cLdotH5), vec3(1.0), f0);
- specular_brdf_NL = cNdotL * D /* F */ * G;
+ specular_brdf_NL = cNdotL * D * F * G;
#endif
@@ -1197,11 +1286,12 @@ LIGHT_SHADER_CODE
#endif
float Dr = GTR1(cNdotH, mix(.1, .001, clearcoat_gloss));
float Fr = mix(.04, 1.0, cLdotH5);
- float Gr = G_GGX_2cos(cNdotL, .25) * G_GGX_2cos(cNdotV, .25);
+ //float Gr = G_GGX_2cos(cNdotL, .25) * G_GGX_2cos(cNdotV, .25);
+ float Gr = V_GGX(cNdotL, cNdotV, 0.25);
- float specular_brdf_NL = 0.25 * clearcoat * Gr * Fr * Dr * cNdotL;
+ float clearcoat_specular_brdf_NL = 0.25 * clearcoat * Gr * Fr * Dr * cNdotL;
- specular_light += specular_brdf_NL * light_color * specular_blob_intensity * attenuation;
+ specular_light += clearcoat_specular_brdf_NL * light_color * specular_blob_intensity * attenuation;
}
#endif
}
@@ -1265,6 +1355,36 @@ float sample_shadow(
#endif
+#if defined(FOG_DEPTH_ENABLED) || defined(FOG_HEIGHT_ENABLED)
+
+#if defined(USE_VERTEX_LIGHTING)
+
+varying vec4 fog_interp;
+
+#else
+uniform mediump vec4 fog_color_base;
+#ifdef LIGHT_MODE_DIRECTIONAL
+uniform mediump vec4 fog_sun_color_amount;
+#endif
+
+uniform bool fog_transmit_enabled;
+uniform mediump float fog_transmit_curve;
+
+#ifdef FOG_DEPTH_ENABLED
+uniform highp float fog_depth_begin;
+uniform mediump float fog_depth_curve;
+uniform mediump float fog_max_distance;
+#endif
+
+#ifdef FOG_HEIGHT_ENABLED
+uniform highp float fog_height_min;
+uniform highp float fog_height_max;
+uniform mediump float fog_height_curve;
+#endif
+
+#endif //vertex lit
+#endif //fog
+
void main() {
#ifdef RENDER_DEPTH_DUAL_PARABOLOID
@@ -1290,6 +1410,11 @@ void main() {
float alpha = 1.0;
float side = 1.0;
+ float specular_blob_intensity = 1.0;
+#if defined(SPECULAR_TOON)
+ specular_blob_intensity *= specular * 2.0;
+#endif
+
#if defined(ENABLE_AO)
float ao = 1.0;
float ao_light_affect = 0.0;
@@ -1504,7 +1629,7 @@ FRAGMENT_SHADER_CODE
highp vec4 splane = shadow_coord;
float shadow_len = length(splane.xyz);
- splane = normalize(splane.xyz);
+ splane.xyz = normalize(splane.xyz);
vec4 clamp_rect = light_clamp;
@@ -1808,7 +1933,7 @@ FRAGMENT_SHADER_CODE
#ifdef USE_VERTEX_LIGHTING
//vertex lighting
- specular_light += specular_interp * specular * light_att;
+ specular_light += specular_interp * specular_blob_intensity * light_att;
diffuse_light += diffuse_interp * albedo * light_att;
#else
@@ -1823,9 +1948,10 @@ FRAGMENT_SHADER_CODE
light_att,
albedo,
transmission,
- specular * light_specular,
+ specular_blob_intensity * light_specular,
roughness,
metallic,
+ specular,
rim,
rim_tint,
clearcoat,
@@ -1872,10 +1998,10 @@ FRAGMENT_SHADER_CODE
vec4 r = roughness * c0 + c1;
float ndotv = clamp(dot(normal, eye_position), 0.0, 1.0);
float a004 = min(r.x * r.x, exp2(-9.28 * ndotv)) * r.x + r.y;
- vec2 AB = vec2(-1.04, 1.04) * a004 + r.zw;
+ vec2 env = vec2(-1.04, 1.04) * a004 + r.zw;
- vec3 specular_color = metallic_to_specular_color(metallic, specular, albedo);
- specular_light *= AB.x * specular_color + AB.y;
+ vec3 f0 = F0(metallic, specular, albedo);
+ specular_light *= env.x * f0 + env.y;
#endif
}
@@ -1889,5 +2015,50 @@ FRAGMENT_SHADER_CODE
#endif //unshaded
+//apply fog
+#if defined(FOG_DEPTH_ENABLED) || defined(FOG_HEIGHT_ENABLED)
+
+#if defined(USE_VERTEX_LIGHTING)
+
+ gl_FragColor.rgb = mix(gl_FragColor.rgb, fog_interp.rgb, fog_interp.a);
+#else //pixel based fog
+ float fog_amount = 0.0;
+
+#ifdef LIGHT_MODE_DIRECTIONAL
+
+ vec3 fog_color = mix(fog_color_base.rgb, fog_sun_color_amount.rgb, fog_sun_color_amount.a * pow(max(dot(eye_position, light_direction), 0.0), 8.0));
+#else
+ vec3 fog_color = fog_color_base.rgb;
+#endif
+
+#ifdef FOG_DEPTH_ENABLED
+
+ {
+
+ float fog_z = smoothstep(fog_depth_begin, fog_max_distance, length(vertex));
+
+ fog_amount = pow(fog_z, fog_depth_curve);
+
+ if (fog_transmit_enabled) {
+ vec3 total_light = gl_FragColor.rgb;
+ float transmit = pow(fog_z, fog_transmit_curve);
+ fog_color = mix(max(total_light, fog_color), fog_color, transmit);
+ }
+ }
+#endif
+
+#ifdef FOG_HEIGHT_ENABLED
+ {
+ float y = (camera_matrix * vec4(vertex, 1.0)).y;
+ fog_amount = max(fog_amount, pow(smoothstep(fog_height_min, fog_height_max, y), fog_height_curve));
+ }
+#endif
+
+ gl_FragColor.rgb = mix(gl_FragColor.rgb, fog_color, fog_amount);
+
+#endif //use vertex lit
+
+#endif // defined(FOG_DEPTH_ENABLED) || defined(FOG_HEIGHT_ENABLED)
+
#endif // not RENDER_DEPTH
}
diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp
index 856c83e297..a9b46baf53 100644
--- a/drivers/gles3/rasterizer_canvas_gles3.cpp
+++ b/drivers/gles3/rasterizer_canvas_gles3.cpp
@@ -1869,6 +1869,39 @@ void RasterizerCanvasGLES3::draw_generic_textured_rect(const Rect2 &p_rect, cons
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
}
+void RasterizerCanvasGLES3::draw_lens_distortion_rect(const Rect2 &p_rect, float p_k1, float p_k2, const Vector2 &p_eye_center, float p_oversample) {
+ Vector2 half_size;
+ if (storage->frame.current_rt) {
+ half_size = Vector2(storage->frame.current_rt->width, storage->frame.current_rt->height);
+ } else {
+ half_size = OS::get_singleton()->get_window_size();
+ }
+ half_size *= 0.5;
+ Vector2 offset((p_rect.position.x - half_size.x) / half_size.x, (p_rect.position.y - half_size.y) / half_size.y);
+ Vector2 scale(p_rect.size.x / half_size.x, p_rect.size.y / half_size.y);
+
+ float aspect_ratio = p_rect.size.x / p_rect.size.y;
+
+ // setup our lens shader
+ state.lens_shader.bind();
+ state.lens_shader.set_uniform(LensDistortedShaderGLES3::OFFSET, offset);
+ state.lens_shader.set_uniform(LensDistortedShaderGLES3::SCALE, scale);
+ state.lens_shader.set_uniform(LensDistortedShaderGLES3::K1, p_k1);
+ state.lens_shader.set_uniform(LensDistortedShaderGLES3::K2, p_k2);
+ state.lens_shader.set_uniform(LensDistortedShaderGLES3::EYE_CENTER, p_eye_center);
+ state.lens_shader.set_uniform(LensDistortedShaderGLES3::UPSCALE, p_oversample);
+ state.lens_shader.set_uniform(LensDistortedShaderGLES3::ASPECT_RATIO, aspect_ratio);
+
+ glBindBufferBase(GL_UNIFORM_BUFFER, 0, state.canvas_item_ubo);
+ glBindVertexArray(data.canvas_quad_array);
+
+ // and draw
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+ glBindVertexArray(0);
+ glBindBufferBase(GL_UNIFORM_BUFFER, 0, 0);
+}
+
void RasterizerCanvasGLES3::draw_window_margins(int *black_margin, RID *black_image) {
Vector2 window_size = OS::get_singleton()->get_window_size();
@@ -2058,6 +2091,7 @@ void RasterizerCanvasGLES3::initialize() {
state.canvas_shader.init();
state.canvas_shader.set_base_material_tex_index(2);
state.canvas_shadow_shader.init();
+ state.lens_shader.init();
state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_RGBA_SHADOWS, storage->config.use_rgba_2d_shadows);
state.canvas_shadow_shader.set_conditional(CanvasShadowShaderGLES3::USE_RGBA_SHADOWS, storage->config.use_rgba_2d_shadows);
diff --git a/drivers/gles3/rasterizer_canvas_gles3.h b/drivers/gles3/rasterizer_canvas_gles3.h
index bc4ea80328..3f306003b4 100644
--- a/drivers/gles3/rasterizer_canvas_gles3.h
+++ b/drivers/gles3/rasterizer_canvas_gles3.h
@@ -35,6 +35,7 @@
#include "servers/visual/rasterizer.h"
#include "shaders/canvas_shadow.glsl.gen.h"
+#include "shaders/lens_distorted.glsl.gen.h"
class RasterizerSceneGLES3;
@@ -72,6 +73,7 @@ public:
bool canvas_texscreen_used;
CanvasShaderGLES3 canvas_shader;
CanvasShadowShaderGLES3 canvas_shadow_shader;
+ LensDistortedShaderGLES3 lens_shader;
bool using_texture_rect;
bool using_ninepatch;
@@ -141,6 +143,7 @@ public:
virtual void reset_canvas();
void draw_generic_textured_rect(const Rect2 &p_rect, const Rect2 &p_src);
+ void draw_lens_distortion_rect(const Rect2 &p_rect, float p_k1, float p_k2, const Vector2 &p_eye_center, float p_oversample);
void initialize();
void finalize();
diff --git a/drivers/gles3/rasterizer_gles3.cpp b/drivers/gles3/rasterizer_gles3.cpp
index 6f13df621f..2b3be9d0bd 100644
--- a/drivers/gles3/rasterizer_gles3.cpp
+++ b/drivers/gles3/rasterizer_gles3.cpp
@@ -73,6 +73,8 @@ RasterizerScene *RasterizerGLES3::get_scene() {
#define _EXT_DEBUG_SEVERITY_LOW_ARB 0x9148
#define _EXT_DEBUG_OUTPUT 0x92E0
+#ifdef GLAD_ENABLED
+// Restricting to GLAD as only used in initialize() with GLAD_GL_ARB_debug_output
#if (defined WINDOWS_ENABLED) && !(defined UWP_ENABLED)
#define GLAPIENTRY APIENTRY
#else
@@ -123,6 +125,7 @@ static void GLAPIENTRY _gl_debug_print(GLenum source, GLenum type, GLuint id, GL
ERR_PRINTS(output);
}
+#endif // GLAD_ENABLED
typedef void (*DEBUGPROCARB)(GLenum source,
GLenum type,
@@ -359,6 +362,26 @@ void RasterizerGLES3::blit_render_target_to_screen(RID p_render_target, const Re
#endif
}
+void RasterizerGLES3::output_lens_distorted_to_screen(RID p_render_target, const Rect2 &p_screen_rect, float p_k1, float p_k2, const Vector2 &p_eye_center, float p_oversample) {
+ ERR_FAIL_COND(storage->frame.current_rt);
+
+ RasterizerStorageGLES3::RenderTarget *rt = storage->render_target_owner.getornull(p_render_target);
+ ERR_FAIL_COND(!rt);
+
+ glDisable(GL_BLEND);
+
+ // render to our framebuffer
+ glBindFramebuffer(GL_FRAMEBUFFER, RasterizerStorageGLES3::system_fbo);
+
+ // output our texture
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, rt->color);
+
+ canvas->draw_lens_distortion_rect(p_screen_rect, p_k1, p_k2, p_eye_center, p_oversample);
+
+ glBindTexture(GL_TEXTURE_2D, 0);
+}
+
void RasterizerGLES3::end_frame(bool p_swap_buffers) {
if (OS::get_singleton()->is_layered_allowed()) {
diff --git a/drivers/gles3/rasterizer_gles3.h b/drivers/gles3/rasterizer_gles3.h
index 543011aff3..477e0dfd48 100644
--- a/drivers/gles3/rasterizer_gles3.h
+++ b/drivers/gles3/rasterizer_gles3.h
@@ -59,6 +59,7 @@ public:
virtual void restore_render_target();
virtual void clear_render_target(const Color &p_color);
virtual void blit_render_target_to_screen(RID p_render_target, const Rect2 &p_screen_rect, int p_screen = 0);
+ virtual void output_lens_distorted_to_screen(RID p_render_target, const Rect2 &p_screen_rect, float p_k1, float p_k2, const Vector2 &p_eye_center, float p_oversample);
virtual void end_frame(bool p_swap_buffers);
virtual void finalize();
diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp
index 7160668fe8..2803f3371b 100644
--- a/drivers/gles3/rasterizer_scene_gles3.cpp
+++ b/drivers/gles3/rasterizer_scene_gles3.cpp
@@ -653,7 +653,7 @@ bool RasterizerSceneGLES3::reflection_probe_instance_begin_render(RID p_instance
int best_free = -1;
int best_used = -1;
- uint64_t best_used_frame;
+ uint64_t best_used_frame = 0;
for (int i = 0; i < reflection_atlas->reflections.size(); i++) {
if (reflection_atlas->reflections[i].owner == RID()) {
@@ -3931,7 +3931,7 @@ void RasterizerSceneGLES3::_post_process(Environment *env, const CameraMatrix &p
state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_FILMIC_TONEMAPPER, env->tone_mapper == VS::ENV_TONE_MAPPER_FILMIC);
state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_ACES_TONEMAPPER, env->tone_mapper == VS::ENV_TONE_MAPPER_ACES);
- state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_REINDHART_TONEMAPPER, env->tone_mapper == VS::ENV_TONE_MAPPER_REINHARDT);
+ state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_REINHARD_TONEMAPPER, env->tone_mapper == VS::ENV_TONE_MAPPER_REINHARD);
state.tonemap_shader.set_conditional(TonemapShaderGLES3::KEEP_3D_LINEAR, storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_KEEP_3D_LINEAR]);
state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_AUTO_EXPOSURE, env->auto_exposure);
@@ -4018,7 +4018,7 @@ void RasterizerSceneGLES3::_post_process(Environment *env, const CameraMatrix &p
state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_AUTO_EXPOSURE, false);
state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_FILMIC_TONEMAPPER, false);
state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_ACES_TONEMAPPER, false);
- state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_REINDHART_TONEMAPPER, false);
+ state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_REINHARD_TONEMAPPER, false);
state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_GLOW_LEVEL1, false);
state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_GLOW_LEVEL2, false);
state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_GLOW_LEVEL3, false);
diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp
index 797441c3a1..9faf07c2f9 100644
--- a/drivers/gles3/rasterizer_storage_gles3.cpp
+++ b/drivers/gles3/rasterizer_storage_gles3.cpp
@@ -730,7 +730,7 @@ void RasterizerStorageGLES3::texture_set_data(RID p_texture, const Ref<Image> &p
}
};
- GLenum blit_target;
+ GLenum blit_target = GL_TEXTURE_2D;
switch (texture->type) {
case VS::TEXTURE_TYPE_2D: {
@@ -948,7 +948,7 @@ void RasterizerStorageGLES3::texture_set_data_partial(RID p_texture, const Ref<I
Image::Format real_format;
Ref<Image> img = _get_gl_image_and_format(p_sub_img, p_sub_img->get_format(), texture->flags, real_format, format, internal_format, type, compressed, srgb);
- GLenum blit_target;
+ GLenum blit_target = GL_TEXTURE_2D;
switch (texture->type) {
case VS::TEXTURE_TYPE_2D: {
@@ -5024,6 +5024,9 @@ void RasterizerStorageGLES3::light_set_reverse_cull_face_mode(RID p_light, bool
ERR_FAIL_COND(!light);
light->reverse_cull = p_enabled;
+
+ light->version++;
+ light->instance_change_notify();
}
void RasterizerStorageGLES3::light_omni_set_shadow_mode(RID p_light, VS::LightOmniShadowMode p_mode) {
@@ -6838,7 +6841,7 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, level);
glDisable(GL_SCISSOR_TEST);
glColorMask(1, 1, 1, 1);
- if (rt->buffers.active == false) {
+ if (!rt->buffers.active) {
glDepthMask(GL_TRUE);
}
diff --git a/drivers/gles3/shader_gles3.h b/drivers/gles3/shader_gles3.h
index 9db4942163..0d360e8453 100644
--- a/drivers/gles3/shader_gles3.h
+++ b/drivers/gles3/shader_gles3.h
@@ -128,11 +128,13 @@ private:
Vector<GLint> texture_uniform_locations;
uint32_t code_version;
bool ok;
- Version() {
- code_version = 0;
- ok = false;
- uniform_location = NULL;
- }
+ Version() :
+ id(0),
+ vert_id(0),
+ frag_id(0),
+ uniform_location(NULL),
+ code_version(0),
+ ok(false) {}
};
Version *version;
diff --git a/drivers/gles3/shaders/SCsub b/drivers/gles3/shaders/SCsub
index f1811fa7b5..27fd1514e7 100644
--- a/drivers/gles3/shaders/SCsub
+++ b/drivers/gles3/shaders/SCsub
@@ -20,3 +20,4 @@ if 'GLES3_GLSL' in env['BUILDERS']:
env.GLES3_GLSL('exposure.glsl');
env.GLES3_GLSL('tonemap.glsl');
env.GLES3_GLSL('particles.glsl');
+ env.GLES3_GLSL('lens_distorted.glsl');
diff --git a/drivers/gles3/shaders/canvas.glsl b/drivers/gles3/shaders/canvas.glsl
index 5203f53fa2..8e8b693eb2 100644
--- a/drivers/gles3/shaders/canvas.glsl
+++ b/drivers/gles3/shaders/canvas.glsl
@@ -182,7 +182,6 @@ VERTEX_SHADER_CODE
color_interp = color;
#ifdef USE_PIXEL_SNAP
-
outvec.xy = floor(outvec + 0.5).xy;
#endif
diff --git a/modules/mobile_vr/shaders/lens_distorted.glsl b/drivers/gles3/shaders/lens_distorted.glsl
index 92604c891c..7b9d0b347f 100644
--- a/modules/mobile_vr/shaders/lens_distorted.glsl
+++ b/drivers/gles3/shaders/lens_distorted.glsl
@@ -3,16 +3,18 @@
layout(location = 0) in highp vec4 vertex_attrib;
/* clang-format on */
-layout(location = 4) in vec2 uv_in;
-uniform float offset_x;
+uniform vec2 offset;
+uniform vec2 scale;
out vec2 uv_interp;
void main() {
- uv_interp = uv_in;
- gl_Position = vec4(vertex_attrib.x + offset_x, vertex_attrib.y, 0.0, 1.0);
+ uv_interp = vertex_attrib.xy * 2.0 - 1.0;
+
+ vec2 v = vertex_attrib.xy * scale + offset;
+ gl_Position = vec4(v, 0.0, 1.0);
}
/* clang-format off */
diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl
index bcaf4a57a8..598bd3465e 100644
--- a/drivers/gles3/shaders/scene.glsl
+++ b/drivers/gles3/shaders/scene.glsl
@@ -920,13 +920,14 @@ float GTR1(float NdotH, float a) {
return (a2 - 1.0) / (M_PI * log(a2) * t);
}
-vec3 metallic_to_specular_color(float metallic, float specular, vec3 albedo) {
- float dielectric = (0.034 * 2.0) * specular;
- // energy conservation
- return mix(vec3(dielectric), albedo, metallic); // TODO: reference?
+vec3 F0(float metallic, float specular, vec3 albedo) {
+ float dielectric = 0.16 * specular * specular;
+ // use albedo * metallic as colored specular reflectance at 0 angle for metallic materials;
+ // see https://google.github.io/filament/Filament.md.html
+ return mix(vec3(dielectric), albedo, vec3(metallic));
}
-void light_compute(vec3 N, vec3 L, vec3 V, vec3 B, vec3 T, vec3 light_color, vec3 attenuation, vec3 diffuse_color, vec3 transmission, float specular_blob_intensity, float roughness, float metallic, float rim, float rim_tint, float clearcoat, float clearcoat_gloss, float anisotropy, inout vec3 diffuse_light, inout vec3 specular_light) {
+void light_compute(vec3 N, vec3 L, vec3 V, vec3 B, vec3 T, vec3 light_color, vec3 attenuation, vec3 diffuse_color, vec3 transmission, float specular_blob_intensity, float roughness, float metallic, float specular, float rim, float rim_tint, float clearcoat, float clearcoat_gloss, float anisotropy, inout vec3 diffuse_light, inout vec3 specular_light) {
#if defined(USE_LIGHT_SHADER_CODE)
// light is written by the light shader
@@ -1069,11 +1070,10 @@ LIGHT_SHADER_CODE
#if defined(LIGHT_USE_ANISOTROPY)
+ float alpha = roughness * roughness;
float aspect = sqrt(1.0 - anisotropy * 0.9);
- float rx = roughness / aspect;
- float ry = roughness * aspect;
- float ax = rx * rx;
- float ay = ry * ry;
+ float ax = alpha / aspect;
+ float ay = alpha * aspect;
float XdotH = dot(T, H);
float YdotH = dot(B, H);
float D = D_GGX_anisotropic(cNdotH, ax, ay, XdotH, YdotH);
@@ -1085,11 +1085,11 @@ LIGHT_SHADER_CODE
float G = G_GGX_2cos(cNdotL, alpha) * G_GGX_2cos(cNdotV, alpha);
#endif
// F
- //float F0 = 1.0;
- //float cLdotH5 = SchlickFresnel(cLdotH);
- //float F = mix(cLdotH5, 1.0, F0);
+ vec3 f0 = F0(metallic, specular, diffuse_color);
+ float cLdotH5 = SchlickFresnel(cLdotH);
+ vec3 F = mix(vec3(cLdotH5), vec3(1.0), f0);
- float specular_brdf_NL = cNdotL * D /* F */ * G;
+ vec3 specular_brdf_NL = cNdotL * D * F * G;
specular_light += specular_brdf_NL * light_color * specular_blob_intensity * attenuation;
#endif
@@ -1191,7 +1191,7 @@ vec3 light_transmittance(float translucency,vec3 light_vec, vec3 normal, vec3 po
}
#endif
-void light_process_omni(int idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 binormal, vec3 tangent, vec3 albedo, vec3 transmission, float roughness, float metallic, float rim, float rim_tint, float clearcoat, float clearcoat_gloss, float anisotropy, float p_blob_intensity, inout vec3 diffuse_light, inout vec3 specular_light) {
+void light_process_omni(int idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 binormal, vec3 tangent, vec3 albedo, vec3 transmission, float roughness, float metallic, float specular, float rim, float rim_tint, float clearcoat, float clearcoat_gloss, float anisotropy, float p_blob_intensity, inout vec3 diffuse_light, inout vec3 specular_light) {
vec3 light_rel_vec = omni_lights[idx].light_pos_inv_radius.xyz - vertex;
float light_length = length(light_rel_vec);
@@ -1245,10 +1245,10 @@ void light_process_omni(int idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 bi
light_attenuation *= mix(omni_lights[idx].shadow_color_contact.rgb, vec3(1.0), shadow);
}
#endif //SHADOWS_DISABLED
- light_compute(normal, normalize(light_rel_vec), eye_vec, binormal, tangent, omni_lights[idx].light_color_energy.rgb, light_attenuation, albedo, transmission, omni_lights[idx].light_params.z * p_blob_intensity, roughness, metallic, rim * omni_attenuation, rim_tint, clearcoat, clearcoat_gloss, anisotropy, diffuse_light, specular_light);
+ light_compute(normal, normalize(light_rel_vec), eye_vec, binormal, tangent, omni_lights[idx].light_color_energy.rgb, light_attenuation, albedo, transmission, omni_lights[idx].light_params.z * p_blob_intensity, roughness, metallic, specular, rim * omni_attenuation, rim_tint, clearcoat, clearcoat_gloss, anisotropy, diffuse_light, specular_light);
}
-void light_process_spot(int idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 binormal, vec3 tangent, vec3 albedo, vec3 transmission, float roughness, float metallic, float rim, float rim_tint, float clearcoat, float clearcoat_gloss, float anisotropy, float p_blob_intensity, inout vec3 diffuse_light, inout vec3 specular_light) {
+void light_process_spot(int idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 binormal, vec3 tangent, vec3 albedo, vec3 transmission, float roughness, float metallic, float specular, float rim, float rim_tint, float clearcoat, float clearcoat_gloss, float anisotropy, float p_blob_intensity, inout vec3 diffuse_light, inout vec3 specular_light) {
vec3 light_rel_vec = spot_lights[idx].light_pos_inv_radius.xyz - vertex;
float light_length = length(light_rel_vec);
@@ -1280,7 +1280,7 @@ void light_process_spot(int idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 bi
}
#endif //SHADOWS_DISABLED
- light_compute(normal, normalize(light_rel_vec), eye_vec, binormal, tangent, spot_lights[idx].light_color_energy.rgb, light_attenuation, albedo, transmission, spot_lights[idx].light_params.z * p_blob_intensity, roughness, metallic, rim * spot_attenuation, rim_tint, clearcoat, clearcoat_gloss, anisotropy, diffuse_light, specular_light);
+ light_compute(normal, normalize(light_rel_vec), eye_vec, binormal, tangent, spot_lights[idx].light_color_energy.rgb, light_attenuation, albedo, transmission, spot_lights[idx].light_params.z * p_blob_intensity, roughness, metallic, specular, rim * spot_attenuation, rim_tint, clearcoat, clearcoat_gloss, anisotropy, diffuse_light, specular_light);
}
void reflection_process(int idx, vec3 vertex, vec3 normal, vec3 binormal, vec3 tangent, float roughness, float anisotropy, vec3 ambient, vec3 skybox, inout highp vec4 reflection_accum, inout highp vec4 ambient_accum) {
@@ -1895,7 +1895,7 @@ FRAGMENT_SHADER_CODE
specular_light *= mix(vec3(1.0), light_attenuation, specular_light_interp.a);
#else
- light_compute(normal, -light_direction_attenuation.xyz, eye_vec, binormal, tangent, light_color_energy.rgb, light_attenuation, albedo, transmission, light_params.z * specular_blob_intensity, roughness, metallic, rim, rim_tint, clearcoat, clearcoat_gloss, anisotropy, diffuse_light, specular_light);
+ light_compute(normal, -light_direction_attenuation.xyz, eye_vec, binormal, tangent, light_color_energy.rgb, light_attenuation, albedo, transmission, light_params.z * specular_blob_intensity, roughness, metallic, specular, rim, rim_tint, clearcoat, clearcoat_gloss, anisotropy, diffuse_light, specular_light);
#endif
#endif //#USE_LIGHT_DIRECTIONAL
@@ -1969,11 +1969,11 @@ FRAGMENT_SHADER_CODE
#else
for (int i = 0; i < omni_light_count; i++) {
- light_process_omni(omni_light_indices[i], vertex, eye_vec, normal, binormal, tangent, albedo, transmission, roughness, metallic, rim, rim_tint, clearcoat, clearcoat_gloss, anisotropy, specular_blob_intensity, diffuse_light, specular_light);
+ light_process_omni(omni_light_indices[i], vertex, eye_vec, normal, binormal, tangent, albedo, transmission, roughness, metallic, specular, rim, rim_tint, clearcoat, clearcoat_gloss, anisotropy, specular_blob_intensity, diffuse_light, specular_light);
}
for (int i = 0; i < spot_light_count; i++) {
- light_process_spot(spot_light_indices[i], vertex, eye_vec, normal, binormal, tangent, albedo, transmission, roughness, metallic, rim, rim_tint, clearcoat, clearcoat_gloss, anisotropy, specular_blob_intensity, diffuse_light, specular_light);
+ light_process_spot(spot_light_indices[i], vertex, eye_vec, normal, binormal, tangent, albedo, transmission, roughness, metallic, specular, rim, rim_tint, clearcoat, clearcoat_gloss, anisotropy, specular_blob_intensity, diffuse_light, specular_light);
}
#endif //USE_VERTEX_LIGHTING
@@ -1994,7 +1994,7 @@ FRAGMENT_SHADER_CODE
diffuse_light *= ao_light_affect;
#endif
- //energy conservation
+ // base color remapping
diffuse_light *= 1.0 - metallic; // TODO: avoid all diffuse and ambient light calculations when metallic == 1 up to this point
ambient_light *= 1.0 - metallic;
@@ -2011,10 +2011,10 @@ FRAGMENT_SHADER_CODE
vec4 r = roughness * c0 + c1;
float ndotv = clamp(dot(normal, eye_vec), 0.0, 1.0);
float a004 = min(r.x * r.x, exp2(-9.28 * ndotv)) * r.x + r.y;
- vec2 AB = vec2(-1.04, 1.04) * a004 + r.zw;
+ vec2 env = vec2(-1.04, 1.04) * a004 + r.zw;
- vec3 specular_color = metallic_to_specular_color(metallic, specular, albedo);
- specular_light *= AB.x * specular_color + AB.y;
+ vec3 f0 = F0(metallic, specular, albedo);
+ specular_light *= env.x * f0 + env.y;
#endif
}
diff --git a/drivers/gles3/shaders/tonemap.glsl b/drivers/gles3/shaders/tonemap.glsl
index dd6d78849b..80ad003c80 100644
--- a/drivers/gles3/shaders/tonemap.glsl
+++ b/drivers/gles3/shaders/tonemap.glsl
@@ -124,13 +124,16 @@ vec4 texture2D_bicubic(sampler2D tex, vec2 uv, int p_lod) {
#endif
vec3 tonemap_filmic(vec3 color, float white) {
- const float A = 0.15f;
- const float B = 0.50f;
+ // exposure bias: input scale (color *= bias, white *= bias) to make the brighness consistent with other tonemappers
+ // also useful to scale the input to the range that the tonemapper is designed for (some require very high input values)
+ // has no effect on the curve's general shape or visual properties
+ const float exposure_bias = 2.0f;
+ const float A = 0.22f * exposure_bias * exposure_bias; // bias baked into constants for performance
+ const float B = 0.30f * exposure_bias;
const float C = 0.10f;
const float D = 0.20f;
- const float E = 0.02f;
+ const float E = 0.01f;
const float F = 0.30f;
- const float W = 11.2f;
vec3 color_tonemapped = ((color * (A * color + C * B) + D * E) / (color * (A * color + B) + D * F)) - E / F;
float white_tonemapped = ((white * (A * white + C * B) + D * E) / (white * (A * white + B) + D * F)) - E / F;
@@ -139,10 +142,11 @@ vec3 tonemap_filmic(vec3 color, float white) {
}
vec3 tonemap_aces(vec3 color, float white) {
- const float A = 2.51f;
- const float B = 0.03f;
- const float C = 2.43f;
- const float D = 0.59f;
+ const float exposure_bias = 0.85f;
+ const float A = 2.51f * exposure_bias * exposure_bias;
+ const float B = 0.03f * exposure_bias;
+ const float C = 2.43f * exposure_bias * exposure_bias;
+ const float D = 0.59f * exposure_bias;
const float E = 0.14f;
vec3 color_tonemapped = (color * (A * color + B)) / (color * (C * color + D) + E);
@@ -151,8 +155,8 @@ vec3 tonemap_aces(vec3 color, float white) {
return clamp(color_tonemapped / white_tonemapped, vec3(0.0f), vec3(1.0f));
}
-vec3 tonemap_reindhart(vec3 color, float white) {
- return clamp((color) / (1.0f + color) * (1.0f + (color / (white))), vec3(0.0f), vec3(1.0f)); // whitepoint is probably not in linear space here!
+vec3 tonemap_reinhard(vec3 color, float white) {
+ return clamp((white * color + color) / (color * white + white), vec3(0.0f), vec3(1.0f));
}
vec3 linear_to_srgb(vec3 color) { // convert linear rgb to srgb, assumes clamped input in range [0;1]
@@ -161,8 +165,8 @@ vec3 linear_to_srgb(vec3 color) { // convert linear rgb to srgb, assumes clamped
}
vec3 apply_tonemapping(vec3 color, float white) { // inputs are LINEAR, always outputs clamped [0;1] color
-#ifdef USE_REINDHART_TONEMAPPER
- return tonemap_reindhart(color, white);
+#ifdef USE_REINHARD_TONEMAPPER
+ return tonemap_reinhard(color, white);
#endif
#ifdef USE_FILMIC_TONEMAPPER
diff --git a/drivers/png/image_loader_png.cpp b/drivers/png/image_loader_png.cpp
index 04acb9387e..a4ea889d3b 100644
--- a/drivers/png/image_loader_png.cpp
+++ b/drivers/png/image_loader_png.cpp
@@ -227,10 +227,7 @@ static void user_read_data(png_structp png_ptr, png_bytep data, png_size_t p_len
PNGReadStatus *rstatus;
rstatus = (PNGReadStatus *)png_get_io_ptr(png_ptr);
- png_size_t to_read = p_length;
- if (rstatus->size >= 0) {
- to_read = MIN(p_length, rstatus->size - rstatus->offset);
- }
+ png_size_t to_read = MIN(p_length, rstatus->size - rstatus->offset);
memcpy(data, &rstatus->image[rstatus->offset], to_read);
rstatus->offset += to_read;
diff --git a/drivers/unix/dir_access_unix.cpp b/drivers/unix/dir_access_unix.cpp
index a5a9258c4a..48b4369b7e 100644
--- a/drivers/unix/dir_access_unix.cpp
+++ b/drivers/unix/dir_access_unix.cpp
@@ -391,7 +391,7 @@ size_t DirAccessUnix::get_space_left() {
return vfs.f_bfree * vfs.f_bsize;
#else
-#warning THIS IS BROKEN
+ // FIXME: Implement this.
return 0;
#endif
};
diff --git a/drivers/unix/net_socket_posix.cpp b/drivers/unix/net_socket_posix.cpp
index 3f03175403..2cc2032cbb 100644
--- a/drivers/unix/net_socket_posix.cpp
+++ b/drivers/unix/net_socket_posix.cpp
@@ -42,12 +42,8 @@
#include <sys/types.h>
#include <unistd.h>
#ifndef NO_FCNTL
-#ifdef __HAIKU__
#include <fcntl.h>
#else
-#include <sys/fcntl.h>
-#endif
-#else
#include <sys/ioctl.h>
#endif
#include <netinet/in.h>
diff --git a/drivers/unix/thread_posix.cpp b/drivers/unix/thread_posix.cpp
index fcefe0a3b3..54bbbf2dad 100644
--- a/drivers/unix/thread_posix.cpp
+++ b/drivers/unix/thread_posix.cpp
@@ -103,8 +103,6 @@ void ThreadPosix::wait_to_finish_func_posix(Thread *p_thread) {
Error ThreadPosix::set_name_func_posix(const String &p_name) {
- pthread_t running_thread = pthread_self();
-
#ifdef PTHREAD_NO_RENAME
return ERR_UNAVAILABLE;
@@ -117,6 +115,7 @@ Error ThreadPosix::set_name_func_posix(const String &p_name) {
#else
+ pthread_t running_thread = pthread_self();
#ifdef PTHREAD_BSD_SET_NAME
pthread_set_name_np(running_thread, p_name.utf8().get_data());
int err = 0; // Open/FreeBSD ignore errors in this function
diff --git a/drivers/wasapi/audio_driver_wasapi.cpp b/drivers/wasapi/audio_driver_wasapi.cpp
index 3d4979175b..a91e41b008 100644
--- a/drivers/wasapi/audio_driver_wasapi.cpp
+++ b/drivers/wasapi/audio_driver_wasapi.cpp
@@ -796,19 +796,18 @@ Error AudioDriverWASAPI::capture_start() {
return err;
}
- if (audio_input.active == false) {
- audio_input.audio_client->Start();
- audio_input.active = true;
-
- return OK;
+ if (audio_input.active) {
+ return FAILED;
}
- return FAILED;
+ audio_input.audio_client->Start();
+ audio_input.active = true;
+ return OK;
}
Error AudioDriverWASAPI::capture_stop() {
- if (audio_input.active == true) {
+ if (audio_input.active) {
audio_input.audio_client->Stop();
audio_input.active = false;
diff --git a/editor/audio_stream_preview.cpp b/editor/audio_stream_preview.cpp
index c5759ac076..5a94d41aba 100644
--- a/editor/audio_stream_preview.cpp
+++ b/editor/audio_stream_preview.cpp
@@ -50,7 +50,7 @@ float AudioStreamPreview::get_max(float p_time, float p_time_next) const {
time_to = time_from + 1;
}
- uint8_t vmax;
+ uint8_t vmax = 0;
for (int i = time_from; i < time_to; i++) {
@@ -77,7 +77,7 @@ float AudioStreamPreview::get_min(float p_time, float p_time_next) const {
time_to = time_from + 1;
}
- uint8_t vmin;
+ uint8_t vmin = 0;
for (int i = time_from; i < time_to; i++) {
diff --git a/editor/create_dialog.cpp b/editor/create_dialog.cpp
index eb11aea9cc..c4516c1f17 100644
--- a/editor/create_dialog.cpp
+++ b/editor/create_dialog.cpp
@@ -558,6 +558,7 @@ void CreateDialog::_history_selected() {
return;
search_box->set_text(item->get_text(0).get_slicec(' ', 0));
+ favorites->deselect_all();
_update_search();
}
@@ -568,6 +569,7 @@ void CreateDialog::_favorite_selected() {
return;
search_box->set_text(item->get_text(0).get_slicec(' ', 0));
+ recent->deselect_all();
_update_search();
}
diff --git a/editor/doc/doc_dump.cpp b/editor/doc/doc_dump.cpp
index 86fd9b436b..f1c337605e 100644
--- a/editor/doc/doc_dump.cpp
+++ b/editor/doc/doc_dump.cpp
@@ -223,7 +223,7 @@ void DocDump::dump(const String &p_file) {
hint = "Values: ";
for (int j = 0; j < arginfo.hint_string.get_slice_count(","); j++) {
if (j > 0) hint += ", ";
- hint += arginfo.hint_string.get_slice(",", j) + "=" + itos(1 << j);
+ hint += arginfo.hint_string.get_slice(",", j) + "=" + itos((uint64_t)1 << j);
}
break;
case PROPERTY_HINT_FILE: hint = "A file:"; break;
diff --git a/editor/editor_export.cpp b/editor/editor_export.cpp
index 455c889224..1a6188862f 100644
--- a/editor/editor_export.cpp
+++ b/editor/editor_export.cpp
@@ -1097,6 +1097,7 @@ Ref<EditorExportPreset> EditorExport::get_export_preset(int p_idx) {
void EditorExport::remove_export_preset(int p_idx) {
export_presets.remove(p_idx);
+ save_presets();
}
void EditorExport::add_export_plugin(const Ref<EditorExportPlugin> &p_plugin) {
diff --git a/editor/editor_file_dialog.cpp b/editor/editor_file_dialog.cpp
index 38bdba31ea..f425d0a995 100644
--- a/editor/editor_file_dialog.cpp
+++ b/editor/editor_file_dialog.cpp
@@ -501,7 +501,7 @@ void EditorFileDialog::_items_clear_selection() {
case MODE_OPEN_FILE:
case MODE_OPEN_FILES:
get_ok()->set_text(TTR("Open"));
- get_ok()->set_disabled(item_list->is_anything_selected() == false);
+ get_ok()->set_disabled(!item_list->is_anything_selected());
break;
case MODE_OPEN_DIR:
diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp
index ee20d95f25..d73bf86f64 100644
--- a/editor/editor_file_system.cpp
+++ b/editor/editor_file_system.cpp
@@ -1705,6 +1705,17 @@ void EditorFileSystem::reimport_files(const Vector<String> &p_files) {
emit_signal("resources_reimported", p_files);
}
+Error EditorFileSystem::_resource_import(const String &p_path) {
+
+ Vector<String> files;
+ files.push_back(p_path);
+
+ singleton->update_file(p_path);
+ singleton->reimport_files(files);
+
+ return OK;
+}
+
void EditorFileSystem::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_filesystem"), &EditorFileSystem::get_filesystem);
@@ -1744,6 +1755,7 @@ void EditorFileSystem::_update_extensions() {
EditorFileSystem::EditorFileSystem() {
+ ResourceLoader::import = _resource_import;
reimport_on_missing_imported_files = GLOBAL_DEF("editor/reimport_missing_imported_files", true);
singleton = this;
diff --git a/editor/editor_file_system.h b/editor/editor_file_system.h
index f2f72eddbd..47077425a1 100644
--- a/editor/editor_file_system.h
+++ b/editor/editor_file_system.h
@@ -230,6 +230,8 @@ class EditorFileSystem : public Node {
String _get_global_script_class(const String &p_type, const String &p_path, String *r_extends, String *r_icon_path) const;
+ static Error _resource_import(const String &p_path);
+
protected:
void _notification(int p_what);
static void _bind_methods();
diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp
index 60040f641b..80dd5aa114 100644
--- a/editor/editor_help.cpp
+++ b/editor/editor_help.cpp
@@ -40,7 +40,7 @@
#define CONTRIBUTE2_URL "https://github.com/godotengine/godot-docs"
#define REQUEST_URL "https://github.com/godotengine/godot-docs/issues/new"
-void EditorHelpSearch::popup() {
+void EditorHelpSearch::popup_dialog() {
popup_centered(Size2(700, 600) * EDSCALE);
if (search_box->get_text() != "") {
@@ -50,15 +50,16 @@ void EditorHelpSearch::popup() {
search_box->grab_focus();
}
-void EditorHelpSearch::popup(const String &p_term) {
+void EditorHelpSearch::popup_dialog(const String &p_term) {
popup_centered(Size2(700, 600) * EDSCALE);
if (p_term != "") {
search_box->set_text(p_term);
search_box->select_all();
_update_search();
- } else
+ } else {
search_box->clear();
+ }
search_box->grab_focus();
}
@@ -362,7 +363,7 @@ void EditorHelpIndex::select_class(const String &p_class) {
class_list->ensure_cursor_is_visible();
}
-void EditorHelpIndex::popup() {
+void EditorHelpIndex::popup_dialog() {
popup_centered(Size2(500, 600) * EDSCALE);
diff --git a/editor/editor_help.h b/editor/editor_help.h
index ad81a39945..25db68b42d 100644
--- a/editor/editor_help.h
+++ b/editor/editor_help.h
@@ -92,8 +92,8 @@ protected:
static void _bind_methods();
public:
- void popup();
- void popup(const String &p_term);
+ void popup_dialog();
+ void popup_dialog(const String &p_term);
EditorHelpSearch();
};
@@ -120,7 +120,7 @@ protected:
public:
void select_class(const String &p_class);
- void popup();
+ void popup_dialog();
EditorHelpIndex();
};
diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp
index 2c4168f1a0..a90f15004a 100644
--- a/editor/editor_inspector.cpp
+++ b/editor/editor_inspector.cpp
@@ -484,6 +484,17 @@ void EditorProperty::update_reload_status() {
}
bool EditorProperty::use_keying_next() const {
+ List<PropertyInfo> plist;
+ object->get_property_list(&plist, true);
+
+ for (List<PropertyInfo>::Element *I = plist.front(); I; I = I->next()) {
+ PropertyInfo &p = I->get();
+
+ if (p.name == property) {
+ return p.hint == PROPERTY_HINT_SPRITE_FRAME;
+ }
+ }
+
return false;
}
void EditorProperty::set_checkable(bool p_checkable) {
@@ -618,6 +629,11 @@ void EditorProperty::_gui_input(const Ref<InputEvent> &p_event) {
if (keying_rect.has_point(mb->get_position())) {
emit_signal("property_keyed", property);
+
+ if (use_keying_next()) {
+ call_deferred("emit_signal", "property_changed", property, object->get(property).operator int64_t() + 1);
+ call_deferred("update_property");
+ }
}
if (revert_rect.has_point(mb->get_position())) {
@@ -2123,6 +2139,13 @@ void EditorInspector::_notification(int p_what) {
}
if (p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) {
+
+ if (use_sub_inspector_bg) {
+ add_style_override("bg", get_stylebox("sub_inspector_bg", "Editor"));
+ } else if (is_inside_tree()) {
+ add_style_override("bg", get_stylebox("bg", "Tree"));
+ }
+
update_tree();
}
}
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index ea063fa798..18dd85617b 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -227,12 +227,6 @@ void EditorNode::_unhandled_input(const Ref<InputEvent> &p_event) {
_editor_select_prev();
}
- if (k->get_scancode() == KEY_ESCAPE) {
- for (int i = 0; i < bottom_panel_items.size(); i++) {
- _bottom_panel_switch(false, i);
- }
- }
-
if (old_editor != editor_plugin_screen) {
get_tree()->set_input_as_handled();
}
@@ -1738,13 +1732,13 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
} break;
case FILE_QUICK_OPEN_SCENE: {
- quick_open->popup("PackedScene", true);
+ quick_open->popup_dialog("PackedScene", true);
quick_open->set_title(TTR("Quick Open Scene..."));
} break;
case FILE_QUICK_OPEN_SCRIPT: {
- quick_open->popup("Script", true);
+ quick_open->popup_dialog("Script", true);
quick_open->set_title(TTR("Quick Open Script..."));
} break;
@@ -2002,7 +1996,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
case RUN_PLAY_CUSTOM_SCENE: {
if (run_custom_filename.empty() || editor_run.get_status() == EditorRun::STATUS_STOP) {
_menu_option_confirm(RUN_STOP, true);
- quick_run->popup("PackedScene", true);
+ quick_run->popup_dialog("PackedScene", true);
quick_run->set_title(TTR("Quick Run Scene..."));
play_custom_scene_button->set_pressed(false);
} else {
@@ -3889,7 +3883,7 @@ void EditorNode::_scene_tab_closed(int p_tab) {
}
void EditorNode::_scene_tab_hover(int p_tab) {
- if (bool(EDITOR_GET("interface/scene_tabs/show_thumbnail_on_hover")) == false) {
+ if (!bool(EDITOR_GET("interface/scene_tabs/show_thumbnail_on_hover"))) {
return;
}
int current_tab = scene_tabs->get_current_tab();
diff --git a/editor/editor_profiler.cpp b/editor/editor_profiler.cpp
index b57e3826c6..d3978749c0 100644
--- a/editor/editor_profiler.cpp
+++ b/editor/editor_profiler.cpp
@@ -257,7 +257,7 @@ void EditorProfiler::_update_plot() {
//get
const Metric &m = frame_metrics[idx];
- if (m.valid == false)
+ if (!m.valid)
continue; //skip because invalid
float value = 0;
diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp
index 2dec21fffb..1e97920f7e 100644
--- a/editor/editor_settings.cpp
+++ b/editor/editor_settings.cpp
@@ -531,7 +531,6 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
_initial_set("docks/property_editor/texture_preview_width", 48);
_initial_set("docks/property_editor/auto_refresh_interval", 0.3);
- _initial_set("text_editor/help/doc_path", "");
_initial_set("text_editor/help/show_help_index", true);
_initial_set("filesystem/import/ask_save_before_reimport", false);
diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp
index 9e81051dc2..768a8fc066 100644
--- a/editor/editor_themes.cpp
+++ b/editor/editor_themes.cpp
@@ -251,7 +251,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
Color preset_accent_color;
Color preset_base_color;
- float preset_contrast;
+ float preset_contrast = 0;
// Please, use alphabet order if you've added new theme here(After "Default" and "Custom")
@@ -376,7 +376,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
//Register icons + font
// the resolution and the icon color (dark_theme bool) has not changed, so we do not regenerate the icons
- if (p_theme != NULL && fabs(p_theme->get_constant("scale", "Editor") - EDSCALE) < 0.00001 && p_theme->get_constant("dark_theme", "Editor") == dark_theme) {
+ if (p_theme != NULL && fabs(p_theme->get_constant("scale", "Editor") - EDSCALE) < 0.00001 && (bool)p_theme->get_constant("dark_theme", "Editor") == dark_theme) {
// register already generated icons
for (int i = 0; i < editor_icons_count; i++) {
theme->set_icon(editor_icons_names[i], "EditorIcons", p_theme->get_icon(editor_icons_names[i], "EditorIcons"));
@@ -1016,6 +1016,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_constant("port_offset", "GraphNode", 14 * EDSCALE);
theme->set_constant("title_h_offset", "GraphNode", -16 * EDSCALE);
+ theme->set_constant("title_offset", "GraphNode", 20 * EDSCALE);
theme->set_constant("close_h_offset", "GraphNode", 20 * EDSCALE);
theme->set_constant("close_offset", "GraphNode", 20 * EDSCALE);
theme->set_constant("separation", "GraphNode", 1 * EDSCALE);
diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp
index 2c69909f23..4d386c1af6 100644
--- a/editor/filesystem_dock.cpp
+++ b/editor/filesystem_dock.cpp
@@ -1953,7 +1953,7 @@ void FileSystemDock::_get_drag_target_folder(String &target, bool &target_favori
}
String ltarget = files->get_item_metadata(pos);
- target = ltarget.ends_with("/") ? ltarget : path;
+ target = ltarget.ends_with("/") ? ltarget : path.get_base_dir();
return;
}
diff --git a/editor/icons/icon_noise_texture.svg b/editor/icons/icon_noise_texture.svg
new file mode 100644
index 0000000000..5908c2b2d4
--- /dev/null
+++ b/editor/icons/icon_noise_texture.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
+<path d="m2 1c-0.55228 0-1 0.44772-1 1v12c0 0.55228 0.44772 1 1 1h12c0.55228 0 1-0.44772 1-1v-12c0-0.55228-0.44772-1-1-1zm1 2h10v8h-10zm3 1v2h2v-2zm2 2v2h2v2h2v-6h-2v2zm0 2h-2v-2h-2v4h4z" fill="#e0e0e0" fill-opacity=".99608"/>
+</svg>
diff --git a/editor/import/editor_scene_importer_gltf.cpp b/editor/import/editor_scene_importer_gltf.cpp
index a6b754de3b..cb15be35f2 100644
--- a/editor/import/editor_scene_importer_gltf.cpp
+++ b/editor/import/editor_scene_importer_gltf.cpp
@@ -1793,22 +1793,22 @@ template <>
struct EditorSceneImporterGLTFInterpolate<Quat> {
Quat lerp(const Quat &a, const Quat &b, float c) const {
- ERR_FAIL_COND_V(a.is_normalized() == false, Quat());
- ERR_FAIL_COND_V(b.is_normalized() == false, Quat());
+ ERR_FAIL_COND_V(!a.is_normalized(), Quat());
+ ERR_FAIL_COND_V(!b.is_normalized(), Quat());
return a.slerp(b, c).normalized();
}
Quat catmull_rom(const Quat &p0, const Quat &p1, const Quat &p2, const Quat &p3, float c) {
- ERR_FAIL_COND_V(p1.is_normalized() == false, Quat());
- ERR_FAIL_COND_V(p2.is_normalized() == false, Quat());
+ ERR_FAIL_COND_V(!p1.is_normalized(), Quat());
+ ERR_FAIL_COND_V(!p2.is_normalized(), Quat());
return p1.slerp(p2, c).normalized();
}
Quat bezier(Quat start, Quat control_1, Quat control_2, Quat end, float t) {
- ERR_FAIL_COND_V(start.is_normalized() == false, Quat());
- ERR_FAIL_COND_V(end.is_normalized() == false, Quat());
+ ERR_FAIL_COND_V(!start.is_normalized(), Quat());
+ ERR_FAIL_COND_V(!end.is_normalized(), Quat());
return start.slerp(end, t).normalized();
}
diff --git a/editor/inspector_dock.cpp b/editor/inspector_dock.cpp
index 4f4980d83c..750fca2852 100644
--- a/editor/inspector_dock.cpp
+++ b/editor/inspector_dock.cpp
@@ -328,6 +328,21 @@ Container *InspectorDock::get_addon_area() {
return this;
}
+void InspectorDock::_notification(int p_what) {
+ switch (p_what) {
+ case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
+ set_theme(editor->get_gui_base()->get_theme());
+ resource_new_button->set_icon(get_icon("New", "EditorIcons"));
+ resource_load_button->set_icon(get_icon("Load", "EditorIcons"));
+ backward_button->set_icon(get_icon("Back", "EditorIcons"));
+ forward_button->set_icon(get_icon("Forward", "EditorIcons"));
+ history_menu->set_icon(get_icon("History", "EditorIcons"));
+ object_menu->set_icon(get_icon("Tools", "EditorIcons"));
+ warning->set_icon(get_icon("NodeWarning", "EditorIcons"));
+ } break;
+ }
+}
+
void InspectorDock::_bind_methods() {
ClassDB::bind_method("_menu_option", &InspectorDock::_menu_option);
diff --git a/editor/inspector_dock.h b/editor/inspector_dock.h
index 97ef6899dc..57d2a03295 100644
--- a/editor/inspector_dock.h
+++ b/editor/inspector_dock.h
@@ -118,6 +118,7 @@ class InspectorDock : public VBoxContainer {
protected:
static void _bind_methods();
+ void _notification(int p_what);
public:
void go_back();
diff --git a/editor/plugin_config_dialog.cpp b/editor/plugin_config_dialog.cpp
index 93bed035a5..a334f79f5a 100644
--- a/editor/plugin_config_dialog.cpp
+++ b/editor/plugin_config_dialog.cpp
@@ -76,7 +76,10 @@ void PluginConfigDialog::_on_confirmed() {
"extends EditorPlugin\n"
"\n"
"func _enter_tree():\n"
- "\tpass");
+ "\tpass\n"
+ "\n"
+ "func _exit_tree():\n"
+ "\tpass\n");
String script_path = path.plus_file(script_edit->get_text());
gdscript->set_path(script_path);
ResourceSaver::save(script_path, gdscript);
@@ -84,7 +87,7 @@ void PluginConfigDialog::_on_confirmed() {
}
//TODO: other languages
- emit_signal("plugin_ready", script.operator->(), active_edit->is_pressed() ? name_edit->get_text() : "");
+ emit_signal("plugin_ready", script.operator->(), active_edit->is_pressed() ? subfolder_edit->get_text() : "");
} else {
EditorNode::get_singleton()->get_project_settings()->update_plugins();
}
diff --git a/editor/plugins/animation_blend_space_2d_editor.cpp b/editor/plugins/animation_blend_space_2d_editor.cpp
index c4f8cdc3d7..394b888d0e 100644
--- a/editor/plugins/animation_blend_space_2d_editor.cpp
+++ b/editor/plugins/animation_blend_space_2d_editor.cpp
@@ -434,7 +434,7 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_draw() {
if (blend_space->get_snap().x > 0) {
- int prev_idx;
+ int prev_idx = 0;
for (int i = 0; i < s.x; i++) {
float v = blend_space->get_min_space().x + i * (blend_space->get_max_space().x - blend_space->get_min_space().x) / s.x;
@@ -450,7 +450,7 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_draw() {
if (blend_space->get_snap().y > 0) {
- int prev_idx;
+ int prev_idx = 0;
for (int i = 0; i < s.y; i++) {
float v = blend_space->get_max_space().y - i * (blend_space->get_max_space().y - blend_space->get_min_space().y) / s.y;
diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp
index f65c8cbd0d..a9bc5e77ac 100644
--- a/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/editor/plugins/canvas_item_editor_plugin.cpp
@@ -179,6 +179,10 @@ void CanvasItemEditor::_snap_if_closer_float(float p_value, float p_target_snap,
}
}
+bool CanvasItemEditor::_is_node_editable(const Node *p_node) {
+ return (!(p_node->has_meta("_edit_lock_") && p_node->get_meta("_edit_lock_")) && !(ClassDB::is_parent_class(p_node->get_parent()->get_class_name(), "Container") && ClassDB::is_parent_class(p_node->get_class_name(), "Control")));
+}
+
void CanvasItemEditor::_snap_if_closer_point(Point2 p_value, Point2 p_target_snap, Point2 &r_current_snap, bool (&r_snapped)[2], real_t rotation, float p_radius) {
Transform2D rot_trans = Transform2D(rotation, Point2());
p_value = rot_trans.inverse().xform(p_value);
@@ -411,7 +415,7 @@ void CanvasItemEditor::_expand_encompassing_rect_using_children(Rect2 &r_rect, c
}
}
- if (canvas_item && canvas_item->is_visible_in_tree() && (include_locked_nodes || !canvas_item->has_meta("_edit_lock_"))) {
+ if (canvas_item && canvas_item->is_visible_in_tree() && (include_locked_nodes || !_is_node_editable(canvas_item))) {
Transform2D xform = p_parent_xform * p_canvas_xform * canvas_item->get_transform();
Rect2 rect = canvas_item->_edit_get_rect();
if (r_first) {
@@ -509,7 +513,7 @@ void CanvasItemEditor::_get_canvas_items_at_pos(const Point2 &p_pos, Vector<_Sel
}
//Remove the item if invalid
- if (!canvas_item || duplicate || (canvas_item != scene && canvas_item->get_owner() != scene && !scene->is_editable_instance(canvas_item->get_owner())) || (canvas_item->has_meta("_edit_lock_") && canvas_item->get_meta("_edit_lock_"))) {
+ if (!canvas_item || duplicate || (canvas_item != scene && canvas_item->get_owner() != scene && !scene->is_editable_instance(canvas_item->get_owner())) || !_is_node_editable(canvas_item)) {
r_items.remove(i);
i--;
} else {
@@ -610,7 +614,7 @@ void CanvasItemEditor::_find_canvas_items_in_rect(const Rect2 &p_rect, Node *p_n
bool editable = p_node == scene || p_node->get_owner() == scene || scene->is_editable_instance(p_node->get_owner());
bool lock_children = p_node->has_meta("_edit_group_") && p_node->get_meta("_edit_group_");
- bool locked = p_node->has_meta("_edit_lock_") && p_node->get_meta("_edit_lock_");
+ bool locked = !_is_node_editable(p_node);
if (!lock_children || !editable) {
for (int i = p_node->get_child_count() - 1; i >= 0; i--) {
@@ -677,7 +681,7 @@ List<CanvasItem *> CanvasItemEditor::_get_edited_canvas_items(bool retreive_lock
List<CanvasItem *> selection;
for (Map<Node *, Object *>::Element *E = editor_selection->get_selection().front(); E; E = E->next()) {
CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E->key());
- if (canvas_item && canvas_item->is_visible_in_tree() && canvas_item->get_viewport() == EditorNode::get_singleton()->get_scene_root() && (retreive_locked || !canvas_item->has_meta("_edit_lock_"))) {
+ if (canvas_item && canvas_item->is_visible_in_tree() && canvas_item->get_viewport() == EditorNode::get_singleton()->get_scene_root() && (retreive_locked || _is_node_editable(canvas_item))) {
CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item);
if (se) {
selection.push_back(canvas_item);
@@ -2946,7 +2950,7 @@ void CanvasItemEditor::_draw_invisible_nodes_positions(Node *p_node, const Trans
_draw_invisible_nodes_positions(p_node->get_child(i), parent_xform, canvas_xform);
}
- if (canvas_item && !canvas_item->_edit_use_rect() && (!editor_selection->is_selected(canvas_item) || (canvas_item->has_meta("_edit_lock_") && canvas_item->get_meta("_edit_lock_")))) {
+ if (canvas_item && !canvas_item->_edit_use_rect() && (!editor_selection->is_selected(canvas_item) || !_is_node_editable(canvas_item))) {
Transform2D xform = transform * canvas_xform * parent_xform;
// Draw the node's position
@@ -5109,7 +5113,7 @@ bool CanvasItemEditorViewport::can_drop_data(const Point2 &p_point, const Varian
type == "AtlasTexture" ||
type == "LargeTexture") {
Ref<Texture> texture = Ref<Texture>(Object::cast_to<Texture>(*res));
- if (texture.is_valid() == false) {
+ if (!texture.is_valid()) {
continue;
}
} else {
diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h
index c788a63d56..4f8cc6ab5e 100644
--- a/editor/plugins/canvas_item_editor_plugin.h
+++ b/editor/plugins/canvas_item_editor_plugin.h
@@ -280,6 +280,10 @@ private:
Transform2D xform;
float length;
uint64_t last_pass;
+
+ BoneList() :
+ length(0.f),
+ last_pass(0) {}
};
uint64_t bone_last_frame;
@@ -365,6 +369,7 @@ private:
Ref<ShortCut> multiply_grid_step_shortcut;
Ref<ShortCut> divide_grid_step_shortcut;
+ bool _is_node_editable(const Node *p_node);
void _find_canvas_items_at_pos(const Point2 &p_pos, Node *p_node, Vector<_SelectResult> &r_items, int p_limit = 0, const Transform2D &p_parent_xform = Transform2D(), const Transform2D &p_canvas_xform = Transform2D());
void _get_canvas_items_at_pos(const Point2 &p_pos, Vector<_SelectResult> &r_items, int p_limit = 0);
void _get_bones_at_pos(const Point2 &p_pos, Vector<_SelectResult> &r_items);
diff --git a/editor/plugins/curve_editor_plugin.cpp b/editor/plugins/curve_editor_plugin.cpp
index 8b7156dcee..ace3012c10 100644
--- a/editor/plugins/curve_editor_plugin.cpp
+++ b/editor/plugins/curve_editor_plugin.cpp
@@ -782,12 +782,13 @@ bool CurvePreviewGenerator::handles(const String &p_type) const {
return p_type == "Curve";
}
-Ref<Texture> CurvePreviewGenerator::generate(const Ref<Resource> &p_from) {
+Ref<Texture> CurvePreviewGenerator::generate(const Ref<Resource> &p_from, const Size2 p_size) const {
Ref<Curve> curve_ref = p_from;
ERR_FAIL_COND_V(curve_ref.is_null(), Ref<Texture>());
Curve &curve = **curve_ref;
+ // FIXME: Should be ported to use p_size as done in b2633a97
int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size");
thumbnail_size *= EDSCALE;
Ref<Image> img_ref;
diff --git a/editor/plugins/curve_editor_plugin.h b/editor/plugins/curve_editor_plugin.h
index 255f359ed2..fa0b92e353 100644
--- a/editor/plugins/curve_editor_plugin.h
+++ b/editor/plugins/curve_editor_plugin.h
@@ -131,14 +131,14 @@ class CurveEditorPlugin : public EditorPlugin {
public:
CurveEditorPlugin(EditorNode *p_node);
- String get_name() const { return "Curve"; }
+ virtual String get_name() const { return "Curve"; }
};
class CurvePreviewGenerator : public EditorResourcePreviewGenerator {
GDCLASS(CurvePreviewGenerator, EditorResourcePreviewGenerator)
public:
- bool handles(const String &p_type) const;
- Ref<Texture> generate(const Ref<Resource> &p_from);
+ virtual bool handles(const String &p_type) const;
+ virtual Ref<Texture> generate(const Ref<Resource> &p_from, const Size2 p_size) const;
};
#endif // CURVE_EDITOR_PLUGIN_H
diff --git a/editor/plugins/resource_preloader_editor_plugin.cpp b/editor/plugins/resource_preloader_editor_plugin.cpp
index dd327d0a2c..bd4a35c9d8 100644
--- a/editor/plugins/resource_preloader_editor_plugin.cpp
+++ b/editor/plugins/resource_preloader_editor_plugin.cpp
@@ -44,7 +44,6 @@ void ResourcePreloaderEditor::_notification(int p_what) {
if (p_what == NOTIFICATION_ENTER_TREE) {
load->set_icon(get_icon("Folder", "EditorIcons"));
- _delete->set_icon(get_icon("Remove", "EditorIcons"));
}
if (p_what == NOTIFICATION_READY) {
@@ -138,15 +137,11 @@ void ResourcePreloaderEditor::_item_edited() {
}
}
-void ResourcePreloaderEditor::_delete_confirm_pressed() {
+void ResourcePreloaderEditor::_remove_resource(const String &p_to_remove) {
- if (!tree->get_selected())
- return;
-
- String to_remove = tree->get_selected()->get_text(0);
undo_redo->create_action(TTR("Delete Resource"));
- undo_redo->add_do_method(preloader, "remove_resource", to_remove);
- undo_redo->add_undo_method(preloader, "add_resource", to_remove, preloader->get_resource(to_remove));
+ undo_redo->add_do_method(preloader, "remove_resource", p_to_remove);
+ undo_redo->add_undo_method(preloader, "add_resource", p_to_remove, preloader->get_resource(p_to_remove));
undo_redo->add_do_method(this, "_update_library");
undo_redo->add_undo_method(this, "_update_library");
undo_redo->commit_action();
@@ -184,21 +179,6 @@ void ResourcePreloaderEditor::_paste_pressed() {
undo_redo->commit_action();
}
-void ResourcePreloaderEditor::_delete_pressed() {
-
- if (!tree->get_selected())
- return;
-
- _delete_confirm_pressed(); //it has undo.. why bother with a dialog..
- /*
- dialog->set_title("Confirm...");
- dialog->set_text("Remove Resource '"+tree->get_selected()->get_text(0)+"' ?");
- //dialog->get_cancel()->set_text("Cancel");
- //dialog->get_ok()->show();
- dialog->get_ok()->set_text("Remove");
- dialog->popup_centered(Size2(300,60));*/
-}
-
void ResourcePreloaderEditor::_update_library() {
tree->clear();
@@ -228,17 +208,20 @@ void ResourcePreloaderEditor::_update_library() {
ERR_CONTINUE(r.is_null());
- ti->set_tooltip(0, r->get_path());
+ String type = r->get_class();
+ ti->set_icon(0, EditorNode::get_singleton()->get_class_icon(type, "Object"));
+ ti->set_tooltip(0, TTR("Instance:") + " " + r->get_path() + "\n" + TTR("Type:") + " " + type);
+
ti->set_text(1, r->get_path());
- ti->add_button(1, get_icon("InstanceOptions", "EditorIcons"), BUTTON_SUBSCENE, false, TTR("Open in Editor"));
- ti->set_tooltip(1, TTR("Instance:") + " " + r->get_path() + "\n" + TTR("Type:") + " " + r->get_class());
ti->set_editable(1, false);
ti->set_selectable(1, false);
- String type = r->get_class();
- ti->set_text(2, type);
- ti->set_selectable(2, false);
- ti->set_icon(2, EditorNode::get_singleton()->get_class_icon(type, ""));
+ if (type == "PackedScene") {
+ ti->add_button(1, get_icon("InstanceOptions", "EditorIcons"), BUTTON_OPEN_SCENE, false, TTR("Open in Editor"));
+ } else {
+ ti->add_button(1, get_icon("Load", "EditorIcons"), BUTTON_EDIT_RESOURCE, false, TTR("Open in Editor"));
+ }
+ ti->add_button(1, get_icon("Remove", "EditorIcons"), BUTTON_REMOVE, false, TTR("Remove"));
}
//player->add_resource("default",resource);
@@ -249,10 +232,16 @@ void ResourcePreloaderEditor::_cell_button_pressed(Object *p_item, int p_column,
TreeItem *item = Object::cast_to<TreeItem>(p_item);
ERR_FAIL_COND(!item);
- String rpath = item->get_text(p_column);
-
- if (p_id == BUTTON_SUBSCENE) {
+ if (p_id == BUTTON_OPEN_SCENE) {
+ String rpath = item->get_text(p_column);
EditorInterface::get_singleton()->open_scene_from_path(rpath);
+
+ } else if (p_id == BUTTON_EDIT_RESOURCE) {
+ RES r = preloader->get_resource(item->get_text(0));
+ EditorInterface::get_singleton()->edit_resource(r);
+
+ } else if (p_id == BUTTON_REMOVE) {
+ _remove_resource(item->get_text(0));
}
}
@@ -365,12 +354,11 @@ void ResourcePreloaderEditor::_bind_methods() {
ClassDB::bind_method(D_METHOD("_gui_input"), &ResourcePreloaderEditor::_gui_input);
ClassDB::bind_method(D_METHOD("_load_pressed"), &ResourcePreloaderEditor::_load_pressed);
ClassDB::bind_method(D_METHOD("_item_edited"), &ResourcePreloaderEditor::_item_edited);
- ClassDB::bind_method(D_METHOD("_delete_pressed"), &ResourcePreloaderEditor::_delete_pressed);
ClassDB::bind_method(D_METHOD("_paste_pressed"), &ResourcePreloaderEditor::_paste_pressed);
- ClassDB::bind_method(D_METHOD("_delete_confirm_pressed"), &ResourcePreloaderEditor::_delete_confirm_pressed);
ClassDB::bind_method(D_METHOD("_files_load_request"), &ResourcePreloaderEditor::_files_load_request);
ClassDB::bind_method(D_METHOD("_update_library"), &ResourcePreloaderEditor::_update_library);
ClassDB::bind_method(D_METHOD("_cell_button_pressed"), &ResourcePreloaderEditor::_cell_button_pressed);
+ ClassDB::bind_method(D_METHOD("_remove_resource", "to_remove"), &ResourcePreloaderEditor::_remove_resource);
ClassDB::bind_method(D_METHOD("get_drag_data_fw"), &ResourcePreloaderEditor::get_drag_data_fw);
ClassDB::bind_method(D_METHOD("can_drop_data_fw"), &ResourcePreloaderEditor::can_drop_data_fw);
@@ -391,9 +379,6 @@ ResourcePreloaderEditor::ResourcePreloaderEditor() {
load->set_tooltip(TTR("Load Resource"));
hbc->add_child(load);
- _delete = memnew(Button);
- hbc->add_child(_delete);
-
paste = memnew(Button);
paste->set_text(TTR("Paste"));
hbc->add_child(paste);
@@ -403,13 +388,11 @@ ResourcePreloaderEditor::ResourcePreloaderEditor() {
tree = memnew(Tree);
tree->connect("button_pressed", this, "_cell_button_pressed");
- tree->set_columns(3);
- tree->set_column_min_width(0, 3);
- tree->set_column_min_width(1, 1);
- tree->set_column_min_width(2, 1);
+ tree->set_columns(2);
+ tree->set_column_min_width(0, 2);
+ tree->set_column_min_width(1, 3);
tree->set_column_expand(0, true);
tree->set_column_expand(1, true);
- tree->set_column_expand(2, true);
tree->set_v_size_flags(SIZE_EXPAND_FILL);
tree->set_drag_forwarding(this);
@@ -419,10 +402,8 @@ ResourcePreloaderEditor::ResourcePreloaderEditor() {
add_child(dialog);
load->connect("pressed", this, "_load_pressed");
- _delete->connect("pressed", this, "_delete_pressed");
paste->connect("pressed", this, "_paste_pressed");
file->connect("files_selected", this, "_files_load_request");
- //dialog->connect("confirmed", this,"_delete_confirm_pressed");
tree->connect("item_edited", this, "_item_edited");
loading_scene = false;
}
diff --git a/editor/plugins/resource_preloader_editor_plugin.h b/editor/plugins/resource_preloader_editor_plugin.h
index e737157785..0a8238ce18 100644
--- a/editor/plugins/resource_preloader_editor_plugin.h
+++ b/editor/plugins/resource_preloader_editor_plugin.h
@@ -43,11 +43,12 @@ class ResourcePreloaderEditor : public PanelContainer {
GDCLASS(ResourcePreloaderEditor, PanelContainer);
enum {
- BUTTON_SUBSCENE = 0,
+ BUTTON_OPEN_SCENE,
+ BUTTON_EDIT_RESOURCE,
+ BUTTON_REMOVE
};
Button *load;
- Button *_delete;
Button *paste;
Tree *tree;
bool loading_scene;
@@ -62,8 +63,7 @@ class ResourcePreloaderEditor : public PanelContainer {
void _load_scene_pressed();
void _files_load_request(const Vector<String> &p_paths);
void _paste_pressed();
- void _delete_pressed();
- void _delete_confirm_pressed();
+ void _remove_resource(const String &p_to_remove);
void _update_library();
void _cell_button_pressed(Object *p_item, int p_column, int p_id);
void _item_edited();
diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp
index d2a9830fe0..d26e1a39f6 100644
--- a/editor/plugins/script_editor_plugin.cpp
+++ b/editor/plugins/script_editor_plugin.cpp
@@ -96,7 +96,7 @@ public:
}
}
- RES get_cached_resource(const String &p_path) {
+ virtual RES get_cached_resource(const String &p_path) {
Map<String, Cache>::Element *E = cached.find(p_path);
if (!E) {
@@ -134,9 +134,11 @@ public:
max_cache_size = 128;
max_time_cache = 5 * 60 * 1000; //minutes, five
}
+
+ virtual ~EditorScriptCodeCompletionCache() {}
};
-void ScriptEditorQuickOpen::popup(const Vector<String> &p_functions, bool p_dontclear) {
+void ScriptEditorQuickOpen::popup_dialog(const Vector<String> &p_functions, bool p_dontclear) {
popup_centered_ratio(0.6);
if (p_dontclear)
@@ -968,11 +970,11 @@ void ScriptEditor::_menu_option(int p_option) {
} break;
case SEARCH_HELP: {
- help_search_dialog->popup();
+ help_search_dialog->popup_dialog();
} break;
case SEARCH_CLASSES: {
- help_index->popup();
+ help_index->popup_dialog();
} break;
case SEARCH_WEBSITE: {
@@ -1204,7 +1206,7 @@ void ScriptEditor::_menu_option(int p_option) {
case SEARCH_CLASSES: {
- help_index->popup();
+ help_index->popup_dialog();
help_index->call_deferred("select_class", help->get_class());
} break;
case HELP_SEARCH_FIND: {
@@ -1958,7 +1960,7 @@ bool ScriptEditor::edit(const RES &p_resource, int p_line, int p_col, bool p_gra
// doesn't have it, make a new one
- ScriptEditorBase *se;
+ ScriptEditorBase *se = NULL;
for (int i = script_editor_func_count - 1; i >= 0; i--) {
se = script_editor_funcs[i](p_resource);
@@ -2727,11 +2729,11 @@ void ScriptEditor::set_live_auto_reload_running_scripts(bool p_enabled) {
}
void ScriptEditor::_help_index(String p_text) {
- help_index->popup();
+ help_index->popup_dialog();
}
void ScriptEditor::_help_search(String p_text) {
- help_search_dialog->popup(p_text);
+ help_search_dialog->popup_dialog(p_text);
}
void ScriptEditor::_open_script_request(const String &p_path) {
diff --git a/editor/plugins/script_editor_plugin.h b/editor/plugins/script_editor_plugin.h
index 120755b5af..28c07393f7 100644
--- a/editor/plugins/script_editor_plugin.h
+++ b/editor/plugins/script_editor_plugin.h
@@ -67,7 +67,7 @@ protected:
static void _bind_methods();
public:
- void popup(const Vector<String> &p_functions, bool p_dontclear = false);
+ void popup_dialog(const Vector<String> &p_functions, bool p_dontclear = false);
ScriptEditorQuickOpen();
};
diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp
index 23babdf07b..9b968c3523 100644
--- a/editor/plugins/script_text_editor.cpp
+++ b/editor/plugins/script_text_editor.cpp
@@ -940,7 +940,7 @@ void ScriptTextEditor::_edit_option(int p_op) {
} break;
case SEARCH_LOCATE_FUNCTION: {
- quick_open->popup(get_functions());
+ quick_open->popup_dialog(get_functions());
quick_open->set_title(TTR("Go to Function"));
} break;
case SEARCH_GOTO_LINE: {
diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp
index 114610c562..f57614b3b3 100644
--- a/editor/plugins/spatial_editor_plugin.cpp
+++ b/editor/plugins/spatial_editor_plugin.cpp
@@ -534,9 +534,9 @@ void SpatialEditorViewport::_update_name() {
String view_mode = orthogonal ? TTR("Orthogonal") : TTR("Perspective");
if (name != "")
- view_menu->set_text("[ " + name + " " + view_mode + " ]");
+ view_menu->set_text(name + " " + view_mode);
else
- view_menu->set_text("[ " + view_mode + " ]");
+ view_menu->set_text(view_mode);
view_menu->set_size(Vector2(0, 0)); // resets the button size
}
@@ -2124,7 +2124,7 @@ void SpatialEditorViewport::_notification(int p_what) {
_update_freelook(delta);
Node *scene_root = editor->get_scene_tree_dock()->get_editor_data()->get_edited_scene_root();
- if (previewing_cinema == true && scene_root != NULL) {
+ if (previewing_cinema && scene_root != NULL) {
Camera *cam = scene_root->get_viewport()->get_camera();
if (cam != NULL && cam != previewing) {
//then switch the viewport's camera to the scene's viewport camera
@@ -2260,6 +2260,12 @@ void SpatialEditorViewport::_notification(int p_what) {
surface->connect("mouse_exited", this, "_surface_mouse_exit");
surface->connect("focus_entered", this, "_surface_focus_enter");
surface->connect("focus_exited", this, "_surface_focus_exit");
+ view_menu->set_flat(false);
+ view_menu->add_style_override("normal", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles"));
+ view_menu->add_style_override("hover", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles"));
+ view_menu->add_style_override("pressed", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles"));
+ view_menu->add_style_override("focus", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles"));
+ view_menu->add_style_override("disabled", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles"));
info_label->add_style_override("normal", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles"));
fps_label->add_style_override("normal", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles"));
cinema_label->add_style_override("normal", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles"));
@@ -3421,7 +3427,6 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed
view_menu = memnew(MenuButton);
surface->add_child(view_menu);
view_menu->set_position(Point2(4, 4) * EDSCALE);
- view_menu->set_self_modulate(Color(1, 1, 1, 0.5));
view_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("spatial_editor/top_view"), VIEW_TOP);
view_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("spatial_editor/bottom_view"), VIEW_BOTTOM);
view_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("spatial_editor/left_view"), VIEW_LEFT);
diff --git a/editor/plugins/tile_map_editor_plugin.cpp b/editor/plugins/tile_map_editor_plugin.cpp
index aa4338d775..27c3ff960b 100644
--- a/editor/plugins/tile_map_editor_plugin.cpp
+++ b/editor/plugins/tile_map_editor_plugin.cpp
@@ -43,8 +43,8 @@ void TileMapEditor::_notification(int p_what) {
case NOTIFICATION_PROCESS: {
- if (bucket_queue.size() && canvas_item_editor) {
- canvas_item_editor->update();
+ if (bucket_queue.size() && canvas_item_editor_viewport) {
+ canvas_item_editor_viewport->update();
}
} break;
@@ -97,27 +97,27 @@ void TileMapEditor::_menu_option(int p_option) {
// immediately without pressing the left mouse button first
tool = TOOL_NONE;
- canvas_item_editor->update();
+ canvas_item_editor_viewport->update();
} break;
case OPTION_BUCKET: {
tool = TOOL_BUCKET;
- canvas_item_editor->update();
+ canvas_item_editor_viewport->update();
} break;
case OPTION_PICK_TILE: {
tool = TOOL_PICKING;
- canvas_item_editor->update();
+ canvas_item_editor_viewport->update();
} break;
case OPTION_SELECT: {
tool = TOOL_SELECTING;
selection_active = false;
- canvas_item_editor->update();
+ canvas_item_editor_viewport->update();
} break;
case OPTION_COPY: {
@@ -126,7 +126,7 @@ void TileMapEditor::_menu_option(int p_option) {
if (selection_active) {
tool = TOOL_PASTING;
- canvas_item_editor->update();
+ canvas_item_editor_viewport->update();
}
} break;
case OPTION_ERASE_SELECTION: {
@@ -141,7 +141,7 @@ void TileMapEditor::_menu_option(int p_option) {
selection_active = false;
copydata.clear();
- canvas_item_editor->update();
+ canvas_item_editor_viewport->update();
} break;
case OPTION_FIX_INVALID: {
@@ -165,7 +165,7 @@ void TileMapEditor::_menu_option(int p_option) {
tool = TOOL_PASTING;
- canvas_item_editor->update();
+ canvas_item_editor_viewport->update();
}
} break;
}
@@ -182,13 +182,13 @@ void TileMapEditor::_palette_multi_selected(int index, bool selected) {
void TileMapEditor::_canvas_mouse_enter() {
mouse_over = true;
- canvas_item_editor->update();
+ canvas_item_editor_viewport->update();
}
void TileMapEditor::_canvas_mouse_exit() {
mouse_over = false;
- canvas_item_editor->update();
+ canvas_item_editor_viewport->update();
}
Vector<int> TileMapEditor::get_selected_tiles() const {
@@ -318,7 +318,7 @@ void TileMapEditor::_manual_toggled(bool p_enabled) {
void TileMapEditor::_text_entered(const String &p_text) {
- canvas_item_editor->grab_focus();
+ canvas_item_editor_viewport->grab_focus();
}
void TileMapEditor::_text_changed(const String &p_text) {
@@ -524,7 +524,7 @@ void TileMapEditor::_pick_tile(const Point2 &p_pos) {
transp->set_pressed(node->is_cell_transposed(p_pos.x, p_pos.y));
_update_transform_buttons();
- canvas_item_editor->update();
+ canvas_item_editor_viewport->update();
}
PoolVector<Vector2> TileMapEditor::_bucket_fill(const Point2i &p_start, bool erase, bool preview) {
@@ -671,7 +671,7 @@ void TileMapEditor::_select(const Point2i &p_from, const Point2i &p_to) {
rectangle.position = begin;
rectangle.size = end - begin;
- canvas_item_editor->update();
+ canvas_item_editor_viewport->update();
}
void TileMapEditor::_erase_selection() {
@@ -978,7 +978,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
paint_undo.clear();
- canvas_item_editor->update();
+ canvas_item_editor_viewport->update();
}
} else if (tool == TOOL_RECTANGLE_PAINT) {
@@ -995,7 +995,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
}
_finish_undo();
- canvas_item_editor->update();
+ canvas_item_editor_viewport->update();
}
} else if (tool == TOOL_PASTING) {
@@ -1011,12 +1011,12 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
}
_finish_undo();
- canvas_item_editor->update();
+ canvas_item_editor_viewport->update();
return true; // We want to keep the Pasting tool
} else if (tool == TOOL_SELECTING) {
- canvas_item_editor->update();
+ canvas_item_editor_viewport->update();
} else if (tool == TOOL_BUCKET) {
@@ -1055,7 +1055,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
tool = TOOL_NONE;
selection_active = false;
- canvas_item_editor->update();
+ canvas_item_editor_viewport->update();
return true;
}
@@ -1065,7 +1065,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
tool = TOOL_NONE;
copydata.clear();
- canvas_item_editor->update();
+ canvas_item_editor_viewport->update();
return true;
}
@@ -1106,7 +1106,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
_finish_undo();
if (tool == TOOL_RECTANGLE_ERASE || tool == TOOL_LINE_ERASE) {
- canvas_item_editor->update();
+ canvas_item_editor_viewport->update();
}
tool = TOOL_NONE;
@@ -1149,7 +1149,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
if (new_over_tile != over_tile) {
over_tile = new_over_tile;
- canvas_item_editor->update();
+ canvas_item_editor_viewport->update();
}
if (show_tile_info) {
@@ -1235,7 +1235,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
_set_cell(points[i], invalid_cell);
}
- canvas_item_editor->update();
+ canvas_item_editor_viewport->update();
}
return true;
@@ -1294,7 +1294,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
tool = TOOL_NONE;
- canvas_item_editor->update();
+ canvas_item_editor_viewport->update();
return true;
}
@@ -1308,13 +1308,13 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
// NOTE: We do not set tool = TOOL_PAINTING as this begins painting
// immediately without pressing the left mouse button first
tool = TOOL_NONE;
- canvas_item_editor->update();
+ canvas_item_editor_viewport->update();
return true;
}
if (ED_IS_SHORTCUT("tile_map_editor/bucket_fill", p_event)) {
tool = TOOL_BUCKET;
- canvas_item_editor->update();
+ canvas_item_editor_viewport->update();
return true;
}
@@ -1327,7 +1327,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
tool = TOOL_SELECTING;
selection_active = false;
- canvas_item_editor->update();
+ canvas_item_editor_viewport->update();
return true;
}
@@ -1337,7 +1337,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
if (selection_active) {
tool = TOOL_PASTING;
- canvas_item_editor->update();
+ canvas_item_editor_viewport->update();
return true;
}
@@ -1354,7 +1354,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
tool = TOOL_PASTING;
- canvas_item_editor->update();
+ canvas_item_editor_viewport->update();
return true;
}
}
@@ -1368,21 +1368,21 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
flip_h = !flip_h;
mirror_x->set_pressed(flip_h);
_update_transform_buttons();
- canvas_item_editor->update();
+ canvas_item_editor_viewport->update();
return true;
}
if (ED_IS_SHORTCUT("tile_map_editor/mirror_y", p_event)) {
flip_v = !flip_v;
mirror_y->set_pressed(flip_v);
_update_transform_buttons();
- canvas_item_editor->update();
+ canvas_item_editor_viewport->update();
return true;
}
if (ED_IS_SHORTCUT("tile_map_editor/transpose", p_event)) {
transpose = !transpose;
transp->set_pressed(transpose);
_update_transform_buttons();
- canvas_item_editor->update();
+ canvas_item_editor_viewport->update();
return true;
}
}
@@ -1396,8 +1396,7 @@ void TileMapEditor::forward_canvas_draw_over_viewport(Control *p_overlay) {
return;
Transform2D cell_xf = node->get_cell_transform();
-
- Transform2D xform = p_overlay->get_canvas_transform() * node->get_global_transform();
+ Transform2D xform = CanvasItemEditor::get_singleton()->get_canvas_transform() * node->get_global_transform();
Transform2D xform_inv = xform.affine_inverse();
Size2 screen_size = p_overlay->get_size();
@@ -1608,8 +1607,8 @@ void TileMapEditor::edit(Node *p_tile_map) {
search_box->set_text("");
- if (!canvas_item_editor) {
- canvas_item_editor = CanvasItemEditor::get_singleton()->get_viewport_control();
+ if (!canvas_item_editor_viewport) {
+ canvas_item_editor_viewport = CanvasItemEditor::get_singleton()->get_viewport_control();
}
if (node)
@@ -1617,20 +1616,20 @@ void TileMapEditor::edit(Node *p_tile_map) {
if (p_tile_map) {
node = Object::cast_to<TileMap>(p_tile_map);
- if (!canvas_item_editor->is_connected("mouse_entered", this, "_canvas_mouse_enter"))
- canvas_item_editor->connect("mouse_entered", this, "_canvas_mouse_enter");
- if (!canvas_item_editor->is_connected("mouse_exited", this, "_canvas_mouse_exit"))
- canvas_item_editor->connect("mouse_exited", this, "_canvas_mouse_exit");
+ if (!canvas_item_editor_viewport->is_connected("mouse_entered", this, "_canvas_mouse_enter"))
+ canvas_item_editor_viewport->connect("mouse_entered", this, "_canvas_mouse_enter");
+ if (!canvas_item_editor_viewport->is_connected("mouse_exited", this, "_canvas_mouse_exit"))
+ canvas_item_editor_viewport->connect("mouse_exited", this, "_canvas_mouse_exit");
_update_palette();
} else {
node = NULL;
- if (canvas_item_editor->is_connected("mouse_entered", this, "_canvas_mouse_enter"))
- canvas_item_editor->disconnect("mouse_entered", this, "_canvas_mouse_enter");
- if (canvas_item_editor->is_connected("mouse_exited", this, "_canvas_mouse_exit"))
- canvas_item_editor->disconnect("mouse_exited", this, "_canvas_mouse_exit");
+ if (canvas_item_editor_viewport->is_connected("mouse_entered", this, "_canvas_mouse_enter"))
+ canvas_item_editor_viewport->disconnect("mouse_entered", this, "_canvas_mouse_enter");
+ if (canvas_item_editor_viewport->is_connected("mouse_exited", this, "_canvas_mouse_exit"))
+ canvas_item_editor_viewport->disconnect("mouse_exited", this, "_canvas_mouse_exit");
_update_palette();
}
@@ -1645,8 +1644,8 @@ void TileMapEditor::_tileset_settings_changed() {
_update_palette();
- if (canvas_item_editor)
- canvas_item_editor->update();
+ if (canvas_item_editor_viewport)
+ canvas_item_editor_viewport->update();
}
void TileMapEditor::_icon_size_changed(float p_value) {
@@ -1730,7 +1729,7 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) {
node = NULL;
manual_autotile = false;
manual_position = Vector2(0, 0);
- canvas_item_editor = NULL;
+ canvas_item_editor_viewport = NULL;
editor = p_editor;
undo_redo = editor->get_undo_redo();
diff --git a/editor/plugins/tile_map_editor_plugin.h b/editor/plugins/tile_map_editor_plugin.h
index 74aece6f47..3d44647a1b 100644
--- a/editor/plugins/tile_map_editor_plugin.h
+++ b/editor/plugins/tile_map_editor_plugin.h
@@ -82,7 +82,7 @@ class TileMapEditor : public VBoxContainer {
EditorNode *editor;
UndoRedo *undo_redo;
- Control *canvas_item_editor;
+ Control *canvas_item_editor_viewport;
LineEdit *search_box;
HSlider *size_slider;
diff --git a/editor/project_export.cpp b/editor/project_export.cpp
index fa6dce1771..3ec49e187f 100644
--- a/editor/project_export.cpp
+++ b/editor/project_export.cpp
@@ -638,10 +638,10 @@ bool ProjectExportDialog::_fill_tree(EditorFileSystemDirectory *p_dir, TreeItem
for (int i = 0; i < p_dir->get_subdir_count(); i++) {
TreeItem *subdir = include_files->create_item(p_item);
- if (_fill_tree(p_dir->get_subdir(i), subdir, current, p_only_scenes) == false) {
- memdelete(subdir);
- } else {
+ if (_fill_tree(p_dir->get_subdir(i), subdir, current, p_only_scenes)) {
used = true;
+ } else {
+ memdelete(subdir);
}
}
diff --git a/editor/quick_open.cpp b/editor/quick_open.cpp
index 497596a508..e48a0022e8 100644
--- a/editor/quick_open.cpp
+++ b/editor/quick_open.cpp
@@ -32,7 +32,7 @@
#include "core/os/keyboard.h"
-void EditorQuickOpen::popup(const StringName &p_base, bool p_enable_multi, bool p_add_dirs, bool p_dontclear) {
+void EditorQuickOpen::popup_dialog(const StringName &p_base, bool p_enable_multi, bool p_add_dirs, bool p_dontclear) {
add_directories = p_add_dirs;
popup_centered_ratio(0.6);
diff --git a/editor/quick_open.h b/editor/quick_open.h
index ffea6b52bd..5451d5a08c 100644
--- a/editor/quick_open.h
+++ b/editor/quick_open.h
@@ -66,7 +66,7 @@ public:
String get_selected() const;
Vector<String> get_selected_files() const;
- void popup(const StringName &p_base, bool p_enable_multi = false, bool p_add_dirs = false, bool p_dontclear = false);
+ void popup_dialog(const StringName &p_base, bool p_enable_multi = false, bool p_add_dirs = false, bool p_dontclear = false);
EditorQuickOpen();
};
diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp
index 11a0a42b9e..a6a014f3bd 100644
--- a/editor/scene_tree_dock.cpp
+++ b/editor/scene_tree_dock.cpp
@@ -689,6 +689,13 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
}
}
} break;
+ case TOOL_OPEN_DOCUMENTATION: {
+ List<Node *> selection = editor_selection->get_selected_node_list();
+ for (int i = 0; i < selection.size(); i++) {
+ ScriptEditor::get_singleton()->goto_help("class_name:" + selection[i]->get_class());
+ }
+ EditorNode::get_singleton()->set_visible_editor(EditorNode::EDITOR_SCRIPT);
+ } break;
case TOOL_SCENE_EDITABLE_CHILDREN: {
List<Node *> selection = editor_selection->get_selected_node_list();
List<Node *>::Element *e = selection.front();
@@ -790,7 +797,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
case TOOL_CREATE_USER_INTERFACE:
case TOOL_CREATE_FAVORITE: {
- Node *new_node;
+ Node *new_node = NULL;
if (TOOL_CREATE_FAVORITE == p_tool) {
String name = selected_favorite_root.get_slicec(' ', 0);
@@ -829,6 +836,8 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
editor_data->get_undo_redo().commit_action();
editor->edit_node(new_node);
+ editor_selection->clear();
+ editor_selection->add_node(new_node);
} break;
@@ -2027,6 +2036,7 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
menu->clear();
+ Ref<Script> existing_script;
if (selection.size() == 1) {
Node *selected = selection[0];
@@ -2041,16 +2051,20 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
menu->add_icon_shortcut(get_icon("Add", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/add_child_node"), TOOL_NEW);
menu->add_icon_shortcut(get_icon("Instance", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/instance_scene"), TOOL_INSTANCE);
menu->add_separator();
+ existing_script = selected->get_script();
+ }
- menu->add_icon_shortcut(get_icon("ScriptCreate", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/attach_script"), TOOL_ATTACH_SCRIPT);
- Ref<Script> existing = selected->get_script();
- if (existing.is_valid()) {
- menu->add_icon_shortcut(get_icon("ScriptRemove", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/clear_script"), TOOL_CLEAR_SCRIPT);
- }
- menu->add_separator();
+ menu->add_icon_shortcut(get_icon("ScriptCreate", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/attach_script"), TOOL_ATTACH_SCRIPT);
+ if (selection.size() > 1 || existing_script.is_valid()) {
+ menu->add_icon_shortcut(get_icon("ScriptRemove", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/clear_script"), TOOL_CLEAR_SCRIPT);
+ }
+
+ menu->add_separator();
+ if (selection.size() == 1) {
menu->add_icon_shortcut(get_icon("Rename", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/rename"), TOOL_RENAME);
}
menu->add_icon_shortcut(get_icon("Reload", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/change_node_type"), TOOL_REPLACE);
+
if (scene_tree->get_selected() != edited_scene) {
menu->add_separator();
menu->add_icon_shortcut(get_icon("MoveUp", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/move_up"), TOOL_MOVE_UP);
@@ -2086,10 +2100,6 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
menu->set_item_checked(menu->get_item_idx_from_text(TTR("Load As Placeholder")), placeholder);
}
}
- } else {
- menu->add_separator();
- menu->add_icon_shortcut(get_icon("ScriptCreate", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/attach_script"), TOOL_ATTACH_SCRIPT);
- menu->add_icon_shortcut(get_icon("ScriptRemove", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/clear_script"), TOOL_CLEAR_SCRIPT);
}
if (selection.size() > 1) {
@@ -2098,6 +2108,9 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
menu->add_icon_shortcut(get_icon("Rename", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/batch_rename"), TOOL_BATCH_RENAME);
}
menu->add_separator();
+ menu->add_icon_item(get_icon("Help", "EditorIcons"), TTR("Open documentation"), TOOL_OPEN_DOCUMENTATION);
+
+ menu->add_separator();
menu->add_icon_shortcut(get_icon("Remove", "EditorIcons"), ED_SHORTCUT("scene_tree/delete", TTR("Delete Node(s)"), KEY_DELETE), TOOL_ERASE);
menu->set_size(Size2(1, 1));
menu->set_position(p_menu_pos);
diff --git a/editor/scene_tree_dock.h b/editor/scene_tree_dock.h
index 269b0b69db..eea34a3ec5 100644
--- a/editor/scene_tree_dock.h
+++ b/editor/scene_tree_dock.h
@@ -75,6 +75,7 @@ class SceneTreeDock : public VBoxContainer {
TOOL_ERASE,
TOOL_COPY_NODE_PATH,
TOOL_BUTTON_MAX,
+ TOOL_OPEN_DOCUMENTATION,
TOOL_SCENE_EDITABLE_CHILDREN,
TOOL_SCENE_USE_PLACEHOLDER,
TOOL_SCENE_MAKE_LOCAL,
diff --git a/editor/spatial_editor_gizmos.cpp b/editor/spatial_editor_gizmos.cpp
index 96bca86f83..a321cb16c5 100644
--- a/editor/spatial_editor_gizmos.cpp
+++ b/editor/spatial_editor_gizmos.cpp
@@ -4201,21 +4201,16 @@ void JointSpatialGizmoPlugin::CreateGeneric6DOFJointGizmo(
float cs = 0.25;
for (int ax = 0; ax < 3; ax++) {
- /*r_points.push_back(p_offset.translated(Vector3(+cs,0,0)).origin);
- r_points.push_back(p_offset.translated(Vector3(-cs,0,0)).origin);
- r_points.push_back(p_offset.translated(Vector3(0,+cs,0)).origin);
- r_points.push_back(p_offset.translated(Vector3(0,-cs,0)).origin);
- r_points.push_back(p_offset.translated(Vector3(0,0,+cs*2)).origin);
- r_points.push_back(p_offset.translated(Vector3(0,0,-cs*2)).origin); */
-
- float ll;
- float ul;
- float lll;
- float lul;
-
- int a1, a2, a3;
- bool enable_ang;
- bool enable_lin;
+ float ll = 0;
+ float ul = 0;
+ float lll = 0;
+ float lul = 0;
+
+ int a1 = 0;
+ int a2 = 0;
+ int a3 = 0;
+ bool enable_ang = false;
+ bool enable_lin = false;
switch (ax) {
case 0:
diff --git a/main/main.cpp b/main/main.cpp
index 3eb0b7f354..41ae368087 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -115,9 +115,11 @@ static bool editor = false;
static bool project_manager = false;
static String locale;
static bool show_help = false;
-static bool auto_build_solutions = false;
static bool auto_quit = false;
static OS::ProcessID allow_focus_steal_pid = 0;
+#ifdef TOOLS_ENABLED
+static bool auto_build_solutions = false;
+#endif
// Display
@@ -871,13 +873,17 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/driver/driver_fallback", PropertyInfo(Variant::STRING, "rendering/quality/driver/driver_fallback", PROPERTY_HINT_ENUM, "Best,Never"));
GLOBAL_DEF("display/window/size/width", 1024);
+ ProjectSettings::get_singleton()->set_custom_property_info("display/window/size/width", PropertyInfo(Variant::INT, "display/window/size/width", PROPERTY_HINT_RANGE, "0,7680,or_greater")); // 8K resolution
GLOBAL_DEF("display/window/size/height", 600);
+ ProjectSettings::get_singleton()->set_custom_property_info("display/window/size/height", PropertyInfo(Variant::INT, "display/window/size/height", PROPERTY_HINT_RANGE, "0,4320,or_greater")); // 8K resolution
GLOBAL_DEF("display/window/size/resizable", true);
GLOBAL_DEF("display/window/size/borderless", false);
GLOBAL_DEF("display/window/size/fullscreen", false);
GLOBAL_DEF("display/window/size/always_on_top", false);
GLOBAL_DEF("display/window/size/test_width", 0);
+ ProjectSettings::get_singleton()->set_custom_property_info("display/window/size/test_width", PropertyInfo(Variant::INT, "display/window/size/test_width", PROPERTY_HINT_RANGE, "0,7680,or_greater")); // 8K resolution
GLOBAL_DEF("display/window/size/test_height", 0);
+ ProjectSettings::get_singleton()->set_custom_property_info("display/window/size/test_height", PropertyInfo(Variant::INT, "display/window/size/test_height", PROPERTY_HINT_RANGE, "0,4320,or_greater")); // 8K resolution
if (use_custom_res) {
diff --git a/main/tests/test_io.cpp b/main/tests/test_io.cpp
index c1b4b8af9b..4e43ee6a54 100644
--- a/main/tests/test_io.cpp
+++ b/main/tests/test_io.cpp
@@ -50,7 +50,7 @@ class TestMainLoop : public MainLoop {
bool quit;
public:
- virtual void input_event(const InputEvent &p_event) {
+ virtual void input_event(const Ref<InputEvent> &p_event) {
}
virtual bool idle(float p_time) {
return false;
diff --git a/main/tests/test_oa_hash_map.cpp b/main/tests/test_oa_hash_map.cpp
index 0e34faace7..26e728d3aa 100644
--- a/main/tests/test_oa_hash_map.cpp
+++ b/main/tests/test_oa_hash_map.cpp
@@ -48,7 +48,7 @@ MainLoop *test() {
map.set(1337, 21);
map.set(42, 11880);
- int value;
+ int value = 0;
map.lookup(42, value);
OS::get_singleton()->print("capacity %d\n", map.get_capacity());
diff --git a/methods.py b/methods.py
index 3add9b1f18..0cf05751a8 100644
--- a/methods.py
+++ b/methods.py
@@ -22,6 +22,10 @@ def add_source_files(self, sources, filetype, lib_env=None, shared=False):
def disable_warnings(self):
# 'self' is the environment
if self.msvc:
+ # We have to remove existing warning level defines before appending /w,
+ # otherwise we get: "warning D9025 : overriding '/W3' with '/w'"
+ warn_flags = ['/Wall', '/W4', '/W3', '/W2', '/W1', '/WX']
+ self['CCFLAGS'] = [x for x in self['CCFLAGS'] if not x in warn_flags]
self.Append(CCFLAGS=['/w'])
else:
self.Append(CCFLAGS=['-w'])
diff --git a/misc/hooks/pre-commit-clang-format b/misc/hooks/pre-commit-clang-format
index 4f13b2afcb..db241ad172 100755
--- a/misc/hooks/pre-commit-clang-format
+++ b/misc/hooks/pre-commit-clang-format
@@ -31,7 +31,7 @@ PARSE_EXTS=true
# File types to parse. Only effective when PARSE_EXTS is true.
# FILE_EXTS=".c .h .cpp .hpp"
-FILE_EXTS=".c .h .cpp .hpp .cc .hh .cxx .m .mm .inc *.java *.glsl"
+FILE_EXTS=".c .h .cpp .hpp .cc .hh .cxx .m .mm .inc .java .glsl"
# Use pygmentize instead of cat to parse diff with highlighting.
# Install it with `pip install pygments` (Linux) or `easy_install Pygments` (Mac)
diff --git a/misc/travis/android-tools-linux.sh b/misc/travis/android-tools-linux.sh
index 04fb2eee21..830820b10b 100755
--- a/misc/travis/android-tools-linux.sh
+++ b/misc/travis/android-tools-linux.sh
@@ -17,19 +17,19 @@ cd $GODOT_BUILD_TOOLS_PATH
ANDROID_BASE_URL=http://dl.google.com/android/repository
-ANDROID_SDK_RELEASE=3859397
+ANDROID_SDK_RELEASE=4333796
ANDROID_SDK_DIR=android-sdk
ANDROID_SDK_FILENAME=sdk-tools-linux-$ANDROID_SDK_RELEASE.zip
ANDROID_SDK_URL=$ANDROID_BASE_URL/$ANDROID_SDK_FILENAME
ANDROID_SDK_PATH=$GODOT_BUILD_TOOLS_PATH/$ANDROID_SDK_DIR
-ANDROID_SDK_SHA256=444e22ce8ca0f67353bda4b85175ed3731cae3ffa695ca18119cbacef1c1bea0
+ANDROID_SDK_SHA256=92ffee5a1d98d856634e8b71132e8a95d96c83a63fde1099be3d86df3106def9
-ANDROID_NDK_RELEASE=r15c
+ANDROID_NDK_RELEASE=r18
ANDROID_NDK_DIR=android-ndk
ANDROID_NDK_FILENAME=android-ndk-$ANDROID_NDK_RELEASE-linux-x86_64.zip
ANDROID_NDK_URL=$ANDROID_BASE_URL/$ANDROID_NDK_FILENAME
ANDROID_NDK_PATH=$GODOT_BUILD_TOOLS_PATH/$ANDROID_NDK_DIR
-ANDROID_NDK_SHA1=0bf02d4e8b85fd770fd7b9b2cdec57f9441f27a2
+ANDROID_NDK_SHA1=2ac2e8e1ef73ed551cac3a1479bb28bd49369212
echo
echo "Download and install Android development tools ..."
@@ -75,7 +75,7 @@ echo "Installing: Android Tools ..."
yes | $ANDROID_SDK_DIR/tools/bin/sdkmanager --licenses > /dev/null
$ANDROID_SDK_DIR/tools/bin/sdkmanager 'tools' > /dev/null
$ANDROID_SDK_DIR/tools/bin/sdkmanager 'platform-tools' > /dev/null
-$ANDROID_SDK_DIR/tools/bin/sdkmanager 'build-tools;26.0.2' > /dev/null
+$ANDROID_SDK_DIR/tools/bin/sdkmanager 'build-tools;28.0.1' > /dev/null
echo
EXPORT_VAL="export ANDROID_HOME=$ANDROID_SDK_PATH"
diff --git a/modules/bmp/image_loader_bmp.cpp b/modules/bmp/image_loader_bmp.cpp
index 919731b52b..063508a25f 100644
--- a/modules/bmp/image_loader_bmp.cpp
+++ b/modules/bmp/image_loader_bmp.cpp
@@ -42,12 +42,9 @@ Error ImageLoaderBMP::convert_to_image(Ref<Image> p_image,
if (err == OK) {
size_t index = 0;
- size_t width =
- static_cast<size_t>(p_header.bmp_info_header.bmp_width < 0 ? -p_header.bmp_info_header.bmp_width : p_header.bmp_info_header.bmp_width);
- size_t height =
- static_cast<size_t>(p_header.bmp_info_header.bmp_height < 0 ? -p_header.bmp_info_header.bmp_height : p_header.bmp_info_header.bmp_height);
- size_t bits_per_pixel =
- static_cast<size_t>(p_header.bmp_info_header.bmp_bit_count);
+ size_t width = (size_t)p_header.bmp_info_header.bmp_width;
+ size_t height = (size_t)p_header.bmp_info_header.bmp_height;
+ size_t bits_per_pixel = (size_t)p_header.bmp_info_header.bmp_bit_count;
if (p_header.bmp_info_header.bmp_compression != 0) {
err = FAILED;
diff --git a/modules/bullet/area_bullet.cpp b/modules/bullet/area_bullet.cpp
index a3ba3aa0bf..a0486443c2 100644
--- a/modules/bullet/area_bullet.cpp
+++ b/modules/bullet/area_bullet.cpp
@@ -58,7 +58,7 @@ AreaBullet::AreaBullet() :
isScratched(false) {
btGhost = bulletnew(btGhostObject);
- btGhost->setCollisionShape(BulletPhysicsServer::get_empty_shape());
+ reload_shapes();
setupBulletCollisionObject(btGhost);
/// Collision objects with a callback still have collision response with dynamic rigid bodies.
/// In order to use collision objects as trigger, you have to disable the collision response.
@@ -166,11 +166,9 @@ bool AreaBullet::is_monitoring() const {
return get_godot_object_flags() & GOF_IS_MONITORING_AREA;
}
-void AreaBullet::main_shape_resetted() {
- if (get_main_shape())
- btGhost->setCollisionShape(get_main_shape());
- else
- btGhost->setCollisionShape(BulletPhysicsServer::get_empty_shape());
+void AreaBullet::main_shape_changed() {
+ CRASH_COND(!get_main_shape())
+ btGhost->setCollisionShape(get_main_shape());
}
void AreaBullet::reload_body() {
diff --git a/modules/bullet/area_bullet.h b/modules/bullet/area_bullet.h
index a6bf73906c..1c5962cfe3 100644
--- a/modules/bullet/area_bullet.h
+++ b/modules/bullet/area_bullet.h
@@ -142,7 +142,7 @@ public:
_FORCE_INLINE_ void set_spOv_priority(int p_priority) { spOv_priority = p_priority; }
_FORCE_INLINE_ int get_spOv_priority() { return spOv_priority; }
- virtual void main_shape_resetted();
+ virtual void main_shape_changed();
virtual void reload_body();
virtual void set_space(SpaceBullet *p_space);
@@ -157,6 +157,7 @@ public:
virtual void on_collision_filters_change();
virtual void on_collision_checker_start() {}
+ virtual void on_collision_checker_end() { isTransformChanged = false; }
void add_overlap(CollisionObjectBullet *p_otherObject);
void put_overlap_as_exit(int p_index);
diff --git a/modules/bullet/bullet_physics_server.cpp b/modules/bullet/bullet_physics_server.cpp
index 53a38967c3..315afe3d72 100644
--- a/modules/bullet/bullet_physics_server.cpp
+++ b/modules/bullet/bullet_physics_server.cpp
@@ -74,12 +74,6 @@
body->get_space()->add_constraint(joint, joint->is_disabled_collisions_between_bodies());
// <--------------- Joint creation asserts
-btEmptyShape *BulletPhysicsServer::emptyShape(ShapeBullet::create_shape_empty());
-
-btEmptyShape *BulletPhysicsServer::get_empty_shape() {
- return emptyShape;
-}
-
void BulletPhysicsServer::_bind_methods() {
//ClassDB::bind_method(D_METHOD("DoTest"), &BulletPhysicsServer::DoTest);
}
@@ -89,9 +83,7 @@ BulletPhysicsServer::BulletPhysicsServer() :
active(true),
active_spaces_count(0) {}
-BulletPhysicsServer::~BulletPhysicsServer() {
- bulletdelete(emptyShape);
-}
+BulletPhysicsServer::~BulletPhysicsServer() {}
RID BulletPhysicsServer::shape_create(ShapeType p_shape) {
ShapeBullet *shape = NULL;
@@ -338,7 +330,7 @@ Transform BulletPhysicsServer::area_get_shape_transform(RID p_area, int p_shape_
void BulletPhysicsServer::area_remove_shape(RID p_area, int p_shape_idx) {
AreaBullet *area = area_owner.get(p_area);
ERR_FAIL_COND(!area);
- return area->remove_shape(p_shape_idx);
+ return area->remove_shape_full(p_shape_idx);
}
void BulletPhysicsServer::area_clear_shapes(RID p_area) {
@@ -346,7 +338,7 @@ void BulletPhysicsServer::area_clear_shapes(RID p_area) {
ERR_FAIL_COND(!area);
for (int i = area->get_shape_count(); 0 < i; --i)
- area->remove_shape(0);
+ area->remove_shape_full(0);
}
void BulletPhysicsServer::area_set_shape_disabled(RID p_area, int p_shape_idx, bool p_disabled) {
@@ -567,7 +559,7 @@ void BulletPhysicsServer::body_remove_shape(RID p_body, int p_shape_idx) {
RigidBodyBullet *body = rigid_body_owner.get(p_body);
ERR_FAIL_COND(!body);
- body->remove_shape(p_shape_idx);
+ body->remove_shape_full(p_shape_idx);
}
void BulletPhysicsServer::body_clear_shapes(RID p_body) {
@@ -1486,7 +1478,7 @@ void BulletPhysicsServer::free(RID p_rid) {
// Notify the shape is configured
for (Map<ShapeOwnerBullet *, int>::Element *element = shape->get_owners().front(); element; element = element->next()) {
- static_cast<ShapeOwnerBullet *>(element->key())->remove_shape(shape);
+ static_cast<ShapeOwnerBullet *>(element->key())->remove_shape_full(shape);
}
shape_owner.free(p_rid);
@@ -1497,7 +1489,7 @@ void BulletPhysicsServer::free(RID p_rid) {
body->set_space(NULL);
- body->remove_all_shapes(true);
+ body->remove_all_shapes(true, true);
rigid_body_owner.free(p_rid);
bulletdelete(body);
@@ -1517,7 +1509,7 @@ void BulletPhysicsServer::free(RID p_rid) {
area->set_space(NULL);
- area->remove_all_shapes(true);
+ area->remove_all_shapes(true, true);
area_owner.free(p_rid);
bulletdelete(area);
diff --git a/modules/bullet/bullet_physics_server.h b/modules/bullet/bullet_physics_server.h
index 4c52cace67..6b7dcd86e6 100644
--- a/modules/bullet/bullet_physics_server.h
+++ b/modules/bullet/bullet_physics_server.h
@@ -60,13 +60,6 @@ class BulletPhysicsServer : public PhysicsServer {
mutable RID_Owner<SoftBodyBullet> soft_body_owner;
mutable RID_Owner<JointBullet> joint_owner;
-private:
- /// This is used as replacement of collision shape inside a compound or main shape
- static btEmptyShape *emptyShape;
-
-public:
- static btEmptyShape *get_empty_shape();
-
protected:
static void _bind_methods();
diff --git a/modules/bullet/collision_object_bullet.cpp b/modules/bullet/collision_object_bullet.cpp
index 61834b8e3f..a3944b4f99 100644
--- a/modules/bullet/collision_object_bullet.cpp
+++ b/modules/bullet/collision_object_bullet.cpp
@@ -43,8 +43,7 @@
@author AndreaCatania
*/
-#define enableDynamicAabbTree true
-#define initialChildCapacity 1
+#define enableDynamicAabbTree false
CollisionObjectBullet::ShapeWrapper::~ShapeWrapper() {}
@@ -60,7 +59,10 @@ void CollisionObjectBullet::ShapeWrapper::set_transform(const btTransform &p_tra
void CollisionObjectBullet::ShapeWrapper::claim_bt_shape(const btVector3 &body_scale) {
if (!bt_shape) {
- bt_shape = shape->create_bt_shape(scale * body_scale);
+ if (active)
+ bt_shape = shape->create_bt_shape(scale * body_scale);
+ else
+ bt_shape = ShapeBullet::create_shape_empty();
}
}
@@ -72,7 +74,8 @@ CollisionObjectBullet::CollisionObjectBullet(Type p_type) :
bt_collision_object(NULL),
body_scale(1., 1., 1.),
force_shape_reset(false),
- space(NULL) {}
+ space(NULL),
+ isTransformChanged(false) {}
CollisionObjectBullet::~CollisionObjectBullet() {
// Remove all overlapping, notify is not required since godot take care of it
@@ -90,7 +93,7 @@ bool equal(real_t first, real_t second) {
void CollisionObjectBullet::set_body_scale(const Vector3 &p_new_scale) {
if (!equal(p_new_scale[0], body_scale[0]) || !equal(p_new_scale[1], body_scale[1]) || !equal(p_new_scale[2], body_scale[2])) {
body_scale = p_new_scale;
- on_body_scale_changed();
+ body_scale_changed();
}
}
@@ -100,7 +103,7 @@ btVector3 CollisionObjectBullet::get_bt_body_scale() const {
return s;
}
-void CollisionObjectBullet::on_body_scale_changed() {
+void CollisionObjectBullet::body_scale_changed() {
force_shape_reset = true;
}
@@ -186,49 +189,33 @@ Transform CollisionObjectBullet::get_transform() const {
void CollisionObjectBullet::set_transform__bullet(const btTransform &p_global_transform) {
bt_collision_object->setWorldTransform(p_global_transform);
+ notify_transform_changed();
}
const btTransform &CollisionObjectBullet::get_transform__bullet() const {
return bt_collision_object->getWorldTransform();
}
+void CollisionObjectBullet::notify_transform_changed() {
+ isTransformChanged = true;
+}
+
RigidCollisionObjectBullet::RigidCollisionObjectBullet(Type p_type) :
CollisionObjectBullet(p_type),
mainShape(NULL) {
}
RigidCollisionObjectBullet::~RigidCollisionObjectBullet() {
- remove_all_shapes(true);
+ remove_all_shapes(true, true);
if (mainShape && mainShape->isCompound()) {
bulletdelete(mainShape);
}
}
-/* Not used
-void RigidCollisionObjectBullet::_internal_replaceShape(btCollisionShape *p_old_shape, btCollisionShape *p_new_shape) {
- bool at_least_one_was_changed = false;
- btTransform old_transf;
- // Inverse because I need remove the shapes
- // Fetch all shapes to be sure to remove all shapes
- for (int i = compoundShape->getNumChildShapes() - 1; 0 <= i; --i) {
- if (compoundShape->getChildShape(i) == p_old_shape) {
-
- old_transf = compoundShape->getChildTransform(i);
- compoundShape->removeChildShapeByIndex(i);
- compoundShape->addChildShape(old_transf, p_new_shape);
- at_least_one_was_changed = true;
- }
- }
-
- if (at_least_one_was_changed) {
- on_shapes_changed();
- }
-}*/
-
void RigidCollisionObjectBullet::add_shape(ShapeBullet *p_shape, const Transform &p_transform) {
shapes.push_back(ShapeWrapper(p_shape, p_transform, true));
p_shape->add_owner(this);
- on_shapes_changed();
+ reload_shapes();
}
void RigidCollisionObjectBullet::set_shape(int p_index, ShapeBullet *p_shape) {
@@ -236,17 +223,31 @@ void RigidCollisionObjectBullet::set_shape(int p_index, ShapeBullet *p_shape) {
shp.shape->remove_owner(this);
p_shape->add_owner(this);
shp.shape = p_shape;
- on_shapes_changed();
+ reload_shapes();
}
-void RigidCollisionObjectBullet::set_shape_transform(int p_index, const Transform &p_transform) {
- ERR_FAIL_INDEX(p_index, get_shape_count());
+int RigidCollisionObjectBullet::get_shape_count() const {
+ return shapes.size();
+}
- shapes.write[p_index].set_transform(p_transform);
- on_shape_changed(shapes.write[p_index].shape);
+ShapeBullet *RigidCollisionObjectBullet::get_shape(int p_index) const {
+ return shapes[p_index].shape;
}
-void RigidCollisionObjectBullet::remove_shape(ShapeBullet *p_shape) {
+btCollisionShape *RigidCollisionObjectBullet::get_bt_shape(int p_index) const {
+ return shapes[p_index].bt_shape;
+}
+
+int RigidCollisionObjectBullet::find_shape(ShapeBullet *p_shape) const {
+ const int size = shapes.size();
+ for (int i = 0; i < size; ++i) {
+ if (shapes[i].shape == p_shape)
+ return i;
+ }
+ return -1;
+}
+
+void RigidCollisionObjectBullet::remove_shape_full(ShapeBullet *p_shape) {
// Remove the shape, all the times it appears
// Reverse order required for delete.
for (int i = shapes.size() - 1; 0 <= i; --i) {
@@ -255,35 +256,32 @@ void RigidCollisionObjectBullet::remove_shape(ShapeBullet *p_shape) {
shapes.remove(i);
}
}
- on_shapes_changed();
+ reload_shapes();
}
-void RigidCollisionObjectBullet::remove_shape(int p_index) {
+void RigidCollisionObjectBullet::remove_shape_full(int p_index) {
ERR_FAIL_INDEX(p_index, get_shape_count());
internal_shape_destroy(p_index);
shapes.remove(p_index);
- on_shapes_changed();
+ reload_shapes();
}
-void RigidCollisionObjectBullet::remove_all_shapes(bool p_permanentlyFromThisBody) {
+void RigidCollisionObjectBullet::remove_all_shapes(bool p_permanentlyFromThisBody, bool p_force_not_reload) {
// Reverse order required for delete.
for (int i = shapes.size() - 1; 0 <= i; --i) {
internal_shape_destroy(i, p_permanentlyFromThisBody);
}
shapes.clear();
- on_shapes_changed();
+ if (!p_force_not_reload)
+ reload_shapes();
}
-int RigidCollisionObjectBullet::get_shape_count() const {
- return shapes.size();
-}
-
-ShapeBullet *RigidCollisionObjectBullet::get_shape(int p_index) const {
- return shapes[p_index].shape;
-}
+void RigidCollisionObjectBullet::set_shape_transform(int p_index, const Transform &p_transform) {
+ ERR_FAIL_INDEX(p_index, get_shape_count());
-btCollisionShape *RigidCollisionObjectBullet::get_bt_shape(int p_index) const {
- return shapes[p_index].bt_shape;
+ shapes.write[p_index].set_transform(p_transform);
+ // Note, enableDynamicAabbTree is false because on transform change compound is destroyed
+ reload_shapes();
}
const btTransform &RigidCollisionObjectBullet::get_bt_shape_transform(int p_index) const {
@@ -296,21 +294,26 @@ Transform RigidCollisionObjectBullet::get_shape_transform(int p_index) const {
return trs;
}
-void RigidCollisionObjectBullet::on_shape_changed(const ShapeBullet *const p_shape) {
- const int size = shapes.size();
- for (int i = 0; i < size; ++i) {
- if (shapes[i].shape == p_shape) {
- bulletdelete(shapes.write[i].bt_shape);
- }
- }
- on_shapes_changed();
+void RigidCollisionObjectBullet::set_shape_disabled(int p_index, bool p_disabled) {
+ shapes.write[p_index].active = !p_disabled;
+ shape_changed(p_index);
+}
+
+bool RigidCollisionObjectBullet::is_shape_disabled(int p_index) {
+ return !shapes[p_index].active;
}
-void RigidCollisionObjectBullet::on_shapes_changed() {
+void RigidCollisionObjectBullet::shape_changed(int p_shape_index) {
+ bulletdelete(shapes.write[p_shape_index].bt_shape);
+ reload_shapes();
+}
- if (mainShape && mainShape->isCompound()) {
+void RigidCollisionObjectBullet::reload_shapes() {
+
+ if (mainShape && mainShape->isCompound())
+ // Destroy compound
bulletdelete(mainShape);
- }
+
mainShape = NULL;
ShapeWrapper *shpWrapper;
@@ -325,55 +328,38 @@ void RigidCollisionObjectBullet::on_shapes_changed() {
force_shape_reset = false;
}
- btVector3 body_scale(get_bt_body_scale());
-
- if (!shape_count)
- return;
+ const btVector3 body_scale(get_bt_body_scale());
// Try to optimize by not using compound
if (1 == shape_count) {
shpWrapper = &shapes.write[0];
- if (shpWrapper->active && shpWrapper->transform.getOrigin().isZero() && shpWrapper->transform.getBasis() == shpWrapper->transform.getBasis().getIdentity()) {
+ if (shpWrapper->transform.getOrigin().isZero() && shpWrapper->transform.getBasis() == shpWrapper->transform.getBasis().getIdentity()) {
shpWrapper->claim_bt_shape(body_scale);
mainShape = shpWrapper->bt_shape;
- main_shape_resetted();
+ main_shape_changed();
return;
}
}
- btCompoundShape *compoundShape = bulletnew(btCompoundShape(enableDynamicAabbTree, initialChildCapacity));
+ // Optimization not possible use a compound shape
+ btCompoundShape *compoundShape = bulletnew(btCompoundShape(enableDynamicAabbTree, shape_count));
- // Insert all shapes into compound
for (int i(0); i < shape_count; ++i) {
shpWrapper = &shapes.write[i];
- if (shpWrapper->active) {
- shpWrapper->claim_bt_shape(body_scale);
-
- btTransform scaled_shape_transform(shpWrapper->transform);
- scaled_shape_transform.getOrigin() *= body_scale;
- compoundShape->addChildShape(scaled_shape_transform, shpWrapper->bt_shape);
- } else {
- compoundShape->addChildShape(btTransform(), BulletPhysicsServer::get_empty_shape());
- }
+ shpWrapper->claim_bt_shape(body_scale);
+ btTransform scaled_shape_transform(shpWrapper->transform);
+ scaled_shape_transform.getOrigin() *= body_scale;
+ compoundShape->addChildShape(scaled_shape_transform, shpWrapper->bt_shape);
}
compoundShape->recalculateLocalAabb();
mainShape = compoundShape;
- main_shape_resetted();
-}
-
-void RigidCollisionObjectBullet::set_shape_disabled(int p_index, bool p_disabled) {
- shapes.write[p_index].active = !p_disabled;
- on_shapes_changed();
-}
-
-bool RigidCollisionObjectBullet::is_shape_disabled(int p_index) {
- return !shapes[p_index].active;
+ main_shape_changed();
}
-void RigidCollisionObjectBullet::on_body_scale_changed() {
- CollisionObjectBullet::on_body_scale_changed();
- on_shapes_changed();
+void RigidCollisionObjectBullet::body_scale_changed() {
+ CollisionObjectBullet::body_scale_changed();
+ reload_shapes();
}
void RigidCollisionObjectBullet::internal_shape_destroy(int p_index, bool p_permanentlyFromThisBody) {
diff --git a/modules/bullet/collision_object_bullet.h b/modules/bullet/collision_object_bullet.h
index ea06cecb17..4a0c805ce5 100644
--- a/modules/bullet/collision_object_bullet.h
+++ b/modules/bullet/collision_object_bullet.h
@@ -132,6 +132,7 @@ protected:
/// New area is added when overlap with new area (AreaBullet::addOverlap), then is removed when it exit (CollisionObjectBullet::onExitArea)
/// This array is used mainly to know which area hold the pointer of this object
Vector<AreaBullet *> areasOverlapped;
+ bool isTransformChanged;
public:
CollisionObjectBullet(Type p_type);
@@ -157,7 +158,7 @@ public:
void set_body_scale(const Vector3 &p_new_scale);
const Vector3 &get_body_scale() const { return body_scale; }
btVector3 get_bt_body_scale() const;
- virtual void on_body_scale_changed();
+ virtual void body_scale_changed();
void add_collision_exception(const CollisionObjectBullet *p_ignoreCollisionObject);
void remove_collision_exception(const CollisionObjectBullet *p_ignoreCollisionObject);
@@ -185,8 +186,9 @@ public:
virtual void reload_body() = 0;
virtual void set_space(SpaceBullet *p_space) = 0;
_FORCE_INLINE_ SpaceBullet *get_space() const { return space; }
- /// This is an event that is called when a collision checker starts
+
virtual void on_collision_checker_start() = 0;
+ virtual void on_collision_checker_end() = 0;
virtual void dispatch_callbacks() = 0;
@@ -197,7 +199,6 @@ public:
virtual void on_enter_area(AreaBullet *p_area) = 0;
virtual void on_exit_area(AreaBullet *p_area);
- /// GodotObjectFlags
void set_godot_object_flags(int flags);
int get_godot_object_flags() const;
@@ -205,11 +206,13 @@ public:
Transform get_transform() const;
virtual void set_transform__bullet(const btTransform &p_global_transform);
virtual const btTransform &get_transform__bullet() const;
+
+ bool is_transform_changed() const { return isTransformChanged; }
+ virtual void notify_transform_changed();
};
class RigidCollisionObjectBullet : public CollisionObjectBullet, public ShapeOwnerBullet {
protected:
- /// This could be a compound shape in case multi please collision are found
btCollisionShape *mainShape;
Vector<ShapeWrapper> shapes;
@@ -219,31 +222,34 @@ public:
_FORCE_INLINE_ const Vector<ShapeWrapper> &get_shapes_wrappers() const { return shapes; }
- /// This is used to set new shape or replace existing
- //virtual void _internal_replaceShape(btCollisionShape *p_old_shape, btCollisionShape *p_new_shape) = 0;
+ _FORCE_INLINE_ btCollisionShape *get_main_shape() const { return mainShape; }
+
void add_shape(ShapeBullet *p_shape, const Transform &p_transform = Transform());
void set_shape(int p_index, ShapeBullet *p_shape);
- void set_shape_transform(int p_index, const Transform &p_transform);
- virtual void remove_shape(ShapeBullet *p_shape);
- void remove_shape(int p_index);
- void remove_all_shapes(bool p_permanentlyFromThisBody = false);
-
- virtual void on_shape_changed(const ShapeBullet *const p_shape);
- virtual void on_shapes_changed();
-
- _FORCE_INLINE_ btCollisionShape *get_main_shape() const { return mainShape; }
int get_shape_count() const;
ShapeBullet *get_shape(int p_index) const;
btCollisionShape *get_bt_shape(int p_index) const;
+
+ int find_shape(ShapeBullet *p_shape) const;
+
+ virtual void remove_shape_full(ShapeBullet *p_shape);
+ void remove_shape_full(int p_index);
+ void remove_all_shapes(bool p_permanentlyFromThisBody = false, bool p_force_not_reload = false);
+
+ void set_shape_transform(int p_index, const Transform &p_transform);
+
const btTransform &get_bt_shape_transform(int p_index) const;
Transform get_shape_transform(int p_index) const;
void set_shape_disabled(int p_index, bool p_disabled);
bool is_shape_disabled(int p_index);
- virtual void main_shape_resetted() = 0;
- virtual void on_body_scale_changed();
+ virtual void shape_changed(int p_shape_index);
+ virtual void reload_shapes();
+
+ virtual void main_shape_changed() = 0;
+ virtual void body_scale_changed();
private:
void internal_shape_destroy(int p_index, bool p_permanentlyFromThisBody = false);
diff --git a/modules/bullet/godot_motion_state.h b/modules/bullet/godot_motion_state.h
index fa58e86589..5844ef8bf3 100644
--- a/modules/bullet/godot_motion_state.h
+++ b/modules/bullet/godot_motion_state.h
@@ -82,7 +82,7 @@ public:
virtual void setWorldTransform(const btTransform &worldTrans) {
bodyCurrentWorldTransform = worldTrans;
- owner->scratch();
+ owner->notify_transform_changed();
}
public:
diff --git a/modules/bullet/rigid_body_bullet.cpp b/modules/bullet/rigid_body_bullet.cpp
index d9a77885b3..37e7718969 100644
--- a/modules/bullet/rigid_body_bullet.cpp
+++ b/modules/bullet/rigid_body_bullet.cpp
@@ -265,13 +265,13 @@ RigidBodyBullet::RigidBodyBullet() :
angularDamp(0),
can_sleep(true),
omit_forces_integration(false),
+ can_integrate_forces(false),
maxCollisionsDetection(0),
collisionsCount(0),
maxAreasWhereIam(10),
areaWhereIamCount(0),
countGravityPointSpaces(0),
isScratchedSpaceOverrideModificator(false),
- isTransformChanged(false),
previousActiveState(true),
force_integration_callback(NULL) {
@@ -279,9 +279,10 @@ RigidBodyBullet::RigidBodyBullet() :
// Initial properties
const btVector3 localInertia(0, 0, 0);
- btRigidBody::btRigidBodyConstructionInfo cInfo(mass, godotMotionState, BulletPhysicsServer::get_empty_shape(), localInertia);
+ btRigidBody::btRigidBodyConstructionInfo cInfo(mass, godotMotionState, NULL, localInertia);
btBody = bulletnew(btRigidBody(cInfo));
+ reload_shapes();
setupBulletCollisionObject(btBody);
set_mode(PhysicsServer::BODY_MODE_RIGID);
@@ -314,11 +315,9 @@ void RigidBodyBullet::destroy_kinematic_utilities() {
}
}
-void RigidBodyBullet::main_shape_resetted() {
- if (get_main_shape())
- btBody->setCollisionShape(get_main_shape());
- else
- btBody->setCollisionShape(BulletPhysicsServer::get_empty_shape());
+void RigidBodyBullet::main_shape_changed() {
+ CRASH_COND(!get_main_shape())
+ btBody->setCollisionShape(get_main_shape());
set_continuous_collision_detection(is_continuous_collision_detection_enabled()); // Reset
}
@@ -333,7 +332,7 @@ void RigidBodyBullet::reload_body() {
void RigidBodyBullet::set_space(SpaceBullet *p_space) {
// Clear the old space if there is one
if (space) {
- isTransformChanged = false;
+ can_integrate_forces = false;
// Remove all eventual constraints
assert_no_constraints();
@@ -350,8 +349,8 @@ void RigidBodyBullet::set_space(SpaceBullet *p_space) {
}
void RigidBodyBullet::dispatch_callbacks() {
- /// The check isTransformChanged is necessary in order to call integrated forces only when the first transform is sent
- if ((btBody->isKinematicObject() || btBody->isActive() || previousActiveState != btBody->isActive()) && force_integration_callback && isTransformChanged) {
+ /// The check isFirstTransformChanged is necessary in order to call integrated forces only when the first transform is sent
+ if ((btBody->isKinematicObject() || btBody->isActive() || previousActiveState != btBody->isActive()) && force_integration_callback && can_integrate_forces) {
if (omit_forces_integration)
btBody->clearForces();
@@ -400,10 +399,6 @@ void RigidBodyBullet::set_force_integration_callback(ObjectID p_id, const String
}
}
-void RigidBodyBullet::scratch() {
- isTransformChanged = true;
-}
-
void RigidBodyBullet::scratch_space_override_modificator() {
isScratchedSpaceOverrideModificator = true;
}
@@ -418,6 +413,11 @@ void RigidBodyBullet::on_collision_checker_start() {
collisionsCount = 0;
}
+void RigidBodyBullet::on_collision_checker_end() {
+ // Always true if active and not a static or kinematic body
+ isTransformChanged = btBody->isActive() && !btBody->isStaticOrKinematicObject();
+}
+
bool RigidBodyBullet::add_collision_object(RigidBodyBullet *p_otherObject, const Vector3 &p_hitWorldLocation, const Vector3 &p_hitLocalLocation, const Vector3 &p_hitNormal, const float &p_appliedImpulse, int p_other_shape_index, int p_local_shape_index) {
if (collisionsCount >= maxCollisionsDetection) {
@@ -520,7 +520,7 @@ real_t RigidBodyBullet::get_param(PhysicsServer::BodyParameter p_param) const {
void RigidBodyBullet::set_mode(PhysicsServer::BodyMode p_mode) {
// This is necessary to block force_integration untile next move
- isTransformChanged = false;
+ can_integrate_forces = false;
destroy_kinematic_utilities();
// The mode change is relevant to its mass
switch (p_mode) {
@@ -777,8 +777,7 @@ void RigidBodyBullet::set_transform__bullet(const btTransform &p_global_transfor
// The kinematic use MotionState class
godotMotionState->moveBody(p_global_transform);
}
- btBody->setWorldTransform(p_global_transform);
- scratch();
+ CollisionObjectBullet::set_transform__bullet(p_global_transform);
}
const btTransform &RigidBodyBullet::get_transform__bullet() const {
@@ -791,8 +790,8 @@ const btTransform &RigidBodyBullet::get_transform__bullet() const {
}
}
-void RigidBodyBullet::on_shapes_changed() {
- RigidCollisionObjectBullet::on_shapes_changed();
+void RigidBodyBullet::reload_shapes() {
+ RigidCollisionObjectBullet::reload_shapes();
const btScalar invMass = btBody->getInvMass();
const btScalar mass = invMass == 0 ? 0 : 1 / invMass;
@@ -987,6 +986,11 @@ void RigidBodyBullet::reload_kinematic_shapes() {
kinematic_utilities->copyAllOwnerShapes();
}
+void RigidBodyBullet::notify_transform_changed() {
+ RigidCollisionObjectBullet::notify_transform_changed();
+ can_integrate_forces = true;
+}
+
void RigidBodyBullet::_internal_set_mass(real_t p_mass) {
btVector3 localInertia(0, 0, 0);
diff --git a/modules/bullet/rigid_body_bullet.h b/modules/bullet/rigid_body_bullet.h
index 25dac30951..26e5018c87 100644
--- a/modules/bullet/rigid_body_bullet.h
+++ b/modules/bullet/rigid_body_bullet.h
@@ -202,6 +202,7 @@ private:
real_t angularDamp;
bool can_sleep;
bool omit_forces_integration;
+ bool can_integrate_forces;
Vector<CollisionData> collisions;
// these parameters are used to avoid vector resize
@@ -216,7 +217,6 @@ private:
int countGravityPointSpaces;
bool isScratchedSpaceOverrideModificator;
- bool isTransformChanged;
bool previousActiveState; // Last check state
ForceIntegrationCallback *force_integration_callback;
@@ -231,17 +231,18 @@ public:
_FORCE_INLINE_ btRigidBody *get_bt_rigid_body() { return btBody; }
- virtual void main_shape_resetted();
+ virtual void main_shape_changed();
virtual void reload_body();
virtual void set_space(SpaceBullet *p_space);
virtual void dispatch_callbacks();
void set_force_integration_callback(ObjectID p_id, const StringName &p_method, const Variant &p_udata = Variant());
- void scratch();
void scratch_space_override_modificator();
virtual void on_collision_filters_change();
virtual void on_collision_checker_start();
+ virtual void on_collision_checker_end();
+
void set_max_collisions_detection(int p_maxCollisionsDetection) {
maxCollisionsDetection = p_maxCollisionsDetection;
collisions.resize(p_maxCollisionsDetection);
@@ -302,7 +303,7 @@ public:
virtual void set_transform__bullet(const btTransform &p_global_transform);
virtual const btTransform &get_transform__bullet() const;
- virtual void on_shapes_changed();
+ virtual void reload_shapes();
virtual void on_enter_area(AreaBullet *p_area);
virtual void on_exit_area(AreaBullet *p_area);
@@ -311,6 +312,8 @@ public:
/// Kinematic
void reload_kinematic_shapes();
+ virtual void notify_transform_changed();
+
private:
void _internal_set_mass(real_t p_mass);
};
diff --git a/modules/bullet/shape_bullet.cpp b/modules/bullet/shape_bullet.cpp
index 4a2263407c..8bb621a863 100644
--- a/modules/bullet/shape_bullet.cpp
+++ b/modules/bullet/shape_bullet.cpp
@@ -34,6 +34,7 @@
#include "bullet_physics_server.h"
#include "bullet_types_converter.h"
#include "bullet_utilities.h"
+#include "core/project_settings.h"
#include "shape_owner_bullet.h"
#include <BulletCollision/CollisionDispatch/btInternalEdgeUtility.h>
@@ -64,7 +65,8 @@ btCollisionShape *ShapeBullet::prepare(btCollisionShape *p_btShape) const {
void ShapeBullet::notifyShapeChanged() {
for (Map<ShapeOwnerBullet *, int>::Element *E = owners.front(); E; E = E->next()) {
- static_cast<ShapeOwnerBullet *>(E->key())->on_shape_changed(this);
+ ShapeOwnerBullet *owner = static_cast<ShapeOwnerBullet *>(E->key());
+ owner->shape_changed(owner->find_shape(this));
}
}
@@ -400,18 +402,22 @@ void ConcavePolygonShapeBullet::setup(PoolVector<Vector3> p_faces) {
btVector3 supVec_1;
btVector3 supVec_2;
for (int i = 0; i < src_face_count; ++i) {
- G_TO_B(facesr[i * 3], supVec_0);
+ G_TO_B(facesr[i * 3 + 0], supVec_0);
G_TO_B(facesr[i * 3 + 1], supVec_1);
G_TO_B(facesr[i * 3 + 2], supVec_2);
- shapeInterface->addTriangle(supVec_0, supVec_1, supVec_2);
+ // Inverted from standard godot otherwise btGenerateInternalEdgeInfo generates wrong edge info
+ shapeInterface->addTriangle(supVec_2, supVec_1, supVec_0);
}
const bool useQuantizedAabbCompression = true;
meshShape = bulletnew(btBvhTriangleMeshShape(shapeInterface, useQuantizedAabbCompression));
- btTriangleInfoMap *triangleInfoMap = new btTriangleInfoMap();
- btGenerateInternalEdgeInfo(meshShape, triangleInfoMap);
+
+ if (GLOBAL_DEF("physics/3d/smooth_trimesh_collision", false)) {
+ btTriangleInfoMap *triangleInfoMap = new btTriangleInfoMap();
+ btGenerateInternalEdgeInfo(meshShape, triangleInfoMap);
+ }
} else {
meshShape = NULL;
ERR_PRINT("The faces count are 0, the mesh shape cannot be created");
@@ -426,6 +432,7 @@ btCollisionShape *ConcavePolygonShapeBullet::create_bt_shape(const btVector3 &p_
cs = ShapeBullet::create_shape_empty();
cs->setLocalScaling(p_implicit_scale);
prepare(cs);
+ cs->setMargin(0);
return cs;
}
diff --git a/modules/bullet/shape_owner_bullet.h b/modules/bullet/shape_owner_bullet.h
index 29d42d12f2..72ddbc482c 100644
--- a/modules/bullet/shape_owner_bullet.h
+++ b/modules/bullet/shape_owner_bullet.h
@@ -45,11 +45,10 @@ class CollisionObjectBullet;
/// E.G. BodyShape is a child of this
class ShapeOwnerBullet {
public:
- /// This is used to set new shape or replace existing
- //virtual void _internal_replaceShape(btCollisionShape *p_old_shape, btCollisionShape *p_new_shape) = 0;
- virtual void on_shape_changed(const ShapeBullet *const p_shape) = 0;
- virtual void on_shapes_changed() = 0;
- virtual void remove_shape(class ShapeBullet *p_shape) = 0;
+ virtual int find_shape(ShapeBullet *p_shape) const = 0;
+ virtual void shape_changed(int p_shape_index) = 0;
+ virtual void reload_shapes() = 0;
+ virtual void remove_shape_full(class ShapeBullet *p_shape) = 0;
virtual ~ShapeOwnerBullet() {}
};
#endif
diff --git a/modules/bullet/soft_body_bullet.cpp b/modules/bullet/soft_body_bullet.cpp
index f373ce5db4..94f350210f 100644
--- a/modules/bullet/soft_body_bullet.cpp
+++ b/modules/bullet/soft_body_bullet.cpp
@@ -72,12 +72,6 @@ void SoftBodyBullet::set_space(SpaceBullet *p_space) {
}
}
-void SoftBodyBullet::dispatch_callbacks() {}
-
-void SoftBodyBullet::on_collision_filters_change() {}
-
-void SoftBodyBullet::on_collision_checker_start() {}
-
void SoftBodyBullet::on_enter_area(AreaBullet *p_area) {}
void SoftBodyBullet::on_exit_area(AreaBullet *p_area) {}
diff --git a/modules/bullet/soft_body_bullet.h b/modules/bullet/soft_body_bullet.h
index c775193584..d04bfca046 100644
--- a/modules/bullet/soft_body_bullet.h
+++ b/modules/bullet/soft_body_bullet.h
@@ -91,9 +91,10 @@ public:
virtual void reload_body();
virtual void set_space(SpaceBullet *p_space);
- virtual void dispatch_callbacks();
- virtual void on_collision_filters_change();
- virtual void on_collision_checker_start();
+ virtual void dispatch_callbacks() {}
+ virtual void on_collision_filters_change() {}
+ virtual void on_collision_checker_start() {}
+ virtual void on_collision_checker_end() {}
virtual void on_enter_area(AreaBullet *p_area);
virtual void on_exit_area(AreaBullet *p_area);
diff --git a/modules/bullet/space_bullet.cpp b/modules/bullet/space_bullet.cpp
index ba4c72f4c7..ab2d1781ad 100644
--- a/modules/bullet/space_bullet.cpp
+++ b/modules/bullet/space_bullet.cpp
@@ -175,7 +175,7 @@ bool BulletPhysicsDirectSpaceState::cast_motion(const RID &p_shape, const Transf
btResult.m_collisionFilterGroup = 0;
btResult.m_collisionFilterMask = p_collision_mask;
- space->dynamicsWorld->convexSweepTest(bt_convex_shape, bt_xform_from, bt_xform_to, btResult, 0.002);
+ space->dynamicsWorld->convexSweepTest(bt_convex_shape, bt_xform_from, bt_xform_to, btResult, space->dynamicsWorld->getDispatchInfo().m_allowedCcdPenetration);
r_closest_unsafe = 1.0;
r_closest_safe = 1.0;
@@ -540,17 +540,20 @@ void onBulletPreTickCallback(btDynamicsWorld *p_dynamicsWorld, btScalar timeStep
void onBulletTickCallback(btDynamicsWorld *p_dynamicsWorld, btScalar timeStep) {
- // Notify all Collision objects the collision checker is started
const btCollisionObjectArray &colObjArray = p_dynamicsWorld->getCollisionObjectArray();
+
+ // Notify all Collision objects the collision checker is started
for (int i = colObjArray.size() - 1; 0 <= i; --i) {
- CollisionObjectBullet *colObj = static_cast<CollisionObjectBullet *>(colObjArray[i]->getUserPointer());
- assert(NULL != colObj);
- colObj->on_collision_checker_start();
+ static_cast<CollisionObjectBullet *>(colObjArray[i]->getUserPointer())->on_collision_checker_start();
}
SpaceBullet *sb = static_cast<SpaceBullet *>(p_dynamicsWorld->getWorldUserInfo());
sb->check_ghost_overlaps();
sb->check_body_collision();
+
+ for (int i = colObjArray.size() - 1; 0 <= i; --i) {
+ static_cast<CollisionObjectBullet *>(colObjArray[i]->getUserPointer())->on_collision_checker_end();
+ }
}
BulletPhysicsDirectSpaceState *SpaceBullet::get_direct_state() {
@@ -571,7 +574,6 @@ void SpaceBullet::create_empty_world(bool p_create_soft_world) {
gjk_epa_pen_solver = bulletnew(btGjkEpaPenetrationDepthSolver);
gjk_simplex_solver = bulletnew(btVoronoiSimplexSolver);
- gjk_simplex_solver->setEqualVertexThreshold(0.f);
void *world_mem;
if (p_create_soft_world) {
@@ -650,7 +652,6 @@ void SpaceBullet::check_ghost_overlaps() {
btConvexShape *area_shape;
btGjkPairDetector::ClosestPointInput gjk_input;
AreaBullet *area;
- RigidCollisionObjectBullet *otherObject;
int x(-1), i(-1), y(-1), z(-1), indexOverlap(-1);
/// For each areas
@@ -677,13 +678,17 @@ void SpaceBullet::check_ghost_overlaps() {
// For each overlapping
for (i = ghostOverlaps.size() - 1; 0 <= i; --i) {
- if (ghostOverlaps[i]->getUserIndex() == CollisionObjectBullet::TYPE_AREA) {
- if (!static_cast<AreaBullet *>(ghostOverlaps[i]->getUserPointer())->is_monitorable())
- continue;
- } else if (ghostOverlaps[i]->getUserIndex() != CollisionObjectBullet::TYPE_RIGID_BODY)
+ btCollisionObject *overlapped_bt_co = ghostOverlaps[i];
+ RigidCollisionObjectBullet *otherObject = static_cast<RigidCollisionObjectBullet *>(overlapped_bt_co->getUserPointer());
+
+ if (!area->is_transform_changed() && !otherObject->is_transform_changed())
continue;
- otherObject = static_cast<RigidCollisionObjectBullet *>(ghostOverlaps[i]->getUserPointer());
+ if (overlapped_bt_co->getUserIndex() == CollisionObjectBullet::TYPE_AREA) {
+ if (!static_cast<AreaBullet *>(overlapped_bt_co->getUserPointer())->is_monitorable())
+ continue;
+ } else if (overlapped_bt_co->getUserIndex() != CollisionObjectBullet::TYPE_RIGID_BODY)
+ continue;
bool hasOverlap = false;
diff --git a/modules/csg/csg.cpp b/modules/csg/csg.cpp
index 567485c2c7..88f3c0338a 100644
--- a/modules/csg/csg.cpp
+++ b/modules/csg/csg.cpp
@@ -750,7 +750,7 @@ void CSGBrushOperation::_add_poly_outline(const BuildPoly &p_poly, int p_from_po
t2d.affine_invert();
- float max_angle;
+ float max_angle = 0;
int next_point_angle = -1;
for (int i = 0; i < vertex_process[to_point].size(); i++) {
@@ -805,7 +805,7 @@ void CSGBrushOperation::_merge_poly(MeshMerge &mesh, int p_face_idx, const Build
//process points that were not processed
for (int i = 0; i < edge_process.size(); i++) {
- if (edge_process[i] == true)
+ if (edge_process[i])
continue; //already processed
int intersect_poly = -1;
diff --git a/modules/csg/csg_gizmos.cpp b/modules/csg/csg_gizmos.cpp
index 07c33ed670..5864d02615 100644
--- a/modules/csg/csg_gizmos.cpp
+++ b/modules/csg/csg_gizmos.cpp
@@ -215,7 +215,7 @@ void CSGShapeSpatialGizmoPlugin::commit_handle(EditorSpatialGizmo *p_gizmo, int
UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo();
ur->create_action(TTR("Change Box Shape Extents"));
static const char *method[3] = { "set_width", "set_height", "set_depth" };
- float current;
+ float current = 0;
switch (p_idx) {
case 0: current = s->get_width(); break;
case 1: current = s->get_height(); break;
diff --git a/modules/csg/csg_shape.cpp b/modules/csg/csg_shape.cpp
index 714be16db7..d1ef08dc83 100644
--- a/modules/csg/csg_shape.cpp
+++ b/modules/csg/csg_shape.cpp
@@ -1573,7 +1573,7 @@ CSGBrush *CSGPolygon::_build_brush() {
}
CSGBrush *brush = memnew(CSGBrush);
- int face_count;
+ int face_count = 0;
switch (mode) {
case MODE_DEPTH: face_count = triangles.size() * 2 / 3 + (final_polygon.size()) * 2; break;
diff --git a/modules/dds/texture_loader_dds.cpp b/modules/dds/texture_loader_dds.cpp
index ff15aaa735..53e9773791 100644
--- a/modules/dds/texture_loader_dds.cpp
+++ b/modules/dds/texture_loader_dds.cpp
@@ -108,8 +108,8 @@ RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path,
uint32_t magic = f->get_32();
uint32_t hsize = f->get_32();
uint32_t flags = f->get_32();
- uint32_t width = f->get_32();
uint32_t height = f->get_32();
+ uint32_t width = f->get_32();
uint32_t pitch = f->get_32();
/* uint32_t depth = */ f->get_32();
uint32_t mipmaps = f->get_32();
diff --git a/modules/enet/doc_classes/NetworkedMultiplayerENet.xml b/modules/enet/doc_classes/NetworkedMultiplayerENet.xml
index 76c551e8d7..6d990f6f6f 100644
--- a/modules/enet/doc_classes/NetworkedMultiplayerENet.xml
+++ b/modules/enet/doc_classes/NetworkedMultiplayerENet.xml
@@ -76,7 +76,7 @@
<return type="int">
</return>
<description>
- Returns the channel of the next packet that will be retrieved via [method PacketPeer.get_packet_peer]
+ Returns the channel of the next packet that will be retrieved via [method PacketPeer.get_packet]
</description>
</method>
<method name="get_peer_address" qualifiers="const">
diff --git a/modules/gdnative/include/gdnative/gdnative.h b/modules/gdnative/include/gdnative/gdnative.h
index 616c305f25..796ced84f4 100644
--- a/modules/gdnative/include/gdnative/gdnative.h
+++ b/modules/gdnative/include/gdnative/gdnative.h
@@ -35,7 +35,7 @@
extern "C" {
#endif
-#ifdef _WIN32
+#if defined(_WIN32) || defined(__ANDROID__)
#define GDCALLINGCONV
#define GDAPI GDCALLINGCONV
#elif defined(__APPLE__)
@@ -47,7 +47,7 @@ extern "C" {
#define GDCALLINGCONV __attribute__((sysv_abi))
#define GDAPI GDCALLINGCONV
#endif
-#else
+#else // !_WIN32 && !__APPLE__
#define GDCALLINGCONV __attribute__((sysv_abi))
#define GDAPI GDCALLINGCONV
#endif
diff --git a/modules/gdnative/nativescript/api_generator.cpp b/modules/gdnative/nativescript/api_generator.cpp
index 0983c12619..8c6dace847 100644
--- a/modules/gdnative/nativescript/api_generator.cpp
+++ b/modules/gdnative/nativescript/api_generator.cpp
@@ -292,6 +292,7 @@ List<ClassAPI> generate_c_api_classes() {
method_api.has_varargs = method_bind && method_bind->is_vararg();
// Method flags
+ method_api.is_virtual = false;
if (method_info.flags) {
const uint32_t flags = method_info.flags;
method_api.is_editor = flags & METHOD_FLAG_EDITOR;
diff --git a/modules/gdnative/nativescript/nativescript.cpp b/modules/gdnative/nativescript/nativescript.cpp
index 641e4021d8..37e72bf9f8 100644
--- a/modules/gdnative/nativescript/nativescript.cpp
+++ b/modules/gdnative/nativescript/nativescript.cpp
@@ -1016,6 +1016,16 @@ NativeScriptLanguage::NativeScriptLanguage() {
#ifdef DEBUG_ENABLED
profiling = false;
#endif
+
+ _init_call_type = "nativescript_init";
+ _init_call_name = "nativescript_init";
+ _terminate_call_name = "nativescript_terminate";
+ _noarg_call_type = "nativescript_no_arg";
+ _frame_call_name = "nativescript_frame";
+#ifndef NO_THREADS
+ _thread_enter_call_name = "nativescript_thread_enter";
+ _thread_exit_call_name = "nativescript_thread_exit";
+#endif
}
NativeScriptLanguage::~NativeScriptLanguage() {
diff --git a/modules/gdnative/nativescript/nativescript.h b/modules/gdnative/nativescript/nativescript.h
index ade8ffd280..51370f5fbf 100644
--- a/modules/gdnative/nativescript/nativescript.h
+++ b/modules/gdnative/nativescript/nativescript.h
@@ -277,18 +277,14 @@ public:
Map<String, Set<NativeScript *> > library_script_users;
- const StringName _init_call_type = "nativescript_init";
- const StringName _init_call_name = "nativescript_init";
-
- const StringName _terminate_call_name = "nativescript_terminate";
-
- const StringName _noarg_call_type = "nativescript_no_arg";
-
- const StringName _frame_call_name = "nativescript_frame";
-
+ StringName _init_call_type;
+ StringName _init_call_name;
+ StringName _terminate_call_name;
+ StringName _noarg_call_type;
+ StringName _frame_call_name;
#ifndef NO_THREADS
- const StringName _thread_enter_call_name = "nativescript_thread_enter";
- const StringName _thread_exit_call_name = "nativescript_thread_exit";
+ StringName _thread_enter_call_name;
+ StringName _thread_exit_call_name;
#endif
NativeScriptLanguage();
@@ -372,11 +368,14 @@ inline NativeScriptDesc *NativeScript::get_script_desc() const {
class NativeReloadNode : public Node {
GDCLASS(NativeReloadNode, Node)
- bool unloaded = false;
+ bool unloaded;
public:
static void _bind_methods();
void _notification(int p_what);
+
+ NativeReloadNode() :
+ unloaded(false) {}
};
class ResourceFormatLoaderNativeScript : public ResourceFormatLoader {
diff --git a/modules/gdscript/gdscript_function.cpp b/modules/gdscript/gdscript_function.cpp
index b935861652..f09ff224e8 100644
--- a/modules/gdscript/gdscript_function.cpp
+++ b/modules/gdscript/gdscript_function.cpp
@@ -155,6 +155,7 @@ String GDScriptFunction::_get_call_error(const Variant::CallError &p_err, const
return err_text;
}
+#ifdef DEBUG_ENABLED
static String _get_var_type(const Variant *p_type) {
String basestr;
@@ -164,7 +165,6 @@ static String _get_var_type(const Variant *p_type) {
if (!bobj) {
basestr = "null instance";
} else {
-#ifdef DEBUG_ENABLED
if (ObjectDB::instance_validate(bobj)) {
if (bobj->get_script_instance())
basestr = bobj->get_class() + " (" + bobj->get_script_instance()->get_script()->get_path().get_file() + ")";
@@ -173,10 +173,6 @@ static String _get_var_type(const Variant *p_type) {
} else {
basestr = "previously freed instance";
}
-
-#else
- basestr = "Object";
-#endif
}
} else {
@@ -185,6 +181,7 @@ static String _get_var_type(const Variant *p_type) {
return basestr;
}
+#endif
#if defined(__GNUC__)
#define OPCODES_TABLE \
@@ -422,8 +419,8 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
profile.call_count++;
profile.frame_call_count++;
}
-#endif
bool exit_ok = false;
+#endif
#ifdef DEBUG_ENABLED
OPCODE_WHILE(ip < _code_size) {
@@ -682,8 +679,10 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
GET_VARIANT_PTR(src, 2);
bool valid;
+#ifndef DEBUG_ENABLED
+ ClassDB::set_property(p_instance->owner, *index, *src, &valid);
+#else
bool ok = ClassDB::set_property(p_instance->owner, *index, *src, &valid);
-#ifdef DEBUG_ENABLED
if (!ok) {
err_text = "Internal error setting property: " + String(*index);
OPCODE_BREAK;
@@ -703,9 +702,11 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
GD_ERR_BREAK(indexname < 0 || indexname >= _global_names_count);
const StringName *index = &_global_names_ptr[indexname];
GET_VARIANT_PTR(dst, 2);
- bool ok = ClassDB::get_property(p_instance->owner, *index, *dst);
-#ifdef DEBUG_ENABLED
+#ifndef DEBUG_ENABLED
+ ClassDB::get_property(p_instance->owner, *index, *dst);
+#else
+ bool ok = ClassDB::get_property(p_instance->owner, *index, *dst);
if (!ok) {
err_text = "Internal error getting property: " + String(*index);
OPCODE_BREAK;
@@ -752,13 +753,13 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
OPCODE(OPCODE_ASSIGN_TYPED_BUILTIN) {
CHECK_SPACE(4);
- Variant::Type var_type = (Variant::Type)_code_ptr[ip + 1];
GET_VARIANT_PTR(dst, 2);
GET_VARIANT_PTR(src, 3);
+#ifdef DEBUG_ENABLED
+ Variant::Type var_type = (Variant::Type)_code_ptr[ip + 1];
GD_ERR_BREAK(var_type < 0 || var_type >= Variant::VARIANT_MAX);
-#ifdef DEBUG_ENABLED
if (src->get_type() != var_type) {
if (Variant::can_convert_strict(src->get_type(), var_type)) {
Variant::CallError ce;
@@ -782,11 +783,11 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
OPCODE(OPCODE_ASSIGN_TYPED_NATIVE) {
CHECK_SPACE(4);
- GET_VARIANT_PTR(type, 1);
GET_VARIANT_PTR(dst, 2);
GET_VARIANT_PTR(src, 3);
#ifdef DEBUG_ENABLED
+ GET_VARIANT_PTR(type, 1);
GDScriptNativeClass *nc = Object::cast_to<GDScriptNativeClass>(type->operator Object *());
GD_ERR_BREAK(!nc);
if (src->get_type() != Variant::OBJECT && src->get_type() != Variant::NIL) {
@@ -811,11 +812,11 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
OPCODE(OPCODE_ASSIGN_TYPED_SCRIPT) {
CHECK_SPACE(4);
- GET_VARIANT_PTR(type, 1);
GET_VARIANT_PTR(dst, 2);
GET_VARIANT_PTR(src, 3);
#ifdef DEBUG_ENABLED
+ GET_VARIANT_PTR(type, 1);
Script *base_type = Object::cast_to<Script>(type->operator Object *());
GD_ERR_BREAK(!base_type);
@@ -1282,10 +1283,11 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
OPCODE_BREAK;
}
#endif
+
Object *obj = argobj->operator Object *();
String signal = argname->operator String();
-#ifdef DEBUG_ENABLED
+#ifdef DEBUG_ENABLED
if (!obj) {
err_text = "First argument of yield() is null.";
OPCODE_BREAK;
@@ -1302,17 +1304,19 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
OPCODE_BREAK;
}
-#endif
Error err = obj->connect(signal, gdfs.ptr(), "_signal_callback", varray(gdfs), Object::CONNECT_ONESHOT);
-#ifdef DEBUG_ENABLED
if (err != OK) {
err_text = "Error connecting to signal: " + signal + " during yield().";
OPCODE_BREAK;
}
+#else
+ obj->connect(signal, gdfs.ptr(), "_signal_callback", varray(gdfs), Object::CONNECT_ONESHOT);
#endif
}
+#ifdef DEBUG_ENABLED
exit_ok = true;
+#endif
OPCODE_BREAK;
}
@@ -1389,7 +1393,9 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
CHECK_SPACE(2);
GET_VARIANT_PTR(r, 1);
retvalue = *r;
+#ifdef DEBUG_ENABLED
exit_ok = true;
+#endif
OPCODE_BREAK;
}
@@ -1461,9 +1467,9 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
OPCODE(OPCODE_ASSERT) {
CHECK_SPACE(2);
- GET_VARIANT_PTR(test, 1);
#ifdef DEBUG_ENABLED
+ GET_VARIANT_PTR(test, 1);
bool result = test->booleanize();
if (!result) {
@@ -1518,8 +1524,9 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
DISPATCH_OPCODE;
OPCODE(OPCODE_END) {
-
+#ifdef DEBUG_ENABLED
exit_ok = true;
+#endif
OPCODE_BREAK;
}
diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp
index 2fa5084d84..5f2655eb92 100644
--- a/modules/gdscript/gdscript_parser.cpp
+++ b/modules/gdscript/gdscript_parser.cpp
@@ -56,7 +56,9 @@ T *GDScriptParser::alloc_node() {
return t;
}
+#ifdef DEBUG_ENABLED
static String _find_function_name(const GDScriptParser::OperatorNode *p_call);
+#endif // DEBUG_ENABLED
bool GDScriptParser::_end_statement() {
@@ -677,7 +679,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
if (tokenizer->get_token() == GDScriptTokenizer::TK_BUILT_IN_TYPE) {
Variant::Type ct = tokenizer->get_token_type();
- if (p_parsing_constant == false) {
+ if (!p_parsing_constant) {
if (ct == Variant::ARRAY) {
if (tokenizer->get_token(2) == GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
ArrayNode *arr = alloc_node<ArrayNode>();
@@ -747,7 +749,6 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
while (!bfn && b) {
if (b->variables.has(identifier)) {
IdentifierNode *id = alloc_node<IdentifierNode>();
- LocalVarNode *lv = b->variables[identifier];
id->name = identifier;
id->declared_block = b;
id->line = id_line;
@@ -755,6 +756,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
bfn = true;
#ifdef DEBUG_ENABLED
+ LocalVarNode *lv = b->variables[identifier];
switch (tokenizer->get_token()) {
case GDScriptTokenizer::TK_OP_ASSIGN_ADD:
case GDScriptTokenizer::TK_OP_ASSIGN_BIT_AND:
diff --git a/modules/mobile_vr/SCsub b/modules/mobile_vr/SCsub
index e5725ceb6f..4bd184f025 100644
--- a/modules/mobile_vr/SCsub
+++ b/modules/mobile_vr/SCsub
@@ -6,5 +6,3 @@ Import('env_modules')
env_mobile_vr = env_modules.Clone()
env_mobile_vr.add_source_files(env.modules_sources, '*.cpp')
-
-SConscript("shaders/SCsub")
diff --git a/modules/mobile_vr/mobile_vr_interface.cpp b/modules/mobile_vr/mobile_vr_interface.cpp
index 2cabc7bd59..87e4ddd900 100644
--- a/modules/mobile_vr/mobile_vr_interface.cpp
+++ b/modules/mobile_vr/mobile_vr_interface.cpp
@@ -297,49 +297,6 @@ bool MobileVRInterface::initialize() {
mag_current_min = Vector3(0, 0, 0);
mag_current_max = Vector3(0, 0, 0);
-#if !defined(SERVER_ENABLED)
- // build our shader
- if (lens_shader == NULL) {
- ///@TODO need to switch between GLES2 and GLES3 version, Reduz suggested moving this into our drivers and making this a core shader
- // create a shader
- lens_shader = new LensDistortedShaderGLES3();
-
- // create our shader stuff
- lens_shader->init();
-
- glGenBuffers(1, &half_screen_quad);
- glBindBuffer(GL_ARRAY_BUFFER, half_screen_quad);
- {
- /* clang-format off */
- const float qv[16] = {
- 0, -1,
- -1, -1,
- 0, 1,
- -1, 1,
- 1, 1,
- 1, 1,
- 1, -1,
- 1, -1,
- };
- /* clang-format on */
-
- glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 16, qv, GL_STATIC_DRAW);
- }
-
- glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind
-
- glGenVertexArrays(1, &half_screen_array);
- glBindVertexArray(half_screen_array);
- glBindBuffer(GL_ARRAY_BUFFER, half_screen_quad);
- glVertexAttribPointer(VS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, 0);
- glEnableVertexAttribArray(0);
- glVertexAttribPointer(VS::ARRAY_TEX_UV, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, ((uint8_t *)NULL) + 8);
- glEnableVertexAttribArray(4);
- glBindVertexArray(0);
- glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind
- }
-#endif
-
// reset our orientation
orientation = Basis();
@@ -362,17 +319,6 @@ void MobileVRInterface::uninitialize() {
arvr_server->clear_primary_interface_if(this);
}
-#if !defined(SERVER_ENABLED)
- // cleanup our shader and buffers
- if (lens_shader != NULL) {
- glDeleteVertexArrays(1, &half_screen_array);
- glDeleteBuffers(1, &half_screen_quad);
-
- delete lens_shader;
- lens_shader = NULL;
- }
-#endif
-
initialized = false;
};
};
@@ -448,48 +394,29 @@ void MobileVRInterface::commit_for_eye(ARVRInterface::Eyes p_eye, RID p_render_t
// We must have a valid render target
ERR_FAIL_COND(!p_render_target.is_valid());
- // We must have an initialised shader
- ERR_FAIL_COND(lens_shader != NULL);
-
// Because we are rendering to our device we must use our main viewport!
ERR_FAIL_COND(p_screen_rect == Rect2());
- float offset_x = 0.0;
- float aspect_ratio = 0.5 * p_screen_rect.size.x / p_screen_rect.size.y;
+ Rect2 dest = p_screen_rect;
Vector2 eye_center;
+ // we output half a screen
+ dest.size.x *= 0.5;
+
if (p_eye == ARVRInterface::EYE_LEFT) {
- offset_x = -1.0;
eye_center.x = ((-intraocular_dist / 2.0) + (display_width / 4.0)) / (display_width / 2.0);
} else if (p_eye == ARVRInterface::EYE_RIGHT) {
+ dest.position.x = dest.size.x;
eye_center.x = ((intraocular_dist / 2.0) - (display_width / 4.0)) / (display_width / 2.0);
}
+ // we don't offset the eye center vertically (yet)
+ eye_center.y = 0.0;
// unset our render target so we are outputting to our main screen by making RasterizerStorageGLES3::system_fbo our current FBO
VSG::rasterizer->set_current_render_target(RID());
- // now output to screen
- // VSG::rasterizer->blit_render_target_to_screen(p_render_target, screen_rect, 0);
-
- // get our render target
- RID eye_texture = VSG::storage->render_target_get_texture(p_render_target);
- uint32_t texid = VS::get_singleton()->texture_get_texid(eye_texture);
-#if !defined(SERVER_ENABLED)
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, texid);
-
- lens_shader->bind();
- lens_shader->set_uniform(LensDistortedShaderGLES3::OFFSET_X, offset_x);
- lens_shader->set_uniform(LensDistortedShaderGLES3::K1, k1);
- lens_shader->set_uniform(LensDistortedShaderGLES3::K2, k2);
- lens_shader->set_uniform(LensDistortedShaderGLES3::EYE_CENTER, eye_center);
- lens_shader->set_uniform(LensDistortedShaderGLES3::UPSCALE, oversample);
- lens_shader->set_uniform(LensDistortedShaderGLES3::ASPECT_RATIO, aspect_ratio);
-
- glBindVertexArray(half_screen_array);
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- glBindVertexArray(0);
-#endif
+ // and output
+ VSG::rasterizer->output_lens_distorted_to_screen(p_render_target, dest, k1, k2, eye_center, oversample);
};
void MobileVRInterface::process() {
@@ -512,8 +439,6 @@ MobileVRInterface::MobileVRInterface() {
k1 = 0.215;
k2 = 0.215;
last_ticks = 0;
-
- lens_shader = NULL;
};
MobileVRInterface::~MobileVRInterface() {
diff --git a/modules/mobile_vr/mobile_vr_interface.h b/modules/mobile_vr/mobile_vr_interface.h
index 63cad4c738..05b6331f94 100644
--- a/modules/mobile_vr/mobile_vr_interface.h
+++ b/modules/mobile_vr/mobile_vr_interface.h
@@ -34,10 +34,6 @@
#include "servers/arvr/arvr_interface.h"
#include "servers/arvr/arvr_positional_tracker.h"
-#if !defined(SERVER_ENABLED)
-#include "shaders/lens_distorted.glsl.gen.h"
-#endif
-
/**
@author Bastiaan Olij <mux213@gmail.com>
@@ -60,14 +56,6 @@ private:
float eye_height;
uint64_t last_ticks;
-#if !defined(SERVER_ENABLED)
- LensDistortedShaderGLES3 *lens_shader;
- GLuint half_screen_quad;
- GLuint half_screen_array;
-#else
- void *lens_shader;
-#endif
-
real_t intraocular_dist;
real_t display_width;
real_t display_to_lens;
diff --git a/modules/mobile_vr/shaders/SCsub b/modules/mobile_vr/shaders/SCsub
deleted file mode 100644
index 97a3598598..0000000000
--- a/modules/mobile_vr/shaders/SCsub
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/usr/bin/env python
-
-Import('env')
-
-if 'GLES3_GLSL' in env['BUILDERS']:
- env.GLES3_GLSL('lens_distorted.glsl');
diff --git a/modules/mono/SCsub b/modules/mono/SCsub
index 1d5c145027..e4691ee5c8 100644
--- a/modules/mono/SCsub
+++ b/modules/mono/SCsub
@@ -244,16 +244,13 @@ def mono_build_solution(source, target, env):
copyfile(os.path.join(src_dir, asm_file), os.path.join(dst_dir, asm_file))
-output_dir = Dir('#bin').abspath
-assemblies_output_dir = Dir(env['mono_assemblies_output_dir']).abspath
-
-mono_sln_builder = Builder(action=mono_build_solution)
-env_mono.Append(BUILDERS={'MonoBuildSolution': mono_sln_builder})
-env_mono.MonoBuildSolution(
- os.path.join(assemblies_output_dir, 'GodotSharpTools.dll'),
- 'editor/GodotSharpTools/GodotSharpTools.sln'
-)
-
-if os.path.normpath(output_dir) != os.path.normpath(assemblies_output_dir):
- rel_assemblies_output_dir = os.path.relpath(assemblies_output_dir, output_dir)
- env_mono.Append(CPPDEFINES={'GD_MONO_EDITOR_ASSEMBLIES_DIR': rel_assemblies_output_dir})
+if env['tools']:
+ output_dir = Dir('#bin').abspath
+ editor_tools_dir = os.path.join(output_dir, 'GodotSharp', 'Tools')
+
+ mono_sln_builder = Builder(action=mono_build_solution)
+ env_mono.Append(BUILDERS={'MonoBuildSolution': mono_sln_builder})
+ env_mono.MonoBuildSolution(
+ os.path.join(editor_tools_dir, 'GodotSharpTools.dll'),
+ 'editor/GodotSharpTools/GodotSharpTools.sln'
+ )
diff --git a/modules/mono/config.py b/modules/mono/config.py
index 01649a972e..8427103ee7 100644
--- a/modules/mono/config.py
+++ b/modules/mono/config.py
@@ -5,7 +5,7 @@ import sys
import subprocess
from distutils.version import LooseVersion
-from SCons.Script import BoolVariable, Dir, Environment, File, PathVariable, SCons, Variables
+from SCons.Script import BoolVariable, Dir, Environment, File, SCons, Variables
monoreg = imp.load_source('mono_reg_utils', 'modules/mono/mono_reg_utils.py')
@@ -55,30 +55,20 @@ def copy_file(src_dir, dst_dir, name):
copyfile(src_path, dst_path)
-def custom_path_is_dir_create(key, val, env):
- """Validator to check if Path is a directory, creating it if it does not exist.
- Similar to PathIsDirCreate, except it uses SCons.Script.Dir() and
- SCons.Script.File() in order to support the '#' top level directory token.
- """
- # Dir constructor will throw an error if the path points to a file
- fsDir = Dir(val)
- if not fsDir.exists:
- os.makedirs(fsDir.abspath)
-
-
def configure(env):
env.use_ptrcall = True
env.add_module_version_string('mono')
envvars = Variables()
envvars.Add(BoolVariable('mono_static', 'Statically link mono', False))
- envvars.Add(PathVariable('mono_assemblies_output_dir', 'Path to the assemblies output directory', '#bin', custom_path_is_dir_create))
+ envvars.Add(BoolVariable('copy_mono_root', 'Make a copy of the mono installation directory to bundle with the editor', False))
envvars.Update(env)
bits = env['bits']
+ tools_enabled = env['tools']
mono_static = env['mono_static']
- assemblies_output_dir = Dir(env['mono_assemblies_output_dir']).abspath
+ copy_mono_root = env['copy_mono_root']
mono_lib_names = ['mono-2.0-sgen', 'monosgen-2.0']
@@ -151,8 +141,6 @@ def configure(env):
raise RuntimeError('Could not find mono shared library in: ' + mono_bin_path)
copy_file(mono_bin_path, 'bin', mono_dll_name + '.dll')
-
- copy_file(os.path.join(mono_lib_path, 'mono', '4.5'), assemblies_output_dir, 'mscorlib.dll')
else:
sharedlib_ext = '.dylib' if sys.platform == 'darwin' else '.so'
@@ -204,16 +192,14 @@ def configure(env):
if sys.platform == 'darwin':
env.Append(LINKFLAGS=['-Wl,-force_load,' + mono_lib_file])
- elif sys.platform == 'linux' or sys.platform == 'linux2':
- env.Append(LINKFLAGS=['-Wl,-whole-archive', mono_lib_file, '-Wl,-no-whole-archive'])
else:
- raise RuntimeError('mono-static: Not supported on this platform')
+ env.Append(LINKFLAGS=['-Wl,-whole-archive', mono_lib_file, '-Wl,-no-whole-archive'])
else:
env.Append(LIBS=[mono_lib])
if sys.platform == 'darwin':
env.Append(LIBS=['iconv', 'pthread'])
- elif sys.platform == 'linux' or sys.platform == 'linux2':
+ else:
env.Append(LIBS=['m', 'rt', 'dl', 'pthread'])
if not mono_static:
@@ -223,8 +209,6 @@ def configure(env):
raise RuntimeError('Could not find mono shared library in: ' + mono_lib_path)
copy_file(mono_lib_path, 'bin', 'lib' + mono_so_name + sharedlib_ext)
-
- copy_file(os.path.join(mono_lib_path, 'mono', '4.5'), assemblies_output_dir, 'mscorlib.dll')
else:
assert not mono_static
@@ -238,7 +222,6 @@ def configure(env):
mono_lib_path = ''
mono_so_name = ''
- mono_prefix = subprocess.check_output(['pkg-config', 'mono-2', '--variable=prefix']).decode('utf8').strip()
tmpenv = Environment()
tmpenv.AppendENVPath('PKG_CONFIG_PATH', os.getenv('PKG_CONFIG_PATH'))
@@ -255,16 +238,163 @@ def configure(env):
raise RuntimeError('Could not find mono shared library in: ' + str(tmpenv['LIBPATH']))
copy_file(mono_lib_path, 'bin', 'lib' + mono_so_name + sharedlib_ext)
- copy_file(os.path.join(mono_prefix, 'lib', 'mono', '4.5'), assemblies_output_dir, 'mscorlib.dll')
env.Append(LINKFLAGS='-rdynamic')
+ if not tools_enabled:
+ if not mono_root:
+ mono_root = subprocess.check_output(['pkg-config', 'mono-2', '--variable=prefix']).decode('utf8').strip()
+
+ make_template_dir(env, mono_root)
+
+ if copy_mono_root:
+ if not mono_root:
+ mono_root = subprocess.check_output(['pkg-config', 'mono-2', '--variable=prefix']).decode('utf8').strip()
+
+ if tools_enabled:
+ copy_mono_root_files(env, mono_root)
+ else:
+ print("Ignoring option: 'copy_mono_root'. Only available for builds with 'tools' enabled.")
+
+
+def make_template_dir(env, mono_root):
+ from shutil import rmtree
+
+ platform = env['platform']
+ target = env['target']
+
+ template_dir_name = ''
+
+ if platform == 'windows':
+ template_dir_name = 'data.mono.%s.%s.%s' % (platform, env['bits'], target)
+ elif platform == 'osx':
+ template_dir_name = 'data.mono.%s.%s' % (platform, target)
+ elif platform == 'x11':
+ template_dir_name = 'data.mono.%s.%s.%s' % (platform, env['bits'], target)
+ else:
+ assert False
+
+ output_dir = Dir('#bin').abspath
+ template_dir = os.path.join(output_dir, template_dir_name)
+
+ template_mono_root_dir = os.path.join(template_dir, 'Mono')
+
+ if os.path.isdir(template_mono_root_dir):
+ rmtree(template_mono_root_dir) # Clean first
+
+ # Copy etc/mono/
+
+ template_mono_config_dir = os.path.join(template_mono_root_dir, 'etc', 'mono')
+ copy_mono_etc_dir(mono_root, template_mono_config_dir, env['platform'])
+
+ # Copy the required shared libraries
+
+ copy_mono_shared_libs(mono_root, template_mono_root_dir, env['platform'])
+
+
+def copy_mono_root_files(env, mono_root):
+ from glob import glob
+ from shutil import copy
+ from shutil import rmtree
+
+ if not mono_root:
+ raise RuntimeError('Mono installation directory not found')
+
+ output_dir = Dir('#bin').abspath
+ editor_mono_root_dir = os.path.join(output_dir, 'GodotSharp', 'Mono')
+
+ if os.path.isdir(editor_mono_root_dir):
+ rmtree(editor_mono_root_dir) # Clean first
+
+ # Copy etc/mono/
+
+ editor_mono_config_dir = os.path.join(editor_mono_root_dir, 'etc', 'mono')
+ copy_mono_etc_dir(mono_root, editor_mono_config_dir, env['platform'])
+
+ # Copy the required shared libraries
+
+ copy_mono_shared_libs(mono_root, editor_mono_root_dir, env['platform'])
+
+ # Copy framework assemblies
+
+ mono_framework_dir = os.path.join(mono_root, 'lib', 'mono', '4.5')
+ mono_framework_facades_dir = os.path.join(mono_framework_dir, 'Facades')
+
+ editor_mono_framework_dir = os.path.join(editor_mono_root_dir, 'lib', 'mono', '4.5')
+ editor_mono_framework_facades_dir = os.path.join(editor_mono_framework_dir, 'Facades')
+
+ if not os.path.isdir(editor_mono_framework_dir):
+ os.makedirs(editor_mono_framework_dir)
+ if not os.path.isdir(editor_mono_framework_facades_dir):
+ os.makedirs(editor_mono_framework_facades_dir)
+
+ for assembly in glob(os.path.join(mono_framework_dir, '*.dll')):
+ copy(assembly, editor_mono_framework_dir)
+ for assembly in glob(os.path.join(mono_framework_facades_dir, '*.dll')):
+ copy(assembly, editor_mono_framework_facades_dir)
+
+
+def copy_mono_etc_dir(mono_root, target_mono_config_dir, platform):
+ from distutils.dir_util import copy_tree
+ from glob import glob
+ from shutil import copy
+
+ if not os.path.isdir(target_mono_config_dir):
+ os.makedirs(target_mono_config_dir)
+
+ mono_etc_dir = os.path.join(mono_root, 'etc', 'mono')
+ if not os.path.isdir(mono_etc_dir):
+ mono_etc_dir = ''
+ etc_hint_dirs = []
+ if platform != 'windows':
+ etc_hint_dirs += ['/etc/mono', '/usr/local/etc/mono']
+ if 'MONO_CFG_DIR' in os.environ:
+ etc_hint_dirs += [os.path.join(os.environ['MONO_CFG_DIR'], 'mono')]
+ for etc_hint_dir in etc_hint_dirs:
+ if os.path.isdir(etc_hint_dir):
+ mono_etc_dir = etc_hint_dir
+ break
+ if not mono_etc_dir:
+ raise RuntimeError('Mono installation etc directory not found')
+
+ copy_tree(os.path.join(mono_etc_dir, '2.0'), os.path.join(target_mono_config_dir, '2.0'))
+ copy_tree(os.path.join(mono_etc_dir, '4.0'), os.path.join(target_mono_config_dir, '4.0'))
+ copy_tree(os.path.join(mono_etc_dir, '4.5'), os.path.join(target_mono_config_dir, '4.5'))
+ copy_tree(os.path.join(mono_etc_dir, 'mconfig'), os.path.join(target_mono_config_dir, 'mconfig'))
+
+ for file in glob(os.path.join(mono_etc_dir, '*')):
+ if os.path.isfile(file):
+ copy(file, target_mono_config_dir)
+
+
+def copy_mono_shared_libs(mono_root, target_mono_root_dir, platform):
+ from shutil import copy
+
+ if platform == 'windows':
+ target_mono_bin_dir = os.path.join(target_mono_root_dir, 'bin')
+
+ if not os.path.isdir(target_mono_bin_dir):
+ os.makedirs(target_mono_bin_dir)
+
+ copy(os.path.join(mono_root, 'bin', 'MonoPosixHelper.dll'), os.path.join(target_mono_bin_dir, 'MonoPosixHelper.dll'))
+ else:
+ target_mono_lib_dir = os.path.join(target_mono_root_dir, 'lib')
+
+ if not os.path.isdir(target_mono_lib_dir):
+ os.makedirs(target_mono_lib_dir)
+
+ if platform == 'osx':
+ copy(os.path.join(mono_root, 'lib', 'libMonoPosixHelper.dylib'), os.path.join(target_mono_lib_dir, 'libMonoPosixHelper.dylib'))
+ elif platform == 'x11':
+ copy(os.path.join(mono_root, 'lib', 'libmono-btls-shared.so'), os.path.join(target_mono_lib_dir, 'libmono-btls-shared.so'))
+ copy(os.path.join(mono_root, 'lib', 'libMonoPosixHelper.so'), os.path.join(target_mono_lib_dir, 'libMonoPosixHelper.so'))
+
def configure_for_mono_version(env, mono_version):
if mono_version is None:
raise RuntimeError('Mono JIT compiler version not found')
print('Found Mono JIT compiler version: ' + str(mono_version))
- if mono_version >= LooseVersion("5.12.0"):
+ if mono_version >= LooseVersion('5.12.0'):
env.Append(CPPFLAGS=['-DHAS_PENDING_EXCEPTIONS'])
diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp
index 91fd482235..5160d42367 100644
--- a/modules/mono/csharp_script.cpp
+++ b/modules/mono/csharp_script.cpp
@@ -1194,7 +1194,7 @@ bool CSharpInstance::set(const StringName &p_name, const Variant &p_value) {
MonoObject *ret = method->invoke(mono_object, args);
- if (ret && GDMonoMarshal::unbox<MonoBoolean>(ret) == true)
+ if (ret && GDMonoMarshal::unbox<MonoBoolean>(ret))
return true;
break;
@@ -1459,7 +1459,7 @@ MonoObject *CSharpInstance::_internal_new_managed() {
void CSharpInstance::mono_object_disposed(MonoObject *p_obj) {
#ifdef DEBUG_ENABLED
- CRASH_COND(base_ref == true);
+ CRASH_COND(base_ref);
CRASH_COND(gchandle.is_null());
#endif
CSharpLanguage::get_singleton()->release_script_gchandle(p_obj, gchandle);
@@ -1468,7 +1468,7 @@ void CSharpInstance::mono_object_disposed(MonoObject *p_obj) {
void CSharpInstance::mono_object_disposed_baseref(MonoObject *p_obj, bool p_is_finalizer, bool &r_owner_deleted) {
#ifdef DEBUG_ENABLED
- CRASH_COND(base_ref == false);
+ CRASH_COND(!base_ref);
CRASH_COND(gchandle.is_null());
#endif
if (_unreference_owner_unsafe()) {
diff --git a/modules/mono/editor/GodotSharpTools/Editor/GodotSharpExport.cs b/modules/mono/editor/GodotSharpTools/Editor/GodotSharpExport.cs
new file mode 100644
index 0000000000..9f0d562ef7
--- /dev/null
+++ b/modules/mono/editor/GodotSharpTools/Editor/GodotSharpExport.cs
@@ -0,0 +1,72 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Runtime.CompilerServices;
+
+namespace GodotSharpTools.Editor
+{
+ public static class GodotSharpExport
+ {
+ public static void _ExportBegin(string[] features, bool debug, string path, int flags)
+ {
+ var featureSet = new HashSet<string>(features);
+
+ if (PlatformHasTemplateDir(featureSet))
+ {
+ string templateDirName = "data.mono";
+
+ if (featureSet.Contains("Windows"))
+ {
+ templateDirName += ".windows";
+ templateDirName += featureSet.Contains("64") ? ".64" : ".32";
+ }
+ else if (featureSet.Contains("X11"))
+ {
+ templateDirName += ".x11";
+ templateDirName += featureSet.Contains("64") ? ".64" : ".32";
+ }
+ else
+ {
+ throw new NotSupportedException("Target platform not supported");
+ }
+
+ templateDirName += debug ? ".debug" : ".release";
+
+ string templateDirPath = Path.Combine(GetTemplatesDir(), templateDirName);
+
+ if (!Directory.Exists(templateDirPath))
+ throw new FileNotFoundException("Data template directory not found");
+
+ string outputDir = new FileInfo(path).Directory.FullName;
+
+ string outputDataDir = Path.Combine(outputDir, GetDataDirName());
+
+ Directory.Delete(outputDataDir, recursive: true); // Clean first
+ Directory.CreateDirectory(outputDataDir);
+
+ foreach (string dir in Directory.GetDirectories(templateDirPath, "*", SearchOption.AllDirectories))
+ {
+ Directory.CreateDirectory(Path.Combine(outputDataDir, dir.Substring(templateDirPath.Length + 1)));
+ }
+
+ foreach (string file in Directory.GetFiles(templateDirPath, "*", SearchOption.AllDirectories))
+ {
+ File.Copy(file, Path.Combine(outputDataDir, file.Substring(templateDirPath.Length + 1)));
+ }
+ }
+ }
+
+ public static bool PlatformHasTemplateDir(HashSet<string> featureSet)
+ {
+ // OSX export templates are contained in a zip, so we place
+ // our custom template inside it and let Godot do the rest.
+ return !featureSet.Contains("OSX");
+ }
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ extern static string GetTemplatesDir();
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ extern static string GetDataDirName();
+ }
+}
diff --git a/modules/mono/editor/GodotSharpTools/GodotSharpTools.csproj b/modules/mono/editor/GodotSharpTools/GodotSharpTools.csproj
index 773e8196f7..fceb732426 100644
--- a/modules/mono/editor/GodotSharpTools/GodotSharpTools.csproj
+++ b/modules/mono/editor/GodotSharpTools/GodotSharpTools.csproj
@@ -41,6 +41,7 @@
<Compile Include="Project\ProjectUtils.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Utils\OS.cs" />
+ <Compile Include="Editor\GodotSharpExport.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project> \ No newline at end of file
diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp
index 308c54ecb3..bcf08026bc 100644
--- a/modules/mono/editor/bindings_generator.cpp
+++ b/modules/mono/editor/bindings_generator.cpp
@@ -1269,12 +1269,12 @@ Error BindingsGenerator::generate_glue(const String &p_output_dir) {
output.push_back("namespace GodotSharpBindings\n" OPEN_BLOCK "\n");
output.push_back("uint64_t get_core_api_hash() { return ");
- output.push_back(String::num_uint64(GDMono::get_singleton()->get_api_core_hash()) + "; }\n");
+ output.push_back(String::num_uint64(GDMono::get_singleton()->get_api_core_hash()) + "U; }\n");
output.push_back("#ifdef TOOLS_ENABLED\n"
"uint64_t get_editor_api_hash() { return ");
- output.push_back(String::num_uint64(GDMono::get_singleton()->get_api_editor_hash()) +
- "; }\n#endif // TOOLS_ENABLED\n");
+ output.push_back(String::num_uint64(GDMono::get_singleton()->get_api_editor_hash()) + "U; }\n");
+ output.push_back("#endif // TOOLS_ENABLED\n");
output.push_back("uint32_t get_bindings_version() { return ");
output.push_back(String::num_uint64(BINDINGS_GENERATOR_VERSION) + "; }\n");
@@ -2019,7 +2019,7 @@ void BindingsGenerator::_populate_builtin_type_interfaces() {
// bool
itype = TypeInterface::create_value_type(String("bool"));
- itype.c_arg_in = "&%s";
+ itype.c_arg_in = "&%s_in";
// /* MonoBoolean <---> bool
itype.c_in = "\t%0 %1_in = (%0)%1;\n";
itype.c_out = "\treturn (%0)%1;\n";
@@ -2244,8 +2244,8 @@ void BindingsGenerator::_populate_global_constants() {
String constant_name = GlobalConstants::get_global_constant_name(i);
const DocData::ConstantDoc *const_doc = NULL;
- for (int i = 0; i < global_scope_doc.constants.size(); i++) {
- const DocData::ConstantDoc &curr_const_doc = global_scope_doc.constants[i];
+ for (int j = 0; j < global_scope_doc.constants.size(); j++) {
+ const DocData::ConstantDoc &curr_const_doc = global_scope_doc.constants[j];
if (curr_const_doc.name == constant_name) {
const_doc = &curr_const_doc;
diff --git a/modules/mono/editor/csharp_project.cpp b/modules/mono/editor/csharp_project.cpp
index 4764cbe941..6f223b75a3 100644
--- a/modules/mono/editor/csharp_project.cpp
+++ b/modules/mono/editor/csharp_project.cpp
@@ -51,7 +51,7 @@ String generate_core_api_project(const String &p_dir, const Vector<String> &p_fi
MonoObject *ret = klass->get_method("GenCoreApiProject", 2)->invoke(NULL, args, &exc);
if (exc) {
- GDMonoUtils::debug_unhandled_exception(exc);
+ GDMonoUtils::debug_print_unhandled_exception(exc);
ERR_FAIL_V(String());
}
@@ -72,7 +72,7 @@ String generate_editor_api_project(const String &p_dir, const String &p_core_dll
MonoObject *ret = klass->get_method("GenEditorApiProject", 3)->invoke(NULL, args, &exc);
if (exc) {
- GDMonoUtils::debug_unhandled_exception(exc);
+ GDMonoUtils::debug_print_unhandled_exception(exc);
ERR_FAIL_V(String());
}
@@ -93,7 +93,7 @@ String generate_game_project(const String &p_dir, const String &p_name, const Ve
MonoObject *ret = klass->get_method("GenGameProject", 3)->invoke(NULL, args, &exc);
if (exc) {
- GDMonoUtils::debug_unhandled_exception(exc);
+ GDMonoUtils::debug_print_unhandled_exception(exc);
ERR_FAIL_V(String());
}
@@ -114,7 +114,7 @@ void add_item(const String &p_project_path, const String &p_item_type, const Str
klass->get_method("AddItemToProjectChecked", 3)->invoke(NULL, args, &exc);
if (exc) {
- GDMonoUtils::debug_unhandled_exception(exc);
+ GDMonoUtils::debug_print_unhandled_exception(exc);
ERR_FAIL();
}
}
diff --git a/modules/mono/editor/godotsharp_builds.cpp b/modules/mono/editor/godotsharp_builds.cpp
index d397814fa7..8fe6e46b60 100644
--- a/modules/mono/editor/godotsharp_builds.cpp
+++ b/modules/mono/editor/godotsharp_builds.cpp
@@ -249,6 +249,18 @@ bool GodotSharpBuilds::build_api_sln(const String &p_name, const String &p_api_s
bool GodotSharpBuilds::copy_api_assembly(const String &p_src_dir, const String &p_dst_dir, const String &p_assembly_name, APIAssembly::Type p_api_type) {
+ // Create destination directory if needed
+ if (!DirAccess::exists(p_dst_dir)) {
+ DirAccess *da = DirAccess::create_for_path(p_dst_dir);
+ Error err = da->make_dir_recursive(p_dst_dir);
+ memdelete(da);
+
+ if (err != OK) {
+ show_build_error_dialog("Failed to create destination directory for the API assemblies. Error: " + itos(err));
+ return false;
+ }
+ }
+
String assembly_file = p_assembly_name + ".dll";
String assembly_src = p_src_dir.plus_file(assembly_file);
String assembly_dst = p_dst_dir.plus_file(assembly_file);
@@ -296,9 +308,9 @@ bool GodotSharpBuilds::make_api_sln(APIAssembly::Type p_api_type) {
String api_name = p_api_type == APIAssembly::API_CORE ? API_ASSEMBLY_NAME : EDITOR_API_ASSEMBLY_NAME;
String api_build_config = "Release";
- EditorProgress pr("mono_build_release_" + api_name, "Building " + api_name + " solution...", 4);
+ EditorProgress pr("mono_build_release_" + api_name, "Building " + api_name + " solution...", 3);
- pr.step("Generating " + api_name + " solution");
+ pr.step("Generating " + api_name + " solution", 0);
String core_api_sln_dir = GodotSharpDirs::get_mono_solutions_dir()
.plus_file(_api_folder_name(APIAssembly::API_CORE))
@@ -336,34 +348,19 @@ bool GodotSharpBuilds::make_api_sln(APIAssembly::Type p_api_type) {
}
}
- pr.step("Building " + api_name + " solution");
+ pr.step("Building " + api_name + " solution", 1);
if (!GodotSharpBuilds::build_api_sln(api_name, api_sln_dir, api_build_config))
return false;
- pr.step("Copying " + api_name + " assembly");
-
- String res_assemblies_dir = GodotSharpDirs::get_res_assemblies_dir();
-
- // Create assemblies directory if needed
- if (!DirAccess::exists(res_assemblies_dir)) {
- DirAccess *da = DirAccess::create_for_path(res_assemblies_dir);
- Error err = da->make_dir_recursive(res_assemblies_dir);
- memdelete(da);
-
- if (err != OK) {
- show_build_error_dialog("Failed to create assemblies directory. Error: " + itos(err));
- return false;
- }
- }
+ pr.step("Copying " + api_name + " assembly", 2);
// Copy the built assembly to the assemblies directory
String api_assembly_dir = api_sln_dir.plus_file("bin").plus_file(api_build_config);
+ String res_assemblies_dir = GodotSharpDirs::get_res_assemblies_dir();
if (!GodotSharpBuilds::copy_api_assembly(api_assembly_dir, res_assemblies_dir, api_name, p_api_type))
return false;
- pr.step("Done");
-
return true;
}
@@ -372,15 +369,39 @@ bool GodotSharpBuilds::build_project_blocking(const String &p_config) {
if (!FileAccess::exists(GodotSharpDirs::get_project_sln_path()))
return true; // No solution to build
- if (!GodotSharpBuilds::make_api_sln(APIAssembly::API_CORE))
- return false;
+ String editor_prebuilt_api_dir = GodotSharpDirs::get_data_editor_prebuilt_api_dir();
+ String res_assemblies_dir = GodotSharpDirs::get_res_assemblies_dir();
- if (!GodotSharpBuilds::make_api_sln(APIAssembly::API_EDITOR))
- return false;
+ if (FileAccess::exists(editor_prebuilt_api_dir.plus_file(API_ASSEMBLY_NAME ".dll"))) {
+ EditorProgress pr("mono_copy_prebuilt_api_assemblies",
+ "Copying prebuilt " API_ASSEMBLY_NAME " assemblies...", 1);
+ pr.step("Copying " API_ASSEMBLY_NAME " assembly", 0);
- EditorProgress pr("mono_project_debug_build", "Building project solution...", 2);
+ if (!GodotSharpBuilds::copy_api_assembly(editor_prebuilt_api_dir, res_assemblies_dir,
+ API_ASSEMBLY_NAME, APIAssembly::API_CORE)) {
+ return false;
+ }
+ } else {
+ if (!GodotSharpBuilds::make_api_sln(APIAssembly::API_CORE))
+ return false;
+ }
- pr.step("Building project solution");
+ if (DirAccess::exists(editor_prebuilt_api_dir.plus_file(EDITOR_API_ASSEMBLY_NAME ".dll"))) {
+ EditorProgress pr("mono_copy_prebuilt_api_assemblies",
+ "Copying prebuilt " EDITOR_API_ASSEMBLY_NAME " assemblies...", 1);
+ pr.step("Copying " EDITOR_API_ASSEMBLY_NAME " assembly", 0);
+
+ if (!GodotSharpBuilds::copy_api_assembly(editor_prebuilt_api_dir, res_assemblies_dir,
+ EDITOR_API_ASSEMBLY_NAME, APIAssembly::API_EDITOR)) {
+ return false;
+ }
+ } else {
+ if (!GodotSharpBuilds::make_api_sln(APIAssembly::API_EDITOR))
+ return false;
+ }
+
+ EditorProgress pr("mono_project_debug_build", "Building project solution...", 1);
+ pr.step("Building project solution", 0);
MonoBuildInfo build_info(GodotSharpDirs::get_project_sln_path(), p_config);
if (!GodotSharpBuilds::get_singleton()->build(build_info)) {
@@ -388,8 +409,6 @@ bool GodotSharpBuilds::build_project_blocking(const String &p_config) {
return false;
}
- pr.step("Done");
-
return true;
}
diff --git a/modules/mono/editor/godotsharp_editor.cpp b/modules/mono/editor/godotsharp_editor.cpp
index 3ee38515bf..fca88a7164 100644
--- a/modules/mono/editor/godotsharp_editor.cpp
+++ b/modules/mono/editor/godotsharp_editor.cpp
@@ -197,6 +197,7 @@ void GodotSharpEditor::register_internal_calls() {
mono_add_internal_call("GodotSharpTools.Utils.OS::GetPlatformName", (void *)godot_icall_Utils_OS_GetPlatformName);
GodotSharpBuilds::register_internal_calls();
+ GodotSharpExport::register_internal_calls();
}
void GodotSharpEditor::show_error_dialog(const String &p_message, const String &p_title) {
diff --git a/modules/mono/editor/godotsharp_export.cpp b/modules/mono/editor/godotsharp_export.cpp
index cd09e6516a..933ede93dc 100644
--- a/modules/mono/editor/godotsharp_export.cpp
+++ b/modules/mono/editor/godotsharp_export.cpp
@@ -30,12 +30,37 @@
#include "godotsharp_export.h"
+#include "core/version.h"
+
#include "../csharp_script.h"
#include "../godotsharp_defs.h"
#include "../godotsharp_dirs.h"
+#include "../mono_gd/gd_mono_class.h"
+#include "../mono_gd/gd_mono_marshal.h"
#include "godotsharp_builds.h"
-void GodotSharpExport::_export_file(const String &p_path, const String &p_type, const Set<String> &p_features) {
+static MonoString *godot_icall_GodotSharpExport_GetTemplatesDir() {
+ String current_version = VERSION_FULL_CONFIG;
+ String templates_dir = EditorSettings::get_singleton()->get_templates_dir().plus_file(current_version);
+ return GDMonoMarshal::mono_string_from_godot(ProjectSettings::get_singleton()->globalize_path(templates_dir));
+}
+
+static MonoString *godot_icall_GodotSharpExport_GetDataDirName() {
+ String appname = ProjectSettings::get_singleton()->get("application/config/name");
+ String appname_safe = OS::get_singleton()->get_safe_dir_name(appname);
+ return GDMonoMarshal::mono_string_from_godot("data_" + appname_safe);
+}
+
+void GodotSharpExport::register_internal_calls() {
+ static bool registered = false;
+ ERR_FAIL_COND(registered);
+ registered = true;
+
+ mono_add_internal_call("GodotSharpTools.Editor.GodotSharpExport::GetTemplatesDir", (void *)godot_icall_GodotSharpExport_GetTemplatesDir);
+ mono_add_internal_call("GodotSharpTools.Editor.GodotSharpExport::GetDataDirName", (void *)godot_icall_GodotSharpExport_GetDataDirName);
+}
+
+void GodotSharpExport::_export_file(const String &p_path, const String &p_type, const Set<String> &) {
if (p_type != CSharpLanguage::get_singleton()->get_type())
return;
@@ -56,59 +81,78 @@ void GodotSharpExport::_export_begin(const Set<String> &p_features, bool p_debug
// TODO right now there is no way to stop the export process with an error
ERR_FAIL_COND(!GDMono::get_singleton()->is_runtime_initialized());
- ERR_FAIL_NULL(GDMono::get_singleton()->get_tools_domain());
+ ERR_FAIL_NULL(TOOLS_DOMAIN);
+ ERR_FAIL_NULL(GDMono::get_singleton()->get_editor_tools_assembly());
String build_config = p_debug ? "Debug" : "Release";
ERR_FAIL_COND(!GodotSharpBuilds::build_project_blocking(build_config));
- // Add API assemblies
-
- String core_api_dll_path = GodotSharpDirs::get_res_assemblies_dir().plus_file(API_ASSEMBLY_NAME ".dll");
- ERR_FAIL_COND(!_add_assembly(core_api_dll_path, core_api_dll_path));
-
- String editor_api_dll_path = GodotSharpDirs::get_res_assemblies_dir().plus_file(EDITOR_API_ASSEMBLY_NAME ".dll");
- ERR_FAIL_COND(!_add_assembly(editor_api_dll_path, editor_api_dll_path));
+ // Add dependency assemblies
- // Add project assembly
+ Map<String, String> dependencies;
String project_dll_name = ProjectSettings::get_singleton()->get("application/config/name");
if (project_dll_name.empty()) {
project_dll_name = "UnnamedProject";
}
- String project_dll_src_path = GodotSharpDirs::get_res_temp_assemblies_base_dir().plus_file(build_config).plus_file(project_dll_name + ".dll");
- String project_dll_dst_path = GodotSharpDirs::get_res_assemblies_dir().plus_file(project_dll_name + ".dll");
- ERR_FAIL_COND(!_add_assembly(project_dll_src_path, project_dll_dst_path));
-
- // Add dependencies
-
- MonoDomain *prev_domain = mono_domain_get();
- MonoDomain *export_domain = GDMonoUtils::create_domain("GodotEngine.ProjectExportDomain");
+ String project_dll_src_dir = GodotSharpDirs::get_res_temp_assemblies_base_dir().plus_file(build_config);
+ String project_dll_src_path = project_dll_src_dir.plus_file(project_dll_name + ".dll");
+ dependencies.insert(project_dll_name, project_dll_src_path);
- ERR_FAIL_COND(!export_domain);
- ERR_FAIL_COND(!mono_domain_set(export_domain, false));
+ {
+ MonoDomain *export_domain = GDMonoUtils::create_domain("GodotEngine.ProjectExportDomain");
+ ERR_FAIL_NULL(export_domain);
+ _GDMONO_SCOPE_EXIT_DOMAIN_UNLOAD_(export_domain);
- Map<String, String> dependencies;
- dependencies.insert("mscorlib", GDMono::get_singleton()->get_corlib_assembly()->get_path());
-
- GDMonoAssembly *scripts_assembly = GDMonoAssembly::load_from(project_dll_name, project_dll_src_path, /* refonly: */ true);
+ _GDMONO_SCOPE_DOMAIN_(export_domain);
- ERR_EXPLAIN("Cannot load refonly assembly: " + project_dll_name);
- ERR_FAIL_COND(!scripts_assembly);
+ GDMonoAssembly *scripts_assembly = NULL;
+ bool load_success = GDMono::get_singleton()->load_assembly_from(project_dll_name,
+ project_dll_src_dir, &scripts_assembly, /* refonly: */ true);
- Error depend_error = _get_assembly_dependencies(scripts_assembly, dependencies);
+ ERR_EXPLAIN("Cannot load refonly assembly: " + project_dll_name);
+ ERR_FAIL_COND(!load_success);
- GDMono::get_singleton()->finalize_and_unload_domain(export_domain);
- mono_domain_set(prev_domain, false);
-
- ERR_FAIL_COND(depend_error != OK);
+ Vector<String> search_dirs;
+ GDMonoAssembly::fill_search_dirs(search_dirs);
+ Error depend_error = _get_assembly_dependencies(scripts_assembly, search_dirs, dependencies);
+ ERR_FAIL_COND(depend_error != OK);
+ }
for (Map<String, String>::Element *E = dependencies.front(); E; E = E->next()) {
String depend_src_path = E->value();
String depend_dst_path = GodotSharpDirs::get_res_assemblies_dir().plus_file(depend_src_path.get_file());
ERR_FAIL_COND(!_add_assembly(depend_src_path, depend_dst_path));
}
+
+ // Mono specific export template extras (data dir)
+
+ GDMonoClass *export_class = GDMono::get_singleton()->get_editor_tools_assembly()->get_class("GodotSharpTools.Editor", "GodotSharpExport");
+ ERR_FAIL_NULL(export_class);
+ GDMonoMethod *export_begin_method = export_class->get_method("_ExportBegin", 4);
+ ERR_FAIL_NULL(export_begin_method);
+
+ MonoArray *features = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(String), p_features.size());
+ int i = 0;
+ for (const Set<String>::Element *E = p_features.front(); E; E = E->next()) {
+ MonoString *boxed = GDMonoMarshal::mono_string_from_godot(E->get());
+ mono_array_set(features, MonoString *, i, boxed);
+ i++;
+ }
+
+ MonoBoolean debug = p_debug;
+ MonoString *path = GDMonoMarshal::mono_string_from_godot(p_path);
+ uint32_t flags = p_flags;
+ void *args[4] = { features, &debug, path, &flags };
+ MonoException *exc = NULL;
+ export_begin_method->invoke_raw(NULL, args, &exc);
+
+ if (exc) {
+ GDMonoUtils::debug_print_unhandled_exception(exc);
+ ERR_FAIL();
+ }
}
bool GodotSharpExport::_add_assembly(const String &p_src_path, const String &p_dst_path) {
@@ -125,7 +169,7 @@ bool GodotSharpExport::_add_assembly(const String &p_src_path, const String &p_d
return true;
}
-Error GodotSharpExport::_get_assembly_dependencies(GDMonoAssembly *p_assembly, Map<String, String> &r_dependencies) {
+Error GodotSharpExport::_get_assembly_dependencies(GDMonoAssembly *p_assembly, const Vector<String> &p_search_dirs, Map<String, String> &r_dependencies) {
MonoImage *image = p_assembly->get_image();
@@ -134,18 +178,48 @@ Error GodotSharpExport::_get_assembly_dependencies(GDMonoAssembly *p_assembly, M
mono_assembly_get_assemblyref(image, i, ref_aname);
String ref_name = mono_assembly_name_get_name(ref_aname);
- if (ref_name == "mscorlib" || r_dependencies.find(ref_name))
+ if (r_dependencies.find(ref_name))
continue;
GDMonoAssembly *ref_assembly = NULL;
- if (!GDMono::get_singleton()->load_assembly(ref_name, ref_aname, &ref_assembly, /* refonly: */ true)) {
- ERR_EXPLAIN("Cannot load refonly assembly: " + ref_name);
+ String path;
+ bool has_extension = ref_name.ends_with(".dll") || ref_name.ends_with(".exe");
+
+ for (int i = 0; i < p_search_dirs.size(); i++) {
+ const String &search_dir = p_search_dirs[i];
+
+ if (has_extension) {
+ path = search_dir.plus_file(ref_name);
+ if (FileAccess::exists(path)) {
+ GDMono::get_singleton()->load_assembly_from(ref_name.get_basename(), search_dir, ref_aname, &ref_assembly, true);
+ if (ref_assembly != NULL)
+ break;
+ }
+ } else {
+ path = search_dir.plus_file(ref_name + ".dll");
+ if (FileAccess::exists(path)) {
+ GDMono::get_singleton()->load_assembly_from(ref_name, search_dir, ref_aname, &ref_assembly, true);
+ if (ref_assembly != NULL)
+ break;
+ }
+
+ path = search_dir.plus_file(ref_name + ".exe");
+ if (FileAccess::exists(path)) {
+ GDMono::get_singleton()->load_assembly_from(ref_name, search_dir, ref_aname, &ref_assembly, true);
+ if (ref_assembly != NULL)
+ break;
+ }
+ }
+ }
+
+ if (!ref_assembly) {
+ ERR_EXPLAIN("Cannot load assembly (refonly): " + ref_name);
ERR_FAIL_V(ERR_CANT_RESOLVE);
}
r_dependencies.insert(ref_name, ref_assembly->get_path());
- Error err = _get_assembly_dependencies(ref_assembly, r_dependencies);
+ Error err = _get_assembly_dependencies(ref_assembly, p_search_dirs, r_dependencies);
if (err != OK)
return err;
}
diff --git a/modules/mono/editor/godotsharp_export.h b/modules/mono/editor/godotsharp_export.h
index b38db9660c..f007016578 100644
--- a/modules/mono/editor/godotsharp_export.h
+++ b/modules/mono/editor/godotsharp_export.h
@@ -43,13 +43,15 @@ class GodotSharpExport : public EditorExportPlugin {
bool _add_assembly(const String &p_src_path, const String &p_dst_path);
- Error _get_assembly_dependencies(GDMonoAssembly *p_assembly, Map<String, String> &r_dependencies);
+ Error _get_assembly_dependencies(GDMonoAssembly *p_assembly, const Vector<String> &p_search_dirs, Map<String, String> &r_dependencies);
protected:
virtual void _export_file(const String &p_path, const String &p_type, const Set<String> &p_features);
virtual void _export_begin(const Set<String> &p_features, bool p_debug, const String &p_path, int p_flags);
public:
+ static void register_internal_calls();
+
GodotSharpExport();
~GodotSharpExport();
};
diff --git a/modules/mono/editor/mono_bottom_panel.cpp b/modules/mono/editor/mono_bottom_panel.cpp
index ecc3e4c59e..0ac59a1be8 100644
--- a/modules/mono/editor/mono_bottom_panel.cpp
+++ b/modules/mono/editor/mono_bottom_panel.cpp
@@ -63,7 +63,7 @@ void MonoBottomPanel::_update_build_tabs_list() {
item_tooltip += "Running";
}
- if (!tab->build_exited || !tab->build_result == MonoBuildTab::RESULT_SUCCESS) {
+ if (!tab->build_exited || tab->build_result == MonoBuildTab::RESULT_ERROR) {
item_tooltip += "\nErrors: " + itos(tab->error_count);
}
@@ -475,14 +475,14 @@ void MonoBuildTab::_bind_methods() {
}
MonoBuildTab::MonoBuildTab(const MonoBuildInfo &p_build_info, const String &p_logs_dir) :
- build_info(p_build_info),
- logs_dir(p_logs_dir),
build_exited(false),
issues_list(memnew(ItemList)),
error_count(0),
warning_count(0),
errors_visible(true),
- warnings_visible(true) {
+ warnings_visible(true),
+ logs_dir(p_logs_dir),
+ build_info(p_build_info) {
issues_list->set_v_size_flags(SIZE_EXPAND_FILL);
issues_list->connect("item_activated", this, "_issue_activated");
add_child(issues_list);
diff --git a/modules/mono/glue/Managed/Files/Extensions/NodeExtensions.cs b/modules/mono/glue/Managed/Files/Extensions/NodeExtensions.cs
index 71534d7782..366d89b1c2 100644
--- a/modules/mono/glue/Managed/Files/Extensions/NodeExtensions.cs
+++ b/modules/mono/glue/Managed/Files/Extensions/NodeExtensions.cs
@@ -2,42 +2,42 @@ namespace Godot
{
public partial class Node
{
- public T GetNode<T>(NodePath path) where T : Godot.Node
+ public T GetNode<T>(NodePath path) where T : class
{
- return (T)GetNode(path);
+ return (T)(object)GetNode(path);
}
- public T GetNodeOrNull<T>(NodePath path) where T : Godot.Node
+ public T GetNodeOrNull<T>(NodePath path) where T : class
{
return GetNode(path) as T;
}
- public T GetChild<T>(int idx) where T : Godot.Node
+ public T GetChild<T>(int idx) where T : class
{
- return (T)GetChild(idx);
+ return (T)(object)GetChild(idx);
}
- public T GetChildOrNull<T>(int idx) where T : Godot.Node
+ public T GetChildOrNull<T>(int idx) where T : class
{
return GetChild(idx) as T;
}
- public T GetOwner<T>() where T : Godot.Node
+ public T GetOwner<T>() where T : class
{
- return (T)GetOwner();
+ return (T)(object)GetOwner();
}
- public T GetOwnerOrNull<T>() where T : Godot.Node
+ public T GetOwnerOrNull<T>() where T : class
{
return GetOwner() as T;
}
- public T GetParent<T>() where T : Godot.Node
+ public T GetParent<T>() where T : class
{
- return (T)GetParent();
+ return (T)(object)GetParent();
}
- public T GetParentOrNull<T>() where T : Godot.Node
+ public T GetParentOrNull<T>() where T : class
{
return GetParent() as T;
}
diff --git a/modules/mono/glue/Managed/Files/Extensions/ResourceLoaderExtensions.cs b/modules/mono/glue/Managed/Files/Extensions/ResourceLoaderExtensions.cs
index ceecc589e6..684d160b57 100644
--- a/modules/mono/glue/Managed/Files/Extensions/ResourceLoaderExtensions.cs
+++ b/modules/mono/glue/Managed/Files/Extensions/ResourceLoaderExtensions.cs
@@ -2,9 +2,9 @@ namespace Godot
{
public static partial class ResourceLoader
{
- public static T Load<T>(string path) where T : Godot.Resource
+ public static T Load<T>(string path) where T : class
{
- return (T) Load(path);
+ return (T)(object)Load(path);
}
}
}
diff --git a/modules/mono/glue/Managed/Files/GD.cs b/modules/mono/glue/Managed/Files/GD.cs
index 264be23588..e4818e186c 100644
--- a/modules/mono/glue/Managed/Files/GD.cs
+++ b/modules/mono/glue/Managed/Files/GD.cs
@@ -65,9 +65,9 @@ namespace Godot
return ResourceLoader.Load(path);
}
- public static T Load<T>(string path) where T : Godot.Resource
+ public static T Load<T>(string path) where T : class
{
- return (T) ResourceLoader.Load(path);
+ return ResourceLoader.Load<T>(path);
}
public static void Print(params object[] what)
diff --git a/modules/mono/glue/nodepath_glue.cpp b/modules/mono/glue/nodepath_glue.cpp
index 4b7648a4f9..422d73104d 100644
--- a/modules/mono/glue/nodepath_glue.cpp
+++ b/modules/mono/glue/nodepath_glue.cpp
@@ -40,7 +40,7 @@ NodePath *godot_icall_NodePath_Ctor(MonoString *p_path) {
void godot_icall_NodePath_Dtor(NodePath *p_ptr) {
ERR_FAIL_NULL(p_ptr);
- _GodotSharp::get_singleton()->queue_dispose(p_ptr);
+ memdelete(p_ptr);
}
MonoString *godot_icall_NodePath_operator_String(NodePath *p_np) {
diff --git a/modules/mono/glue/rid_glue.cpp b/modules/mono/glue/rid_glue.cpp
index 5d66b8aa6f..6c002b5b9d 100644
--- a/modules/mono/glue/rid_glue.cpp
+++ b/modules/mono/glue/rid_glue.cpp
@@ -45,7 +45,7 @@ RID *godot_icall_RID_Ctor(Object *p_from) {
void godot_icall_RID_Dtor(RID *p_ptr) {
ERR_FAIL_NULL(p_ptr);
- _GodotSharp::get_singleton()->queue_dispose(p_ptr);
+ memdelete(p_ptr);
}
uint32_t godot_icall_RID_get_id(RID *p_ptr) {
diff --git a/modules/mono/godotsharp_dirs.cpp b/modules/mono/godotsharp_dirs.cpp
index 2570e68f13..d3fb2cb640 100644
--- a/modules/mono/godotsharp_dirs.cpp
+++ b/modules/mono/godotsharp_dirs.cpp
@@ -30,11 +30,11 @@
#include "godotsharp_dirs.h"
+#include "core/os/dir_access.h"
#include "core/os/os.h"
+#include "core/project_settings.h"
#ifdef TOOLS_ENABLED
-#include "core/os/dir_access.h"
-#include "core/project_settings.h"
#include "core/version.h"
#include "editor/editor_settings.h"
#endif
@@ -95,10 +95,18 @@ public:
#ifdef TOOLS_ENABLED
String mono_solutions_dir;
String build_logs_dir;
+
String sln_filepath;
String csproj_filepath;
+
+ String data_mono_bin_dir;
+ String data_editor_tools_dir;
+ String data_editor_prebuilt_api_dir;
#endif
+ String data_mono_etc_dir;
+ String data_mono_lib_dir;
+
private:
_GodotSharpDirs() {
res_data_dir = "res://.mono";
@@ -123,10 +131,60 @@ private:
name = "UnnamedProject";
}
- String base_path = String("res://") + name;
+ String base_path = ProjectSettings::get_singleton()->globalize_path("res://");
+
+ sln_filepath = base_path.plus_file(name + ".sln");
+ csproj_filepath = base_path.plus_file(name + ".csproj");
+#endif
+
+ String exe_dir = OS::get_singleton()->get_executable_path().get_base_dir();
+
+#ifdef TOOLS_ENABLED
+
+ String data_dir_root = exe_dir.plus_file("GodotSharp");
+ data_editor_tools_dir = data_dir_root.plus_file("Tools");
+ data_editor_prebuilt_api_dir = data_dir_root.plus_file("Api");
+
+ String data_mono_root_dir = data_dir_root.plus_file("Mono");
+ data_mono_bin_dir = data_mono_root_dir.plus_file("bin");
+ data_mono_etc_dir = data_mono_root_dir.plus_file("etc");
+ data_mono_lib_dir = data_mono_root_dir.plus_file("lib");
+
+#ifdef OSX_ENABLED
+ if (!DirAccess::exists(data_editor_tools_dir)) {
+ data_editor_tools_dir = exe_dir.plus_file("../Frameworks/GodotSharp/Tools");
+ }
+
+ if (!DirAccess::exists(data_editor_prebuilt_api_dir)) {
+ data_editor_prebuilt_api_dir = exe_dir.plus_file("../Frameworks/GodotSharp/Api");
+ }
+
+ if (!DirAccess::exists(data_mono_root_dir)) {
+ data_mono_bin_dir = exe_dir.plus_file("../Frameworks/GodotSharp/Mono/bin");
+ data_mono_etc_dir = exe_dir.plus_file("../Resources/GodotSharp/Mono/etc");
+ data_mono_lib_dir = exe_dir.plus_file("../Frameworks/GodotSharp/Mono/lib");
+ }
+#endif
+
+#else
+
+ String appname = OS::get_singleton()->get_safe_dir_name(ProjectSettings::get_singleton()->get("application/config/name"));
+ String data_dir_root = exe_dir.plus_file("data_" + appname);
+ if (!DirAccess::exists(data_dir_root)) {
+ data_dir_root = exe_dir.plus_file("data_Godot");
+ }
+
+ String data_mono_root_dir = data_dir_root.plus_file("Mono");
+ data_mono_etc_dir = data_mono_root_dir.plus_file("etc");
+ data_mono_lib_dir = data_mono_root_dir.plus_file("lib");
+
+#ifdef OSX_ENABLED
+ if (!DirAccess::exists(data_mono_root_dir)) {
+ data_mono_etc_dir = exe_dir.plus_file("../Resources/GodotSharp/Mono/etc");
+ data_mono_lib_dir = exe_dir.plus_file("../Frameworks/GodotSharp/Mono/lib");
+ }
+#endif
- sln_filepath = ProjectSettings::get_singleton()->globalize_path(base_path + ".sln");
- csproj_filepath = ProjectSettings::get_singleton()->globalize_path(base_path + ".csproj");
#endif
}
@@ -192,5 +250,26 @@ String get_project_sln_path() {
String get_project_csproj_path() {
return _GodotSharpDirs::get_singleton().csproj_filepath;
}
+
+String get_data_mono_bin_dir() {
+ return _GodotSharpDirs::get_singleton().data_mono_bin_dir;
+}
+
+String get_data_editor_tools_dir() {
+ return _GodotSharpDirs::get_singleton().data_editor_tools_dir;
+}
+
+String get_data_editor_prebuilt_api_dir() {
+ return _GodotSharpDirs::get_singleton().data_editor_prebuilt_api_dir;
+}
#endif
+
+String get_data_mono_etc_dir() {
+ return _GodotSharpDirs::get_singleton().data_mono_etc_dir;
+}
+
+String get_data_mono_lib_dir() {
+ return _GodotSharpDirs::get_singleton().data_mono_lib_dir;
+}
+
} // namespace GodotSharpDirs
diff --git a/modules/mono/godotsharp_dirs.h b/modules/mono/godotsharp_dirs.h
index 3466cb271d..35b564be30 100644
--- a/modules/mono/godotsharp_dirs.h
+++ b/modules/mono/godotsharp_dirs.h
@@ -49,11 +49,18 @@ String get_mono_logs_dir();
#ifdef TOOLS_ENABLED
String get_mono_solutions_dir();
String get_build_logs_dir();
-String get_custom_project_settings_dir();
-#endif
String get_project_sln_path();
String get_project_csproj_path();
+
+String get_data_mono_bin_dir();
+String get_data_editor_tools_dir();
+String get_data_editor_prebuilt_api_dir();
+#endif
+
+String get_data_mono_etc_dir();
+String get_data_mono_lib_dir();
+
} // namespace GodotSharpDirs
#endif // GODOTSHARP_DIRS_H
diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp
index 9311aa3930..0c4433112d 100644
--- a/modules/mono/mono_gd/gd_mono.cpp
+++ b/modules/mono/mono_gd/gd_mono.cpp
@@ -162,50 +162,63 @@ void GDMono::initialize() {
mono_trace_set_printerr_handler(gdmono_MonoPrintCallback);
#endif
+ String assembly_rootdir;
+ String config_dir;
+
+#ifdef TOOLS_ENABLED
#ifdef WINDOWS_ENABLED
mono_reg_info = MonoRegUtils::find_mono();
- CharString assembly_dir;
- CharString config_dir;
-
if (mono_reg_info.assembly_dir.length() && DirAccess::exists(mono_reg_info.assembly_dir)) {
- assembly_dir = mono_reg_info.assembly_dir.utf8();
+ assembly_rootdir = mono_reg_info.assembly_dir;
}
if (mono_reg_info.config_dir.length() && DirAccess::exists(mono_reg_info.config_dir)) {
- config_dir = mono_reg_info.config_dir.utf8();
+ config_dir = mono_reg_info.config_dir;
}
-
- mono_set_dirs(assembly_dir.length() ? assembly_dir.get_data() : NULL,
- config_dir.length() ? config_dir.get_data() : NULL);
#elif OSX_ENABLED
- mono_set_dirs(NULL, NULL);
-
- {
- const char *assembly_rootdir = mono_assembly_getrootdir();
- const char *config_dir = mono_get_config_dir();
-
- if (!assembly_rootdir || !config_dir || !DirAccess::exists(assembly_rootdir) || !DirAccess::exists(config_dir)) {
- Vector<const char *> locations;
- locations.push_back("/Library/Frameworks/Mono.framework/Versions/Current/");
- locations.push_back("/usr/local/var/homebrew/linked/mono/");
-
- for (int i = 0; i < locations.size(); i++) {
- String hint_assembly_rootdir = path_join(locations[i], "lib");
- String hint_mscorlib_path = path_join(hint_assembly_rootdir, "mono", "4.5", "mscorlib.dll");
- String hint_config_dir = path_join(locations[i], "etc");
-
- if (FileAccess::exists(hint_mscorlib_path) && DirAccess::exists(hint_config_dir)) {
- mono_set_dirs(hint_assembly_rootdir.utf8().get_data(), hint_config_dir.utf8().get_data());
- break;
- }
+ const char *c_assembly_rootdir = mono_assembly_getrootdir();
+ const char *c_config_dir = mono_get_config_dir();
+
+ if (!c_assembly_rootdir || !c_config_dir || !DirAccess::exists(c_assembly_rootdir) || !DirAccess::exists(c_config_dir)) {
+ Vector<const char *> locations;
+ locations.push_back("/Library/Frameworks/Mono.framework/Versions/Current/");
+ locations.push_back("/usr/local/var/homebrew/linked/mono/");
+
+ for (int i = 0; i < locations.size(); i++) {
+ String hint_assembly_rootdir = path_join(locations[i], "lib");
+ String hint_mscorlib_path = path_join(hint_assembly_rootdir, "mono", "4.5", "mscorlib.dll");
+ String hint_config_dir = path_join(locations[i], "etc");
+
+ if (FileAccess::exists(hint_mscorlib_path) && DirAccess::exists(hint_config_dir)) {
+ need_set_mono_dirs = false;
+ assembly_rootdir = hint_assembly_rootdir;
+ config_dir = hint_config_dir;
+ break;
}
}
}
+#endif
+#endif // TOOLS_ENABLED
+
+ String bundled_assembly_rootdir = GodotSharpDirs::get_data_mono_lib_dir();
+ String bundled_config_dir = GodotSharpDirs::get_data_mono_etc_dir();
+
+#ifdef TOOLS_ENABLED
+ if (DirAccess::exists(bundled_assembly_rootdir) && DirAccess::exists(bundled_config_dir)) {
+ assembly_rootdir = bundled_assembly_rootdir;
+ config_dir = bundled_config_dir;
+ }
#else
- mono_set_dirs(NULL, NULL);
+ // These are always the directories in export templates
+ assembly_rootdir = bundled_assembly_rootdir;
+ config_dir = bundled_config_dir;
#endif
+ // Leak if we call mono_set_dirs more than once
+ mono_set_dirs(assembly_rootdir.length() ? assembly_rootdir.utf8().get_data() : NULL,
+ config_dir.length() ? config_dir.utf8().get_data() : NULL);
+
GDMonoAssembly::initialize();
#ifdef DEBUG_ENABLED
@@ -262,8 +275,11 @@ void GDMono::initialize() {
// Everything is fine with the api assemblies, load the project assembly
_load_project_assembly();
} else {
- if ((core_api_assembly && (core_api_assembly_out_of_sync || !GDMonoUtils::mono_cache.godot_api_cache_updated)) ||
- (editor_api_assembly && editor_api_assembly_out_of_sync)) {
+ if ((core_api_assembly && (core_api_assembly_out_of_sync || !GDMonoUtils::mono_cache.godot_api_cache_updated))
+#ifdef TOOLS_ENABLED
+ || (editor_api_assembly && editor_api_assembly_out_of_sync)
+#endif
+ ) {
#ifdef TOOLS_ENABLED
// The assembly was successfully loaded, but the full api could not be cached.
// This is most likely an outdated assembly loaded because of an invalid version in the
@@ -362,24 +378,34 @@ GDMonoAssembly **GDMono::get_loaded_assembly(const String &p_name) {
bool GDMono::load_assembly(const String &p_name, GDMonoAssembly **r_assembly, bool p_refonly) {
+ return load_assembly_from(p_name, String(), r_assembly, p_refonly);
+}
+
+bool GDMono::load_assembly(const String &p_name, MonoAssemblyName *p_aname, GDMonoAssembly **r_assembly, bool p_refonly) {
+
+ return load_assembly_from(p_name, String(), p_aname, r_assembly, p_refonly);
+}
+
+bool GDMono::load_assembly_from(const String &p_name, const String &p_basedir, GDMonoAssembly **r_assembly, bool p_refonly) {
+
CRASH_COND(!r_assembly);
MonoAssemblyName *aname = mono_assembly_name_new(p_name.utf8());
- bool result = load_assembly(p_name, aname, r_assembly, p_refonly);
+ bool result = load_assembly_from(p_name, p_basedir, aname, r_assembly, p_refonly);
mono_assembly_name_free(aname);
mono_free(aname);
return result;
}
-bool GDMono::load_assembly(const String &p_name, MonoAssemblyName *p_aname, GDMonoAssembly **r_assembly, bool p_refonly) {
+bool GDMono::load_assembly_from(const String &p_name, const String &p_basedir, MonoAssemblyName *p_aname, GDMonoAssembly **r_assembly, bool p_refonly) {
CRASH_COND(!r_assembly);
print_verbose("Mono: Loading assembly " + p_name + (p_refonly ? " (refonly)" : "") + "...");
MonoImageOpenStatus status = MONO_IMAGE_OK;
- MonoAssembly *assembly = mono_assembly_load_full(p_aname, NULL, &status, p_refonly);
+ MonoAssembly *assembly = mono_assembly_load_full(p_aname, p_basedir.length() ? p_basedir.utf8().get_data() : NULL, &status, p_refonly);
if (!assembly)
return false;
@@ -480,12 +506,10 @@ bool GDMono::_load_editor_api_assembly() {
if (editor_api_assembly)
return true;
-#ifdef TOOLS_ENABLED
if (metadata_is_api_assembly_invalidated(APIAssembly::API_EDITOR)) {
print_verbose("Mono: Skipping loading of Editor API assembly because it was invalidated");
return false;
}
-#endif
bool success = load_assembly(EDITOR_API_ASSEMBLY_NAME, &editor_api_assembly);
@@ -647,14 +671,18 @@ Error GDMono::_unload_scripts_domain() {
print_verbose("Mono: Unloading scripts domain...");
- _GodotSharp::get_singleton()->_dispose_callback();
-
if (mono_domain_get() != root_domain)
mono_domain_set(root_domain, true);
mono_gc_collect(mono_gc_max_generation());
- mono_domain_finalize(scripts_domain, 2000);
+ finalizing_scripts_domain = true;
+
+ if (!mono_domain_finalize(scripts_domain, 2000)) {
+ ERR_PRINT("Mono: Domain finalization timeout");
+ }
+
+ finalizing_scripts_domain = false;
mono_gc_collect(mono_gc_max_generation());
@@ -672,8 +700,6 @@ Error GDMono::_unload_scripts_domain() {
MonoDomain *domain = scripts_domain;
scripts_domain = NULL;
- _GodotSharp::get_singleton()->_dispose_callback();
-
MonoException *exc = NULL;
mono_domain_try_unload(domain, (MonoObject **)&exc);
@@ -772,11 +798,13 @@ Error GDMono::finalize_and_unload_domain(MonoDomain *p_domain) {
print_verbose("Mono: Unloading domain `" + domain_name + "`...");
- if (mono_domain_get() != root_domain)
+ if (mono_domain_get() == p_domain)
mono_domain_set(root_domain, true);
mono_gc_collect(mono_gc_max_generation());
- mono_domain_finalize(p_domain, 2000);
+ if (!mono_domain_finalize(p_domain, 2000)) {
+ ERR_PRINT("Mono: Domain finalization timeout");
+ }
mono_gc_collect(mono_gc_max_generation());
_domain_assemblies_cleanup(mono_domain_get_id(p_domain));
@@ -851,6 +879,7 @@ GDMono::GDMono() {
gdmono_log = memnew(GDMonoLog);
runtime_initialized = false;
+ finalizing_scripts_domain = false;
root_domain = NULL;
scripts_domain = NULL;
@@ -917,29 +946,6 @@ GDMono::~GDMono() {
_GodotSharp *_GodotSharp::singleton = NULL;
-void _GodotSharp::_dispose_callback() {
-
-#ifndef NO_THREADS
- queue_mutex->lock();
-#endif
-
- for (List<NodePath *>::Element *E = np_delete_queue.front(); E; E = E->next()) {
- memdelete(E->get());
- }
-
- for (List<RID *>::Element *E = rid_delete_queue.front(); E; E = E->next()) {
- memdelete(E->get());
- }
-
- np_delete_queue.clear();
- rid_delete_queue.clear();
- queue_empty = true;
-
-#ifndef NO_THREADS
- queue_mutex->unlock();
-#endif
-}
-
void _GodotSharp::attach_thread() {
GDMonoUtils::attach_current_thread();
@@ -988,6 +994,8 @@ bool _GodotSharp::is_domain_finalizing_for_unload(MonoDomain *p_domain) {
if (!p_domain)
return true;
+ if (p_domain == SCRIPTS_DOMAIN && GDMono::get_singleton()->is_finalizing_scripts_domain())
+ return true;
return mono_domain_is_unloading(p_domain);
}
@@ -1001,49 +1009,6 @@ bool _GodotSharp::is_runtime_initialized() {
return GDMono::get_singleton()->is_runtime_initialized();
}
-#define ENQUEUE_FOR_DISPOSAL(m_queue, m_inst) \
- m_queue.push_back(m_inst); \
- if (queue_empty) { \
- queue_empty = false; \
- if (!is_domain_finalizing_for_unload(SCRIPTS_DOMAIN)) { /* call_deferred may not be safe here */ \
- call_deferred("_dispose_callback"); \
- } \
- }
-
-void _GodotSharp::queue_dispose(NodePath *p_node_path) {
-
- if (GDMonoUtils::is_main_thread() && !is_domain_finalizing_for_unload(SCRIPTS_DOMAIN)) {
- memdelete(p_node_path);
- } else {
-#ifndef NO_THREADS
- queue_mutex->lock();
-#endif
-
- ENQUEUE_FOR_DISPOSAL(np_delete_queue, p_node_path);
-
-#ifndef NO_THREADS
- queue_mutex->unlock();
-#endif
- }
-}
-
-void _GodotSharp::queue_dispose(RID *p_rid) {
-
- if (GDMonoUtils::is_main_thread() && !is_domain_finalizing_for_unload(SCRIPTS_DOMAIN)) {
- memdelete(p_rid);
- } else {
-#ifndef NO_THREADS
- queue_mutex->lock();
-#endif
-
- ENQUEUE_FOR_DISPOSAL(rid_delete_queue, p_rid);
-
-#ifndef NO_THREADS
- queue_mutex->unlock();
-#endif
- }
-}
-
void _GodotSharp::_bind_methods() {
ClassDB::bind_method(D_METHOD("attach_thread"), &_GodotSharp::attach_thread);
@@ -1056,8 +1021,6 @@ void _GodotSharp::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_runtime_shutting_down"), &_GodotSharp::is_runtime_shutting_down);
ClassDB::bind_method(D_METHOD("is_runtime_initialized"), &_GodotSharp::is_runtime_initialized);
-
- ClassDB::bind_method(D_METHOD("_dispose_callback"), &_GodotSharp::_dispose_callback);
}
_GodotSharp::_GodotSharp() {
diff --git a/modules/mono/mono_gd/gd_mono.h b/modules/mono/mono_gd/gd_mono.h
index 0c5503d28e..745dcc34eb 100644
--- a/modules/mono/mono_gd/gd_mono.h
+++ b/modules/mono/mono_gd/gd_mono.h
@@ -142,7 +142,7 @@ class GDMono {
GDMonoLog *gdmono_log;
-#ifdef WINDOWS_ENABLED
+#if defined(WINDOWS_ENABLED) && defined(TOOLS_ENABLED)
MonoRegInfo mono_reg_info;
#endif
@@ -172,6 +172,8 @@ public:
_FORCE_INLINE_ bool is_runtime_initialized() const { return runtime_initialized && !mono_runtime_is_shutting_down() /* stays true after shutdown finished */; }
+ _FORCE_INLINE_ bool is_finalizing_scripts_domain() { return finalizing_scripts_domain; }
+
_FORCE_INLINE_ MonoDomain *get_scripts_domain() { return scripts_domain; }
#ifdef TOOLS_ENABLED
_FORCE_INLINE_ MonoDomain *get_tools_domain() { return tools_domain; }
@@ -185,7 +187,7 @@ public:
_FORCE_INLINE_ GDMonoAssembly *get_editor_tools_assembly() const { return editor_tools_assembly; }
#endif
-#ifdef WINDOWS_ENABLED
+#if defined(WINDOWS_ENABLED) && defined(TOOLS_ENABLED)
const MonoRegInfo &get_mono_reg_info() { return mono_reg_info; }
#endif
@@ -197,6 +199,9 @@ public:
bool load_assembly(const String &p_name, GDMonoAssembly **r_assembly, bool p_refonly = false);
bool load_assembly(const String &p_name, MonoAssemblyName *p_aname, GDMonoAssembly **r_assembly, bool p_refonly = false);
+ bool load_assembly_from(const String &p_name, const String &p_basedir, GDMonoAssembly **r_assembly, bool p_refonly = false);
+ bool load_assembly_from(const String &p_name, const String &p_basedir, MonoAssemblyName *p_aname, GDMonoAssembly **r_assembly, bool p_refonly = false);
+
Error finalize_and_unload_domain(MonoDomain *p_domain);
void initialize();
@@ -205,12 +210,14 @@ public:
~GDMono();
};
-class GDMonoScopeDomain {
+namespace gdmono {
+
+class ScopeDomain {
MonoDomain *prev_domain;
public:
- GDMonoScopeDomain(MonoDomain *p_domain) {
+ ScopeDomain(MonoDomain *p_domain) {
MonoDomain *prev_domain = mono_domain_get();
if (prev_domain != p_domain) {
this->prev_domain = prev_domain;
@@ -220,23 +227,41 @@ public:
}
}
- ~GDMonoScopeDomain() {
+ ~ScopeDomain() {
if (prev_domain)
mono_domain_set(prev_domain, false);
}
};
-#define _GDMONO_SCOPE_DOMAIN_(m_mono_domain) \
- GDMonoScopeDomain __gdmono__scope__domain__(m_mono_domain); \
+class ScopeExitDomainUnload {
+ MonoDomain *domain;
+
+public:
+ ScopeExitDomainUnload(MonoDomain *p_domain) :
+ domain(p_domain) {
+ }
+
+ ~ScopeExitDomainUnload() {
+ if (domain)
+ GDMono::get_singleton()->finalize_and_unload_domain(domain);
+ }
+};
+
+} // namespace gdmono
+
+#define _GDMONO_SCOPE_DOMAIN_(m_mono_domain) \
+ gdmono::ScopeDomain __gdmono__scope__domain__(m_mono_domain); \
(void)__gdmono__scope__domain__;
+#define _GDMONO_SCOPE_EXIT_DOMAIN_UNLOAD_(m_mono_domain) \
+ gdmono::ScopeExitDomainUnload __gdmono__scope__exit__domain__unload__(m_mono_domain); \
+ (void)__gdmono__scope__exit__domain__unload__;
+
class _GodotSharp : public Object {
GDCLASS(_GodotSharp, Object)
friend class GDMono;
- void _dispose_callback();
-
bool _is_domain_finalizing_for_unload(int32_t p_domain_id);
List<NodePath *> np_delete_queue;
@@ -270,9 +295,6 @@ public:
bool is_runtime_shutting_down();
bool is_runtime_initialized();
- void queue_dispose(NodePath *p_node_path);
- void queue_dispose(RID *p_rid);
-
_GodotSharp();
~_GodotSharp();
};
diff --git a/modules/mono/mono_gd/gd_mono_assembly.cpp b/modules/mono/mono_gd/gd_mono_assembly.cpp
index 27ce39b6d7..1067c11e0e 100644
--- a/modules/mono/mono_gd/gd_mono_assembly.cpp
+++ b/modules/mono/mono_gd/gd_mono_assembly.cpp
@@ -46,6 +46,29 @@ bool GDMonoAssembly::in_preload = false;
Vector<String> GDMonoAssembly::search_dirs;
+void GDMonoAssembly::fill_search_dirs(Vector<String> &r_search_dirs, const String &p_custom_config) {
+
+ const char *rootdir = mono_assembly_getrootdir();
+ if (rootdir) {
+ String framework_dir = String(rootdir).plus_file("mono").plus_file("4.5");
+ r_search_dirs.push_back(framework_dir);
+ r_search_dirs.push_back(framework_dir.plus_file("Facades"));
+ }
+
+ if (p_custom_config.length()) {
+ r_search_dirs.push_back(GodotSharpDirs::get_res_temp_assemblies_base_dir().plus_file(p_custom_config));
+ } else {
+ r_search_dirs.push_back(GodotSharpDirs::get_res_temp_assemblies_dir());
+ }
+
+ r_search_dirs.push_back(GodotSharpDirs::get_res_assemblies_dir());
+ r_search_dirs.push_back(OS::get_singleton()->get_resource_dir());
+ r_search_dirs.push_back(OS::get_singleton()->get_executable_path().get_base_dir());
+#ifdef TOOLS_ENABLED
+ r_search_dirs.push_back(GodotSharpDirs::get_data_editor_tools_dir());
+#endif
+}
+
void GDMonoAssembly::assembly_load_hook(MonoAssembly *assembly, void *user_data) {
if (no_search)
@@ -93,35 +116,7 @@ MonoAssembly *GDMonoAssembly::_search_hook(MonoAssemblyName *aname, void *user_d
no_search = true; // Avoid the recursion madness
- String path;
- GDMonoAssembly *res = NULL;
-
- for (int i = 0; i < search_dirs.size(); i++) {
- const String &search_dir = search_dirs[i];
-
- if (has_extension) {
- path = search_dir.plus_file(name);
- if (FileAccess::exists(path)) {
- res = _load_assembly_from(name.get_basename(), path, refonly);
- if (res != NULL)
- break;
- }
- } else {
- path = search_dir.plus_file(name + ".dll");
- if (FileAccess::exists(path)) {
- res = _load_assembly_from(name, path, refonly);
- if (res != NULL)
- break;
- }
-
- path = search_dir.plus_file(name + ".exe");
- if (FileAccess::exists(path)) {
- res = _load_assembly_from(name, path, refonly);
- if (res != NULL)
- break;
- }
- }
- }
+ GDMonoAssembly *res = _load_assembly_search(name, search_dirs, refonly);
no_search = false;
@@ -130,31 +125,12 @@ MonoAssembly *GDMonoAssembly::_search_hook(MonoAssemblyName *aname, void *user_d
static _THREAD_LOCAL_(MonoImage *) image_corlib_loading = NULL;
-MonoAssembly *GDMonoAssembly::_preload_hook(MonoAssemblyName *aname, char **assemblies_path, void *user_data, bool refonly) {
+MonoAssembly *GDMonoAssembly::_preload_hook(MonoAssemblyName *aname, char **, void *user_data, bool refonly) {
(void)user_data; // UNUSED
if (search_dirs.empty()) {
- search_dirs.push_back(GodotSharpDirs::get_res_temp_assemblies_dir());
- search_dirs.push_back(GodotSharpDirs::get_res_assemblies_dir());
- search_dirs.push_back(OS::get_singleton()->get_resource_dir());
- search_dirs.push_back(OS::get_singleton()->get_executable_path().get_base_dir());
-#ifdef GD_MONO_EDITOR_ASSEMBLIES_DIR
- search_dirs.push_back(OS::get_singleton()->get_executable_path().get_base_dir().plus_file(_MKSTR(GD_MONO_EDITOR_ASSEMBLIES_DIR)).simplify_path());
-#endif
-
- const char *rootdir = mono_assembly_getrootdir();
- if (rootdir) {
- search_dirs.push_back(String(rootdir).plus_file("mono").plus_file("4.5"));
- search_dirs.push_back(String(rootdir).plus_file("mono").plus_file("4.5").plus_file("Facades"));
- }
-
- if (assemblies_path) {
- while (*assemblies_path) {
- search_dirs.push_back(*assemblies_path);
- ++assemblies_path;
- }
- }
+ fill_search_dirs(search_dirs);
}
{
@@ -188,27 +164,7 @@ MonoAssembly *GDMonoAssembly::_preload_hook(MonoAssemblyName *aname, char **asse
if (stored_assembly)
return (*stored_assembly)->get_assembly();
- String path;
-
- for (int i = 0; i < search_dirs.size(); i++) {
- const String &search_dir = search_dirs[i];
-
- if (has_extension) {
- path = search_dir.plus_file(name);
- if (FileAccess::exists(path)) {
- res = _load_assembly_from(name.get_basename(), path, refonly);
- if (res != NULL)
- break;
- }
- } else {
- path = search_dir.plus_file(name + ".dll");
- if (FileAccess::exists(path)) {
- res = _load_assembly_from(name, path, refonly);
- if (res != NULL)
- break;
- }
- }
- }
+ res = _load_assembly_search("mscorlib.dll", search_dirs, refonly);
}
no_search = false;
@@ -217,6 +173,43 @@ MonoAssembly *GDMonoAssembly::_preload_hook(MonoAssemblyName *aname, char **asse
return res ? res->get_assembly() : NULL;
}
+GDMonoAssembly *GDMonoAssembly::_load_assembly_search(const String &p_name, const Vector<String> &p_search_dirs, bool p_refonly) {
+
+ GDMonoAssembly *res = NULL;
+ String path;
+
+ bool has_extension = p_name.ends_with(".dll") || p_name.ends_with(".exe");
+
+ for (int i = 0; i < p_search_dirs.size(); i++) {
+ const String &search_dir = p_search_dirs[i];
+
+ if (has_extension) {
+ path = search_dir.plus_file(p_name);
+ if (FileAccess::exists(path)) {
+ res = _load_assembly_from(p_name.get_basename(), path, p_refonly);
+ if (res != NULL)
+ return res;
+ }
+ } else {
+ path = search_dir.plus_file(p_name + ".dll");
+ if (FileAccess::exists(path)) {
+ res = _load_assembly_from(p_name, path, p_refonly);
+ if (res != NULL)
+ return res;
+ }
+
+ path = search_dir.plus_file(p_name + ".exe");
+ if (FileAccess::exists(path)) {
+ res = _load_assembly_from(p_name, path, p_refonly);
+ if (res != NULL)
+ return res;
+ }
+ }
+ }
+
+ return NULL;
+}
+
GDMonoAssembly *GDMonoAssembly::_load_assembly_from(const String &p_name, const String &p_path, bool p_refonly) {
GDMonoAssembly *assembly = memnew(GDMonoAssembly(p_name, p_path));
@@ -464,19 +457,6 @@ GDMonoClass *GDMonoAssembly::get_object_derived_class(const StringName &p_class)
return match;
}
-GDMonoAssembly *GDMonoAssembly::load_from(const String &p_name, const String &p_path, bool p_refonly) {
-
- GDMonoAssembly **loaded_asm = GDMono::get_singleton()->get_loaded_assembly(p_name);
- if (loaded_asm)
- return *loaded_asm;
-
- no_search = true;
- GDMonoAssembly *res = _load_assembly_from(p_name, p_path, p_refonly);
- no_search = false;
-
- return res;
-}
-
GDMonoAssembly::GDMonoAssembly(const String &p_name, const String &p_path) {
loaded = false;
diff --git a/modules/mono/mono_gd/gd_mono_assembly.h b/modules/mono/mono_gd/gd_mono_assembly.h
index 0ba11ac412..4c9b1cb10d 100644
--- a/modules/mono/mono_gd/gd_mono_assembly.h
+++ b/modules/mono/mono_gd/gd_mono_assembly.h
@@ -102,6 +102,7 @@ class GDMonoAssembly {
static MonoAssembly *_preload_hook(MonoAssemblyName *aname, char **assemblies_path, void *user_data, bool refonly);
static GDMonoAssembly *_load_assembly_from(const String &p_name, const String &p_path, bool p_refonly);
+ static GDMonoAssembly *_load_assembly_search(const String &p_name, const Vector<String> &p_search_dirs, bool p_refonly);
static void _wrap_mono_assembly(MonoAssembly *assembly);
friend class GDMono;
@@ -125,7 +126,7 @@ public:
GDMonoClass *get_object_derived_class(const StringName &p_class);
- static GDMonoAssembly *load_from(const String &p_name, const String &p_path, bool p_refonly);
+ static void fill_search_dirs(Vector<String> &r_search_dirs, const String &p_custom_config = String());
GDMonoAssembly(const String &p_name, const String &p_path = String());
~GDMonoAssembly();
diff --git a/modules/mono/utils/mono_reg_utils.cpp b/modules/mono/utils/mono_reg_utils.cpp
index 8116df5f51..6bb6efa92a 100644
--- a/modules/mono/utils/mono_reg_utils.cpp
+++ b/modules/mono/utils/mono_reg_utils.cpp
@@ -228,4 +228,4 @@ cleanup:
}
} // namespace MonoRegUtils
-#endif WINDOWS_ENABLED
+#endif // WINDOWS_ENABLED
diff --git a/modules/mono/utils/thread_local.h b/modules/mono/utils/thread_local.h
index 84dae1d86b..d7d98c47e2 100644
--- a/modules/mono/utils/thread_local.h
+++ b/modules/mono/utils/thread_local.h
@@ -108,17 +108,23 @@ class ThreadLocal {
return data;
}
+ void _initialize(const T &p_init_val) {
+ init_val = p_init_val;
+ storage.alloc(&destr_callback);
+ }
+
public:
- ThreadLocal() :
- ThreadLocal(T()) {}
+ ThreadLocal() {
+ _initialize(T());
+ }
- ThreadLocal(const T &p_init_val) :
- init_val(p_init_val) {
- storage.alloc(&destr_callback);
+ ThreadLocal(const T &p_init_val) {
+ _initialize(p_init_val);
}
- ThreadLocal(const ThreadLocal &other) :
- ThreadLocal(*other._tls_get_value()) {}
+ ThreadLocal(const ThreadLocal &other) {
+ _initialize(*other._tls_get_value());
+ }
~ThreadLocal() {
storage.free();
diff --git a/modules/opensimplex/config.py b/modules/opensimplex/config.py
index c91c9e5c80..c1010ad433 100644
--- a/modules/opensimplex/config.py
+++ b/modules/opensimplex/config.py
@@ -7,7 +7,7 @@ def configure(env):
def get_doc_classes():
return [
"NoiseTexture",
- "SimplexNoise"
+ "OpenSimplexNoise"
]
def get_doc_path():
diff --git a/modules/opensimplex/doc_classes/NoiseTexture.xml b/modules/opensimplex/doc_classes/NoiseTexture.xml
index 6af58e7a6b..9642865c43 100644
--- a/modules/opensimplex/doc_classes/NoiseTexture.xml
+++ b/modules/opensimplex/doc_classes/NoiseTexture.xml
@@ -41,8 +41,11 @@
<member name="seamless" type="bool" setter="set_seamless" getter="get_seamless">
Whether the texture can be tiled without visible seams or not. Seamless textures take longer to generate.
</member>
- <member name="size" type="Vector2" setter="set_size" getter="get_size">
- Size of the generated texture.
+ <member name="width" type="int" setter="set_width" getter="get_width">
+ Width of the generated texture.
+ </member>
+ <member name="height" type="int" setter="set_height" getter="get_height">
+ Height of the generated texture.
</member>
</members>
<constants>
diff --git a/modules/opensimplex/noise_texture.cpp b/modules/opensimplex/noise_texture.cpp
index 6f2723e43b..be522a9ab1 100644
--- a/modules/opensimplex/noise_texture.cpp
+++ b/modules/opensimplex/noise_texture.cpp
@@ -58,7 +58,6 @@ void NoiseTexture::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_width", "width"), &NoiseTexture::set_width);
ClassDB::bind_method(D_METHOD("set_height", "height"), &NoiseTexture::set_height);
- ClassDB::bind_method(D_METHOD("set_size", "size"), &NoiseTexture::set_size);
ClassDB::bind_method(D_METHOD("set_noise", "noise"), &NoiseTexture::set_noise);
ClassDB::bind_method(D_METHOD("get_noise"), &NoiseTexture::get_noise);
@@ -73,7 +72,8 @@ void NoiseTexture::_bind_methods() {
ClassDB::bind_method(D_METHOD("_generate_texture"), &NoiseTexture::_generate_texture);
ClassDB::bind_method(D_METHOD("_thread_done", "image"), &NoiseTexture::_thread_done);
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "size"), "set_size", "get_size");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "width", PROPERTY_HINT_RANGE, "1,2048,1,or_greater"), "set_width", "get_width");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "height", PROPERTY_HINT_RANGE, "1,2048,1,or_greater"), "set_height", "get_height");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "seamless"), "set_seamless", "get_seamless");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "as_normalmap"), "set_as_normalmap", "is_normalmap");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "noise", PROPERTY_HINT_RESOURCE_TYPE, "OpenSimplexNoise"), "set_noise", "get_noise");
@@ -208,17 +208,6 @@ bool NoiseTexture::is_normalmap() {
return as_normalmap;
}
-void NoiseTexture::set_size(Vector2 p_size) {
- if (p_size == size) return;
- size = p_size;
- _queue_update();
-}
-
-Vector2 NoiseTexture::get_size() {
-
- return size;
-}
-
int NoiseTexture::get_width() const {
return size.x;
diff --git a/modules/opensimplex/noise_texture.h b/modules/opensimplex/noise_texture.h
index 78a02cda9f..2a4c32d633 100644
--- a/modules/opensimplex/noise_texture.h
+++ b/modules/opensimplex/noise_texture.h
@@ -83,9 +83,6 @@ public:
void set_as_normalmap(bool p_seamless);
bool is_normalmap();
- void set_size(Vector2 p_size);
- Vector2 get_size();
-
int get_width() const;
int get_height() const;
diff --git a/modules/thekla_unwrap/config.py b/modules/thekla_unwrap/config.py
index bd092bdc16..fad6095064 100644
--- a/modules/thekla_unwrap/config.py
+++ b/modules/thekla_unwrap/config.py
@@ -1,5 +1,6 @@
def can_build(env, platform):
- return (env['tools'] and platform not in ["android", "ios"])
+ #return (env['tools'] and platform not in ["android", "ios"])
+ return False
def configure(env):
pass
diff --git a/modules/theora/video_stream_theora.cpp b/modules/theora/video_stream_theora.cpp
index d72d74cf79..2a6bb0783b 100644
--- a/modules/theora/video_stream_theora.cpp
+++ b/modules/theora/video_stream_theora.cpp
@@ -730,7 +730,6 @@ RES ResourceFormatLoaderTheora::load(const String &p_path, const String &p_origi
if (r_error) {
*r_error = ERR_CANT_OPEN;
}
- memdelete(f);
return RES();
}
diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp
index 79f71535ad..25cd4ab54e 100644
--- a/modules/visual_script/visual_script_editor.cpp
+++ b/modules/visual_script/visual_script_editor.cpp
@@ -2639,7 +2639,7 @@ void VisualScriptEditor::_selected_connect_node(const String &p_text, const Stri
}
undo_redo->create_action(TTR("Add Node"));
undo_redo->add_do_method(script.ptr(), "add_node", edited_func, new_id, vnode_new, ofs);
- if (vnode_old.is_valid() && p_connecting == true) {
+ if (vnode_old.is_valid() && p_connecting) {
connect_seq(vnode_old, vnode_new, new_id);
connect_data(vnode_old, vnode_new, new_id);
}
@@ -2806,7 +2806,7 @@ void VisualScriptEditor::_selected_connect_node(const String &p_text, const Stri
}
}
Ref<VisualScriptNode> vnode_old = script->get_node(edited_func, port_action_node);
- if (vnode_old.is_valid() && p_connecting == true) {
+ if (vnode_old.is_valid() && p_connecting) {
connect_seq(vnode_old, vnode, port_action_new_node);
connect_data(vnode_old, vnode, port_action_new_node);
}
@@ -2816,7 +2816,7 @@ void VisualScriptEditor::_selected_connect_node(const String &p_text, const Stri
void VisualScriptEditor::connect_seq(Ref<VisualScriptNode> vnode_old, Ref<VisualScriptNode> vnode_new, int new_id) {
VisualScriptOperator *vnode_operator = Object::cast_to<VisualScriptOperator>(vnode_new.ptr());
- if (vnode_operator != NULL && vnode_operator->has_input_sequence_port() == false) {
+ if (vnode_operator != NULL && !vnode_operator->has_input_sequence_port()) {
return;
}
VisualScriptConstructor *vnode_constructor = Object::cast_to<VisualScriptConstructor>(vnode_new.ptr());
@@ -2826,7 +2826,7 @@ void VisualScriptEditor::connect_seq(Ref<VisualScriptNode> vnode_old, Ref<Visual
if (vnode_old->get_output_sequence_port_count() <= 0) {
return;
}
- if (vnode_new->has_input_sequence_port() == false) {
+ if (!vnode_new->has_input_sequence_port()) {
return;
}
diff --git a/modules/visual_script/visual_script_nodes.cpp b/modules/visual_script/visual_script_nodes.cpp
index 5c880f48d1..865f93a148 100644
--- a/modules/visual_script/visual_script_nodes.cpp
+++ b/modules/visual_script/visual_script_nodes.cpp
@@ -853,7 +853,7 @@ public:
virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Variant::CallError &r_error, String &r_error_str) {
- if (instance->get_variable(variable, p_outputs[0]) == false) {
+ if (!instance->get_variable(variable, p_outputs[0])) {
r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
r_error_str = RTR("VariableGet not found in script: ") + "'" + String(variable) + "'";
return false;
@@ -975,7 +975,7 @@ public:
virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Variant::CallError &r_error, String &r_error_str) {
- if (instance->set_variable(variable, *p_inputs[0]) == false) {
+ if (!instance->set_variable(variable, *p_inputs[0])) {
r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
r_error_str = RTR("VariableSet not found in script: ") + "'" + String(variable) + "'";
diff --git a/modules/visual_script/visual_script_property_selector.cpp b/modules/visual_script/visual_script_property_selector.cpp
index cd29df9855..d3637939c9 100644
--- a/modules/visual_script/visual_script_property_selector.cpp
+++ b/modules/visual_script/visual_script_property_selector.cpp
@@ -149,7 +149,7 @@ void VisualScriptPropertySelector::_update_search() {
Control::get_icon("PoolColorArray", "EditorIcons")
};
- if (!seq_connect && visual_script_generic == false) {
+ if (!seq_connect && !visual_script_generic) {
get_visual_node_names("flow_control/type_cast", Set<String>(), found, root, search_box);
get_visual_node_names("functions/built_in/print", Set<String>(), found, root, search_box);
get_visual_node_names("functions/by_type/" + Variant::get_type_name(type), Set<String>(), found, root, search_box);
@@ -228,7 +228,7 @@ void VisualScriptPropertySelector::_update_search() {
}
}
- if (seq_connect == true && visual_script_generic == false) {
+ if (seq_connect && !visual_script_generic) {
String text = search_box->get_text();
create_visualscript_item(String("VisualScriptCondition"), root, text, String("Condition"));
create_visualscript_item(String("VisualScriptSwitch"), root, text, String("Switch"));
@@ -392,7 +392,7 @@ void VisualScriptPropertySelector::get_visual_node_names(const String &root_filt
break;
}
}
- if (is_filter == true) {
+ if (is_filter) {
continue;
}
diff --git a/modules/webm/video_stream_webm.cpp b/modules/webm/video_stream_webm.cpp
index d9a6ece085..675fc97b55 100644
--- a/modules/webm/video_stream_webm.cpp
+++ b/modules/webm/video_stream_webm.cpp
@@ -453,7 +453,6 @@ RES ResourceFormatLoaderWebm::load(const String &p_path, const String &p_origina
if (r_error) {
*r_error = ERR_CANT_OPEN;
}
- memdelete(f);
return RES();
}
diff --git a/modules/xatlas_unwrap/config.py b/modules/xatlas_unwrap/config.py
index 962d33280f..2dda5db7e0 100644
--- a/modules/xatlas_unwrap/config.py
+++ b/modules/xatlas_unwrap/config.py
@@ -1,6 +1,6 @@
def can_build(env, platform):
- return False #xatlas is buggy
- #return (env['tools'] and platform not in ["android", "ios"])
+ #return False #xatlas is buggy
+ return (env['tools'] and platform not in ["android", "ios"])
def configure(env):
pass
diff --git a/modules/xatlas_unwrap/register_types.cpp b/modules/xatlas_unwrap/register_types.cpp
index 9df16aac70..57eea4eda6 100644
--- a/modules/xatlas_unwrap/register_types.cpp
+++ b/modules/xatlas_unwrap/register_types.cpp
@@ -75,8 +75,9 @@ bool xatlas_mesh_lightmap_unwrap_callback(float p_texel_size, const float *p_ver
xatlas::CharterOptions chart_options;
xatlas::PackerOptions pack_options;
+ pack_options.method = xatlas::PackMethod::TexelArea;
pack_options.texelArea = 1.0 / p_texel_size;
- pack_options.quality = 4;
+ pack_options.quality = 3;
xatlas::Atlas *atlas = xatlas::Create();
printf("adding mesh..\n");
@@ -93,7 +94,10 @@ bool xatlas_mesh_lightmap_unwrap_callback(float p_texel_size, const float *p_ver
float w = *r_size_hint_x;
float h = *r_size_hint_y;
- printf("final texsize: %f,%f\n", w, h);
+ if (w == 0 || h == 0) {
+ return false; //could not bake
+ }
+
const xatlas::OutputMesh *const *output_meshes = xatlas::GetOutputMeshes(atlas);
const xatlas::OutputMesh *output = output_meshes[0];
@@ -102,11 +106,17 @@ bool xatlas_mesh_lightmap_unwrap_callback(float p_texel_size, const float *p_ver
*r_uv = (float *)malloc(sizeof(float) * output->vertexCount * 2);
*r_index = (int *)malloc(sizeof(int) * output->indexCount);
+ float max_x = 0;
+ float max_y = 0;
for (int i = 0; i < output->vertexCount; i++) {
(*r_vertex)[i] = output->vertexArray[i].xref;
- (*r_uv)[i * 2 + 0] = output->vertexArray[i].uv[0];
- (*r_uv)[i * 2 + 1] = output->vertexArray[i].uv[1];
+ (*r_uv)[i * 2 + 0] = output->vertexArray[i].uv[0] / w;
+ (*r_uv)[i * 2 + 1] = output->vertexArray[i].uv[1] / h;
+ max_x = MAX(max_x, output->vertexArray[i].uv[0]);
+ max_y = MAX(max_y, output->vertexArray[i].uv[1]);
}
+
+ printf("final texsize: %f,%f - max %f,%f\n", w, h, max_x, max_y);
*r_vertex_count = output->vertexCount;
for (int i = 0; i < output->indexCount; i++) {
diff --git a/platform/android/SCsub b/platform/android/SCsub
index 807506000f..da2219b9e4 100644
--- a/platform/android/SCsub
+++ b/platform/android/SCsub
@@ -18,14 +18,17 @@ android_files = [
'dir_access_jandroid.cpp',
'thread_jandroid.cpp',
'audio_driver_jandroid.cpp',
- 'ifaddrs_android.cpp',
- 'android_native_app_glue.c',
'java_glue.cpp',
- 'cpu-features.c',
'java_class_wrapper.cpp',
# 'power_android.cpp'
]
+thirdparty_files = [
+ 'ifaddrs_android.cpp',
+ 'android_native_app_glue.c',
+ 'cpu-features.c',
+]
+
env_android = env.Clone()
if env['target'] == "profile":
env_android.Append(CPPFLAGS=['-DPROFILER_ENABLED'])
@@ -34,6 +37,11 @@ android_objects = []
for x in android_files:
android_objects.append(env_android.SharedObject(x))
+env_thirdparty = env_android.Clone()
+env_thirdparty.disable_warnings()
+for x in thirdparty_files:
+ android_objects.append(env_thirdparty.SharedObject(x))
+
prog = None
abspath = env.Dir(".").abspath
diff --git a/platform/android/audio_driver_opensl.cpp b/platform/android/audio_driver_opensl.cpp
index 28e3ea962f..21c61f6ca0 100644
--- a/platform/android/audio_driver_opensl.cpp
+++ b/platform/android/audio_driver_opensl.cpp
@@ -38,12 +38,7 @@
/* Structure for passing information to callback function */
void AudioDriverOpenSL::_buffer_callback(
- SLAndroidSimpleBufferQueueItf queueItf
- /* SLuint32 eventFlags,
- const void * pBuffer,
- SLuint32 bufferSize,
- SLuint32 dataUsed*/
-) {
+ SLAndroidSimpleBufferQueueItf queueItf) {
bool mix = true;
@@ -85,7 +80,6 @@ void AudioDriverOpenSL::_buffer_callbacks(
AudioDriverOpenSL *ad = (AudioDriverOpenSL *)pContext;
- //ad->_buffer_callback(queueItf,eventFlags,pBuffer,bufferSize,dataUsed);
ad->_buffer_callback(queueItf);
}
@@ -98,12 +92,9 @@ const char *AudioDriverOpenSL::get_name() const {
Error AudioDriverOpenSL::init() {
- SLresult
- res;
+ SLresult res;
SLEngineOption EngineOption[] = {
- (SLuint32)SL_ENGINEOPTION_THREADSAFE,
- (SLuint32)SL_BOOLEAN_TRUE
-
+ { (SLuint32)SL_ENGINEOPTION_THREADSAFE, (SLuint32)SL_BOOLEAN_TRUE }
};
res = slCreateEngine(&sl, 1, EngineOption, 0, NULL, NULL);
if (res != SL_RESULT_SUCCESS) {
@@ -126,8 +117,6 @@ void AudioDriverOpenSL::start() {
mutex = Mutex::create();
active = false;
- SLint32 numOutputs = 0;
- SLuint32 deviceID = 0;
SLresult res;
buffer_size = 1024;
diff --git a/platform/android/audio_driver_opensl.h b/platform/android/audio_driver_opensl.h
index 8e879b27c5..39e1315a02 100644
--- a/platform/android/audio_driver_opensl.h
+++ b/platform/android/audio_driver_opensl.h
@@ -70,19 +70,10 @@ class AudioDriverOpenSL : public AudioDriver {
static AudioDriverOpenSL *s_ad;
void _buffer_callback(
- SLAndroidSimpleBufferQueueItf queueItf
- /* SLuint32 eventFlags,
- const void * pBuffer,
- SLuint32 bufferSize,
- SLuint32 dataUsed*/
- );
+ SLAndroidSimpleBufferQueueItf queueItf);
static void _buffer_callbacks(
SLAndroidSimpleBufferQueueItf queueItf,
- /*SLuint32 eventFlags,
- const void * pBuffer,
- SLuint32 bufferSize,
- SLuint32 dataUsed,*/
void *pContext);
public:
diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp
index 021a92ca1e..3b503e2657 100644
--- a/platform/android/export/export.cpp
+++ b/platform/android/export/export.cpp
@@ -1085,6 +1085,7 @@ public:
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "screen/support_normal"), true));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "screen/support_large"), true));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "screen/support_xlarge"), true));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "screen/opengl_debug"), false));
for (unsigned int i = 0; i < sizeof(launcher_icons) / sizeof(launcher_icons[0]); ++i) {
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, launcher_icons[i].option_id, PROPERTY_HINT_FILE, "*.png"), ""));
@@ -1438,6 +1439,7 @@ public:
bool use_32_fb = p_preset->get("graphics/32_bits_framebuffer");
bool immersive = p_preset->get("screen/immersive_mode");
+ bool debug_opengl = p_preset->get("screen/opengl_debug");
bool _signed = p_preset->get("package/signed");
@@ -1639,6 +1641,9 @@ public:
if (immersive)
cl.push_back("--use_immersive");
+ if (debug_opengl)
+ cl.push_back("--debug_opengl");
+
if (cl.size()) {
//add comandline
Vector<uint8_t> clf;
diff --git a/platform/android/godot_android.cpp b/platform/android/godot_android.cpp
index 54692dc831..c46c6f7804 100644
--- a/platform/android/godot_android.cpp
+++ b/platform/android/godot_android.cpp
@@ -408,7 +408,7 @@ static void engine_draw_frame(struct engine *engine) {
// Just fill the screen with a color.
//glClearColor(0,1,0,1);
//glClear(GL_COLOR_BUFFER_BIT);
- if (engine->os && engine->os->main_loop_iterate() == true) {
+ if (engine->os && engine->os->main_loop_iterate()) {
engine->requested_quit = true;
return; //should exit instead
diff --git a/platform/android/java/src/org/godotengine/godot/Godot.java b/platform/android/java/src/org/godotengine/godot/Godot.java
index c23037f3e0..ab37f7a02c 100644
--- a/platform/android/java/src/org/godotengine/godot/Godot.java
+++ b/platform/android/java/src/org/godotengine/godot/Godot.java
@@ -116,6 +116,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
private boolean use_32_bits = false;
private boolean use_immersive = false;
+ private boolean use_debug_opengl = false;
private boolean mStatePaused;
private int mState;
private boolean keep_screen_on = true;
@@ -278,7 +279,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
// ...add to FrameLayout
layout.addView(edittext);
- mView = new GodotView(getApplication(), io, use_gl3, use_32_bits, this);
+ mView = new GodotView(getApplication(), io, use_gl3, use_32_bits, use_debug_opengl,this);
layout.addView(mView, new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
edittext.setView(mView);
io.setEdit(edittext);
@@ -471,6 +472,8 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
boolean has_extra = i < command_line.length - 1;
if (command_line[i].equals("--use_depth_32")) {
use_32_bits = true;
+ } else if (command_line[i].equals("--debug_opengl")) {
+ use_debug_opengl = true;
} else if (command_line[i].equals("--use_immersive")) {
use_immersive = true;
if (Build.VERSION.SDK_INT >= 19.0) { // check if the application runs on an android 4.4+
diff --git a/platform/android/java/src/org/godotengine/godot/GodotView.java b/platform/android/java/src/org/godotengine/godot/GodotView.java
index 23723c2696..181ffc3b4b 100644
--- a/platform/android/java/src/org/godotengine/godot/GodotView.java
+++ b/platform/android/java/src/org/godotengine/godot/GodotView.java
@@ -81,16 +81,18 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener {
private static boolean firsttime = true;
private static boolean use_gl3 = false;
private static boolean use_32 = false;
+ private static boolean use_debug_opengl = false;
private Godot activity;
private InputManagerCompat mInputManager;
- public GodotView(Context context, GodotIO p_io, boolean p_use_gl3, boolean p_use_32_bits, Godot p_activity) {
+ public GodotView(Context context, GodotIO p_io, boolean p_use_gl3, boolean p_use_32_bits, boolean p_use_debug_opengl,Godot p_activity) {
super(context);
ctx = context;
io = p_io;
use_gl3 = p_use_gl3;
use_32 = p_use_32_bits;
+ use_debug_opengl = p_use_debug_opengl;
activity = p_activity;
@@ -406,6 +408,9 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener {
setRenderer(new Renderer());
}
+ private static final int _EGL_CONTEXT_FLAGS_KHR = 0x30FC;
+ private static final int _EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR= 0x00000001;
+
private static class ContextFactory implements GLSurfaceView.EGLContextFactory {
private static int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig eglConfig) {
@@ -415,9 +420,16 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener {
Log.w(TAG, "creating OpenGL ES 2.0 context :");
checkEglError("Before eglCreateContext", egl);
- int[] attrib_list2 = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE };
- int[] attrib_list3 = { EGL_CONTEXT_CLIENT_VERSION, 3, EGL10.EGL_NONE };
- EGLContext context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, use_gl3 ? attrib_list3 : attrib_list2);
+ EGLContext context;
+ if (use_debug_opengl) {
+ int[] attrib_list2 = { EGL_CONTEXT_CLIENT_VERSION, 2,_EGL_CONTEXT_FLAGS_KHR,_EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR, EGL10.EGL_NONE };
+ int[] attrib_list3 = { EGL_CONTEXT_CLIENT_VERSION, 3,_EGL_CONTEXT_FLAGS_KHR,_EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR, EGL10.EGL_NONE };
+ context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, use_gl3 ? attrib_list3 : attrib_list2);
+ } else {
+ int[] attrib_list2 = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE };
+ int[] attrib_list3 = { EGL_CONTEXT_CLIENT_VERSION, 3, EGL10.EGL_NONE };
+ context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, use_gl3 ? attrib_list3 : attrib_list2);
+ }
checkEglError("After eglCreateContext", egl);
return context;
}
diff --git a/platform/android/java_glue.cpp b/platform/android/java_glue.cpp
index 6cf49758bc..ad8f21785d 100644
--- a/platform/android/java_glue.cpp
+++ b/platform/android/java_glue.cpp
@@ -589,8 +589,6 @@ TST tst;
static bool initialized = false;
static int step = 0;
-static bool resized = false;
-static bool resized_reload = false;
static Size2 new_size;
static Vector3 accelerometer;
static Vector3 gravity;
@@ -792,7 +790,6 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *en
_getClipboard = env->GetMethodID(cls, "getClipboard", "()Ljava/lang/String;");
_setClipboard = env->GetMethodID(cls, "setClipboard", "(Ljava/lang/String;)V");
- jclass clsio = env->FindClass("org/godotengine/godot/Godot");
if (cls) {
jclass c = env->GetObjectClass(gob);
_openURI = env->GetMethodID(c, "openURI", "(Ljava/lang/String;)I");
@@ -886,8 +883,6 @@ static void _initialize_java_modules() {
ERR_EXPLAIN("Couldn't find proper initialize function 'public static Godot.SingletonBase Class::initialize(Activity p_activity)' initializer for singleton class: " + m);
ERR_CONTINUE(!initialize);
}
- jobject obj = env->CallStaticObjectMethod(singletonClass, initialize, _godot_instance);
- jobject gob = env->NewGlobalRef(obj);
}
}
}
@@ -931,13 +926,6 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_resize(JNIEnv *env, j
if (os_android)
os_android->set_display_size(Size2(width, height));
-
- /*input_mutex->lock();
- resized=true;
- if (reload)
- resized_reload=true;
- new_size=Size2(width,height);
- input_mutex->unlock();*/
}
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_newcontext(JNIEnv *env, jobject obj, bool p_32_bits) {
@@ -986,7 +974,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, job
os_android->process_gyroscope(gyroscope);
- if (os_android->main_loop_iterate() == true) {
+ if (os_android->main_loop_iterate()) {
jclass cls = env->FindClass("org/godotengine/godot/Godot");
jmethodID _finish = env->GetMethodID(cls, "forceQuit", "()V");
diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp
index 484ca4fff8..30bc413459 100644
--- a/platform/android/os_android.cpp
+++ b/platform/android/os_android.cpp
@@ -677,13 +677,14 @@ String OS_Android::get_unique_id() const {
return OS::get_unique_id();
}
-Error OS_Android::native_video_play(String p_path, float p_volume) {
+Error OS_Android::native_video_play(String p_path, float p_volume, String p_audio_track, String p_subtitle_track) {
+ // FIXME: Add support for volume, audio and subtitle tracks
if (video_play_func)
video_play_func(p_path);
return OK;
}
-bool OS_Android::native_video_is_playing() {
+bool OS_Android::native_video_is_playing() const {
if (video_is_playing_func)
return video_is_playing_func();
return false;
diff --git a/platform/android/os_android.h b/platform/android/os_android.h
index 9594c6fdf4..e89a380e4c 100644
--- a/platform/android/os_android.h
+++ b/platform/android/os_android.h
@@ -237,8 +237,8 @@ public:
void process_event(Ref<InputEvent> p_event);
void init_video_mode(int p_video_width, int p_video_height);
- virtual Error native_video_play(String p_path, float p_volume);
- virtual bool native_video_is_playing();
+ virtual Error native_video_play(String p_path, float p_volume, String p_audio_track, String p_subtitle_track);
+ virtual bool native_video_is_playing() const;
virtual void native_video_pause();
virtual void native_video_stop();
diff --git a/platform/haiku/context_gl_haiku.h b/platform/haiku/context_gl_haiku.h
index 74f09984f2..2c20570a8d 100644
--- a/platform/haiku/context_gl_haiku.h
+++ b/platform/haiku/context_gl_haiku.h
@@ -46,9 +46,6 @@ private:
bool use_vsync;
public:
- ContextGL_Haiku(HaikuDirectWindow *p_window);
- ~ContextGL_Haiku();
-
virtual Error initialize();
virtual void release_current();
virtual void make_current();
@@ -58,6 +55,9 @@ public:
virtual void set_use_vsync(bool p_use);
virtual bool is_using_vsync() const;
+
+ ContextGL_Haiku(HaikuDirectWindow *p_window);
+ virtual ~ContextGL_Haiku();
};
#endif
diff --git a/platform/haiku/haiku_direct_window.cpp b/platform/haiku/haiku_direct_window.cpp
index 150e90be65..6b64082250 100644
--- a/platform/haiku/haiku_direct_window.cpp
+++ b/platform/haiku/haiku_direct_window.cpp
@@ -86,7 +86,7 @@ void HaikuDirectWindow::DirectConnected(direct_buffer_info *info) {
void HaikuDirectWindow::MessageReceived(BMessage *message) {
switch (message->what) {
case REDRAW_MSG:
- if (Main::iteration() == true) {
+ if (Main::iteration()) {
view->EnableDirectMode(false);
Quit();
}
diff --git a/platform/iphone/gl_view.mm b/platform/iphone/gl_view.mm
index 478a3125af..2925b46007 100644
--- a/platform/iphone/gl_view.mm
+++ b/platform/iphone/gl_view.mm
@@ -53,7 +53,6 @@ static GLView *_instance = NULL;
static bool video_found_error = false;
static bool video_playing = false;
-static float video_previous_volume = 0.0f;
static CMTime video_current_time;
void _show_keyboard(String);
@@ -248,16 +247,6 @@ static int remove_touch(UITouch *p_touch) {
return remaining;
};
-static int get_first_id(UITouch *p_touch) {
-
- for (int i = 0; i < max_touches; i++) {
-
- if (touches[i] != NULL)
- return i;
- };
- return -1;
-};
-
static void clear_touches() {
for (int i = 0; i < max_touches; i++) {
@@ -751,7 +740,6 @@ static void clear_touches() {
[_instance.moviePlayerController stop];
[_instance.moviePlayerController.view removeFromSuperview];
- //[[MPMusicPlayerController applicationMusicPlayer] setVolume: video_previous_volume];
video_playing = false;
}
*/
diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm
index 886ff4b332..6ab433203f 100644
--- a/platform/osx/os_osx.mm
+++ b/platform/osx/os_osx.mm
@@ -76,11 +76,6 @@
#define NSWindowStyleMaskBorderless NSBorderlessWindowMask
#endif
-static NSRect convertRectToBacking(NSRect contentRect) {
-
- return [OS_OSX::singleton->window_view convertRectToBacking:contentRect];
-}
-
static void get_key_modifier_state(unsigned int p_osx_state, Ref<InputEventWithModifiers> state) {
state->set_shift((p_osx_state & NSEventModifierFlagShift));
@@ -271,7 +266,7 @@ static Vector2 get_mouse_pos(NSEvent *event) {
float newDisplayScale = OS_OSX::singleton->is_hidpi_allowed() ? newBackingScaleFactor : 1.0;
const NSRect contentRect = [OS_OSX::singleton->window_view frame];
- const NSRect fbRect = contentRect; //convertRectToBacking(contentRect);
+ const NSRect fbRect = contentRect;
OS_OSX::singleton->window_size.width = fbRect.size.width * newDisplayScale;
OS_OSX::singleton->window_size.height = fbRect.size.height * newDisplayScale;
@@ -292,7 +287,7 @@ static Vector2 get_mouse_pos(NSEvent *event) {
[OS_OSX::singleton->context update];
const NSRect contentRect = [OS_OSX::singleton->window_view frame];
- const NSRect fbRect = contentRect; //convertRectToBacking(contentRect);
+ const NSRect fbRect = contentRect;
float displayScale = OS_OSX::singleton->_display_scale();
OS_OSX::singleton->window_size.width = fbRect.size.width * displayScale;
@@ -1864,28 +1859,30 @@ bool OS_OSX::can_draw() const {
void OS_OSX::set_clipboard(const String &p_text) {
- NSArray *types = [NSArray arrayWithObjects:NSStringPboardType, nil];
+ NSString *copiedString = [NSString stringWithUTF8String:p_text.utf8().get_data()];
+ NSArray *copiedStringArray = [NSArray arrayWithObject:copiedString];
NSPasteboard *pasteboard = [NSPasteboard generalPasteboard];
- [pasteboard declareTypes:types owner:nil];
- [pasteboard setString:[NSString stringWithUTF8String:p_text.utf8().get_data()]
- forType:NSStringPboardType];
+ [pasteboard clearContents];
+ [pasteboard writeObjects:copiedStringArray];
}
String OS_OSX::get_clipboard() const {
NSPasteboard *pasteboard = [NSPasteboard generalPasteboard];
+ NSArray *classArray = [NSArray arrayWithObject:[NSString class]];
+ NSDictionary *options = [NSDictionary dictionary];
- if (![[pasteboard types] containsObject:NSStringPboardType]) {
- return "";
- }
+ BOOL ok = [pasteboard canReadObjectForClasses:classArray options:options];
- NSString *object = [pasteboard stringForType:NSStringPboardType];
- if (!object) {
+ if (!ok) {
return "";
}
- char *utfs = strdup([object UTF8String]);
+ NSArray *objectsToPaste = [pasteboard readObjectsForClasses:classArray options:options];
+ NSString *string = [objectsToPaste objectAtIndex:0];
+
+ char *utfs = strdup([string UTF8String]);
String ret;
ret.parse_utf8(utfs);
free(utfs);
diff --git a/platform/server/os_server.cpp b/platform/server/os_server.cpp
index 1069d6bbed..6a7038e946 100644
--- a/platform/server/os_server.cpp
+++ b/platform/server/os_server.cpp
@@ -221,7 +221,7 @@ void OS_Server::run() {
while (!force_quit) {
- if (Main::iteration() == true)
+ if (Main::iteration())
break;
};
diff --git a/platform/uwp/gl_context_egl.h b/platform/uwp/gl_context_egl.h
index 3e3c4a0f57..3c7115cc34 100644
--- a/platform/uwp/gl_context_egl.h
+++ b/platform/uwp/gl_context_egl.h
@@ -71,8 +71,8 @@ public:
virtual int get_window_height();
virtual void swap_buffers();
- void set_use_vsync(bool use) { vsync = use; }
- bool is_using_vsync() const { return vsync; }
+ virtual void set_use_vsync(bool use) { vsync = use; }
+ virtual bool is_using_vsync() const { return vsync; }
virtual Error initialize();
void reset();
@@ -80,7 +80,7 @@ public:
void cleanup();
ContextEGL(CoreWindow ^ p_window, Driver p_driver);
- ~ContextEGL();
+ virtual ~ContextEGL();
};
#endif
diff --git a/platform/uwp/os_uwp.cpp b/platform/uwp/os_uwp.cpp
index f489c0894f..6410378593 100644
--- a/platform/uwp/os_uwp.cpp
+++ b/platform/uwp/os_uwp.cpp
@@ -864,7 +864,7 @@ void OSUWP::run() {
CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent);
if (managed_object->alert_close_handle) continue;
process_events(); // get rid of pending events
- if (Main::iteration() == true)
+ if (Main::iteration())
break;
};
diff --git a/platform/windows/context_gl_win.h b/platform/windows/context_gl_win.h
index af2f89568e..5bcdb433b3 100644
--- a/platform/windows/context_gl_win.h
+++ b/platform/windows/context_gl_win.h
@@ -69,7 +69,7 @@ public:
virtual bool is_using_vsync() const;
ContextGL_Win(HWND hwnd, bool p_opengl_3_context);
- ~ContextGL_Win();
+ virtual ~ContextGL_Win();
};
#endif
diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp
index e8c209c0fc..739fcbacda 100644
--- a/platform/windows/os_windows.cpp
+++ b/platform/windows/os_windows.cpp
@@ -1744,7 +1744,7 @@ void OS_Windows::set_window_size(const Size2 p_size) {
RECT rect;
GetWindowRect(hWnd, &rect);
- if (video_mode.borderless_window == false) {
+ if (!video_mode.borderless_window) {
RECT crect;
GetClientRect(hWnd, &crect);
@@ -2737,7 +2737,7 @@ void OS_Windows::run() {
while (!force_quit) {
process_events(); // get rid of pending events
- if (Main::iteration() == true)
+ if (Main::iteration())
break;
};
diff --git a/platform/x11/context_gl_x11.h b/platform/x11/context_gl_x11.h
index ab0379a2fe..be3083d957 100644
--- a/platform/x11/context_gl_x11.h
+++ b/platform/x11/context_gl_x11.h
@@ -79,7 +79,7 @@ public:
virtual bool is_using_vsync() const;
ContextGL_X11(::Display *p_x11_display, ::Window &p_x11_window, const OS::VideoMode &p_default_video_mode, ContextType p_context_type);
- ~ContextGL_X11();
+ virtual ~ContextGL_X11();
};
#endif
diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp
index 5be0b9304a..7c4c8f0eff 100644
--- a/platform/x11/os_x11.cpp
+++ b/platform/x11/os_x11.cpp
@@ -1096,7 +1096,7 @@ void OS_X11::set_window_size(const Size2 p_size) {
int old_h = xwa.height;
// If window resizable is disabled we need to update the attributes first
- if (is_window_resizable() == false) {
+ if (!is_window_resizable()) {
XSizeHints *xsh;
xsh = XAllocSizeHints();
xsh->flags = PMinSize | PMaxSize;
@@ -1688,7 +1688,7 @@ void OS_X11::handle_key_event(XKeyEvent *p_event, bool p_echo) {
}
} else {
//ignore
- if (last_is_pressed == false) {
+ if (!last_is_pressed) {
return;
}
}
@@ -2814,7 +2814,7 @@ void OS_X11::run() {
#ifdef JOYDEV_ENABLED
joypad->process_joypads();
#endif
- if (Main::iteration() == true)
+ if (Main::iteration())
break;
};
diff --git a/scene/2d/animated_sprite.cpp b/scene/2d/animated_sprite.cpp
index a33fc844a5..8a5910c10e 100644
--- a/scene/2d/animated_sprite.cpp
+++ b/scene/2d/animated_sprite.cpp
@@ -395,15 +395,17 @@ void AnimatedSprite::_notification(int p_what) {
int fc = frames->get_frame_count(animation);
if (frame >= fc - 1) {
if (frames->get_animation_loop(animation)) {
+ emit_signal(SceneStringNames::get_singleton()->animation_finished);
frame = 0;
} else {
+ if (!is_over) {
+ emit_signal(SceneStringNames::get_singleton()->animation_finished);
+ is_over = true;
+ }
frame = fc - 1;
}
} else {
frame++;
- if (frame == fc - 1) {
- emit_signal(SceneStringNames::get_singleton()->animation_finished);
- }
}
update();
@@ -625,6 +627,7 @@ void AnimatedSprite::_reset_timeout() {
return;
timeout = _get_frame_duration();
+ is_over = false;
}
void AnimatedSprite::set_animation(const StringName &p_animation) {
@@ -712,4 +715,5 @@ AnimatedSprite::AnimatedSprite() {
playing = false;
animation = "default";
timeout = 0;
+ is_over = false;
}
diff --git a/scene/2d/animated_sprite.h b/scene/2d/animated_sprite.h
index cc49465403..7270ee4d0e 100644
--- a/scene/2d/animated_sprite.h
+++ b/scene/2d/animated_sprite.h
@@ -135,6 +135,7 @@ class AnimatedSprite : public Node2D {
bool centered;
Point2 offset;
+ bool is_over;
float timeout;
bool hflip;
diff --git a/scene/2d/camera_2d.cpp b/scene/2d/camera_2d.cpp
index 3b86ca76ea..788a39d05d 100644
--- a/scene/2d/camera_2d.cpp
+++ b/scene/2d/camera_2d.cpp
@@ -422,14 +422,14 @@ void Camera2D::clear_current() {
void Camera2D::set_limit(Margin p_margin, int p_limit) {
- ERR_FAIL_INDEX(p_margin, 4);
+ ERR_FAIL_INDEX((int)p_margin, 4);
limit[p_margin] = p_limit;
update();
}
int Camera2D::get_limit(Margin p_margin) const {
- ERR_FAIL_INDEX_V(p_margin, 4, 0);
+ ERR_FAIL_INDEX_V((int)p_margin, 4, 0);
return limit[p_margin];
}
@@ -446,14 +446,14 @@ bool Camera2D::is_limit_smoothing_enabled() const {
void Camera2D::set_drag_margin(Margin p_margin, float p_drag_margin) {
- ERR_FAIL_INDEX(p_margin, 4);
+ ERR_FAIL_INDEX((int)p_margin, 4);
drag_margin[p_margin] = p_drag_margin;
update();
}
float Camera2D::get_drag_margin(Margin p_margin) const {
- ERR_FAIL_INDEX_V(p_margin, 4, 0);
+ ERR_FAIL_INDEX_V((int)p_margin, 4, 0);
return drag_margin[p_margin];
}
diff --git a/scene/2d/collision_polygon_2d.cpp b/scene/2d/collision_polygon_2d.cpp
index 508ceeaaf9..410b27c691 100644
--- a/scene/2d/collision_polygon_2d.cpp
+++ b/scene/2d/collision_polygon_2d.cpp
@@ -247,7 +247,7 @@ Vector<Point2> CollisionPolygon2D::get_polygon() const {
void CollisionPolygon2D::set_build_mode(BuildMode p_mode) {
- ERR_FAIL_INDEX(p_mode, 2);
+ ERR_FAIL_INDEX((int)p_mode, 2);
build_mode = p_mode;
if (parent) {
_build_polygon();
diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp
index 5b8d10ea85..a60ce47f5c 100644
--- a/scene/2d/tile_map.cpp
+++ b/scene/2d/tile_map.cpp
@@ -304,7 +304,7 @@ void TileMap::update_dirty_quadrants() {
}
q.occluder_instances.clear();
Ref<ShaderMaterial> prev_material;
- int prev_z_index;
+ int prev_z_index = 0;
RID prev_canvas_item;
RID prev_debug_canvas_item;
diff --git a/scene/2d/visibility_notifier_2d.h b/scene/2d/visibility_notifier_2d.h
index c4e12dfa22..04084b609a 100644
--- a/scene/2d/visibility_notifier_2d.h
+++ b/scene/2d/visibility_notifier_2d.h
@@ -43,7 +43,7 @@ class VisibilityNotifier2D : public Node2D {
Rect2 rect;
protected:
- friend class SpatialIndexer2D;
+ friend struct SpatialIndexer2D;
void _enter_viewport(Viewport *p_viewport);
void _exit_viewport(Viewport *p_viewport);
diff --git a/scene/3d/audio_stream_player_3d.cpp b/scene/3d/audio_stream_player_3d.cpp
index b1f90b72e7..abf022ecb3 100644
--- a/scene/3d/audio_stream_player_3d.cpp
+++ b/scene/3d/audio_stream_player_3d.cpp
@@ -814,7 +814,7 @@ AudioStreamPlayer3D::AttenuationModel AudioStreamPlayer3D::get_attenuation_model
void AudioStreamPlayer3D::set_out_of_range_mode(OutOfRangeMode p_mode) {
- ERR_FAIL_INDEX(p_mode, 2);
+ ERR_FAIL_INDEX((int)p_mode, 2);
out_of_range_mode = p_mode;
}
diff --git a/scene/3d/baked_lightmap.cpp b/scene/3d/baked_lightmap.cpp
index c58e318651..62589bd67e 100644
--- a/scene/3d/baked_lightmap.cpp
+++ b/scene/3d/baked_lightmap.cpp
@@ -29,6 +29,7 @@
/*************************************************************************/
#include "baked_lightmap.h"
+#include "core/io/config_file.h"
#include "core/io/resource_saver.h"
#include "core/os/dir_access.h"
#include "core/os/os.h"
@@ -365,7 +366,7 @@ BakedLightmap::BakeError BakedLightmap::bake(Node *p_from_node, bool p_create_vi
{
bake_bounds = AABB(-extents, extents * 2.0);
int subdiv = nearest_power_of_2_templated(int(bake_bounds.get_longest_axis_size() / bake_cell_size));
- bake_bounds.size[bake_bounds.get_longest_axis_size()] = subdiv * bake_cell_size;
+ bake_bounds.size[bake_bounds.get_longest_axis_index()] = subdiv * bake_cell_size;
bake_subdiv = nearest_shift(subdiv) + 1;
capture_subdiv = bake_subdiv;
@@ -526,21 +527,60 @@ BakedLightmap::BakeError BakedLightmap::bake(Node *p_from_node, bool p_create_vi
tex_flags |= Texture::FLAG_CONVERT_TO_LINEAR;
}
- Ref<ImageTexture> tex;
- String image_path = save_path.plus_file(mesh_name + ".tex");
- bool set_path = true;
- if (ResourceCache::has(image_path)) {
- tex = Ref<Resource>((Resource *)ResourceCache::get(image_path));
- set_path = false;
- }
+ String image_path = save_path.plus_file(mesh_name);
+ Ref<Texture> texture;
- if (!tex.is_valid()) {
- tex.instance();
- }
+ if (ResourceLoader::import) {
+
+ bool srgb = false;
+ if (false && hdr) {
+ //save hdr
+ } else {
+ image_path += ".png";
+ print_line("image path saving png: " + image_path);
+ image->save_png(image_path);
+ srgb = true;
+ }
- tex->create_from_image(image, tex_flags);
+ if (!FileAccess::exists(image_path + ".import")) {
+ Ref<ConfigFile> config;
+ config.instance();
+ config->set_value("remap", "importer", "texture");
+ config->set_value("remap", "type", "StreamTexture");
+ config->set_value("params", "compress/mode", 2);
+ config->set_value("params", "detect_3d", false);
+ config->set_value("params", "flags/repeat", false);
+ config->set_value("params", "flags/filter", true);
+ config->set_value("params", "flags/mipmaps", false);
+ config->set_value("params", "flags/srgb", srgb);
+
+ config->save(image_path + ".import");
+ }
+
+ ResourceLoader::import(image_path);
+ texture = ResourceLoader::load(image_path); //if already loaded, it will be updated on refocus?
+ } else {
- err = ResourceSaver::save(image_path, tex, ResourceSaver::FLAG_CHANGE_PATH);
+ image_path += ".text";
+ Ref<ImageTexture> tex;
+ bool set_path = true;
+ if (ResourceCache::has(image_path)) {
+ tex = Ref<Resource>((Resource *)ResourceCache::get(image_path));
+ set_path = false;
+ }
+
+ if (!tex.is_valid()) {
+ tex.instance();
+ }
+
+ tex->create_from_image(image, tex_flags);
+
+ err = ResourceSaver::save(image_path, tex, ResourceSaver::FLAG_CHANGE_PATH);
+ if (set_path) {
+ tex->set_path(image_path);
+ }
+ texture = tex;
+ }
if (err != OK) {
if (bake_end_function) {
bake_end_function();
@@ -548,10 +588,7 @@ BakedLightmap::BakeError BakedLightmap::bake(Node *p_from_node, bool p_create_vi
ERR_FAIL_COND_V(err != OK, BAKE_ERROR_CANT_CREATE_IMAGE);
}
- if (set_path) {
- tex->set_path(image_path);
- }
- new_light_data->add_user(E->get().path, tex, E->get().instance_idx);
+ new_light_data->add_user(E->get().path, texture, E->get().instance_idx);
}
}
diff --git a/scene/3d/physics_body.h b/scene/3d/physics_body.h
index ca48b51ffb..ed9f41197b 100644
--- a/scene/3d/physics_body.h
+++ b/scene/3d/physics_body.h
@@ -389,6 +389,8 @@ public:
virtual bool _set(const StringName &p_name, const Variant &p_value, RID j = RID());
virtual bool _get(const StringName &p_name, Variant &r_ret) const;
virtual void _get_property_list(List<PropertyInfo> *p_list) const;
+
+ virtual ~JointData() {}
};
struct PinJointData : public JointData {
diff --git a/scene/3d/visibility_notifier.h b/scene/3d/visibility_notifier.h
index b1985f4a0c..2cf685a92c 100644
--- a/scene/3d/visibility_notifier.h
+++ b/scene/3d/visibility_notifier.h
@@ -48,7 +48,7 @@ protected:
void _notification(int p_what);
static void _bind_methods();
- friend class SpatialIndexer;
+ friend struct SpatialIndexer;
void _enter_camera(Camera *p_camera);
void _exit_camera(Camera *p_camera);
diff --git a/scene/3d/voxel_light_baker.cpp b/scene/3d/voxel_light_baker.cpp
index 651a057392..f9bd905181 100644
--- a/scene/3d/voxel_light_baker.cpp
+++ b/scene/3d/voxel_light_baker.cpp
@@ -734,7 +734,8 @@ void VoxelLightBaker::_check_init_light() {
leaf_voxel_count = 0;
_fixup_plot(0, 0); //pre fixup, so normal, albedo, emission, etc. work for lighting.
bake_light.resize(bake_cells.size());
- zeromem(bake_light.ptrw(), bake_light.size() * sizeof(Light));
+ print_line("bake light size: " + itos(bake_light.size()));
+ //zeromem(bake_light.ptrw(), bake_light.size() * sizeof(Light));
first_leaf = -1;
_init_light_plot(0, 0, 0, 0, 0, CHILD_EMPTY);
}
@@ -1586,10 +1587,10 @@ Vector3 VoxelLightBaker::_compute_pixel_light_at_pos(const Vector3 &p_pos, const
Vector3 bitangent = tangent.cross(p_normal).normalized();
Basis normal_xform = Basis(tangent, bitangent, p_normal).transposed();
- const Vector3 *cone_dirs;
- const float *cone_weights;
- int cone_dir_count;
- float cone_aperture;
+ const Vector3 *cone_dirs = NULL;
+ const float *cone_weights = NULL;
+ int cone_dir_count = 0;
+ float cone_aperture = 0;
switch (bake_quality) {
case BAKE_QUALITY_LOW: {
diff --git a/scene/3d/voxel_light_baker.h b/scene/3d/voxel_light_baker.h
index 6a1f1253a3..3d55c053f3 100644
--- a/scene/3d/voxel_light_baker.h
+++ b/scene/3d/voxel_light_baker.h
@@ -92,6 +92,16 @@ private:
float accum[6][3]; //rgb anisotropic
float direct_accum[6][3]; //for direct bake
int next_leaf;
+ Light() {
+ x = y = z = 0;
+ for (int i = 0; i < 6; i++) {
+ for (int j = 0; j < 3; j++) {
+ accum[i][j] = 0;
+ direct_accum[i][j] = 0;
+ }
+ }
+ next_leaf = 0;
+ }
};
int first_leaf;
diff --git a/scene/animation/animation_blend_space_2d.cpp b/scene/animation/animation_blend_space_2d.cpp
index f5f899a6cd..9321133d5f 100644
--- a/scene/animation/animation_blend_space_2d.cpp
+++ b/scene/animation/animation_blend_space_2d.cpp
@@ -468,7 +468,7 @@ float AnimationNodeBlendSpace2D::process(float p_time, bool p_seek) {
}
first = true;
- float mind;
+ float mind = 0;
for (int i = 0; i < blend_points_used; i++) {
bool found = false;
diff --git a/scene/gui/base_button.cpp b/scene/gui/base_button.cpp
index 71fb97c2c6..6dfaacc776 100644
--- a/scene/gui/base_button.cpp
+++ b/scene/gui/base_button.cpp
@@ -368,7 +368,7 @@ BaseButton::DrawMode BaseButton::get_draw_mode() const {
return DRAW_DISABLED;
};
- if (status.press_attempt == false && status.hovering) {
+ if (!status.press_attempt && status.hovering) {
if (status.pressed)
return DRAW_HOVER_PRESSED;
diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp
index 03eee9c6d8..c5d3def4c1 100644
--- a/scene/gui/color_picker.cpp
+++ b/scene/gui/color_picker.cpp
@@ -159,7 +159,10 @@ void ColorPicker::_html_entered(const String &p_html) {
if (updating)
return;
+ float last_alpha = color.a;
color = Color::html(p_html);
+ if (!is_editing_alpha())
+ color.a = last_alpha;
if (!is_inside_tree())
return;
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp
index dc18895298..effcd0abee 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -1079,7 +1079,7 @@ bool Control::has_constant_override(const StringName &p_name) const {
bool Control::has_icon(const StringName &p_name, const StringName &p_type) const {
if (p_type == StringName() || p_type == "") {
- if (has_icon_override(p_name) == true)
+ if (has_icon_override(p_name))
return true;
}
@@ -1113,7 +1113,7 @@ bool Control::has_icon(const StringName &p_name, const StringName &p_type) const
bool Control::has_shader(const StringName &p_name, const StringName &p_type) const {
if (p_type == StringName() || p_type == "") {
- if (has_shader_override(p_name) == true)
+ if (has_shader_override(p_name))
return true;
}
@@ -1146,7 +1146,7 @@ bool Control::has_shader(const StringName &p_name, const StringName &p_type) con
bool Control::has_stylebox(const StringName &p_name, const StringName &p_type) const {
if (p_type == StringName() || p_type == "") {
- if (has_stylebox_override(p_name) == true)
+ if (has_stylebox_override(p_name))
return true;
}
@@ -1179,7 +1179,7 @@ bool Control::has_stylebox(const StringName &p_name, const StringName &p_type) c
bool Control::has_font(const StringName &p_name, const StringName &p_type) const {
if (p_type == StringName() || p_type == "") {
- if (has_font_override(p_name) == true)
+ if (has_font_override(p_name))
return true;
}
@@ -1213,7 +1213,7 @@ bool Control::has_font(const StringName &p_name, const StringName &p_type) const
bool Control::has_color(const StringName &p_name, const StringName &p_type) const {
if (p_type == StringName() || p_type == "") {
- if (has_color_override(p_name) == true)
+ if (has_color_override(p_name))
return true;
}
@@ -1247,7 +1247,7 @@ bool Control::has_color(const StringName &p_name, const StringName &p_type) cons
bool Control::has_constant(const StringName &p_name, const StringName &p_type) const {
if (p_type == StringName() || p_type == "") {
- if (has_constant_override(p_name) == true)
+ if (has_constant_override(p_name))
return true;
}
@@ -2235,13 +2235,13 @@ String Control::_get_tooltip() const {
void Control::set_focus_neighbour(Margin p_margin, const NodePath &p_neighbour) {
- ERR_FAIL_INDEX(p_margin, 4);
+ ERR_FAIL_INDEX((int)p_margin, 4);
data.focus_neighbour[p_margin] = p_neighbour;
}
NodePath Control::get_focus_neighbour(Margin p_margin) const {
- ERR_FAIL_INDEX_V(p_margin, 4, NodePath());
+ ERR_FAIL_INDEX_V((int)p_margin, 4, NodePath());
return data.focus_neighbour[p_margin];
}
diff --git a/scene/gui/gradient_edit.cpp b/scene/gui/gradient_edit.cpp
index 19ffe681ef..934b84ec0c 100644
--- a/scene/gui/gradient_edit.cpp
+++ b/scene/gui/gradient_edit.cpp
@@ -238,21 +238,21 @@ void GradientEdit::_gui_input(const Ref<InputEvent> &p_event) {
if (mm->get_shift()) {
float snap_treshhold = 0.03;
float smallest_ofs = snap_treshhold;
- bool founded = false;
- int nearest_point;
+ bool found = false;
+ int nearest_point = 0;
for (int i = 0; i < points.size(); ++i) {
if (i != grabbed) {
float temp_ofs = ABS(points[i].offset - newofs);
if (temp_ofs < smallest_ofs) {
smallest_ofs = temp_ofs;
nearest_point = i;
- if (founded)
+ if (found)
break;
- founded = true;
+ found = true;
}
}
}
- if (founded) {
+ if (found) {
if (points[nearest_point].offset < newofs)
newofs = points[nearest_point].offset + 0.00001;
else
diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp
index 0ffaac20f6..b4fd7484e9 100644
--- a/scene/gui/graph_edit.cpp
+++ b/scene/gui/graph_edit.cpp
@@ -1042,7 +1042,7 @@ void GraphEdit::set_connection_activity(const StringName &p_from, int p_from_por
if (E->get().from == p_from && E->get().from_port == p_from_port && E->get().to == p_to && E->get().to_port == p_to_port) {
- if (ABS(E->get().activity != p_activity)) {
+ if (ABS(E->get().activity - p_activity) < CMP_EPSILON) {
//update only if changed
top_layer->update();
connections_layer->update();
diff --git a/scene/gui/grid_container.cpp b/scene/gui/grid_container.cpp
index 278e4123d7..bb1d1d7695 100644
--- a/scene/gui/grid_container.cpp
+++ b/scene/gui/grid_container.cpp
@@ -184,8 +184,6 @@ void GridContainer::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_columns", "columns"), &GridContainer::set_columns);
ClassDB::bind_method(D_METHOD("get_columns"), &GridContainer::get_columns);
- ClassDB::bind_method(D_METHOD("get_child_control_at_cell", "row", "column"),
- &GridContainer::get_child_control_at_cell);
ADD_PROPERTY(PropertyInfo(Variant::INT, "columns", PROPERTY_HINT_RANGE, "1,1024,1"), "set_columns", "get_columns");
}
@@ -241,21 +239,6 @@ Size2 GridContainer::get_minimum_size() const {
return ms;
}
-Control *GridContainer::get_child_control_at_cell(int row, int column) {
- Control *c;
- int grid_index = row * columns + column;
- for (int i = 0; i < get_child_count(); i++) {
- c = Object::cast_to<Control>(get_child(i));
- if (!c || !c->is_visible_in_tree())
- continue;
-
- if (grid_index == i) {
- break;
- }
- }
- return c;
-}
-
GridContainer::GridContainer() {
set_mouse_filter(MOUSE_FILTER_PASS);
diff --git a/scene/gui/grid_container.h b/scene/gui/grid_container.h
index 7e3470dc89..243d06f034 100644
--- a/scene/gui/grid_container.h
+++ b/scene/gui/grid_container.h
@@ -47,7 +47,6 @@ public:
void set_columns(int p_columns);
int get_columns() const;
virtual Size2 get_minimum_size() const;
- Control *get_child_control_at_cell(int row, int column);
GridContainer();
};
diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp
index 91dab27930..6ff2d232f0 100644
--- a/scene/gui/label.cpp
+++ b/scene/gui/label.cpp
@@ -511,7 +511,7 @@ void Label::regenerate_word_cache() {
void Label::set_align(Align p_align) {
- ERR_FAIL_INDEX(p_align, 4);
+ ERR_FAIL_INDEX((int)p_align, 4);
align = p_align;
update();
}
@@ -523,7 +523,7 @@ Label::Align Label::get_align() const {
void Label::set_valign(VAlign p_align) {
- ERR_FAIL_INDEX(p_align, 4);
+ ERR_FAIL_INDEX((int)p_align, 4);
valign = p_align;
update();
}
diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp
index 9c43d5b308..6f344f1028 100644
--- a/scene/gui/line_edit.cpp
+++ b/scene/gui/line_edit.cpp
@@ -527,7 +527,7 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
void LineEdit::set_align(Align p_align) {
- ERR_FAIL_INDEX(p_align, 4);
+ ERR_FAIL_INDEX((int)p_align, 4);
align = p_align;
update();
}
diff --git a/scene/gui/nine_patch_rect.cpp b/scene/gui/nine_patch_rect.cpp
index b8f6ffe6d2..c6a34921c7 100644
--- a/scene/gui/nine_patch_rect.cpp
+++ b/scene/gui/nine_patch_rect.cpp
@@ -110,7 +110,7 @@ Ref<Texture> NinePatchRect::get_texture() const {
void NinePatchRect::set_patch_margin(Margin p_margin, int p_size) {
- ERR_FAIL_INDEX(p_margin, 4);
+ ERR_FAIL_INDEX((int)p_margin, 4);
margin[p_margin] = p_size;
update();
minimum_size_changed();
@@ -132,7 +132,7 @@ void NinePatchRect::set_patch_margin(Margin p_margin, int p_size) {
int NinePatchRect::get_patch_margin(Margin p_margin) const {
- ERR_FAIL_INDEX_V(p_margin, 4, 0);
+ ERR_FAIL_INDEX_V((int)p_margin, 4, 0);
return margin[p_margin];
}
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index c390c60a8c..32580a5ae6 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -334,15 +334,12 @@ void TextEdit::_update_scrollbars() {
h_scroll->set_begin(Point2(0, size.height - hmin.height));
h_scroll->set_end(Point2(size.width - vmin.width, size.height));
- int hscroll_rows = ((hmin.height - 1) / get_row_height()) + 1;
int visible_rows = get_visible_rows();
-
int total_rows = get_total_visible_rows();
if (scroll_past_end_of_file_enabled) {
total_rows += visible_rows - 1;
}
- int vscroll_pixels = v_scroll->get_combined_minimum_size().width;
int visible_width = size.width - cache.style_normal->get_minimum_size().width;
int total_width = text.get_max_width(true) + vmin.x;
@@ -367,12 +364,12 @@ void TextEdit::_update_scrollbars() {
} else {
- if (total_rows > visible_rows && total_width <= visible_width - vscroll_pixels) {
+ if (total_rows > visible_rows && total_width <= visible_width) {
//thanks yessopie for this clever bit of logic
use_hscroll = false;
}
- if (total_rows <= visible_rows - hscroll_rows && total_width > visible_width) {
+ if (total_rows <= visible_rows && total_width > visible_width) {
//thanks yessopie for this clever bit of logic
use_vscroll = false;
}
@@ -3260,7 +3257,7 @@ void TextEdit::_scroll_down(real_t p_delta) {
}
if (smooth_scroll_enabled) {
- int max_v_scroll = v_scroll->get_max() - v_scroll->get_page();
+ int max_v_scroll = round(v_scroll->get_max() - v_scroll->get_page());
if (target_v_scroll > max_v_scroll) {
target_v_scroll = max_v_scroll;
v_scroll->set_value(target_v_scroll);
diff --git a/scene/gui/texture_progress.cpp b/scene/gui/texture_progress.cpp
index d28b4065fb..75f88dc4e6 100644
--- a/scene/gui/texture_progress.cpp
+++ b/scene/gui/texture_progress.cpp
@@ -59,14 +59,14 @@ Ref<Texture> TextureProgress::get_over_texture() const {
}
void TextureProgress::set_stretch_margin(Margin p_margin, int p_size) {
- ERR_FAIL_INDEX(p_margin, 4);
+ ERR_FAIL_INDEX((int)p_margin, 4);
stretch_margin[p_margin] = p_size;
update();
minimum_size_changed();
}
int TextureProgress::get_stretch_margin(Margin p_margin) const {
- ERR_FAIL_INDEX_V(p_margin, 4, 0);
+ ERR_FAIL_INDEX_V((int)p_margin, 4, 0);
return stretch_margin[p_margin];
}
@@ -148,9 +148,9 @@ Point2 TextureProgress::unit_val_to_uv(float val) {
float angle = (val * Math_TAU) - Math_PI * 0.5;
Point2 dir = Vector2(Math::cos(angle), Math::sin(angle));
float t1 = 1.0;
- float cp;
- float cq;
- float cr;
+ float cp = 0;
+ float cq = 0;
+ float cr = 0;
float edgeLeft = 0.0;
float edgeRight = 1.0;
float edgeBottom = 0.0;
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index d3282c6ada..8fd7dc1d7b 100644
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -2182,13 +2182,15 @@ void Node::_duplicate_signals(const Node *p_original, Node *p_copy) const {
continue;
}
NodePath ptarget = p_original->get_path_to(target);
- Node *copytarget = p_copy->get_node(ptarget);
- // Cannot find a path to the duplicate target, so it seems it's not part
- // of the duplicated and not yet parented hierarchy, so at least try to connect
+ Node *copytarget = target;
+
+ // Atempt to find a path to the duplicate target, if it seems it's not part
+ // of the duplicated and not yet parented hierarchy then at least try to connect
// to the same target as the original
- if (!copytarget)
- copytarget = target;
+
+ if (p_copy->has_node(ptarget))
+ copytarget = p_copy->get_node(ptarget);
if (copy && copytarget) {
copy->connect(E->get().signal, copytarget, E->get().method, E->get().binds, E->get().flags);
@@ -2486,6 +2488,7 @@ void Node::_set_tree(SceneTree *p_tree) {
tree_changed_b->tree_changed();
}
+#ifdef DEBUG_ENABLED
static void _Node_debug_sn(Object *p_obj) {
Node *n = Object::cast_to<Node>(p_obj);
@@ -2507,6 +2510,7 @@ static void _Node_debug_sn(Object *p_obj) {
path = String(p->get_name()) + "/" + p->get_path_to(n);
print_line(itos(p_obj->get_instance_id()) + " - Stray Node: " + path + " (Type: " + n->get_class() + ")");
}
+#endif // DEBUG_ENABLED
void Node::_print_stray_nodes() {
@@ -2516,7 +2520,6 @@ void Node::_print_stray_nodes() {
void Node::print_stray_nodes() {
#ifdef DEBUG_ENABLED
-
ObjectDB::debug_objects(_Node_debug_sn);
#endif
}
diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp
index 80ad2ad739..5c01cadcd5 100644
--- a/scene/resources/animation.cpp
+++ b/scene/resources/animation.cpp
@@ -1901,7 +1901,7 @@ void Animation::value_track_set_update_mode(int p_track, UpdateMode p_mode) {
ERR_FAIL_INDEX(p_track, tracks.size());
Track *t = tracks[p_track];
ERR_FAIL_COND(t->type != TYPE_VALUE);
- ERR_FAIL_INDEX(p_mode, 4);
+ ERR_FAIL_INDEX((int)p_mode, 4);
ValueTrack *vt = static_cast<ValueTrack *>(t);
vt->update_mode = p_mode;
diff --git a/scene/resources/dynamic_font.cpp b/scene/resources/dynamic_font.cpp
index 0785d3bfc6..6790c35c4b 100644
--- a/scene/resources/dynamic_font.cpp
+++ b/scene/resources/dynamic_font.cpp
@@ -1083,8 +1083,19 @@ void DynamicFont::update_oversampling() {
E->self()->outline_data_at_size->update_oversampling();
}
+ for (int i = 0; i < E->self()->fallback_data_at_size.size(); i++) {
+ if (E->self()->fallback_data_at_size[i].is_valid()) {
+ E->self()->fallback_data_at_size.write[i]->update_oversampling();
+
+ if (E->self()->has_outline() && E->self()->fallback_outline_data_at_size[i].is_valid()) {
+ E->self()->fallback_outline_data_at_size.write[i]->update_oversampling();
+ }
+ }
+ }
+
changed.push_back(Ref<DynamicFont>(E->self()));
}
+
E = E->next();
}
diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp
index f4d5b8376b..7b43c33692 100644
--- a/scene/resources/environment.cpp
+++ b/scene/resources/environment.cpp
@@ -961,7 +961,7 @@ void Environment::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_tonemap_auto_exposure_grey"), &Environment::get_tonemap_auto_exposure_grey);
ADD_GROUP("Tonemap", "tonemap_");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "tonemap_mode", PROPERTY_HINT_ENUM, "Linear,Reindhart,Filmic,Aces"), "set_tonemapper", "get_tonemapper");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "tonemap_mode", PROPERTY_HINT_ENUM, "Linear,Reinhard,Filmic,Aces"), "set_tonemapper", "get_tonemapper");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "tonemap_exposure", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_tonemap_exposure", "get_tonemap_exposure");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "tonemap_white", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_tonemap_white", "get_tonemap_white");
ADD_GROUP("Auto Exposure", "auto_exposure_");
diff --git a/scene/resources/material.h b/scene/resources/material.h
index 0154874ae4..cf4d19b5a7 100644
--- a/scene/resources/material.h
+++ b/scene/resources/material.h
@@ -286,7 +286,7 @@ private:
mk.key = 0;
for (int i = 0; i < FEATURE_MAX; i++) {
if (features[i]) {
- mk.feature_mask |= (1 << i);
+ mk.feature_mask |= ((uint64_t)1 << i);
}
}
mk.detail_uv = detail_uv;
@@ -295,7 +295,7 @@ private:
mk.cull_mode = cull_mode;
for (int i = 0; i < FLAG_MAX; i++) {
if (flags[i]) {
- mk.flags |= (1 << i);
+ mk.flags |= ((uint64_t)1 << i);
}
}
mk.detail_blend_mode = detail_blend_mode;
diff --git a/scene/resources/shape.cpp b/scene/resources/shape.cpp
index 8ccca81acd..869f4a3a9b 100644
--- a/scene/resources/shape.cpp
+++ b/scene/resources/shape.cpp
@@ -101,7 +101,7 @@ void Shape::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_margin", "margin"), &Shape::set_margin);
ClassDB::bind_method(D_METHOD("get_margin"), &Shape::get_margin);
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "margin", PROPERTY_HINT_RANGE, "0.04,10,0.01"), "set_margin", "get_margin");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "margin", PROPERTY_HINT_RANGE, "0.04,10,0.001"), "set_margin", "get_margin");
}
Shape::Shape() :
diff --git a/scene/resources/style_box.cpp b/scene/resources/style_box.cpp
index fb81375b0a..69d85eeef3 100644
--- a/scene/resources/style_box.cpp
+++ b/scene/resources/style_box.cpp
@@ -136,7 +136,7 @@ Ref<Texture> StyleBoxTexture::get_normal_map() const {
void StyleBoxTexture::set_margin_size(Margin p_margin, float p_size) {
- ERR_FAIL_INDEX(p_margin, 4);
+ ERR_FAIL_INDEX((int)p_margin, 4);
margin[p_margin] = p_size;
emit_changed();
@@ -200,7 +200,7 @@ Size2 StyleBoxTexture::get_center_size() const {
void StyleBoxTexture::set_expand_margin_size(Margin p_expand_margin, float p_size) {
- ERR_FAIL_INDEX(p_expand_margin, 4);
+ ERR_FAIL_INDEX((int)p_expand_margin, 4);
expand_margin[p_expand_margin] = p_size;
emit_changed();
}
@@ -223,7 +223,7 @@ void StyleBoxTexture::set_expand_margin_size_all(float p_expand_margin_size) {
float StyleBoxTexture::get_expand_margin_size(Margin p_expand_margin) const {
- ERR_FAIL_INDEX_V(p_expand_margin, 4, 0);
+ ERR_FAIL_INDEX_V((int)p_expand_margin, 4, 0);
return expand_margin[p_expand_margin];
}
diff --git a/servers/audio/effects/audio_effect_record.cpp b/servers/audio/effects/audio_effect_record.cpp
index 78ba658ed8..a0094f66b8 100644
--- a/servers/audio/effects/audio_effect_record.cpp
+++ b/servers/audio/effects/audio_effect_record.cpp
@@ -44,7 +44,7 @@ void AudioEffectRecordInstance::process(const AudioFrame *p_src_frames, AudioFra
}
}
-bool AudioEffectRecordInstance::process_silence() {
+bool AudioEffectRecordInstance::process_silence() const {
return true;
}
diff --git a/servers/audio/effects/audio_effect_record.h b/servers/audio/effects/audio_effect_record.h
index edf8565c06..4b8ee2bcdd 100644
--- a/servers/audio/effects/audio_effect_record.h
+++ b/servers/audio/effects/audio_effect_record.h
@@ -66,7 +66,7 @@ class AudioEffectRecordInstance : public AudioEffectInstance {
public:
void init();
virtual void process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count);
- virtual bool process_silence();
+ virtual bool process_silence() const;
AudioEffectRecordInstance() :
thread_active(false) {}
diff --git a/servers/physics/joints/generic_6dof_joint_sw.cpp b/servers/physics/joints/generic_6dof_joint_sw.cpp
index 9b1a41e80d..60505c08c5 100644
--- a/servers/physics/joints/generic_6dof_joint_sw.cpp
+++ b/servers/physics/joints/generic_6dof_joint_sw.cpp
@@ -83,7 +83,7 @@ int G6DOFRotationalLimitMotorSW::testLimitValue(real_t test_value) {
real_t G6DOFRotationalLimitMotorSW::solveAngularLimits(
real_t timeStep, Vector3 &axis, real_t jacDiagABInv,
BodySW *body0, BodySW *body1) {
- if (needApplyTorques() == false) return 0.0f;
+ if (!needApplyTorques()) return 0.0f;
real_t target_velocity = m_targetVelocity;
real_t maxMotorForce = m_maxMotorForce;
diff --git a/servers/physics/joints/generic_6dof_joint_sw.h b/servers/physics/joints/generic_6dof_joint_sw.h
index b350546c5d..035525c9e6 100644
--- a/servers/physics/joints/generic_6dof_joint_sw.h
+++ b/servers/physics/joints/generic_6dof_joint_sw.h
@@ -118,14 +118,12 @@ public:
//! Is limited
bool isLimited() {
- if (m_loLimit >= m_hiLimit) return false;
- return true;
+ return (m_loLimit < m_hiLimit);
}
//! Need apply correction
bool needApplyTorques() {
- if (m_currentLimit == 0 && m_enableMotor == false) return false;
- return true;
+ return (m_enableMotor || m_currentLimit != 0);
}
//! calculates error
diff --git a/servers/physics/shape_sw.cpp b/servers/physics/shape_sw.cpp
index e1c985f44f..e7fc821c2c 100644
--- a/servers/physics/shape_sw.cpp
+++ b/servers/physics/shape_sw.cpp
@@ -1047,7 +1047,7 @@ void FaceShapeSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_su
/** FIND SUPPORT VERTEX **/
int vert_support_idx = -1;
- real_t support_max;
+ real_t support_max = 0;
for (int i = 0; i < 3; i++) {
diff --git a/servers/physics_2d/body_pair_2d_sw.cpp b/servers/physics_2d/body_pair_2d_sw.cpp
index 2633edf7bb..93a05b74ef 100644
--- a/servers/physics_2d/body_pair_2d_sw.cpp
+++ b/servers/physics_2d/body_pair_2d_sw.cpp
@@ -138,7 +138,7 @@ void BodyPair2DSW::_validate_contacts() {
Contact &c = contacts[i];
bool erase = false;
- if (c.reused == false) {
+ if (!c.reused) {
//was left behind in previous frame
erase = true;
} else {
diff --git a/servers/physics_2d/step_2d_sw.cpp b/servers/physics_2d/step_2d_sw.cpp
index 0fb7af0c94..e4e1b03623 100644
--- a/servers/physics_2d/step_2d_sw.cpp
+++ b/servers/physics_2d/step_2d_sw.cpp
@@ -222,7 +222,7 @@ void Step2DSW::step(Space2DSW *p_space, real_t p_delta, int p_iterations) {
Constraint2DSW *prev_ci = NULL;
while (ci) {
- if (_setup_island(ci, p_delta) == true) {
+ if (_setup_island(ci, p_delta)) {
//removed the root from the island graph because it is not to be processed
diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h
index 207f13ac1a..8c3736a1bf 100644
--- a/servers/visual/rasterizer.h
+++ b/servers/visual/rasterizer.h
@@ -1104,6 +1104,7 @@ public:
virtual void restore_render_target() = 0;
virtual void clear_render_target(const Color &p_color) = 0;
virtual void blit_render_target_to_screen(RID p_render_target, const Rect2 &p_screen_rect, int p_screen = 0) = 0;
+ virtual void output_lens_distorted_to_screen(RID p_render_target, const Rect2 &p_screen_rect, float p_k1, float p_k2, const Vector2 &p_eye_center, float p_oversample) = 0;
virtual void end_frame(bool p_swap_buffers) = 0;
virtual void finalize() = 0;
diff --git a/servers/visual/visual_server_scene.cpp b/servers/visual/visual_server_scene.cpp
index cd0702d20b..654994b83f 100644
--- a/servers/visual/visual_server_scene.cpp
+++ b/servers/visual/visual_server_scene.cpp
@@ -2831,7 +2831,7 @@ void VisualServerScene::_bake_gi_probe(Instance *p_gi_probe) {
RID rid = E->key();
const InstanceGIProbeData::LightCache &lc = E->get();
- if ((!probe_data->dynamic.light_cache_changes.has(rid) || !(probe_data->dynamic.light_cache_changes[rid] == lc)) && lc.visible) {
+ if ((!probe_data->dynamic.light_cache_changes.has(rid) || probe_data->dynamic.light_cache_changes[rid] != lc) && lc.visible) {
//erase light data
_bake_gi_probe_light(header, cells, local_data, leaves, leaf_count, lc, -1);
@@ -2844,7 +2844,7 @@ void VisualServerScene::_bake_gi_probe(Instance *p_gi_probe) {
RID rid = E->key();
const InstanceGIProbeData::LightCache &lc = E->get();
- if ((!probe_data->dynamic.light_cache.has(rid) || !(probe_data->dynamic.light_cache[rid] == lc)) && lc.visible) {
+ if ((!probe_data->dynamic.light_cache.has(rid) || probe_data->dynamic.light_cache[rid] != lc) && lc.visible) {
//add light data
_bake_gi_probe_light(header, cells, local_data, leaves, leaf_count, lc, 1);
@@ -3061,7 +3061,7 @@ bool VisualServerScene::_check_gi_probe(Instance *p_gi_probe) {
lc.transform = probe_data->dynamic.light_to_cell_xform * E->get()->transform;
lc.visible = E->get()->visible;
- if (!probe_data->dynamic.light_cache.has(E->get()->self) || !(probe_data->dynamic.light_cache[E->get()->self] == lc)) {
+ if (!probe_data->dynamic.light_cache.has(E->get()->self) || probe_data->dynamic.light_cache[E->get()->self] != lc) {
all_equal = false;
}
@@ -3081,7 +3081,7 @@ bool VisualServerScene::_check_gi_probe(Instance *p_gi_probe) {
lc.transform = probe_data->dynamic.light_to_cell_xform * E->get()->transform;
lc.visible = E->get()->visible;
- if (!probe_data->dynamic.light_cache.has(E->get()->self) || !(probe_data->dynamic.light_cache[E->get()->self] == lc)) {
+ if (!probe_data->dynamic.light_cache.has(E->get()->self) || probe_data->dynamic.light_cache[E->get()->self] != lc) {
all_equal = false;
}
@@ -3164,7 +3164,7 @@ void VisualServerScene::render_probes() {
force_lighting = true;
}
- if (probe->invalid == false && probe->dynamic.enabled) {
+ if (!probe->invalid && probe->dynamic.enabled) {
switch (probe->dynamic.updating_stage) {
case GI_UPDATE_STAGE_CHECK: {
diff --git a/servers/visual/visual_server_scene.h b/servers/visual/visual_server_scene.h
index 87e19bc6b0..0d4737f268 100644
--- a/servers/visual/visual_server_scene.h
+++ b/servers/visual/visual_server_scene.h
@@ -355,6 +355,11 @@ public:
visible == p_cache.visible);
}
+ bool operator!=(const LightCache &p_cache) {
+
+ return !operator==(p_cache);
+ }
+
LightCache() {
type = VS::LIGHT_DIRECTIONAL;
@@ -544,7 +549,7 @@ public:
bool free(RID p_rid);
VisualServerScene();
- ~VisualServerScene();
+ virtual ~VisualServerScene();
};
#endif // VISUALSERVERSCENE_H
diff --git a/servers/visual/visual_server_viewport.h b/servers/visual/visual_server_viewport.h
index 978d6ae4ae..cb7912d6f4 100644
--- a/servers/visual/visual_server_viewport.h
+++ b/servers/visual/visual_server_viewport.h
@@ -194,6 +194,7 @@ public:
bool free(RID p_rid);
VisualServerViewport();
+ virtual ~VisualServerViewport() {}
};
#endif // VISUALSERVERVIEWPORT_H
diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp
index 18a239b019..9d684d33d6 100644
--- a/servers/visual_server.cpp
+++ b/servers/visual_server.cpp
@@ -2283,7 +2283,7 @@ void VisualServer::_bind_methods() {
BIND_ENUM_CONSTANT(GLOW_BLEND_MODE_REPLACE);
BIND_ENUM_CONSTANT(ENV_TONE_MAPPER_LINEAR);
- BIND_ENUM_CONSTANT(ENV_TONE_MAPPER_REINHARDT);
+ BIND_ENUM_CONSTANT(ENV_TONE_MAPPER_REINHARD);
BIND_ENUM_CONSTANT(ENV_TONE_MAPPER_FILMIC);
BIND_ENUM_CONSTANT(ENV_TONE_MAPPER_ACES);
diff --git a/servers/visual_server.h b/servers/visual_server.h
index 100bc06db6..9d98fca21b 100644
--- a/servers/visual_server.h
+++ b/servers/visual_server.h
@@ -737,7 +737,7 @@ public:
enum EnvironmentToneMapper {
ENV_TONE_MAPPER_LINEAR,
- ENV_TONE_MAPPER_REINHARDT,
+ ENV_TONE_MAPPER_REINHARD,
ENV_TONE_MAPPER_FILMIC,
ENV_TONE_MAPPER_ACES
};