summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/multiplayer/multiplayer_peer.cpp27
-rw-r--r--core/multiplayer/multiplayer_peer.h6
-rw-r--r--core/variant/variant_call.cpp2
-rw-r--r--doc/classes/BaseMaterial3D.xml8
-rw-r--r--doc/classes/MultiplayerPeerExtension.xml13
-rw-r--r--doc/classes/Plane.xml4
-rw-r--r--doc/classes/SceneTree.xml6
-rw-r--r--modules/gltf/gltf_document.cpp92
-rw-r--r--modules/gltf/gltf_state.h1
-rw-r--r--platform/uwp/os_uwp.cpp1
-rw-r--r--scene/animation/animation_node_state_machine.cpp2
11 files changed, 112 insertions, 50 deletions
diff --git a/core/multiplayer/multiplayer_peer.cpp b/core/multiplayer/multiplayer_peer.cpp
index b262903ce8..c7de7a1313 100644
--- a/core/multiplayer/multiplayer_peer.cpp
+++ b/core/multiplayer/multiplayer_peer.cpp
@@ -130,6 +130,20 @@ Error MultiplayerPeerExtension::get_packet(const uint8_t **r_buffer, int &r_buff
if (GDVIRTUAL_CALL(_get_packet, r_buffer, &r_buffer_size, err)) {
return (Error)err;
}
+ if (GDVIRTUAL_IS_OVERRIDDEN(_get_packet_script)) {
+ if (!GDVIRTUAL_CALL(_get_packet_script, script_buffer)) {
+ return FAILED;
+ }
+
+ if (script_buffer.size() == 0) {
+ return Error::ERR_UNAVAILABLE;
+ }
+
+ *r_buffer = script_buffer.ptr();
+ r_buffer_size = script_buffer.size();
+
+ return Error::OK;
+ }
WARN_PRINT_ONCE("MultiplayerPeerExtension::_get_packet_native is unimplemented!");
return FAILED;
}
@@ -139,6 +153,16 @@ Error MultiplayerPeerExtension::put_packet(const uint8_t *p_buffer, int p_buffer
if (GDVIRTUAL_CALL(_put_packet, p_buffer, p_buffer_size, err)) {
return (Error)err;
}
+ if (GDVIRTUAL_IS_OVERRIDDEN(_put_packet_script)) {
+ PackedByteArray a;
+ a.resize(p_buffer_size);
+ memcpy(a.ptrw(), p_buffer, p_buffer_size);
+
+ if (!GDVIRTUAL_CALL(_put_packet_script, a, err)) {
+ return FAILED;
+ }
+ return (Error)err;
+ }
WARN_PRINT_ONCE("MultiplayerPeerExtension::_put_packet_native is unimplemented!");
return FAILED;
}
@@ -254,6 +278,9 @@ void MultiplayerPeerExtension::_bind_methods() {
GDVIRTUAL_BIND(_get_available_packet_count);
GDVIRTUAL_BIND(_get_max_packet_size);
+ GDVIRTUAL_BIND(_get_packet_script)
+ GDVIRTUAL_BIND(_put_packet_script, "p_buffer");
+
GDVIRTUAL_BIND(_set_transfer_channel, "p_channel");
GDVIRTUAL_BIND(_get_transfer_channel);
diff --git a/core/multiplayer/multiplayer_peer.h b/core/multiplayer/multiplayer_peer.h
index dee2be7b4b..474b18d2b6 100644
--- a/core/multiplayer/multiplayer_peer.h
+++ b/core/multiplayer/multiplayer_peer.h
@@ -93,6 +93,8 @@ class MultiplayerPeerExtension : public MultiplayerPeer {
protected:
static void _bind_methods();
+ PackedByteArray script_buffer;
+
public:
/* PacketPeer */
virtual int get_available_packet_count() const override;
@@ -126,6 +128,10 @@ public:
GDVIRTUAL2R(int, _put_packet, GDNativeConstPtr<const uint8_t>, int);
GDVIRTUAL0RC(int, _get_max_packet_size);
+ /* PacketPeer GDScript */
+ GDVIRTUAL0R(PackedByteArray, _get_packet_script);
+ GDVIRTUAL1R(int, _put_packet_script, PackedByteArray);
+
/* MultiplayerPeer GDExtension */
GDVIRTUAL1(_set_transfer_channel, int);
GDVIRTUAL0RC(int, _get_transfer_channel);
diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp
index 47943a563f..fbbbc39af2 100644
--- a/core/variant/variant_call.cpp
+++ b/core/variant/variant_call.cpp
@@ -1730,7 +1730,7 @@ static void _register_variant_builtin_methods() {
bind_method(Plane, normalized, sarray(), varray());
bind_method(Plane, center, sarray(), varray());
bind_method(Plane, is_equal_approx, sarray("to_plane"), varray());
- bind_method(Plane, is_point_over, sarray("plane"), varray());
+ bind_method(Plane, is_point_over, sarray("point"), varray());
bind_method(Plane, distance_to, sarray("point"), varray());
bind_method(Plane, has_point, sarray("point", "tolerance"), varray(CMP_EPSILON));
bind_method(Plane, project, sarray("point"), varray());
diff --git a/doc/classes/BaseMaterial3D.xml b/doc/classes/BaseMaterial3D.xml
index d3ae85101d..b3cea7217e 100644
--- a/doc/classes/BaseMaterial3D.xml
+++ b/doc/classes/BaseMaterial3D.xml
@@ -374,10 +374,10 @@
[b]Note:[/b] This is only effective for objects whose geometry is point-based rather than triangle-based. See also [member point_size].
</member>
<member name="uv1_offset" type="Vector3" setter="set_uv1_offset" getter="get_uv1_offset" default="Vector3(0, 0, 0)">
- How much to offset the [code]UV[/code] coordinates. This amount will be added to [code]UV[/code] in the vertex function. This can be used to offset a texture.
+ How much to offset the [code]UV[/code] coordinates. This amount will be added to [code]UV[/code] in the vertex function. This can be used to offset a texture. The Z component is used when [member uv1_triplanar] is enabled, but it is not used anywhere else.
</member>
<member name="uv1_scale" type="Vector3" setter="set_uv1_scale" getter="get_uv1_scale" default="Vector3(1, 1, 1)">
- How much to scale the [code]UV[/code] coordinates. This is multiplied by [code]UV[/code] in the vertex function.
+ How much to scale the [code]UV[/code] coordinates. This is multiplied by [code]UV[/code] in the vertex function. The Z component is used when [member uv1_triplanar] is enabled, but it is not used anywhere else.
</member>
<member name="uv1_triplanar" type="bool" setter="set_flag" getter="get_flag" default="false">
If [code]true[/code], instead of using [code]UV[/code] textures will use a triplanar texture lookup to determine how to apply textures. Triplanar uses the orientation of the object's surface to blend between texture coordinates. It reads from the source texture 3 times, once for each axis and then blends between the results based on how closely the pixel aligns with each axis. This is often used for natural features to get a realistic blend of materials. Because triplanar texturing requires many more texture reads per-pixel it is much slower than normal UV texturing. Additionally, because it is blending the texture between the three axes, it is unsuitable when you are trying to achieve crisp texturing.
@@ -389,10 +389,10 @@
If [code]true[/code], triplanar mapping for [code]UV[/code] is calculated in world space rather than object local space. See also [member uv1_triplanar].
</member>
<member name="uv2_offset" type="Vector3" setter="set_uv2_offset" getter="get_uv2_offset" default="Vector3(0, 0, 0)">
- How much to offset the [code]UV2[/code] coordinates. This amount will be added to [code]UV2[/code] in the vertex function. This can be used to offset a texture.
+ How much to offset the [code]UV2[/code] coordinates. This amount will be added to [code]UV2[/code] in the vertex function. This can be used to offset a texture. The Z component is used when [member uv2_triplanar] is enabled, but it is not used anywhere else.
</member>
<member name="uv2_scale" type="Vector3" setter="set_uv2_scale" getter="get_uv2_scale" default="Vector3(1, 1, 1)">
- How much to scale the [code]UV2[/code] coordinates. This is multiplied by [code]UV2[/code] in the vertex function.
+ How much to scale the [code]UV2[/code] coordinates. This is multiplied by [code]UV2[/code] in the vertex function. The Z component is used when [member uv2_triplanar] is enabled, but it is not used anywhere else.
</member>
<member name="uv2_triplanar" type="bool" setter="set_flag" getter="get_flag" default="false">
If [code]true[/code], instead of using [code]UV2[/code] textures will use a triplanar texture lookup to determine how to apply textures. Triplanar uses the orientation of the object's surface to blend between texture coordinates. It reads from the source texture 3 times, once for each axis and then blends between the results based on how closely the pixel aligns with each axis. This is often used for natural features to get a realistic blend of materials. Because triplanar texturing requires many more texture reads per-pixel it is much slower than normal UV texturing. Additionally, because it is blending the texture between the three axes, it is unsuitable when you are trying to achieve crisp texturing.
diff --git a/doc/classes/MultiplayerPeerExtension.xml b/doc/classes/MultiplayerPeerExtension.xml
index bd11c76039..f837171e2f 100644
--- a/doc/classes/MultiplayerPeerExtension.xml
+++ b/doc/classes/MultiplayerPeerExtension.xml
@@ -41,6 +41,12 @@
Called when the ID of the [MultiplayerPeer] who sent the most recent packet is requested (see [method MultiplayerPeer.get_packet_peer]).
</description>
</method>
+ <method name="_get_packet_script" qualifiers="virtual">
+ <return type="PackedByteArray" />
+ <description>
+ Called when a packet needs to be received by the [MultiplayerAPI], if [method _get_packet] isn't implemented. Use this when extending this class via GDScript.
+ </description>
+ </method>
<method name="_get_transfer_channel" qualifiers="virtual const">
<return type="int" />
<description>
@@ -85,6 +91,13 @@
Called when a packet needs to be sent by the [MultiplayerAPI], with [code]p_buffer_size[/code] being the size of the binary [code]p_buffer[/code] in bytes.
</description>
</method>
+ <method name="_put_packet_script" qualifiers="virtual">
+ <return type="int" />
+ <argument index="0" name="p_buffer" type="PackedByteArray" />
+ <description>
+ Called when a packet needs to be sent by the [MultiplayerAPI], if [method _put_packet] isn't implemented. Use this when extending this class via GDScript.
+ </description>
+ </method>
<method name="_set_refuse_new_connections" qualifiers="virtual">
<return type="void" />
<argument index="0" name="p_enable" type="bool" />
diff --git a/doc/classes/Plane.xml b/doc/classes/Plane.xml
index 33e9e0c92d..32eb71f1c7 100644
--- a/doc/classes/Plane.xml
+++ b/doc/classes/Plane.xml
@@ -109,7 +109,7 @@
<argument index="0" name="from" type="Vector3" />
<argument index="1" name="to" type="Vector3" />
<description>
- Returns the intersection point of a segment from position [code]begin[/code] to position [code]end[/code] with this plane. If no intersection is found, [code]null[/code] is returned.
+ Returns the intersection point of a segment from position [code]from[/code] to position [code]to[/code] with this plane. If no intersection is found, [code]null[/code] is returned.
</description>
</method>
<method name="is_equal_approx" qualifiers="const">
@@ -121,7 +121,7 @@
</method>
<method name="is_point_over" qualifiers="const">
<return type="bool" />
- <argument index="0" name="plane" type="Vector3" />
+ <argument index="0" name="point" type="Vector3" />
<description>
Returns [code]true[/code] if [code]point[/code] is located above the plane.
</description>
diff --git a/doc/classes/SceneTree.xml b/doc/classes/SceneTree.xml
index cf6ab977db..9982cc0d60 100644
--- a/doc/classes/SceneTree.xml
+++ b/doc/classes/SceneTree.xml
@@ -18,8 +18,7 @@
<argument index="0" name="group" type="StringName" />
<argument index="1" name="method" type="StringName" />
<description>
- Calls [code]method[/code] on each member of the given group. You can pass arguments to [code]method[/code] by specifying them at the end of the method call.
- [b]Note:[/b] Due to design limitations, [method call_group] will fail silently if one of the arguments is [code]null[/code].
+ Calls [code]method[/code] on each member of the given group. You can pass arguments to [code]method[/code] by specifying them at the end of the method call. If a node doesn't have the given method or the argument list does not match (either in count or in types), it will be skipped.
[b]Note:[/b] [method call_group] will call methods immediately on all members at once, which can cause stuttering if an expensive method is called on lots of members. To wait for one frame after [method call_group] was called, use [method call_group_flags] with the [constant GROUP_CALL_DEFERRED] flag.
</description>
</method>
@@ -29,12 +28,11 @@
<argument index="1" name="group" type="StringName" />
<argument index="2" name="method" type="StringName" />
<description>
- Calls [code]method[/code] on each member of the given group, respecting the given [enum GroupCallFlags]. You can pass arguments to [code]method[/code] by specifying them at the end of the method call.
+ Calls [code]method[/code] on each member of the given group, respecting the given [enum GroupCallFlags]. You can pass arguments to [code]method[/code] by specifying them at the end of the method call. If a node doesn't have the given method or the argument list does not match (either in count or in types), it will be skipped.
[codeblock]
# Call the method in a deferred manner and in reverse order.
get_tree().call_group_flags(SceneTree.GROUP_CALL_DEFERRED | SceneTree.GROUP_CALL_REVERSE)
[/codeblock]
- [b]Note:[/b] Due to design limitations, [method call_group_flags] will fail silently if one of the arguments is [code]null[/code].
[b]Note:[/b] Group call flags are used to control the method calling behavior. By default, methods will be called immediately in a way similar to [method call_group]. However, if the [constant GROUP_CALL_DEFERRED] flag is present in the [code]flags[/code] argument, methods will be called with a one-frame delay in a way similar to [method Object.set_deferred].
</description>
</method>
diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp
index babdc9f33b..5f9099cb31 100644
--- a/modules/gltf/gltf_document.cpp
+++ b/modules/gltf/gltf_document.cpp
@@ -230,15 +230,21 @@ Error GLTFDocument::_serialize(Ref<GLTFState> state, const String &p_path) {
}
Error GLTFDocument::_serialize_extensions(Ref<GLTFState> state) const {
- const String texture_transform = "KHR_texture_transform";
- const String punctual_lights = "KHR_lights_punctual";
Array extensions_used;
- extensions_used.push_back(punctual_lights);
- extensions_used.push_back(texture_transform);
- state->json["extensionsUsed"] = extensions_used;
Array extensions_required;
- extensions_required.push_back(texture_transform);
- state->json["extensionsRequired"] = extensions_required;
+ if (!state->lights.is_empty()) {
+ extensions_used.push_back("KHR_lights_punctual");
+ }
+ if (state->use_khr_texture_transform) {
+ extensions_used.push_back("KHR_texture_transform");
+ extensions_required.push_back("KHR_texture_transform");
+ }
+ if (!extensions_used.is_empty()) {
+ state->json["extensionsUsed"] = extensions_used;
+ }
+ if (!extensions_required.is_empty()) {
+ state->json["extensionsRequired"] = extensions_required;
+ }
return OK;
}
@@ -3305,7 +3311,11 @@ Error GLTFDocument::_serialize_materials(Ref<GLTFState> state) {
}
if (gltf_texture_index != -1) {
bct["index"] = gltf_texture_index;
- bct["extensions"] = _serialize_texture_transform_uv1(material);
+ Dictionary extensions = _serialize_texture_transform_uv1(material);
+ if (!extensions.is_empty()) {
+ bct["extensions"] = extensions;
+ state->use_khr_texture_transform = true;
+ }
mr["baseColorTexture"] = bct;
}
}
@@ -3436,7 +3446,11 @@ Error GLTFDocument::_serialize_materials(Ref<GLTFState> state) {
}
if (has_roughness || has_metalness) {
mrt["index"] = orm_texture_index;
- mrt["extensions"] = _serialize_texture_transform_uv1(material);
+ Dictionary extensions = _serialize_texture_transform_uv1(material);
+ if (!extensions.is_empty()) {
+ mrt["extensions"] = extensions;
+ state->use_khr_texture_transform = true;
+ }
mr["metallicRoughnessTexture"] = mrt;
}
}
@@ -4525,6 +4539,9 @@ void GLTFDocument::_remove_duplicate_skins(Ref<GLTFState> state) {
}
Error GLTFDocument::_serialize_lights(Ref<GLTFState> state) {
+ if (state->lights.is_empty()) {
+ return OK;
+ }
Array lights;
for (GLTFLightIndex i = 0; i < state->lights.size(); i++) {
Dictionary d;
@@ -4551,10 +4568,6 @@ Error GLTFDocument::_serialize_lights(Ref<GLTFState> state) {
lights.push_back(d);
}
- if (!state->lights.size()) {
- return OK;
- }
-
Dictionary extensions;
if (state->json.has("extensions")) {
extensions = state->json["extensions"];
@@ -6651,45 +6664,48 @@ Error GLTFDocument::_parse(Ref<GLTFState> state, String p_path, Ref<FileAccess>
return OK;
}
-Dictionary GLTFDocument::_serialize_texture_transform_uv2(Ref<BaseMaterial3D> p_material) {
- Dictionary extension;
- Ref<BaseMaterial3D> mat = p_material;
- if (mat.is_valid()) {
- Dictionary texture_transform;
+Dictionary _serialize_texture_transform_uv(Vector2 p_offset, Vector2 p_scale) {
+ Dictionary texture_transform;
+ bool is_offset = p_offset != Vector2(0.0, 0.0);
+ if (is_offset) {
Array offset;
offset.resize(2);
- offset[0] = mat->get_uv2_offset().x;
- offset[1] = mat->get_uv2_offset().y;
+ offset[0] = p_offset.x;
+ offset[1] = p_offset.y;
texture_transform["offset"] = offset;
+ }
+ bool is_scaled = p_scale != Vector2(1.0, 1.0);
+ if (is_scaled) {
Array scale;
scale.resize(2);
- scale[0] = mat->get_uv2_scale().x;
- scale[1] = mat->get_uv2_scale().y;
+ scale[0] = p_scale.x;
+ scale[1] = p_scale.y;
texture_transform["scale"] = scale;
- // Godot doesn't support texture rotation
+ }
+ Dictionary extension;
+ // Note: Godot doesn't support texture rotation.
+ if (is_offset || is_scaled) {
extension["KHR_texture_transform"] = texture_transform;
}
return extension;
}
Dictionary GLTFDocument::_serialize_texture_transform_uv1(Ref<BaseMaterial3D> p_material) {
- Dictionary extension;
if (p_material.is_valid()) {
- Dictionary texture_transform;
- Array offset;
- offset.resize(2);
- offset[0] = p_material->get_uv1_offset().x;
- offset[1] = p_material->get_uv1_offset().y;
- texture_transform["offset"] = offset;
- Array scale;
- scale.resize(2);
- scale[0] = p_material->get_uv1_scale().x;
- scale[1] = p_material->get_uv1_scale().y;
- texture_transform["scale"] = scale;
- // Godot doesn't support texture rotation
- extension["KHR_texture_transform"] = texture_transform;
+ Vector3 offset = p_material->get_uv1_offset();
+ Vector3 scale = p_material->get_uv1_scale();
+ return _serialize_texture_transform_uv(Vector2(offset.x, offset.y), Vector2(scale.x, scale.y));
}
- return extension;
+ return Dictionary();
+}
+
+Dictionary GLTFDocument::_serialize_texture_transform_uv2(Ref<BaseMaterial3D> p_material) {
+ if (p_material.is_valid()) {
+ Vector3 offset = p_material->get_uv2_offset();
+ Vector3 scale = p_material->get_uv2_scale();
+ return _serialize_texture_transform_uv(Vector2(offset.x, offset.y), Vector2(scale.x, scale.y));
+ }
+ return Dictionary();
}
Error GLTFDocument::_serialize_version(Ref<GLTFState> state) {
diff --git a/modules/gltf/gltf_state.h b/modules/gltf/gltf_state.h
index 2fdef19038..7a06c93d59 100644
--- a/modules/gltf/gltf_state.h
+++ b/modules/gltf/gltf_state.h
@@ -60,6 +60,7 @@ class GLTFState : public Resource {
Vector<uint8_t> glb_data;
bool use_named_skin_binds = false;
+ bool use_khr_texture_transform = false;
bool discard_meshes_and_materials = false;
Vector<Ref<GLTFNode>> nodes;
diff --git a/platform/uwp/os_uwp.cpp b/platform/uwp/os_uwp.cpp
index 1614bfdcc3..f37759c66f 100644
--- a/platform/uwp/os_uwp.cpp
+++ b/platform/uwp/os_uwp.cpp
@@ -557,6 +557,7 @@ uint64_t OS_UWP::get_ticks_usec() const {
void OS_UWP::process_events() {
joypad->process_controllers();
process_key_events();
+ input->flush_buffered_events();
}
void OS_UWP::process_key_events() {
diff --git a/scene/animation/animation_node_state_machine.cpp b/scene/animation/animation_node_state_machine.cpp
index fe08e849a1..fbe23bedad 100644
--- a/scene/animation/animation_node_state_machine.cpp
+++ b/scene/animation/animation_node_state_machine.cpp
@@ -630,7 +630,7 @@ bool AnimationNodeStateMachinePlayback::_check_advance_condition(const Ref<Anima
Node *expression_base = tree_base->get_node_or_null(advance_expression_base_node_path);
if (expression_base) {
Ref<Expression> exp = transition->expression;
- bool ret = exp->execute(Array(), tree_base, false, Engine::get_singleton()->is_editor_hint()); // Avoids allowing the user to crash the system with an expression by only allowing const calls.
+ bool ret = exp->execute(Array(), expression_base, false, Engine::get_singleton()->is_editor_hint()); // Avoids allowing the user to crash the system with an expression by only allowing const calls.
if (!exp->has_execute_failed()) {
if (ret) {
return true;