Merge pull request #75786 from YuriSizov/4.0-cherrypicks
Cherry-picks for the 4.0 branch (future 4.0.3) - 1st batch
This commit is contained in:
commit
16a6bdd423
3
.github/workflows/android_builds.yml
vendored
3
.github/workflows/android_builds.yml
vendored
@ -1,5 +1,6 @@
|
||||
name: 🤖 Android Builds
|
||||
on: [push, pull_request]
|
||||
on:
|
||||
workflow_call:
|
||||
|
||||
# Global Settings
|
||||
env:
|
||||
|
3
.github/workflows/ios_builds.yml
vendored
3
.github/workflows/ios_builds.yml
vendored
@ -1,5 +1,6 @@
|
||||
name: 🍏 iOS Builds
|
||||
on: [push, pull_request]
|
||||
on:
|
||||
workflow_call:
|
||||
|
||||
# Global Settings
|
||||
env:
|
||||
|
3
.github/workflows/linux_builds.yml
vendored
3
.github/workflows/linux_builds.yml
vendored
@ -1,5 +1,6 @@
|
||||
name: 🐧 Linux Builds
|
||||
on: [push, pull_request]
|
||||
on:
|
||||
workflow_call:
|
||||
|
||||
# Global Settings
|
||||
env:
|
||||
|
3
.github/workflows/macos_builds.yml
vendored
3
.github/workflows/macos_builds.yml
vendored
@ -1,5 +1,6 @@
|
||||
name: 🍎 macOS Builds
|
||||
on: [push, pull_request]
|
||||
on:
|
||||
workflow_call:
|
||||
|
||||
# Global Settings
|
||||
env:
|
||||
|
41
.github/workflows/runner.yml
vendored
Normal file
41
.github/workflows/runner.yml
vendored
Normal file
@ -0,0 +1,41 @@
|
||||
name: 🔗 GHA
|
||||
on: [push, pull_request]
|
||||
|
||||
concurrency:
|
||||
group: ci-${{github.actor}}-${{github.head_ref || github.run_number}}-${{github.ref}}-runner
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
static-checks:
|
||||
name: 📊 Static
|
||||
uses: ./.github/workflows/static_checks.yml
|
||||
|
||||
android-build:
|
||||
name: 🤖 Android
|
||||
needs: static-checks
|
||||
uses: ./.github/workflows/android_builds.yml
|
||||
|
||||
ios-build:
|
||||
name: 🍏 iOS
|
||||
needs: static-checks
|
||||
uses: ./.github/workflows/ios_builds.yml
|
||||
|
||||
linux-build:
|
||||
name: 🐧 Linux
|
||||
needs: static-checks
|
||||
uses: ./.github/workflows/linux_builds.yml
|
||||
|
||||
macos-build:
|
||||
name: 🍎 macOS
|
||||
needs: static-checks
|
||||
uses: ./.github/workflows/macos_builds.yml
|
||||
|
||||
windows-build:
|
||||
name: 🏁 Windows
|
||||
needs: static-checks
|
||||
uses: ./.github/workflows/windows_builds.yml
|
||||
|
||||
web-build:
|
||||
name: 🌐 Web
|
||||
needs: static-checks
|
||||
uses: ./.github/workflows/web_builds.yml
|
6
.github/workflows/static_checks.yml
vendored
6
.github/workflows/static_checks.yml
vendored
@ -1,5 +1,6 @@
|
||||
name: 📊 Static Checks
|
||||
on: [push, pull_request]
|
||||
on:
|
||||
workflow_call:
|
||||
|
||||
concurrency:
|
||||
group: ci-${{github.actor}}-${{github.head_ref || github.run_number}}-${{github.ref}}-static
|
||||
@ -21,7 +22,8 @@ jobs:
|
||||
sudo apt-get install -qq dos2unix clang-format-15 libxml2-utils python3-pip moreutils
|
||||
sudo update-alternatives --remove-all clang-format || true
|
||||
sudo update-alternatives --install /usr/bin/clang-format clang-format /usr/bin/clang-format-15 100
|
||||
sudo pip3 install black==22.3.0 pygments pytest==7.1.2 mypy==0.971
|
||||
sudo pip3 install black==22.3.0 pytest==7.1.2 mypy==0.971
|
||||
git config diff.wsErrorHighlight all
|
||||
|
||||
- name: File formatting checks (file_format.sh)
|
||||
run: |
|
||||
|
3
.github/workflows/web_builds.yml
vendored
3
.github/workflows/web_builds.yml
vendored
@ -1,5 +1,6 @@
|
||||
name: 🌐 Web Builds
|
||||
on: [push, pull_request]
|
||||
on:
|
||||
workflow_call:
|
||||
|
||||
# Global Settings
|
||||
env:
|
||||
|
5
.github/workflows/windows_builds.yml
vendored
5
.github/workflows/windows_builds.yml
vendored
@ -1,5 +1,6 @@
|
||||
name: 🏁 Windows Builds
|
||||
on: [push, pull_request]
|
||||
on:
|
||||
workflow_call:
|
||||
|
||||
# Global Settings
|
||||
# SCONS_CACHE for windows must be set in the build environment
|
||||
@ -30,7 +31,7 @@ jobs:
|
||||
sconsflags: debug_symbols=no vsproj=yes
|
||||
bin: "./bin/godot.windows.editor.x86_64.exe"
|
||||
|
||||
- name: Template (target=template_release, tools=no)
|
||||
- name: Template (target=template_release)
|
||||
cache-name: windows-template
|
||||
target: template_release
|
||||
tests: false
|
||||
|
118
CHANGELOG.md
118
CHANGELOG.md
@ -4,6 +4,123 @@ All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||
|
||||
## [4.0.3] - TBD
|
||||
|
||||
See the [release announcement](https://godotengine.org/article/maintenance-release-godot-4-0-3) for details.
|
||||
|
||||
### Added
|
||||
|
||||
#### Editor
|
||||
|
||||
- Properly remember snapping options per-project ([GH-74682](https://github.com/godotengine/godot/pull/74682)).
|
||||
- Remember directory when installing templates file ([GH-74735](https://github.com/godotengine/godot/pull/74735)).
|
||||
- Improve editor state initialization ([GH-75563](https://github.com/godotengine/godot/pull/75563)).
|
||||
|
||||
#### Navigation
|
||||
|
||||
- Navigation: Expose NavigationAgent path postprocessing and pathfinding algorithm options ([GH-75326](https://github.com/godotengine/godot/pull/75326)).
|
||||
|
||||
#### Physics
|
||||
|
||||
- Warn when a concave polygon is assigned to ConvexPolygonShape2D ([GH-56671](https://github.com/godotengine/godot/pull/56671)).
|
||||
|
||||
### Changed
|
||||
|
||||
#### 3D
|
||||
|
||||
- Use physical shortcuts for freelook navigation in the editor ([GH-73651](https://github.com/godotengine/godot/pull/73651)).
|
||||
|
||||
#### Buildsystem
|
||||
|
||||
- Wait for static check results before starting other CI builds ([GH-65232](https://github.com/godotengine/godot/pull/65232)).
|
||||
- Remove obsolete 'tools' in a CI workflow name ([GH-75687](https://github.com/godotengine/godot/pull/75687)).
|
||||
- Visibly print trailing whitespace when static checks fail ([GH-75700](https://github.com/godotengine/godot/pull/75700)).
|
||||
|
||||
#### C#/.NET
|
||||
|
||||
- Truncate instead of round in Vector2/3/4 to Vector2I/3I/4I conversion ([GH-75477](https://github.com/godotengine/godot/pull/75477)).
|
||||
|
||||
#### Editor
|
||||
|
||||
- Prevent off-screen controls in editor ([GH-73646](https://github.com/godotengine/godot/pull/73646)).
|
||||
- Re-enable script editor File menu shortcuts when the menu is hidden ([GH-74319](https://github.com/godotengine/godot/pull/74319)).
|
||||
- Prevent color conversion of the big Godot logo ([GH-75653](https://github.com/godotengine/godot/pull/75653)).
|
||||
|
||||
#### GUI
|
||||
|
||||
- Ignore invisible children of GraphNode for minimum size ([GH-72240](https://github.com/godotengine/godot/pull/72240)).
|
||||
- Update `TextureProgressBar` upon texture changes ([GH-75532](https://github.com/godotengine/godot/pull/75532)).
|
||||
- Keep a copy of UTF-8 XML source string during the SVG font processing ([GH-75675](https://github.com/godotengine/godot/pull/75675)).
|
||||
|
||||
#### Import
|
||||
|
||||
- gltf: Remove obsolete hack to embed gltf textures in advanced import ([GH-75636](https://github.com/godotengine/godot/pull/75636)).
|
||||
|
||||
#### Physics
|
||||
|
||||
- Modify contact_max_allowed_penetration precision to 3 significant digits ([GH-75665](https://github.com/godotengine/godot/pull/75665)).
|
||||
|
||||
#### Rendering
|
||||
|
||||
- Recreate swap chain when suboptimal to avoid error spam ([GH-72859](https://github.com/godotengine/godot/pull/72859)).
|
||||
|
||||
#### Thirdparty
|
||||
|
||||
- thorvg updated to 0.8.4.
|
||||
|
||||
### Fixed
|
||||
|
||||
#### 2D
|
||||
|
||||
- Fix RemoteTransform2D could fail to update AnimatableBody2D's position or rotation ([GH-75487](https://github.com/godotengine/godot/pull/75487)).
|
||||
|
||||
#### Audio
|
||||
|
||||
- Fix AudioStreamPlayer2D crash when PhysicsServer2D runs on thread ([GH-75728](https://github.com/godotengine/godot/pull/75728)).
|
||||
|
||||
#### Buildsystem
|
||||
|
||||
- Fix the Python type error when creating the .sln file ([GH-75309](https://github.com/godotengine/godot/pull/75309)).
|
||||
|
||||
#### Core
|
||||
|
||||
- Fix moving position indicator out of bounds in FileAccessMemory ([GH-75641](https://github.com/godotengine/godot/pull/75641)).
|
||||
|
||||
#### Editor
|
||||
|
||||
- Fix off-by-one issue where "Go to Line" dialog shows the incorrect line number ([GH-75523](https://github.com/godotengine/godot/pull/75523)).
|
||||
|
||||
#### GUI
|
||||
|
||||
- Fix commenting collapsed function issue ([GH-75070](https://github.com/godotengine/godot/pull/75070)).
|
||||
- Fix fill align and trim with enabled dropcap in `RichTextLabel` ([GH-75504](https://github.com/godotengine/godot/pull/75504)).
|
||||
- Fix descriptions not showing for theme properties ([GH-75559](https://github.com/godotengine/godot/pull/75559)).
|
||||
- Fix some theme values affect the editor by setting a default value for them ([GH-75566](https://github.com/godotengine/godot/pull/75566)).
|
||||
- Fix several GraphEdit operations at zoom levels other than 100% ([GH-75595](https://github.com/godotengine/godot/pull/75595)).
|
||||
|
||||
#### Import
|
||||
|
||||
- SVG: fix tvg::Picture->size() and scale based errors. ([GH-75034](https://github.com/godotengine/godot/pull/75034)).
|
||||
|
||||
#### Input
|
||||
|
||||
- Fix guide button detection with XInput and Xbox Series controllers ([GH-73200](https://github.com/godotengine/godot/pull/73200)).
|
||||
- Fix the issue preventing dragging in the 2D editor ([GH-75113](https://github.com/godotengine/godot/pull/75113)).
|
||||
- Fix keycode/physical keycode mix up on web ([GH-75738](https://github.com/godotengine/godot/pull/75738)).
|
||||
|
||||
#### Navigation
|
||||
|
||||
- Navigation: Fix NavigationObstacles not being added to avoidance simulation ([GH-75756](https://github.com/godotengine/godot/pull/75756)).
|
||||
|
||||
#### Porting
|
||||
|
||||
- Windows: Fix clipboard relying on focused window ([GH-73878](https://github.com/godotengine/godot/pull/73878)).
|
||||
|
||||
#### Rendering
|
||||
|
||||
- Fix interpolation of R0 for metallic and calculation of the Fresnel Shlick term in SSR ([GH-75368](https://github.com/godotengine/godot/pull/75368)).
|
||||
|
||||
|
||||
## [4.0.2] - 2023-04-04
|
||||
|
||||
See the [release announcement](https://godotengine.org/article/maintenance-release-godot-4-0-2) for details.
|
||||
@ -2817,6 +2934,7 @@ See the [release announcement](https://godotengine.org/article/godot-3-3-has-arr
|
||||
- Only WebAssembly is supported now, since all browsers supporting WebGL 2.0 also support WebAssembly.
|
||||
|
||||
|
||||
[4.0.3]: https://github.com/godotengine/godot/compare/4.0.2-stable...4.0.3-stable
|
||||
[4.0.2]: https://github.com/godotengine/godot/compare/4.0.1-stable...4.0.2-stable
|
||||
[4.0.1]: https://github.com/godotengine/godot/compare/4.0-stable...4.0.1-stable
|
||||
[4.0]: https://github.com/godotengine/godot/compare/3.2-stable...4.0-stable
|
||||
|
@ -2,7 +2,7 @@
|
||||
# Source: https://github.com/godotengine/godot
|
||||
|
||||
# Windows
|
||||
__XINPUT_DEVICE__,XInput Gamepad,a:b12,b:b13,x:b14,y:b15,start:b4,back:b5,leftstick:b6,rightstick:b7,leftshoulder:b8,rightshoulder:b9,dpup:b0,dpdown:b1,dpleft:b2,dpright:b3,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,platform:Windows,
|
||||
__XINPUT_DEVICE__,XInput Gamepad,a:b12,b:b13,x:b14,y:b15,start:b4,guide:b10,back:b5,leftstick:b6,rightstick:b7,leftshoulder:b8,rightshoulder:b9,dpup:b0,dpdown:b1,dpleft:b2,dpright:b3,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,platform:Windows,
|
||||
|
||||
# Android
|
||||
Default Android Gamepad,Default Controller,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b8,rightshoulder:b10,rightx:a2,start:b6,righty:a3,dpleft:h0.8,lefttrigger:a4,x:b2,dpup:h0.1,back:b4,leftstick:b7,leftshoulder:b9,y:b3,a:b0,dpright:h0.2,righttrigger:a5,b:b1,platform:Android,
|
||||
|
@ -474,10 +474,15 @@ String InputEventKey::to_string() {
|
||||
return vformat("InputEventKey: keycode=%s, mods=%s, physical=%s, pressed=%s, echo=%s", kc, mods, physical, p, e);
|
||||
}
|
||||
|
||||
Ref<InputEventKey> InputEventKey::create_reference(Key p_keycode) {
|
||||
Ref<InputEventKey> InputEventKey::create_reference(Key p_keycode, bool p_physical) {
|
||||
Ref<InputEventKey> ie;
|
||||
ie.instantiate();
|
||||
ie->set_keycode(p_keycode & KeyModifierMask::CODE_MASK);
|
||||
if (p_physical) {
|
||||
ie->set_physical_keycode(p_keycode & KeyModifierMask::CODE_MASK);
|
||||
} else {
|
||||
ie->set_keycode(p_keycode & KeyModifierMask::CODE_MASK);
|
||||
}
|
||||
|
||||
ie->set_unicode(char32_t(p_keycode & KeyModifierMask::CODE_MASK));
|
||||
|
||||
if ((p_keycode & KeyModifierMask::SHIFT) != Key::NONE) {
|
||||
|
@ -195,7 +195,7 @@ public:
|
||||
virtual String as_text() const override;
|
||||
virtual String to_string() override;
|
||||
|
||||
static Ref<InputEventKey> create_reference(Key p_keycode_with_modifier_masks);
|
||||
static Ref<InputEventKey> create_reference(Key p_keycode_with_modifier_masks, bool p_physical = false);
|
||||
|
||||
InputEventKey() {}
|
||||
};
|
||||
|
@ -144,7 +144,7 @@ uint64_t FileAccessMemory::get_buffer(uint8_t *p_dst, uint64_t p_length) const {
|
||||
}
|
||||
|
||||
memcpy(p_dst, &data[pos], read);
|
||||
pos += p_length;
|
||||
pos += read;
|
||||
|
||||
return read;
|
||||
}
|
||||
@ -172,5 +172,5 @@ void FileAccessMemory::store_buffer(const uint8_t *p_src, uint64_t p_length) {
|
||||
}
|
||||
|
||||
memcpy(&data[pos], p_src, write);
|
||||
pos += p_length;
|
||||
pos += write;
|
||||
}
|
||||
|
@ -5,10 +5,11 @@
|
||||
</brief_description>
|
||||
<description>
|
||||
A cubemap that is loaded from a [code].ccube[/code] file. This file format is internal to Godot; it is created by importing other image formats with the import system. [CompressedCubemap] can use one of 4 compresson methods:
|
||||
- Uncompressed (uncompressed on the GPU)
|
||||
- Lossless (WebP or PNG, uncompressed on the GPU)
|
||||
- Lossy (WebP, uncompressed on the GPU)
|
||||
- VRAM Compressed (compressed on the GPU)
|
||||
- VRAM Uncompressed (uncompressed on the GPU)
|
||||
- Basis Universal (compressed on the GPU. Lower file sizes than VRAM Compressed, but slower to compress and lower quality than VRAM Compressed)
|
||||
Only [b]VRAM Compressed[/b] actually reduces the memory usage on the GPU. The [b]Lossless[/b] and [b]Lossy[/b] compression methods will reduce the required storage on disk, but they will not reduce memory usage on the GPU as the texture is sent to the GPU uncompressed.
|
||||
Using [b]VRAM Compressed[/b] also improves loading times, as VRAM-compressed textures are faster to load compared to textures using lossless or lossy compression. VRAM compression can exhibit noticeable artifacts and is intended to be used for 3D rendering, not 2D.
|
||||
See [Cubemap] for a general description of cubemaps.
|
||||
|
@ -5,10 +5,11 @@
|
||||
</brief_description>
|
||||
<description>
|
||||
A cubemap array that is loaded from a [code].ccubearray[/code] file. This file format is internal to Godot; it is created by importing other image formats with the import system. [CompressedCubemapArray] can use one of 4 compresson methods:
|
||||
- Uncompressed (uncompressed on the GPU)
|
||||
- Lossless (WebP or PNG, uncompressed on the GPU)
|
||||
- Lossy (WebP, uncompressed on the GPU)
|
||||
- VRAM Compressed (compressed on the GPU)
|
||||
- VRAM Uncompressed (uncompressed on the GPU)
|
||||
- Basis Universal (compressed on the GPU. Lower file sizes than VRAM Compressed, but slower to compress and lower quality than VRAM Compressed)
|
||||
Only [b]VRAM Compressed[/b] actually reduces the memory usage on the GPU. The [b]Lossless[/b] and [b]Lossy[/b] compression methods will reduce the required storage on disk, but they will not reduce memory usage on the GPU as the texture is sent to the GPU uncompressed.
|
||||
Using [b]VRAM Compressed[/b] also improves loading times, as VRAM-compressed textures are faster to load compared to textures using lossless or lossy compression. VRAM compression can exhibit noticeable artifacts and is intended to be used for 3D rendering, not 2D.
|
||||
See [CubemapArray] for a general description of cubemap arrays.
|
||||
|
@ -5,10 +5,11 @@
|
||||
</brief_description>
|
||||
<description>
|
||||
A texture that is loaded from a [code].ctex[/code] file. This file format is internal to Godot; it is created by importing other image formats with the import system. [CompressedTexture2D] can use one of 4 compression methods (including a lack of any compression):
|
||||
- Uncompressed (uncompressed on the GPU)
|
||||
- Lossless (WebP or PNG, uncompressed on the GPU)
|
||||
- Lossy (WebP, uncompressed on the GPU)
|
||||
- VRAM Compressed (compressed on the GPU)
|
||||
- VRAM Uncompressed (uncompressed on the GPU)
|
||||
- Basis Universal (compressed on the GPU. Lower file sizes than VRAM Compressed, but slower to compress and lower quality than VRAM Compressed)
|
||||
Only [b]VRAM Compressed[/b] actually reduces the memory usage on the GPU. The [b]Lossless[/b] and [b]Lossy[/b] compression methods will reduce the required storage on disk, but they will not reduce memory usage on the GPU as the texture is sent to the GPU uncompressed.
|
||||
Using [b]VRAM Compressed[/b] also improves loading times, as VRAM-compressed textures are faster to load compared to textures using lossless or lossy compression. VRAM compression can exhibit noticeable artifacts and is intended to be used for 3D rendering, not 2D.
|
||||
</description>
|
||||
|
@ -5,10 +5,11 @@
|
||||
</brief_description>
|
||||
<description>
|
||||
A texture array that is loaded from a [code].ctexarray[/code] file. This file format is internal to Godot; it is created by importing other image formats with the import system. [CompressedTexture2DArray] can use one of 4 compresson methods:
|
||||
- Uncompressed (uncompressed on the GPU)
|
||||
- Lossless (WebP or PNG, uncompressed on the GPU)
|
||||
- Lossy (WebP, uncompressed on the GPU)
|
||||
- VRAM Compressed (compressed on the GPU)
|
||||
- VRAM Uncompressed (uncompressed on the GPU)
|
||||
- Basis Universal (compressed on the GPU. Lower file sizes than VRAM Compressed, but slower to compress and lower quality than VRAM Compressed)
|
||||
Only [b]VRAM Compressed[/b] actually reduces the memory usage on the GPU. The [b]Lossless[/b] and [b]Lossy[/b] compression methods will reduce the required storage on disk, but they will not reduce memory usage on the GPU as the texture is sent to the GPU uncompressed.
|
||||
Using [b]VRAM Compressed[/b] also improves loading times, as VRAM-compressed textures are faster to load compared to textures using lossless or lossy compression. VRAM compression can exhibit noticeable artifacts and is intended to be used for 3D rendering, not 2D.
|
||||
See [Texture2DArray] for a general description of texture arrays.
|
||||
|
@ -4,13 +4,7 @@
|
||||
Base class for texture arrays that can optionally be compressed.
|
||||
</brief_description>
|
||||
<description>
|
||||
A texture array that is loaded from a [code].ctexarray[/code] file. This file format is internal to Godot; it is created by importing other image formats with the import system. [CompressedTexture2D] can use one of 4 compresson methods:
|
||||
- Uncompressed (uncompressed on the GPU)
|
||||
- Lossless (WebP or PNG, uncompressed on the GPU)
|
||||
- Lossy (WebP, uncompressed on the GPU)
|
||||
- VRAM Compressed (compressed on the GPU)
|
||||
Only [b]VRAM Compressed[/b] actually reduces the memory usage on the GPU. The [b]Lossless[/b] and [b]Lossy[/b] compression methods will reduce the required storage on disk, but they will not reduce memory usage on the GPU as the texture is sent to the GPU uncompressed.
|
||||
Using [b]VRAM Compressed[/b] also improves loading times, as VRAM-compressed textures are faster to load compared to textures using lossless or lossy compression. VRAM compression can exhibit noticeable artifacts and is intended to be used for 3D rendering, not 2D.
|
||||
Base class for [CompressedTexture2DArray] and [CompressedTexture3D]. Cannot be used directly, but contains all the functions necessary for accessing the derived resource types. See also [TextureLayered].
|
||||
</description>
|
||||
<tutorials>
|
||||
</tutorials>
|
||||
|
@ -147,6 +147,12 @@
|
||||
<member name="path_metadata_flags" type="int" setter="set_path_metadata_flags" getter="get_path_metadata_flags" enum="NavigationPathQueryParameters2D.PathMetadataFlags" default="7">
|
||||
Additional information to return with the navigation path.
|
||||
</member>
|
||||
<member name="path_postprocessing" type="int" setter="set_path_postprocessing" getter="get_path_postprocessing" enum="NavigationPathQueryParameters2D.PathPostProcessing" default="0">
|
||||
The path postprocessing applied to the raw path corridor found by the [member pathfinding_algorithm].
|
||||
</member>
|
||||
<member name="pathfinding_algorithm" type="int" setter="set_pathfinding_algorithm" getter="get_pathfinding_algorithm" enum="NavigationPathQueryParameters2D.PathfindingAlgorithm" default="0">
|
||||
The pathfinding algorithm used in the path query.
|
||||
</member>
|
||||
<member name="radius" type="float" setter="set_radius" getter="get_radius" default="10.0">
|
||||
The radius of the avoidance agent. This is the "body" of the avoidance agent and not the avoidance maneuver starting radius (which is controlled by [member neighbor_distance]).
|
||||
Does not affect normal pathfinding. To change an actor's pathfinding radius bake [NavigationMesh] resources with a different [member NavigationMesh.agent_radius] property and use different navigation maps for each actor size.
|
||||
|
@ -150,6 +150,12 @@
|
||||
<member name="path_metadata_flags" type="int" setter="set_path_metadata_flags" getter="get_path_metadata_flags" enum="NavigationPathQueryParameters3D.PathMetadataFlags" default="7">
|
||||
Additional information to return with the navigation path.
|
||||
</member>
|
||||
<member name="path_postprocessing" type="int" setter="set_path_postprocessing" getter="get_path_postprocessing" enum="NavigationPathQueryParameters3D.PathPostProcessing" default="0">
|
||||
The path postprocessing applied to the raw path corridor found by the [member pathfinding_algorithm].
|
||||
</member>
|
||||
<member name="pathfinding_algorithm" type="int" setter="set_pathfinding_algorithm" getter="get_pathfinding_algorithm" enum="NavigationPathQueryParameters3D.PathfindingAlgorithm" default="0">
|
||||
The pathfinding algorithm used in the path query.
|
||||
</member>
|
||||
<member name="radius" type="float" setter="set_radius" getter="get_radius" default="0.5">
|
||||
The radius of the avoidance agent. This is the "body" of the avoidance agent and not the avoidance maneuver starting radius (which is controlled by [member neighbor_distance]).
|
||||
Does not affect normal pathfinding. To change an actor's pathfinding radius bake [NavigationMesh] resources with a different [member NavigationMesh.agent_radius] property and use different navigation maps for each actor size.
|
||||
|
@ -4,7 +4,7 @@
|
||||
Base class for texture types which contain the data of multiple [Image]s. Each image is of the same size and format.
|
||||
</brief_description>
|
||||
<description>
|
||||
Base class for [ImageTextureLayered]. Cannot be used directly, but contains all the functions necessary for accessing the derived resource types. See also [Texture3D].
|
||||
Base class for [ImageTextureLayered] and [CompressedTextureLayered]. Cannot be used directly, but contains all the functions necessary for accessing the derived resource types. See also [Texture3D].
|
||||
Data is set on a per-layer basis. For [Texture2DArray]s, the layer specifies the array layer.
|
||||
All images need to have the same width, height and number of mipmap levels.
|
||||
A [TextureLayered] can be loaded with [method ResourceLoader.load].
|
||||
|
@ -31,7 +31,7 @@
|
||||
<return type="Vector2i" />
|
||||
<param index="0" name="from" type="Vector2" />
|
||||
<description>
|
||||
Constructs a new [Vector2i] from [Vector2]. The floating point coordinates will be truncated.
|
||||
Constructs a new [Vector2i] from the given [Vector2] by truncating components' fractional parts (rounding towards zero). For a different behavior consider passing the result of [method Vector2.ceil], [method Vector2.floor] or [method Vector2.round] to this constructor instead.
|
||||
</description>
|
||||
</constructor>
|
||||
<constructor name="Vector2i">
|
||||
|
@ -31,7 +31,7 @@
|
||||
<return type="Vector3i" />
|
||||
<param index="0" name="from" type="Vector3" />
|
||||
<description>
|
||||
Constructs a new [Vector3i] from [Vector3]. The floating point coordinates will be truncated.
|
||||
Constructs a new [Vector3i] from the given [Vector3] by truncating components' fractional parts (rounding towards zero). For a different behavior consider passing the result of [method Vector3.ceil], [method Vector3.floor] or [method Vector3.round] to this constructor instead.
|
||||
</description>
|
||||
</constructor>
|
||||
<constructor name="Vector3i">
|
||||
|
@ -27,7 +27,7 @@
|
||||
<return type="Vector4i" />
|
||||
<param index="0" name="from" type="Vector4" />
|
||||
<description>
|
||||
Constructs a new [Vector4i] from the given [Vector4].
|
||||
Constructs a new [Vector4i] from the given [Vector4] by truncating components' fractional parts (rounding towards zero). For a different behavior consider passing the result of [method Vector4.ceil], [method Vector4.floor] or [method Vector4.round] to this constructor instead.
|
||||
</description>
|
||||
</constructor>
|
||||
<constructor name="Vector4i">
|
||||
|
@ -2274,8 +2274,8 @@ Error VulkanContext::prepare_buffers() {
|
||||
} else if (err == VK_SUBOPTIMAL_KHR) {
|
||||
// Swapchain is not as optimal as it could be, but the platform's
|
||||
// presentation engine will still present the image correctly.
|
||||
print_verbose("Vulkan: Early suboptimal swapchain.");
|
||||
break;
|
||||
print_verbose("Vulkan: Early suboptimal swapchain, recreating.");
|
||||
_update_swap_chain(w);
|
||||
} else if (err != VK_SUCCESS) {
|
||||
ERR_BREAK_MSG(err != VK_SUCCESS, "Vulkan: Did not create swapchain successfully. Error code: " + String(string_VkResult(err)));
|
||||
} else {
|
||||
|
@ -42,7 +42,8 @@
|
||||
void GotoLineDialog::popup_find_line(CodeEdit *p_edit) {
|
||||
text_editor = p_edit;
|
||||
|
||||
line->set_text(itos(text_editor->get_caret_line()));
|
||||
// Add 1 because text_editor->get_caret_line() starts from 0, but the editor user interface starts from 1.
|
||||
line->set_text(itos(text_editor->get_caret_line() + 1));
|
||||
line->select_all();
|
||||
popup_centered(Size2(180, 80) * EDSCALE);
|
||||
line->grab_focus();
|
||||
@ -53,12 +54,14 @@ int GotoLineDialog::get_line() const {
|
||||
}
|
||||
|
||||
void GotoLineDialog::ok_pressed() {
|
||||
if (get_line() < 1 || get_line() > text_editor->get_line_count()) {
|
||||
// Subtract 1 because the editor user interface starts from 1, but text_editor->set_caret_line(n) starts from 0.
|
||||
const int line_number = get_line() - 1;
|
||||
if (line_number < 0 || line_number >= text_editor->get_line_count()) {
|
||||
return;
|
||||
}
|
||||
text_editor->remove_secondary_carets();
|
||||
text_editor->unfold_line(get_line() - 1);
|
||||
text_editor->set_caret_line(get_line() - 1);
|
||||
text_editor->unfold_line(line_number);
|
||||
text_editor->set_caret_line(line_number);
|
||||
hide();
|
||||
}
|
||||
|
||||
@ -1092,13 +1095,13 @@ void CodeTextEditor::remove_find_replace_bar() {
|
||||
}
|
||||
|
||||
void CodeTextEditor::trim_trailing_whitespace() {
|
||||
bool trimed_whitespace = false;
|
||||
bool trimmed_whitespace = false;
|
||||
for (int i = 0; i < text_editor->get_line_count(); i++) {
|
||||
String line = text_editor->get_line(i);
|
||||
if (line.ends_with(" ") || line.ends_with("\t")) {
|
||||
if (!trimed_whitespace) {
|
||||
if (!trimmed_whitespace) {
|
||||
text_editor->begin_complex_operation();
|
||||
trimed_whitespace = true;
|
||||
trimmed_whitespace = true;
|
||||
}
|
||||
|
||||
int end = 0;
|
||||
@ -1112,7 +1115,7 @@ void CodeTextEditor::trim_trailing_whitespace() {
|
||||
}
|
||||
}
|
||||
|
||||
if (trimed_whitespace) {
|
||||
if (trimmed_whitespace) {
|
||||
text_editor->merge_overlapping_carets();
|
||||
text_editor->end_complex_operation();
|
||||
text_editor->queue_redraw();
|
||||
@ -1584,11 +1587,17 @@ void CodeTextEditor::toggle_inline_comment(const String &delimiter) {
|
||||
Vector<int> caret_edit_order = text_editor->get_caret_index_edit_order();
|
||||
caret_edit_order.reverse();
|
||||
int last_line = -1;
|
||||
int folded_to = 0;
|
||||
for (const int &c1 : caret_edit_order) {
|
||||
int from = _get_affected_lines_from(c1);
|
||||
from += from == last_line ? 1 : 0;
|
||||
from += from == last_line ? 1 + folded_to : 0;
|
||||
int to = _get_affected_lines_to(c1);
|
||||
last_line = to;
|
||||
// If last line is folded, extends to the end of the folded section
|
||||
if (text_editor->is_line_folded(to)) {
|
||||
folded_to = text_editor->get_next_visible_line_offset_from(to + 1, 1) - 1;
|
||||
to += folded_to;
|
||||
}
|
||||
// Check first if there's any uncommented lines in selection.
|
||||
bool is_commented = true;
|
||||
for (int line = from; line <= to; line++) {
|
||||
|
@ -293,6 +293,13 @@ Dictionary EditorData::get_scene_editor_states(int p_idx) const {
|
||||
}
|
||||
|
||||
void EditorData::set_editor_states(const Dictionary &p_states) {
|
||||
if (p_states.is_empty()) {
|
||||
for (EditorPlugin *ep : editor_plugins) {
|
||||
ep->clear();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
List<Variant> keys;
|
||||
p_states.get_key_list(&keys);
|
||||
|
||||
|
@ -3133,6 +3133,11 @@ void EditorInspector::update_tree() {
|
||||
StringName propname = property_prefix + p.name;
|
||||
bool found = false;
|
||||
|
||||
// Small hack for theme_overrides. They are listed under Control, but come from another class.
|
||||
if (classname == "Control" && p.name.begins_with("theme_override_")) {
|
||||
classname = get_edited_object()->get_class();
|
||||
}
|
||||
|
||||
// Search for the property description in the cache.
|
||||
HashMap<StringName, HashMap<StringName, PropertyDocInfo>>::Iterator E = doc_info_cache.find(classname);
|
||||
if (E) {
|
||||
|
@ -1468,7 +1468,7 @@ Ref<Shortcut> ED_GET_SHORTCUT(const String &p_path) {
|
||||
return sc;
|
||||
}
|
||||
|
||||
void ED_SHORTCUT_OVERRIDE(const String &p_path, const String &p_feature, Key p_keycode) {
|
||||
void ED_SHORTCUT_OVERRIDE(const String &p_path, const String &p_feature, Key p_keycode, bool p_physical) {
|
||||
ERR_FAIL_NULL_MSG(EditorSettings::get_singleton(), "EditorSettings not instantiated yet.");
|
||||
|
||||
Ref<Shortcut> sc = EditorSettings::get_singleton()->get_shortcut(p_path);
|
||||
@ -1477,10 +1477,10 @@ void ED_SHORTCUT_OVERRIDE(const String &p_path, const String &p_feature, Key p_k
|
||||
PackedInt32Array arr;
|
||||
arr.push_back((int32_t)p_keycode);
|
||||
|
||||
ED_SHORTCUT_OVERRIDE_ARRAY(p_path, p_feature, arr);
|
||||
ED_SHORTCUT_OVERRIDE_ARRAY(p_path, p_feature, arr, p_physical);
|
||||
}
|
||||
|
||||
void ED_SHORTCUT_OVERRIDE_ARRAY(const String &p_path, const String &p_feature, const PackedInt32Array &p_keycodes) {
|
||||
void ED_SHORTCUT_OVERRIDE_ARRAY(const String &p_path, const String &p_feature, const PackedInt32Array &p_keycodes, bool p_physical) {
|
||||
ERR_FAIL_NULL_MSG(EditorSettings::get_singleton(), "EditorSettings not instantiated yet.");
|
||||
|
||||
Ref<Shortcut> sc = EditorSettings::get_singleton()->get_shortcut(p_path);
|
||||
@ -1505,7 +1505,7 @@ void ED_SHORTCUT_OVERRIDE_ARRAY(const String &p_path, const String &p_feature, c
|
||||
|
||||
Ref<InputEventKey> ie;
|
||||
if (keycode != Key::NONE) {
|
||||
ie = InputEventKey::create_reference(keycode);
|
||||
ie = InputEventKey::create_reference(keycode, p_physical);
|
||||
events.push_back(ie);
|
||||
}
|
||||
}
|
||||
@ -1518,13 +1518,13 @@ void ED_SHORTCUT_OVERRIDE_ARRAY(const String &p_path, const String &p_feature, c
|
||||
sc->set_meta("original", events.duplicate(true));
|
||||
}
|
||||
|
||||
Ref<Shortcut> ED_SHORTCUT(const String &p_path, const String &p_name, Key p_keycode) {
|
||||
Ref<Shortcut> ED_SHORTCUT(const String &p_path, const String &p_name, Key p_keycode, bool p_physical) {
|
||||
PackedInt32Array arr;
|
||||
arr.push_back((int32_t)p_keycode);
|
||||
return ED_SHORTCUT_ARRAY(p_path, p_name, arr);
|
||||
return ED_SHORTCUT_ARRAY(p_path, p_name, arr, p_physical);
|
||||
}
|
||||
|
||||
Ref<Shortcut> ED_SHORTCUT_ARRAY(const String &p_path, const String &p_name, const PackedInt32Array &p_keycodes) {
|
||||
Ref<Shortcut> ED_SHORTCUT_ARRAY(const String &p_path, const String &p_name, const PackedInt32Array &p_keycodes, bool p_physical) {
|
||||
Array events;
|
||||
|
||||
for (int i = 0; i < p_keycodes.size(); i++) {
|
||||
@ -1539,7 +1539,7 @@ Ref<Shortcut> ED_SHORTCUT_ARRAY(const String &p_path, const String &p_name, cons
|
||||
|
||||
Ref<InputEventKey> ie;
|
||||
if (keycode != Key::NONE) {
|
||||
ie = InputEventKey::create_reference(keycode);
|
||||
ie = InputEventKey::create_reference(keycode, p_physical);
|
||||
events.push_back(ie);
|
||||
}
|
||||
}
|
||||
|
@ -195,10 +195,10 @@ Variant _EDITOR_DEF(const String &p_setting, const Variant &p_default, bool p_re
|
||||
Variant _EDITOR_GET(const String &p_setting);
|
||||
|
||||
#define ED_IS_SHORTCUT(p_name, p_ev) (EditorSettings::get_singleton()->is_shortcut(p_name, p_ev))
|
||||
Ref<Shortcut> ED_SHORTCUT(const String &p_path, const String &p_name, Key p_keycode = Key::NONE);
|
||||
Ref<Shortcut> ED_SHORTCUT_ARRAY(const String &p_path, const String &p_name, const PackedInt32Array &p_keycodes);
|
||||
void ED_SHORTCUT_OVERRIDE(const String &p_path, const String &p_feature, Key p_keycode = Key::NONE);
|
||||
void ED_SHORTCUT_OVERRIDE_ARRAY(const String &p_path, const String &p_feature, const PackedInt32Array &p_keycodes);
|
||||
Ref<Shortcut> ED_SHORTCUT(const String &p_path, const String &p_name, Key p_keycode = Key::NONE, bool p_physical = false);
|
||||
Ref<Shortcut> ED_SHORTCUT_ARRAY(const String &p_path, const String &p_name, const PackedInt32Array &p_keycodes, bool p_physical = false);
|
||||
void ED_SHORTCUT_OVERRIDE(const String &p_path, const String &p_feature, Key p_keycode = Key::NONE, bool p_physical = false);
|
||||
void ED_SHORTCUT_OVERRIDE_ARRAY(const String &p_path, const String &p_feature, const PackedInt32Array &p_keycodes, bool p_physical = false);
|
||||
Ref<Shortcut> ED_GET_SHORTCUT(const String &p_path);
|
||||
|
||||
#endif // EDITOR_SETTINGS_H
|
||||
|
@ -859,6 +859,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
|
||||
theme->set_color("icon_pressed_color", "Button", icon_pressed_color);
|
||||
theme->set_color("icon_disabled_color", "Button", icon_disabled_color);
|
||||
|
||||
theme->set_constant("h_separation", "Button", 2 * EDSCALE);
|
||||
theme->set_constant("outline_size", "Button", 0 * EDSCALE);
|
||||
|
||||
const float ACTION_BUTTON_EXTRA_MARGIN = 32 * EDSCALE;
|
||||
@ -915,6 +916,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
|
||||
theme->set_color("icon_pressed_color", "MenuBar", icon_pressed_color);
|
||||
theme->set_color("icon_disabled_color", "MenuBar", icon_disabled_color);
|
||||
|
||||
theme->set_constant("h_separation", "MenuBar", 4 * EDSCALE);
|
||||
theme->set_constant("outline_size", "MenuBar", 0 * EDSCALE);
|
||||
|
||||
// OptionButton
|
||||
@ -1450,6 +1452,8 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
|
||||
theme->set_color("font_outline_color", "TextEdit", font_outline_color);
|
||||
theme->set_color("caret_color", "TextEdit", font_color);
|
||||
theme->set_color("selection_color", "TextEdit", selection_color);
|
||||
theme->set_color("background_color", "TextEdit", Color(0, 0, 0, 0));
|
||||
|
||||
theme->set_constant("line_spacing", "TextEdit", 4 * EDSCALE);
|
||||
theme->set_constant("outline_size", "TextEdit", 0 * EDSCALE);
|
||||
|
||||
|
@ -529,6 +529,7 @@ bool ExportTemplateManager::_install_file_selected(const String &p_file, bool p_
|
||||
unzClose(pkg);
|
||||
|
||||
_update_template_status();
|
||||
EditorSettings::get_singleton()->set_meta("export_template_download_directory", p_file.get_base_dir());
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -992,6 +993,7 @@ ExportTemplateManager::ExportTemplateManager() {
|
||||
install_file_dialog->set_title(TTR("Select Template File"));
|
||||
install_file_dialog->set_access(FileDialog::ACCESS_FILESYSTEM);
|
||||
install_file_dialog->set_file_mode(FileDialog::FILE_MODE_OPEN_FILE);
|
||||
install_file_dialog->set_current_dir(EditorSettings::get_singleton()->get_meta("export_template_download_directory", ""));
|
||||
install_file_dialog->add_filter("*.tpz", TTR("Godot Export Templates"));
|
||||
install_file_dialog->connect("file_selected", callable_mp(this, &ExportTemplateManager::_install_file_selected).bind(false));
|
||||
add_child(install_file_dialog);
|
||||
|
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
@ -2302,11 +2302,6 @@ Node *ResourceImporterScene::pre_import(const String &p_source_file, const HashM
|
||||
Error err = OK;
|
||||
HashMap<StringName, Variant> options_dupe = p_options;
|
||||
|
||||
// By default, the GLTF importer will extract embedded images into files on disk
|
||||
// However, we do not want the advanced settings dialog to be able to write files on disk.
|
||||
// To avoid this and also avoid compressing to basis every time, we are using the uncompressed option.
|
||||
options_dupe["gltf/embedded_image_handling"] = 3; // Embed as Uncompressed defined in GLTFState::GLTFHandleBinary::HANDLE_BINARY_EMBED_AS_UNCOMPRESSED
|
||||
|
||||
Node *scene = importer->import_scene(p_source_file, EditorSceneFormatImporter::IMPORT_ANIMATION | EditorSceneFormatImporter::IMPORT_GENERATE_TANGENT_ARRAYS, options_dupe, nullptr, &err);
|
||||
if (!scene || err != OK) {
|
||||
return nullptr;
|
||||
|
@ -895,6 +895,14 @@ void CanvasItemEditor::_commit_canvas_item_state(List<CanvasItem *> p_canvas_ite
|
||||
|
||||
void CanvasItemEditor::_snap_changed() {
|
||||
static_cast<SnapDialog *>(snap_dialog)->get_fields(grid_offset, grid_step, primary_grid_steps, snap_rotation_offset, snap_rotation_step, snap_scale_step);
|
||||
|
||||
EditorSettings::get_singleton()->set_project_metadata("2d_editor", "grid_offset", grid_offset);
|
||||
EditorSettings::get_singleton()->set_project_metadata("2d_editor", "grid_step", grid_step);
|
||||
EditorSettings::get_singleton()->set_project_metadata("2d_editor", "primary_grid_steps", primary_grid_steps);
|
||||
EditorSettings::get_singleton()->set_project_metadata("2d_editor", "snap_rotation_offset", snap_rotation_offset);
|
||||
EditorSettings::get_singleton()->set_project_metadata("2d_editor", "snap_rotation_step", snap_rotation_step);
|
||||
EditorSettings::get_singleton()->set_project_metadata("2d_editor", "snap_scale_step", snap_scale_step);
|
||||
|
||||
grid_step_multiplier = 0;
|
||||
viewport->queue_redraw();
|
||||
}
|
||||
@ -4683,7 +4691,6 @@ void CanvasItemEditor::_reset_drag() {
|
||||
void CanvasItemEditor::_bind_methods() {
|
||||
ClassDB::bind_method("_get_editor_data", &CanvasItemEditor::_get_editor_data);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_state"), &CanvasItemEditor::set_state);
|
||||
ClassDB::bind_method(D_METHOD("update_viewport"), &CanvasItemEditor::update_viewport);
|
||||
ClassDB::bind_method(D_METHOD("center_at", "position"), &CanvasItemEditor::center_at);
|
||||
|
||||
@ -4896,6 +4903,22 @@ void CanvasItemEditor::set_state(const Dictionary &p_state) {
|
||||
viewport->queue_redraw();
|
||||
}
|
||||
|
||||
void CanvasItemEditor::clear() {
|
||||
zoom = 1.0 / MAX(1, EDSCALE);
|
||||
zoom_widget->set_zoom(zoom);
|
||||
|
||||
view_offset = Point2(-150 - RULER_WIDTH, -95 - RULER_WIDTH);
|
||||
previous_update_view_offset = view_offset; // Moves the view a little bit to the left so that (0,0) is visible. The values a relative to a 16/10 screen.
|
||||
_update_scrollbars();
|
||||
|
||||
grid_offset = EditorSettings::get_singleton()->get_project_metadata("2d_editor", "grid_offset", Vector2());
|
||||
grid_step = EditorSettings::get_singleton()->get_project_metadata("2d_editor", "grid_step", Vector2(8, 8));
|
||||
primary_grid_steps = EditorSettings::get_singleton()->get_project_metadata("2d_editor", "primary_grid_steps", 8);
|
||||
snap_rotation_step = EditorSettings::get_singleton()->get_project_metadata("2d_editor", "snap_rotation_step", Math::deg_to_rad(15.0));
|
||||
snap_rotation_offset = EditorSettings::get_singleton()->get_project_metadata("2d_editor", "snap_rotation_offset", 0.0);
|
||||
snap_scale_step = EditorSettings::get_singleton()->get_project_metadata("2d_editor", "snap_scale_step", 0.1);
|
||||
}
|
||||
|
||||
void CanvasItemEditor::add_control_to_menu_panel(Control *p_control) {
|
||||
ERR_FAIL_COND(!p_control);
|
||||
|
||||
@ -4939,10 +4962,6 @@ void CanvasItemEditor::center_at(const Point2 &p_pos) {
|
||||
}
|
||||
|
||||
CanvasItemEditor::CanvasItemEditor() {
|
||||
zoom = 1.0 / MAX(1, EDSCALE);
|
||||
view_offset = Point2(-150 - RULER_WIDTH, -95 - RULER_WIDTH);
|
||||
previous_update_view_offset = view_offset; // Moves the view a little bit to the left so that (0,0) is visible. The values a relative to a 16/10 screen
|
||||
|
||||
snap_target[0] = SNAP_TARGET_NONE;
|
||||
snap_target[1] = SNAP_TARGET_NONE;
|
||||
|
||||
@ -5388,9 +5407,10 @@ CanvasItemEditor::CanvasItemEditor() {
|
||||
singleton = this;
|
||||
|
||||
set_process_shortcut_input(true);
|
||||
clear(); // Make sure values are initialized.
|
||||
|
||||
// Update the menus' checkboxes
|
||||
call_deferred(SNAME("set_state"), get_state());
|
||||
// Update the menus' checkboxes.
|
||||
callable_mp(this, &CanvasItemEditor::set_state).bind(get_state()).call_deferred();
|
||||
}
|
||||
|
||||
CanvasItemEditor *CanvasItemEditor::singleton = nullptr;
|
||||
@ -5426,6 +5446,10 @@ void CanvasItemEditorPlugin::set_state(const Dictionary &p_state) {
|
||||
canvas_item_editor->set_state(p_state);
|
||||
}
|
||||
|
||||
void CanvasItemEditorPlugin::clear() {
|
||||
canvas_item_editor->clear();
|
||||
}
|
||||
|
||||
void CanvasItemEditorPlugin::_notification(int p_what) {
|
||||
switch (p_what) {
|
||||
case NOTIFICATION_ENTER_TREE: {
|
||||
|
@ -211,15 +211,15 @@ private:
|
||||
|
||||
bool selected_from_canvas = false;
|
||||
|
||||
// Defaults are defined in clear().
|
||||
Point2 grid_offset;
|
||||
// A power-of-two value works better as a default grid size.
|
||||
Point2 grid_step = Point2(8, 8);
|
||||
int primary_grid_steps = 8;
|
||||
Point2 grid_step;
|
||||
int primary_grid_steps = 0;
|
||||
int grid_step_multiplier = 0;
|
||||
|
||||
real_t snap_rotation_step = Math::deg_to_rad(15.0);
|
||||
real_t snap_rotation_step = 0.0;
|
||||
real_t snap_rotation_offset = 0.0;
|
||||
real_t snap_scale_step = 0.1f;
|
||||
real_t snap_scale_step = 0.0;
|
||||
bool smart_snap_active = false;
|
||||
bool grid_snap_active = false;
|
||||
|
||||
@ -526,6 +526,7 @@ public:
|
||||
static CanvasItemEditor *get_singleton() { return singleton; }
|
||||
Dictionary get_state() const;
|
||||
void set_state(const Dictionary &p_state);
|
||||
void clear();
|
||||
|
||||
void add_control_to_menu_panel(Control *p_control);
|
||||
void remove_control_from_menu_panel(Control *p_control);
|
||||
@ -575,6 +576,7 @@ public:
|
||||
virtual void make_visible(bool p_visible) override;
|
||||
virtual Dictionary get_state() const override;
|
||||
virtual void set_state(const Dictionary &p_state) override;
|
||||
virtual void clear() override;
|
||||
|
||||
CanvasItemEditor *get_canvas_item_editor() { return canvas_item_editor; }
|
||||
|
||||
|
@ -4872,8 +4872,8 @@ void Node3DEditorViewport::finish_transform() {
|
||||
}
|
||||
|
||||
// Register a shortcut and also add it as an input action with the same events.
|
||||
void Node3DEditorViewport::register_shortcut_action(const String &p_path, const String &p_name, Key p_keycode) {
|
||||
Ref<Shortcut> sc = ED_SHORTCUT(p_path, p_name, p_keycode);
|
||||
void Node3DEditorViewport::register_shortcut_action(const String &p_path, const String &p_name, Key p_keycode, bool p_physical) {
|
||||
Ref<Shortcut> sc = ED_SHORTCUT(p_path, p_name, p_keycode, p_physical);
|
||||
shortcut_changed_callback(sc, p_path);
|
||||
// Connect to the change event on the shortcut so the input binding can be updated.
|
||||
sc->connect("changed", callable_mp(this, &Node3DEditorViewport::shortcut_changed_callback).bind(sc, p_path));
|
||||
@ -5054,12 +5054,12 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, int p
|
||||
view_menu->get_popup()->set_item_tooltip(shadeless_idx, unsupported_tooltip);
|
||||
}
|
||||
|
||||
register_shortcut_action("spatial_editor/freelook_left", TTR("Freelook Left"), Key::A);
|
||||
register_shortcut_action("spatial_editor/freelook_right", TTR("Freelook Right"), Key::D);
|
||||
register_shortcut_action("spatial_editor/freelook_forward", TTR("Freelook Forward"), Key::W);
|
||||
register_shortcut_action("spatial_editor/freelook_backwards", TTR("Freelook Backwards"), Key::S);
|
||||
register_shortcut_action("spatial_editor/freelook_up", TTR("Freelook Up"), Key::E);
|
||||
register_shortcut_action("spatial_editor/freelook_down", TTR("Freelook Down"), Key::Q);
|
||||
register_shortcut_action("spatial_editor/freelook_left", TTR("Freelook Left"), Key::A, true);
|
||||
register_shortcut_action("spatial_editor/freelook_right", TTR("Freelook Right"), Key::D, true);
|
||||
register_shortcut_action("spatial_editor/freelook_forward", TTR("Freelook Forward"), Key::W, true);
|
||||
register_shortcut_action("spatial_editor/freelook_backwards", TTR("Freelook Backwards"), Key::S, true);
|
||||
register_shortcut_action("spatial_editor/freelook_up", TTR("Freelook Up"), Key::E, true);
|
||||
register_shortcut_action("spatial_editor/freelook_down", TTR("Freelook Down"), Key::Q, true);
|
||||
register_shortcut_action("spatial_editor/freelook_speed_modifier", TTR("Freelook Speed Modifier"), Key::SHIFT);
|
||||
register_shortcut_action("spatial_editor/freelook_slow_modifier", TTR("Freelook Slow Modifier"), Key::ALT);
|
||||
|
||||
@ -5995,6 +5995,10 @@ void Node3DEditor::_snap_changed() {
|
||||
snap_translate_value = snap_translate->get_text().to_float();
|
||||
snap_rotate_value = snap_rotate->get_text().to_float();
|
||||
snap_scale_value = snap_scale->get_text().to_float();
|
||||
|
||||
EditorSettings::get_singleton()->set_project_metadata("3d_editor", "snap_translate_value", snap_translate_value);
|
||||
EditorSettings::get_singleton()->set_project_metadata("3d_editor", "snap_rotate_value", snap_rotate_value);
|
||||
EditorSettings::get_singleton()->set_project_metadata("3d_editor", "snap_scale_value", snap_scale_value);
|
||||
}
|
||||
|
||||
void Node3DEditor::_snap_update() {
|
||||
@ -7853,11 +7857,19 @@ void Node3DEditor::clear() {
|
||||
settings_znear->set_value(EDITOR_GET("editors/3d/default_z_near"));
|
||||
settings_zfar->set_value(EDITOR_GET("editors/3d/default_z_far"));
|
||||
|
||||
snap_translate_value = EditorSettings::get_singleton()->get_project_metadata("3d_editor", "snap_translate_value", 1);
|
||||
snap_rotate_value = EditorSettings::get_singleton()->get_project_metadata("3d_editor", "snap_rotate_value", 15);
|
||||
snap_scale_value = EditorSettings::get_singleton()->get_project_metadata("3d_editor", "snap_scale_value", 10);
|
||||
_snap_update();
|
||||
|
||||
for (uint32_t i = 0; i < VIEWPORTS_COUNT; i++) {
|
||||
viewports[i]->reset();
|
||||
}
|
||||
|
||||
RenderingServer::get_singleton()->instance_set_visible(origin_instance, true);
|
||||
if (origin_instance.is_valid()) {
|
||||
RenderingServer::get_singleton()->instance_set_visible(origin_instance, true);
|
||||
}
|
||||
|
||||
view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_ORIGIN), true);
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
if (grid_enable[i]) {
|
||||
@ -8307,10 +8319,6 @@ Node3DEditor::Node3DEditor() {
|
||||
|
||||
/* SNAP DIALOG */
|
||||
|
||||
snap_translate_value = 1;
|
||||
snap_rotate_value = 15;
|
||||
snap_scale_value = 10;
|
||||
|
||||
snap_dialog = memnew(ConfirmationDialog);
|
||||
snap_dialog->set_title(TTR("Snap Settings"));
|
||||
add_child(snap_dialog);
|
||||
@ -8649,6 +8657,7 @@ void fragment() {
|
||||
_load_default_preview_settings();
|
||||
_preview_settings_changed();
|
||||
}
|
||||
clear(); // Make sure values are initialized.
|
||||
}
|
||||
Node3DEditor::~Node3DEditor() {
|
||||
memdelete(preview_node);
|
||||
|
@ -441,7 +441,7 @@ private:
|
||||
void update_transform(Point2 p_mousepos, bool p_shift);
|
||||
void finish_transform();
|
||||
|
||||
void register_shortcut_action(const String &p_path, const String &p_name, Key p_keycode);
|
||||
void register_shortcut_action(const String &p_path, const String &p_name, Key p_keycode, bool p_physical = false);
|
||||
void shortcut_changed_callback(const Ref<Shortcut> p_shortcut, const String &p_shortcut_path);
|
||||
|
||||
protected:
|
||||
|
@ -1561,6 +1561,30 @@ void ScriptEditor::_prepare_file_menu() {
|
||||
menu->set_item_disabled(menu->get_item_index(FILE_RUN), current_is_doc);
|
||||
}
|
||||
|
||||
void ScriptEditor::_file_menu_closed() {
|
||||
PopupMenu *menu = file_menu->get_popup();
|
||||
|
||||
menu->set_item_disabled(menu->get_item_index(FILE_REOPEN_CLOSED), false);
|
||||
|
||||
menu->set_item_disabled(menu->get_item_index(FILE_SAVE), false);
|
||||
menu->set_item_disabled(menu->get_item_index(FILE_SAVE_AS), false);
|
||||
menu->set_item_disabled(menu->get_item_index(FILE_SAVE_ALL), false);
|
||||
|
||||
menu->set_item_disabled(menu->get_item_index(FILE_TOOL_RELOAD_SOFT), false);
|
||||
menu->set_item_disabled(menu->get_item_index(FILE_COPY_PATH), false);
|
||||
menu->set_item_disabled(menu->get_item_index(SHOW_IN_FILE_SYSTEM), false);
|
||||
|
||||
menu->set_item_disabled(menu->get_item_index(WINDOW_PREV), false);
|
||||
menu->set_item_disabled(menu->get_item_index(WINDOW_NEXT), false);
|
||||
|
||||
menu->set_item_disabled(menu->get_item_index(FILE_CLOSE), false);
|
||||
menu->set_item_disabled(menu->get_item_index(CLOSE_ALL), false);
|
||||
menu->set_item_disabled(menu->get_item_index(CLOSE_OTHER_TABS), false);
|
||||
menu->set_item_disabled(menu->get_item_index(CLOSE_DOCS), false);
|
||||
|
||||
menu->set_item_disabled(menu->get_item_index(FILE_RUN), false);
|
||||
}
|
||||
|
||||
void ScriptEditor::_tab_changed(int p_which) {
|
||||
ensure_select_current();
|
||||
}
|
||||
@ -3916,6 +3940,7 @@ ScriptEditor::ScriptEditor() {
|
||||
file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/toggle_scripts_panel", TTR("Toggle Scripts Panel"), KeyModifierMask::CMD_OR_CTRL | Key::BACKSLASH), TOGGLE_SCRIPTS_PANEL);
|
||||
file_menu->get_popup()->connect("id_pressed", callable_mp(this, &ScriptEditor::_menu_option));
|
||||
file_menu->get_popup()->connect("about_to_popup", callable_mp(this, &ScriptEditor::_prepare_file_menu));
|
||||
file_menu->get_popup()->connect("popup_hide", callable_mp(this, &ScriptEditor::_file_menu_closed));
|
||||
|
||||
script_search_menu = memnew(MenuButton);
|
||||
script_search_menu->set_text(TTR("Search"));
|
||||
|
@ -336,6 +336,7 @@ class ScriptEditor : public PanelContainer {
|
||||
bool _has_docs_tab() const;
|
||||
bool _has_script_tab() const;
|
||||
void _prepare_file_menu();
|
||||
void _file_menu_closed();
|
||||
|
||||
Tree *disk_changed_list = nullptr;
|
||||
ConfirmationDialog *disk_changed = nullptr;
|
||||
|
@ -848,6 +848,12 @@ void TextureRegionEditor::_notification(int p_what) {
|
||||
if (snap_mode == SNAP_AUTOSLICE && is_visible() && autoslice_is_dirty) {
|
||||
_update_autoslice();
|
||||
}
|
||||
|
||||
if (!is_visible()) {
|
||||
EditorSettings::get_singleton()->set_project_metadata("texture_region_editor", "snap_step", snap_step);
|
||||
EditorSettings::get_singleton()->set_project_metadata("texture_region_editor", "snap_separation", snap_separation);
|
||||
EditorSettings::get_singleton()->set_project_metadata("texture_region_editor", "snap_mode", snap_mode);
|
||||
}
|
||||
} break;
|
||||
|
||||
case NOTIFICATION_WM_WINDOW_FOCUS_IN: {
|
||||
@ -1076,9 +1082,9 @@ TextureRegionEditor::TextureRegionEditor() {
|
||||
preview_tex = Ref<CanvasTexture>(memnew(CanvasTexture));
|
||||
|
||||
// A power-of-two value works better as a default grid size.
|
||||
snap_step = Vector2(8, 8);
|
||||
snap_separation = Vector2(0, 0);
|
||||
snap_mode = SNAP_NONE;
|
||||
snap_step = EditorSettings::get_singleton()->get_project_metadata("texture_region_editor", "snap_step", Vector2(8, 8));
|
||||
snap_separation = EditorSettings::get_singleton()->get_project_metadata("texture_region_editor", "snap_separation", Vector2());
|
||||
snap_mode = EditorSettings::get_singleton()->get_project_metadata("texture_region_editor", "snap_mode", SNAP_NONE);
|
||||
edited_margin = -1;
|
||||
drag_index = -1;
|
||||
drag = false;
|
||||
|
@ -783,7 +783,7 @@ def generate_vs_project(env, num_jobs, project_name="godot"):
|
||||
for plat_id in ModuleConfigs.PLATFORM_IDS
|
||||
]
|
||||
self.arg_dict["cpppaths"] += ModuleConfigs.for_every_variant(env["CPPPATH"] + [includes])
|
||||
self.arg_dict["cppdefines"] += ModuleConfigs.for_every_variant(env["CPPDEFINES"] + defines)
|
||||
self.arg_dict["cppdefines"] += ModuleConfigs.for_every_variant(list(env["CPPDEFINES"]) + defines)
|
||||
self.arg_dict["cmdargs"] += ModuleConfigs.for_every_variant(cli_args)
|
||||
|
||||
def build_commandline(self, commands):
|
||||
|
@ -13,13 +13,14 @@ diff=$(git diff --color)
|
||||
|
||||
# If no diff has been generated all is OK, clean up, and exit.
|
||||
if [ -z "$diff" ] ; then
|
||||
printf "Files in this commit comply with the black style rules.\n"
|
||||
printf "\e[1;32m*** Files in this commit comply with the black style rules.\e[0m\n"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# A diff has been created, notify the user, clean up, and exit.
|
||||
printf "\n*** The following differences were found between the code "
|
||||
printf "and the formatting rules:\n\n"
|
||||
echo "$diff"
|
||||
printf "\n*** Aborting, please fix your commit(s) with 'git commit --amend' or 'git rebase -i <hash>'\n"
|
||||
printf "\n\e[1;33m*** The following changes must be made to comply with the formatting rules:\e[0m\n\n"
|
||||
# Perl commands replace trailing spaces with `·` and tabs with `<TAB>`.
|
||||
printf "$diff\n" | perl -pe 's/(.*[^ ])( +)(\e\[m)$/my $spaces="·" x length($2); sprintf("$1$spaces$3")/ge' | perl -pe 's/(.*[^\t])(\t+)(\e\[m)$/my $tabs="<TAB>" x length($2); sprintf("$1$tabs$3")/ge'
|
||||
|
||||
printf "\n\e[1;91m*** Please fix your commit(s) with 'git commit --amend' or 'git rebase -i <hash>'\e[0m\n"
|
||||
exit 1
|
||||
|
@ -33,12 +33,14 @@ diff=$(git diff --color)
|
||||
|
||||
# If no diff has been generated all is OK, clean up, and exit.
|
||||
if [ -z "$diff" ] ; then
|
||||
printf "Files in this commit comply with the clang-format style rules.\n"
|
||||
printf "\e[1;32m*** Files in this commit comply with the clang-format style rules.\e[0m\n"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# A diff has been created, notify the user, clean up, and exit.
|
||||
printf "\n*** The following changes have been made to comply with the formatting rules:\n\n"
|
||||
echo "$diff"
|
||||
printf "\n*** Please fix your commit(s) with 'git commit --amend' or 'git rebase -i <hash>'\n"
|
||||
printf "\n\e[1;33m*** The following changes must be made to comply with the formatting rules:\e[0m\n\n"
|
||||
# Perl commands replace trailing spaces with `·` and tabs with `<TAB>`.
|
||||
printf "$diff\n" | perl -pe 's/(.*[^ ])( +)(\e\[m)$/my $spaces="·" x length($2); sprintf("$1$spaces$3")/ge' | perl -pe 's/(.*[^\t])(\t+)(\e\[m)$/my $tabs="<TAB>" x length($2); sprintf("$1$tabs$3")/ge'
|
||||
|
||||
printf "\n\e[1;91m*** Please fix your commit(s) with 'git commit --amend' or 'git rebase -i <hash>'\e[0m\n"
|
||||
exit 1
|
||||
|
@ -20,12 +20,14 @@ diff=$(git diff --color)
|
||||
|
||||
# If no diff has been generated all is OK, clean up, and exit.
|
||||
if [ -z "$diff" ] ; then
|
||||
printf "Files in this commit comply with the clang-tidy style rules.\n"
|
||||
printf "\e[1;32m*** Files in this commit comply with the clang-tidy style rules.\e[0m\n"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# A diff has been created, notify the user, clean up, and exit.
|
||||
printf "\n*** The following changes have been made to comply with the formatting rules:\n\n"
|
||||
echo "$diff"
|
||||
printf "\n*** Please fix your commit(s) with 'git commit --amend' or 'git rebase -i <hash>'\n"
|
||||
printf "\n\e[1;33m*** The following changes must be made to comply with the formatting rules:\e[0m\n\n"
|
||||
# Perl commands replace trailing spaces with `·` and tabs with `<TAB>`.
|
||||
printf "$diff\n" | perl -pe 's/(.*[^ ])( +)(\e\[m)$/my $spaces="·" x length($2); sprintf("$1$spaces$3")/ge' | perl -pe 's/(.*[^\t])(\t+)(\e\[m)$/my $tabs="<TAB>" x length($2); sprintf("$1$tabs$3")/ge'
|
||||
|
||||
printf "\n\e[1;91m*** Please fix your commit(s) with 'git commit --amend' or 'git rebase -i <hash>'\e[0m\n"
|
||||
exit 1
|
||||
|
@ -24,12 +24,14 @@ diff=$(git diff --color)
|
||||
|
||||
# If no diff has been generated all is OK, clean up, and exit.
|
||||
if [ -z "$diff" ] ; then
|
||||
printf "Files in this commit comply with the dotnet format style rules.\n"
|
||||
printf "\e[1;32m*** Files in this commit comply with the dotnet format style rules.\e[0m\n"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# A diff has been created, notify the user, clean up, and exit.
|
||||
printf "\n*** The following changes have been made to comply with the formatting rules:\n\n"
|
||||
echo "$diff"
|
||||
printf "\n*** Please fix your commit(s) with 'git commit --amend' or 'git rebase -i <hash>'\n"
|
||||
printf "\n\e[1;33m*** The following changes must be made to comply with the formatting rules:\e[0m\n\n"
|
||||
# Perl commands replace trailing spaces with `·` and tabs with `<TAB>`.
|
||||
printf "$diff\n" | perl -pe 's/(.*[^ ])( +)(\e\[m)$/my $spaces="·" x length($2); sprintf("$1$spaces$3")/ge' | perl -pe 's/(.*[^\t])(\t+)(\e\[m)$/my $tabs="<TAB>" x length($2); sprintf("$1$tabs$3")/ge'
|
||||
|
||||
printf "\n\e[1;91m*** Please fix your commit(s) with 'git commit --amend' or 'git rebase -i <hash>'\e[0m\n"
|
||||
exit 1
|
||||
|
@ -56,7 +56,7 @@ diff=$(git diff --color)
|
||||
if [ ! -s utf8-validation.txt ] && [ -z "$diff" ] ; then
|
||||
# If no UTF-8 violations were collected (the file is empty) and
|
||||
# no diff has been generated all is OK, clean up, and exit.
|
||||
printf "Files in this commit comply with the formatting rules.\n"
|
||||
printf "\e[1;32m*** Files in this commit comply with the file formatting rules.\e[0m\n"
|
||||
rm -f utf8-validation.txt
|
||||
exit 0
|
||||
fi
|
||||
@ -65,7 +65,7 @@ if [ -s utf8-validation.txt ]
|
||||
then
|
||||
# If the file has content and is not empty, violations
|
||||
# detected, notify the user, clean up, and exit.
|
||||
printf "\n*** The following files contain invalid UTF-8 character sequences:\n\n"
|
||||
printf "\n\e[1;33m*** The following files contain invalid UTF-8 character sequences:\e[0m\n\n"
|
||||
cat utf8-validation.txt
|
||||
fi
|
||||
|
||||
@ -73,10 +73,11 @@ rm -f utf8-validation.txt
|
||||
|
||||
if [ ! -z "$diff" ]
|
||||
then
|
||||
printf "\n*** The following differences were found between the code "
|
||||
printf "and the formatting rules:\n\n"
|
||||
echo "$diff"
|
||||
# A diff has been created, notify the user, clean up, and exit.
|
||||
printf "\n\e[1;33m*** The following changes must be made to comply with the formatting rules:\e[0m\n\n"
|
||||
# Perl commands replace trailing spaces with `·` and tabs with `<TAB>`.
|
||||
printf "$diff\n" | perl -pe 's/(.*[^ ])( +)(\e\[m)$/my $spaces="·" x length($2); sprintf("$1$spaces$3")/ge' | perl -pe 's/(.*[^\t])(\t+)(\e\[m)$/my $tabs="<TAB>" x length($2); sprintf("$1$tabs$3")/ge'
|
||||
fi
|
||||
|
||||
printf "\n*** Aborting, please fix your commit(s) with 'git commit --amend' or 'git rebase -i <hash>'\n"
|
||||
printf "\n\e[1;91m*** Please fix your commit(s) with 'git commit --amend' or 'git rebase -i <hash>'\e[0m\n"
|
||||
exit 1
|
||||
|
@ -66,13 +66,14 @@ diff=$(git diff --color)
|
||||
|
||||
# If no diff has been generated all is OK, clean up, and exit.
|
||||
if [ -z "$diff" ] ; then
|
||||
printf "Files in this commit comply with the header guards formatting rules.\n"
|
||||
printf "\e[1;32m*** Files in this commit comply with the header guards formatting rules.\e[0m\n"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# A diff has been created, notify the user, clean up, and exit.
|
||||
printf "\n*** The following differences were found between the code "
|
||||
printf "and the header guards formatting rules:\n\n"
|
||||
echo "$diff"
|
||||
printf "\n*** Aborting, please fix your commit(s) with 'git commit --amend' or 'git rebase -i <hash>'\n"
|
||||
printf "\n\e[1;33m*** The following changes must be made to comply with the formatting rules:\e[0m\n\n"
|
||||
# Perl commands replace trailing spaces with `·` and tabs with `<TAB>`.
|
||||
printf "$diff\n" | perl -pe 's/(.*[^ ])( +)(\e\[m)$/my $spaces="·" x length($2); sprintf("$1$spaces$3")/ge' | perl -pe 's/(.*[^\t])(\t+)(\e\[m)$/my $tabs="<TAB>" x length($2); sprintf("$1$tabs$3")/ge'
|
||||
|
||||
printf "\n\e[1;91m*** Please fix your commit(s) with 'git commit --amend' or 'git rebase -i <hash>'\e[0m\n"
|
||||
exit 1
|
||||
|
@ -504,15 +504,15 @@ namespace Godot
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a <see cref="Vector2"/> to a <see cref="Vector2I"/>.
|
||||
/// Converts a <see cref="Vector2"/> to a <see cref="Vector2I"/> by truncating
|
||||
/// components' fractional parts (rounding towards zero). For a different
|
||||
/// behavior consider passing the result of <see cref="Vector2.Ceil"/>,
|
||||
/// <see cref="Vector2.Floor"/> or <see cref="Vector2.Round"/> to this conversion operator instead.
|
||||
/// </summary>
|
||||
/// <param name="value">The vector to convert.</param>
|
||||
public static explicit operator Vector2I(Vector2 value)
|
||||
{
|
||||
return new Vector2I(
|
||||
Mathf.RoundToInt(value.X),
|
||||
Mathf.RoundToInt(value.Y)
|
||||
);
|
||||
return new Vector2I((int)value.X, (int)value.Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -559,16 +559,15 @@ namespace Godot
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a <see cref="Vector3"/> to a <see cref="Vector3I"/>.
|
||||
/// Converts a <see cref="Vector3"/> to a <see cref="Vector3I"/> by truncating
|
||||
/// components' fractional parts (rounding towards zero). For a different
|
||||
/// behavior consider passing the result of <see cref="Vector3.Ceil"/>,
|
||||
/// <see cref="Vector3.Floor"/> or <see cref="Vector3.Round"/> to this conversion operator instead.
|
||||
/// </summary>
|
||||
/// <param name="value">The vector to convert.</param>
|
||||
public static explicit operator Vector3I(Vector3 value)
|
||||
{
|
||||
return new Vector3I(
|
||||
Mathf.RoundToInt(value.X),
|
||||
Mathf.RoundToInt(value.Y),
|
||||
Mathf.RoundToInt(value.Z)
|
||||
);
|
||||
return new Vector3I((int)value.X, (int)value.Y, (int)value.Z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -580,17 +580,15 @@ namespace Godot
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a <see cref="Vector4"/> to a <see cref="Vector4I"/>.
|
||||
/// Converts a <see cref="Vector4"/> to a <see cref="Vector4I"/> by truncating
|
||||
/// components' fractional parts (rounding towards zero). For a different
|
||||
/// behavior consider passing the result of <see cref="Vector4.Ceil"/>,
|
||||
/// <see cref="Vector4.Floor"/> or <see cref="Vector4.Round"/> to this conversion operator instead.
|
||||
/// </summary>
|
||||
/// <param name="value">The vector to convert.</param>
|
||||
public static explicit operator Vector4I(Vector4 value)
|
||||
{
|
||||
return new Vector4I(
|
||||
Mathf.RoundToInt(value.X),
|
||||
Mathf.RoundToInt(value.Y),
|
||||
Mathf.RoundToInt(value.Z),
|
||||
Mathf.RoundToInt(value.W)
|
||||
);
|
||||
return new Vector4I((int)value.X, (int)value.Y, (int)value.Z, (int)value.W);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -79,8 +79,8 @@ Error ImageLoaderSVG::create_image_from_utf8_buffer(Ref<Image> p_image, const Pa
|
||||
float fw, fh;
|
||||
picture->size(&fw, &fh);
|
||||
|
||||
uint32_t width = round(fw * p_scale);
|
||||
uint32_t height = round(fh * p_scale);
|
||||
uint32_t width = MAX(1, round(fw * p_scale));
|
||||
uint32_t height = MAX(1, round(fh * p_scale));
|
||||
|
||||
const uint32_t max_dimension = 16384;
|
||||
if (width > max_dimension || height > max_dimension) {
|
||||
|
@ -126,10 +126,11 @@ FT_Error tvg_svg_in_ot_preset_slot(FT_GlyphSlot p_slot, FT_Bool p_cache, FT_Poin
|
||||
xml_body += vformat("</%s>", parser->get_node_name());
|
||||
}
|
||||
}
|
||||
String temp_xml = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 0 0\">" + xml_body;
|
||||
String temp_xml_str = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 0 0\">" + xml_body;
|
||||
CharString temp_xml = temp_xml_str.utf8();
|
||||
|
||||
std::unique_ptr<tvg::Picture> picture = tvg::Picture::gen();
|
||||
tvg::Result result = picture->load(temp_xml.utf8().get_data(), temp_xml.utf8().length(), "svg+xml", false);
|
||||
tvg::Result result = picture->load(temp_xml.get_data(), temp_xml.length(), "svg+xml", false);
|
||||
if (result != tvg::Result::Success) {
|
||||
ERR_FAIL_V_MSG(FT_Err_Invalid_SVG_Document, "Failed to load SVG document (bounds detection).");
|
||||
}
|
||||
@ -146,10 +147,11 @@ FT_Error tvg_svg_in_ot_preset_slot(FT_GlyphSlot p_slot, FT_Bool p_cache, FT_Poin
|
||||
new_h = (new_w / aspect);
|
||||
}
|
||||
|
||||
gl_state.xml_code = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"" + rtos(min_x) + " " + rtos(min_y) + " " + rtos(new_w) + " " + rtos(new_h) + "\">" + xml_body;
|
||||
String xml_code_str = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"" + rtos(min_x) + " " + rtos(min_y) + " " + rtos(new_w) + " " + rtos(new_h) + "\">" + xml_body;
|
||||
gl_state.xml_code = xml_code_str.utf8();
|
||||
|
||||
picture = tvg::Picture::gen();
|
||||
result = picture->load(gl_state.xml_code.utf8().get_data(), gl_state.xml_code.utf8().length(), "svg+xml", false);
|
||||
result = picture->load(gl_state.xml_code.get_data(), gl_state.xml_code.length(), "svg+xml", false);
|
||||
if (result != tvg::Result::Success) {
|
||||
ERR_FAIL_V_MSG(FT_Err_Invalid_SVG_Document, "Failed to load SVG document (glyph metrics).");
|
||||
}
|
||||
@ -237,7 +239,7 @@ FT_Error tvg_svg_in_ot_render(FT_GlyphSlot p_slot, FT_Pointer *p_state) {
|
||||
ERR_FAIL_COND_V_MSG(!gl_state.ready, FT_Err_Invalid_SVG_Document, "SVG glyph not ready.");
|
||||
|
||||
std::unique_ptr<tvg::Picture> picture = tvg::Picture::gen();
|
||||
tvg::Result res = picture->load(gl_state.xml_code.utf8().get_data(), gl_state.xml_code.utf8().length(), "svg+xml", false);
|
||||
tvg::Result res = picture->load(gl_state.xml_code.get_data(), gl_state.xml_code.length(), "svg+xml", false);
|
||||
if (res != tvg::Result::Success) {
|
||||
ERR_FAIL_V_MSG(FT_Err_Invalid_SVG_Document, "Failed to load SVG document (glyph rendering).");
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ struct GL_State {
|
||||
float y = 0;
|
||||
float w = 0;
|
||||
float h = 0;
|
||||
String xml_code;
|
||||
CharString xml_code;
|
||||
tvg::Matrix m;
|
||||
};
|
||||
|
||||
|
@ -126,10 +126,11 @@ FT_Error tvg_svg_in_ot_preset_slot(FT_GlyphSlot p_slot, FT_Bool p_cache, FT_Poin
|
||||
xml_body += vformat("</%s>", parser->get_node_name());
|
||||
}
|
||||
}
|
||||
String temp_xml = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 0 0\">" + xml_body;
|
||||
String temp_xml_str = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 0 0\">" + xml_body;
|
||||
CharString temp_xml = temp_xml_str.utf8();
|
||||
|
||||
std::unique_ptr<tvg::Picture> picture = tvg::Picture::gen();
|
||||
tvg::Result result = picture->load(temp_xml.utf8().get_data(), temp_xml.utf8().length(), "svg+xml", false);
|
||||
tvg::Result result = picture->load(temp_xml.get_data(), temp_xml.length(), "svg+xml", false);
|
||||
if (result != tvg::Result::Success) {
|
||||
ERR_FAIL_V_MSG(FT_Err_Invalid_SVG_Document, "Failed to load SVG document (bounds detection).");
|
||||
}
|
||||
@ -146,10 +147,11 @@ FT_Error tvg_svg_in_ot_preset_slot(FT_GlyphSlot p_slot, FT_Bool p_cache, FT_Poin
|
||||
new_h = (new_w / aspect);
|
||||
}
|
||||
|
||||
gl_state.xml_code = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"" + rtos(min_x) + " " + rtos(min_y) + " " + rtos(new_w) + " " + rtos(new_h) + "\">" + xml_body;
|
||||
String xml_code_str = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"" + rtos(min_x) + " " + rtos(min_y) + " " + rtos(new_w) + " " + rtos(new_h) + "\">" + xml_body;
|
||||
gl_state.xml_code = xml_code_str.utf8();
|
||||
|
||||
picture = tvg::Picture::gen();
|
||||
result = picture->load(gl_state.xml_code.utf8().get_data(), gl_state.xml_code.utf8().length(), "svg+xml", false);
|
||||
result = picture->load(gl_state.xml_code.get_data(), gl_state.xml_code.length(), "svg+xml", false);
|
||||
if (result != tvg::Result::Success) {
|
||||
ERR_FAIL_V_MSG(FT_Err_Invalid_SVG_Document, "Failed to load SVG document (glyph metrics).");
|
||||
}
|
||||
@ -237,7 +239,7 @@ FT_Error tvg_svg_in_ot_render(FT_GlyphSlot p_slot, FT_Pointer *p_state) {
|
||||
ERR_FAIL_COND_V_MSG(!gl_state.ready, FT_Err_Invalid_SVG_Document, "SVG glyph not ready.");
|
||||
|
||||
std::unique_ptr<tvg::Picture> picture = tvg::Picture::gen();
|
||||
tvg::Result res = picture->load(gl_state.xml_code.utf8().get_data(), gl_state.xml_code.utf8().length(), "svg+xml", false);
|
||||
tvg::Result res = picture->load(gl_state.xml_code.get_data(), gl_state.xml_code.length(), "svg+xml", false);
|
||||
if (res != tvg::Result::Success) {
|
||||
ERR_FAIL_V_MSG(FT_Err_Invalid_SVG_Document, "Failed to load SVG document (glyph rendering).");
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ struct GL_State {
|
||||
float y = 0;
|
||||
float w = 0;
|
||||
float h = 0;
|
||||
String xml_code;
|
||||
CharString xml_code;
|
||||
tvg::Matrix m;
|
||||
};
|
||||
|
||||
|
@ -33,7 +33,7 @@
|
||||
// See https://w3c.github.io/uievents-code/#code-value-tables
|
||||
Key dom_code2godot_scancode(EM_UTF8 const p_code[32], EM_UTF8 const p_key[32], bool p_physical) {
|
||||
#define DOM2GODOT(p_str, p_godot_code) \
|
||||
if (memcmp((const void *)p_str, (void *)(p_physical ? p_key : p_code), strlen(p_str) + 1) == 0) { \
|
||||
if (memcmp((const void *)p_str, (void *)(p_physical ? p_code : p_key), strlen(p_str) + 1) == 0) { \
|
||||
return Key::p_godot_code; \
|
||||
}
|
||||
|
||||
|
@ -264,15 +264,15 @@ BitField<MouseButtonMask> DisplayServerWindows::mouse_get_button_state() const {
|
||||
void DisplayServerWindows::clipboard_set(const String &p_text) {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
if (!windows.has(last_focused_window)) {
|
||||
return; // No focused window?
|
||||
if (!windows.has(MAIN_WINDOW_ID)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Convert LF line endings to CRLF in clipboard content.
|
||||
// Otherwise, line endings won't be visible when pasted in other software.
|
||||
String text = p_text.replace("\r\n", "\n").replace("\n", "\r\n"); // Avoid \r\r\n.
|
||||
|
||||
if (!OpenClipboard(windows[last_focused_window].hWnd)) {
|
||||
if (!OpenClipboard(windows[MAIN_WINDOW_ID].hWnd)) {
|
||||
ERR_FAIL_MSG("Unable to open clipboard.");
|
||||
}
|
||||
EmptyClipboard();
|
||||
@ -305,12 +305,12 @@ void DisplayServerWindows::clipboard_set(const String &p_text) {
|
||||
String DisplayServerWindows::clipboard_get() const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
if (!windows.has(last_focused_window)) {
|
||||
return String(); // No focused window?
|
||||
if (!windows.has(MAIN_WINDOW_ID)) {
|
||||
return String();
|
||||
}
|
||||
|
||||
String ret;
|
||||
if (!OpenClipboard(windows[last_focused_window].hWnd)) {
|
||||
if (!OpenClipboard(windows[MAIN_WINDOW_ID].hWnd)) {
|
||||
ERR_FAIL_V_MSG("", "Unable to open clipboard.");
|
||||
}
|
||||
|
||||
|
@ -516,11 +516,13 @@ void JoypadWindows::joypad_vibration_stop_xinput(int p_device, uint64_t p_timest
|
||||
void JoypadWindows::load_xinput() {
|
||||
xinput_get_state = &_xinput_get_state;
|
||||
xinput_set_state = &_xinput_set_state;
|
||||
bool legacy_xinput = false;
|
||||
xinput_dll = LoadLibrary("XInput1_4.dll");
|
||||
if (!xinput_dll) {
|
||||
xinput_dll = LoadLibrary("XInput1_3.dll");
|
||||
if (!xinput_dll) {
|
||||
xinput_dll = LoadLibrary("XInput9_1_0.dll");
|
||||
legacy_xinput = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -529,7 +531,9 @@ void JoypadWindows::load_xinput() {
|
||||
return;
|
||||
}
|
||||
|
||||
XInputGetState_t func = (XInputGetState_t)GetProcAddress((HMODULE)xinput_dll, "XInputGetState");
|
||||
// (LPCSTR)100 is the magic number to get XInputGetStateEx, which also provides the state for the guide button
|
||||
LPCSTR get_state_func_name = legacy_xinput ? "XInputGetState" : (LPCSTR)100;
|
||||
XInputGetState_t func = (XInputGetState_t)GetProcAddress((HMODULE)xinput_dll, get_state_func_name);
|
||||
XInputSetState_t set_func = (XInputSetState_t)GetProcAddress((HMODULE)xinput_dll, "XInputSetState");
|
||||
if (!func || !set_func) {
|
||||
unload_xinput();
|
||||
|
@ -68,7 +68,8 @@ void AudioStreamPlayer2D::_notification(int p_what) {
|
||||
|
||||
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
|
||||
// Update anything related to position first, if possible of course.
|
||||
if (setplay.get() > 0 || (active.is_set() && last_mix_count != AudioServer::get_singleton()->get_mix_count())) {
|
||||
if (setplay.get() > 0 || (active.is_set() && last_mix_count != AudioServer::get_singleton()->get_mix_count()) || force_update_panning) {
|
||||
force_update_panning = false;
|
||||
_update_panning();
|
||||
}
|
||||
|
||||
@ -109,6 +110,7 @@ void AudioStreamPlayer2D::_notification(int p_what) {
|
||||
}
|
||||
}
|
||||
|
||||
// Interacts with PhysicsServer2D, so can only be called during _physics_process
|
||||
StringName AudioStreamPlayer2D::_get_actual_bus() {
|
||||
Vector2 global_pos = get_global_position();
|
||||
|
||||
@ -117,6 +119,7 @@ StringName AudioStreamPlayer2D::_get_actual_bus() {
|
||||
ERR_FAIL_COND_V(world_2d.is_null(), SNAME("Master"));
|
||||
|
||||
PhysicsDirectSpaceState2D *space_state = PhysicsServer2D::get_singleton()->space_get_direct_state(world_2d->get_space());
|
||||
ERR_FAIL_COND_V(space_state == nullptr, SNAME("Master"));
|
||||
PhysicsDirectSpaceState2D::ShapeResult sr[MAX_INTERSECT_AREAS];
|
||||
|
||||
PhysicsDirectSpaceState2D::PointParameters point_params;
|
||||
@ -142,6 +145,7 @@ StringName AudioStreamPlayer2D::_get_actual_bus() {
|
||||
return default_bus;
|
||||
}
|
||||
|
||||
// Interacts with PhysicsServer2D, so can only be called during _physics_process
|
||||
void AudioStreamPlayer2D::_update_panning() {
|
||||
if (!active.is_set() || stream.is_null()) {
|
||||
return;
|
||||
|
@ -61,6 +61,7 @@ private:
|
||||
Vector<AudioFrame> volume_vector;
|
||||
|
||||
uint64_t last_mix_count = -1;
|
||||
bool force_update_panning = false;
|
||||
|
||||
float volume_db = 0.0;
|
||||
float pitch_scale = 1.0;
|
||||
@ -75,7 +76,7 @@ private:
|
||||
void _update_panning();
|
||||
void _bus_layout_changed();
|
||||
|
||||
static void _listener_changed_cb(void *self) { reinterpret_cast<AudioStreamPlayer2D *>(self)->_update_panning(); }
|
||||
static void _listener_changed_cb(void *self) { reinterpret_cast<AudioStreamPlayer2D *>(self)->force_update_panning = true; }
|
||||
|
||||
uint32_t area_mask = 1;
|
||||
|
||||
|
@ -71,6 +71,12 @@ void NavigationAgent2D::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_navigation_layer_value", "layer_number", "value"), &NavigationAgent2D::set_navigation_layer_value);
|
||||
ClassDB::bind_method(D_METHOD("get_navigation_layer_value", "layer_number"), &NavigationAgent2D::get_navigation_layer_value);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_pathfinding_algorithm", "pathfinding_algorithm"), &NavigationAgent2D::set_pathfinding_algorithm);
|
||||
ClassDB::bind_method(D_METHOD("get_pathfinding_algorithm"), &NavigationAgent2D::get_pathfinding_algorithm);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_path_postprocessing", "path_postprocessing"), &NavigationAgent2D::set_path_postprocessing);
|
||||
ClassDB::bind_method(D_METHOD("get_path_postprocessing"), &NavigationAgent2D::get_path_postprocessing);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_path_metadata_flags", "flags"), &NavigationAgent2D::set_path_metadata_flags);
|
||||
ClassDB::bind_method(D_METHOD("get_path_metadata_flags"), &NavigationAgent2D::get_path_metadata_flags);
|
||||
|
||||
@ -99,6 +105,8 @@ void NavigationAgent2D::_bind_methods() {
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "target_desired_distance", PROPERTY_HINT_RANGE, "0.1,1000,0.01,or_greater,suffix:px"), "set_target_desired_distance", "get_target_desired_distance");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "path_max_distance", PROPERTY_HINT_RANGE, "10,1000,1,or_greater,suffix:px"), "set_path_max_distance", "get_path_max_distance");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "navigation_layers", PROPERTY_HINT_LAYERS_2D_NAVIGATION), "set_navigation_layers", "get_navigation_layers");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "pathfinding_algorithm", PROPERTY_HINT_ENUM, "AStar"), "set_pathfinding_algorithm", "get_pathfinding_algorithm");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "path_postprocessing", PROPERTY_HINT_ENUM, "Corridorfunnel,Edgecentered"), "set_path_postprocessing", "get_path_postprocessing");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "path_metadata_flags", PROPERTY_HINT_FLAGS, "Include Types,Include RIDs,Include Owners"), "set_path_metadata_flags", "get_path_metadata_flags");
|
||||
|
||||
ADD_GROUP("Avoidance", "");
|
||||
@ -328,6 +336,26 @@ bool NavigationAgent2D::get_navigation_layer_value(int p_layer_number) const {
|
||||
return get_navigation_layers() & (1 << (p_layer_number - 1));
|
||||
}
|
||||
|
||||
void NavigationAgent2D::set_pathfinding_algorithm(const NavigationPathQueryParameters2D::PathfindingAlgorithm p_pathfinding_algorithm) {
|
||||
if (pathfinding_algorithm == p_pathfinding_algorithm) {
|
||||
return;
|
||||
}
|
||||
|
||||
pathfinding_algorithm = p_pathfinding_algorithm;
|
||||
|
||||
navigation_query->set_pathfinding_algorithm(pathfinding_algorithm);
|
||||
}
|
||||
|
||||
void NavigationAgent2D::set_path_postprocessing(const NavigationPathQueryParameters2D::PathPostProcessing p_path_postprocessing) {
|
||||
if (path_postprocessing == p_path_postprocessing) {
|
||||
return;
|
||||
}
|
||||
|
||||
path_postprocessing = p_path_postprocessing;
|
||||
|
||||
navigation_query->set_path_postprocessing(path_postprocessing);
|
||||
}
|
||||
|
||||
void NavigationAgent2D::set_path_metadata_flags(BitField<NavigationPathQueryParameters2D::PathMetadataFlags> p_path_metadata_flags) {
|
||||
if (path_metadata_flags == p_path_metadata_flags) {
|
||||
return;
|
||||
|
@ -48,6 +48,8 @@ class NavigationAgent2D : public Node {
|
||||
|
||||
bool avoidance_enabled = false;
|
||||
uint32_t navigation_layers = 1;
|
||||
NavigationPathQueryParameters2D::PathfindingAlgorithm pathfinding_algorithm = NavigationPathQueryParameters2D::PathfindingAlgorithm::PATHFINDING_ALGORITHM_ASTAR;
|
||||
NavigationPathQueryParameters2D::PathPostProcessing path_postprocessing = NavigationPathQueryParameters2D::PathPostProcessing::PATH_POSTPROCESSING_CORRIDORFUNNEL;
|
||||
BitField<NavigationPathQueryParameters2D::PathMetadataFlags> path_metadata_flags = NavigationPathQueryParameters2D::PathMetadataFlags::PATH_METADATA_INCLUDE_ALL;
|
||||
|
||||
real_t path_desired_distance = 20.0;
|
||||
@ -112,6 +114,16 @@ public:
|
||||
void set_navigation_layer_value(int p_layer_number, bool p_value);
|
||||
bool get_navigation_layer_value(int p_layer_number) const;
|
||||
|
||||
void set_pathfinding_algorithm(const NavigationPathQueryParameters2D::PathfindingAlgorithm p_pathfinding_algorithm);
|
||||
NavigationPathQueryParameters2D::PathfindingAlgorithm get_pathfinding_algorithm() const {
|
||||
return pathfinding_algorithm;
|
||||
}
|
||||
|
||||
void set_path_postprocessing(const NavigationPathQueryParameters2D::PathPostProcessing p_path_postprocessing);
|
||||
NavigationPathQueryParameters2D::PathPostProcessing get_path_postprocessing() const {
|
||||
return path_postprocessing;
|
||||
}
|
||||
|
||||
void set_path_metadata_flags(BitField<NavigationPathQueryParameters2D::PathMetadataFlags> p_flags);
|
||||
BitField<NavigationPathQueryParameters2D::PathMetadataFlags> get_path_metadata_flags() const {
|
||||
return path_metadata_flags;
|
||||
|
@ -196,13 +196,20 @@ void NavigationObstacle2D::set_agent_parent(Node *p_agent_parent) {
|
||||
} else {
|
||||
NavigationServer2D::get_singleton()->agent_set_map(get_rid(), parent_node2d->get_world_2d()->get_navigation_map());
|
||||
}
|
||||
// Need to register Callback as obstacle requires a valid Callback to be added to avoidance simulation.
|
||||
NavigationServer2D::get_singleton()->agent_set_callback(get_rid(), callable_mp(this, &NavigationObstacle2D::_avoidance_done));
|
||||
reevaluate_agent_radius();
|
||||
} else {
|
||||
parent_node2d = nullptr;
|
||||
NavigationServer2D::get_singleton()->agent_set_map(get_rid(), RID());
|
||||
NavigationServer2D::get_singleton()->agent_set_callback(agent, Callable());
|
||||
}
|
||||
}
|
||||
|
||||
void NavigationObstacle2D::_avoidance_done(Vector3 p_new_velocity) {
|
||||
// Dummy function as obstacle requires a valid Callback to be added to avoidance simulation.
|
||||
}
|
||||
|
||||
void NavigationObstacle2D::set_navigation_map(RID p_navigation_map) {
|
||||
if (map_override == p_navigation_map) {
|
||||
return;
|
||||
|
@ -75,6 +75,8 @@ public:
|
||||
|
||||
PackedStringArray get_configuration_warnings() const override;
|
||||
|
||||
void _avoidance_done(Vector3 p_new_velocity); // Dummy
|
||||
|
||||
private:
|
||||
void initialize_agent();
|
||||
void reevaluate_agent_radius();
|
||||
|
@ -60,54 +60,51 @@ void RemoteTransform2D::_update_remote() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(update_remote_position || update_remote_rotation || update_remote_scale)) {
|
||||
return; // The transform data of the RemoteTransform2D is not used at all.
|
||||
}
|
||||
|
||||
//todo make faster
|
||||
if (use_global_coordinates) {
|
||||
if (update_remote_position && update_remote_rotation && update_remote_scale) {
|
||||
n->set_global_transform(get_global_transform());
|
||||
} else {
|
||||
Transform2D n_trans = n->get_global_transform();
|
||||
Transform2D our_trans = get_global_transform();
|
||||
Vector2 n_scale = n->get_scale();
|
||||
|
||||
if (!update_remote_position) {
|
||||
our_trans.set_origin(n_trans.get_origin());
|
||||
}
|
||||
if (!update_remote_rotation) {
|
||||
our_trans.set_rotation(n_trans.get_rotation());
|
||||
}
|
||||
|
||||
n->set_global_transform(our_trans);
|
||||
|
||||
if (update_remote_scale) {
|
||||
n->set_scale(get_global_scale());
|
||||
} else {
|
||||
n->set_scale(n_scale);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Transform2D n_trans = n->get_global_transform();
|
||||
Transform2D our_trans = get_global_transform();
|
||||
|
||||
// There are more steps in the operation of set_rotation, so avoid calling it.
|
||||
Transform2D trans = update_remote_rotation ? our_trans : n_trans;
|
||||
|
||||
if (update_remote_rotation ^ update_remote_position) {
|
||||
trans.set_origin(update_remote_position ? our_trans.get_origin() : n_trans.get_origin());
|
||||
}
|
||||
if (update_remote_rotation ^ update_remote_scale) {
|
||||
trans.set_scale(update_remote_scale ? our_trans.get_scale() : n_trans.get_scale());
|
||||
}
|
||||
|
||||
n->set_global_transform(trans);
|
||||
} else {
|
||||
if (update_remote_position && update_remote_rotation && update_remote_scale) {
|
||||
n->set_transform(get_transform());
|
||||
} else {
|
||||
Transform2D n_trans = n->get_transform();
|
||||
Transform2D our_trans = get_transform();
|
||||
Vector2 n_scale = n->get_scale();
|
||||
|
||||
if (!update_remote_position) {
|
||||
our_trans.set_origin(n_trans.get_origin());
|
||||
}
|
||||
if (!update_remote_rotation) {
|
||||
our_trans.set_rotation(n_trans.get_rotation());
|
||||
}
|
||||
|
||||
n->set_transform(our_trans);
|
||||
|
||||
if (update_remote_scale) {
|
||||
n->set_scale(get_scale());
|
||||
} else {
|
||||
n->set_scale(n_scale);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Transform2D n_trans = n->get_transform();
|
||||
Transform2D our_trans = get_transform();
|
||||
|
||||
// There are more steps in the operation of set_rotation, so avoid calling it.
|
||||
Transform2D trans = update_remote_rotation ? our_trans : n_trans;
|
||||
|
||||
if (update_remote_rotation ^ update_remote_position) {
|
||||
trans.set_origin(update_remote_position ? our_trans.get_origin() : n_trans.get_origin());
|
||||
}
|
||||
if (update_remote_rotation ^ update_remote_scale) {
|
||||
trans.set_scale(update_remote_scale ? our_trans.get_scale() : n_trans.get_scale());
|
||||
}
|
||||
|
||||
n->set_transform(trans);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -75,6 +75,12 @@ void NavigationAgent3D::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_navigation_layer_value", "layer_number", "value"), &NavigationAgent3D::set_navigation_layer_value);
|
||||
ClassDB::bind_method(D_METHOD("get_navigation_layer_value", "layer_number"), &NavigationAgent3D::get_navigation_layer_value);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_pathfinding_algorithm", "pathfinding_algorithm"), &NavigationAgent3D::set_pathfinding_algorithm);
|
||||
ClassDB::bind_method(D_METHOD("get_pathfinding_algorithm"), &NavigationAgent3D::get_pathfinding_algorithm);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_path_postprocessing", "path_postprocessing"), &NavigationAgent3D::set_path_postprocessing);
|
||||
ClassDB::bind_method(D_METHOD("get_path_postprocessing"), &NavigationAgent3D::get_path_postprocessing);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_path_metadata_flags", "flags"), &NavigationAgent3D::set_path_metadata_flags);
|
||||
ClassDB::bind_method(D_METHOD("get_path_metadata_flags"), &NavigationAgent3D::get_path_metadata_flags);
|
||||
|
||||
@ -104,6 +110,8 @@ void NavigationAgent3D::_bind_methods() {
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "agent_height_offset", PROPERTY_HINT_RANGE, "-100.0,100,0.01,or_greater,suffix:m"), "set_agent_height_offset", "get_agent_height_offset");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "path_max_distance", PROPERTY_HINT_RANGE, "0.01,100,0.1,or_greater,suffix:m"), "set_path_max_distance", "get_path_max_distance");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "navigation_layers", PROPERTY_HINT_LAYERS_3D_NAVIGATION), "set_navigation_layers", "get_navigation_layers");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "pathfinding_algorithm", PROPERTY_HINT_ENUM, "AStar"), "set_pathfinding_algorithm", "get_pathfinding_algorithm");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "path_postprocessing", PROPERTY_HINT_ENUM, "Corridorfunnel,Edgecentered"), "set_path_postprocessing", "get_path_postprocessing");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "path_metadata_flags", PROPERTY_HINT_FLAGS, "Include Types,Include RIDs,Include Owners"), "set_path_metadata_flags", "get_path_metadata_flags");
|
||||
|
||||
ADD_GROUP("Avoidance", "");
|
||||
@ -335,6 +343,26 @@ bool NavigationAgent3D::get_navigation_layer_value(int p_layer_number) const {
|
||||
return get_navigation_layers() & (1 << (p_layer_number - 1));
|
||||
}
|
||||
|
||||
void NavigationAgent3D::set_pathfinding_algorithm(const NavigationPathQueryParameters3D::PathfindingAlgorithm p_pathfinding_algorithm) {
|
||||
if (pathfinding_algorithm == p_pathfinding_algorithm) {
|
||||
return;
|
||||
}
|
||||
|
||||
pathfinding_algorithm = p_pathfinding_algorithm;
|
||||
|
||||
navigation_query->set_pathfinding_algorithm(pathfinding_algorithm);
|
||||
}
|
||||
|
||||
void NavigationAgent3D::set_path_postprocessing(const NavigationPathQueryParameters3D::PathPostProcessing p_path_postprocessing) {
|
||||
if (path_postprocessing == p_path_postprocessing) {
|
||||
return;
|
||||
}
|
||||
|
||||
path_postprocessing = p_path_postprocessing;
|
||||
|
||||
navigation_query->set_path_postprocessing(path_postprocessing);
|
||||
}
|
||||
|
||||
void NavigationAgent3D::set_path_metadata_flags(BitField<NavigationPathQueryParameters3D::PathMetadataFlags> p_path_metadata_flags) {
|
||||
if (path_metadata_flags == p_path_metadata_flags) {
|
||||
return;
|
||||
|
@ -48,6 +48,8 @@ class NavigationAgent3D : public Node {
|
||||
|
||||
bool avoidance_enabled = false;
|
||||
uint32_t navigation_layers = 1;
|
||||
NavigationPathQueryParameters3D::PathfindingAlgorithm pathfinding_algorithm = NavigationPathQueryParameters3D::PathfindingAlgorithm::PATHFINDING_ALGORITHM_ASTAR;
|
||||
NavigationPathQueryParameters3D::PathPostProcessing path_postprocessing = NavigationPathQueryParameters3D::PathPostProcessing::PATH_POSTPROCESSING_CORRIDORFUNNEL;
|
||||
BitField<NavigationPathQueryParameters3D::PathMetadataFlags> path_metadata_flags = NavigationPathQueryParameters3D::PathMetadataFlags::PATH_METADATA_INCLUDE_ALL;
|
||||
|
||||
real_t path_desired_distance = 1.0;
|
||||
@ -116,6 +118,16 @@ public:
|
||||
void set_navigation_layer_value(int p_layer_number, bool p_value);
|
||||
bool get_navigation_layer_value(int p_layer_number) const;
|
||||
|
||||
void set_pathfinding_algorithm(const NavigationPathQueryParameters3D::PathfindingAlgorithm p_pathfinding_algorithm);
|
||||
NavigationPathQueryParameters3D::PathfindingAlgorithm get_pathfinding_algorithm() const {
|
||||
return pathfinding_algorithm;
|
||||
}
|
||||
|
||||
void set_path_postprocessing(const NavigationPathQueryParameters3D::PathPostProcessing p_path_postprocessing);
|
||||
NavigationPathQueryParameters3D::PathPostProcessing get_path_postprocessing() const {
|
||||
return path_postprocessing;
|
||||
}
|
||||
|
||||
void set_path_metadata_flags(BitField<NavigationPathQueryParameters3D::PathMetadataFlags> p_flags);
|
||||
BitField<NavigationPathQueryParameters3D::PathMetadataFlags> get_path_metadata_flags() const {
|
||||
return path_metadata_flags;
|
||||
|
@ -203,13 +203,20 @@ void NavigationObstacle3D::set_agent_parent(Node *p_agent_parent) {
|
||||
} else {
|
||||
NavigationServer3D::get_singleton()->agent_set_map(get_rid(), parent_node3d->get_world_3d()->get_navigation_map());
|
||||
}
|
||||
// Need to register Callback as obstacle requires a valid Callback to be added to avoidance simulation.
|
||||
NavigationServer3D::get_singleton()->agent_set_callback(get_rid(), callable_mp(this, &NavigationObstacle3D::_avoidance_done));
|
||||
reevaluate_agent_radius();
|
||||
} else {
|
||||
parent_node3d = nullptr;
|
||||
NavigationServer3D::get_singleton()->agent_set_map(get_rid(), RID());
|
||||
NavigationServer3D::get_singleton()->agent_set_callback(agent, Callable());
|
||||
}
|
||||
}
|
||||
|
||||
void NavigationObstacle3D::_avoidance_done(Vector3 p_new_velocity) {
|
||||
// Dummy function as obstacle requires a valid Callback to be added to avoidance simulation.
|
||||
}
|
||||
|
||||
void NavigationObstacle3D::set_navigation_map(RID p_navigation_map) {
|
||||
if (map_override == p_navigation_map) {
|
||||
return;
|
||||
|
@ -74,6 +74,8 @@ public:
|
||||
|
||||
PackedStringArray get_configuration_warnings() const override;
|
||||
|
||||
void _avoidance_done(Vector3 p_new_velocity); // Dummy
|
||||
|
||||
private:
|
||||
void initialize_agent();
|
||||
void reevaluate_agent_radius();
|
||||
|
@ -533,7 +533,6 @@ void GraphEdit::_notification(int p_what) {
|
||||
|
||||
void GraphEdit::_update_comment_enclosed_nodes_list(GraphNode *p_node, HashMap<StringName, Vector<GraphNode *>> &p_comment_enclosed_nodes) {
|
||||
Rect2 comment_node_rect = p_node->get_rect();
|
||||
comment_node_rect.size *= zoom;
|
||||
|
||||
Vector<GraphNode *> enclosed_nodes;
|
||||
for (int i = 0; i < get_child_count(); i++) {
|
||||
@ -543,7 +542,6 @@ void GraphEdit::_update_comment_enclosed_nodes_list(GraphNode *p_node, HashMap<S
|
||||
}
|
||||
|
||||
Rect2 node_rect = gn->get_rect();
|
||||
node_rect.size *= zoom;
|
||||
|
||||
bool included = comment_node_rect.encloses(node_rect);
|
||||
if (included) {
|
||||
@ -806,7 +804,6 @@ bool GraphEdit::_check_clickable_control(Control *p_control, const Vector2 &mpos
|
||||
}
|
||||
|
||||
Rect2 control_rect = p_control->get_rect();
|
||||
control_rect.size *= zoom;
|
||||
control_rect.position *= zoom;
|
||||
control_rect.position += p_offset;
|
||||
|
||||
@ -873,7 +870,6 @@ bool GraphEdit::is_in_port_hotzone(const Vector2 &p_pos, const Vector2 &p_mouse_
|
||||
continue;
|
||||
}
|
||||
Rect2 child_rect = child->get_rect();
|
||||
child_rect.size *= zoom;
|
||||
|
||||
if (child_rect.has_point(p_mouse_pos * zoom)) {
|
||||
for (int j = 0; j < child->get_child_count(); j++) {
|
||||
@ -1169,7 +1165,6 @@ void GraphEdit::gui_input(const Ref<InputEvent> &p_ev) {
|
||||
}
|
||||
|
||||
Rect2 r = gn->get_rect();
|
||||
r.size *= zoom;
|
||||
bool in_box = r.intersects(box_selecting_rect);
|
||||
|
||||
if (in_box) {
|
||||
@ -1215,7 +1210,6 @@ void GraphEdit::gui_input(const Ref<InputEvent> &p_ev) {
|
||||
|
||||
if (gn) {
|
||||
Rect2 r = gn->get_rect();
|
||||
r.size *= zoom;
|
||||
if (r.has_point(mb->get_position())) {
|
||||
gn->set_selected(false);
|
||||
}
|
||||
|
@ -664,7 +664,7 @@ Size2 GraphNode::get_minimum_size() const {
|
||||
|
||||
for (int i = 0; i < get_child_count(); i++) {
|
||||
Control *c = Object::cast_to<Control>(get_child(i));
|
||||
if (!c) {
|
||||
if (!c || !c->is_visible()) {
|
||||
continue;
|
||||
}
|
||||
if (c->is_set_as_top_level()) {
|
||||
|
@ -31,15 +31,10 @@
|
||||
#include "texture_progress_bar.h"
|
||||
|
||||
#include "core/config/engine.h"
|
||||
#include "core/core_string_names.h"
|
||||
|
||||
void TextureProgressBar::set_under_texture(const Ref<Texture2D> &p_texture) {
|
||||
if (under == p_texture) {
|
||||
return;
|
||||
}
|
||||
|
||||
under = p_texture;
|
||||
queue_redraw();
|
||||
update_minimum_size();
|
||||
_set_texture(&under, p_texture);
|
||||
}
|
||||
|
||||
Ref<Texture2D> TextureProgressBar::get_under_texture() const {
|
||||
@ -47,15 +42,7 @@ Ref<Texture2D> TextureProgressBar::get_under_texture() const {
|
||||
}
|
||||
|
||||
void TextureProgressBar::set_over_texture(const Ref<Texture2D> &p_texture) {
|
||||
if (over == p_texture) {
|
||||
return;
|
||||
}
|
||||
|
||||
over = p_texture;
|
||||
queue_redraw();
|
||||
if (under.is_null()) {
|
||||
update_minimum_size();
|
||||
}
|
||||
_set_texture(&over, p_texture);
|
||||
}
|
||||
|
||||
Ref<Texture2D> TextureProgressBar::get_over_texture() const {
|
||||
@ -108,13 +95,7 @@ Size2 TextureProgressBar::get_minimum_size() const {
|
||||
}
|
||||
|
||||
void TextureProgressBar::set_progress_texture(const Ref<Texture2D> &p_texture) {
|
||||
if (progress == p_texture) {
|
||||
return;
|
||||
}
|
||||
|
||||
progress = p_texture;
|
||||
queue_redraw();
|
||||
update_minimum_size();
|
||||
_set_texture(&progress, p_texture);
|
||||
}
|
||||
|
||||
Ref<Texture2D> TextureProgressBar::get_progress_texture() const {
|
||||
@ -173,6 +154,28 @@ Color TextureProgressBar::get_tint_over() const {
|
||||
return tint_over;
|
||||
}
|
||||
|
||||
void TextureProgressBar::_set_texture(Ref<Texture2D> *p_destination, const Ref<Texture2D> &p_texture) {
|
||||
DEV_ASSERT(p_destination);
|
||||
Ref<Texture2D> &destination = *p_destination;
|
||||
if (destination == p_texture) {
|
||||
return;
|
||||
}
|
||||
if (destination.is_valid()) {
|
||||
destination->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &TextureProgressBar::_texture_changed));
|
||||
}
|
||||
destination = p_texture;
|
||||
if (destination.is_valid()) {
|
||||
// Pass `CONNECT_REFERENCE_COUNTED` to avoid early disconnect in case the same texture is assigned to different "slots".
|
||||
destination->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &TextureProgressBar::_texture_changed), CONNECT_REFERENCE_COUNTED);
|
||||
}
|
||||
_texture_changed();
|
||||
}
|
||||
|
||||
void TextureProgressBar::_texture_changed() {
|
||||
update_minimum_size();
|
||||
queue_redraw();
|
||||
}
|
||||
|
||||
Point2 TextureProgressBar::unit_val_to_uv(float val) {
|
||||
if (progress.is_null()) {
|
||||
return Point2();
|
||||
|
@ -113,6 +113,8 @@ private:
|
||||
Color tint_progress = Color(1, 1, 1);
|
||||
Color tint_over = Color(1, 1, 1);
|
||||
|
||||
void _set_texture(Ref<Texture2D> *p_destination, const Ref<Texture2D> &p_texture);
|
||||
void _texture_changed();
|
||||
Point2 unit_val_to_uv(float val);
|
||||
Point2 get_relative_center();
|
||||
void draw_nine_patch_stretched(const Ref<Texture2D> &p_texture, FillMode p_mode, double p_ratio, const Color &p_modulate);
|
||||
|
@ -130,7 +130,12 @@ bool ViewPanner::gui_input(const Ref<InputEvent> &p_event, Rect2 p_canvas_rect)
|
||||
|
||||
Ref<InputEventScreenDrag> screen_drag = p_event;
|
||||
if (screen_drag.is_valid()) {
|
||||
callback_helper(pan_callback, varray(screen_drag->get_relative(), p_event));
|
||||
if (Input::get_singleton()->is_emulating_mouse_from_touch() || Input::get_singleton()->is_emulating_touch_from_mouse()) {
|
||||
// This set of events also generates/is generated by
|
||||
// InputEventMouseButton/InputEventMouseMotion events which will be processed instead.
|
||||
} else {
|
||||
callback_helper(pan_callback, varray(screen_drag->get_relative(), p_event));
|
||||
}
|
||||
}
|
||||
|
||||
Ref<InputEventKey> k = p_event;
|
||||
|
@ -1408,6 +1408,10 @@ SceneTree::SceneTree() {
|
||||
root->set_name("root");
|
||||
root->set_title(GLOBAL_GET("application/config/name"));
|
||||
|
||||
if (Engine::get_singleton()->is_editor_hint()) {
|
||||
root->set_wrap_controls(true);
|
||||
}
|
||||
|
||||
#ifndef _3D_DISABLED
|
||||
if (!root->get_world_3d().is_valid()) {
|
||||
root->set_world_3d(Ref<World3D>(memnew(World3D)));
|
||||
|
@ -38,11 +38,41 @@ bool ConvexPolygonShape2D::_edit_is_selected_on_click(const Point2 &p_point, dou
|
||||
return Geometry2D::is_point_in_polygon(p_point, points);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
// Check if point p3 is to the left of [p1, p2] segment or on it.
|
||||
bool left_test(const Vector2 &p1, const Vector2 &p2, const Vector2 &p3) {
|
||||
Vector2 p12 = p2 - p1;
|
||||
Vector2 p13 = p3 - p1;
|
||||
// If the value of the cross product is positive or zero; p3 is to the left or on the segment, respectively.
|
||||
return p12.cross(p13) >= 0;
|
||||
}
|
||||
|
||||
bool is_convex(const Vector<Vector2> &p_points) {
|
||||
// Pre-condition: Polygon is in counter-clockwise order.
|
||||
int polygon_size = p_points.size();
|
||||
for (int i = 0; i < polygon_size && polygon_size > 3; i++) {
|
||||
int j = (i + 1) % polygon_size;
|
||||
int k = (j + 1) % polygon_size;
|
||||
// If any consecutive three points fail left-test, then there is a concavity.
|
||||
if (!left_test(p_points[i], p_points[j], p_points[k])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
void ConvexPolygonShape2D::_update_shape() {
|
||||
Vector<Vector2> final_points = points;
|
||||
if (Geometry2D::is_polygon_clockwise(final_points)) { //needs to be counter clockwise
|
||||
final_points.reverse();
|
||||
}
|
||||
#ifdef DEBUG_ENABLED
|
||||
if (!is_convex(final_points)) {
|
||||
WARN_PRINT("Concave polygon is assigned to ConvexPolygonShape2D.");
|
||||
}
|
||||
#endif
|
||||
PhysicsServer2D::get_singleton()->shape_set_data(get_rid(), final_points);
|
||||
emit_changed();
|
||||
}
|
||||
|
@ -233,27 +233,27 @@ void TextParagraph::_shape_lines() {
|
||||
}
|
||||
if (alignment == HORIZONTAL_ALIGNMENT_FILL) {
|
||||
for (int i = 0; i < (int)lines_rid.size(); i++) {
|
||||
float line_w = (i <= dropcap_lines) ? (width - h_offset) : width;
|
||||
if (i < visible_lines - 1 || (int)lines_rid.size() == 1) {
|
||||
TS->shaped_text_fit_to_width(lines_rid[i], width, jst_flags);
|
||||
TS->shaped_text_fit_to_width(lines_rid[i], line_w, jst_flags);
|
||||
} else if (i == (visible_lines - 1)) {
|
||||
TS->shaped_text_overrun_trim_to_width(lines_rid[visible_lines - 1], width, overrun_flags);
|
||||
TS->shaped_text_overrun_trim_to_width(lines_rid[visible_lines - 1], line_w, overrun_flags);
|
||||
}
|
||||
}
|
||||
|
||||
} else if (lines_hidden) {
|
||||
TS->shaped_text_overrun_trim_to_width(lines_rid[visible_lines - 1], width, overrun_flags);
|
||||
TS->shaped_text_overrun_trim_to_width(lines_rid[visible_lines - 1], (visible_lines - 1 <= dropcap_lines) ? (width - h_offset) : width, overrun_flags);
|
||||
}
|
||||
|
||||
} else {
|
||||
// Autowrap disabled.
|
||||
for (const RID &line_rid : lines_rid) {
|
||||
for (int i = 0; i < (int)lines_rid.size(); i++) {
|
||||
float line_w = (i <= dropcap_lines) ? (width - h_offset) : width;
|
||||
if (alignment == HORIZONTAL_ALIGNMENT_FILL) {
|
||||
TS->shaped_text_fit_to_width(line_rid, width, jst_flags);
|
||||
TS->shaped_text_fit_to_width(lines_rid[i], line_w, jst_flags);
|
||||
overrun_flags.set_flag(TextServer::OVERRUN_JUSTIFICATION_AWARE);
|
||||
TS->shaped_text_overrun_trim_to_width(line_rid, width, overrun_flags);
|
||||
TS->shaped_text_fit_to_width(line_rid, width, jst_flags | TextServer::JUSTIFICATION_CONSTRAIN_ELLIPSIS);
|
||||
TS->shaped_text_overrun_trim_to_width(lines_rid[i], line_w, overrun_flags);
|
||||
TS->shaped_text_fit_to_width(lines_rid[i], line_w, jst_flags | TextServer::JUSTIFICATION_CONSTRAIN_ELLIPSIS);
|
||||
} else {
|
||||
TS->shaped_text_overrun_trim_to_width(line_rid, width, overrun_flags);
|
||||
TS->shaped_text_overrun_trim_to_width(lines_rid[i], line_w, overrun_flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -893,7 +893,7 @@ PhysicsServer2D::PhysicsServer2D() {
|
||||
GLOBAL_DEF(PropertyInfo(Variant::INT, "physics/2d/solver/solver_iterations", PROPERTY_HINT_RANGE, "1,32,1,or_greater"), 16);
|
||||
GLOBAL_DEF(PropertyInfo(Variant::FLOAT, "physics/2d/solver/contact_recycle_radius", PROPERTY_HINT_RANGE, "0,10,0.01,or_greater"), 1.0);
|
||||
GLOBAL_DEF(PropertyInfo(Variant::FLOAT, "physics/2d/solver/contact_max_separation", PROPERTY_HINT_RANGE, "0,10,0.01,or_greater"), 1.5);
|
||||
GLOBAL_DEF(PropertyInfo(Variant::FLOAT, "physics/2d/solver/contact_max_allowed_penetration", PROPERTY_HINT_RANGE, "0,10,0.01,or_greater"), 0.3);
|
||||
GLOBAL_DEF(PropertyInfo(Variant::FLOAT, "physics/2d/solver/contact_max_allowed_penetration", PROPERTY_HINT_RANGE, "0.01,10,0.01,or_greater"), 0.3);
|
||||
GLOBAL_DEF(PropertyInfo(Variant::FLOAT, "physics/2d/solver/default_contact_bias", PROPERTY_HINT_RANGE, "0,1,0.01"), 0.8);
|
||||
GLOBAL_DEF(PropertyInfo(Variant::FLOAT, "physics/2d/solver/default_constraint_bias", PROPERTY_HINT_RANGE, "0,1,0.01"), 0.2);
|
||||
}
|
||||
|
@ -1059,9 +1059,9 @@ PhysicsServer3D::PhysicsServer3D() {
|
||||
GLOBAL_DEF("physics/3d/sleep_threshold_angular", Math::deg_to_rad(8.0));
|
||||
GLOBAL_DEF(PropertyInfo(Variant::FLOAT, "physics/3d/time_before_sleep", PROPERTY_HINT_RANGE, "0,5,0.01,or_greater"), 0.5);
|
||||
GLOBAL_DEF(PropertyInfo(Variant::INT, "physics/3d/solver/solver_iterations", PROPERTY_HINT_RANGE, "1,32,1,or_greater"), 16);
|
||||
GLOBAL_DEF(PropertyInfo(Variant::FLOAT, "physics/3d/solver/contact_recycle_radius", PROPERTY_HINT_RANGE, "0,0.1,0.01,or_greater"), 0.01);
|
||||
GLOBAL_DEF(PropertyInfo(Variant::FLOAT, "physics/3d/solver/contact_max_separation", PROPERTY_HINT_RANGE, "0,0.1,0.01,or_greater"), 0.05);
|
||||
GLOBAL_DEF(PropertyInfo(Variant::FLOAT, "physics/3d/solver/contact_max_allowed_penetration", PROPERTY_HINT_RANGE, "0,0.1,0.01,or_greater"), 0.01);
|
||||
GLOBAL_DEF(PropertyInfo(Variant::FLOAT, "physics/3d/solver/contact_recycle_radius", PROPERTY_HINT_RANGE, "0,0.1,0.001,or_greater"), 0.01);
|
||||
GLOBAL_DEF(PropertyInfo(Variant::FLOAT, "physics/3d/solver/contact_max_separation", PROPERTY_HINT_RANGE, "0,0.1,0.001,or_greater"), 0.05);
|
||||
GLOBAL_DEF(PropertyInfo(Variant::FLOAT, "physics/3d/solver/contact_max_allowed_penetration", PROPERTY_HINT_RANGE, "0.001,0.1,0.001,or_greater"), 0.01);
|
||||
GLOBAL_DEF(PropertyInfo(Variant::FLOAT, "physics/3d/solver/default_contact_bias", PROPERTY_HINT_RANGE, "0,1,0.01"), 0.8);
|
||||
}
|
||||
|
||||
|
@ -263,9 +263,8 @@ void main() {
|
||||
|
||||
// Schlick term.
|
||||
float metallic = texelFetch(source_metallic, ssC << 1, 0).w;
|
||||
float f0 = mix(0.04, 1.0, metallic); // Assume a "specular" amount of 0.5
|
||||
normal.y = -normal.y;
|
||||
float m = clamp(1.0 - dot(normalize(normal), -view_dir), 0.0, 1.0);
|
||||
float f0 = mix(0.04, 0.37, metallic); // The default value of R0 is 0.04 and the maximum value is considered to be Germanium with R0 value of 0.37
|
||||
float m = clamp(1.0 - dot(normal, -view_dir), 0.0, 1.0);
|
||||
float m2 = m * m;
|
||||
m = m2 * m2 * m; // pow(m,5)
|
||||
final_color.a *= f0 + (1.0 - f0) * m; // Fresnel Schlick term.
|
||||
|
2
thirdparty/README.md
vendored
2
thirdparty/README.md
vendored
@ -686,7 +686,7 @@ instead of `miniz.h` as an external dependency.
|
||||
## thorvg
|
||||
|
||||
- Upstream: https://github.com/Samsung/thorvg
|
||||
- Version: 0.8.3 (a0fcf51f80a75f63a066df085f60cdaf715188b6, 2022)
|
||||
- Version: 0.8.4 (b0b7f207c6235691d694fc3f76e0b96e4858e606, 2023)
|
||||
- License: MIT
|
||||
|
||||
Files extracted from upstream source:
|
||||
|
2
thirdparty/thorvg/AUTHORS
vendored
2
thirdparty/thorvg/AUTHORS
vendored
@ -4,7 +4,7 @@ Junsu Choi <jsuya.choi@samsung.com>
|
||||
Pranay Samanta <pranay.ks@samsung.com>
|
||||
Mateusz Palkowski <m.palkowski@samsung.com>
|
||||
Subhransu Mohanty <sub.mohanty@samsung.com>
|
||||
Mira Grudzinska <m.grudzinska@samsung.com>
|
||||
Mira Grudzinska <veleveta@gmail.com>
|
||||
Michal Szczecinski <m.szczecinsk@partner.samsung.com>
|
||||
Shinwoo Kim <cinoo.kim@samsung.com>
|
||||
Piotr Kalota <p.kalota@samsung.com>
|
||||
|
2
thirdparty/thorvg/inc/config.h
vendored
2
thirdparty/thorvg/inc/config.h
vendored
@ -13,5 +13,5 @@
|
||||
|
||||
#define THORVG_JPG_LOADER_SUPPORT 1
|
||||
|
||||
#define THORVG_VERSION_STRING "0.8.3"
|
||||
#define THORVG_VERSION_STRING "0.8.4"
|
||||
#endif
|
||||
|
14
thirdparty/thorvg/inc/thorvg.h
vendored
14
thirdparty/thorvg/inc/thorvg.h
vendored
@ -335,6 +335,20 @@ public:
|
||||
*/
|
||||
CompositeMethod composite(const Paint** target) const noexcept;
|
||||
|
||||
/**
|
||||
* @brief Gets the composition source object and the composition method.
|
||||
*
|
||||
* @param[out] source The paint of the composition source object.
|
||||
* @param[out] method The method used to composite the source object with the target.
|
||||
*
|
||||
* @return Result::Success when the paint object used as a composition target, Result::InsufficientCondition otherwise.
|
||||
*
|
||||
* @warning Please do not use it, this API is not official one. It could be modified in the next version.
|
||||
*
|
||||
* @BETA_API
|
||||
*/
|
||||
Result composite(const Paint** source, CompositeMethod* method) const noexcept;
|
||||
|
||||
/**
|
||||
* @brief Return the unique id value of the paint instance.
|
||||
*
|
||||
|
@ -76,7 +76,9 @@ struct SwShapeTask : SwTask
|
||||
|
||||
void run(unsigned tid) override
|
||||
{
|
||||
if (opacity == 0) return; //Invisible
|
||||
auto compMethod = CompositeMethod::None;
|
||||
auto usedAsClip = (sdata->composite(nullptr, &compMethod) == Result::Success) && (compMethod == CompositeMethod::ClipPath);
|
||||
if (opacity == 0 && !usedAsClip) return; //Invisible
|
||||
|
||||
uint8_t strokeAlpha = 0;
|
||||
auto visibleStroke = false;
|
||||
@ -98,7 +100,7 @@ struct SwShapeTask : SwTask
|
||||
sdata->fillColor(nullptr, nullptr, nullptr, &alpha);
|
||||
alpha = static_cast<uint8_t>(static_cast<uint32_t>(alpha) * opacity / 255);
|
||||
visibleFill = (alpha > 0 || sdata->fill());
|
||||
if (visibleFill || visibleStroke) {
|
||||
if (visibleFill || visibleStroke || usedAsClip) {
|
||||
shapeReset(&shape);
|
||||
if (!shapePrepare(&shape, sdata, transform, clipRegion, bbox, mpool, tid, clips.count > 0 ? true : false)) goto err;
|
||||
}
|
||||
@ -110,7 +112,7 @@ struct SwShapeTask : SwTask
|
||||
|
||||
//Fill
|
||||
if (flags & (RenderUpdateFlag::Gradient | RenderUpdateFlag::Transform | RenderUpdateFlag::Color)) {
|
||||
if (visibleFill) {
|
||||
if (visibleFill || usedAsClip) {
|
||||
/* We assume that if stroke width is bigger than 2,
|
||||
shape outline below stroke could be full covered by stroke drawing.
|
||||
Thus it turns off antialising in that condition.
|
||||
@ -291,7 +293,7 @@ bool SwRenderer::viewport(const RenderRegion& vp)
|
||||
}
|
||||
|
||||
|
||||
bool SwRenderer::target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t h, uint32_t cs)
|
||||
bool SwRenderer::target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t h, uint32_t colorSpace)
|
||||
{
|
||||
if (!buffer || stride == 0 || w == 0 || h == 0 || w > stride) return false;
|
||||
|
||||
@ -301,7 +303,7 @@ bool SwRenderer::target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t
|
||||
surface->stride = stride;
|
||||
surface->w = w;
|
||||
surface->h = h;
|
||||
surface->cs = cs;
|
||||
surface->cs = colorSpace;
|
||||
|
||||
vport.x = vport.y = 0;
|
||||
vport.w = surface->w;
|
||||
@ -644,6 +646,13 @@ SwRenderer::SwRenderer():mpool(globalMpool)
|
||||
}
|
||||
|
||||
|
||||
uint32_t SwRenderer::colorSpace()
|
||||
{
|
||||
if (surface) return surface->cs;
|
||||
return tvg::SwCanvas::ARGB8888;
|
||||
}
|
||||
|
||||
|
||||
bool SwRenderer::init(uint32_t threads)
|
||||
{
|
||||
if ((initEngineCnt++) > 0) return true;
|
||||
|
@ -48,7 +48,7 @@ public:
|
||||
|
||||
bool clear() override;
|
||||
bool sync() override;
|
||||
bool target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t h, uint32_t cs);
|
||||
bool target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t h, uint32_t colorSpace);
|
||||
bool mempool(bool shared);
|
||||
|
||||
Compositor* target(const RenderRegion& region) override;
|
||||
@ -56,6 +56,8 @@ public:
|
||||
bool endComposite(Compositor* cmp) override;
|
||||
void clearCompositors();
|
||||
|
||||
uint32_t colorSpace() override;
|
||||
|
||||
static SwRenderer* gen();
|
||||
static bool init(uint32_t threads);
|
||||
static int32_t init();
|
||||
|
2
thirdparty/thorvg/src/lib/tvgAccessor.cpp
vendored
2
thirdparty/thorvg/src/lib/tvgAccessor.cpp
vendored
@ -72,7 +72,7 @@ Accessor::~Accessor()
|
||||
}
|
||||
|
||||
|
||||
Accessor::Accessor()
|
||||
Accessor::Accessor() : pImpl(nullptr)
|
||||
{
|
||||
|
||||
}
|
||||
|
3
thirdparty/thorvg/src/lib/tvgLoadModule.h
vendored
3
thirdparty/thorvg/src/lib/tvgLoadModule.h
vendored
@ -36,6 +36,7 @@ public:
|
||||
float vw = 0;
|
||||
float vh = 0;
|
||||
float w = 0, h = 0; //default image size
|
||||
uint32_t colorSpace = SwCanvas::ARGB8888;
|
||||
|
||||
virtual ~LoadModule() {}
|
||||
|
||||
@ -48,7 +49,7 @@ public:
|
||||
|
||||
virtual bool read() = 0;
|
||||
virtual bool close() = 0;
|
||||
virtual unique_ptr<Surface> bitmap() { return nullptr; }
|
||||
virtual unique_ptr<Surface> bitmap(uint32_t colorSpace) { return nullptr; }
|
||||
virtual unique_ptr<Paint> paint() { return nullptr; }
|
||||
};
|
||||
|
||||
|
6
thirdparty/thorvg/src/lib/tvgMath.h
vendored
6
thirdparty/thorvg/src/lib/tvgMath.h
vendored
@ -53,6 +53,12 @@ static inline bool mathRightAngle(const Matrix* m)
|
||||
}
|
||||
|
||||
|
||||
static inline bool mathSkewed(const Matrix* m)
|
||||
{
|
||||
return (fabsf(m->e21 + m->e12) > FLT_EPSILON);
|
||||
}
|
||||
|
||||
|
||||
static inline bool mathIdentity(const Matrix* m)
|
||||
{
|
||||
if (!mathEqual(m->e11, 1.0f) || !mathZero(m->e12) || !mathZero(m->e13) ||
|
||||
|
19
thirdparty/thorvg/src/lib/tvgPaint.cpp
vendored
19
thirdparty/thorvg/src/lib/tvgPaint.cpp
vendored
@ -38,9 +38,9 @@ static bool _compFastTrack(Paint* cmpTarget, const RenderTransform* pTransform,
|
||||
|
||||
if (rTransform) rTransform->update();
|
||||
|
||||
//No rotational.
|
||||
if (pTransform && !mathRightAngle(&pTransform->m)) return false;
|
||||
if (rTransform && !mathRightAngle(&rTransform->m)) return false;
|
||||
//No rotation and no skewing
|
||||
if (pTransform && (!mathRightAngle(&pTransform->m) || mathSkewed(&pTransform->m))) return false;
|
||||
if (rTransform && (!mathRightAngle(&rTransform->m) || mathSkewed(&rTransform->m))) return false;
|
||||
|
||||
//Perpendicular Rectangle?
|
||||
auto pt1 = pts + 0;
|
||||
@ -384,6 +384,19 @@ CompositeMethod Paint::composite(const Paint** target) const noexcept
|
||||
}
|
||||
|
||||
|
||||
Result Paint::composite(const Paint** source, CompositeMethod* method) const noexcept
|
||||
{
|
||||
if (source) *source = pImpl->compSource;
|
||||
auto met = (pImpl->compSource && pImpl->compSource->pImpl->compData ?
|
||||
pImpl->compSource->pImpl->compData->method : CompositeMethod::None);
|
||||
if (method) *method = met;
|
||||
|
||||
if (pImpl->compSource != nullptr && met != CompositeMethod::None)
|
||||
return Result::Success;
|
||||
return Result::InsufficientCondition;
|
||||
}
|
||||
|
||||
|
||||
Result Paint::opacity(uint8_t o) noexcept
|
||||
{
|
||||
if (pImpl->opacity == o) return Result::Success;
|
||||
|
2
thirdparty/thorvg/src/lib/tvgPaint.h
vendored
2
thirdparty/thorvg/src/lib/tvgPaint.h
vendored
@ -62,6 +62,7 @@ namespace tvg
|
||||
StrategyMethod* smethod = nullptr;
|
||||
RenderTransform* rTransform = nullptr;
|
||||
Composite* compData = nullptr;
|
||||
Paint* compSource = nullptr;
|
||||
uint32_t renderFlag = RenderUpdateFlag::None;
|
||||
uint32_t ctxFlag = ContextFlag::Invalid;
|
||||
uint32_t id;
|
||||
@ -136,6 +137,7 @@ namespace tvg
|
||||
if (!target && method == CompositeMethod::None) return true;
|
||||
compData = static_cast<Composite*>(calloc(1, sizeof(Composite)));
|
||||
}
|
||||
target->pImpl->compSource = source;
|
||||
compData->target = target;
|
||||
compData->source = source;
|
||||
compData->method = method;
|
||||
|
4
thirdparty/thorvg/src/lib/tvgPictureImpl.h
vendored
4
thirdparty/thorvg/src/lib/tvgPictureImpl.h
vendored
@ -66,6 +66,7 @@ struct Picture::Impl
|
||||
void* rdata = nullptr; //engine data
|
||||
float w = 0, h = 0;
|
||||
bool resizing = false;
|
||||
uint32_t rendererColorSpace = 0;
|
||||
|
||||
~Impl()
|
||||
{
|
||||
@ -100,7 +101,7 @@ struct Picture::Impl
|
||||
}
|
||||
}
|
||||
free(surface);
|
||||
if ((surface = loader->bitmap().release())) {
|
||||
if ((surface = loader->bitmap(rendererColorSpace).release())) {
|
||||
loader->close();
|
||||
return RenderUpdateFlag::Image;
|
||||
}
|
||||
@ -124,6 +125,7 @@ struct Picture::Impl
|
||||
|
||||
void* update(RenderMethod &renderer, const RenderTransform* pTransform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag pFlag)
|
||||
{
|
||||
rendererColorSpace = renderer.colorSpace();
|
||||
auto flag = reload();
|
||||
|
||||
if (surface) {
|
||||
|
2
thirdparty/thorvg/src/lib/tvgRender.h
vendored
2
thirdparty/thorvg/src/lib/tvgRender.h
vendored
@ -106,6 +106,8 @@ public:
|
||||
virtual Compositor* target(const RenderRegion& region) = 0;
|
||||
virtual bool beginComposite(Compositor* cmp, CompositeMethod method, uint32_t opacity) = 0;
|
||||
virtual bool endComposite(Compositor* cmp) = 0;
|
||||
|
||||
virtual uint32_t colorSpace() = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
2
thirdparty/thorvg/src/lib/tvgScene.cpp
vendored
2
thirdparty/thorvg/src/lib/tvgScene.cpp
vendored
@ -25,7 +25,7 @@
|
||||
/* External Class Implementation */
|
||||
/************************************************************************/
|
||||
|
||||
Scene::Scene() : pImpl(new Impl())
|
||||
Scene::Scene() : pImpl(new Impl(this))
|
||||
{
|
||||
Paint::pImpl->id = TVG_CLASS_ID_SCENE;
|
||||
Paint::pImpl->method(new PaintMethod<Scene::Impl>(pImpl));
|
||||
|
13
thirdparty/thorvg/src/lib/tvgSceneImpl.h
vendored
13
thirdparty/thorvg/src/lib/tvgSceneImpl.h
vendored
@ -60,6 +60,11 @@ struct Scene::Impl
|
||||
Array<Paint*> paints;
|
||||
uint8_t opacity; //for composition
|
||||
RenderMethod* renderer = nullptr; //keep it for explicit clear
|
||||
Scene* scene = nullptr;
|
||||
|
||||
Impl(Scene* s) : scene(s)
|
||||
{
|
||||
}
|
||||
|
||||
~Impl()
|
||||
{
|
||||
@ -81,8 +86,14 @@ struct Scene::Impl
|
||||
|
||||
bool needComposition(uint32_t opacity)
|
||||
{
|
||||
if (opacity == 0 || paints.count == 0) return false;
|
||||
|
||||
//Masking may require composition (even if opacity == 255)
|
||||
auto compMethod = scene->composite(nullptr);
|
||||
if (compMethod != CompositeMethod::None && compMethod != CompositeMethod::ClipPath) return true;
|
||||
|
||||
//Half translucent requires intermediate composition.
|
||||
if (opacity == 255 || opacity == 0) return false;
|
||||
if (opacity == 255) return false;
|
||||
|
||||
//If scene has several children or only scene, it may require composition.
|
||||
if (paints.count > 1) return true;
|
||||
|
@ -42,6 +42,24 @@ static void _premultiply(uint32_t* data, uint32_t w, uint32_t h)
|
||||
}
|
||||
|
||||
|
||||
static inline uint32_t CHANGE_COLORSPACE(uint32_t c)
|
||||
{
|
||||
return (c & 0xff000000) + ((c & 0x00ff0000)>>16) + (c & 0x0000ff00) + ((c & 0x000000ff)<<16);
|
||||
}
|
||||
|
||||
|
||||
static void _changeColorSpace(uint32_t* data, uint32_t w, uint32_t h)
|
||||
{
|
||||
auto buffer = data;
|
||||
for (uint32_t y = 0; y < h; ++y, buffer += w) {
|
||||
auto src = buffer;
|
||||
for (uint32_t x = 0; x < w; ++x, ++src) {
|
||||
*src = CHANGE_COLORSPACE(*src);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PngLoader::PngLoader()
|
||||
{
|
||||
image = static_cast<png_imagep>(calloc(1, sizeof(png_image)));
|
||||
@ -110,16 +128,21 @@ bool PngLoader::close()
|
||||
return true;
|
||||
}
|
||||
|
||||
unique_ptr<Surface> PngLoader::bitmap()
|
||||
unique_ptr<Surface> PngLoader::bitmap(uint32_t colorSpace)
|
||||
{
|
||||
if (!content) return nullptr;
|
||||
if (this->colorSpace != colorSpace) {
|
||||
this->colorSpace = colorSpace;
|
||||
_changeColorSpace(content, w, h);
|
||||
}
|
||||
|
||||
auto surface = static_cast<Surface*>(malloc(sizeof(Surface)));
|
||||
surface->buffer = (uint32_t*)(content);
|
||||
surface->buffer = content;
|
||||
surface->stride = w;
|
||||
surface->w = w;
|
||||
surface->h = h;
|
||||
surface->cs = SwCanvas::ARGB8888;
|
||||
surface->cs = colorSpace;
|
||||
|
||||
return unique_ptr<Surface>(surface);
|
||||
}
|
||||
|
||||
|
@ -36,11 +36,11 @@ public:
|
||||
bool read() override;
|
||||
bool close() override;
|
||||
|
||||
unique_ptr<Surface> bitmap() override;
|
||||
unique_ptr<Surface> bitmap(uint32_t colorSpace) override;
|
||||
|
||||
private:
|
||||
png_imagep image = nullptr;
|
||||
const uint32_t* content = nullptr;
|
||||
uint32_t* content = nullptr;
|
||||
};
|
||||
|
||||
#endif //_TVG_PNG_LOADER_H_
|
||||
|
@ -28,6 +28,24 @@
|
||||
/* Internal Class Implementation */
|
||||
/************************************************************************/
|
||||
|
||||
static inline uint32_t CHANGE_COLORSPACE(uint32_t c)
|
||||
{
|
||||
return (c & 0xff000000) + ((c & 0x00ff0000)>>16) + (c & 0x0000ff00) + ((c & 0x000000ff)<<16);
|
||||
}
|
||||
|
||||
|
||||
static void _changeColorSpace(uint32_t* data, uint32_t w, uint32_t h)
|
||||
{
|
||||
auto buffer = data;
|
||||
for (uint32_t y = 0; y < h; ++y, buffer += w) {
|
||||
auto src = buffer;
|
||||
for (uint32_t x = 0; x < w; ++x, ++src) {
|
||||
*src = CHANGE_COLORSPACE(*src);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void JpgLoader::clear()
|
||||
{
|
||||
jpgdDelete(decoder);
|
||||
@ -110,18 +128,22 @@ bool JpgLoader::close()
|
||||
}
|
||||
|
||||
|
||||
unique_ptr<Surface> JpgLoader::bitmap()
|
||||
unique_ptr<Surface> JpgLoader::bitmap(uint32_t colorSpace)
|
||||
{
|
||||
this->done();
|
||||
|
||||
if (!image) return nullptr;
|
||||
if (this->colorSpace != colorSpace) {
|
||||
this->colorSpace = colorSpace;
|
||||
_changeColorSpace(reinterpret_cast<uint32_t*>(image), w, h);
|
||||
}
|
||||
|
||||
auto surface = static_cast<Surface*>(malloc(sizeof(Surface)));
|
||||
surface->buffer = (uint32_t*)(image);
|
||||
surface->buffer = reinterpret_cast<uint32_t*>(image);
|
||||
surface->stride = static_cast<uint32_t>(w);
|
||||
surface->w = static_cast<uint32_t>(w);
|
||||
surface->h = static_cast<uint32_t>(h);
|
||||
surface->cs = SwCanvas::ARGB8888;
|
||||
surface->cs = colorSpace;
|
||||
|
||||
return unique_ptr<Surface>(surface);
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ public:
|
||||
bool read() override;
|
||||
bool close() override;
|
||||
|
||||
unique_ptr<Surface> bitmap() override;
|
||||
unique_ptr<Surface> bitmap(uint32_t colorSpace) override;
|
||||
void run(unsigned tid) override;
|
||||
};
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user