Compare commits

...

196 Commits
master ... 4.3

Author SHA1 Message Date
Rémi Verschelde 6699ae7897
Update AUTHORS and DONORS list
(cherry picked from commit a1b081f45c)
2024-09-17 20:47:01 +02:00
Rémi Verschelde 53cde2eb85
i18n: Sync translations with Weblate
Adds Irish (ga) doc translations, and Bengali (bg) editor translations.
2024-09-17 20:46:20 +02:00
Rémi Verschelde 6225d39826
Merge pull request #97082 from akien-mga/4.3-cherrypicks
[4.3] Cherry-picks for the 4.3 branch (future 4.3.1) - 1st batch
2024-09-17 12:39:29 +02:00
patwork 3a2804a7e7
Fix for GLES3 radiance cubemap update
(cherry picked from commit 3038de4245)
2024-09-17 10:00:12 +02:00
Silc Lizard (Tokage) Renew 7b32e96f3d
Fix syncing PhysicalBone internal poses individually
(cherry picked from commit 2b3cf2451f)
2024-09-17 09:59:53 +02:00
Hilderin 15129c044e
Fix error reopening non existing scene on startup
(cherry picked from commit d06c7ad6f0)
2024-09-17 09:59:30 +02:00
Raffaele Picca 56a1d07421
Added a more detailed error message when instatiating a scene with missing export properties.
(cherry picked from commit 1df0159b36)
2024-09-17 09:59:13 +02:00
Pedro J. Estébanez 2c612abdd1
WorkerThreadPool: Fix end-of-yield logic potentially leading to deadlocks
(cherry picked from commit 5dade0e08b)
2024-09-17 09:55:10 +02:00
Rémi Verschelde f273c7c773
thorvg: Update to 0.14.10
More fixes to rendering of SVG files with broken text tags.

Also backports upstream patch to fix #97078.

(cherry picked from commit 0c0336f704)
2024-09-17 08:57:46 +02:00
Rémi Verschelde 99a8821a71
thorvg: Update to 0.14.9
Fixes #96491.

Update fix for #96262 to a simple revert of the problematic commit,
as the upstream fix is still being debated and caused other issues.

Also include fix for upstream regression 2715 added in 0.14.9.

(cherry picked from commit a6ab039f2b)
2024-09-17 08:57:46 +02:00
Rémi Verschelde 7a7e4129bd
thorvg: Update to 0.14.8, and workaround Bezier precision regression
Fixes #96262 by backporting https://github.com/thorvg/thorvg/pull/2702.

(cherry picked from commit 7375f9b923)
2024-09-17 08:57:46 +02:00
Rémi Verschelde 4abc358952
thorvg: Update to 0.14.7
Fixes #95861.

(cherry picked from commit f16d4af342)
2024-09-17 08:57:46 +02:00
Robert Cadena f7ad4dca8c
Remove debug print from Android `DisplayServer.screen_get_scale` implementation
(cherry picked from commit 42b0e91ee4)
2024-09-17 08:57:46 +02:00
bruvzg 35b4a1f374
[Windows] Emit native file dialog callback from event loop, fix selected options not saved.
(cherry picked from commit ea252675aa)
2024-09-17 08:57:46 +02:00
bruvzg 4944d59198
[Windows] Run native file dialogs in thread to make it non-blocking.
(cherry picked from commit 66832e9968)
2024-09-17 08:57:46 +02:00
Mounir Tohami 0a83f06608
Fix `VSlider` grabber area.
(cherry picked from commit 701188fd1e)
2024-09-17 08:57:46 +02:00
HolonProduction 03168cc9d1
LSP: Don't use smart resolve for completion
(cherry picked from commit 8155c1f836)
2024-09-17 08:57:46 +02:00
Silc Lizard (Tokage) Renew 47f34e8436
Add missing "Quad" capture TransitionType enum hint
(cherry picked from commit 8d30ccd067)
2024-09-17 08:57:46 +02:00
Daylily-Zeleen abe68d397e
Fix description of `Array.sort_custom()`
(cherry picked from commit c6f7c89149)
2024-09-17 08:57:46 +02:00
Hilderin 7246e1488e
Fix editor_doc_cache locked on editor startup
(cherry picked from commit e064efccbc)
2024-09-17 08:57:45 +02:00
HolonProduction a2e3c13451
LSP: Omit some values based on specification version 3.17
(cherry picked from commit 4d713d91b5)
2024-09-17 08:57:45 +02:00
Pedro J. Estébanez 3030d4b806
Object: Add tests about the safety of tail destruction
(cherry picked from commit bb77520599)
2024-09-17 08:57:45 +02:00
Pedro J. Estébanez 018f8be3d5
Object: Let debug lock handle callee destruction within call chain gracefully
Co-authored-by: lawnjelly <lawnjelly@gmail.com>
(cherry picked from commit 10e2318bde)
2024-09-17 08:57:45 +02:00
Lisandro Lorea d92f9017c6
Fix gamepad triggers not working on web exports
Fixes #81758

DisplayServerWeb::process_joypads handles buttons 6 and 7 of the
HTML5 Standard Gamepad as a special case by doing:
`input->joy_axis(idx, (JoyAxis)b, s_btns[b]);`

This doesn't work because there is no JoyAxis 6 or 7 in the enum

To fix this we use JoyAxis::TRIGGER_LEFT and TRIGGER_RIGHT for button 6
and 7

However since we are now lying to input->joy_axis we also need to lie in
the mappings for the standard gamepad in godotcontrollersdb.txt,
otherwise input->joy_axis will try to find a mapping to axis 4(LT) and
axis 5(RT) that's not defined.

Therefore we set lefttrigger to +a4 and righttrigger to +a5 in the
mapping, to match what we are actually sending.

A cleaner, and more involved fix to this would be modifying
input->joy_button so that it can handle analog buttons and map them to
axes preserving their value instead of converting to boolean

(cherry picked from commit 9dd372f316)
2024-09-17 08:57:45 +02:00
A Thousand Ships 34251cf5b3
[Windows] Use `GetFileTime` for `FileAccess`
Prevents DST from rearranging file times.

(cherry picked from commit 7139f46c9a)
2024-09-17 08:57:45 +02:00
Giganzo d00e4fbb16
Fix double lock/group buttons when starting editor with empty scene
(cherry picked from commit 96aa2f285c)
2024-09-17 08:57:45 +02:00
Giganzo 927d7a9250
Fix below what value is invalid in default_font_size doc
(cherry picked from commit 575a0b4dfb)
2024-09-17 08:57:45 +02:00
Giganzo 13701384ab
Fix slider size in compact mode
(cherry picked from commit f21a969bb9)
2024-09-17 08:57:45 +02:00
Hristo Iliev f4b71b5325
Fix polygon node losing its UV toolbar by adding a call to the show method when assinging a node.
Fixes #96238

(cherry picked from commit dabeaa6a4b)
2024-09-17 08:57:45 +02:00
DeeJayLSP 51c86eb085
WAV: Fix one frame overflow at the end
(cherry picked from commit 147accdf74)
2024-09-17 08:57:45 +02:00
BlueCube3310 4addddd8df
Compatibility: Fix alignment of compressed textures when retrieving
(cherry picked from commit 0182294b37)
2024-09-17 08:57:45 +02:00
Dowsley 6dd8e7fece
Update AnimationPlayer in real-time when bezier curve properties or bezier editor changes
(cherry picked from commit 9d0944b673)
2024-09-17 08:57:45 +02:00
bruvzg 69713dadf0
[RTL] Fix font not updated for some spans.
(cherry picked from commit e517eaf053)
2024-09-17 08:57:45 +02:00
Mikael Hermansson 90f1c3e7bd
Fix issue with GDScript binary tokens being non-deterministic
(cherry picked from commit e120792760)
2024-09-17 08:57:45 +02:00
A Thousand Ships d51be1f68d
[Buildsystem] Improve cache handling
Prevents cache issues by not purging cache before starting a build.
Splits cache purge related code from progress code and delays the purge
until after final build is done.

(cherry picked from commit acffc53e01)
2024-09-17 08:57:45 +02:00
Rudolph Bester 3fac9e43af
Fixed OpenGL shadow textures not honoring texture type when reusing textures
(cherry picked from commit 359aaa48ee)
2024-09-17 08:57:44 +02:00
Haoyu Qiu 1d790deedb
Fix parsing of `4.` in Expression
(cherry picked from commit ee9cea521d)
2024-09-17 08:57:44 +02:00
kleonc 88370e44d8
Fix undoing "Move tiles" TileMapLayer action when drag/drop areas overlap
(cherry picked from commit ab504b3139)
2024-09-17 08:57:44 +02:00
shahriarlabib000 c7a173aa60
Fix directory empty bug on Android
(cherry picked from commit 8f66513bad)
2024-09-17 08:57:44 +02:00
Yaohua Xiong e7e723b3e3
Do not defer PathFollow3D transform updates
Co-authored-by: Yaohua Xiong <xiongyaohua@gmail.com>
(cherry picked from commit 51b8b74d4b)
2024-09-17 08:57:44 +02:00
Praytic 281642831c
Enable MSAA support for all non-web platforms
MSAA support is built into GLES3 core, eliminating the need to check for GL_EXT_framebuffer_multisample, which was necessary only in GLES2 due to the lack of inherent multisample framebuffer support. This commit corrects an oversight from GLES2-based code, ensuring compatibility with GLES3 where multisampling is natively supported without extensions.

(cherry picked from commit fc955fa89f)
2024-09-17 08:57:44 +02:00
bruvzg 6b7f36e2a9
[Windows] Fix broken apksigner detection.
(cherry picked from commit 2c991a727b)
2024-09-17 08:57:44 +02:00
Pedro J. Estébanez f757cc9a70
RenderingDevice: Fix uncapped mipmap sizes causing div-by-zero
(cherry picked from commit 7f1989bac1)
2024-09-17 08:57:44 +02:00
ajreckof cab91cf8fb
fix clear button on Array[Node]
(cherry picked from commit dee0453b57)
2024-09-17 08:57:44 +02:00
Adam Scott 0b815cbb99
Fix leak when using audio samples instead of streams
(cherry picked from commit d3ddce6b88)
2024-09-17 08:57:44 +02:00
Pedro J. Estébanez f11f9e3b7f
AudioServer: Fix code style issues
- Drop STL copy in favor of old-school for loops.
- Be explicit about loads and stores to atomic value. (This also fixes an error in certain compiler toolchains.)

(cherry picked from commit 1cc485ba1f)
2024-09-17 08:57:44 +02:00
A Thousand Ships b2b882cc1d
Fix super call in various `get_configuration_warnings` methods
(cherry picked from commit 9dc231366d)
2024-09-17 08:57:44 +02:00
Gustavo Jaruga Cruz f5b5b6cbfe
Fix interactive audio transitions fade in for clips with auto_advance
(cherry picked from commit 4fa6287de1)
2024-09-17 08:57:44 +02:00
RedMser 02c45088ea
Fix "reparent to new node" when node has internal children
(cherry picked from commit 8da49ab947)
2024-09-17 08:57:44 +02:00
RedMser 7f0cc1aa35
Fix "reparent to new node" not remembering index
(cherry picked from commit b11ccf3c77)
2024-09-17 08:57:44 +02:00
kleonc 21a0a84c6f
Fix StyleBoxFlat rectangles skewing independently
(cherry picked from commit 86c773d208)
2024-09-17 08:57:44 +02:00
jsjtxietian fb1758ce23
Fixes godot crash or give unclear message when exporting with invalid args
(cherry picked from commit 1d09970404)
2024-09-17 08:57:44 +02:00
Danil Alexeev c4525f24e3
GDScript: Do not produce `UNUSED_SIGNAL` warning for common implicit uses
(cherry picked from commit d1e2afaae3)
2024-09-17 08:57:43 +02:00
Giganzo 61b2ad9242
Fix Set Frame Title popup position
(cherry picked from commit 7d78d753b5)
2024-09-17 08:57:43 +02:00
smix8 d7a8654edd
Fix 2D debug navigation flickering with tile maps
Both the tile map layers and the debug navigation canvas items did fight for the same z order causing a lot of flickering in certain situations.

(cherry picked from commit 5bedaf77f7)
2024-09-17 08:57:43 +02:00
Giganzo 1629e9b1fa
Fix shift clicking on Add Sun/Environment to Scene buttons
(cherry picked from commit 1b6af3acd3)
2024-09-17 08:57:43 +02:00
A Thousand Ships 3783527410
[Editor] Fix handle ID being passed for 3D Gizmo plugins
(cherry picked from commit 62d98c6f02)
2024-09-17 08:57:43 +02:00
A Thousand Ships 00866dc80a
[Editor] Prevent duplicate `Open in Editor` buttons in scene tree dock
Duplicate buttons were added when editor description changed

(cherry picked from commit ab04d76e0e)
2024-09-17 08:57:43 +02:00
Hilderin d842870331
Fix selection stuck after saving scene
(cherry picked from commit 613d4d10cb)
2024-09-17 08:57:43 +02:00
detomon 2635ff777e
Prevent editing value on focus when `EditorSpinSlider` is read-only
(cherry picked from commit 88f1b679f3)
2024-09-17 08:57:43 +02:00
ev13bird cbcc5f8d19
Fix instant transformations not being committed when used in succession
Also:
- Fix holding down keys repeatedly committing instant transformations, and disallow starting instant during non-instant
- Fix echoed inputs starting new instant transformations after clicking to confirm, and disallow left mouse release committing instant transformations

(cherry picked from commit 060a1a0899)
2024-09-17 08:57:43 +02:00
A Thousand Ships 64cbde426f
[Editor] Don't show popup when clicking empty in Favorites
(cherry picked from commit d2a8b330d8)
2024-09-17 08:57:43 +02:00
bruvzg b1c1c40250
[Windows] Use the same API for all `OS_Windows::*_environment` functions.
(cherry picked from commit 319bfa9965)
2024-09-17 08:57:43 +02:00
clayjohn e09cada53f
Only use backbuffer mipmaps in SCREEN_TEXTURE when generated.
(cherry picked from commit d2f5c1a552)
2024-09-17 08:57:43 +02:00
Alexis Breust 2b05cf154a
Sky: No more auto-selecting REALTIME mode if radiance is not 256
(cherry picked from commit 44e526d3d5)
2024-09-17 08:57:43 +02:00
Arsh Panesar 26cc13705a
Fix `AnimationPlayer` crash when it's made the scene root
When an AnimationPlayer is made root of a scene,
the track links may become broken and clicking on
them will crash.

Current master branch also breaks node links when
AnimationPlayer is made scene root, and can also
crash the engine if another node was made scene
root prior to the AnimationPlayer.

This happens because when made root, the editor
loses track of AnimPlayer's root node. By keeping
a copy of the AnimPlayer's root_node, the track
links remain functional.

Fixes #91043.

(cherry picked from commit e905be8249)
2024-09-17 08:57:43 +02:00
Radiant af8caffd0e
Fix shadow mesh recursion.
(cherry picked from commit 70860aafd8)
2024-09-17 08:57:43 +02:00
aaronp64 ec20c3ff76
Fix Array.sort_custom example code
Array.sort_custom descending sort example was comparing index 0, but had expected result based on comparing index 1.  Updated to use index 1 consistently.

(cherry picked from commit 39ca8b4e23)
2024-09-17 08:57:43 +02:00
aaronp64 a2f64b3c10
Fix SubViewport/AudioStreamPlayer2D crash
Updated Viewport destructor to remove itself from World2D, to avoid World2D keeping invalid pointers.

(cherry picked from commit 7a9acd5aca)
2024-09-17 08:57:42 +02:00
kobewi fc5e7c7411
Fix Path2D splitting
(cherry picked from commit 7e7a4f238b)
2024-09-17 08:57:42 +02:00
Giganzo 1e5d7a0907
Fix floating window corner radius
(cherry picked from commit 308186a89e)
2024-09-17 08:57:42 +02:00
Hilderin 4d0f10a543
Fix missing material override after two glb reimports
(cherry picked from commit 79d0254a2d)
2024-09-17 08:57:42 +02:00
kerstop f8c9ec3f37
fix deadzone slider not working correctly
(cherry picked from commit 2fd39eca30)
2024-09-17 08:57:42 +02:00
bruvzg fd17fae4bd
[RTL] Do not add final newline to the paragraph context.
(cherry picked from commit 02113dff83)
2024-09-17 08:57:42 +02:00
clayjohn b1fda8f5c4
Avoid indexing instances without a base in scene cull phase
(cherry picked from commit b5fd29e7bc)
2024-09-17 08:57:42 +02:00
clayjohn 1250b4568a
Various fixes for transmittance effect
Use correct shadow sampling for omni and spot lights

Disable transmittance if shadows are disabled

Correct DirectionalLight transmittance bias to match shadow bias (its still pretty sensitive though)

(cherry picked from commit d61fae36f3)
2024-09-17 08:57:42 +02:00
ComycSans 430a69baed
Fix SkyRD::Sky::free() freeing material
(cherry picked from commit 09e59fbec5)
2024-09-17 08:57:42 +02:00
Silc Lizard (Tokage) Renew b60bf28a2f
Fix physical bone update without simulating
(cherry picked from commit f2186eeac0)
2024-09-17 08:57:42 +02:00
NotWearingPants 5567fedd04
NoiseTexture2D/3D: Don't use a thread to regenerate when the build doesn't support threads
(cherry picked from commit b47b98db34)
2024-09-17 08:57:42 +02:00
Fabio Alessandrelli 1a5ac1fd59
[MP] Fix division by zero in network profiler
The debugger reports synchronizers with empty state to the editor
even if no data is being sent to other peers.

The editor conditional to avoid division by zero was checking the wrong
variable.

(cherry picked from commit 042b264c55)
2024-09-17 08:57:42 +02:00
Haoyu Qiu e72e42fe9b
Fix collapsing TreeItem not updating horizontal scrollbar
(cherry picked from commit d16dcbb3ac)
2024-09-17 08:57:42 +02:00
Lars Pettersson f783cf7b81
Fix Polygon2D UV editor error when opening grid settings
(cherry picked from commit 5a0a0257e1)
2024-09-17 08:57:42 +02:00
viksl f3848b75cb
Fixes alpha materials being rendered with a reverse cull which is visible in reflections from reflection probes.
(cherry picked from commit 929c69bad8)
2024-09-17 08:57:42 +02:00
David Snopek 19843328d9
GDExtension: Show warning on missing PDB file, rather than error
(cherry picked from commit 760099ca6f)
2024-09-17 08:57:42 +02:00
Hilderin 1e9f578740
Fix no unsaved indicator Save As resource
(cherry picked from commit b97c128b34)
2024-09-17 08:57:42 +02:00
clayjohn 0a1724f713
Use correct lightmap coefficients to ensure that the directional lightmap mode looks correct
Also remove the metallic option from directional lightmap as it is guaranteed to return negative numbers in many cases

(cherry picked from commit f4ccba7508)
2024-09-17 08:57:41 +02:00
Leonardo Demartino e79157af72
Only main binaries require entitlements. This fixes signing issues on macOS.
(cherry picked from commit 0a57dd4682)
2024-09-17 08:57:41 +02:00
Hristo Iliev 6ab9ec33f2
Add modf function and fix snap behavior
Fixes #96159

(cherry picked from commit fcc8518bce)
2024-09-17 08:57:41 +02:00
MBCX 4acc73dbfa
Make sure huf_decompress is only applied to 64-bit x86.
(cherry picked from commit 6b13236956)
2024-09-17 08:57:41 +02:00
kleonc e549ab35fa
Fix SceneTreeDock invalid state after trying to remove internal Node
(cherry picked from commit 5ae85a4fb9)
2024-09-17 08:57:41 +02:00
RedOrbweaver 43fa723659
Fix build logger unable to handle an event without an associated file
(cherry picked from commit 81799b8fa3)
2024-09-17 08:57:41 +02:00
passivestar 1c9ba616d5
Fix missing project date showing the unix epoch
(cherry picked from commit 6ed54ab9ba)
2024-09-17 08:57:41 +02:00
DeeJayLSP 682ee73f64
Fix memory leak on QOA import
(cherry picked from commit e67cc73463)
2024-09-16 17:25:14 +02:00
David Snopek 9946eba398
Windows: Call `AddDllDirectory()` with an absolute path
(cherry picked from commit e8bd385f53)
2024-09-16 17:24:05 +02:00
Saracen 30bba8745c
Fix crash when selecting ownerless 3D node.
(cherry picked from commit 279ccd6d32)
2024-09-16 17:23:54 +02:00
Togira c4351c8d98
Fix RandomPCG::rand_weighted incorrectly returning -1
(cherry picked from commit ab13513403)
2024-09-16 17:23:44 +02:00
jsjtxietian e2184c5da0
Support opening custom class documentation with "Open Documentation" menu entry
(cherry picked from commit b5fa2a3d3a)
2024-09-16 17:23:31 +02:00
kit 4fabc1ba58
Fix script overwriting with external editor
(cherry picked from commit 23927c3d9b)
2024-09-16 17:23:16 +02:00
kleonc 4d7feff723
Fix snapping when zoomed in Polygon2D UV editor
(cherry picked from commit 1b7626f391)
2024-09-16 17:22:50 +02:00
Fabio Alessandrelli 1d775b5b97
[mbedTLS] Fix incorrect cert pinning with client_unsafe
(cherry picked from commit ccae47ab66)
2024-09-16 17:22:33 +02:00
bruvzg b6055941b9
[Windows] Hide cursor before moving.
(cherry picked from commit 9a2977fef1)
2024-09-16 17:20:22 +02:00
Sen e5be133032
Fix for multimesh motion vector corruption by resetting motion vector state and filling both halves of buffer
(cherry picked from commit 52cd5acdda)
2024-09-16 17:19:58 +02:00
Fredia Huya-Kouadio 0f33a4b97e
Fix invalid `Skeleton3D` bone pose updates
The issue would cause log spams when trying to update the bone pose position or rotation with an invalid bone index.

(cherry picked from commit 039722a341)
2024-09-16 17:19:17 +02:00
Rakka Rage f9bcd4f0ca
Enable revert button for `ShaderMaterial::next_pass` and `ShaderMaterial::render_priority`.
(cherry picked from commit ba23b22153)
2024-09-16 17:19:07 +02:00
Jason Wodicka 169b568e65
Fix C# code example for Object._get_property_list
There were two small errors in this code example that kept it from working when copied to a new node locally. These are the fixes I used locally to test the example.

(cherry picked from commit 97cf2c147e)
2024-09-16 17:18:54 +02:00
Mikael Hermansson 95a0525361
Fix animation library copy-paste not preserving resource reference
(cherry picked from commit 08ef14a037)
2024-09-16 17:18:40 +02:00
BlueCube3310 8e1d1a54fe
Compatibility: Fix crash when initializing certain compressed layered textures
(cherry picked from commit e8b4568900)
2024-09-16 17:18:24 +02:00
Paul Joannon 99dde70ad3
Fix relative paths for global class icons in C#
(cherry picked from commit 3c0eaec39f)
2024-09-16 17:18:14 +02:00
bruvzg e59f59a439
[Editor] Prevent unnecessary editor theme regeneration on unrelated system setting update.
(cherry picked from commit 97085358ce)
2024-09-16 17:18:03 +02:00
Joel Winarske afc330e33f
Use wayland-egl-core.h instead of wayland-egl.h
-avoid use of transitive wayland include

-resolves https://github.com/godotengine/godot/issues/95830

Signed-off-by: Joel Winarske <joel.winarske@gmail.com>
(cherry picked from commit 6ce71f0fb0)
2024-09-16 17:17:49 +02:00
Adam Scott 219ddde30c
Honor `pitch_scale` value before playing audio sample
(cherry picked from commit aaafd163b2)
2024-09-16 17:15:29 +02:00
kobewi 2dd696867f
Always store ID of PopupMenu items
(cherry picked from commit 5279fec60f)
2024-09-16 17:15:19 +02:00
Dungeon Master 9cf21b4b03
Fix some C# variable types In `AStar2D/3D` Class Reference
(cherry picked from commit 1928a84f6e)
2024-09-16 17:15:07 +02:00
Tallivm 497570b1cf
Fix typo in Array code example
(cherry picked from commit b516742358)
2024-09-16 17:14:51 +02:00
David Snopek 70a8761deb
Fix crash when calling OpenXRAPI::get_hand_tracker() and hand-tracking is disabled
(cherry picked from commit 11dd1f52ae)
2024-09-16 17:14:35 +02:00
Z0rb14n 19bed8fee7
Fix Vector3 Slerp Normalizing Zero Vectors
Ported the existing zero length check in C++ into C#.

(cherry picked from commit 0d6e9de0b9)
2024-09-16 17:14:24 +02:00
aaronp64 7874dad279
Minor AnimationNodeBlendSpace2D documentation fixes
Updated a couple parts that seemed to be copied over from AnimationNodeBlendSpace1D

(cherry picked from commit 05bcfda784)
2024-09-16 17:12:52 +02:00
jsjtxietian 05860062a5
Fix curve2d incorrect sample range description
(cherry picked from commit 5183588499)
2024-09-16 17:12:40 +02:00
Hilderin 8496e0738f
Fix drag&drop between window on Windows
(cherry picked from commit 0987a9dc06)
2024-09-16 17:12:26 +02:00
tetrapod00 20ce427a6c
Remember "View Grid" (per-viewport) setting between editor sessions
(cherry picked from commit 080acd7246)
2024-09-16 17:11:42 +02:00
Arseny Kapoulkine 40dcdcbe79
Fix double free in FSR2 destructor
Before this change, using FSR2 resulted in the following error when the
effect was destroyed:

	ERROR: Attempted to free invalid ID: 662734928609453
	   at: _free_internal (servers/rendering/rendering_device.cpp:4957)

This happened because ACCUMULATE and ACCUMULATE_SHARPEN passes shared
the same shader_version object but had different pipeline IDs. When
version_free was called for ACCUMULATE pass, it destroyed pipelines
created from that version, including the pipeline for the
ACCUMULATE_SHARPEN pass.

Using a unique version could work around this problem, but it's easier
to rely on version_free destroying the created pipelines through the
dependency mechanism.

(cherry picked from commit 0024cface5)
2024-09-16 17:10:59 +02:00
Arseny Kapoulkine b2c83b42f6
Relax motion vector updates to allow skipped frames for skeletons
Before this change, a skeleton that was not updated every frame would
result in a difference of 2+ between last_change and frame index every
frame, which would disable the buffer rotation and set motion vectors to
zero. This results in significant visual artifacts for FSR2 that are
especially prominent on the characters that move together with the view
such as the main character in third person mode.

This is a significant problem for high refresh rate displays: at 120 Hz,
we are effectively guaranteed to skip skeleton updates every other frame
with skeleton update happening during physics processing, and the lack
of physics interpolation for skeletons. This happens by default in TPS
demo when FSR2 is enabled.

In other places where motion vectors are disabled, such as multi-mesh
and mesh rendering (where previous transform is updated), the logic
effectively allows for a single-frame gap in updates, because it
compares the frame where the update happened (which is the current frame
if updates are consistent) with the current frame, so the latency of 0
means "update just happened", but both multi-mesh and mesh transform
updates permit a latency of 1 as well.

Here, however, last_change is updated *after* the frame processing has
concluded, so a zero-latency update has a distance of 1. Allowing a
distance of 2 (latency 1) reduces the severity of the problem and aligns
the logic with transform updates.

Note that the problem will still happen when refresh rate is noticeably
higher than physics rate times 2. For example, it still happens at 240
Hz. However, a longer latency allowance is inconsistent with other
transforms and could lead to issues, so ideally long term physical
interpolation of skeleton transforms would completely solve this.

(cherry picked from commit 92f2bc70dd)
2024-09-16 17:10:47 +02:00
Giganzo cf40a5bc5a
Fix huge tscn icon in FileSystem split mode using list view
(cherry picked from commit 36c9d31a9e)
2024-09-16 17:10:34 +02:00
Mikael Hermansson 1ecf20c783
Fix errors about `UndoRedo` history mismatch when deleting bezier track
(cherry picked from commit 4db3e6e6cd)
2024-09-16 17:10:19 +02:00
Hilderin b05470efd0
Fix display dialog while saving scene
(cherry picked from commit da31679d12)
2024-09-16 17:10:04 +02:00
aryan-11825114 433509b489
Fix small graph editor pins at higher display scales
(cherry picked from commit 3f7efd2291)
2024-09-16 17:09:50 +02:00
jsjtxietian 139f5ee15e
Add model_normal_matrix for fragment shader
(cherry picked from commit e698351db2)
2024-09-16 17:09:36 +02:00
matheusmdx bd552ff609
Fallback to theme icon when no custom icon is set in autocompletion
(cherry picked from commit e8254dc3f4)
2024-09-16 17:09:23 +02:00
Orion Lawlor ecbb9a9c6a
Fix GLES3 crash with Mesh surface with exactly 65536 vertices
Fixes #95837.

(cherry picked from commit bde165ccb3)
2024-09-16 17:09:12 +02:00
Juan Pablo Arce d0c4f19dd2
Fix gizmos without visible geometry not being selectable
The issue was that Node3DEditorViewport was using the render server's BVH to filter out nodes,
which is not correct for gizmos that have no renderable components,
or have collision triangles that exceed the bounds of their renderable components.

(cherry picked from commit 45f6110e26)
2024-09-16 17:08:59 +02:00
kleonc df6bbb2538
Fix MenuBar popup placement assuming it's in viewport default canvas
(cherry picked from commit 8228d647a9)
2024-09-16 17:08:44 +02:00
Aaron Franke 1d0bcae019
GLTF: Propagate owner for root node children
(cherry picked from commit 246cc7e86d)
2024-09-16 17:08:33 +02:00
voidedWarranties df522db6f0
Fix virtual binding for `ScriptLanguageExtension::_reload_scripts`
(cherry picked from commit d65ea6fb9c)
2024-09-16 17:06:44 +02:00
clayjohn c684d65c64
Use transformed roughness instead of raw roughness to calculate roughness fade in SSR
(cherry picked from commit b99d0d778a)
2024-09-16 17:06:30 +02:00
Pedro J. Estébanez 5676d398e0
Avoid potential crash on signal disconnection
(cherry picked from commit 32b7f835d8)
2024-09-16 17:06:19 +02:00
jordi 32f2b851ab
Redraw SubViewportContainer on SubViewport size change
(cherry picked from commit 61e2aa7914)
2024-09-16 17:06:04 +02:00
Gergely Kis bf5907b724
StringName: Use inline static field definitions
Before this change StringName used regular static field
definitions for its mutex, _table, configured and debug_stringname
fields.

Since in the general case the ordering of the static variable and field
initialization and destruction is undefined, it was possible that
the destruction of StringName's static fields happened prior to
the destruction of statically allocated StringName instances.

By changing the static field definitions to inline in string_name.h,
the C++17 standard guarantees the correct initialization and destruction
ordering.

(cherry picked from commit 723878bbab)
2024-09-16 17:05:50 +02:00
Robert Yevdokimov cff0ebd603
Clear drag preview material on `NOTIFICATION_DRAG_END`
(cherry picked from commit 6aee6c1fdd)
2024-09-16 17:05:37 +02:00
MrPersonDev 9af6e04a15
Fix backspace always unfolding previous line
(cherry picked from commit 2860b99077)
2024-09-16 17:05:16 +02:00
Hilderin 39fb871310
Fix no validation on Blender path on importation
(cherry picked from commit 2dc9cf50c5)
2024-09-16 17:05:03 +02:00
Silc Lizard (Tokage) Renew eaa8ecb182
Fix bone2d scaling
Co-authored-by: Thiago Lages de Alencar <thiagola92@gmail.com>
(cherry picked from commit de558123bf)
2024-09-16 17:04:49 +02:00
kleonc c7dbcbd6d4
Fix Skeleton2D.{_set|_get} always returning true
(cherry picked from commit 115cd47fd6)
2024-09-16 17:04:28 +02:00
kleonc f0f69a7b7c
Fix Parallax2D repeats being not relative to its transform
(cherry picked from commit 1bd8372813)
2024-09-16 17:04:12 +02:00
Artemy Fedotov 4168220169
Fix `EditorInterface.get_selected_paths()` working incorrectly when FileSystemDock is in split mode
(cherry picked from commit b55e97cd85)
2024-09-16 17:03:50 +02:00
Hilderin d8c13f88ed
Fix scene node selection problem when no auto expand
(cherry picked from commit e46280dbb5)
2024-09-16 17:03:02 +02:00
Radiant 7266418bdf
Fix node.duplicate, return nullptr if this operation fails.
(cherry picked from commit 70f41e414e)
2024-09-16 17:02:35 +02:00
Hilderin b7fc063038
Fix uid:// Paths Fail to Load at Editor Startup
(cherry picked from commit b1c97313e0)
2024-09-16 17:02:12 +02:00
clayjohn 6c202154a7
Add fixed fog to the sky in the Compatibility renderer
And apply luminance multiplier after fog in RD renderer

(cherry picked from commit 578049b7b9)
2024-09-16 17:01:45 +02:00
Rémi Verschelde 6d41487459
OpenXR: Fix support for building against distro package
(cherry picked from commit 2206f5c6a4)
2024-09-16 17:01:18 +02:00
Cory Petkovsek 3876287162
Ensure selected node is a descendant of the edited scene
(cherry picked from commit b1a45d9487)
2024-09-16 17:00:54 +02:00
Kusok 8ea64814ed
Add `stop_callable` to `AudioStreamPlayerInternal`
(cherry picked from commit 8c7dd3cb61)
2024-09-16 17:00:18 +02:00
Nodragem 6b323241b1
prevent the click to get processed further after a paste action
(cherry picked from commit e7e633760a)
2024-09-16 16:57:44 +02:00
clayjohn 2d7266e764
Ensure fog_sky_affect is used even when using a background color
(cherry picked from commit 37be585fdf)
2024-09-16 16:57:44 +02:00
Rio Arswendo Rachmad 7726ced085
fix: project settings not properly saved after a file removal
(cherry picked from commit 138bcc7cfd)
2024-09-16 16:56:22 +02:00
jsjtxietian bba8f85945
Fix Pressing Escape doesn't exit freelook in the 3D editor
(cherry picked from commit 78dc310103)
2024-09-16 16:56:10 +02:00
Juan Pablo Arce 63ff665fd0
Fix GD0107 not applying to arrays and dictionaries containing nodes
(cherry picked from commit 8aa444d212)
2024-09-16 16:55:57 +02:00
Joel Croteau 6e78eec37f
Fix reload of GDExtension libraries in framework package on macos
`GDExtension::open_library` has a check in it to see if the library was loaded
from a temp file, and if it was to restore the original name as that is the one
we actually care about. This check is breaking extension reloading on Mac when
the library path is to a framework folder, as the file inside the framework
will not generally be the same name as the folder.

This check also shouldn't be necessary even on Windows, which is the only
platform that uses `generate_temp_files`, since disposal of the created temp
file is handled within `OS_Windows::open_dynamic_library`, and
`GDExtension::open_library` (which is the only function to call
`open_dynamic_library` with a `p_data` argument) only cares about the original
library file path and has to do extra work to remove the name of the temp file.
Instead, I have removed that check and set `OS_Windows::open_dynamic_library`
to return the name of the original file and not the name of the copy.

This fixes GDExtension reloading on macOS. I do not have a Windows machine
available to test that it still works properly on Windows, so someone should
check that before merging this.

(cherry picked from commit f44d6a235f)
2024-09-16 16:55:39 +02:00
ocean 6eea970e8c
Fix Godot not quitting with `--doctool --gdscript-docs`.
(cherry picked from commit 13b20820ba)
2024-09-16 16:55:26 +02:00
kevinkuo52 6aff947ee5
pass in render_info to _fill_instance_data for alpha to fix overdraw call count
(cherry picked from commit 3388a4a360)
2024-09-16 16:55:12 +02:00
bruvzg 686591b948
[ImageFont] Fix escape sequence parsing, add note to the docs.
(cherry picked from commit 4cc065c2db)
2024-09-16 16:54:56 +02:00
Jiří Švejda acba31b746
Fix SoftBody3D pinned points breaking when reloading scene
(cherry picked from commit bde8c5977b)
2024-09-16 16:47:13 +02:00
kleonc d915947f3d
Fix transposed tiles drawing in GenericTilePolygonEditor
(cherry picked from commit 3dfac1644d)
2024-09-16 16:47:00 +02:00
kleonc a031407e82
Fix TileAtlasView bounds checks for transposed tiles
(cherry picked from commit 6895f6f8cc)
2024-09-16 16:46:57 +02:00
Fredia Huya-Kouadio 26b151a945
Update the Android `fileLastModified` method to return values in seconds instead of milliseconds
(cherry picked from commit cde873b406)
2024-09-16 16:46:41 +02:00
tetrapod00 2eb2052cb9
Change "Node3D" to "Spatial" in VisualShader resource
(cherry picked from commit b9876b626d)
2024-09-16 16:46:29 +02:00
kit 1f92092b08
Fix EditorSpinSlider when hidden
(cherry picked from commit d357a7d0f9)
2024-09-16 16:46:07 +02:00
Pedro J. Estébanez c831bdbbe2
D3D12: Be explicit about all-resources texture barriers
(cherry picked from commit 3260437afc)
2024-09-16 16:45:55 +02:00
smix8 ea5989e3f5
Add NavigationLink function to change navigation map
Adds NavigationLink function to change navigation map.

(cherry picked from commit e6ff4e56e3)
2024-09-16 16:45:38 +02:00
Jordyfel 6073b86e71
Fix typo in MultiplayerSpawner doc
(cherry picked from commit 8c626f23c1)
2024-09-16 16:45:24 +02:00
jsjtxietian b84dbab84d
Fix undefined `alpha_scissor` in standard shader
(cherry picked from commit 970a237c20)
2024-09-16 16:42:01 +02:00
Michael Alexsander 1ebf488a4e
Fix incorrect parsing of nested nodes when generating the POT
(cherry picked from commit 84c5403578)
2024-09-16 16:41:48 +02:00
Hilderin 4a64c95732
Fix autoload node cannot be accessed by plugin on start-up
(cherry picked from commit 2d4e573b20)
2024-09-16 16:41:32 +02:00
Yahkub-R 2b4ade1ed6
Fix AudioStreamPlayer get_playback_position() for web build
(cherry picked from commit bcd776e441)
2024-09-16 16:41:06 +02:00
Haoyu Qiu 562e583872
Fix split_floats behavior when spaces are used as separators
(cherry picked from commit f483c3aafa)
2024-09-16 16:40:48 +02:00
Ian McCleary cfa33666c9
Fix custom resources using incorrect icons
(cherry picked from commit 140f9dc3e7)
2024-09-16 16:40:33 +02:00
Chaosus 3dc376ec0b
Fix shader crash when the comma used in `for` loop as a trailing
(cherry picked from commit d74749fd60)
2024-09-16 16:39:51 +02:00
bruvzg a7d79f9e6c
Fix `TextServer::shaped_text_*_character_pos` for the first character of wrapped string. Allow starting/ending RTL selection before line start.
(cherry picked from commit 932acce8f2)
2024-09-16 16:38:23 +02:00
bruvzg fac12603ef
[.NET] Move search in files extension list definition to be after Scene level module init.
(cherry picked from commit 69d52ed081)
2024-09-16 16:38:08 +02:00
bruvzg 8c5edcb03a
Run cleanup code on DisplayServer init failure to prevent crash on exit.
(cherry picked from commit f15ad72355)
2024-09-16 16:37:54 +02:00
bruvzg 79848620ce
[BMFont] Fix importing fonts with `Match char height` enabled.
(cherry picked from commit e7f215c2c4)
2024-09-16 16:35:06 +02:00
Jonatan Röjder Delnavaz 91ed3cd307
* Changed the VisualShaderNodeCustom template to use the correct overrides and added the GlobalClass attribute
(cherry picked from commit 74389e8395)
2024-09-16 16:34:53 +02:00
aaronp64 302af188a1
Fix tooltip content being cut off at some display scales
When getting the minimum size for a tooltip, we get the value as a Vector2.  Window::set_size() takes a Vector2i, so this size was getting truncated.  At certain display scales, this could be enough to cut off part of the tooltip.  Updated to call Vector2::ceil() to round up before calling Window::set_size()

Fixes #91958

(cherry picked from commit ca8e3d4923)
2024-09-16 16:34:31 +02:00
Zi Ye 2eec361f5f
Corrected rotation gizmo plane math for off-center perspective view.
(cherry picked from commit 1fc8255355)
2024-09-16 16:34:16 +02:00
jsjtxietian a70df8537e
Fix uniform subgroup in shader will carry out to next group
(cherry picked from commit e6c45fbe5d)
2024-09-16 16:34:02 +02:00
clayjohn cbee16418a
Increase precision of skeleton transforms in the skeleton shader in the Compatibility renderer
(cherry picked from commit 1bf594fb5a)
2024-09-16 16:33:38 +02:00
clayjohn 5a33e45fed
Fail when submit or sync called on main rendering device
Fail if submit or sync called multiple times in a row

(cherry picked from commit b0e33aa00f)
2024-09-16 16:33:25 +02:00
Hugo Locurcio 6595395b8b
Fix LightmapGI not taking environment sky rotation into account when baking
The sky rotation now affects the baked environment lighting as it should,
making it match how real-time ambient light rendering works.

Co-authored-by: Per Melin <git@melin.net>
(cherry picked from commit 661cf1f351)
2024-09-16 16:33:15 +02:00
Miley Hollenberg a7756d530e
Fixed crash on PowerVR GE8320 GPUs
(cherry picked from commit 1c31e30359)
2024-09-16 16:32:56 +02:00
Kyle Appelgate 2df506ea15
fix to ensure generated light probes do not get placed too close to manual light probes
(cherry picked from commit 97205ea5b8)
2024-09-16 16:32:22 +02:00
Slashscreen 13d5227911
Apply patch for considering visual layers for DirectionalLight
Co-authored-by: majikayogames <152851004+majikayogames@users.noreply.github.com>
(cherry picked from commit 4457b11ff0)
2024-09-16 16:31:40 +02:00
Chris Cranford b9271608df
Remove superfluous `print_line` call
(cherry picked from commit b1421a0d98)
2024-09-16 16:30:46 +02:00
Silc Lizard (Tokage) Renew 5caaa6ce19
Fix incorrect warning on SkeletonModifier
(cherry picked from commit 4727c4f783)
2024-09-16 16:30:30 +02:00
David Snopek e1af61467a
OpenGL: Unconditionally do `glDisable(GL_FRAMEBUFFER_SRGB)` because we do our own sRGB conversion
(cherry picked from commit dfcff4ef46)
2024-09-16 16:30:06 +02:00
Rémi Verschelde d40fc50f08
Merge pull request #95835 from BastiaanOlij/xrnode_visibility_43
[4.3] XRNode - fix visibility issue
2024-08-30 09:47:50 +02:00
Bastiaan Olij 620cc30f2a XRNode - fix visibility issue 2024-08-29 11:55:43 +10:00
Rémi Verschelde ff9bc04223
Bump version to 4.3.1-rc
And update CI base branch to 4.3.
2024-08-15 11:35:17 +02:00
362 changed files with 207296 additions and 4370 deletions

View File

@ -5,7 +5,7 @@ on:
# Global Settings
env:
# Used for the cache key. Add version suffix to force clean build.
GODOT_BASE_BRANCH: master
GODOT_BASE_BRANCH: 4.3
SCONSFLAGS: verbose=yes warnings=extra werror=yes debug_symbols=no module_text_server_fb_enabled=yes
concurrency:

View File

@ -5,7 +5,7 @@ on:
# Global Settings
env:
# Used for the cache key. Add version suffix to force clean build.
GODOT_BASE_BRANCH: master
GODOT_BASE_BRANCH: 4.3
# Used for the godot-cpp checkout.
GODOT_CPP_BRANCH: '4.2'

View File

@ -5,7 +5,7 @@ on:
# Global Settings
env:
# Used for the cache key. Add version suffix to force clean build.
GODOT_BASE_BRANCH: master
GODOT_BASE_BRANCH: 4.3
SCONSFLAGS: verbose=yes warnings=extra werror=yes debug_symbols=no module_text_server_fb_enabled=yes
concurrency:

View File

@ -5,7 +5,7 @@ on:
# Global Settings
env:
# Used for the cache key. Add version suffix to force clean build.
GODOT_BASE_BRANCH: master
GODOT_BASE_BRANCH: 4.3
SCONSFLAGS: verbose=yes warnings=extra werror=yes module_text_server_fb_enabled=yes
DOTNET_NOLOGO: true
DOTNET_CLI_TELEMETRY_OPTOUT: true

View File

@ -5,7 +5,7 @@ on:
# Global Settings
env:
# Used for the cache key. Add version suffix to force clean build.
GODOT_BASE_BRANCH: master
GODOT_BASE_BRANCH: 4.3
SCONSFLAGS: verbose=yes warnings=extra werror=yes module_text_server_fb_enabled=yes
concurrency:

View File

@ -5,7 +5,7 @@ on:
# Global Settings
env:
# Used for the cache key. Add version suffix to force clean build.
GODOT_BASE_BRANCH: master
GODOT_BASE_BRANCH: 4.3
SCONSFLAGS: verbose=yes warnings=extra werror=yes debug_symbols=no use_closure_compiler=yes
EM_VERSION: 3.1.64
EM_CACHE_FOLDER: "emsdk-cache"

View File

@ -6,7 +6,7 @@ on:
# SCONS_CACHE for windows must be set in the build environment
env:
# Used for the cache key. Add version suffix to force clean build.
GODOT_BASE_BRANCH: master
GODOT_BASE_BRANCH: 4.3
SCONSFLAGS: verbose=yes warnings=extra werror=yes module_text_server_fb_enabled=yes d3d12=yes "angle_libs=${{github.workspace}}/"
SCONS_CACHE_MSVC_CONFIG: true

View File

@ -84,6 +84,7 @@ Jean-Michel Bernard <jmb462@gmail.com>
Jérôme Gully <jerome.gully0@gmail.com>
JFonS <joan.fonssanchez@gmail.com>
jitspoe <jitspoe@yahoo.com> <jitspoeAyahoooDcom>
Johan Aires Rastén <johan@oljud.se>
Juan Linietsky <reduzio@gmail.com>
Juan Linietsky <reduzio@gmail.com> <juan@godotengine.org>
Juan Linietsky <reduzio@gmail.com> <juan@okamstudio.com>
@ -97,6 +98,7 @@ karroffel <therzog@mail.de> <thomas.herzog@simedis.com>
Kelly Thomas <kelly.thomas@hotmail.com.au>
Kongfa Waroros <gongpha@hotmail.com>
K. S. Ernest (iFire) Lee <ernest.lee@chibifire.com>
K. S. Ernest (iFire) Lee <ernest.lee@chibifire.com> <fire@users.noreply.github.com>
kleonc <9283098+kleonc@users.noreply.github.com> <kleonc@users.noreply.github.com>
Leon Krause <lk@leonkrause.com> <eska@eska.me>
Leon Krause <lk@leonkrause.com> <eska014@users.noreply.github.com>
@ -142,6 +144,7 @@ Pieter-Jan Briers <pieterjan.briers+git@gmail.com>
Pieter-Jan Briers <pieterjan.briers+git@gmail.com> <pieterjan.briers@gmail.com>
Poommetee Ketson <poommetee@protonmail.com>
Przemysław Gołąb (n-pigeon) <golab.przemyslaw@gmail.com>
Radiant <69520693+RadiantUwU@users.noreply.github.com> <i.like.using.discord@gmail.com>
Rafał Mikrut <mikrutrafal@protonmail.com>
Rafał Mikrut <mikrutrafal@protonmail.com> <mikrutrafal54@gmail.com>
Ralf Hölzemer <r.hoelzemer@posteo.de> <rollenrolm@posteo.de>

View File

@ -1,11 +1,17 @@
# Godot Engine authors
Godot Engine is developed by a community of voluntary contributors who
contribute code, bug reports, documentation, artwork, support, etc.
contribute code, bug reports, documentation, translations, support, etc.,
across multiple repositories.
It is impossible to list them all; nevertheless, this file aims at listing
the developers who contributed significant patches to this MIT licensed
source code. "Significant" is arbitrarily decided, but should be fair :)
the developers who contributed significant improvements to the engine code.
To keep the list curated, we use a threshold of a minimum of 11 commits.
This file does not strictly reflect copyright ownership for the engine
source code. For this, refer to the Git history to know which contributor
wrote which part of the codebase.
GitHub usernames are indicated in parentheses, or as sole entry when no other
name is available.
@ -25,8 +31,6 @@ name is available.
## Developers
(in alphabetical order, with over 10 commits excluding merges)
Aaron Franke (aaronfranke)
Aaron Pagano (aaronp64)
Aaron Record (LightningAA)
@ -38,6 +42,7 @@ name is available.
Alfred Reinold Baudisch (alfredbaudisch)
Alistair Leslie-Hughes (alesliehughes)
Alket Rexhepi (alketii)
Alvin Wong (alvinhochun)
Andrea Catania (AndreaCatania)
Andreia Gaita (shana)
Andrii Doroshenko (Xrayez)
@ -46,11 +51,13 @@ name is available.
Angad Kambli (angad-k)
Anilforextra (AnilBK)
Anish Bhobe (KidRigger)
Anni Ryynänen (anniryynanen)
Anton Yabchinskiy (a12n)
Anutrix
Aren Villanueva (kurikaesu)
Ariel Manzur (punto-)
Arman Elgudzhyan (puchik)
Arseny Kapoulkine (zeux)
AThousandShips
aXu-AP
Bartłomiej T. Listwon (Listwon)
@ -72,6 +79,7 @@ name is available.
Carter Anderson (cart)
ChibiDenDen
Chris Bradfield (cbscribe)
Chris Cranford (Naros)
Christian Kaiser (ckaiser)
Clay John (clayjohn)
ConteZero
@ -86,7 +94,9 @@ name is available.
David Cambré (Gallilus)
David Sichma (DavidSichma)
David Snopek (dsnopek)
derammo
Dharkael (lupoDharkael)
Dirk Steinmetz (rsjtdrjgfuzkfg)
Dmitry Koteroff (Krakean)
Dmitry Maganov (vonagam)
Dominik Jasiński (dreamsComeTrue)
@ -117,6 +127,7 @@ name is available.
Geequlim
George Marques (vnen)
Gerrit Großkopf (Grosskopf)
Giganzo
Gilles Roudiere (groud)
Gordon MacPherson (RevoluPowered)
Guilherme Felipe de C. G. da Silva (guilhermefelipecgs)
@ -126,7 +137,6 @@ name is available.
Hein-Pieter van Braam-Stewart (hpvb)
Hendrik Brucker (Geometror)
Hilderin
hilfazer
Hiroshi Ogawa (hi-ogawa)
HolonProduction
homer666
@ -151,6 +161,7 @@ name is available.
Jia Jun Chai (SkyLucilfer)
jitspoe
Joan Fons Sanchez (JFonS)
Johan Aires Rastén (JohanAR)
Johan Manuel (29jm)
Johannes Witt (HaSa1002)
Jonathan Nicholl (jtnicholl)
@ -163,11 +174,13 @@ name is available.
Jummit
Justo Delgado (mrcdk)
karroffel
Kassandra Pucher (PucklaJ)
Kelly Thomas (KellyThomas)
kleonc
Kongfa Waroros (gongpha)
Kostadin Damyanov (Max-Might)
K. S. Ernest (iFire) Lee (fire)
Kyle Eichlin (likeich)
lawnjelly
Leon Krause (leonkrause)
Liz Haas (27thLiz)
@ -185,6 +198,7 @@ name is available.
Marcus Brummer (mbrlabs)
Marcus Elg (MCrafterzz)
Mariano Javier Suligoy (MarianoGnu)
Mario Liebisch (MarioLiebisch)
Mario Schlack (hurikhan)
Marios Staikopoulos (marstaik)
Marius Hanl (Maran23)
@ -198,6 +212,7 @@ name is available.
Masoud BH (masoudbh3)
Mateo Kuruk Miccino (kuruk-mm)
Matias N. Goldberg (darksylinc)
Matthew Murphy (mashumafi)
Matthew (skyace65)
Matthias Hölzl (hoelzl)
Max Hilbrunner (mhilbrunner)
@ -209,9 +224,10 @@ name is available.
MichiRecRoom (LikeLakers2)
Micky (Mickeon)
Mikael Hermansson (mihe)
Mika Viskari (miv391)
MinusKube
MJacred
Morris "Tabor" Arroad (mortarroad)
Mounir Tohami (WhalesState)
mrezai
Muhammad Huri (CakHuri)
muiroc
@ -234,6 +250,7 @@ name is available.
Patrick Dawson (pkdawson)
Patrick Exner (FlameLizard)
Patrick (firefly2442)
patwork
Paul Batty (Paulb23)
Paul Joannon (paulloz)
Paul Trojahn (ptrojahn)
@ -245,6 +262,7 @@ name is available.
Pieter-Jan Briers (PJB3005)
Poommetee Ketson (Noshyaar)
Przemysław Gołąb (n-pigeon)
Radiant (RadiantUwU)
Rafael M. G. (rafallus)
Rafał Mikrut (qarmin)
Raffaele Picca (RPicster)
@ -282,6 +300,7 @@ name is available.
Stanislav Labzyuk (DarkMessiah)
Stijn Hinlopen (hinlopen)
stmSi
Stuart Carnie (stuartcarnie)
Swarnim Arun (minraws)
TC (floppyhammer)
TechnoPorg
@ -289,6 +308,7 @@ name is available.
Thakee Nathees (ThakeeNathees)
thebestnom
Theo Hallenius (TheoXD)
Thomas ten Cate (ttencate)
Timo Schwarzer (timoschwarzer)
Timothé Bonhoure (ajreckof)
Timo (toger5)

View File

@ -12,12 +12,12 @@ generous deed immortalized in the next stable release of Godot Engine.
## Patrons
Khronos® Group <https://www.khronos.org/>
OSS Capital <https://oss.capital/>
Re-Logic <https://re-logic.com/>
## Platinum sponsors
Google Play <https://play.google.com/>
Google Play <https://play.google.com>
Ramatak <https://ramatak.com/>
V-Sekai <https://github.com/V-Sekai>
W4 Games <https://w4games.com/>
@ -25,53 +25,56 @@ generous deed immortalized in the next stable release of Godot Engine.
## Gold sponsors
Mega Crit <https://www.megacrit.com/>
Pirate Software <https://gopiratesoftware.com/>
Prehensile Tales <https://prehensile-tales.com/>
Pirate Software <https://gopiratesoftware.com>
Prehensile Tales <https://prehensile-tales.com>
Robot Gentleman <http://robotgentleman.com/>
## Silver sponsors
Broken Rules <https://brokenrul.es/>
Chasing Carrots <https://www.chasing-carrots.com/>
Broken Rules <https://brokenrul.es>
Chasing Carrots <https://www.chasing-carrots.com>
Copia Wealth Studios <https://copiawealthstudios.com/>
Indoor Astronaut <https://indoorastronaut.ch/>
Load Complete <https://loadcomplete.com/>
LoadComplete <https://loadcomplete.com/>
Null <https://null.com/>
Orbital Knight <https://www.orbitalknight.com/>
Playful Studios <https://playfulstudios.com/>
Re-Logic <https://re-logic.com/>
## Diamond members
Bippinbits <http://domekeepergame.com/>
Sealow
And 5 anonymous donors
Sylv <https://rankith.itch.io/unnamed-space-idle-prototype>
And 3 anonymous donors
## Titanium members
Adriaan de Jongh <https://adriaan.games/>
Anitya Space <https://www.anitya.space/>
Adriaan de Jongh <https://adriaan.games>
Anitya Space <https://www.anitya.space>
Basically Games
FDG Entertainment <https://www.fdg-entertainment.com/>
Game Dev Artisan <https://gamedevartisan.com/>
FDG Entertainment <https://www.fdg-entertainment.com>
Game Dev Artisan <https://gamedevartisan.com>
Garry Newman
Isaiah Smith <https://www.isaiahsmith.dev/>
Libretrend <https://libretrend.com/>
Kenney <https://kenney.nl/>
Libretrend <https://libretrend.com>
Life Art Studios <https://lifeartstudios.net/>
Lucid Silence Games
Matthew Campbell
PolyMars <https://polymars.dev/>
RPG in a Box <https://www.rpginabox.com/>
Razenpok <https://www.youtube.com/watch?v=-QxI-RP6-HM>
Smirk Software <https://smirk.gg/>
RPG in a Box <https://www.rpginabox.com>
Smirk Software <https://smirk.gg>
Studio Sunshower <https://www.studiosunshower.com/>
TrampolineTales <https://TrampolineTales.com/>
粟二华 (Su Erhua)
And 6 anonymous donors
And 4 anonymous donors
## Platinum members
Andy Touch
BlockImperiumGames (BIG)
Christoph Woinke
Christopher Shifflett
Christoph Woinke
Cody Bentley
Darrin Massena
Edward Flick
@ -79,8 +82,8 @@ generous deed immortalized in the next stable release of Godot Engine.
HP van Braam
iCommitGames
Jonah Stich
Justo Delgado Baudí
katnamag
Marek Belski
Matthew Ekenstedt
Memories in 8Bit
Mike King
@ -97,13 +100,14 @@ generous deed immortalized in the next stable release of Godot Engine.
TigerJ
Violin Iliev
Vladimír Chvátil
And 16 anonymous donors
And 13 anonymous donors
## Gold members
80px
afreytes
alMoo Games
alMoo Games
Alva Majo
Antti Vesanen
Asher Glick
@ -119,6 +123,8 @@ generous deed immortalized in the next stable release of Godot Engine.
Bryce Dixon
c64cosmin
Carlo del Mundo
Carl van der Geest
Chocolate Software
Cindy Trieu
ClarkThyLord
Codex404
@ -135,17 +141,21 @@ generous deed immortalized in the next stable release of Godot Engine.
dgehrig
dhanielk
Distorted Realities
Donkung
Dono
Don't You Know Who I Am? Inc.
Dustuu
Dylan P.
Edelweiss
Ends
Eren Ogrul
Eric Brand
Eric Phy
Faisal Al-Kubaisi (QatariGameDev)
Felix Adam
FeralBytes
Festzeltgaming.de
Frozen Fractal
Gaudipern
GlassBrick
Grau
@ -153,6 +163,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Hayden Oliver
hiulit
Illyan
Immaculate Lift Studio
Ivan Tabashki
Jacob (HACKhalo2 Studios)
Jam
@ -160,13 +171,12 @@ generous deed immortalized in the next stable release of Godot Engine.
Javier Roman
Jeff Hungerford
Jeronimo Schreyer
Joel Martinez
Johannes Wuensch
John Gabriel
Jonas Yamazaki
Jonathan
José Canepa
Joshua Stelly
Justin Sasso
Kalydi Balázs
KAR Games
Kiri "ExpiredPopsicle" Artemis
@ -181,7 +191,9 @@ generous deed immortalized in the next stable release of Godot Engine.
m1n1ster
Manuel Requena
Mara Huldra
Marek Belski
Martin Šenkeřík
MHDante
Michael Gooch
Modus Ponens
Moshe Harris
@ -190,6 +202,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Nassor Paulino da Silva
nezticle
Niklas Wahrman
Nitzan Bueno
Niwl Games
NotNet
Oathbringer
@ -207,6 +220,7 @@ generous deed immortalized in the next stable release of Godot Engine.
re:thinc
Richard Ivánek
Rudi P
Sam Leathers
Samuel Judd
ScoreSpace
Shiny Shinken
@ -238,12 +252,12 @@ generous deed immortalized in the next stable release of Godot Engine.
Zhu Li
zikes
嗯大爷
潘彦圣
Alex Khayrullin
Algebrute
Andriy
Antanas Paskauskas
anti666
Ari
Arisaka Mayuki
Arthur S. Muszynski
@ -269,13 +283,11 @@ generous deed immortalized in the next stable release of Godot Engine.
Liam Smyth
LoparPanda
Martin Gulliksson
Martin Soucek
Michael Dürwald
Michael Policastro
n00sh
Nicolás Monner Sans
Nikita Rotskov
Nikola Whallon
Oliver Dick
Patrick Wuttke
Pete Goodwin
@ -298,7 +310,6 @@ generous deed immortalized in the next stable release of Godot Engine.
VoidPointer
Yifan Lai
Aaron Mayfield
Adam Carr
Adam Smeltzer
Adisibio
@ -315,7 +326,6 @@ generous deed immortalized in the next stable release of Godot Engine.
Ano Nim
Arch Toasty
Arda Erol
A Really Tall Horse
Arturo Rosales
Ash K
Aubrey Falconer
@ -343,6 +353,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Dakota Watkins
Daniele Tolomelli
Daniel Ramos
Daren Scot Wilson
Dave Jansen
Davesnothere
David Baker
@ -361,12 +372,11 @@ generous deed immortalized in the next stable release of Godot Engine.
Eric Stokes
Eric Williams
Erkki Seppälä
Ewan Holmes
Felix Adam
Frank
Frying☆Pan
Game Endeavor
gamerminstrel
Garrett S
Gary Thomas
gebba
Greyson Richey
@ -385,7 +395,6 @@ generous deed immortalized in the next stable release of Godot Engine.
Jamie Massey
JARKKO PARVIAINEN
Jason Evans
Joakim Askenbäck
Jonas
Jonas Arndt
Jonas Yamazaki
@ -421,7 +430,6 @@ generous deed immortalized in the next stable release of Godot Engine.
Martin Holas
Martin Liška
Martin Trbola
Matěj Drábek
Mathieu
Matt Edwards
Maverick
@ -441,7 +449,6 @@ generous deed immortalized in the next stable release of Godot Engine.
Neofytos Chimonas
Nerdforge
Nerdyninja
Nick Eldrenkamp
Nik Rudenko
Noel Billig
ozrk
@ -450,7 +457,6 @@ generous deed immortalized in the next stable release of Godot Engine.
Patrick Nafarrete
Paul Black
Paul Gieske
Paul Mozet
Pete
Phoenix Jauregui
Pierre Caye
@ -462,7 +468,6 @@ generous deed immortalized in the next stable release of Godot Engine.
Raghava Kovvali
Ragnar Pettersson
Rammeow
Rebecca H
Richard Hayes
Riley
RobotCritter
@ -508,7 +513,7 @@ generous deed immortalized in the next stable release of Godot Engine.
ケルベロス
貴宏 小松
And 181 anonymous donors
And 176 anonymous donors
## Silver and bronze donors

View File

@ -1070,7 +1070,6 @@ if "check_c_headers" in env:
env.AppendUnique(CPPDEFINES=[headers[header]])
# FIXME: This method mixes both cosmetic progress stuff and cache handling...
methods.show_progress(env)
# TODO: replace this with `env.Dump(format="json")`
# once we start requiring SCons 4.0 as min version.
@ -1102,3 +1101,5 @@ def purge_flaky_files():
atexit.register(purge_flaky_files)
methods.clean_cache(env)

View File

@ -140,7 +140,7 @@ if env["builtin_zstd"]:
"decompress/zstd_decompress_block.c",
"decompress/zstd_decompress.c",
]
if env["platform"] in ["android", "ios", "linuxbsd", "macos"]:
if env["platform"] in ["android", "ios", "linuxbsd", "macos"] and env["arch"] == "x86_64":
# Match platforms with ZSTD_ASM_SUPPORTED in common/portability_macros.h
thirdparty_zstd_sources.append("decompress/huf_decompress_amd64.S")
thirdparty_zstd_sources = [thirdparty_zstd_dir + file for file in thirdparty_zstd_sources]

View File

@ -1489,15 +1489,6 @@ ProjectSettings::ProjectSettings() {
GLOBAL_DEF(PropertyInfo(Variant::INT, "audio/general/ios/session_category", PROPERTY_HINT_ENUM, "Ambient,Multi Route,Play and Record,Playback,Record,Solo Ambient"), 0);
GLOBAL_DEF("audio/general/ios/mix_with_others", false);
PackedStringArray extensions;
extensions.push_back("gd");
if (ClassDB::class_exists("CSharpScript")) {
extensions.push_back("cs");
}
extensions.push_back("gdshader");
GLOBAL_DEF(PropertyInfo(Variant::PACKED_STRING_ARRAY, "editor/script/search_in_file_extensions"), extensions);
_add_builtin_input_map();
// Keep the enum values in sync with the `DisplayServer::ScreenOrientation` enum.

View File

@ -781,23 +781,14 @@ Error GDExtension::open_library(const String &p_path, const String &p_entry_symb
}
}
String actual_lib_path;
OS::GDExtensionData data = {
true, // also_set_library_path
&actual_lib_path, // r_resolved_path
&library_path, // r_resolved_path
Engine::get_singleton()->is_editor_hint(), // generate_temp_files
&abs_dependencies_paths, // library_dependencies
};
Error err = OS::get_singleton()->open_dynamic_library(abs_path, library, &data);
if (actual_lib_path.get_file() != abs_path.get_file()) {
// If temporary files are generated, let's change the library path to point at the original,
// because that's what we want to check to see if it's changed.
library_path = actual_lib_path.get_base_dir().path_join(p_path.get_file());
} else {
library_path = actual_lib_path;
}
ERR_FAIL_COND_V_MSG(err == ERR_FILE_NOT_FOUND, err, "GDExtension dynamic library not found: " + abs_path);
ERR_FAIL_COND_V_MSG(err != OK, err, "Can't open GDExtension dynamic library: " + abs_path);

View File

@ -8,7 +8,7 @@ __XINPUT_DEVICE__,XInput Gamepad,a:b12,b:b13,x:b14,y:b15,start:b4,guide:b10,back
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,
# Web
standard,Standard Gamepad Mapping,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b8,start:b9,leftstick:b10,rightstick:b11,dpup:b12,dpdown:b13,dpleft:b14,dpright:b15,guide:b16,leftstick:b10,rightstick:b11,platform:Web,
standard,Standard Gamepad Mapping,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:+a4,righttrigger:+a5,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b8,start:b9,leftstick:b10,rightstick:b11,dpup:b12,dpdown:b13,dpleft:b14,dpright:b15,guide:b16,leftstick:b10,rightstick:b11,platform:Web,
Linux24c6581a,PowerA Xbox One Cabled,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:-a7,dpleft:-a6,dpdown:+a7,dpright:+a6,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Web,
Linux0e6f0301,Logic 3 Controller (xbox compatible),a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:-a7,dpleft:-a6,dpdown:+a7,dpright:+a6,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Web,
Linux045e028e,Microsoft X-Box 360 pad,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:-a7,dpleft:-a6,dpdown:+a7,dpright:+a6,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Web,

View File

@ -30,12 +30,7 @@
#include "expression.h"
#include "core/io/marshalls.h"
#include "core/math/math_funcs.h"
#include "core/object/class_db.h"
#include "core/object/ref_counted.h"
#include "core/os/os.h"
#include "core/variant/variant_parser.h"
Error Expression::_get_token(Token &r_token) {
while (true) {
@ -392,7 +387,6 @@ Error Expression::_get_token(Token &r_token) {
if (is_digit(c)) {
} else if (c == 'e') {
reading = READING_EXP;
} else {
reading = READING_DONE;
}
@ -419,7 +413,9 @@ Error Expression::_get_token(Token &r_token) {
is_first_char = false;
}
str_ofs--;
if (c != 0) {
str_ofs--;
}
r_token.type = TK_CONSTANT;

View File

@ -105,6 +105,9 @@ public:
static _ALWAYS_INLINE_ double fmod(double p_x, double p_y) { return ::fmod(p_x, p_y); }
static _ALWAYS_INLINE_ float fmod(float p_x, float p_y) { return ::fmodf(p_x, p_y); }
static _ALWAYS_INLINE_ double modf(double p_x, double *r_y) { return ::modf(p_x, r_y); }
static _ALWAYS_INLINE_ float modf(float p_x, float *r_y) { return ::modff(p_x, r_y); }
static _ALWAYS_INLINE_ double floor(double p_x) { return ::floor(p_x); }
static _ALWAYS_INLINE_ float floor(float p_x) { return ::floorf(p_x); }

View File

@ -60,6 +60,11 @@ int64_t RandomPCG::rand_weighted(const Vector<float> &p_weights) {
}
}
for (int64_t i = weights_size - 1; i >= 0; --i) {
if (weights[i] > 0) {
return i;
}
}
return -1;
}

View File

@ -45,14 +45,17 @@
#ifdef DEBUG_ENABLED
struct _ObjectDebugLock {
Object *obj;
ObjectID obj_id;
_ObjectDebugLock(Object *p_obj) {
obj = p_obj;
obj->_lock_index.ref();
obj_id = p_obj->get_instance_id();
p_obj->_lock_index.ref();
}
~_ObjectDebugLock() {
obj->_lock_index.unref();
Object *obj_ptr = ObjectDB::get_instance(obj_id);
if (likely(obj_ptr)) {
obj_ptr->_lock_index.unref();
}
}
};
@ -2097,7 +2100,11 @@ Object::~Object() {
// Disconnect signals that connect to this object.
while (connections.size()) {
Connection c = connections.front()->get();
bool disconnected = c.signal.get_object()->_disconnect(c.signal.get_name(), c.callable, true);
Object *obj = c.callable.get_object();
bool disconnected = false;
if (likely(obj)) {
disconnected = c.signal.get_object()->_disconnect(c.signal.get_name(), c.callable, true);
}
if (unlikely(!disconnected)) {
// If the disconnect has failed, abandon the connection to avoid getting trapped in an infinite loop here.
connections.pop_front();

View File

@ -142,6 +142,7 @@ void ScriptLanguageExtension::_bind_methods() {
GDVIRTUAL_BIND(_debug_get_current_stack_info);
GDVIRTUAL_BIND(_reload_all_scripts);
GDVIRTUAL_BIND(_reload_scripts, "scripts", "soft_reload");
GDVIRTUAL_BIND(_reload_tool_script, "script", "soft_reload");
GDVIRTUAL_BIND(_get_recognized_extensions);

View File

@ -468,7 +468,10 @@ void WorkerThreadPool::_wait_collaboratively(ThreadData *p_caller_pool_thread, T
p_caller_pool_thread->signaled = false;
if (IS_WAIT_OVER) {
p_caller_pool_thread->yield_is_over = false;
if (unlikely(p_task == ThreadData::YIELDING)) {
p_caller_pool_thread->yield_is_over = false;
}
if (!exit_threads && was_signaled) {
// This thread was awaken for some additional reason, but it's about to exit.
// Let's find out what may be pending and forward the requests.

View File

@ -39,19 +39,10 @@ StaticCString StaticCString::create(const char *p_ptr) {
return scs;
}
StringName::_Data *StringName::_table[STRING_TABLE_LEN];
StringName _scs_create(const char *p_chr, bool p_static) {
return (p_chr[0] ? StringName(StaticCString::create(p_chr), p_static) : StringName());
}
bool StringName::configured = false;
Mutex StringName::mutex;
#ifdef DEBUG_ENABLED
bool StringName::debug_stringname = false;
#endif
void StringName::setup() {
ERR_FAIL_COND(configured);
for (int i = 0; i < STRING_TABLE_LEN; i++) {

View File

@ -67,7 +67,7 @@ class StringName {
_Data() {}
};
static _Data *_table[STRING_TABLE_LEN];
static inline _Data *_table[STRING_TABLE_LEN];
_Data *_data = nullptr;
@ -75,10 +75,10 @@ class StringName {
friend void register_core_types();
friend void unregister_core_types();
friend class Main;
static Mutex mutex;
static inline Mutex mutex;
static void setup();
static void cleanup();
static bool configured;
static inline bool configured = false;
#ifdef DEBUG_ENABLED
struct DebugSortReferences {
bool operator()(const _Data *p_left, const _Data *p_right) const {
@ -86,7 +86,7 @@ class StringName {
}
};
static bool debug_stringname;
static inline bool debug_stringname = false;
#endif
StringName(_Data *p_data) { _data = p_data; }

View File

@ -1537,13 +1537,16 @@ Vector<double> String::split_floats(const String &p_splitter, bool p_allow_empty
int from = 0;
int len = length();
String buffer = *this;
while (true) {
int end = find(p_splitter, from);
if (end < 0) {
end = len;
}
if (p_allow_empty || (end > from)) {
ret.push_back(String::to_float(&get_data()[from]));
buffer[end] = 0;
ret.push_back(String::to_float(&buffer.get_data()[from]));
buffer[end] = _cowdata.get(end);
}
if (end == len) {
@ -1561,6 +1564,7 @@ Vector<float> String::split_floats_mk(const Vector<String> &p_splitters, bool p_
int from = 0;
int len = length();
String buffer = *this;
while (true) {
int idx;
int end = findmk(p_splitters, from, &idx);
@ -1572,7 +1576,9 @@ Vector<float> String::split_floats_mk(const Vector<String> &p_splitters, bool p_
}
if (p_allow_empty || (end > from)) {
ret.push_back(String::to_float(&get_data()[from]));
buffer[end] = 0;
ret.push_back(String::to_float(&buffer.get_data()[from]));
buffer[end] = _cowdata.get(end);
}
if (end == len) {

View File

@ -169,7 +169,7 @@
astar.ConnectPoints(2, 3, false);
astar.ConnectPoints(4, 3, false);
astar.ConnectPoints(1, 4, false);
int[] res = astar.GetIdPath(1, 3); // Returns [1, 2, 3]
long[] res = astar.GetIdPath(1, 3); // Returns [1, 2, 3]
[/csharp]
[/codeblocks]
If you change the 2nd point's weight to 3, then the result will be [code][1, 4, 3][/code] instead, because now even though the distance is longer, it's "easier" to get through point 4 than through point 2.
@ -209,7 +209,7 @@
astar.ConnectPoints(1, 2, true);
astar.ConnectPoints(1, 3, true);
int[] neighbors = astar.GetPointConnections(1); // Returns [2, 3]
long[] neighbors = astar.GetPointConnections(1); // Returns [2, 3]
[/csharp]
[/codeblocks]
</description>

View File

@ -197,7 +197,7 @@
astar.ConnectPoints(2, 3, false);
astar.ConnectPoints(4, 3, false);
astar.ConnectPoints(1, 4, false);
int[] res = astar.GetIdPath(1, 3); // Returns [1, 2, 3]
long[] res = astar.GetIdPath(1, 3); // Returns [1, 2, 3]
[/csharp]
[/codeblocks]
If you change the 2nd point's weight to 3, then the result will be [code][1, 4, 3][/code] instead, because now even though the distance is longer, it's "easier" to get through point 4 than through point 2.
@ -236,7 +236,7 @@
astar.ConnectPoints(1, 2, true);
astar.ConnectPoints(1, 3, true);
int[] neighbors = astar.GetPointConnections(1); // Returns [2, 3]
long[] neighbors = astar.GetPointConnections(1); // Returns [2, 3]
[/csharp]
[/codeblocks]
</description>

View File

@ -5,7 +5,7 @@
</brief_description>
<description>
A resource used by [AnimationNodeBlendTree].
[AnimationNodeBlendSpace1D] represents a virtual 2D space on which [AnimationRootNode]s are placed. Outputs the linear blend of the three adjacent animations using a [Vector2] weight. Adjacent in this context means the three [AnimationRootNode]s making up the triangle that contains the current value.
[AnimationNodeBlendSpace2D] represents a virtual 2D space on which [AnimationRootNode]s are placed. Outputs the linear blend of the three adjacent animations using a [Vector2] weight. Adjacent in this context means the three [AnimationRootNode]s making up the triangle that contains the current value.
You can add vertices to the blend space with [method add_blend_point] and automatically triangulate it by setting [member auto_triangles] to [code]true[/code]. Otherwise, use [method add_triangle] and [method remove_triangle] to triangulate the blend space by hand.
</description>
<tutorials>
@ -93,7 +93,7 @@
<param index="0" name="point" type="int" />
<param index="1" name="pos" type="Vector2" />
<description>
Updates the position of the point at index [param point] on the blend axis.
Updates the position of the point at index [param point] in the blend space.
</description>
</method>
</methods>

View File

@ -243,7 +243,7 @@
var numbers = [1, 2, 3]
var extra = [4, 5, 6]
numbers.append_array(extra)
print(nums) # Prints [1, 2, 3, 4, 5, 6]
print(numbers) # Prints [1, 2, 3, 4, 5, 6]
[/codeblock]
</description>
</method>
@ -715,7 +715,7 @@
<param index="0" name="func" type="Callable" />
<description>
Sorts the array using a custom [Callable].
[param func] is called as many times as necessary, receiving two array elements as arguments. The function should return [code]true[/code] if the first element should be moved [i]behind[/i] the second one, otherwise it should return [code]false[/code].
[param func] is called as many times as necessary, receiving two array elements as arguments. The function should return [code]true[/code] if the first element should be moved [i]before[/i] the second one, otherwise it should return [code]false[/code].
[codeblock]
func sort_ascending(a, b):
if a[1] &lt; b[1]:
@ -728,7 +728,7 @@
print(my_items) # Prints [["Rice", 4], ["Tomato", 5], ["Apple", 9]]
# Sort descending, using a lambda function.
my_items.sort_custom(func(a, b): return a[0] &gt; b[0])
my_items.sort_custom(func(a, b): return a[1] &gt; b[1])
print(my_items) # Prints [["Apple", 9], ["Tomato", 5], ["Rice", 4]]
[/codeblock]
It may also be necessary to use this method to sort strings by natural order, with [method String.naturalnocasecmp_to], as in the following example:

View File

@ -88,7 +88,7 @@
<param index="0" name="idx" type="int" />
<param index="1" name="t" type="float" />
<description>
Returns the position between the vertex [param idx] and the vertex [code]idx + 1[/code], where [param t] controls if the point is the first vertex ([code]t = 0.0[/code]), the last vertex ([code]t = 1.0[/code]), or in between. Values of [param t] outside the range ([code]0.0 &gt;= t &lt;=1[/code]) give strange, but predictable results.
Returns the position between the vertex [param idx] and the vertex [code]idx + 1[/code], where [param t] controls if the point is the first vertex ([code]t = 0.0[/code]), the last vertex ([code]t = 1.0[/code]), or in between. Values of [param t] outside the range ([code]0.0 &lt;= t &lt;= 1.0[/code]) give strange, but predictable results.
If [param idx] is out of bounds it is truncated to the first or last vertex, and [param t] is ignored. If the curve has no points, the function sends an error to the console, and returns [code](0, 0)[/code].
</description>
</method>

View File

@ -29,6 +29,12 @@
Returns whether or not the specified layer of the [member navigation_layers] bitmask is enabled, given a [param layer_number] between 1 and 32.
</description>
</method>
<method name="get_navigation_map" qualifiers="const">
<return type="RID" />
<description>
Returns the current navigation map [RID] used by this link.
</description>
</method>
<method name="get_rid" qualifiers="const">
<return type="RID" />
<description>
@ -57,6 +63,13 @@
Based on [param value], enables or disables the specified layer in the [member navigation_layers] bitmask, given a [param layer_number] between 1 and 32.
</description>
</method>
<method name="set_navigation_map">
<return type="void" />
<param index="0" name="navigation_map" type="RID" />
<description>
Sets the [RID] of the navigation map this link should use. By default the link will automatically join the [World2D] default navigation map so this function is only required to override the default map.
</description>
</method>
</methods>
<members>
<member name="bidirectional" type="bool" setter="set_bidirectional" getter="is_bidirectional" default="true">

View File

@ -29,6 +29,12 @@
Returns whether or not the specified layer of the [member navigation_layers] bitmask is enabled, given a [param layer_number] between 1 and 32.
</description>
</method>
<method name="get_navigation_map" qualifiers="const">
<return type="RID" />
<description>
Returns the current navigation map [RID] used by this link.
</description>
</method>
<method name="get_rid" qualifiers="const">
<return type="RID" />
<description>
@ -57,6 +63,13 @@
Based on [param value], enables or disables the specified layer in the [member navigation_layers] bitmask, given a [param layer_number] between 1 and 32.
</description>
</method>
<method name="set_navigation_map">
<return type="void" />
<param index="0" name="navigation_map" type="RID" />
<description>
Sets the [RID] of the navigation map this link should use. By default the link will automatically join the [World3D] default navigation map so this function is only required to override the default map.
</description>
</method>
</methods>
<members>
<member name="bidirectional" type="bool" setter="set_bidirectional" getter="is_bidirectional" default="true">

View File

@ -136,7 +136,7 @@
}
}
private List&lt;int&gt; _numbers = new();
private Godot.Collections.Array&lt;int&gt; _numbers = new();
public override Godot.Collections.Array&lt;Godot.Collections.Dictionary&gt; _GetPropertyList()
{
@ -173,7 +173,7 @@
if (propertyName.StartsWith("number_"))
{
int index = int.Parse(propertyName.Substring("number_".Length));
numbers[index] = value.As&lt;int&gt;();
_numbers[index] = value.As&lt;int&gt;();
return true;
}
return false;

View File

@ -1000,7 +1000,7 @@
prime-run %command%
[/codeblock]
</member>
<member name="editor/script/search_in_file_extensions" type="PackedStringArray" setter="" getter="" default="PackedStringArray(&quot;gd&quot;, &quot;gdshader&quot;)">
<member name="editor/script/search_in_file_extensions" type="PackedStringArray" setter="" getter="">
Text-based file extensions to include in the script editor's "Find in Files" feature. You can add e.g. [code]tscn[/code] if you wish to also parse your scene files, especially if you use built-in scripts which are serialized in the scene files.
</member>
<member name="editor/script/templates_search_path" type="String" setter="" getter="" default="&quot;res://script_templates&quot;">

View File

@ -944,7 +944,8 @@
<param index="1" name="item" type="RID" />
<param index="2" name="mirroring" type="Vector2" />
<description>
A copy of the canvas item will be drawn with a local offset of the mirroring [Vector2].
A copy of the canvas item will be drawn with a local offset of the [param mirroring].
[b]Note:[/b] This is equivalent to calling [method canvas_set_item_repeat] like [code]canvas_set_item_repeat(item, mirroring, 1)[/code], with an additional check ensuring [param canvas] is a parent of [param item].
</description>
</method>
<method name="canvas_set_item_repeat">

View File

@ -40,7 +40,7 @@
</member>
<member name="kerning_pairs" type="PackedStringArray" setter="" getter="" default="PackedStringArray()">
Kerning pairs for the font. Kerning pair adjust the spacing between two characters.
Each string consist of three space separated values: "from" string, "to" string and integer offset. Each combination form the two string for a kerning pair, e.g, [code]ab cd -3[/code] will create kerning pairs [code]ac[/code], [code]ad[/code], [code]bc[/code], and [code]bd[/code] with offset [code]-3[/code].
Each string consist of three space separated values: "from" string, "to" string and integer offset. Each combination form the two string for a kerning pair, e.g, [code]ab cd -3[/code] will create kerning pairs [code]ac[/code], [code]ad[/code], [code]bc[/code], and [code]bd[/code] with offset [code]-3[/code]. [code]\uXXXX[/code] escape sequences can be used to add Unicode characters.
</member>
<member name="rows" type="int" setter="" getter="" default="1">
Number of rows in the font image. See also [member columns].

View File

@ -314,6 +314,13 @@
<description>
</description>
</method>
<method name="_reload_scripts" qualifiers="virtual">
<return type="void" />
<param index="0" name="scripts" type="Array" />
<param index="1" name="soft_reload" type="bool" />
<description>
</description>
</method>
<method name="_reload_tool_script" qualifiers="virtual">
<return type="void" />
<param index="0" name="script" type="Script" />

View File

@ -551,7 +551,7 @@
</member>
<member name="default_font_size" type="int" setter="set_default_font_size" getter="get_default_font_size" default="-1">
The default font size of this theme resource. Used as the default value when trying to fetch a font size value that doesn't exist in this theme or is in invalid state. If the default font size is also missing or invalid, the engine fallback value is used (see [member ThemeDB.fallback_font_size]).
Values below [code]0[/code] are invalid and can be used to unset the property. Use [method has_default_font_size] to check if this value is valid.
Values below [code]1[/code] are invalid and can be used to unset the property. Use [method has_default_font_size] to check if this value is valid.
</member>
</members>
<constants>

View File

@ -12226,65 +12226,6 @@ msgstr ""
"5[/code] reicht. Es ist die Position im Segment, die dem angegebenen Punkt am "
"nächsten liegt."
msgid ""
"Returns an array with the IDs of the points that form the connection with the "
"given point.\n"
"[codeblocks]\n"
"[gdscript]\n"
"var astar = AStar2D.new()\n"
"astar.add_point(1, Vector2(0, 0))\n"
"astar.add_point(2, Vector2(0, 1))\n"
"astar.add_point(3, Vector2(1, 1))\n"
"astar.add_point(4, Vector2(2, 0))\n"
"\n"
"astar.connect_points(1, 2, true)\n"
"astar.connect_points(1, 3, true)\n"
"\n"
"var neighbors = astar.get_point_connections(1) # Returns [2, 3]\n"
"[/gdscript]\n"
"[csharp]\n"
"var astar = new AStar2D();\n"
"astar.AddPoint(1, new Vector2(0, 0));\n"
"astar.AddPoint(2, new Vector2(0, 1));\n"
"astar.AddPoint(3, new Vector2(1, 1));\n"
"astar.AddPoint(4, new Vector2(2, 0));\n"
"\n"
"astar.ConnectPoints(1, 2, true);\n"
"astar.ConnectPoints(1, 3, true);\n"
"\n"
"int[] neighbors = astar.GetPointConnections(1); // Returns [2, 3]\n"
"[/csharp]\n"
"[/codeblocks]"
msgstr ""
"Gibt ein Array mit den IDs der Punkte zurück, die eine Verbindung mit dem "
"angegebenen Punkt bilden.\n"
"[codeblocks]\n"
"[gdscript]\n"
"var astar = AStar2D.new()\n"
"astar.add_point(1, Vector2(0, 0))\n"
"astar.add_point(2, Vector2(0, 1))\n"
"astar.add_point(3, Vector2(1, 1))\n"
"astar.add_point(4, Vector2(2, 0))\n"
"\n"
"astar.connect_points(1, 2, true)\n"
"astar.connect_points(1, 3, true)\n"
"\n"
"var neighbors = astar.get_point_connections(1) # Gibt [2, 3] zurück\n"
"[/gdscript]\n"
"[csharp]\n"
"var astar = new AStar2D();\n"
"astar.AddPoint(1, new Vector2(0, 0));\n"
"astar.AddPoint(2, new Vector2(0, 1));\n"
"astar.AddPoint(3, new Vector2(1, 1));\n"
"astar.AddPoint(4, new Vector2(2, 0));\n"
"\n"
"astar.ConnectPoints(1, 2, true);\n"
"astar.ConnectPoints(1, 3, true);\n"
"\n"
"int[] neighbors = astar.GetPointConnections(1); // Gibt [2, 3] zurück\n"
"[/csharp]\n"
"[/codeblocks]"
msgid "Returns the number of points currently in the points pool."
msgstr ""
"Gibt die Anzahl der Punkte zurück, die sich derzeit im Punktepool befinden."
@ -12523,63 +12464,6 @@ msgstr ""
"5[/code] reicht. Es ist die Position im Segment, die dem angegebenen Punkt am "
"nächsten liegt."
msgid ""
"Returns an array with the IDs of the points that form the connection with the "
"given point.\n"
"[codeblocks]\n"
"[gdscript]\n"
"var astar = AStar3D.new()\n"
"astar.add_point(1, Vector3(0, 0, 0))\n"
"astar.add_point(2, Vector3(0, 1, 0))\n"
"astar.add_point(3, Vector3(1, 1, 0))\n"
"astar.add_point(4, Vector3(2, 0, 0))\n"
"\n"
"astar.connect_points(1, 2, true)\n"
"astar.connect_points(1, 3, true)\n"
"\n"
"var neighbors = astar.get_point_connections(1) # Returns [2, 3]\n"
"[/gdscript]\n"
"[csharp]\n"
"var astar = new AStar3D();\n"
"astar.AddPoint(1, new Vector3(0, 0, 0));\n"
"astar.AddPoint(2, new Vector3(0, 1, 0));\n"
"astar.AddPoint(3, new Vector3(1, 1, 0));\n"
"astar.AddPoint(4, new Vector3(2, 0, 0));\n"
"astar.ConnectPoints(1, 2, true);\n"
"astar.ConnectPoints(1, 3, true);\n"
"\n"
"int[] neighbors = astar.GetPointConnections(1); // Returns [2, 3]\n"
"[/csharp]\n"
"[/codeblocks]"
msgstr ""
"Gibt ein Array mit den IDs der Punkte zurück, die eine Verbindung mit dem "
"angegebenen Punkt bilden.\n"
"[codeblocks]\n"
"[gdscript]\n"
"var astar = AStar3D.new()\n"
"astar.add_point(1, Vector3(0, 0, 0))\n"
"astar.add_point(2, Vector3(0, 1, 0))\n"
"astar.add_point(3, Vector3(1, 1, 0))\n"
"astar.add_point(4, Vector3(2, 0, 0))\n"
"\n"
"astar.connect_points(1, 2, true)\n"
"astar.connect_points(1, 3, true)\n"
"\n"
"var neighbors = astar.get_point_connections(1) # Gibt [2, 3] zurück\n"
"[/gdscript]\n"
"[csharp]\n"
"var astar = new AStar3D();\n"
"astar.AddPoint(1, new Vector3(0, 0, 0));\n"
"astar.AddPoint(2, new Vector3(0, 1, 0));\n"
"astar.AddPoint(3, new Vector3(1, 1, 0));\n"
"astar.AddPoint(4, new Vector3(2, 0, 0));\n"
"astar.ConnectPoints(1, 2, true);\n"
"astar.ConnectPoints(1, 3, true);\n"
"\n"
"int[] neighbors = astar.GetPointConnections(1); // Gibt [2, 3] zurück\n"
"[/csharp]\n"
"[/codeblocks]"
msgid ""
"[AStarGrid2D] is a variant of [AStar2D] that is specialized for partial 2D "
"grids. It is simpler to use because it doesn't require you to manually create "

View File

@ -87,13 +87,16 @@
# Alejandro Moctezuma <moctezumaalejandro25@gmail.com>, 2024.
# gallegonovato <fran-carro@hotmail.es>, 2024.
# Andres David Calderon <andresdavidcalderonjimenez@gmail.com>, 2024.
# MayorTom4815 <domiisac2004@proton.me>, 2024.
# Jesús Arriaza <jesusarriaza0@gmail.com>, 2024.
# Simja 82 <simja.82@hotmail.com>, 2024.
# Keider Kaize <keiderkaize@gmail.com>, 2024.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine class reference\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
"PO-Revision-Date: 2024-08-07 15:09+0000\n"
"Last-Translator: Andres David Calderon <andresdavidcalderonjimenez@gmail."
"com>\n"
"PO-Revision-Date: 2024-09-13 04:52+0000\n"
"Last-Translator: Keider Kaize <keiderkaize@gmail.com>\n"
"Language-Team: Spanish <https://hosted.weblate.org/projects/godot-engine/"
"godot-class-reference/es/>\n"
"Language: es\n"
@ -101,7 +104,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8-bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 5.7-dev\n"
"X-Generator: Weblate 5.8-dev\n"
msgid "All classes"
msgstr "Todas las clases"
@ -777,6 +780,34 @@ msgstr ""
"[b]Nota:[/b] No se soporta la llamada a esta función desde un [Thread]. Si lo "
"hace, se imprimirá el ID del hilo."
msgid ""
"Prints a stack trace at the current code location. See also [method "
"get_stack].\n"
"The output in the console may look like the following:\n"
"[codeblock lang=text]\n"
"Frame 0 - res://test.gd:16 in function '_process'\n"
"[/codeblock]\n"
"[b]Note:[/b] This function only works if the running instance is connected to "
"a debugging server (i.e. an editor instance). [method print_stack] will not "
"work in projects exported in release mode, or in projects exported in debug "
"mode if not connected to a debugging server.\n"
"[b]Note:[/b] Calling this function from a [Thread] is not supported. Doing so "
"will instead print the thread ID."
msgstr ""
"Imprime un seguimiento de la pila en la ubicación de código actual. Véase "
"también [method get_stack].\n"
"La salida en la consola puede verse similar a la siguiente:\n"
"[codeblock lang=text]\n"
"Frame 0 - res://test.gd:16 in function '_process'\n"
"[/codeblock]\n"
"[b]Nota:[/b] Esta función solo actua correctamente si la instancia ejecutada "
"está conectada a un servidor de depuración (p.e. una instancia de editor). "
"[method print_stack] no funcionará en proyectos exportados en modo release, o "
"en proyectos exportados en modo depurar si no está conectado a un servidor de "
"depuración.\n"
"[b]Nota:[/b] Llamar a esta función desde [Thread] no está soportado. Hacerlo "
"en este caso imprimirá el ID del hilo."
msgid ""
"Returns [code]true[/code] if the given [Object]-derived class exists in "
"[ClassDB]. Note that [Variant] data types are not registered in [ClassDB].\n"
@ -1526,6 +1557,28 @@ msgstr ""
"argumentos de cualquier tipo en una cadena de la mejor manera posible y los "
"imprime en la consola."
msgid ""
"Prints one or more arguments to the console with a space between each "
"argument.\n"
"[codeblocks]\n"
"[gdscript]\n"
"prints(\"A\", \"B\", \"C\") # Prints A B C\n"
"[/gdscript]\n"
"[csharp]\n"
"GD.PrintS(\"A\", \"B\", \"C\"); // Prints A B C\n"
"[/csharp]\n"
"[/codeblocks]"
msgstr ""
"Imprime uno o más argumentos en la consola con un espacio entre cada "
"argumento.\n"
"[codeblock]\n"
"[gdscript]\n"
"prints(\"A\", \"B\", \"C\") # Imprime A B C\n"
"[/gdscript]\n"
"GD.PrintS(\"A\",\"B\",\"C\");//Imprime A B C\n"
"[/csharp]\n"
"[/codeblocks]"
msgid ""
"Given a [param seed], returns a [PackedInt64Array] of size [code]2[/code], "
"where its first element is the randomized [int] value, and the second element "
@ -1554,6 +1607,107 @@ msgstr ""
"print(a[1])\t# Prints 4\n"
"[/codeblock]"
msgid ""
"Randomizes the seed (or the internal state) of the random number generator. "
"The current implementation uses a number based on the device's time.\n"
"[b]Note:[/b] This function is called automatically when the project is run. "
"If you need to fix the seed to have consistent, reproducible results, use "
"[method seed] to initialize the random number generator."
msgstr ""
"Aleatorizar la semilla (o el estado interno) del generador de números "
"aleatorios. Es una implementación actual que utiliza un numero basado en el "
"tiempo del dispositivo.\n"
"[b]Nota:[/b] Esta función es llamada automáticamente cuando se ejecuta el "
"proyecto. Si se necesita arreglar la semilla para mas consistencia o "
"reproducir resultados, usa [method seed] para inicializar el generador de "
"números aleatorios."
msgid ""
"Maps a [param value] from range [code][istart, istop][/code] to [code]"
"[ostart, ostop][/code]. See also [method lerp] and [method inverse_lerp]. If "
"[param value] is outside [code][istart, istop][/code], then the resulting "
"value will also be outside [code][ostart, ostop][/code]. If this is not "
"desired, use [method clamp] on the result of this function.\n"
"[codeblock]\n"
"remap(75, 0, 100, -1, 1) # Returns 0.5\n"
"[/codeblock]\n"
"For complex use cases where multiple ranges are needed, consider using "
"[Curve] or [Gradient] instead.\n"
"[b]Note:[/b] If [code]istart == istop[/code], the return value is undefined "
"(most likely NaN, INF, or -INF)."
msgstr ""
"Mapea un [param value] en un rango de [code][istart, istop][/code] a [code]"
"[ostart, ostop][/code]. Ver también [method lerp] y [method inverse_lerp]. Si "
"[param value] esta afuera [code][istart, istop][/code], entonces el valor "
"resultante también estara fuera [code][ostart, ostop][/code]. Si esto no es "
"lo deseado, use [method clamp] en el resultado de esta función.\n"
"[codeblock]\n"
"remap(75, 0, 100, -1, 1) #Devuelve 0.5\n"
"[/codeblock]\n"
"Para casos mas complejos en donde se requieran multiples rangos, considere "
"usar [Curve] o [Gradient] en su lugar.\n"
"[b]Nota:[/b] Si [code]istart == istop[/code], el valor devuelto es indefinido "
"(probablemente NaN, INF, o -INF)."
msgid ""
"Allocates a unique ID which can be used by the implementation to construct an "
"RID. This is used mainly from native extensions to implement servers."
msgstr ""
"Asigna un ID único que puede se usado por la implementación para la "
"construcción de un RID. Esto se utiliza principalmente desde extensiones "
"nativas para implementar en servidores."
msgid ""
"Creates an RID from a [param base]. This is used mainly from native "
"extensions to build servers."
msgstr ""
"Crea un RID a partir de un [param base]. Esto es usado principalmente por "
"extensiones nativas para la constricción de servidores."
msgid ""
"Rounds [param x] to the nearest whole number, with halfway cases rounded away "
"from 0. Supported types: [int], [float], [Vector2], [Vector2i], [Vector3], "
"[Vector3i], [Vector4], [Vector4i].\n"
"[codeblock]\n"
"round(2.4) # Returns 2\n"
"round(2.5) # Returns 3\n"
"round(2.6) # Returns 3\n"
"[/codeblock]\n"
"See also [method floor], [method ceil], and [method snapped].\n"
"[b]Note:[/b] For better type safety, use [method roundf], [method roundi], "
"[method Vector2.round], [method Vector3.round], or [method Vector4.round]."
msgstr ""
"Redondea [param x] al número entero más cercano, con los casos intermedios "
"redondeados a partir de 0. Datos soportados: [int], [float], [Vector2], "
"[Vector2i], [Vector3], [Vector3i], [Vector4], [Vector4i].\n"
"[codeblock]\n"
"round(2.4) # Devuelve 2\n"
"round(2.5) # Devuelve 3\n"
"round(2.6) # Devuelve 3\n"
"[/codeblock]\n"
"Ver también [method floor], [method ceil], y [method snapped].\n"
"[b]Nota:[/b] Para un mejor tipado seguro, use [method roundf], [method "
"roundi], [method Vector2.round], [method Vector3.round], o [method Vector4."
"round]."
msgid ""
"Rounds [param x] to the nearest whole number, with halfway cases rounded away "
"from 0.\n"
"A type-safe version of [method round], returning a [float]."
msgstr ""
"Redondea [param x] al numero entero mas cercano, con los casos intermedios "
"redondeados a partir de 0.\n"
"Es una version de tipado seguro del [method round] , retorna un [float]."
msgid ""
"Rounds [param x] to the nearest whole number, with halfway cases rounded away "
"from 0.\n"
"A type-safe version of [method round], returning an [int]."
msgstr ""
"Redondea [param x] al numero entero mas cercano, con los casos intermedios "
"redondeados a partir de 0.\n"
"Es una version de tipado seguro del [method round] , retorna un [int]."
msgid "The [AudioServer] singleton."
msgstr "El singleton [AudioServer]."
@ -2449,9 +2603,6 @@ msgstr "Operador NOT lógico ([code]NOT[/code] o [code]![/code])."
msgid "Logical IN operator ([code]in[/code])."
msgstr "Operador lógico In ([code]in[/code])."
msgid "Represents the size of the [enum Variant.Operator] enum."
msgstr "Representa el tamaño del enum [enum Variant.Operator]."
msgid "Math documentation index"
msgstr "Índice de documentación matemática"
@ -15622,13 +15773,6 @@ msgstr ""
msgid "Sets the shape of the occluder polygon."
msgstr "Establece la forma del polígono oclusor."
msgid ""
"A copy of the canvas item will be drawn with a local offset of the mirroring "
"[Vector2]."
msgstr ""
"Se dibujará una copia del objeto de canvas con un desplazamiento local del "
"espejo [Vector2]."
msgid "Modulates all colors in the given canvas."
msgstr "Modula todos los colores en el canvas dado."

View File

@ -105,13 +105,15 @@
# Unreal Vision <unrealvisionyt@gmail.com>, 2024.
# Romain Defente <rdefente@gmail.com>, 2024.
# zefdzeqf <azrzrezfafe@users.noreply.hosted.weblate.org>, 2024.
# Edvard Fauchelevent <edvardfauchelevent@gmail.com>, 2024.
# Fontaine Nathan <nathan.fontaine53@gmail.com>, 2024.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine class reference\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
"POT-Creation-Date: \n"
"PO-Revision-Date: 2024-07-16 05:13+0000\n"
"Last-Translator: zefdzeqf <azrzrezfafe@users.noreply.hosted.weblate.org>\n"
"PO-Revision-Date: 2024-09-04 20:31+0000\n"
"Last-Translator: Fontaine Nathan <nathan.fontaine53@gmail.com>\n"
"Language-Team: French <https://hosted.weblate.org/projects/godot-engine/godot-"
"class-reference/fr/>\n"
"Language: fr\n"
@ -119,7 +121,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n > 1;\n"
"X-Generator: Weblate 5.7-dev\n"
"X-Generator: Weblate 5.7.2-rc\n"
msgid "All classes"
msgstr "Toutes les classes"
@ -6937,6 +6939,121 @@ msgstr "Toutes les particules seront émises depuis l'intérieur d'une boite."
msgid "Particles will be emitted in a ring or cylinder."
msgstr "Toutes les particules seront émises depuis un anneau ou un cylindre."
msgid ""
"The Crypto class provides access to advanced cryptographic functionalities.\n"
"Currently, this includes asymmetric key encryption/decryption, signing/"
"verification, and generating cryptographically secure random bytes, RSA keys, "
"HMAC digests, and self-signed [X509Certificate]s.\n"
"[codeblocks]\n"
"[gdscript]\n"
"var crypto = Crypto.new()\n"
"\n"
"# Generate new RSA key.\n"
"var key = crypto.generate_rsa(4096)\n"
"\n"
"# Generate new self-signed certificate with the given key.\n"
"var cert = crypto.generate_self_signed_certificate(key, \"CN=mydomain.com,"
"O=My Game Company,C=IT\")\n"
"\n"
"# Save key and certificate in the user folder.\n"
"key.save(\"user://generated.key\")\n"
"cert.save(\"user://generated.crt\")\n"
"\n"
"# Encryption\n"
"var data = \"Some data\"\n"
"var encrypted = crypto.encrypt(key, data.to_utf8_buffer())\n"
"\n"
"# Decryption\n"
"var decrypted = crypto.decrypt(key, encrypted)\n"
"\n"
"# Signing\n"
"var signature = crypto.sign(HashingContext.HASH_SHA256, data.sha256_buffer(), "
"key)\n"
"\n"
"# Verifying\n"
"var verified = crypto.verify(HashingContext.HASH_SHA256, data."
"sha256_buffer(), signature, key)\n"
"\n"
"# Checks\n"
"assert(verified)\n"
"assert(data.to_utf8_buffer() == decrypted)\n"
"[/gdscript]\n"
"[csharp]\n"
"using Godot;\n"
"using System.Diagnostics;\n"
"\n"
"Crypto crypto = new Crypto();\n"
"\n"
"// Generate new RSA key.\n"
"CryptoKey key = crypto.GenerateRsa(4096);\n"
"\n"
"// Generate new self-signed certificate with the given key.\n"
"X509Certificate cert = crypto.GenerateSelfSignedCertificate(key, "
"\"CN=mydomain.com,O=My Game Company,C=IT\");\n"
"\n"
"// Save key and certificate in the user folder.\n"
"key.Save(\"user://generated.key\");\n"
"cert.Save(\"user://generated.crt\");\n"
"\n"
"// Encryption\n"
"string data = \"Some data\";\n"
"byte[] encrypted = crypto.Encrypt(key, data.ToUtf8Buffer());\n"
"\n"
"// Decryption\n"
"byte[] decrypted = crypto.Decrypt(key, encrypted);\n"
"\n"
"// Signing\n"
"byte[] signature = crypto.Sign(HashingContext.HashType.Sha256, Data."
"Sha256Buffer(), key);\n"
"\n"
"// Verifying\n"
"bool verified = crypto.Verify(HashingContext.HashType.Sha256, Data."
"Sha256Buffer(), signature, key);\n"
"\n"
"// Checks\n"
"Debug.Assert(verified);\n"
"Debug.Assert(data.ToUtf8Buffer() == decrypted);\n"
"[/csharp]\n"
"[/codeblocks]"
msgstr ""
"La classe Crypto permet d'accéder à des fonctionnalités cryptographiques plus "
"avancées dans Godot.\n"
"Pour l'instant, cela inclus la génération de données aléatoires pour des "
"utilisations cryptographiques, la génération de clés RSA et de certificats "
"auto-signés X509, de clé asymétriques de cryptage/décryptage, la signature et "
"la vérification.\n"
"[codeblock]\n"
"extends Node\n"
"\n"
"var crypto = Crypto.new()\n"
"var key = CryptoKey.new()\n"
"var cert = X509Certificate.new()\n"
"\n"
"func _ready():\n"
" # Générer une nouvelle clé RSA.\n"
" key = crypto.generate_rsa(4096)\n"
" # Générer un nouveau certificat auto-signé avec le clé.\n"
" cert = crypto.generate_self_signed_certificate(key, \"CN=mydomain.com,"
"O=My Game Company,C=IT\")\n"
" # Enregistrer la clé et le certificat dans le dossier utilisateur.\n"
" key.save(\"user://generated.key\")\n"
" cert.save(\"user://generated.crt\")\n"
" # Cryptage\n"
" var data = \"Des données\"\n"
" var encrypted = crypto.encrypt(key, data.to_utf8())\n"
" # Décryptage\n"
" var decrypted = crypto.decrypt(key, encrypted)\n"
" # Signature\n"
" var signature = crypto.sign(HashingContext.HASH_SHA256, data."
"sha256_buffer(), key)\n"
" # Vérification\n"
" var verified = crypto.verify(HashingContext.HASH_SHA256, data."
"sha256_buffer(), signature, key)\n"
" # Tests\n"
" assert(verified)\n"
" assert(data.to_utf8() == decrypted)\n"
"[/codeblock]"
msgid "SSL certificates"
msgstr "Certificats SSL"

191390
doc/translations/ga.po Normal file

File diff suppressed because it is too large Load Diff

View File

@ -10762,23 +10762,6 @@ msgid ""
msgstr ""
"Appende [param value] alla fine dell'array (alias di [method push_back])."
msgid ""
"Appends another [param array] at the end of this array.\n"
"[codeblock]\n"
"var numbers = [1, 2, 3]\n"
"var extra = [4, 5, 6]\n"
"numbers.append_array(extra)\n"
"print(nums) # Prints [1, 2, 3, 4, 5, 6]\n"
"[/codeblock]"
msgstr ""
"Accoda un altro [param array] alla fine di questo array.\n"
"[codeblock]\n"
"numeri = [1, 2, 3]\n"
"var aggiuntivi = [4, 5, 6]\n"
"numeri.append_array(aggiuntivi)\n"
"print(numeri) # Stampa [1, 2, 3, 4, 5, 6]\n"
"[/codeblock]"
msgid ""
"Assigns elements of another [param array] into the array. Resizes the array "
"to match [param array]. Performs type conversions if the array is typed."
@ -11579,87 +11562,6 @@ msgstr ""
"print(lettere.slice(4, 1, -1)) # Stampa [\"E\", \"D\", \"C\"]\n"
"[/codeblock]"
msgid ""
"Sorts the array using a custom [Callable].\n"
"[param func] is called as many times as necessary, receiving two array "
"elements as arguments. The function should return [code]true[/code] if the "
"first element should be moved [i]behind[/i] the second one, otherwise it "
"should return [code]false[/code].\n"
"[codeblock]\n"
"func sort_ascending(a, b):\n"
" if a[1] < b[1]:\n"
" return true\n"
" return false\n"
"\n"
"func _ready():\n"
" var my_items = [[\"Tomato\", 5], [\"Apple\", 9], [\"Rice\", 4]]\n"
" my_items.sort_custom(sort_ascending)\n"
" print(my_items) # Prints [[\"Rice\", 4], [\"Tomato\", 5], [\"Apple\", "
"9]]\n"
"\n"
" # Sort descending, using a lambda function.\n"
" my_items.sort_custom(func(a, b): return a[0] > b[0])\n"
" print(my_items) # Prints [[\"Apple\", 9], [\"Tomato\", 5], [\"Rice\", "
"4]]\n"
"[/codeblock]\n"
"It may also be necessary to use this method to sort strings by natural order, "
"with [method String.naturalnocasecmp_to], as in the following example:\n"
"[codeblock]\n"
"var files = [\"newfile1\", \"newfile2\", \"newfile10\", \"newfile11\"]\n"
"files.sort_custom(func(a, b): return a.naturalnocasecmp_to(b) < 0)\n"
"print(files) # Prints [\"newfile1\", \"newfile2\", \"newfile10\", "
"\"newfile11\"]\n"
"[/codeblock]\n"
"[b]Note:[/b] In C#, this method is not supported.\n"
"[b]Note:[/b] The sorting algorithm used is not [url=https://en.wikipedia.org/"
"wiki/Sorting_algorithm#Stability]stable[/url]. This means that values "
"considered equal may have their order changed when calling this method.\n"
"[b]Note:[/b] You should not randomize the return value of [param func], as "
"the heapsort algorithm expects a consistent result. Randomizing the return "
"value will result in unexpected behavior."
msgstr ""
"Ordina l'array utilizzando un [Callable] personalizzato.\n"
"[param func] è chiamato quante più volte è necessario, ricevendo due elementi "
"dell'array come argomenti. La funzione dovrebbe restituire [code]true[/code] "
"se il primo elemento deve essere spostato [i]dietro[/i] al secondo, "
"altrimenti dovrebbe restituire [code]false[/code].\n"
"[codeblock]\n"
"func sort_ascending(a, b):\n"
" if a[1] < b[1]:\n"
" return true\n"
" return false\n"
"\n"
"func _ready():\n"
" var my_items = [[\"Pomodoro\", 5], [\"Mela\", 9], [\"Riso\", 4]]\n"
" my_items.sort_custom(sort_ascending)\n"
" print(my_items) # Stampa [[\"Riso\", 4], [\"Pomodoro\", 5], [\"Mela\", "
"9]]\n"
"\n"
" # Ordina in ordine decrescente, usando una funzione lambda.\n"
" my_items.sort_custom(func(a, b): return a[0] > b[0])\n"
" print(my_items) # Stampa [[\"Mela\", 9], [\"Pomodoro\", 5], [\"Riso\", "
"4]]\n"
"[/codeblock]\n"
"Può anche essere necessario utilizzare questo metodo per ordinare le stringhe "
"per ordine naturale, con [method String.naturalnocasecmp_to], come "
"nell'esempio seguente:\n"
"[codeblock]\n"
"var file_array = [\"nuovofile1\", \"nuovofile2\", \"nuovofile10\", "
"\"nuovofile11\"]\n"
"file_array.sort_custom(func(a, b): return a.naturalnocasecmp_to(b) < 0)\n"
"print(file_array) # Stampa [\"newfile1\", \"newfile2\", \"newfile10\", "
"\"newfile11\"]\n"
"[/codeblock]\n"
"[b]Nota:[/b] In C#, questo metodo non è supportato.\n"
"[b]Nota:[/b] L'algoritmo di selezione utilizzato non è [url=https://it."
"wikipedia.org/wiki/"
"Algoritmo_di_ordinamento#Stabilit%C3%A0_di_un_algoritmo]stabile[/url]. Ciò "
"significa che gli elementi considerati equivalenti potrebbero avere il loro "
"ordine cambiato quando si chiama [method sort].\n"
"[b]Nota:[/b] Non si dovrebbe randomizzare il valore di ritorno di [param "
"func], poiché l'algoritmo di heapsort si aspetta un risultato coerente. "
"Randomizzare il valore restituito risulterà in comportamento inaspettato."
msgid ""
"Returns [code]true[/code] if the array's size or its elements are different "
"than [param right]'s."
@ -12187,85 +12089,6 @@ msgstr ""
"Il risultato è nel segmento che va da [code]y = 0[/code] a [code]y = 5[/"
"code]. È la posizione più vicina nel segmento al punto indicato."
msgid ""
"Returns an array with the IDs of the points that form the path found by "
"AStar2D between the given points. The array is ordered from the starting "
"point to the ending point of the path.\n"
"If there is no valid path to the target, and [param allow_partial_path] is "
"[code]true[/code], returns a path to the point closest to the target that can "
"be reached.\n"
"[codeblocks]\n"
"[gdscript]\n"
"var astar = AStar2D.new()\n"
"astar.add_point(1, Vector2(0, 0))\n"
"astar.add_point(2, Vector2(0, 1), 1) # Default weight is 1\n"
"astar.add_point(3, Vector2(1, 1))\n"
"astar.add_point(4, Vector2(2, 0))\n"
"\n"
"astar.connect_points(1, 2, false)\n"
"astar.connect_points(2, 3, false)\n"
"astar.connect_points(4, 3, false)\n"
"astar.connect_points(1, 4, false)\n"
"\n"
"var res = astar.get_id_path(1, 3) # Returns [1, 2, 3]\n"
"[/gdscript]\n"
"[csharp]\n"
"var astar = new AStar2D();\n"
"astar.AddPoint(1, new Vector2(0, 0));\n"
"astar.AddPoint(2, new Vector2(0, 1), 1); // Default weight is 1\n"
"astar.AddPoint(3, new Vector2(1, 1));\n"
"astar.AddPoint(4, new Vector2(2, 0));\n"
"\n"
"astar.ConnectPoints(1, 2, false);\n"
"astar.ConnectPoints(2, 3, false);\n"
"astar.ConnectPoints(4, 3, false);\n"
"astar.ConnectPoints(1, 4, false);\n"
"int[] res = astar.GetIdPath(1, 3); // Returns [1, 2, 3]\n"
"[/csharp]\n"
"[/codeblocks]\n"
"If you change the 2nd point's weight to 3, then the result will be [code][1, "
"4, 3][/code] instead, because now even though the distance is longer, it's "
"\"easier\" to get through point 4 than through point 2."
msgstr ""
"Restituisce un array con gli ID dei punti che formano il percorso trovato da "
"AStar2D tra i punti indicati. L'array è ordinato dal punto iniziale al punto "
"finale del percorso.\n"
"Se non c'è un percorso valido per l'obiettivo, e [param allow_partial_path] è "
"[code]true[/code], restituisce un percorso al punto più vicino all'obiettivo "
"che può essere raggiunto.\n"
"[codeblocks]\n"
"[gdscript]\n"
"var astar = AStar2D.new()\n"
"astar.add_point(1, Vector2(0, 0))\n"
"astar.add_point(2, Vector2(0, 1), 1) # Il peso predefinito è 1\n"
"astar.add_point(3, Vector2(1, 1))\n"
"astar.add_point(4, Vector2(2, 0))\n"
"\n"
"astar.connect_points(1, 2, false)\n"
"astar.connect_points(2, 3, false)\n"
"astar.connect_points(4, 3, false)\n"
"astar.connect_points(1, 4, false)\n"
"\n"
"var res = astar.get_id_path(1, 3) # Restituisce [1, 2, 3]\n"
"[/gdscript]\n"
"[csharp]\n"
"var astar = new AStar2D();\n"
"astar.AddPoint(1, new Vector2(0, 0));\n"
"astar.AddPoint(2, new Vector2(0, 1), 1); // Il peso predefinito è 1\n"
"astar.AddPoint(3, new Vector2(1, 1));\n"
"astar.AddPoint(4, new Vector2(2, 0));\n"
"\n"
"astar.ConnectPoints(1, 2, false);\n"
"astar.ConnectPoints(2, 3, false);\n"
"astar.ConnectPoints(4, 3, false);\n"
"astar.ConnectPoints(1, 4, false);\n"
"int[] res = astar.GetIdPath(1, 3); // Restituisce [1, 2, 3]\n"
"[/csharp]\n"
"[/codeblocks]\n"
"Se si cambia il peso a 3 per il punto 2, allora il risultato sarà [code][1, "
"4, 3][/code] invece, poiché adesso anche se la distanza è più lunga, è \"più "
"facile\" arrivare attraverso il punto 4 che attraverso il punto 2."
msgid ""
"Returns the capacity of the structure backing the points, useful in "
"conjunction with [method reserve_space]."
@ -12273,65 +12096,6 @@ msgstr ""
"Restituisce la capacità della struttura che sostiene i punti, utile in "
"combinazione con [method reserve_space]."
msgid ""
"Returns an array with the IDs of the points that form the connection with the "
"given point.\n"
"[codeblocks]\n"
"[gdscript]\n"
"var astar = AStar2D.new()\n"
"astar.add_point(1, Vector2(0, 0))\n"
"astar.add_point(2, Vector2(0, 1))\n"
"astar.add_point(3, Vector2(1, 1))\n"
"astar.add_point(4, Vector2(2, 0))\n"
"\n"
"astar.connect_points(1, 2, true)\n"
"astar.connect_points(1, 3, true)\n"
"\n"
"var neighbors = astar.get_point_connections(1) # Returns [2, 3]\n"
"[/gdscript]\n"
"[csharp]\n"
"var astar = new AStar2D();\n"
"astar.AddPoint(1, new Vector2(0, 0));\n"
"astar.AddPoint(2, new Vector2(0, 1));\n"
"astar.AddPoint(3, new Vector2(1, 1));\n"
"astar.AddPoint(4, new Vector2(2, 0));\n"
"\n"
"astar.ConnectPoints(1, 2, true);\n"
"astar.ConnectPoints(1, 3, true);\n"
"\n"
"int[] neighbors = astar.GetPointConnections(1); // Returns [2, 3]\n"
"[/csharp]\n"
"[/codeblocks]"
msgstr ""
"Restituisce un array con gli ID dei punti che formano la connessione con il "
"punto indicato.\n"
"[codeblocks]\n"
"[gdscript]\n"
"var astar = AStar2D.new()\n"
"astar.add_point(1, Vector2(0, 0))\n"
"astar.add_point(2, Vector2(0, 1))\n"
"astar.add_point(3, Vector2(1, 1))\n"
"astar.add_point(4, Vector2(2, 0))\n"
"\n"
"astar.connect_points(1, 2, true)\n"
"astar.connect_points(1, 3, true)\n"
"\n"
"var neighbors = astar.get_point_connections(1) # Restituisce [2, 3]\n"
"[/gdscript]\n"
"[csharp]\n"
"var astar = new AStar2D();\n"
"astar.AddPoint(1, new Vector2(0, 0));\n"
"astar.AddPoint(2, new Vector2(0, 1));\n"
"astar.AddPoint(3, new Vector2(1, 1));\n"
"astar.AddPoint(4, new Vector2(2, 0));\n"
"\n"
"astar.ConnectPoints(1, 2, true);\n"
"astar.ConnectPoints(1, 3, true);\n"
"\n"
"int[] neighbors = astar.GetPointConnections(1); // Restituisce [2, 3]\n"
"[/csharp]\n"
"[/codeblocks]"
msgid "Returns the number of points currently in the points pool."
msgstr "Restituisce il numero di punti attualmente nell'insieme dei punti."
@ -12444,140 +12208,6 @@ msgstr ""
"movimento da [param id] a [param to_id] è possibile attraverso questo "
"segmento."
msgid ""
"Returns an array with the IDs of the points that form the path found by "
"AStar3D between the given points. The array is ordered from the starting "
"point to the ending point of the path.\n"
"If there is no valid path to the target, and [param allow_partial_path] is "
"[code]true[/code], returns a path to the point closest to the target that can "
"be reached.\n"
"[codeblocks]\n"
"[gdscript]\n"
"var astar = AStar3D.new()\n"
"astar.add_point(1, Vector3(0, 0, 0))\n"
"astar.add_point(2, Vector3(0, 1, 0), 1) # Default weight is 1\n"
"astar.add_point(3, Vector3(1, 1, 0))\n"
"astar.add_point(4, Vector3(2, 0, 0))\n"
"\n"
"astar.connect_points(1, 2, false)\n"
"astar.connect_points(2, 3, false)\n"
"astar.connect_points(4, 3, false)\n"
"astar.connect_points(1, 4, false)\n"
"\n"
"var res = astar.get_id_path(1, 3) # Returns [1, 2, 3]\n"
"[/gdscript]\n"
"[csharp]\n"
"var astar = new AStar3D();\n"
"astar.AddPoint(1, new Vector3(0, 0, 0));\n"
"astar.AddPoint(2, new Vector3(0, 1, 0), 1); // Default weight is 1\n"
"astar.AddPoint(3, new Vector3(1, 1, 0));\n"
"astar.AddPoint(4, new Vector3(2, 0, 0));\n"
"astar.ConnectPoints(1, 2, false);\n"
"astar.ConnectPoints(2, 3, false);\n"
"astar.ConnectPoints(4, 3, false);\n"
"astar.ConnectPoints(1, 4, false);\n"
"int[] res = astar.GetIdPath(1, 3); // Returns [1, 2, 3]\n"
"[/csharp]\n"
"[/codeblocks]\n"
"If you change the 2nd point's weight to 3, then the result will be [code][1, "
"4, 3][/code] instead, because now even though the distance is longer, it's "
"\"easier\" to get through point 4 than through point 2."
msgstr ""
"Restituisce un array con gli ID dei punti che formano il percorso trovato da "
"AStar3D tra i punti indicati. L'array è ordinato dal punto iniziale al punto "
"finale del percorso.\n"
"Se non c'è un percorso valido per l'obiettivo, e [param allow_partial_path] è "
"[code]true[/code], restituisce un percorso al punto più vicino all'obiettivo "
"che può essere raggiunto.\n"
"[codeblocks]\n"
"[gdscript]\n"
"var astar = AStar3D.new()\n"
"astar.add_point(1, Vector3(0, 0, 0))\n"
"astar.add_point(2, Vector3(0, 1, 0), 1) # Il peso predefinito è 1\n"
"astar.add_point(3, Vector3(1, 1, 0))\n"
"astar.add_point(4, Vector3(2, 0, 0))\n"
"\n"
"astar.connect_points(1, 2, false)\n"
"astar.connect_points(2, 3, false)\n"
"astar.connect_points(4, 3, false)\n"
"astar.connect_points(1, 4, false)\n"
"\n"
"var res = astar.get_id_path(1, 3) # Restituisce [1, 2, 3]\n"
"[/gdscript]\n"
"[csharp]\n"
"var astar = new AStar3D();\n"
"astar.AddPoint(1, new Vector3(0, 0, 0));\n"
"astar.AddPoint(2, new Vector3(0, 1, 0), 1); // Il peso predefinito è 1\n"
"astar.AddPoint(3, new Vector3(1, 1, 0));\n"
"astar.AddPoint(4, new Vector3(2, 0, 0));\n"
"astar.ConnectPoints(1, 2, false);\n"
"astar.ConnectPoints(2, 3, false);\n"
"astar.ConnectPoints(4, 3, false);\n"
"astar.ConnectPoints(1, 4, false);\n"
"int[] res = astar.GetIdPath(1, 3); // Restituisce [1, 2, 3]\n"
"[/csharp]\n"
"[/codeblocks]\n"
"Se si cambia il peso a 3 per il punto 2, allora il risultato sarà [code][1, "
"4, 3][/code] invece, poiché adesso anche se la distanza è più lunga, è \"più "
"facile\" arrivare attraverso il punto 4 che attraverso il punto 2."
msgid ""
"Returns an array with the IDs of the points that form the connection with the "
"given point.\n"
"[codeblocks]\n"
"[gdscript]\n"
"var astar = AStar3D.new()\n"
"astar.add_point(1, Vector3(0, 0, 0))\n"
"astar.add_point(2, Vector3(0, 1, 0))\n"
"astar.add_point(3, Vector3(1, 1, 0))\n"
"astar.add_point(4, Vector3(2, 0, 0))\n"
"\n"
"astar.connect_points(1, 2, true)\n"
"astar.connect_points(1, 3, true)\n"
"\n"
"var neighbors = astar.get_point_connections(1) # Returns [2, 3]\n"
"[/gdscript]\n"
"[csharp]\n"
"var astar = new AStar3D();\n"
"astar.AddPoint(1, new Vector3(0, 0, 0));\n"
"astar.AddPoint(2, new Vector3(0, 1, 0));\n"
"astar.AddPoint(3, new Vector3(1, 1, 0));\n"
"astar.AddPoint(4, new Vector3(2, 0, 0));\n"
"astar.ConnectPoints(1, 2, true);\n"
"astar.ConnectPoints(1, 3, true);\n"
"\n"
"int[] neighbors = astar.GetPointConnections(1); // Returns [2, 3]\n"
"[/csharp]\n"
"[/codeblocks]"
msgstr ""
"Restituisce un array con gli ID dei punti che formano la connessione con il "
"punto indicato.\n"
"[codeblocks]\n"
"[gdscript]\n"
"var astar = AStar3D.new()\n"
"astar.add_point(1, Vector3(0, 0, 0))\n"
"astar.add_point(2, Vector3(0, 1, 0))\n"
"astar.add_point(3, Vector3(1, 1, 0))\n"
"astar.add_point(4, Vector3(2, 0, 0))\n"
"\n"
"astar.connect_points(1, 2, true)\n"
"astar.connect_points(1, 3, true)\n"
"\n"
"var neighbors = astar.get_point_connections(1) # Restituisce [2, 3]\n"
"[/gdscript]\n"
"[csharp]\n"
"var astar = new AStar3D();\n"
"astar.AddPoint(1, new Vector3(0, 0, 0));\n"
"astar.AddPoint(2, new Vector3(0, 1, 0));\n"
"astar.AddPoint(3, new Vector3(1, 1, 0));\n"
"astar.AddPoint(4, new Vector3(2, 0, 0));\n"
"astar.ConnectPoints(1, 2, true);\n"
"astar.ConnectPoints(1, 3, true);\n"
"\n"
"int[] neighbors = astar.GetPointConnections(1); // Restituisce [2, 3]\n"
"[/csharp]\n"
"[/codeblocks]"
msgid ""
"Returns an array with the points that are in the path found by AStar3D "
"between the given points. The array is ordered from the starting point to the "
@ -28011,25 +27641,6 @@ msgstr ""
"Elimina il punto all'indice [param idx] dalla curva. Invia un errore alla "
"console se [param idx] è fuori dai limiti."
msgid ""
"Returns the position between the vertex [param idx] and the vertex [code]idx "
"+ 1[/code], where [param t] controls if the point is the first vertex "
"([code]t = 0.0[/code]), the last vertex ([code]t = 1.0[/code]), or in "
"between. Values of [param t] outside the range ([code]0.0 >= t <=1[/code]) "
"give strange, but predictable results.\n"
"If [param idx] is out of bounds it is truncated to the first or last vertex, "
"and [param t] is ignored. If the curve has no points, the function sends an "
"error to the console, and returns [code](0, 0)[/code]."
msgstr ""
"Restituisce la posizione tra il vertice [param idx] e il vertice [code]idx + "
"1[/code], dove [param t] controlla se il punto è il primo vertice ([code]t = "
"0,0[/code]), l'ultimo vertice ([code]t = 1,0[/code]) o intermedio. I valori "
"di [param t] al di fuori dell'intervallo ([code]0,0 >= t <=1[/code]) danno "
"risultati strani, ma prevedibili.\n"
"Se [param idx] è fuori dai limiti, viene troncato al primo o all'ultimo "
"vertice e [param t] viene ignorato. Se la curva non ha punti, la funzione "
"invia un errore alla console e restituisce [code](0, 0)[/code]."
msgid "Returns the cache of points as a [PackedVector3Array]."
msgstr "Restituisce i punti memorizzati nella cache come [PackedVector3Array]."
@ -93310,23 +92921,6 @@ msgstr ""
"ThemeDB.fallback_font]).\n"
"Usa [method has_default_font] per verificare se questo valore è valido."
msgid ""
"The default font size of this theme resource. Used as the default value when "
"trying to fetch a font size value that doesn't exist in this theme or is in "
"invalid state. If the default font size is also missing or invalid, the "
"engine fallback value is used (see [member ThemeDB.fallback_font_size]).\n"
"Values below [code]0[/code] are invalid and can be used to unset the "
"property. Use [method has_default_font_size] to check if this value is valid."
msgstr ""
"La dimensione predefinita del font di questa risorsa tema. Utilizzata come "
"valore predefinito quando si tenta di recuperare un valore di dimensione del "
"font che non esiste in questo tema o è in uno stato non valido. Se anche la "
"dimensione predefinita del font è mancante o non valida, viene utilizzato il "
"valore di riserva del motore (vedi [member ThemeDB.fallback_font_size]).\n"
"I valori inferiori a [code]0[/code] non sono validi e possono essere "
"utilizzati per annullare l'impostazione della proprietà. Usa [method "
"has_default_font_size] per verificare se questo valore è valido."
msgid "Theme's [Color] item type."
msgstr "Il tipo di [Color] del tema."

File diff suppressed because it is too large Load Diff

View File

@ -6370,26 +6370,6 @@ msgstr ""
"一組放置在 2D 座標上的 [AnimationRootNode],在三個相鄰節點之間交叉淡化。被 "
"[AnimationTree] 使用。"
msgid ""
"A resource used by [AnimationNodeBlendTree].\n"
"[AnimationNodeBlendSpace1D] represents a virtual 2D space on which "
"[AnimationRootNode]s are placed. Outputs the linear blend of the three "
"adjacent animations using a [Vector2] weight. Adjacent in this context means "
"the three [AnimationRootNode]s making up the triangle that contains the "
"current value.\n"
"You can add vertices to the blend space with [method add_blend_point] and "
"automatically triangulate it by setting [member auto_triangles] to "
"[code]true[/code]. Otherwise, use [method add_triangle] and [method "
"remove_triangle] to triangulate the blend space by hand."
msgstr ""
"[AnimationNodeBlendTree] 使用的資源。\n"
"[AnimationNodeBlendSpace1D] 代表放置 [AnimationRootNode] 的虛擬 2D 空間。輸出"
"的是使用 [Vector2] 權重對相鄰的三個動畫進行線性混合的結果。此處的“相鄰”指的是"
"構成包含目前值的三角形的三個 [AnimationRootNode]。\n"
"你可以使用 [method add_blend_point] 向混合空間中新增頂點,將 [member "
"auto_triangles] 設為 [code]true[/code] 可以將其自動三角形化。否則,請使用 "
"[method add_triangle] 和 [method remove_triangle] 手動對混合空間進行三角形化。"
msgid ""
"Adds a new point that represents a [param node] at the position set by [param "
"pos]. You can insert it at a specific index using the [param at_index] "
@ -8728,64 +8708,6 @@ msgid ""
msgstr ""
"該函式返回支援點的資料結構的容量,可以與 [method reserve_space] 方法一起使用。"
msgid ""
"Returns an array with the IDs of the points that form the connection with the "
"given point.\n"
"[codeblocks]\n"
"[gdscript]\n"
"var astar = AStar2D.new()\n"
"astar.add_point(1, Vector2(0, 0))\n"
"astar.add_point(2, Vector2(0, 1))\n"
"astar.add_point(3, Vector2(1, 1))\n"
"astar.add_point(4, Vector2(2, 0))\n"
"\n"
"astar.connect_points(1, 2, true)\n"
"astar.connect_points(1, 3, true)\n"
"\n"
"var neighbors = astar.get_point_connections(1) # Returns [2, 3]\n"
"[/gdscript]\n"
"[csharp]\n"
"var astar = new AStar2D();\n"
"astar.AddPoint(1, new Vector2(0, 0));\n"
"astar.AddPoint(2, new Vector2(0, 1));\n"
"astar.AddPoint(3, new Vector2(1, 1));\n"
"astar.AddPoint(4, new Vector2(2, 0));\n"
"\n"
"astar.ConnectPoints(1, 2, true);\n"
"astar.ConnectPoints(1, 3, true);\n"
"\n"
"int[] neighbors = astar.GetPointConnections(1); // Returns [2, 3]\n"
"[/csharp]\n"
"[/codeblocks]"
msgstr ""
"返回一個陣列,其中包含與給定點形成連接的點的 ID。\n"
"[codeblocks]\n"
"[gdscript]\n"
"var astar = AStar2D.new()\n"
"astar.add_point(1, Vector2(0, 0))\n"
"astar.add_point(2, Vector2(0, 1))\n"
"astar.add_point(3, Vector2(1, 1))\n"
"astar.add_point(4, Vector2(2, 0))\n"
"\n"
"astar.connect_points(1, 2, true)\n"
"astar.connect_points(1, 3, true)\n"
"\n"
"var neighbors = astar.get_point_connections(1) # 返回 [2, 3]\n"
"[/gdscript]\n"
"[csharp]\n"
"var astar = new AStar2D();\n"
"astar.AddPoint(1, new Vector2(0, 0));\n"
"astar.AddPoint(2, new Vector2(0, 1));\n"
"astar.AddPoint(3, new Vector2(1, 1));\n"
"astar.AddPoint(4, new Vector2(2, 0));\n"
"\n"
"astar.ConnectPoints(1, 2, true);\n"
"astar.ConnectPoints(1, 3, true);\n"
"\n"
"int[] neighbors = astar.GetPointConnections(1); // 返回 [2, 3]\n"
"[/csharp]\n"
"[/codeblocks]"
msgid "Returns the number of points currently in the points pool."
msgstr "返回點池中目前的點數。"
@ -8975,62 +8897,6 @@ msgstr ""
"結果是在從 [code]y = 0[/code] 到 [code]y = 5[/code] 的線段中。它是線段中距離給"
"定點最近的位置。"
msgid ""
"Returns an array with the IDs of the points that form the connection with the "
"given point.\n"
"[codeblocks]\n"
"[gdscript]\n"
"var astar = AStar3D.new()\n"
"astar.add_point(1, Vector3(0, 0, 0))\n"
"astar.add_point(2, Vector3(0, 1, 0))\n"
"astar.add_point(3, Vector3(1, 1, 0))\n"
"astar.add_point(4, Vector3(2, 0, 0))\n"
"\n"
"astar.connect_points(1, 2, true)\n"
"astar.connect_points(1, 3, true)\n"
"\n"
"var neighbors = astar.get_point_connections(1) # Returns [2, 3]\n"
"[/gdscript]\n"
"[csharp]\n"
"var astar = new AStar3D();\n"
"astar.AddPoint(1, new Vector3(0, 0, 0));\n"
"astar.AddPoint(2, new Vector3(0, 1, 0));\n"
"astar.AddPoint(3, new Vector3(1, 1, 0));\n"
"astar.AddPoint(4, new Vector3(2, 0, 0));\n"
"astar.ConnectPoints(1, 2, true);\n"
"astar.ConnectPoints(1, 3, true);\n"
"\n"
"int[] neighbors = astar.GetPointConnections(1); // Returns [2, 3]\n"
"[/csharp]\n"
"[/codeblocks]"
msgstr ""
"返回一個陣列,其中包含與給定點形成連接的點的 ID。\n"
"[codeblocks]\n"
"[gdscript]\n"
"var astar = AStar3D.new()\n"
"astar.add_point(1, Vector3(0, 0, 0))\n"
"astar.add_point(2, Vector3(0, 1, 0))\n"
"astar.add_point(3, Vector3(1, 1, 0))\n"
"astar.add_point(4, Vector3(2, 0, 0))\n"
"\n"
"astar.connect_points(1, 2, true)\n"
"astar.connect_points(1, 3, true)\n"
"\n"
"var neighbors = astar.get_point_connections(1) # 返回 [2, 3]\n"
"[/gdscript]\n"
"[csharp]\n"
"var astar = new AStar3D();\n"
"astar.AddPoint(1, new Vector3(0, 0, 0));\n"
"astar.AddPoint(2, new Vector3(0, 1, 0));\n"
"astar.AddPoint(3, new Vector3(1, 1, 0));\n"
"astar.AddPoint(4, new Vector3(2, 0, 0));\n"
"astar.ConnectPoints(1, 2, true);\n"
"astar.ConnectPoints(1, 3, true);\n"
"\n"
"int[] neighbors = astar.GetPointConnections(1); // 返回 [2, 3]\n"
"[/csharp]\n"
"[/codeblocks]"
msgid ""
"Reserves space internally for [param num_nodes] points. Useful if you're "
"adding a known large number of points at once, such as points on a grid. New "
@ -24475,24 +24341,6 @@ msgid ""
msgstr ""
"從曲線上刪除點 [param idx]。如果 [param idx] 越界,則會向控制台發送錯誤資訊。"
msgid ""
"Returns the position between the vertex [param idx] and the vertex [code]idx "
"+ 1[/code], where [param t] controls if the point is the first vertex "
"([code]t = 0.0[/code]), the last vertex ([code]t = 1.0[/code]), or in "
"between. Values of [param t] outside the range ([code]0.0 >= t <=1[/code]) "
"give strange, but predictable results.\n"
"If [param idx] is out of bounds it is truncated to the first or last vertex, "
"and [param t] is ignored. If the curve has no points, the function sends an "
"error to the console, and returns [code](0, 0)[/code]."
msgstr ""
"返回頂點 [param idx] 和頂點 [code]idx + 1[/code] 之間的位置,其中 [param t] 控"
"制該點是否為第一個頂點([code]t = 0.0[/code])、最後一個頂點([code]t = 1.0[/"
"code])、或介於兩者之間。超出範圍([code]0.0 >= t <=1[/code])的 [param t] 的"
"值會給出奇怪但可預測的結果。\n"
"如果 [param idx] 越界,它將被截斷到第一個或最後一個頂點,而 [param t] 將被忽"
"略。如果曲線沒有點,則該函式將向控制台發送一個錯誤,並返回 [code](0, 0)[/"
"code]。"
msgid ""
"Returns a point within the curve at position [param offset], where [param "
"offset] is measured as a pixel distance along the curve.\n"
@ -55642,26 +55490,6 @@ msgstr ""
"[member spawn_path] 指向的節點的子節點。\n"
"[b]注意:[/b]可出生的場景是自動出生的。[method spawn] 僅在自訂出生時需要。"
msgid ""
"Method called on all peers when for every custom [method spawn] requested by "
"the authority. Will receive the [code]data[/code] parameter, and should "
"return a [Node] that is not in the scene tree.\n"
"[b]Note:[/b] The returned node should [b]not[/b] be added to the scene with "
"[method Node.add_child]. This is done automatically."
msgstr ""
"當每個自訂 [method spawn] 被授權端請求時,在所有對等體上呼叫的方法。將接收 "
"[code]data[/code] 參數,並且應該返回一個不在場景樹中的 [Node]。\n"
"[b]注意:[/b]返回的節點[b]不[/b]應該用 [method Node.add_child] 新增到場景中。"
"這是自動完成的。"
msgid ""
"Maximum nodes that is allowed to be spawned by this spawner. Includes both "
"spawnable scenes and custom spawns.\n"
"When set to [code]0[/code] (the default), there is no limit."
msgstr ""
"該出生器允許出生的最大節點數。包括可出生場景和自訂出生。\n"
"當設定為 [code]0[/code](預設值)時,沒有限制。"
msgid ""
"Path to the spawn root. Spawnable scenes that are added as direct children "
"are replicated to other peers."
@ -83450,11 +83278,6 @@ msgstr "設定遮擋多邊形剔除模式。詳見 [enum CanvasOccluderPolygonCu
msgid "Sets the shape of the occluder polygon."
msgstr "設定遮擋多邊形的形狀。"
msgid ""
"A copy of the canvas item will be drawn with a local offset of the mirroring "
"[Vector2]."
msgstr "畫布專案的副本將以鏡像的局部偏移量[Vector2]被繪製。"
msgid "Modulates all colors in the given canvas."
msgstr "調變給定畫布中的所有顏色。"
@ -103778,20 +103601,6 @@ msgstr ""
"ThemeDB.fallback_font])。\n"
"請使用 [method has_default_font] 來檢查該值是否有效。"
msgid ""
"The default font size of this theme resource. Used as the default value when "
"trying to fetch a font size value that doesn't exist in this theme or is in "
"invalid state. If the default font size is also missing or invalid, the "
"engine fallback value is used (see [member ThemeDB.fallback_font_size]).\n"
"Values below [code]0[/code] are invalid and can be used to unset the "
"property. Use [method has_default_font_size] to check if this value is valid."
msgstr ""
"該主題資源的預設字形大小。嘗試獲取字形大小時,如果該主題中不存在或者為無效狀"
"態,則會用它作為預設值。如果預設字形大小也缺失或無效,則會使用引擎的退回值"
"(見 [member ThemeDB.fallback_font_size])。\n"
"小於 [code]0[/code] 的值無效,可用於清除對該屬性的設定。請使用 [method "
"has_default_font_size] 來檢查該值是否有效。"
msgid "Theme's [Color] item type."
msgstr "主題的 [Color] 顏色項型別。"

View File

@ -2143,17 +2143,28 @@ void RenderingDeviceDriverD3D12::command_pipeline_barrier(CommandBufferID p_cmd_
for (uint32_t i = 0; i < p_texture_barriers.size(); i++) {
const TextureBarrier &texture_barrier_rd = p_texture_barriers[i];
const TextureInfo *texture_info = (const TextureInfo *)(texture_barrier_rd.texture.id);
if (texture_info->main_texture) {
texture_info = texture_info->main_texture;
}
_rd_stages_and_access_to_d3d12(p_src_stages, texture_barrier_rd.prev_layout, texture_barrier_rd.src_access, texture_barrier_d3d12.SyncBefore, texture_barrier_d3d12.AccessBefore);
_rd_stages_and_access_to_d3d12(p_dst_stages, texture_barrier_rd.next_layout, texture_barrier_rd.dst_access, texture_barrier_d3d12.SyncAfter, texture_barrier_d3d12.AccessAfter);
texture_barrier_d3d12.LayoutBefore = _rd_texture_layout_to_d3d12_barrier_layout(texture_barrier_rd.prev_layout);
texture_barrier_d3d12.LayoutAfter = _rd_texture_layout_to_d3d12_barrier_layout(texture_barrier_rd.next_layout);
texture_barrier_d3d12.pResource = texture_info->resource;
texture_barrier_d3d12.Subresources.IndexOrFirstMipLevel = texture_barrier_rd.subresources.base_mipmap;
texture_barrier_d3d12.Subresources.NumMipLevels = texture_barrier_rd.subresources.mipmap_count;
texture_barrier_d3d12.Subresources.FirstArraySlice = texture_barrier_rd.subresources.base_layer;
texture_barrier_d3d12.Subresources.NumArraySlices = texture_barrier_rd.subresources.layer_count;
texture_barrier_d3d12.Subresources.FirstPlane = _compute_plane_slice(texture_info->format, texture_barrier_rd.subresources.aspect);
texture_barrier_d3d12.Subresources.NumPlanes = format_get_plane_count(texture_info->format);
if (texture_barrier_rd.subresources.mipmap_count == texture_info->mipmaps && texture_barrier_rd.subresources.layer_count == texture_info->layers) {
// So, all resources. Then, let's be explicit about it so D3D12 doesn't think
// we are dealing with a subset of subresources.
texture_barrier_d3d12.Subresources.IndexOrFirstMipLevel = 0xffffffff;
texture_barrier_d3d12.Subresources.NumMipLevels = 0;
// Because NumMipLevels == 0, all the other fields are ignored by D3D12.
} else {
texture_barrier_d3d12.Subresources.IndexOrFirstMipLevel = texture_barrier_rd.subresources.base_mipmap;
texture_barrier_d3d12.Subresources.NumMipLevels = texture_barrier_rd.subresources.mipmap_count;
texture_barrier_d3d12.Subresources.FirstArraySlice = texture_barrier_rd.subresources.base_layer;
texture_barrier_d3d12.Subresources.NumArraySlices = texture_barrier_rd.subresources.layer_count;
texture_barrier_d3d12.Subresources.FirstPlane = _compute_plane_slice(texture_info->format, texture_barrier_rd.subresources.aspect);
texture_barrier_d3d12.Subresources.NumPlanes = format_get_plane_count(texture_info->format);
}
texture_barrier_d3d12.Flags = (texture_barrier_rd.prev_layout == RDD::TEXTURE_LAYOUT_UNDEFINED) ? D3D12_TEXTURE_BARRIER_FLAG_DISCARD : D3D12_TEXTURE_BARRIER_FLAG_NONE;
texture_barriers.push_back(texture_barrier_d3d12);
}

View File

@ -468,7 +468,7 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_
update_skeletons = false;
}
// Canvas group begins here, render until before this item
_render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list, r_sdf_used, false, r_render_info);
_render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list, r_sdf_used, false, r_render_info, material_screen_texture_mipmaps_cached);
item_count = 0;
if (ci->canvas_group_owner->canvas_group->mode != RS::CANVAS_GROUP_MODE_TRANSPARENT) {
@ -499,7 +499,7 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_
mesh_storage->update_mesh_instances();
update_skeletons = false;
}
_render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list, r_sdf_used, true, r_render_info);
_render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list, r_sdf_used, true, r_render_info, material_screen_texture_mipmaps_cached);
item_count = 0;
if (ci->canvas_group->blur_mipmaps) {
@ -523,7 +523,7 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_
}
//render anything pending, including clearing if no items
_render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list, r_sdf_used, false, r_render_info);
_render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list, r_sdf_used, false, r_render_info, material_screen_texture_mipmaps_cached);
item_count = 0;
texture_storage->render_target_copy_to_back_buffer(p_to_render_target, back_buffer_rect, backbuffer_gen_mipmaps);
@ -553,7 +553,7 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_
mesh_storage->update_mesh_instances();
update_skeletons = false;
}
_render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list, r_sdf_used, canvas_group_owner != nullptr, r_render_info);
_render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list, r_sdf_used, canvas_group_owner != nullptr, r_render_info, material_screen_texture_mipmaps_cached);
//then reset
item_count = 0;
}
@ -573,10 +573,10 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_
state.current_instance_buffer_index = 0;
}
void RasterizerCanvasGLES3::_render_items(RID p_to_render_target, int p_item_count, const Transform2D &p_canvas_transform_inverse, Light *p_lights, bool &r_sdf_used, bool p_to_backbuffer, RenderingMethod::RenderInfo *r_render_info) {
void RasterizerCanvasGLES3::_render_items(RID p_to_render_target, int p_item_count, const Transform2D &p_canvas_transform_inverse, Light *p_lights, bool &r_sdf_used, bool p_to_backbuffer, RenderingMethod::RenderInfo *r_render_info, bool p_backbuffer_has_mipmaps) {
GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton();
canvas_begin(p_to_render_target, p_to_backbuffer);
canvas_begin(p_to_render_target, p_to_backbuffer, p_backbuffer_has_mipmaps);
if (p_item_count <= 0) {
// Nothing to draw, just call canvas_begin() to clear the render target and return.
@ -647,18 +647,17 @@ void RasterizerCanvasGLES3::_render_items(RID p_to_render_target, int p_item_cou
_record_item_commands(ci, p_to_render_target, p_canvas_transform_inverse, current_clip, blend_mode, p_lights, index, batch_broken, r_sdf_used, Point2());
} else {
Point2 start_pos = ci->repeat_size * -(ci->repeat_times / 2);
Point2 end_pos = ci->repeat_size * ci->repeat_times + ci->repeat_size + start_pos;
Point2 pos = start_pos;
Point2 offset;
do {
do {
_record_item_commands(ci, p_to_render_target, p_canvas_transform_inverse, current_clip, blend_mode, p_lights, index, batch_broken, r_sdf_used, pos);
pos.y += ci->repeat_size.y;
} while (pos.y < end_pos.y);
pos.x += ci->repeat_size.x;
pos.y = start_pos.y;
} while (pos.x < end_pos.x);
int repeat_times_x = ci->repeat_size.x ? ci->repeat_times : 0;
int repeat_times_y = ci->repeat_size.y ? ci->repeat_times : 0;
for (int ry = 0; ry <= repeat_times_y; ry++) {
offset.y = start_pos.y + ry * ci->repeat_size.y;
for (int rx = 0; rx <= repeat_times_x; rx++) {
offset.x = start_pos.x + rx * ci->repeat_size.x;
_record_item_commands(ci, p_to_render_target, p_canvas_transform_inverse, current_clip, blend_mode, p_lights, index, batch_broken, r_sdf_used, offset);
}
}
}
}
@ -809,7 +808,7 @@ void RasterizerCanvasGLES3::_render_items(RID p_to_render_target, int p_item_cou
state.last_item_index += index;
}
void RasterizerCanvasGLES3::_record_item_commands(const Item *p_item, RID p_render_target, const Transform2D &p_canvas_transform_inverse, Item *&current_clip, GLES3::CanvasShaderData::BlendMode p_blend_mode, Light *p_lights, uint32_t &r_index, bool &r_batch_broken, bool &r_sdf_used, const Point2 &p_offset) {
void RasterizerCanvasGLES3::_record_item_commands(const Item *p_item, RID p_render_target, const Transform2D &p_canvas_transform_inverse, Item *&current_clip, GLES3::CanvasShaderData::BlendMode p_blend_mode, Light *p_lights, uint32_t &r_index, bool &r_batch_broken, bool &r_sdf_used, const Point2 &p_repeat_offset) {
RenderingServer::CanvasItemTextureFilter texture_filter = p_item->texture_filter == RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT ? state.default_filter : p_item->texture_filter;
if (texture_filter != state.canvas_instance_batches[state.current_batch_index].filter) {
@ -826,11 +825,11 @@ void RasterizerCanvasGLES3::_record_item_commands(const Item *p_item, RID p_rend
state.canvas_instance_batches[state.current_batch_index].repeat = texture_repeat;
}
Transform2D base_transform = p_canvas_transform_inverse * p_item->final_transform;
if (p_offset.x || p_offset.y) {
base_transform *= Transform2D(0, p_offset / p_item->xform_curr.get_scale()); // TODO: Interpolate or explain why not needed.
Transform2D base_transform = p_item->final_transform;
if (p_item->repeat_source_item && (p_repeat_offset.x || p_repeat_offset.y)) {
base_transform.columns[2] += p_item->repeat_source_item->final_transform.basis_xform(p_repeat_offset);
}
base_transform = p_canvas_transform_inverse * base_transform;
Transform2D draw_transform; // Used by transform command
@ -2170,7 +2169,7 @@ bool RasterizerCanvasGLES3::free(RID p_rid) {
void RasterizerCanvasGLES3::update() {
}
void RasterizerCanvasGLES3::canvas_begin(RID p_to_render_target, bool p_to_backbuffer) {
void RasterizerCanvasGLES3::canvas_begin(RID p_to_render_target, bool p_to_backbuffer, bool p_backbuffer_has_mipmaps) {
GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();
GLES3::Config *config = GLES3::Config::get_singleton();
@ -2185,6 +2184,7 @@ void RasterizerCanvasGLES3::canvas_begin(RID p_to_render_target, bool p_to_backb
glBindFramebuffer(GL_FRAMEBUFFER, render_target->fbo);
glActiveTexture(GL_TEXTURE0 + config->max_texture_image_units - 4);
glBindTexture(GL_TEXTURE_2D, render_target->backbuffer);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, p_backbuffer_has_mipmaps ? render_target->mipmap_count - 1 : 0);
}
if (render_target->is_transparent || p_to_backbuffer) {

View File

@ -335,7 +335,7 @@ public:
typedef void Texture;
void canvas_begin(RID p_to_render_target, bool p_to_backbuffer);
void canvas_begin(RID p_to_render_target, bool p_to_backbuffer, bool p_backbuffer_has_mipmaps);
//virtual void draw_window_margins(int *black_margin, RID *black_image) override;
void draw_lens_distortion_rect(const Rect2 &p_rect, float p_k1, float p_k2, const Vector2 &p_eye_center, float p_oversample);
@ -361,8 +361,8 @@ public:
void _prepare_canvas_texture(RID p_texture, RS::CanvasItemTextureFilter p_base_filter, RS::CanvasItemTextureRepeat p_base_repeat, uint32_t &r_index, Size2 &r_texpixel_size);
void canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, Light *p_directional_list, const Transform2D &p_canvas_transform, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel, bool &r_sdf_used, RenderingMethod::RenderInfo *r_render_info = nullptr) override;
void _render_items(RID p_to_render_target, int p_item_count, const Transform2D &p_canvas_transform_inverse, Light *p_lights, bool &r_sdf_used, bool p_to_backbuffer = false, RenderingMethod::RenderInfo *r_render_info = nullptr);
void _record_item_commands(const Item *p_item, RID p_render_target, const Transform2D &p_canvas_transform_inverse, Item *&current_clip, GLES3::CanvasShaderData::BlendMode p_blend_mode, Light *p_lights, uint32_t &r_index, bool &r_break_batch, bool &r_sdf_used, const Point2 &p_offset);
void _render_items(RID p_to_render_target, int p_item_count, const Transform2D &p_canvas_transform_inverse, Light *p_lights, bool &r_sdf_used, bool p_to_backbuffer = false, RenderingMethod::RenderInfo *r_render_info = nullptr, bool p_backbuffer_has_mipmaps = false);
void _record_item_commands(const Item *p_item, RID p_render_target, const Transform2D &p_canvas_transform_inverse, Item *&current_clip, GLES3::CanvasShaderData::BlendMode p_blend_mode, Light *p_lights, uint32_t &r_index, bool &r_break_batch, bool &r_sdf_used, const Point2 &p_repeat_offset);
void _render_batch(Light *p_lights, uint32_t p_index, RenderingMethod::RenderInfo *r_render_info = nullptr);
bool _bind_material(GLES3::CanvasMaterialData *p_material_data, CanvasShaderGLES3::ShaderVariant p_variant, uint64_t p_specialization);
void _new_batch(bool &r_batch_broken);

View File

@ -62,6 +62,10 @@
#define _EXT_DEBUG_SEVERITY_LOW_ARB 0x9148
#define _EXT_DEBUG_OUTPUT 0x92E0
#ifndef GL_FRAMEBUFFER_SRGB
#define GL_FRAMEBUFFER_SRGB 0x8DB9
#endif
#ifndef GLAPIENTRY
#if defined(WINDOWS_ENABLED)
#define GLAPIENTRY APIENTRY
@ -345,6 +349,9 @@ RasterizerGLES3::RasterizerGLES3() {
}
}
// Disable OpenGL linear to sRGB conversion, because Godot will always do this conversion itself.
glDisable(GL_FRAMEBUFFER_SRGB);
// OpenGL needs to be initialized before initializing the Rasterizers
config = memnew(GLES3::Config);
utilities = memnew(GLES3::Utilities);

View File

@ -777,7 +777,6 @@ void RasterizerSceneGLES3::_draw_sky(RID p_env, const Projection &p_projection,
ERR_FAIL_COND(p_env.is_null());
Sky *sky = sky_owner.get_or_null(environment_get_sky(p_env));
ERR_FAIL_NULL(sky);
GLES3::SkyMaterialData *material_data = nullptr;
RID sky_material;
@ -851,6 +850,15 @@ void RasterizerSceneGLES3::_draw_sky(RID p_env, const Projection &p_projection,
material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::SKY_ENERGY_MULTIPLIER, p_sky_energy_multiplier, shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);
material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::LUMINANCE_MULTIPLIER, p_luminance_multiplier, shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);
Color fog_color = environment_get_fog_light_color(p_env).srgb_to_linear() * environment_get_fog_light_energy(p_env);
material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::FOG_ENABLED, environment_get_fog_enabled(p_env), shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);
material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::FOG_AERIAL_PERSPECTIVE, environment_get_fog_aerial_perspective(p_env), shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);
material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::FOG_LIGHT_COLOR, fog_color, shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);
material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::FOG_SUN_SCATTER, environment_get_fog_sun_scatter(p_env), shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);
material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::FOG_DENSITY, environment_get_fog_density(p_env), shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);
material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::FOG_SKY_AFFECT, environment_get_fog_sky_affect(p_env), shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);
material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::DIRECTIONAL_LIGHT_COUNT, sky_globals.directional_light_count, shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);
if (p_use_multiview) {
glBindBufferBase(GL_UNIFORM_BUFFER, SKY_MULTIVIEW_UNIFORM_LOCATION, scene_state.multiview_buffer);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
@ -904,7 +912,7 @@ void RasterizerSceneGLES3::_update_sky_radiance(RID p_env, const Projection &p_p
RS::SkyMode sky_mode = sky->mode;
if (sky_mode == RS::SKY_MODE_AUTOMATIC) {
if (shader_data->uses_time || shader_data->uses_position) {
if ((shader_data->uses_time || shader_data->uses_position) && sky->radiance_size == 256) {
update_single_frame = true;
sky_mode = RS::SKY_MODE_REALTIME;
} else if (shader_data->uses_light || shader_data->ubo_size > 0) {
@ -925,7 +933,7 @@ void RasterizerSceneGLES3::_update_sky_radiance(RID p_env, const Projection &p_p
int max_processing_layer = sky->mipmap_count;
// Update radiance cubemap
if (sky->reflection_dirty && (sky->processing_layer > max_processing_layer || update_single_frame)) {
if (sky->reflection_dirty && (sky->processing_layer >= max_processing_layer || update_single_frame)) {
static const Vector3 view_normals[6] = {
Vector3(+1, 0, 0),
Vector3(-1, 0, 0),
@ -2587,7 +2595,7 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_
scene_state.enable_gl_depth_draw(false);
if (draw_sky) {
if (draw_sky || draw_sky_fog_only) {
RENDER_TIMESTAMP("Render Sky");
scene_state.enable_gl_depth_test(true);

View File

@ -698,7 +698,8 @@ void ShaderGLES3::_clear_version(Version *p_version) {
void ShaderGLES3::_initialize_version(Version *p_version) {
ERR_FAIL_COND(p_version->variants.size() > 0);
if (shader_cache_dir_valid && _load_from_cache(p_version)) {
bool use_cache = shader_cache_dir_valid && !(feedback_count > 0 && GLES3::Config::get_singleton()->disable_transform_feedback_shader_cache);
if (use_cache && _load_from_cache(p_version)) {
return;
}
p_version->variants.reserve(variant_count);
@ -709,7 +710,7 @@ void ShaderGLES3::_initialize_version(Version *p_version) {
_compile_specialization(spec, i, p_version, specialization_default_mask);
p_version->variants[i].insert(specialization_default_mask, spec);
}
if (shader_cache_dir_valid) {
if (use_cache) {
_save_to_cache(p_version);
}
}

View File

@ -583,6 +583,8 @@ void main() {
#define SHADER_IS_SRGB true
#define FLAGS_NON_UNIFORM_SCALE (1 << 4)
/* Varyings */
#if defined(COLOR_USED)
@ -955,6 +957,7 @@ ivec2 multiview_uv(ivec2 uv) {
uniform highp mat4 world_transform;
uniform mediump float opaque_prepass_threshold;
uniform highp uint model_flags;
#if defined(RENDER_MATERIAL)
layout(location = 0) out vec4 albedo_output_buffer;
@ -1521,6 +1524,13 @@ void main() {
vec3 light_vertex = vertex;
#endif //LIGHT_VERTEX_USED
highp mat3 model_normal_matrix;
if (bool(model_flags & uint(FLAGS_NON_UNIFORM_SCALE))) {
model_normal_matrix = transpose(inverse(mat3(model_matrix)));
} else {
model_normal_matrix = mat3(model_matrix);
}
{
#CODE : FRAGMENT
}
@ -1728,16 +1738,10 @@ void main() {
vec3 n = normalize(lightmap_normal_xform * normal);
ambient_light += lm_light_l0 * 0.282095f;
ambient_light += lm_light_l1n1 * 0.32573 * n.y * lightmap_exposure_normalization;
ambient_light += lm_light_l1_0 * 0.32573 * n.z * lightmap_exposure_normalization;
ambient_light += lm_light_l1p1 * 0.32573 * n.x * lightmap_exposure_normalization;
if (metallic > 0.01) { // Since the more direct bounced light is lost, we can kind of fake it with this trick.
vec3 r = reflect(normalize(-vertex), normal);
specular_light += lm_light_l1n1 * 0.32573 * r.y * lightmap_exposure_normalization;
specular_light += lm_light_l1_0 * 0.32573 * r.z * lightmap_exposure_normalization;
specular_light += lm_light_l1p1 * 0.32573 * r.x * lightmap_exposure_normalization;
}
ambient_light += lm_light_l0 * lightmap_exposure_normalization;
ambient_light += lm_light_l1n1 * n.y * lightmap_exposure_normalization;
ambient_light += lm_light_l1_0 * n.z * lightmap_exposure_normalization;
ambient_light += lm_light_l1p1 * n.x * lightmap_exposure_normalization;
#else
ambient_light += textureLod(lightmap_textures, uvw, 0.0).rgb * lightmap_exposure_normalization;
#endif
@ -1871,7 +1875,7 @@ void main() {
alpha = min(alpha, clamp(length(ambient_light), 0.0, 1.0));
#if defined(ALPHA_SCISSOR_USED)
if (alpha < alpha_scissor) {
if (alpha < alpha_scissor_threshold) {
discard;
}
#endif // !ALPHA_SCISSOR_USED

View File

@ -59,7 +59,7 @@ layout(location = 10) in highp uvec4 in_bone_attrib;
layout(location = 11) in mediump vec4 in_weight_attrib;
#endif
uniform mediump sampler2D skeleton_texture; // texunit:0
uniform highp sampler2D skeleton_texture; // texunit:0
#endif
/* clang-format on */

View File

@ -108,11 +108,11 @@ uniform float sky_energy_multiplier;
uniform float luminance_multiplier;
uniform float fog_aerial_perspective;
uniform vec3 fog_light_color;
uniform vec4 fog_light_color;
uniform float fog_sun_scatter;
uniform bool fog_enabled;
uniform float fog_density;
uniform float z_far;
uniform float fog_sky_affect;
uniform uint directional_light_count;
#ifdef USE_MULTIVIEW
@ -135,6 +135,24 @@ vec3 interleaved_gradient_noise(vec2 pos) {
}
#endif
#if !defined(DISABLE_FOG)
vec4 fog_process(vec3 view, vec3 sky_color) {
vec3 fog_color = mix(fog_light_color.rgb, sky_color, fog_aerial_perspective);
if (fog_sun_scatter > 0.001) {
vec4 sun_scatter = vec4(0.0);
float sun_total = 0.0;
for (uint i = 0u; i < directional_light_count; i++) {
vec3 light_color = directional_lights.data[i].color_size.xyz * directional_lights.data[i].direction_energy.w;
float light_amount = pow(max(dot(view, directional_lights.data[i].direction_energy.xyz), 0.0), 8.0);
fog_color += light_color * light_amount * fog_sun_scatter;
}
}
return vec4(fog_color, 1.0);
}
#endif // !DISABLE_FOG
void main() {
vec3 cube_normal;
#ifdef USE_MULTIVIEW
@ -203,6 +221,21 @@ void main() {
// Convert to Linear for tonemapping so color matches scene shader better
color = srgb_to_linear(color);
#if !defined(DISABLE_FOG) && !defined(USE_CUBEMAP_PASS)
// Draw "fixed" fog before volumetric fog to ensure volumetric fog can appear in front of the sky.
if (fog_enabled) {
vec4 fog = fog_process(cube_normal, color.rgb);
color.rgb = mix(color.rgb, fog.rgb, fog.a * fog_sky_affect);
}
if (custom_fog.a > 0.0) {
color.rgb = mix(color.rgb, custom_fog.rgb, custom_fog.a);
}
#endif // DISABLE_FOG
color *= exposure;
#ifdef APPLY_TONEMAPPING
color = apply_tonemapping(color, white);

View File

@ -121,7 +121,7 @@ Config::Config() {
#ifdef WEB_ENABLED
msaa_supported = (msaa_max_samples > 0);
#else
msaa_supported = extensions.has("GL_EXT_framebuffer_multisample");
msaa_supported = true;
#endif
#ifndef IOS_ENABLED
#ifdef WEB_ENABLED
@ -218,6 +218,8 @@ Config::Config() {
//https://github.com/godotengine/godot/issues/92662#issuecomment-2161199477
//disable_particles_workaround = false;
}
} else if (rendering_device_name == "PowerVR Rogue GE8320") {
disable_transform_feedback_shader_cache = true;
}
}

View File

@ -96,6 +96,9 @@ public:
bool disable_particles_workaround = false; // set to 'true' to disable 'GPUParticles'
bool flip_xy_workaround = false;
// PowerVR GE 8320 workaround
bool disable_transform_feedback_shader_cache = false;
#ifdef ANDROID_ENABLED
PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC eglFramebufferTextureMultiviewOVR = nullptr;
PFNGLTEXSTORAGE3DMULTISAMPLEPROC eglTexStorage3DMultisample = nullptr;

View File

@ -1518,6 +1518,11 @@ bool LightStorage::_shadow_atlas_find_shadow(ShadowAtlas *shadow_atlas, int *p_i
uint64_t min_pass = 0; // Pass of the existing one, try to use the least recently used one (LRU fashion).
for (int j = 0; j < sc; j++) {
if (sarr[j].owner_is_omni != is_omni) {
// Existing light instance type doesn't match new light instance type skip.
continue;
}
LightInstance *sli = light_instance_owner.get_or_null(sarr[j].owner);
if (!sli) {
// Found a released light instance.

View File

@ -301,7 +301,7 @@ void MeshStorage::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface)
Vector<uint8_t> ir = new_surface.index_data;
wr = wf_indices.ptrw();
if (new_surface.vertex_count < (1 << 16)) {
if (new_surface.vertex_count <= 65536) {
// Read 16 bit indices.
const uint16_t *src_idx = (const uint16_t *)ir.ptr();
for (uint32_t i = 0; i + 5 < wf_index_count; i += 6) {
@ -743,6 +743,7 @@ String MeshStorage::mesh_get_path(RID p_mesh) const {
}
void MeshStorage::mesh_set_shadow_mesh(RID p_mesh, RID p_shadow_mesh) {
ERR_FAIL_COND_MSG(p_mesh == p_shadow_mesh, "Cannot set a mesh as its own shadow mesh.");
Mesh *mesh = mesh_owner.get_or_null(p_mesh);
ERR_FAIL_NULL(mesh);

View File

@ -1039,7 +1039,7 @@ Ref<Image> TextureStorage::texture_2d_get(RID p_texture) const {
data.resize(data_size);
ERR_FAIL_COND_V(data.is_empty(), Ref<Image>());
image = Image::create_from_data(texture->width, texture->height, texture->mipmaps > 1, texture->real_format, data);
image = Image::create_from_data(texture->alloc_width, texture->alloc_height, texture->mipmaps > 1, texture->real_format, data);
ERR_FAIL_COND_V(image->is_empty(), Ref<Image>());
if (texture->format != texture->real_format) {
image->convert(texture->format);
@ -1095,7 +1095,7 @@ Ref<Image> TextureStorage::texture_2d_get(RID p_texture) const {
data.resize(data_size);
ERR_FAIL_COND_V(data.is_empty(), Ref<Image>());
image = Image::create_from_data(texture->width, texture->height, false, Image::FORMAT_RGBA8, data);
image = Image::create_from_data(texture->alloc_width, texture->alloc_height, false, Image::FORMAT_RGBA8, data);
ERR_FAIL_COND_V(image->is_empty(), Ref<Image>());
if (texture->format != Image::FORMAT_RGBA8) {
@ -1497,11 +1497,9 @@ void TextureStorage::_texture_set_data(RID p_texture, const Ref<Image> &p_image,
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
if (texture->target == GL_TEXTURE_2D_ARRAY) {
if (p_initialize) {
glCompressedTexImage3D(GL_TEXTURE_2D_ARRAY, i, internal_format, w, h, texture->layers, 0,
size * texture->layers, &read[ofs]);
} else {
glCompressedTexSubImage3D(GL_TEXTURE_2D_ARRAY, i, 0, 0, p_layer, w, h, 1, internal_format, size, &read[ofs]);
glCompressedTexImage3D(GL_TEXTURE_2D_ARRAY, i, internal_format, w, h, texture->layers, 0, size * texture->layers, nullptr);
}
glCompressedTexSubImage3D(GL_TEXTURE_2D_ARRAY, i, 0, 0, p_layer, w, h, 1, internal_format, size, &read[ofs]);
} else {
glCompressedTexImage2D(blit_target, i, internal_format, w, h, 0, size, &read[ofs]);
}

View File

@ -383,7 +383,7 @@ uint64_t FileAccessUnix::_get_modified_time(const String &p_file) {
if (!err) {
return status.st_mtime;
} else {
print_verbose("Failed to get modified time for: " + p_file + "");
WARN_PRINT("Failed to get modified time for: " + p_file);
return 0;
}
}

View File

@ -553,15 +553,40 @@ uint64_t FileAccessWindows::_get_modified_time(const String &p_file) {
file = file.substr(0, file.length() - 1);
}
struct _stat st;
int rv = _wstat((LPCWSTR)(file.utf16().get_data()), &st);
HANDLE handle = CreateFileW((LPCWSTR)(file.utf16().get_data()), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr);
if (rv == 0) {
return st.st_mtime;
} else {
print_verbose("Failed to get modified time for: " + p_file + "");
return 0;
if (handle != INVALID_HANDLE_VALUE) {
FILETIME ft_create, ft_write;
bool status = GetFileTime(handle, &ft_create, nullptr, &ft_write);
CloseHandle(handle);
if (status) {
uint64_t ret = 0;
// If write time is invalid, fallback to creation time.
if (ft_write.dwHighDateTime == 0 && ft_write.dwLowDateTime == 0) {
ret = ft_create.dwHighDateTime;
ret <<= 32;
ret |= ft_create.dwLowDateTime;
} else {
ret = ft_write.dwHighDateTime;
ret <<= 32;
ret |= ft_write.dwLowDateTime;
}
const uint64_t WINDOWS_TICKS_PER_SECOND = 10000000;
const uint64_t TICKS_TO_UNIX_EPOCH = 116444736000000000LL;
if (ret >= TICKS_TO_UNIX_EPOCH) {
return (ret - TICKS_TO_UNIX_EPOCH) / WINDOWS_TICKS_PER_SECOND;
}
}
}
print_verbose("Failed to get modified time for: " + p_file);
return 0;
}
BitField<FileAccess::UnixPermissionFlags> FileAccessWindows::_get_unix_permissions(const String &p_file) {

View File

@ -35,6 +35,7 @@
#include "editor/editor_string_names.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/gui/editor_spin_slider.h"
#include "editor/plugins/animation_player_editor_plugin.h"
#include "editor/themes/editor_scale.h"
#include "scene/gui/view_panner.h"
#include "scene/resources/text_line.h"
@ -868,6 +869,11 @@ void AnimationBezierTrackEdit::_change_selected_keys_handle_mode(Animation::Hand
undo_redo->add_undo_method(animation.ptr(), "bezier_track_set_key_out_handle", track_key_pair.first, track_key_pair.second, animation->bezier_track_get_key_out_handle(track_key_pair.first, track_key_pair.second));
undo_redo->add_do_method(editor, "_bezier_track_set_key_handle_mode", animation.ptr(), track_key_pair.first, track_key_pair.second, p_mode, p_auto ? Animation::HANDLE_SET_MODE_AUTO : Animation::HANDLE_SET_MODE_RESET);
}
AnimationPlayerEditor *ape = AnimationPlayerEditor::get_singleton();
if (ape) {
undo_redo->add_do_method(ape, "_animation_update_key_frame");
undo_redo->add_undo_method(ape, "_animation_update_key_frame");
}
undo_redo->commit_action();
}
@ -1083,7 +1089,7 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) {
if (I.key == REMOVE_ICON) {
if (!read_only) {
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
undo_redo->create_action("Remove Bezier Track");
undo_redo->create_action("Remove Bezier Track", UndoRedo::MERGE_DISABLE, animation.ptr());
undo_redo->add_do_method(this, "_update_locked_tracks_after", track);
undo_redo->add_do_method(this, "_update_hidden_tracks_after", track);
@ -1559,6 +1565,11 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) {
undo_redo->add_do_method(animation.ptr(), "bezier_track_set_key_out_handle", moving_handle_track, moving_handle_key, moving_handle_right, ratio);
undo_redo->add_undo_method(animation.ptr(), "bezier_track_set_key_out_handle", moving_handle_track, moving_handle_key, animation->bezier_track_get_key_out_handle(moving_handle_track, moving_handle_key), ratio);
}
AnimationPlayerEditor *ape = AnimationPlayerEditor::get_singleton();
if (ape) {
undo_redo->add_do_method(ape, "_animation_update_key_frame");
undo_redo->add_undo_method(ape, "_animation_update_key_frame");
}
undo_redo->commit_action();
moving_handle = 0;
queue_redraw();
@ -1672,6 +1683,11 @@ void AnimationBezierTrackEdit::_menu_selected(int p_index) {
undo_redo->add_do_method(animation.ptr(), "track_insert_key", selected_track, time, new_point);
undo_redo->add_undo_method(this, "_clear_selection_for_anim", animation);
undo_redo->add_undo_method(animation.ptr(), "track_remove_key_at_time", selected_track, time);
AnimationPlayerEditor *ape = AnimationPlayerEditor::get_singleton();
if (ape) {
undo_redo->add_do_method(ape, "_animation_update_key_frame");
undo_redo->add_undo_method(ape, "_animation_update_key_frame");
}
undo_redo->commit_action();
queue_redraw();
}
@ -1772,6 +1788,11 @@ void AnimationBezierTrackEdit::duplicate_selected_keys(real_t p_ofs, bool p_ofs_
i++;
}
AnimationPlayerEditor *ape = AnimationPlayerEditor::get_singleton();
if (ape) {
undo_redo->add_do_method(ape, "_animation_update_key_frame");
undo_redo->add_undo_method(ape, "_animation_update_key_frame");
}
undo_redo->add_do_method(this, "queue_redraw");
undo_redo->add_undo_method(this, "queue_redraw");
undo_redo->commit_action();
@ -1821,6 +1842,15 @@ void AnimationBezierTrackEdit::copy_selected_keys(bool p_cut) {
undo_redo->add_undo_method(this, "_select_at_anim", animation, E->key().track, E->value().pos, i == 0);
i++;
}
AnimationPlayerEditor *ape = AnimationPlayerEditor::get_singleton();
if (ape) {
undo_redo->add_do_method(ape, "_animation_update_key_frame");
undo_redo->add_undo_method(ape, "_animation_update_key_frame");
}
undo_redo->add_do_method(this, "queue_redraw");
undo_redo->add_undo_method(this, "queue_redraw");
undo_redo->commit_action();
}
}
@ -1899,9 +1929,15 @@ void AnimationBezierTrackEdit::paste_keys(real_t p_ofs, bool p_ofs_valid) {
i++;
}
undo_redo->commit_action();
AnimationPlayerEditor *ape = AnimationPlayerEditor::get_singleton();
if (ape) {
undo_redo->add_do_method(ape, "_animation_update_key_frame");
undo_redo->add_undo_method(ape, "_animation_update_key_frame");
}
undo_redo->add_do_method(this, "queue_redraw");
undo_redo->add_undo_method(this, "queue_redraw");
queue_redraw();
undo_redo->commit_action();
}
}
@ -1916,6 +1952,11 @@ void AnimationBezierTrackEdit::delete_selection() {
}
undo_redo->add_do_method(this, "_clear_selection_for_anim", animation);
undo_redo->add_undo_method(this, "_clear_selection_for_anim", animation);
AnimationPlayerEditor *ape = AnimationPlayerEditor::get_singleton();
if (ape) {
undo_redo->add_do_method(ape, "_animation_update_key_frame");
undo_redo->add_undo_method(ape, "_animation_update_key_frame");
}
undo_redo->commit_action();
//selection.clear();
@ -1925,6 +1966,15 @@ void AnimationBezierTrackEdit::delete_selection() {
void AnimationBezierTrackEdit::_bezier_track_insert_key_at_anim(const Ref<Animation> &p_anim, int p_track, double p_time, real_t p_value, const Vector2 &p_in_handle, const Vector2 &p_out_handle, const Animation::HandleMode p_handle_mode) {
int idx = p_anim->bezier_track_insert_key(p_track, p_time, p_value, p_in_handle, p_out_handle);
p_anim->bezier_track_set_key_handle_mode(p_track, idx, p_handle_mode);
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
undo_redo->create_action(TTR("Animation Bezier Curve Change Call"));
AnimationPlayerEditor *ape = AnimationPlayerEditor::get_singleton();
if (ape) {
undo_redo->add_do_method(ape, "_animation_update_key_frame");
undo_redo->add_undo_method(ape, "_animation_update_key_frame");
}
undo_redo->commit_action();
}
void AnimationBezierTrackEdit::_bind_methods() {

View File

@ -266,6 +266,11 @@ bool AnimationTrackKeyEdit::_set(const StringName &p_name, const Variant &p_valu
undo_redo->add_undo_method(animation.ptr(), "bezier_track_set_key_value", track, key, prev);
undo_redo->add_do_method(this, "_update_obj", animation);
undo_redo->add_undo_method(this, "_update_obj", animation);
AnimationPlayerEditor *ape = AnimationPlayerEditor::get_singleton();
if (ape) {
undo_redo->add_do_method(ape, "_animation_update_key_frame");
undo_redo->add_undo_method(ape, "_animation_update_key_frame");
}
undo_redo->commit_action();
setting = false;
@ -282,6 +287,11 @@ bool AnimationTrackKeyEdit::_set(const StringName &p_name, const Variant &p_valu
undo_redo->add_undo_method(animation.ptr(), "bezier_track_set_key_in_handle", track, key, prev);
undo_redo->add_do_method(this, "_update_obj", animation);
undo_redo->add_undo_method(this, "_update_obj", animation);
AnimationPlayerEditor *ape = AnimationPlayerEditor::get_singleton();
if (ape) {
undo_redo->add_do_method(ape, "_animation_update_key_frame");
undo_redo->add_undo_method(ape, "_animation_update_key_frame");
}
undo_redo->commit_action();
setting = false;
@ -298,6 +308,11 @@ bool AnimationTrackKeyEdit::_set(const StringName &p_name, const Variant &p_valu
undo_redo->add_undo_method(animation.ptr(), "bezier_track_set_key_out_handle", track, key, prev);
undo_redo->add_do_method(this, "_update_obj", animation);
undo_redo->add_undo_method(this, "_update_obj", animation);
AnimationPlayerEditor *ape = AnimationPlayerEditor::get_singleton();
if (ape) {
undo_redo->add_do_method(ape, "_animation_update_key_frame");
undo_redo->add_undo_method(ape, "_animation_update_key_frame");
}
undo_redo->commit_action();
setting = false;
@ -318,6 +333,11 @@ bool AnimationTrackKeyEdit::_set(const StringName &p_name, const Variant &p_valu
undo_redo->add_undo_method(animation.ptr(), "bezier_track_set_key_in_handle", track, key, prev_in_handle);
undo_redo->add_undo_method(animation.ptr(), "bezier_track_set_key_out_handle", track, key, prev_out_handle);
undo_redo->add_undo_method(this, "_update_obj", animation);
AnimationPlayerEditor *ape = AnimationPlayerEditor::get_singleton();
if (ape) {
undo_redo->add_do_method(ape, "_animation_update_key_frame");
undo_redo->add_undo_method(ape, "_animation_update_key_frame");
}
undo_redo->commit_action();
setting = false;
@ -7032,7 +7052,10 @@ void AnimationTrackEditor::_update_snap_unit() {
if (timeline->is_using_fps()) {
snap_unit = 1.0 / step->get_value();
} else {
snap_unit = 1.0 / Math::round(1.0 / step->get_value()); // Follow the snap behavior of the timeline editor.
double integer;
double fraction = Math::modf(step->get_value(), &integer);
fraction = 1.0 / Math::round(1.0 / fraction);
snap_unit = integer + fraction;
}
}

View File

@ -994,6 +994,9 @@ Ref<Texture2D> CodeTextEditor::_get_completion_icon(const ScriptLanguage::CodeCo
tex = get_editor_theme_icon(p_option.display);
} else {
tex = EditorNode::get_singleton()->get_class_icon(p_option.display);
if (!tex.is_valid()) {
tex = get_editor_theme_icon(SNAME("Object"));
}
}
} break;
case ScriptLanguage::CODE_COMPLETION_KIND_ENUM:

View File

@ -578,32 +578,34 @@ void DependencyRemoveDialog::ok_pressed() {
}
}
bool project_settings_modified = false;
for (int i = 0; i < files_to_delete.size(); ++i) {
// If the file we are deleting for e.g. the main scene, default environment,
// or audio bus layout, we must clear its definition in Project Settings.
if (files_to_delete[i] == String(GLOBAL_GET("application/config/icon"))) {
ProjectSettings::get_singleton()->set("application/config/icon", "");
}
if (files_to_delete[i] == String(GLOBAL_GET("application/run/main_scene"))) {
project_settings_modified = true;
} else if (files_to_delete[i] == String(GLOBAL_GET("application/run/main_scene"))) {
ProjectSettings::get_singleton()->set("application/run/main_scene", "");
}
if (files_to_delete[i] == String(GLOBAL_GET("application/boot_splash/image"))) {
project_settings_modified = true;
} else if (files_to_delete[i] == String(GLOBAL_GET("application/boot_splash/image"))) {
ProjectSettings::get_singleton()->set("application/boot_splash/image", "");
}
if (files_to_delete[i] == String(GLOBAL_GET("rendering/environment/defaults/default_environment"))) {
project_settings_modified = true;
} else if (files_to_delete[i] == String(GLOBAL_GET("rendering/environment/defaults/default_environment"))) {
ProjectSettings::get_singleton()->set("rendering/environment/defaults/default_environment", "");
}
if (files_to_delete[i] == String(GLOBAL_GET("display/mouse_cursor/custom_image"))) {
project_settings_modified = true;
} else if (files_to_delete[i] == String(GLOBAL_GET("display/mouse_cursor/custom_image"))) {
ProjectSettings::get_singleton()->set("display/mouse_cursor/custom_image", "");
}
if (files_to_delete[i] == String(GLOBAL_GET("gui/theme/custom"))) {
project_settings_modified = true;
} else if (files_to_delete[i] == String(GLOBAL_GET("gui/theme/custom"))) {
ProjectSettings::get_singleton()->set("gui/theme/custom", "");
}
if (files_to_delete[i] == String(GLOBAL_GET("gui/theme/custom_font"))) {
project_settings_modified = true;
} else if (files_to_delete[i] == String(GLOBAL_GET("gui/theme/custom_font"))) {
ProjectSettings::get_singleton()->set("gui/theme/custom_font", "");
}
if (files_to_delete[i] == String(GLOBAL_GET("audio/buses/default_bus_layout"))) {
project_settings_modified = true;
} else if (files_to_delete[i] == String(GLOBAL_GET("audio/buses/default_bus_layout"))) {
ProjectSettings::get_singleton()->set("audio/buses/default_bus_layout", "");
project_settings_modified = true;
}
String path = OS::get_singleton()->get_resource_dir() + files_to_delete[i].replace_first("res://", "/");
@ -615,6 +617,9 @@ void DependencyRemoveDialog::ok_pressed() {
emit_signal(SNAME("file_removed"), files_to_delete[i]);
}
}
if (project_settings_modified) {
ProjectSettings::get_singleton()->save();
}
if (dirs_to_delete.size() == 0) {
// If we only deleted files we should only need to tell the file system about the files we touched.

View File

@ -457,7 +457,9 @@ void EditorAutoloadSettings::init_autoloads() {
for (const AutoloadInfo &info : autoload_cache) {
if (info.node && info.in_editor) {
callable_mp((Node *)get_tree()->get_root(), &Node::add_child).call_deferred(info.node, false, Node::INTERNAL_MODE_DISABLED);
// It's important to add the node without deferring because code in plugins or tool scripts
// could use the autoload node when they are enabled.
get_tree()->get_root()->add_child(info.node);
}
}
}

View File

@ -386,6 +386,8 @@ void EditorFileSystem::_scan_filesystem() {
// On the first scan, the first_scan_root_dir is created in _first_scan_filesystem.
if (first_scan) {
sd = first_scan_root_dir;
// Will be updated on scan.
ResourceUID::get_singleton()->clear();
} else {
Ref<DirAccess> d = DirAccess::create(DirAccess::ACCESS_RESOURCES);
sd = memnew(ScannedDirectory);
@ -1779,7 +1781,9 @@ String EditorFileSystem::_get_global_script_class(const String &p_type, const St
void EditorFileSystem::_update_file_icon_path(EditorFileSystemDirectory::FileInfo *file_info) {
String icon_path;
if (file_info->script_class_icon_path.is_empty() && !file_info->deps.is_empty()) {
if (file_info->resource_script_class != StringName()) {
icon_path = EditorNode::get_editor_data().script_class_get_icon_path(file_info->resource_script_class);
} else if (file_info->script_class_icon_path.is_empty() && !file_info->deps.is_empty()) {
const String &script_dep = file_info->deps[0]; // Assuming the first dependency is a script.
const String &script_path = script_dep.contains("::") ? script_dep.get_slice("::", 2) : script_dep;
if (!script_path.is_empty()) {
@ -3059,7 +3063,6 @@ EditorFileSystem::EditorFileSystem() {
using_fat32_or_exfat = (da->get_filesystem_type() == "FAT32" || da->get_filesystem_type() == "exFAT");
scan_total = 0;
callable_mp(ResourceUID::get_singleton(), &ResourceUID::clear).call_deferred(); // Will be updated on scan.
ResourceSaver::set_get_resource_id_for_path(_resource_saver_get_resource_id_for_path);
}

View File

@ -174,6 +174,32 @@ static const String EDITOR_NODE_CONFIG_SECTION = "EditorNode";
static const String REMOVE_ANDROID_BUILD_TEMPLATE_MESSAGE = "The Android build template is already installed in this project and it won't be overwritten.\nRemove the \"%s\" directory manually before attempting this operation again.";
static const String INSTALL_ANDROID_BUILD_TEMPLATE_MESSAGE = "This will set up your project for gradle Android builds by installing the source template to \"%s\".\nNote that in order to make gradle builds instead of using pre-built APKs, the \"Use Gradle Build\" option should be enabled in the Android export preset.";
bool EditorProgress::step(const String &p_state, int p_step, bool p_force_refresh) {
if (Thread::is_main_thread()) {
return EditorNode::progress_task_step(task, p_state, p_step, p_force_refresh);
} else {
EditorNode::progress_task_step_bg(task, p_step);
return false;
}
}
EditorProgress::EditorProgress(const String &p_task, const String &p_label, int p_amount, bool p_can_cancel) {
if (Thread::is_main_thread()) {
EditorNode::progress_add_task(p_task, p_label, p_amount, p_can_cancel);
} else {
EditorNode::progress_add_task_bg(p_task, p_label, p_amount);
}
task = p_task;
}
EditorProgress::~EditorProgress() {
if (Thread::is_main_thread()) {
EditorNode::progress_end_task(task);
} else {
EditorNode::progress_end_task_bg(task);
}
}
void EditorNode::disambiguate_filenames(const Vector<String> p_full_paths, Vector<String> &r_filenames) {
ERR_FAIL_COND_MSG(p_full_paths.size() != r_filenames.size(), vformat("disambiguate_filenames requires two string vectors of same length (%d != %d).", p_full_paths.size(), r_filenames.size()));
@ -670,7 +696,10 @@ void EditorNode::_notification(int p_what) {
callable_mp(this, &EditorNode::_begin_first_scan).call_deferred();
DisplayServer::get_singleton()->set_system_theme_change_callback(callable_mp(this, &EditorNode::_update_theme).bind(false));
last_dark_mode_state = DisplayServer::get_singleton()->is_dark_mode();
last_system_accent_color = DisplayServer::get_singleton()->get_accent_color();
last_system_base_color = DisplayServer::get_singleton()->get_base_color();
DisplayServer::get_singleton()->set_system_theme_change_callback(callable_mp(this, &EditorNode::_check_system_theme_changed));
/* DO NOT LOAD SCENES HERE, WAIT FOR FILE SCANNING AND REIMPORT TO COMPLETE */
} break;
@ -1658,17 +1687,17 @@ void EditorNode::_find_node_types(Node *p_node, int &count_2d, int &count_3d) {
}
void EditorNode::_save_scene_with_preview(String p_file, int p_idx) {
EditorProgress save("save", TTR("Saving Scene"), 4);
save_scene_progress = memnew(EditorProgress("save", TTR("Saving Scene"), 4));
if (editor_data.get_edited_scene_root() != nullptr) {
save.step(TTR("Analyzing"), 0);
save_scene_progress->step(TTR("Analyzing"), 0);
int c2d = 0;
int c3d = 0;
_find_node_types(editor_data.get_edited_scene_root(), c2d, c3d);
save.step(TTR("Creating Thumbnail"), 1);
save_scene_progress->step(TTR("Creating Thumbnail"), 1);
// Current view?
Ref<Image> img;
@ -1696,8 +1725,7 @@ void EditorNode::_save_scene_with_preview(String p_file, int p_idx) {
if (img.is_valid() && img->get_width() > 0 && img->get_height() > 0) {
img = img->duplicate();
save.step(TTR("Creating Thumbnail"), 2);
save.step(TTR("Creating Thumbnail"), 3);
save_scene_progress->step(TTR("Creating Thumbnail"), 3);
int preview_size = EDITOR_GET("filesystem/file_dialog/thumbnail_size");
preview_size *= EDSCALE;
@ -1733,12 +1761,19 @@ void EditorNode::_save_scene_with_preview(String p_file, int p_idx) {
}
}
save.step(TTR("Saving Scene"), 4);
save_scene_progress->step(TTR("Saving Scene"), 4);
_save_scene(p_file, p_idx);
if (!singleton->cmdline_export_mode) {
EditorResourcePreview::get_singleton()->check_for_invalidation(p_file);
}
_close_save_scene_progress();
}
void EditorNode::_close_save_scene_progress() {
memdelete_notnull(save_scene_progress);
save_scene_progress = nullptr;
}
bool EditorNode::_validate_scene_recursive(const String &p_filename, Node *p_node) {
@ -5132,6 +5167,7 @@ bool EditorNode::is_project_exporting() const {
void EditorNode::show_accept(const String &p_text, const String &p_title) {
current_menu_option = -1;
if (accept) {
_close_save_scene_progress();
accept->set_ok_button_text(p_title);
accept->set_text(p_text);
EditorInterface::get_singleton()->popup_dialog_centered(accept);
@ -5141,6 +5177,7 @@ void EditorNode::show_accept(const String &p_text, const String &p_title) {
void EditorNode::show_save_accept(const String &p_text, const String &p_title) {
current_menu_option = -1;
if (save_accept) {
_close_save_scene_progress();
save_accept->set_ok_button_text(p_title);
save_accept->set_text(p_text);
EditorInterface::get_singleton()->popup_dialog_centered(save_accept);
@ -5149,6 +5186,7 @@ void EditorNode::show_save_accept(const String &p_text, const String &p_title) {
void EditorNode::show_warning(const String &p_text, const String &p_title) {
if (warning) {
_close_save_scene_progress();
warning->set_text(p_text);
warning->set_title(p_title);
EditorInterface::get_singleton()->popup_dialog_centered(warning);
@ -5296,14 +5334,18 @@ void EditorNode::_load_open_scenes_from_config(Ref<ConfigFile> p_layout) {
PackedStringArray scenes = p_layout->get_value(EDITOR_NODE_CONFIG_SECTION, "open_scenes");
for (int i = 0; i < scenes.size(); i++) {
load_scene(scenes[i]);
if (FileAccess::exists(scenes[i])) {
load_scene(scenes[i]);
}
}
if (p_layout->has_section_key(EDITOR_NODE_CONFIG_SECTION, "current_scene")) {
String current_scene = p_layout->get_value(EDITOR_NODE_CONFIG_SECTION, "current_scene");
int current_scene_idx = scenes.find(current_scene);
if (current_scene_idx >= 0) {
_set_current_scene(current_scene_idx);
for (int i = 0; i < editor_data.get_edited_scene_count(); i++) {
if (editor_data.get_scene_path(i) == current_scene) {
_set_current_scene(i);
break;
}
}
}
@ -6033,7 +6075,7 @@ void EditorNode::reload_instances_with_path_in_edited_scenes() {
base_packed_scene = current_packed_scene;
}
if (!local_scene_cache.find(path)) {
current_packed_scene = ResourceLoader::load(path, "", ResourceFormatLoader::CACHE_MODE_REPLACE_DEEP, &err);
current_packed_scene = ResourceLoader::load(path, "", ResourceFormatLoader::CACHE_MODE_REPLACE, &err);
local_scene_cache[path] = current_packed_scene;
} else {
current_packed_scene = local_scene_cache[path];

View File

@ -122,6 +122,14 @@ class SurfaceUpgradeTool;
class SurfaceUpgradeDialog;
class WindowWrapper;
struct EditorProgress {
String task;
bool step(const String &p_state, int p_step = -1, bool p_force_refresh = true);
EditorProgress(const String &p_task, const String &p_label, int p_amount, bool p_can_cancel = false);
~EditorProgress();
};
class EditorNode : public Node {
GDCLASS(EditorNode, Node);
@ -470,6 +478,7 @@ private:
String external_file;
String open_navigate;
String saving_scene;
EditorProgress *save_scene_progress = nullptr;
DynamicFontImportSettingsDialog *fontdata_import_settings = nullptr;
SceneImportSettingsDialog *scene_import_settings = nullptr;
@ -624,6 +633,7 @@ private:
void _find_node_types(Node *p_node, int &count_2d, int &count_3d);
void _save_scene_with_preview(String p_file, int p_idx = -1);
void _close_save_scene_progress();
bool _find_scene_in_use(Node *p_node, const String &p_path) const;
@ -952,33 +962,6 @@ public:
bool ensure_main_scene(bool p_from_native);
};
struct EditorProgress {
String task;
bool step(const String &p_state, int p_step = -1, bool p_force_refresh = true) {
if (Thread::is_main_thread()) {
return EditorNode::progress_task_step(task, p_state, p_step, p_force_refresh);
} else {
EditorNode::progress_task_step_bg(task, p_step);
return false;
}
}
EditorProgress(const String &p_task, const String &p_label, int p_amount, bool p_can_cancel = false) {
if (Thread::is_main_thread()) {
EditorNode::progress_add_task(p_task, p_label, p_amount, p_can_cancel);
} else {
EditorNode::progress_add_task_bg(p_task, p_label, p_amount);
}
task = p_task;
}
~EditorProgress() {
if (Thread::is_main_thread()) {
EditorNode::progress_end_task(task);
} else {
EditorNode::progress_end_task_bg(task);
}
}
};
class EditorPluginList : public Object {
private:
Vector<EditorPlugin *> plugins_list;

View File

@ -2778,7 +2778,11 @@ void EditorPropertyNodePath::_update_menu() {
void EditorPropertyNodePath::_menu_option(int p_idx) {
switch (p_idx) {
case ACTION_CLEAR: {
emit_changed(get_edited_property(), NodePath());
if (editing_node) {
emit_changed(get_edited_property(), Variant());
} else {
emit_changed(get_edited_property(), NodePath());
}
update_property();
} break;

View File

@ -175,6 +175,13 @@ void EditorResourcePicker::_file_quick_selected() {
_file_selected(quick_open->get_selected());
}
void EditorResourcePicker::_resource_saved(Object *p_resource) {
if (edited_resource.is_valid() && p_resource == edited_resource.ptr()) {
emit_signal(SNAME("resource_changed"), edited_resource);
_update_resource();
}
}
void EditorResourcePicker::_update_menu() {
_update_menu_items();
@ -408,6 +415,10 @@ void EditorResourcePicker::_edit_menu_cbk(int p_which) {
if (edited_resource.is_null()) {
return;
}
Callable resource_saved = callable_mp(this, &EditorResourcePicker::_resource_saved);
if (!EditorNode::get_singleton()->is_connected("resource_saved", resource_saved)) {
EditorNode::get_singleton()->connect("resource_saved", resource_saved);
}
EditorNode::get_singleton()->save_resource_as(edited_resource);
} break;
@ -833,6 +844,13 @@ void EditorResourcePicker::_notification(int p_what) {
assign_button->queue_redraw();
}
} break;
case NOTIFICATION_EXIT_TREE: {
Callable resource_saved = callable_mp(this, &EditorResourcePicker::_resource_saved);
if (EditorNode::get_singleton()->is_connected("resource_saved", resource_saved)) {
EditorNode::get_singleton()->disconnect("resource_saved", resource_saved);
}
} break;
}
}

View File

@ -91,6 +91,8 @@ class EditorResourcePicker : public HBoxContainer {
void _file_quick_selected();
void _file_selected(const String &p_path);
void _resource_saved(Object *p_resource);
void _update_menu();
void _update_menu_items();
void _edit_menu_cbk(int p_which);

View File

@ -685,7 +685,15 @@ void FileSystemDock::_tree_multi_selected(Object *p_item, int p_column, bool p_s
}
Vector<String> FileSystemDock::get_selected_paths() const {
return _tree_get_selected(false);
if (display_mode == DISPLAY_MODE_TREE_ONLY) {
return _tree_get_selected(false);
} else {
Vector<String> selected = _file_list_get_selected();
if (selected.is_empty()) {
selected.push_back(get_current_directory());
}
return selected;
}
}
String FileSystemDock::get_current_path() const {
@ -953,7 +961,8 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) {
files->set_max_columns(1);
files->set_max_text_lines(1);
files->set_fixed_column_width(0);
files->set_fixed_icon_size(Size2());
const int icon_size = get_theme_constant(SNAME("class_icon_size"), EditorStringName(Editor));
files->set_fixed_icon_size(Size2(icon_size, icon_size));
}
Ref<Texture2D> folder_icon = (use_thumbnails) ? folder_thumbnail : get_theme_icon(SNAME("folder"), SNAME("FileDialog"));
@ -2049,6 +2058,15 @@ Vector<String> FileSystemDock::_tree_get_selected(bool remove_self_inclusion, bo
return selected_strings;
}
Vector<String> FileSystemDock::_file_list_get_selected() const {
Vector<String> selected;
for (int idx : files->get_selected_items()) {
selected.push_back(files->get_item_metadata(idx));
}
return selected;
}
Vector<String> FileSystemDock::_remove_self_included_paths(Vector<String> selected_strings) {
// Remove paths or files that are included into another.
if (selected_strings.size() > 1) {
@ -3392,6 +3410,11 @@ void FileSystemDock::_file_list_empty_clicked(const Vector2 &p_pos, MouseButton
current_path = current_path_line_edit->get_text();
// Favorites isn't a directory so don't show menu.
if (current_path == "Favorites") {
return;
}
file_list_popup->clear();
file_list_popup->reset_size();

View File

@ -359,6 +359,7 @@ private:
void _update_display_mode(bool p_force = false);
Vector<String> _tree_get_selected(bool remove_self_inclusion = true, bool p_include_unselected_cursor = false) const;
Vector<String> _file_list_get_selected() const;
bool _is_file_type_disabled_by_feature_profile(const StringName &p_class);

View File

@ -115,6 +115,8 @@ void EditorFileDialog::_native_dialog_cb(bool p_ok, const Vector<String> &p_file
file_name = ProjectSettings::get_singleton()->localize_path(file_name);
}
}
selected_options = p_selected_options;
String f = files[0];
if (mode == FILE_MODE_OPEN_FILES) {
emit_signal(SNAME("files_selected"), files);
@ -146,7 +148,6 @@ void EditorFileDialog::_native_dialog_cb(bool p_ok, const Vector<String> &p_file
}
file->set_text(f);
dir->set_text(f.get_base_dir());
selected_options = p_selected_options;
filter->select(p_filter);
}

View File

@ -614,13 +614,13 @@ void EditorSpinSlider::_value_focus_exited() {
// -> TAB was pressed
// -> modal_close was not called
// -> need to close/hide manually
if (value_input_closed_frame != Engine::get_singleton()->get_frames_drawn()) {
if (!is_visible_in_tree() || value_input_closed_frame != Engine::get_singleton()->get_frames_drawn()) {
// Hidden or something else took focus.
if (value_input_popup) {
value_input_popup->hide();
}
//tab was pressed
} else {
//enter, click, esc
// Enter or Esc was pressed.
grab_focus();
}
@ -664,6 +664,10 @@ bool EditorSpinSlider::is_grabbing() const {
}
void EditorSpinSlider::_focus_entered() {
if (is_read_only()) {
return;
}
_ensure_input_popup();
value_input->set_text(get_text_value());
value_input_popup->set_size(get_size());

View File

@ -490,10 +490,14 @@ void SceneTreeEditor::_update_node_tooltip(Node *p_node, TreeItem *p_item) {
String tooltip = p_node->get_name();
if (p_node == get_scene_node() && p_node->get_scene_inherited_state().is_valid()) {
p_item->add_button(0, get_editor_theme_icon(SNAME("InstanceOptions")), BUTTON_SUBSCENE, false, TTR("Open in Editor"));
if (p_item->get_button_by_id(0, BUTTON_SUBSCENE) == -1) {
p_item->add_button(0, get_editor_theme_icon(SNAME("InstanceOptions")), BUTTON_SUBSCENE, false, TTR("Open in Editor"));
}
tooltip += String("\n" + TTR("Inherits:") + " " + p_node->get_scene_inherited_state()->get_path());
} else if (p_node != get_scene_node() && !p_node->get_scene_file_path().is_empty() && can_open_instance) {
p_item->add_button(0, get_editor_theme_icon(SNAME("InstanceOptions")), BUTTON_SUBSCENE, false, TTR("Open in Editor"));
if (p_item->get_button_by_id(0, BUTTON_SUBSCENE) == -1) {
p_item->add_button(0, get_editor_theme_icon(SNAME("InstanceOptions")), BUTTON_SUBSCENE, false, TTR("Open in Editor"));
}
tooltip += String("\n" + TTR("Instance:") + " " + p_node->get_scene_file_path());
}
@ -1000,6 +1004,7 @@ void SceneTreeEditor::set_selected(Node *p_node, bool p_emit_selected) {
TreeItem *item = p_node ? _find(tree->get_root(), p_node->get_path()) : nullptr;
if (item) {
selected = p_node;
if (auto_expand_selected) {
// Make visible when it's collapsed.
TreeItem *node = item->get_parent();
@ -1009,8 +1014,24 @@ void SceneTreeEditor::set_selected(Node *p_node, bool p_emit_selected) {
}
item->select(0);
item->set_as_cursor(0);
selected = p_node;
tree->ensure_cursor_is_visible();
} else {
// Ensure the node is selected and visible for the user if the node
// is not collapsed.
bool collapsed = false;
TreeItem *node = item;
while (node && node != tree->get_root()) {
if (node->is_collapsed()) {
collapsed = true;
break;
}
node = node->get_parent();
}
if (!collapsed) {
item->select(0);
item->set_as_cursor(0);
tree->ensure_cursor_is_visible();
}
}
} else {
if (!p_node) {

View File

@ -293,18 +293,20 @@ Error ResourceImporterImageFont::import(const String &p_source_file, const Strin
}
String from_tokens;
for (int i = 0; i < kp_tokens[0].length(); i++) {
if (i <= kp_tokens[0].length() - 6 && kp_tokens[0][i] == '\\' && kp_tokens[0][i + 1] == 'u') {
if (i <= kp_tokens[0].length() - 6 && kp_tokens[0][i] == '\\' && kp_tokens[0][i + 1] == 'u' && is_hex_digit(kp_tokens[0][i + 2]) && is_hex_digit(kp_tokens[0][i + 3]) && is_hex_digit(kp_tokens[0][i + 4]) && is_hex_digit(kp_tokens[0][i + 5])) {
char32_t charcode = kp_tokens[0].substr(i + 2, 4).hex_to_int();
from_tokens += charcode;
i += 5;
} else {
from_tokens += kp_tokens[0][i];
}
}
String to_tokens;
for (int i = 0; i < kp_tokens[1].length(); i++) {
if (i <= kp_tokens[1].length() - 6 && kp_tokens[1][i] == '\\' && kp_tokens[1][i + 1] == 'u') {
if (i <= kp_tokens[1].length() - 6 && kp_tokens[1][i] == '\\' && kp_tokens[1][i + 1] == 'u' && is_hex_digit(kp_tokens[1][i + 2]) && is_hex_digit(kp_tokens[1][i + 3]) && is_hex_digit(kp_tokens[1][i + 4]) && is_hex_digit(kp_tokens[1][i + 5])) {
char32_t charcode = kp_tokens[1].substr(i + 2, 4).hex_to_int();
to_tokens += charcode;
i += 5;
} else {
to_tokens += kp_tokens[1][i];
}

View File

@ -428,10 +428,10 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s
loop_end = p_options["edit/loop_end"];
// Wrap around to max frames, so `-1` can be used to select the end, etc.
if (loop_begin < 0) {
loop_begin = CLAMP(loop_begin + frames + 1, 0, frames);
loop_begin = CLAMP(loop_begin + frames, 0, frames - 1);
}
if (loop_end < 0) {
loop_end = CLAMP(loop_end + frames + 1, 0, frames);
loop_end = CLAMP(loop_end + frames, 0, frames - 1);
}
}
@ -517,16 +517,19 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s
Vector<uint8_t> dst_data;
if (compression == 2) {
dst_format = AudioStreamWAV::FORMAT_QOA;
qoa_desc desc = { 0, 0, 0, { { { 0 }, { 0 } } } };
qoa_desc desc = {};
uint32_t qoa_len = 0;
desc.samplerate = rate;
desc.samples = frames;
desc.channels = format_channels;
void *encoded = qoa_encode((short *)pcm_data.ptrw(), &desc, &qoa_len);
dst_data.resize(qoa_len);
memcpy(dst_data.ptrw(), encoded, qoa_len);
void *encoded = qoa_encode((short *)pcm_data.ptr(), &desc, &qoa_len);
if (encoded) {
dst_data.resize(qoa_len);
memcpy(dst_data.ptrw(), encoded, qoa_len);
QOA_FREE(encoded);
}
} else {
dst_data = pcm_data;
}

View File

@ -751,7 +751,9 @@ AbstractPolygon2DEditor::AbstractPolygon2DEditor(bool p_wip_destructive) {
}
void AbstractPolygon2DEditorPlugin::edit(Object *p_object) {
polygon_editor->edit(Object::cast_to<Node>(p_object));
Node *polygon_node = Object::cast_to<Node>(p_object);
polygon_editor->edit(polygon_node);
make_visible(polygon_node != nullptr);
}
bool AbstractPolygon2DEditorPlugin::handles(Object *p_object) const {

View File

@ -561,7 +561,9 @@ void AnimationLibraryEditor::_button_pressed(TreeItem *p_item, int p_column, int
return;
}
anim = anim->duplicate(); // Users simply dont care about referencing, so making a copy works better here.
if (!anim->get_path().is_resource_file()) {
anim = anim->duplicate(); // Users simply dont care about referencing, so making a copy works better here.
}
String base_name;
if (anim->get_name() != "") {

View File

@ -339,7 +339,17 @@ void AnimationPlayerEditor::_animation_selected(int p_which) {
track_editor->set_animation(anim, animation_is_readonly);
Node *root = player->get_node_or_null(player->get_root_node());
if (root) {
// Player shouldn't access parent if it's the scene root.
if (!root || (player == get_tree()->get_edited_scene_root() && player->get_root_node() == SceneStringName(path_pp))) {
NodePath cached_root_path = player->get_path_to(get_cached_root_node());
if (player->get_node_or_null(cached_root_path) != nullptr) {
player->set_root_node(cached_root_path);
} else {
player->set_root_node(SceneStringName(path_pp)); // No other choice, preventing crash.
}
} else {
cached_root_node_id = root->get_instance_id(); // Caching as `track_editor` can lose track of player's root node.
track_editor->set_root(root);
}
}
@ -1824,6 +1834,10 @@ AnimationMixer *AnimationPlayerEditor::fetch_mixer_for_library() const {
return original_node;
}
Node *AnimationPlayerEditor::get_cached_root_node() const {
return Object::cast_to<Node>(ObjectDB::get_instance(cached_root_node_id));
}
bool AnimationPlayerEditor::_validate_tracks(const Ref<Animation> p_anim) {
bool is_valid = true;
if (!p_anim.is_valid()) {

View File

@ -52,6 +52,7 @@ class AnimationPlayerEditor : public VBoxContainer {
AnimationPlayerEditorPlugin *plugin = nullptr;
AnimationMixer *original_node = nullptr; // For pinned mark in SceneTree.
AnimationPlayer *player = nullptr; // For AnimationPlayerEditor, could be dummy.
ObjectID cached_root_node_id;
bool is_dummy = false;
enum {
@ -251,6 +252,7 @@ public:
AnimationMixer *get_editing_node() const;
AnimationPlayer *get_player() const;
AnimationMixer *fetch_mixer_for_library() const;
Node *get_cached_root_node() const;
static AnimationPlayerEditor *get_singleton() { return singleton; }

View File

@ -3999,6 +3999,8 @@ void CanvasItemEditor::_project_settings_changed() {
void CanvasItemEditor::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_READY: {
_update_lock_and_group_button();
EditorRunBar::get_singleton()->connect("play_pressed", callable_mp(this, &CanvasItemEditor::_update_override_camera_button).bind(true));
EditorRunBar::get_singleton()->connect("stop_pressed", callable_mp(this, &CanvasItemEditor::_update_override_camera_button).bind(false));
ProjectSettings::get_singleton()->connect("settings_changed", callable_mp(this, &CanvasItemEditor::_project_settings_changed));
@ -4108,7 +4110,8 @@ void CanvasItemEditor::_notification(int p_what) {
}
} break;
case NOTIFICATION_APPLICATION_FOCUS_OUT: {
case NOTIFICATION_APPLICATION_FOCUS_OUT:
case NOTIFICATION_WM_WINDOW_FOCUS_OUT: {
if (drag_type != DRAG_NONE) {
_reset_drag();
viewport->queue_redraw();

View File

@ -81,6 +81,8 @@ void EditorNode3DGizmo::redraw() {
gizmo_plugin->redraw(this);
}
_update_bvh();
if (Node3DEditor::get_singleton()->is_current_selected_gizmo(this)) {
Node3DEditor::get_singleton()->update_transform_gizmo();
}
@ -244,6 +246,32 @@ void EditorNode3DGizmo::add_mesh(const Ref<Mesh> &p_mesh, const Ref<Material> &p
instances.push_back(ins);
}
void EditorNode3DGizmo::_update_bvh() {
ERR_FAIL_NULL(spatial_node);
Transform3D transform = spatial_node->get_global_transform();
float effective_icon_size = selectable_icon_size > 0.0f ? selectable_icon_size : 0.0f;
Vector3 icon_size_vector3 = Vector3(effective_icon_size, effective_icon_size, effective_icon_size);
AABB aabb(spatial_node->get_position() - icon_size_vector3 * 100.0f, icon_size_vector3 * 200.0f);
for (const Vector3 &segment_end : collision_segments) {
aabb.expand_to(transform.xform(segment_end));
}
if (collision_mesh.is_valid()) {
for (const Face3 &face : collision_mesh->get_faces()) {
aabb.expand_to(transform.xform(face.vertex[0]));
aabb.expand_to(transform.xform(face.vertex[1]));
aabb.expand_to(transform.xform(face.vertex[2]));
}
}
Node3DEditor::get_singleton()->update_gizmo_bvh_node(
bvh_node_id,
aabb);
}
void EditorNode3DGizmo::add_lines(const Vector<Vector3> &p_lines, const Ref<Material> &p_material, bool p_billboard, const Color &p_modulate) {
add_vertices(p_lines, p_material, Mesh::PRIMITIVE_LINES, p_billboard, p_modulate);
}
@ -403,12 +431,13 @@ void EditorNode3DGizmo::add_handles(const Vector<Vector3> &p_handles, const Ref<
colors.resize(p_handles.size());
Color *w = colors.ptrw();
for (int i = 0; i < p_handles.size(); i++) {
int id = p_ids.is_empty() ? i : p_ids[i];
Color col(1, 1, 1, 1);
if (is_handle_highlighted(i, p_secondary)) {
if (is_handle_highlighted(id, p_secondary)) {
col = Color(0, 0, 1, 0.9);
}
int id = p_ids.is_empty() ? i : p_ids[i];
if (!is_current_hover_gizmo || current_hover_handle != id || p_secondary != current_hover_handle_secondary) {
col.a = 0.8;
}
@ -765,6 +794,10 @@ void EditorNode3DGizmo::create() {
instances.write[i].create_instance(spatial_node, hidden);
}
bvh_node_id = Node3DEditor::get_singleton()->insert_gizmo_bvh_node(
spatial_node,
AABB(spatial_node->get_position(), Vector3(0, 0, 0)));
transform();
}
@ -774,6 +807,8 @@ void EditorNode3DGizmo::transform() {
for (int i = 0; i < instances.size(); i++) {
RS::get_singleton()->instance_set_transform(instances[i].instance, spatial_node->get_global_transform() * instances[i].xform);
}
_update_bvh();
}
void EditorNode3DGizmo::free() {
@ -790,6 +825,9 @@ void EditorNode3DGizmo::free() {
clear();
Node3DEditor::get_singleton()->remove_gizmo_bvh_node(bvh_node_id);
bvh_node_id = DynamicBVH::ID();
valid = false;
}

View File

@ -31,6 +31,7 @@
#ifndef NODE_3D_EDITOR_GIZMOS_H
#define NODE_3D_EDITOR_GIZMOS_H
#include "core/math/dynamic_bvh.h"
#include "core/templates/hash_map.h"
#include "core/templates/local_vector.h"
#include "scene/3d/camera_3d.h"
@ -72,8 +73,12 @@ class EditorNode3DGizmo : public Node3DGizmo {
Vector<Instance> instances;
Node3D *spatial_node = nullptr;
DynamicBVH::ID bvh_node_id;
void _set_node_3d(Node *p_node) { set_node_3d(Object::cast_to<Node3D>(p_node)); }
void _update_bvh();
protected:
static void _bind_methods();

View File

@ -770,7 +770,7 @@ void Node3DEditorViewport::_select_clicked(bool p_allow_locked) {
}
}
if (p_allow_locked || !_is_node_locked(selected)) {
if (p_allow_locked || (selected != nullptr && !_is_node_locked(selected))) {
if (clicked_wants_append) {
if (editor_selection->is_selected(selected)) {
editor_selection->remove_node(selected);
@ -800,7 +800,6 @@ ObjectID Node3DEditorViewport::_select_ray(const Point2 &p_pos) const {
RS::get_singleton()->sdfgi_set_debug_probe_select(pos, ray);
}
Vector<ObjectID> instances = RenderingServer::get_singleton()->instances_cull_ray(pos, pos + ray * camera->get_far(), get_tree()->get_root()->get_world_3d()->get_scenario());
HashSet<Ref<EditorNode3DGizmo>> found_gizmos;
Node *edited_scene = get_tree()->get_edited_scene_root();
@ -808,9 +807,9 @@ ObjectID Node3DEditorViewport::_select_ray(const Point2 &p_pos) const {
Node *item = nullptr;
float closest_dist = 1e20;
for (int i = 0; i < instances.size(); i++) {
Node3D *spat = Object::cast_to<Node3D>(ObjectDB::get_instance(instances[i]));
Vector<Node3D *> nodes_with_gizmos = Node3DEditor::get_singleton()->gizmo_bvh_ray_query(pos, pos + ray * camera->get_far());
for (Node3D *spat : nodes_with_gizmos) {
if (!spat) {
continue;
}
@ -863,12 +862,11 @@ void Node3DEditorViewport::_find_items_at_pos(const Point2 &p_pos, Vector<_RayRe
Vector3 ray = get_ray(p_pos);
Vector3 pos = get_ray_pos(p_pos);
Vector<ObjectID> instances = RenderingServer::get_singleton()->instances_cull_ray(pos, pos + ray * camera->get_far(), get_tree()->get_root()->get_world_3d()->get_scenario());
Vector<Node3D *> nodes_with_gizmos = Node3DEditor::get_singleton()->gizmo_bvh_ray_query(pos, pos + ray * camera->get_far());
HashSet<Node3D *> found_nodes;
for (int i = 0; i < instances.size(); i++) {
Node3D *spat = Object::cast_to<Node3D>(ObjectDB::get_instance(instances[i]));
for (Node3D *spat : nodes_with_gizmos) {
if (!spat) {
continue;
}
@ -1046,7 +1044,7 @@ void Node3DEditorViewport::_select_region() {
_clear_selected();
}
Vector<ObjectID> instances = RenderingServer::get_singleton()->instances_cull_convex(frustum, get_tree()->get_root()->get_world_3d()->get_scenario());
Vector<Node3D *> nodes_with_gizmos = Node3DEditor::get_singleton()->gizmo_bvh_frustum_query(frustum);
HashSet<Node3D *> found_nodes;
Vector<Node *> selected;
@ -1055,8 +1053,7 @@ void Node3DEditorViewport::_select_region() {
return;
}
for (int i = 0; i < instances.size(); i++) {
Node3D *sp = Object::cast_to<Node3D>(ObjectDB::get_instance(instances[i]));
for (Node3D *sp : nodes_with_gizmos) {
if (!sp || _is_node_locked(sp)) {
continue;
}
@ -1064,21 +1061,23 @@ void Node3DEditorViewport::_select_region() {
if (found_nodes.has(sp)) {
continue;
}
found_nodes.insert(sp);
Node *node = Object::cast_to<Node>(sp);
if (node != edited_scene) {
node = edited_scene->get_deepest_editable_node(node);
}
// Prevent selection of nodes not owned by the edited scene.
while (node && node != edited_scene->get_parent()) {
Node *node_owner = node->get_owner();
if (node_owner == edited_scene || node == edited_scene || (node_owner != nullptr && edited_scene->is_editable_instance(node_owner))) {
break;
// Selection requires that the node is the edited scene or its descendant, and has an owner.
if (node != edited_scene) {
if (!node->get_owner() || !edited_scene->is_ancestor_of(node)) {
continue;
}
node = edited_scene->get_deepest_editable_node(node);
while (node != edited_scene) {
Node *node_owner = node->get_owner();
if (node_owner == edited_scene || (node_owner != nullptr && edited_scene->is_editable_instance(node_owner))) {
break;
}
node = node->get_parent();
}
node = node->get_parent();
}
// Replace the node by the group if grouped
@ -1952,7 +1951,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
}
}
if (_edit.mode != TRANSFORM_NONE) {
if (!_edit.instant && _edit.mode != TRANSFORM_NONE) {
Node3D *selected = spatial_editor->get_single_selected_node();
Node3DEditorSelectedItem *se = selected ? editor_selection->get_node_editor_data<Node3DEditorSelectedItem>(selected) : nullptr;
@ -2252,6 +2251,11 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
}
if (_edit.mode == TRANSFORM_NONE) {
if (_edit.gizmo.is_null() && is_freelook_active() && k->get_keycode() == Key::ESCAPE) {
set_freelook_active(false);
return;
}
if (_edit.gizmo.is_valid() && (k->get_keycode() == Key::ESCAPE || k->get_keycode() == Key::BACKSPACE)) {
// Restore.
_edit.gizmo->commit_handle(_edit.gizmo_handle, _edit.gizmo_handle_secondary, _edit.gizmo_initial_value, true);
@ -2390,15 +2394,30 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
if (ED_IS_SHORTCUT("spatial_editor/cancel_transform", p_event) && _edit.mode != TRANSFORM_NONE) {
cancel_transform();
}
if (!is_freelook_active()) {
if (ED_IS_SHORTCUT("spatial_editor/instant_translate", p_event)) {
begin_transform(TRANSFORM_TRANSLATE, true);
if (!is_freelook_active() && !k->is_echo()) {
if (ED_IS_SHORTCUT("spatial_editor/instant_translate", p_event) && _edit.mode != TRANSFORM_TRANSLATE) {
if (_edit.mode == TRANSFORM_NONE) {
begin_transform(TRANSFORM_TRANSLATE, true);
} else if (_edit.instant) {
commit_transform();
begin_transform(TRANSFORM_TRANSLATE, true);
}
}
if (ED_IS_SHORTCUT("spatial_editor/instant_rotate", p_event)) {
begin_transform(TRANSFORM_ROTATE, true);
if (ED_IS_SHORTCUT("spatial_editor/instant_rotate", p_event) && _edit.mode != TRANSFORM_ROTATE) {
if (_edit.mode == TRANSFORM_NONE) {
begin_transform(TRANSFORM_ROTATE, true);
} else if (_edit.instant) {
commit_transform();
begin_transform(TRANSFORM_ROTATE, true);
}
}
if (ED_IS_SHORTCUT("spatial_editor/instant_scale", p_event)) {
begin_transform(TRANSFORM_SCALE, true);
if (ED_IS_SHORTCUT("spatial_editor/instant_scale", p_event) && _edit.mode != TRANSFORM_SCALE) {
if (_edit.mode == TRANSFORM_NONE) {
begin_transform(TRANSFORM_SCALE, true);
} else if (_edit.instant) {
commit_transform();
begin_transform(TRANSFORM_SCALE, true);
}
}
}
@ -3030,8 +3049,11 @@ void Node3DEditorViewport::_notification(int p_what) {
update_preview_node = false;
} break;
case NOTIFICATION_APPLICATION_FOCUS_OUT:
case NOTIFICATION_WM_WINDOW_FOCUS_OUT: {
set_freelook_active(false);
cursor.region_select = false;
surface->queue_redraw();
} break;
case NOTIFICATION_ENTER_TREE: {
@ -3107,6 +3129,7 @@ void Node3DEditorViewport::_notification(int p_what) {
case NOTIFICATION_DRAG_END: {
// Clear preview material when dropped outside applicable object.
if (spatial_editor->get_preview_material().is_valid() && !is_drag_successful()) {
_reset_preview_material();
_remove_preview_material();
} else {
_remove_preview_node();
@ -4001,6 +4024,14 @@ void Node3DEditorViewport::set_state(const Dictionary &p_state) {
_menu_option(VIEW_GIZMOS);
}
}
if (p_state.has("grid")) {
bool grid = p_state["grid"];
int idx = view_menu->get_popup()->get_item_index(VIEW_GRID);
if (view_menu->get_popup()->is_item_checked(idx) != grid) {
_menu_option(VIEW_GRID);
}
}
if (p_state.has("information")) {
bool information = p_state["information"];
@ -4079,6 +4110,7 @@ Dictionary Node3DEditorViewport::get_state() const {
d["listener"] = viewport->is_audio_listener_3d();
d["doppler"] = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_AUDIO_DOPPLER));
d["gizmos"] = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_GIZMOS));
d["grid"] = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_GRID));
d["information"] = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_INFORMATION));
d["frame_time"] = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_FRAME_TIME));
d["half_res"] = subviewport_container->get_stretch_shrink() > 1;
@ -5001,14 +5033,24 @@ void Node3DEditorViewport::update_transform(bool p_shift) {
} break;
case TRANSFORM_ROTATE: {
Plane plane = Plane(_get_camera_normal(), _edit.center);
Plane plane;
if (camera->get_projection() == Camera3D::PROJECTION_PERSPECTIVE) {
Vector3 cam_to_obj = _edit.center - _get_camera_position();
if (!cam_to_obj.is_zero_approx()) {
plane = Plane(cam_to_obj.normalized(), _edit.center);
} else {
plane = Plane(_get_camera_normal(), _edit.center);
}
} else {
plane = Plane(_get_camera_normal(), _edit.center);
}
Vector3 local_axis;
Vector3 global_axis;
switch (_edit.plane) {
case TRANSFORM_VIEW:
// local_axis unused
global_axis = _get_camera_normal();
global_axis = plane.normal;
break;
case TRANSFORM_X_AXIS:
local_axis = Vector3(1, 0, 0);
@ -5039,7 +5081,7 @@ void Node3DEditorViewport::update_transform(bool p_shift) {
break;
}
static const float orthogonal_threshold = Math::cos(Math::deg_to_rad(87.0f));
static const float orthogonal_threshold = Math::cos(Math::deg_to_rad(85.0f));
bool axis_is_orthogonal = ABS(plane.normal.dot(global_axis)) < orthogonal_threshold;
double angle = 0.0f;
@ -7746,6 +7788,9 @@ void Node3DEditor::_sun_environ_settings_pressed() {
sun_environ_popup->set_position(pos - Vector2(sun_environ_popup->get_contents_minimum_size().width / 2, 0));
sun_environ_popup->reset_size();
sun_environ_popup->popup();
// Grabbing the focus is required for Shift modifier checking to be functional
// (when the Add sun/environment buttons are pressed).
sun_environ_popup->grab_focus();
}
void Node3DEditor::_add_sun_to_scene(bool p_already_added_environment) {
@ -9208,6 +9253,49 @@ void Node3DEditor::remove_gizmo_plugin(Ref<EditorNode3DGizmoPlugin> p_plugin) {
_update_gizmos_menu();
}
DynamicBVH::ID Node3DEditor::insert_gizmo_bvh_node(Node3D *p_node, const AABB &p_aabb) {
return gizmo_bvh.insert(p_aabb, p_node);
}
void Node3DEditor::update_gizmo_bvh_node(DynamicBVH::ID p_id, const AABB &p_aabb) {
gizmo_bvh.update(p_id, p_aabb);
gizmo_bvh.optimize_incremental(1);
}
void Node3DEditor::remove_gizmo_bvh_node(DynamicBVH::ID p_id) {
gizmo_bvh.remove(p_id);
}
Vector<Node3D *> Node3DEditor::gizmo_bvh_ray_query(const Vector3 &p_ray_start, const Vector3 &p_ray_end) {
struct Result {
Vector<Node3D *> nodes;
bool operator()(void *p_data) {
nodes.append((Node3D *)p_data);
return false;
}
} result;
gizmo_bvh.ray_query(p_ray_start, p_ray_end, result);
return result.nodes;
}
Vector<Node3D *> Node3DEditor::gizmo_bvh_frustum_query(const Vector<Plane> &p_frustum) {
Vector<Vector3> points = Geometry3D::compute_convex_mesh_points(&p_frustum[0], p_frustum.size());
struct Result {
Vector<Node3D *> nodes;
bool operator()(void *p_data) {
nodes.append((Node3D *)p_data);
return false;
}
} result;
gizmo_bvh.convex_query(p_frustum.ptr(), p_frustum.size(), points.ptr(), points.size(), result);
return result.nodes;
}
Node3DEditorPlugin::Node3DEditorPlugin() {
spatial_editor = memnew(Node3DEditor);
spatial_editor->set_v_size_flags(Control::SIZE_EXPAND_FILL);

View File

@ -31,6 +31,7 @@
#ifndef NODE_3D_EDITOR_PLUGIN_H
#define NODE_3D_EDITOR_PLUGIN_H
#include "core/math/dynamic_bvh.h"
#include "editor/plugins/editor_plugin.h"
#include "editor/plugins/node_3d_editor_gizmos.h"
#include "editor/themes/editor_scale.h"
@ -629,6 +630,8 @@ private:
int current_hover_gizmo_handle;
bool current_hover_gizmo_handle_secondary;
DynamicBVH gizmo_bvh;
real_t snap_translate_value;
real_t snap_rotate_value;
real_t snap_scale_value;
@ -933,6 +936,12 @@ public:
void add_gizmo_plugin(Ref<EditorNode3DGizmoPlugin> p_plugin);
void remove_gizmo_plugin(Ref<EditorNode3DGizmoPlugin> p_plugin);
DynamicBVH::ID insert_gizmo_bvh_node(Node3D *p_node, const AABB &p_aabb);
void update_gizmo_bvh_node(DynamicBVH::ID p_id, const AABB &p_aabb);
void remove_gizmo_bvh_node(DynamicBVH::ID p_id);
Vector<Node3D *> gizmo_bvh_ray_query(const Vector3 &p_ray_start, const Vector3 &p_ray_end);
Vector<Node3D *> gizmo_bvh_frustum_query(const Vector<Plane> &p_frustum);
void edit(Node3D *p_spatial);
void clear();

View File

@ -83,9 +83,8 @@ Error PackedSceneEditorTranslationParserPlugin::parse_file(const String &p_path,
int idx_last = atr_owners.size() - 1;
if (idx_last > 0 && !parent_path.begins_with(atr_owners[idx_last].first)) {
// Switch to the previous auto translation owner this was nested in, if that was the case.
// Exit from the current owner nesting into the previous one.
atr_owners.remove_at(idx_last);
idx_last -= 1;
}
if (property == "auto_translate_mode") {
@ -106,7 +105,7 @@ Error PackedSceneEditorTranslationParserPlugin::parse_file(const String &p_path,
// If `auto_translate_mode` wasn't found, that means it is set to its default value (`AUTO_TRANSLATE_MODE_INHERIT`).
if (!auto_translate_mode_found) {
int idx_last = atr_owners.size() - 1;
if (idx_last > 0 && atr_owners[idx_last].first == parent_path) {
if (idx_last > 0 && parent_path.begins_with(atr_owners[idx_last].first)) {
auto_translating = atr_owners[idx_last].second;
} else {
atr_owners.push_back(Pair(state->get_node_path(i), true));

View File

@ -197,12 +197,7 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
const Vector2 new_point = xform.affine_inverse().xform(gpoint2);
curve->add_point(new_point, Vector2(0, 0), Vector2(0, 0), insertion_point + 1);
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
undo_redo->create_action(TTR("Split Curve"));
undo_redo->add_do_method(curve.ptr(), "add_point", new_point, Vector2(0, 0), Vector2(0, 0), insertion_point + 1);
undo_redo->add_undo_method(curve.ptr(), "remove_point", insertion_point + 1);
action = ACTION_MOVING_NEW_POINT;
action = ACTION_MOVING_NEW_POINT_FROM_SPLIT;
action_point = insertion_point + 1;
moving_from = curve->get_point_position(action_point);
moving_screen_from = gpoint2;
@ -245,6 +240,16 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
undo_redo->commit_action(false);
} break;
case ACTION_MOVING_NEW_POINT_FROM_SPLIT: {
undo_redo->create_action(TTR("Split Curve"));
undo_redo->add_do_method(curve.ptr(), "add_point", Vector2(), Vector2(), Vector2(), action_point);
undo_redo->add_do_method(curve.ptr(), "set_point_position", action_point, cpoint);
undo_redo->add_undo_method(curve.ptr(), "remove_point", action_point);
undo_redo->add_do_method(canvas_item_editor, "update_viewport");
undo_redo->add_undo_method(canvas_item_editor, "update_viewport");
undo_redo->commit_action(false);
} break;
case ACTION_MOVING_IN: {
if (original_mouse_pos != gpoint) {
undo_redo->create_action(TTR("Move In-Control in Curve"));
@ -350,7 +355,8 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
break;
case ACTION_MOVING_POINT:
case ACTION_MOVING_NEW_POINT: {
case ACTION_MOVING_NEW_POINT:
case ACTION_MOVING_NEW_POINT_FROM_SPLIT: {
curve->set_point_position(action_point, cpoint);
} break;
@ -573,6 +579,10 @@ void Path2DEditor::_cancel_current_action() {
curve->remove_point(curve->get_point_count() - 1);
} break;
case ACTION_MOVING_NEW_POINT_FROM_SPLIT: {
curve->remove_point(action_point);
} break;
case ACTION_MOVING_IN: {
curve->set_point_in(action_point, moving_from);
curve->set_point_out(action_point, mirror_handle_length ? -moving_from : (-moving_from.normalized() * orig_out_length));

View File

@ -81,6 +81,7 @@ class Path2DEditor : public HBoxContainer {
ACTION_NONE,
ACTION_MOVING_POINT,
ACTION_MOVING_NEW_POINT,
ACTION_MOVING_NEW_POINT_FROM_SPLIT,
ACTION_MOVING_IN,
ACTION_MOVING_OUT,
};

View File

@ -181,7 +181,7 @@ void Polygon2DEditor::_sync_bones() {
}
if (weights.size() == 0) { //create them
weights.resize(node->get_polygon().size());
weights.resize(wc);
float *w = weights.ptrw();
for (int j = 0; j < wc; j++) {
w[j] = 0.0;
@ -850,8 +850,8 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) {
if (mm.is_valid()) {
if (uv_drag) {
Vector2 uv_drag_to = mm->get_position();
uv_drag_to = snap_point(uv_drag_to); // FIXME: Only works correctly with 'UV_MODE_EDIT_POINT', it's imprecise with the rest.
Vector2 drag = mtx.affine_inverse().xform(uv_drag_to) - mtx.affine_inverse().xform(uv_drag_from);
uv_drag_to = snap_point(uv_drag_to);
Vector2 drag = mtx.affine_inverse().basis_xform(uv_drag_to - uv_drag_from);
switch (uv_move_current) {
case UV_MODE_CREATE: {
@ -1166,12 +1166,8 @@ void Polygon2DEditor::_uv_draw() {
poly_line_color.a *= 0.25;
}
Color polygon_line_color = Color(0.5, 0.5, 0.9);
Vector<Color> polygon_fill_color;
{
Color pf = polygon_line_color;
pf.a *= 0.5;
polygon_fill_color.push_back(pf);
}
Color polygon_fill_color = polygon_line_color;
polygon_fill_color.a *= 0.5;
Color prev_color = Color(0.5, 0.5, 0.5);
int uv_draw_max = uvs.size();
@ -1216,7 +1212,7 @@ void Polygon2DEditor::_uv_draw() {
uv_edit_draw->draw_line(mtx.xform(uvs[idx]), mtx.xform(uvs[idx_next]), polygon_line_color, Math::round(EDSCALE));
}
if (points.size() >= 3) {
uv_edit_draw->draw_polygon(polypoints, polygon_fill_color);
uv_edit_draw->draw_colored_polygon(polypoints, polygon_fill_color);
}
}
@ -1309,8 +1305,8 @@ void Polygon2DEditor::_bind_methods() {
Vector2 Polygon2DEditor::snap_point(Vector2 p_target) const {
if (use_snap) {
p_target.x = Math::snap_scalar(snap_offset.x * uv_draw_zoom - uv_draw_ofs.x, snap_step.x * uv_draw_zoom, p_target.x);
p_target.y = Math::snap_scalar(snap_offset.y * uv_draw_zoom - uv_draw_ofs.y, snap_step.y * uv_draw_zoom, p_target.y);
p_target.x = Math::snap_scalar((snap_offset.x - uv_draw_ofs.x) * uv_draw_zoom, snap_step.x * uv_draw_zoom, p_target.x);
p_target.y = Math::snap_scalar((snap_offset.y - uv_draw_ofs.y) * uv_draw_zoom, snap_step.y * uv_draw_zoom, p_target.y);
}
return p_target;
@ -1486,7 +1482,7 @@ Polygon2DEditor::Polygon2DEditor() {
grid_settings = memnew(AcceptDialog);
grid_settings->set_title(TTR("Configure Grid:"));
add_child(grid_settings);
uv_edit->add_child(grid_settings);
VBoxContainer *grid_settings_vb = memnew(VBoxContainer);
grid_settings->add_child(grid_settings_vb);

View File

@ -2711,9 +2711,11 @@ void ScriptEditor::apply_scripts() const {
}
void ScriptEditor::reload_scripts(bool p_refresh_only) {
if (external_editor_active) {
return;
}
// Call deferred to make sure it runs on the main thread.
callable_mp(this, &ScriptEditor::_reload_scripts).call_deferred(p_refresh_only);
}
void ScriptEditor::_reload_scripts(bool p_refresh_only) {
for (int i = 0; i < tab_container->get_tab_count(); i++) {
ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_tab_control(i));
if (!se) {

View File

@ -436,6 +436,7 @@ class ScriptEditor : public PanelContainer {
void _file_removed(const String &p_file);
void _autosave_scripts();
void _update_autosave_timer();
void _reload_scripts(bool p_refresh_only = false);
void _update_members_overview_visibility();
void _update_members_overview();

View File

@ -372,7 +372,7 @@ void TileAtlasView::_draw_base_tiles_shape_grid() {
for (int i = 0; i < tile_set_atlas_source->get_tiles_count(); i++) {
Vector2i tile_id = tile_set_atlas_source->get_tile_id(i);
Vector2 in_tile_base_offset = tile_set_atlas_source->get_tile_data(tile_id, 0)->get_texture_origin();
if (tile_set_atlas_source->is_position_in_tile_texture_region(tile_id, 0, -tile_shape_size / 2) && tile_set_atlas_source->is_position_in_tile_texture_region(tile_id, 0, tile_shape_size / 2 - Vector2(1, 1))) {
if (tile_set_atlas_source->is_rect_in_tile_texture_region(tile_id, 0, Rect2(Vector2(-tile_shape_size) / 2, tile_shape_size))) {
for (int frame = 0; frame < tile_set_atlas_source->get_tile_animation_frames_count(tile_id); frame++) {
Color color = grid_color;
if (frame > 0) {

View File

@ -165,10 +165,14 @@ void GenericTilePolygonEditor::_base_control_draw() {
base_control->draw_set_transform_matrix(xform);
// Draw fill rect under texture region.
Rect2 texture_rect(-background_region.size / 2, background_region.size);
Rect2 texture_rect(Vector2(), background_region.size);
if (tile_data) {
texture_rect.position -= tile_data->get_texture_origin();
if (tile_data->get_transpose()) {
texture_rect.size = Size2(texture_rect.size.y, texture_rect.size.x);
}
}
texture_rect.position -= texture_rect.size / 2; // Half-size offset must be applied after transposing.
base_control->draw_rect(texture_rect, Color(1, 1, 1, 0.3));
// Draw the background.
@ -180,18 +184,14 @@ void GenericTilePolygonEditor::_base_control_draw() {
if (tile_data->get_flip_v()) {
region_size.y = -region_size.y;
}
base_control->draw_texture_rect_region(background_atlas_source->get_texture(), Rect2(-background_region.size / 2 - tile_data->get_texture_origin(), region_size), background_region, tile_data->get_modulate(), tile_data->get_transpose());
// Destination rect position must account for transposing, size must not.
base_control->draw_texture_rect_region(background_atlas_source->get_texture(), Rect2(texture_rect.position, region_size), background_region, tile_data->get_modulate(), tile_data->get_transpose());
}
// Compute and draw the grid area.
Rect2 grid_area = Rect2(-base_tile_size / 2, base_tile_size);
if (tile_data) {
grid_area.expand_to(-background_region.get_size() / 2 - tile_data->get_texture_origin());
grid_area.expand_to(background_region.get_size() / 2 - tile_data->get_texture_origin());
} else {
grid_area.expand_to(-background_region.get_size() / 2);
grid_area.expand_to(background_region.get_size() / 2);
}
grid_area.expand_to(texture_rect.position);
grid_area.expand_to(texture_rect.get_end());
base_control->draw_rect(grid_area, Color(1, 1, 1, 0.3), false);
// Draw grid.
@ -1385,10 +1385,8 @@ void TileDataTextureOriginEditor::draw_over_tile(CanvasItem *p_canvas_item, Tran
TileSetSource *source = *(tile_set->get_source(p_cell.source_id));
TileSetAtlasSource *atlas_source = Object::cast_to<TileSetAtlasSource>(source);
if (atlas_source->is_position_in_tile_texture_region(p_cell.get_atlas_coords(), p_cell.alternative_tile, -tile_set_tile_size / 2) && atlas_source->is_position_in_tile_texture_region(p_cell.get_atlas_coords(), p_cell.alternative_tile, tile_set_tile_size / 2 - Vector2(1, 1))) {
Transform2D tile_xform;
tile_xform.set_scale(tile_set_tile_size);
tile_set->draw_tile_shape(p_canvas_item, p_transform * tile_xform, color);
if (atlas_source->is_rect_in_tile_texture_region(p_cell.get_atlas_coords(), p_cell.alternative_tile, Rect2(Vector2(-tile_set_tile_size) / 2, tile_set_tile_size))) {
tile_set->draw_tile_shape(p_canvas_item, p_transform.scaled_local(tile_set_tile_size), color);
}
if (atlas_source->is_position_in_tile_texture_region(p_cell.get_atlas_coords(), p_cell.alternative_tile, Vector2())) {

View File

@ -1366,11 +1366,13 @@ void TileMapLayerEditorTilesPlugin::_stop_dragging() {
Vector2i coords;
HashMap<Vector2i, TileMapCell> cells_undo;
for (int i = 0; i < selection_used_cells.size(); i++) {
coords = tile_set->map_pattern(top_left, selection_used_cells[i], selection_pattern);
cells_undo[coords] = TileMapCell(drag_modified[coords].source_id, drag_modified[coords].get_atlas_coords(), drag_modified[coords].alternative_tile);
coords = tile_set->map_pattern(top_left + offset, selection_used_cells[i], selection_pattern);
cells_undo[coords] = TileMapCell(edited_layer->get_cell_source_id(coords), edited_layer->get_cell_atlas_coords(coords), edited_layer->get_cell_alternative_tile(coords));
}
for (int i = 0; i < selection_used_cells.size(); i++) {
coords = tile_set->map_pattern(top_left, selection_used_cells[i], selection_pattern);
cells_undo[coords] = TileMapCell(drag_modified[coords].source_id, drag_modified[coords].get_atlas_coords(), drag_modified[coords].alternative_tile);
}
// Build the list of cells to do.
HashMap<Vector2i, TileMapCell> cells_do;

View File

@ -115,8 +115,8 @@ void VSGraphNode::_draw_port(int p_slot_index, Point2i p_pos, bool p_left, const
icon_offset = -port_icon->get_size() * 0.5;
// Draw "shadow"/outline in the connection rim color.
draw_texture_rect(port_icon, Rect2(p_pos + icon_offset - Size2(2, 2), port_icon->get_size() + Size2(4, 4)), false, p_rim_color);
draw_texture(port_icon, p_pos + icon_offset, p_color);
draw_texture_rect(port_icon, Rect2(p_pos + (icon_offset - Size2(2, 2)) * EDSCALE, (port_icon->get_size() + Size2(4, 4)) * EDSCALE), false, p_rim_color);
draw_texture_rect(port_icon, Rect2(p_pos + icon_offset * EDSCALE, port_icon->get_size() * EDSCALE), false, p_color);
}
void VSGraphNode::draw_port(int p_slot_index, Point2i p_pos, bool p_left, const Color &p_color) {
@ -154,7 +154,6 @@ VSRerouteNode::VSRerouteNode() {
title_lbl->hide();
const Size2 size = Size2(32, 32) * EDSCALE;
print_line("VSRerouteNode size: " + size);
Control *slot_area = memnew(Control);
slot_area->set_custom_minimum_size(size);
@ -2888,8 +2887,8 @@ void VisualShaderEditor::_frame_title_popup_show(const Point2 &p_position, int p
}
frame_title_change_edit->set_text(node->get_title());
frame_title_change_popup->set_meta("id", p_node_id);
frame_title_change_popup->popup();
frame_title_change_popup->set_position(p_position);
frame_title_change_popup->popup();
// Select current text.
frame_title_change_edit->grab_focus();

View File

@ -162,7 +162,7 @@ void ProjectDialog::_validate_path() {
}
}
if (target_path.is_empty() || target_path.is_relative_path()) {
if (target_path.is_relative_path()) {
_set_message(TTR("The path specified is invalid."), MESSAGE_ERROR, target_path_input_type);
return;
}
@ -352,7 +352,7 @@ void ProjectDialog::_install_path_changed() {
void ProjectDialog::_browse_project_path() {
String path = project_path->get_text();
if (path.is_empty()) {
if (path.is_relative_path()) {
path = EDITOR_GET("filesystem/directories/default_project_path");
}
if (mode == MODE_IMPORT && install_path->is_visible_in_tree()) {
@ -382,12 +382,16 @@ void ProjectDialog::_browse_project_path() {
void ProjectDialog::_browse_install_path() {
ERR_FAIL_COND_MSG(mode != MODE_IMPORT, "Install path is only used for MODE_IMPORT.");
String path = install_path->get_text();
if (path.is_relative_path() || !DirAccess::dir_exists_absolute(path)) {
path = EDITOR_GET("filesystem/directories/default_project_path");
}
if (create_dir->is_pressed()) {
// Select parent directory of install path.
fdialog_install->set_current_dir(install_path->get_text().get_base_dir());
fdialog_install->set_current_dir(path.get_base_dir());
} else {
// Select install path.
fdialog_install->set_current_dir(install_path->get_text());
fdialog_install->set_current_dir(path);
}
fdialog_install->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_DIR);

View File

@ -760,7 +760,7 @@ void ProjectList::_create_project_item_control(int p_index) {
hb->set_tags(item.tags, this);
hb->set_unsupported_features(item.unsupported_features.duplicate());
hb->set_project_version(item.project_version);
hb->set_last_edited_info(Time::get_singleton()->get_datetime_string_from_unix_time(item.last_edited, true));
hb->set_last_edited_info(!item.missing ? Time::get_singleton()->get_datetime_string_from_unix_time(item.last_edited, true) : TTR("Missing Date"));
hb->set_is_favorite(item.favorite);
hb->set_is_missing(item.missing);

View File

@ -1181,7 +1181,16 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
case TOOL_OPEN_DOCUMENTATION: {
List<Node *> selection = editor_selection->get_selected_node_list();
for (const Node *node : selection) {
ScriptEditor::get_singleton()->goto_help("class_name:" + node->get_class());
String class_name;
Ref<Script> script_base = node->get_script();
if (script_base.is_valid()) {
class_name = script_base->get_global_name();
}
if (class_name.is_empty()) {
class_name = node->get_class();
}
ScriptEditor::get_singleton()->goto_help("class_name:" + class_name);
}
EditorNode::get_singleton()->set_visible_editor(EditorNode::EDITOR_SCRIPT);
} break;
@ -2226,8 +2235,7 @@ void SceneTreeDock::_node_reparent(NodePath p_path, bool p_keep_global_xform) {
}
void SceneTreeDock::_do_reparent(Node *p_new_parent, int p_position_in_parent, Vector<Node *> p_nodes, bool p_keep_global_xform) {
Node *new_parent = p_new_parent;
ERR_FAIL_NULL(new_parent);
ERR_FAIL_NULL(p_new_parent);
if (p_nodes.size() == 0) {
return; // Nothing to reparent.
@ -2267,7 +2275,7 @@ void SceneTreeDock::_do_reparent(Node *p_new_parent, int p_position_in_parent, V
// Prevent selecting the hovered node and keep the reparented node(s) selected instead.
hovered_but_reparenting = true;
Node *validate = new_parent;
Node *validate = p_new_parent;
while (validate) {
ERR_FAIL_COND_MSG(p_nodes.has(validate), "Selection changed at some point. Can't reparent.");
validate = validate->get_parent();
@ -2289,7 +2297,7 @@ void SceneTreeDock::_do_reparent(Node *p_new_parent, int p_position_in_parent, V
// No undo implemented for this yet.
Node *node = p_nodes[ni];
fill_path_renames(node, new_parent, &path_renames);
fill_path_renames(node, p_new_parent, &path_renames);
former_names.push_back(node->get_name());
List<Node *> owned;
@ -2299,7 +2307,7 @@ void SceneTreeDock::_do_reparent(Node *p_new_parent, int p_position_in_parent, V
owners.push_back(E);
}
bool same_parent = new_parent == node->get_parent();
bool same_parent = p_new_parent == node->get_parent();
if (same_parent && node->get_index(false) < p_position_in_parent + ni) {
inc--; // If the child will generate a gap when moved, adjust.
}
@ -2310,17 +2318,17 @@ void SceneTreeDock::_do_reparent(Node *p_new_parent, int p_position_in_parent, V
need_edit = select_node_hovered_at_end_of_drag;
} else {
undo_redo->add_do_method(node->get_parent(), "remove_child", node);
undo_redo->add_do_method(new_parent, "add_child", node, true);
undo_redo->add_do_method(p_new_parent, "add_child", node, true);
}
int new_position_in_parent = p_position_in_parent == -1 ? -1 : p_position_in_parent + inc;
if (new_position_in_parent >= 0 || same_parent) {
undo_redo->add_do_method(new_parent, "move_child", node, new_position_in_parent);
undo_redo->add_do_method(p_new_parent, "move_child", node, new_position_in_parent);
}
EditorDebuggerNode *ed = EditorDebuggerNode::get_singleton();
String old_name = former_names[ni];
String new_name = new_parent->validate_child_name(node);
String new_name = p_new_parent->validate_child_name(node);
// Name was modified, fix the path renames.
if (old_name.casecmp_to(new_name) != 0) {
@ -2345,8 +2353,12 @@ void SceneTreeDock::_do_reparent(Node *p_new_parent, int p_position_in_parent, V
}
}
undo_redo->add_do_method(ed, "live_debug_reparent_node", edited_scene->get_path_to(node), edited_scene->get_path_to(new_parent), new_name, new_position_in_parent);
undo_redo->add_undo_method(ed, "live_debug_reparent_node", NodePath(String(edited_scene->get_path_to(new_parent)).path_join(new_name)), edited_scene->get_path_to(node->get_parent()), node->get_name(), node->get_index(false));
// FIXME: Live editing for "Reparent to New Node" option is broken.
// We must get the path to `p_new_parent` *after* it was added to the scene.
if (p_new_parent->is_inside_tree()) {
undo_redo->add_do_method(ed, "live_debug_reparent_node", edited_scene->get_path_to(node), edited_scene->get_path_to(p_new_parent), new_name, new_position_in_parent);
undo_redo->add_undo_method(ed, "live_debug_reparent_node", NodePath(String(edited_scene->get_path_to(p_new_parent)).path_join(new_name)), edited_scene->get_path_to(node->get_parent()), node->get_name(), node->get_index(false));
}
if (p_keep_global_xform) {
if (Object::cast_to<Node2D>(node)) {
@ -2366,7 +2378,7 @@ void SceneTreeDock::_do_reparent(Node *p_new_parent, int p_position_in_parent, V
undo_redo->add_do_method(AnimationPlayerEditor::get_singleton()->get_track_editor(), "set_root", node);
}
undo_redo->add_undo_method(new_parent, "remove_child", node);
undo_redo->add_undo_method(p_new_parent, "remove_child", node);
undo_redo->add_undo_method(node, "set_name", former_names[ni]);
inc++;
@ -2384,7 +2396,7 @@ void SceneTreeDock::_do_reparent(Node *p_new_parent, int p_position_in_parent, V
}
int child_pos = node->get_index(false);
bool reparented_to_container = Object::cast_to<Container>(new_parent) && Object::cast_to<Control>(node);
bool reparented_to_container = Object::cast_to<Container>(p_new_parent) && Object::cast_to<Control>(node);
undo_redo->add_undo_method(node->get_parent(), "add_child", node, true);
undo_redo->add_undo_method(node->get_parent(), "move_child", node, child_pos);
@ -2641,6 +2653,13 @@ void SceneTreeDock::_delete_confirm(bool p_cut) {
}
}
if (!entire_scene) {
for (const Node *E : remove_list) {
// `move_child` + `get_index` doesn't really work for internal nodes.
ERR_FAIL_COND_MSG(E->get_internal_mode() != INTERNAL_MODE_DISABLED, "Trying to remove internal node, this is not supported.");
}
}
EditorNode::get_singleton()->hide_unused_editors(this);
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
@ -2653,10 +2672,6 @@ void SceneTreeDock::_delete_confirm(bool p_cut) {
undo_redo->add_undo_method(scene_tree, "update_tree");
undo_redo->add_undo_reference(edited_scene);
} else {
for (const Node *E : remove_list) {
// `move_child` + `get_index` doesn't really work for internal nodes.
ERR_FAIL_COND_MSG(E->get_internal_mode() != INTERNAL_MODE_DISABLED, "Trying to remove internal node, this is not supported.");
}
if (delete_tracks_checkbox->is_pressed() || p_cut) {
remove_list.sort_custom<Node::Comparator>(); // Sort nodes to keep positions.
HashMap<Node *, NodePath> path_renames;
@ -2761,10 +2776,10 @@ void SceneTreeDock::_selection_changed() {
_update_script_button();
}
void SceneTreeDock::_do_create(Node *p_parent) {
Node *SceneTreeDock::_do_create(Node *p_parent) {
Variant c = create_dialog->instantiate_selected();
Node *child = Object::cast_to<Node>(c);
ERR_FAIL_NULL(child);
ERR_FAIL_NULL_V(child, nullptr);
String new_name = p_parent->validate_child_name(child);
if (GLOBAL_GET("editor/naming/node_name_casing").operator int() != NAME_CASING_PASCAL_CASE) {
@ -2778,8 +2793,6 @@ void SceneTreeDock::_do_create(Node *p_parent) {
if (edited_scene) {
undo_redo->add_do_method(p_parent, "add_child", child, true);
undo_redo->add_do_method(child, "set_owner", edited_scene);
undo_redo->add_do_method(editor_selection, "clear");
undo_redo->add_do_method(editor_selection, "add_node", child);
undo_redo->add_do_reference(child);
undo_redo->add_undo_method(p_parent, "remove_child", child);
@ -2794,28 +2807,34 @@ void SceneTreeDock::_do_create(Node *p_parent) {
undo_redo->add_undo_method(EditorNode::get_singleton(), "set_edited_scene", (Object *)nullptr);
}
undo_redo->add_do_method(this, "_post_do_create", child);
undo_redo->commit_action();
_push_item(c);
editor_selection->clear();
editor_selection->add_node(child);
if (Object::cast_to<Control>(c)) {
//make editor more comfortable, so some controls don't appear super shrunk
Control *ct = Object::cast_to<Control>(c);
Size2 ms = ct->get_minimum_size();
return child;
}
void SceneTreeDock::_post_do_create(Node *p_child) {
editor_selection->clear();
editor_selection->add_node(p_child);
_push_item(p_child);
// Make editor more comfortable, so some controls don't appear super shrunk.
Control *control = Object::cast_to<Control>(p_child);
if (control) {
Size2 ms = control->get_minimum_size();
if (ms.width < 4) {
ms.width = 40;
}
if (ms.height < 4) {
ms.height = 40;
}
if (ct->is_layout_rtl()) {
ct->set_position(ct->get_position() - Vector2(ms.x, 0));
if (control->is_layout_rtl()) {
control->set_position(control->get_position() - Vector2(ms.x, 0));
}
ct->set_size(ms);
control->set_size(ms);
}
emit_signal(SNAME("node_created"), c);
emit_signal(SNAME("node_created"), p_child);
}
void SceneTreeDock::_create() {
@ -2898,22 +2917,24 @@ void SceneTreeDock::_create() {
}
Node *parent = nullptr;
int original_position = -1;
if (only_one_top_node) {
parent = top_node->get_parent();
original_position = top_node->get_index(false);
} else {
parent = top_node->get_parent()->get_parent();
}
_do_create(parent);
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
undo_redo->create_action_for_history(TTR("Reparent to New Node"), editor_data->get_current_edited_scene_history_id());
Node *last_created = _do_create(parent);
Vector<Node *> nodes;
for (Node *E : selection) {
nodes.push_back(E);
}
// This works because editor_selection was cleared and populated with last created node in _do_create()
Node *last_created = editor_selection->get_selected_node_list().front()->get();
if (center_parent) {
// Find parent type and only average positions of relevant nodes.
Node3D *parent_node_3d = Object::cast_to<Node3D>(last_created);
@ -2952,6 +2973,11 @@ void SceneTreeDock::_create() {
}
_do_reparent(last_created, -1, nodes, true);
if (only_one_top_node) {
undo_redo->add_do_method(parent, "move_child", last_created, original_position);
}
undo_redo->commit_action();
}
scene_tree->get_scene_tree()->grab_focus();
@ -4354,6 +4380,7 @@ void SceneTreeDock::_edit_subresource(int p_idx, const PopupMenu *p_from_menu) {
}
void SceneTreeDock::_bind_methods() {
ClassDB::bind_method(D_METHOD("_post_do_create"), &SceneTreeDock::_post_do_create);
ClassDB::bind_method(D_METHOD("_set_owners"), &SceneTreeDock::_set_owners);
ClassDB::bind_method(D_METHOD("_reparent_nodes_to_root"), &SceneTreeDock::_reparent_nodes_to_root);
ClassDB::bind_method(D_METHOD("_reparent_nodes_to_paths_with_transform_and_name"), &SceneTreeDock::_reparent_nodes_to_paths_with_transform_and_name);

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