mirror of
https://github.com/godotengine/godot
synced 2024-09-30 04:38:44 +00:00
Compare commits
16 commits
604493eb6e
...
0b1d516f67
Author | SHA1 | Date | |
---|---|---|---|
0b1d516f67 | |||
a268dcc7e3 | |||
1253547837 | |||
bbff9fd7a4 | |||
ea5cf7d4b8 | |||
2c008ac8c5 | |||
da81c3f9b5 | |||
b0598dcdb7 | |||
e14cacb8da | |||
497f5576c1 | |||
bf0cc8f52a | |||
03ae8caea8 | |||
1459b9c24c | |||
7caf08ec75 | |||
54f8fb010c | |||
386f62df96 |
|
@ -239,13 +239,18 @@ void Basis::scale_orthogonal(const Vector3 &p_scale) {
|
|||
Basis Basis::scaled_orthogonal(const Vector3 &p_scale) const {
|
||||
Basis m = *this;
|
||||
Vector3 s = Vector3(-1, -1, -1) + p_scale;
|
||||
bool sign = signbit(s.x + s.y + s.z);
|
||||
Basis b = m.orthonormalized();
|
||||
s = b.xform_inv(s);
|
||||
Vector3 dots;
|
||||
Basis b;
|
||||
for (int i = 0; i < 3; i++) {
|
||||
for (int j = 0; j < 3; j++) {
|
||||
dots[j] += s[i] * abs(m.get_column(i).normalized().dot(b.get_column(j)));
|
||||
}
|
||||
}
|
||||
if (sign != signbit(dots.x + dots.y + dots.z)) {
|
||||
dots = -dots;
|
||||
}
|
||||
m.scale_local(Vector3(1, 1, 1) + dots);
|
||||
return m;
|
||||
}
|
||||
|
|
|
@ -629,14 +629,14 @@ void Array::shuffle() {
|
|||
}
|
||||
}
|
||||
|
||||
int Array::bsearch(const Variant &p_value, bool p_before) {
|
||||
int Array::bsearch(const Variant &p_value, bool p_before) const {
|
||||
Variant value = p_value;
|
||||
ERR_FAIL_COND_V(!_p->typed.validate(value, "binary search"), -1);
|
||||
SearchArray<Variant, _ArrayVariantSort> avs;
|
||||
return avs.bisect(_p->array.ptrw(), _p->array.size(), value, p_before);
|
||||
}
|
||||
|
||||
int Array::bsearch_custom(const Variant &p_value, const Callable &p_callable, bool p_before) {
|
||||
int Array::bsearch_custom(const Variant &p_value, const Callable &p_callable, bool p_before) const {
|
||||
Variant value = p_value;
|
||||
ERR_FAIL_COND_V(!_p->typed.validate(value, "custom binary search"), -1);
|
||||
|
||||
|
|
|
@ -83,8 +83,8 @@ public:
|
|||
void sort();
|
||||
void sort_custom(const Callable &p_callable);
|
||||
void shuffle();
|
||||
int bsearch(const Variant &p_value, bool p_before = true);
|
||||
int bsearch_custom(const Variant &p_value, const Callable &p_callable, bool p_before = true);
|
||||
int bsearch(const Variant &p_value, bool p_before = true) const;
|
||||
int bsearch_custom(const Variant &p_value, const Callable &p_callable, bool p_before = true) const;
|
||||
void reverse();
|
||||
|
||||
int find(const Variant &p_value, int p_from = 0) const;
|
||||
|
|
|
@ -214,7 +214,7 @@
|
|||
[b]Note:[/b] Calling this function is not the same as writing [code]array[-1][/code]. If the array is empty, accessing by index will pause project execution when running from the editor.
|
||||
</description>
|
||||
</method>
|
||||
<method name="bsearch">
|
||||
<method name="bsearch" qualifiers="const">
|
||||
<return type="int" />
|
||||
<param index="0" name="value" type="Variant" />
|
||||
<param index="1" name="before" type="bool" default="true" />
|
||||
|
@ -223,7 +223,7 @@
|
|||
[b]Note:[/b] Calling [method bsearch] on an unsorted array results in unexpected behavior.
|
||||
</description>
|
||||
</method>
|
||||
<method name="bsearch_custom">
|
||||
<method name="bsearch_custom" qualifiers="const">
|
||||
<return type="int" />
|
||||
<param index="0" name="value" type="Variant" />
|
||||
<param index="1" name="func" type="Callable" />
|
||||
|
@ -276,7 +276,7 @@
|
|||
array.fill(0) # Initialize the 10 elements to 0.
|
||||
[/gdscript]
|
||||
[csharp]
|
||||
var array = new Godot.Collections.Array{};
|
||||
var array = new Godot.Collections.Array();
|
||||
array.Resize(10);
|
||||
array.Fill(0); // Initialize the 10 elements to 0.
|
||||
[/csharp]
|
||||
|
@ -347,7 +347,7 @@
|
|||
print(["inside", 7].has("7")) # False
|
||||
[/gdscript]
|
||||
[csharp]
|
||||
var arr = new Godot.Collections.Array{"inside", 7};
|
||||
var arr = new Godot.Collections.Array { "inside", 7 };
|
||||
// has is renamed to Contains
|
||||
GD.Print(arr.Contains("inside")); // True
|
||||
GD.Print(arr.Contains("outside")); // False
|
||||
|
@ -364,7 +364,7 @@
|
|||
[/gdscript]
|
||||
[csharp]
|
||||
// As there is no "in" keyword in C#, you have to use Contains
|
||||
var array = new Godot.Collections.Array{2, 4, 6, 8};
|
||||
var array = new Godot.Collections.Array { 2, 4, 6, 8 };
|
||||
if (array.Contains(2))
|
||||
{
|
||||
GD.Print("Contains!");
|
||||
|
@ -454,10 +454,16 @@
|
|||
<return type="Variant" />
|
||||
<description>
|
||||
Returns a random value from the target array.
|
||||
[codeblock]
|
||||
[codeblocks]
|
||||
[gdscript]
|
||||
var array: Array[int] = [1, 2, 3, 4]
|
||||
print(array.pick_random()) # Prints either of the four numbers.
|
||||
[/codeblock]
|
||||
[/gdscript]
|
||||
[csharp]
|
||||
var array = new Godot.Collections.Array { 1, 2, 3, 4 };
|
||||
GD.Print(array.PickRandom()); // Prints either of the four numbers.
|
||||
[/csharp]
|
||||
[/codeblocks]
|
||||
</description>
|
||||
</method>
|
||||
<method name="pop_at">
|
||||
|
@ -566,7 +572,7 @@
|
|||
Returns the slice of the [Array], from [param begin] (inclusive) to [param end] (exclusive), as a new [Array].
|
||||
The absolute value of [param begin] and [param end] will be clamped to the array size, so the default value for [param end] makes it slice to the size of the array by default (i.e. [code]arr.slice(1)[/code] is a shorthand for [code]arr.slice(1, arr.size())[/code]).
|
||||
If either [param begin] or [param end] are negative, they will be relative to the end of the array (i.e. [code]arr.slice(0, -2)[/code] is a shorthand for [code]arr.slice(0, arr.size() - 2)[/code]).
|
||||
If specified, [param step] is the relative index between source elements. It can be negative, then [param begin] must be higher than [param end]. For example, [code][0, 1, 2, 3, 4, 5].slice(5, 1, -2)[/code] returns [code][5, 3][/code]).
|
||||
If specified, [param step] is the relative index between source elements. It can be negative, then [param begin] must be higher than [param end]. For example, [code][0, 1, 2, 3, 4, 5].slice(5, 1, -2)[/code] returns [code][5, 3][/code].
|
||||
If [param deep] is true, each element will be copied by value rather than by reference.
|
||||
</description>
|
||||
</method>
|
||||
|
@ -583,7 +589,9 @@
|
|||
print(strings) # Prints [string1, string10, string11, string2]
|
||||
[/gdscript]
|
||||
[csharp]
|
||||
// There is no sort support for Godot.Collections.Array
|
||||
var strings = new Godot.Collections.Array { "string1", "string2", "string10", "string11" };
|
||||
strings.Sort();
|
||||
GD.Print(strings); // Prints [string1, string10, string11, string2]
|
||||
[/csharp]
|
||||
[/codeblocks]
|
||||
To perform natural order sorting, you can use [method sort_custom] with [method String.naturalnocasecmp_to] as follows:
|
||||
|
|
|
@ -639,7 +639,7 @@
|
|||
<description>
|
||||
Returns an [Array] of connections for the given [param signal] name. Each connection is represented as a [Dictionary] that contains three entries:
|
||||
- [code]signal[/code] is a reference to the [Signal];
|
||||
- [code]callable[/code] is a reference to the [Callable];
|
||||
- [code]callable[/code] is a reference to the connected [Callable];
|
||||
- [code]flags[/code] is a combination of [enum ConnectFlags].
|
||||
</description>
|
||||
</method>
|
||||
|
|
|
@ -85,7 +85,10 @@
|
|||
<method name="get_connections" qualifiers="const">
|
||||
<return type="Array" />
|
||||
<description>
|
||||
Returns the list of [Callable]s connected to this signal.
|
||||
Returns an [Array] of connections for this signal. Each connection is represented as a [Dictionary] that contains three entries:
|
||||
- [code]signal[/code] is a reference to this signal;
|
||||
- [code]callable[/code] is a reference to the connected [Callable];
|
||||
- [code]flags[/code] is a combination of [enum Object.ConnectFlags].
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_name" qualifiers="const">
|
||||
|
|
|
@ -1128,6 +1128,12 @@ void RasterizerCanvasGLES3::_record_item_commands(const Item *p_item, RID p_rend
|
|||
state.canvas_instance_batches[state.current_batch_index].tex = mm->texture;
|
||||
state.canvas_instance_batches[state.current_batch_index].shader_variant = CanvasShaderGLES3::MODE_INSTANCED;
|
||||
|
||||
if (GLES3::MeshStorage::get_singleton()->multimesh_uses_colors(mm->multimesh)) {
|
||||
state.instance_data_array[r_index].flags |= FLAGS_INSTANCING_HAS_COLORS;
|
||||
}
|
||||
if (GLES3::MeshStorage::get_singleton()->multimesh_uses_custom_data(mm->multimesh)) {
|
||||
state.instance_data_array[r_index].flags |= FLAGS_INSTANCING_HAS_CUSTOM_DATA;
|
||||
}
|
||||
} else if (c->type == Item::Command::TYPE_PARTICLES) {
|
||||
GLES3::ParticlesStorage *particles_storage = GLES3::ParticlesStorage::get_singleton();
|
||||
GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();
|
||||
|
|
|
@ -179,7 +179,8 @@ typedef void (*DEBUGPROCARB)(GLenum source,
|
|||
typedef void (*DebugMessageCallbackARB)(DEBUGPROCARB callback, const void *userParam);
|
||||
|
||||
void RasterizerGLES3::initialize() {
|
||||
print_line(vformat("OpenGL API %s - Compatibility - Using Device: %s - %s", RS::get_singleton()->get_video_adapter_api_version(), RS::get_singleton()->get_video_adapter_vendor(), RS::get_singleton()->get_video_adapter_name()));
|
||||
// NVIDIA suffixes all GPU model names with "/PCIe/SSE2" in OpenGL (but not Vulkan). This isn't necessary to display nowadays, so it can be trimmed.
|
||||
print_line(vformat("OpenGL API %s - Compatibility - Using Device: %s - %s", RS::get_singleton()->get_video_adapter_api_version(), RS::get_singleton()->get_video_adapter_vendor(), RS::get_singleton()->get_video_adapter_name().trim_suffix("/PCIe/SSE2")));
|
||||
}
|
||||
|
||||
void RasterizerGLES3::finalize() {
|
||||
|
|
|
@ -162,9 +162,13 @@ void main() {
|
|||
vec2 uv = uv_attrib;
|
||||
|
||||
#ifdef USE_INSTANCING
|
||||
vec4 instance_color = vec4(unpackHalf2x16(instance_color_custom_data.x), unpackHalf2x16(instance_color_custom_data.y));
|
||||
color *= instance_color;
|
||||
instance_custom = vec4(unpackHalf2x16(instance_color_custom_data.z), unpackHalf2x16(instance_color_custom_data.w));
|
||||
if (bool(read_draw_data_flags & FLAGS_INSTANCING_HAS_COLORS)) {
|
||||
vec4 instance_color = vec4(unpackHalf2x16(instance_color_custom_data.x), unpackHalf2x16(instance_color_custom_data.y));
|
||||
color *= instance_color;
|
||||
}
|
||||
if (bool(read_draw_data_flags & FLAGS_INSTANCING_HAS_CUSTOM_DATA)) {
|
||||
instance_custom = vec4(unpackHalf2x16(instance_color_custom_data.z), unpackHalf2x16(instance_color_custom_data.w));
|
||||
}
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
|
|
@ -1835,8 +1835,12 @@ void MeshStorage::multimesh_set_visible_instances(RID p_multimesh, int p_visible
|
|||
}
|
||||
|
||||
if (multimesh->data_cache.size()) {
|
||||
//there is a data cache..
|
||||
// There is a data cache, but we may need to update some sections.
|
||||
_multimesh_mark_all_dirty(multimesh, false, true);
|
||||
int start = multimesh->visible_instances >= 0 ? multimesh->visible_instances : multimesh->instances;
|
||||
for (int i = start; i < p_visible; i++) {
|
||||
_multimesh_mark_dirty(multimesh, i, true);
|
||||
}
|
||||
}
|
||||
|
||||
multimesh->visible_instances = p_visible;
|
||||
|
@ -1868,7 +1872,7 @@ void MeshStorage::_update_dirty_multimeshes() {
|
|||
if (multimesh->data_cache_used_dirty_regions > 32 || multimesh->data_cache_used_dirty_regions > visible_region_count / 2) {
|
||||
// If there too many dirty regions, or represent the majority of regions, just copy all, else transfer cost piles up too much
|
||||
glBindBuffer(GL_ARRAY_BUFFER, multimesh->buffer);
|
||||
glBufferData(GL_ARRAY_BUFFER, MIN(visible_region_count * region_size, multimesh->instances * multimesh->stride_cache * sizeof(float)), data, GL_STATIC_DRAW);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, MIN(visible_region_count * region_size, multimesh->instances * multimesh->stride_cache * sizeof(float)), data);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
} else {
|
||||
// Not that many regions? update them all
|
||||
|
|
|
@ -1423,9 +1423,11 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
|
|||
theme->set_icon("grabber", "VSplitContainer", theme->get_icon(SNAME("GuiVsplitter"), SNAME("EditorIcons")));
|
||||
theme->set_icon("grabber", "HSplitContainer", theme->get_icon(SNAME("GuiHsplitter"), SNAME("EditorIcons")));
|
||||
|
||||
theme->set_constant("separation", "SplitContainer", default_margin_size * 2 * EDSCALE);
|
||||
theme->set_constant("separation", "HSplitContainer", default_margin_size * 2 * EDSCALE);
|
||||
theme->set_constant("separation", "VSplitContainer", default_margin_size * 2 * EDSCALE);
|
||||
|
||||
theme->set_constant("minimum_grab_thickness", "SplitContainer", 6 * EDSCALE);
|
||||
theme->set_constant("minimum_grab_thickness", "HSplitContainer", 6 * EDSCALE);
|
||||
theme->set_constant("minimum_grab_thickness", "VSplitContainer", 6 * EDSCALE);
|
||||
|
||||
|
|
|
@ -4876,6 +4876,10 @@ NavigationRegion3DGizmoPlugin::NavigationRegion3DGizmoPlugin() {
|
|||
create_material("face_material_disabled", NavigationServer3D::get_singleton()->get_debug_navigation_geometry_face_disabled_color(), false, false, true);
|
||||
create_material("edge_material", NavigationServer3D::get_singleton()->get_debug_navigation_geometry_edge_color());
|
||||
create_material("edge_material_disabled", NavigationServer3D::get_singleton()->get_debug_navigation_geometry_edge_disabled_color());
|
||||
|
||||
Color baking_aabb_material_color = Color(0.8, 0.5, 0.7);
|
||||
baking_aabb_material_color.a = 0.1;
|
||||
create_material("baking_aabb_material", baking_aabb_material_color);
|
||||
}
|
||||
|
||||
bool NavigationRegion3DGizmoPlugin::has_gizmo(Node3D *p_spatial) {
|
||||
|
@ -4899,6 +4903,16 @@ void NavigationRegion3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
|
|||
return;
|
||||
}
|
||||
|
||||
AABB baking_aabb = navigationmesh->get_filter_baking_aabb();
|
||||
if (baking_aabb.has_volume()) {
|
||||
Vector3 baking_aabb_offset = navigationmesh->get_filter_baking_aabb_offset();
|
||||
|
||||
if (p_gizmo->is_selected()) {
|
||||
Ref<Material> material = get_material("baking_aabb_material", p_gizmo);
|
||||
p_gizmo->add_solid_box(material, baking_aabb.get_size(), baking_aabb.get_center() + baking_aabb_offset);
|
||||
}
|
||||
}
|
||||
|
||||
Vector<Vector3> vertices = navigationmesh->get_vertices();
|
||||
const Vector3 *vr = vertices.ptr();
|
||||
List<Face3> faces;
|
||||
|
|
|
@ -1415,9 +1415,6 @@ Transform3D Node3DEditorViewport::_compute_transform(TransformMode p_mode, const
|
|||
// Recalculate orthogonalized scale without moving origin.
|
||||
if (p_orthogonal) {
|
||||
s.basis = p_original.basis.scaled_orthogonal(p_motion + Vector3(1, 1, 1));
|
||||
// The scaled_orthogonal() does not require orthogonal Basis,
|
||||
// but it may make a bit skew by precision problems.
|
||||
s.basis.orthogonalize();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4634,7 +4631,7 @@ void Node3DEditorViewport::update_transform(Point2 p_mousepos, bool p_shift) {
|
|||
if (se->gizmo.is_valid()) {
|
||||
for (KeyValue<int, Transform3D> &GE : se->subgizmos) {
|
||||
Transform3D xform = GE.value;
|
||||
Transform3D new_xform = _compute_transform(TRANSFORM_SCALE, se->original * xform, xform, motion, snap, local_coords, true); // Force orthogonal with subgizmo.
|
||||
Transform3D new_xform = _compute_transform(TRANSFORM_SCALE, se->original * xform, xform, motion, snap, local_coords, _edit.plane != TRANSFORM_VIEW); // Force orthogonal with subgizmo.
|
||||
if (!local_coords) {
|
||||
new_xform = se->original.affine_inverse() * new_xform;
|
||||
}
|
||||
|
|
|
@ -1301,7 +1301,7 @@ void Skeleton3DGizmoPlugin::set_subgizmo_transform(const EditorNode3DGizmo *p_gi
|
|||
Transform3D original_to_local;
|
||||
int parent_idx = skeleton->get_bone_parent(p_id);
|
||||
if (parent_idx >= 0) {
|
||||
original_to_local = original_to_local * skeleton->get_bone_global_pose(parent_idx);
|
||||
original_to_local = skeleton->get_bone_global_pose(parent_idx);
|
||||
}
|
||||
Basis to_local = original_to_local.get_basis().inverse();
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -365,21 +365,44 @@ namespace Godot.NativeInterop
|
|||
|
||||
public static partial int godotsharp_array_add(ref godot_array p_self, in godot_variant p_item);
|
||||
|
||||
public static partial int godotsharp_array_add_range(ref godot_array p_self, in godot_array p_collection);
|
||||
|
||||
public static partial int godotsharp_array_binary_search(ref godot_array p_self, int p_index, int p_count, in godot_variant p_value);
|
||||
|
||||
public static partial void
|
||||
godotsharp_array_duplicate(ref godot_array p_self, godot_bool p_deep, out godot_array r_dest);
|
||||
|
||||
public static partial int godotsharp_array_index_of(ref godot_array p_self, in godot_variant p_item);
|
||||
public static partial void godotsharp_array_fill(ref godot_array p_self, in godot_variant p_value);
|
||||
|
||||
public static partial int godotsharp_array_index_of(ref godot_array p_self, in godot_variant p_item, int p_index = 0);
|
||||
|
||||
public static partial void godotsharp_array_insert(ref godot_array p_self, int p_index, in godot_variant p_item);
|
||||
|
||||
public static partial int godotsharp_array_last_index_of(ref godot_array p_self, in godot_variant p_item, int p_index);
|
||||
|
||||
public static partial void godotsharp_array_make_read_only(ref godot_array p_self);
|
||||
|
||||
public static partial void godotsharp_array_max(ref godot_array p_self, out godot_variant r_value);
|
||||
|
||||
public static partial void godotsharp_array_min(ref godot_array p_self, out godot_variant r_value);
|
||||
|
||||
public static partial void godotsharp_array_pick_random(ref godot_array p_self, out godot_variant r_value);
|
||||
|
||||
public static partial godot_bool godotsharp_array_recursive_equal(ref godot_array p_self, in godot_array p_other);
|
||||
|
||||
public static partial void godotsharp_array_remove_at(ref godot_array p_self, int p_index);
|
||||
|
||||
public static partial Error godotsharp_array_resize(ref godot_array p_self, int p_new_size);
|
||||
|
||||
public static partial void godotsharp_array_make_read_only(ref godot_array p_self);
|
||||
public static partial void godotsharp_array_reverse(ref godot_array p_self);
|
||||
|
||||
public static partial void godotsharp_array_shuffle(ref godot_array p_self);
|
||||
|
||||
public static partial void godotsharp_array_slice(ref godot_array p_self, int p_start, int p_end,
|
||||
int p_step, godot_bool p_deep, out godot_array r_dest);
|
||||
|
||||
public static partial void godotsharp_array_sort(ref godot_array p_self);
|
||||
|
||||
public static partial void godotsharp_array_to_string(ref godot_array p_self, out godot_string r_str);
|
||||
|
||||
// Dictionary
|
||||
|
|
|
@ -992,18 +992,78 @@ int32_t godotsharp_array_add(Array *p_self, const Variant *p_item) {
|
|||
return p_self->size();
|
||||
}
|
||||
|
||||
int32_t godotsharp_array_add_range(Array *p_self, const Array *p_collection) {
|
||||
p_self->append_array(*p_collection);
|
||||
return p_self->size();
|
||||
}
|
||||
|
||||
int32_t godotsharp_array_binary_search(const Array *p_self, int32_t p_index, int32_t p_length, const Variant *p_value) {
|
||||
ERR_FAIL_COND_V(p_index < 0, -1);
|
||||
ERR_FAIL_COND_V(p_length < 0, -1);
|
||||
ERR_FAIL_COND_V(p_self->size() - p_index < p_length, -1);
|
||||
|
||||
const Variant &value = *p_value;
|
||||
const Array &array = *p_self;
|
||||
|
||||
int lo = p_index;
|
||||
int hi = p_index + p_length - 1;
|
||||
while (lo <= hi) {
|
||||
int mid = lo + ((hi - lo) >> 1);
|
||||
const Variant &mid_item = array[mid];
|
||||
|
||||
if (mid_item == value) {
|
||||
return mid;
|
||||
}
|
||||
if (mid_item < value) {
|
||||
lo = mid + 1;
|
||||
} else {
|
||||
hi = mid - 1;
|
||||
}
|
||||
}
|
||||
|
||||
return ~lo;
|
||||
}
|
||||
|
||||
void godotsharp_array_duplicate(const Array *p_self, bool p_deep, Array *r_dest) {
|
||||
memnew_placement(r_dest, Array(p_self->duplicate(p_deep)));
|
||||
}
|
||||
|
||||
int32_t godotsharp_array_index_of(const Array *p_self, const Variant *p_item) {
|
||||
return p_self->find(*p_item);
|
||||
void godotsharp_array_fill(Array *p_self, const Variant *p_value) {
|
||||
p_self->fill(*p_value);
|
||||
}
|
||||
|
||||
int32_t godotsharp_array_index_of(const Array *p_self, const Variant *p_item, int32_t p_index = 0) {
|
||||
return p_self->find(*p_item, p_index);
|
||||
}
|
||||
|
||||
void godotsharp_array_insert(Array *p_self, int32_t p_index, const Variant *p_item) {
|
||||
p_self->insert(p_index, *p_item);
|
||||
}
|
||||
|
||||
int32_t godotsharp_array_last_index_of(const Array *p_self, const Variant *p_item, int32_t p_index) {
|
||||
return p_self->rfind(*p_item, p_index);
|
||||
}
|
||||
|
||||
void godotsharp_array_make_read_only(Array *p_self) {
|
||||
p_self->make_read_only();
|
||||
}
|
||||
|
||||
void godotsharp_array_max(const Array *p_self, Variant *r_value) {
|
||||
*r_value = p_self->max();
|
||||
}
|
||||
|
||||
void godotsharp_array_min(const Array *p_self, Variant *r_value) {
|
||||
*r_value = p_self->min();
|
||||
}
|
||||
|
||||
void godotsharp_array_pick_random(const Array *p_self, Variant *r_value) {
|
||||
*r_value = p_self->pick_random();
|
||||
}
|
||||
|
||||
bool godotsharp_array_recursive_equal(const Array *p_self, const Array *p_other) {
|
||||
return p_self->recursive_equal(*p_other, 0);
|
||||
}
|
||||
|
||||
void godotsharp_array_remove_at(Array *p_self, int32_t p_index) {
|
||||
p_self->remove_at(p_index);
|
||||
}
|
||||
|
@ -1012,14 +1072,22 @@ int32_t godotsharp_array_resize(Array *p_self, int32_t p_new_size) {
|
|||
return (int32_t)p_self->resize(p_new_size);
|
||||
}
|
||||
|
||||
void godotsharp_array_make_read_only(Array *p_self) {
|
||||
p_self->make_read_only();
|
||||
void godotsharp_array_reverse(Array *p_self) {
|
||||
p_self->reverse();
|
||||
}
|
||||
|
||||
void godotsharp_array_shuffle(Array *p_self) {
|
||||
p_self->shuffle();
|
||||
}
|
||||
|
||||
void godotsharp_array_slice(Array *p_self, int32_t p_start, int32_t p_end, int32_t p_step, bool p_deep, Array *r_dest) {
|
||||
memnew_placement(r_dest, Array(p_self->slice(p_start, p_end, p_step, p_deep)));
|
||||
}
|
||||
|
||||
void godotsharp_array_sort(Array *p_self) {
|
||||
p_self->sort();
|
||||
}
|
||||
|
||||
void godotsharp_array_to_string(const Array *p_self, String *r_str) {
|
||||
*r_str = Variant(*p_self).operator String();
|
||||
}
|
||||
|
@ -1450,13 +1518,24 @@ static const void *unmanaged_callbacks[]{
|
|||
(void *)godotsharp_array_destroy,
|
||||
(void *)godotsharp_dictionary_destroy,
|
||||
(void *)godotsharp_array_add,
|
||||
(void *)godotsharp_array_add_range,
|
||||
(void *)godotsharp_array_binary_search,
|
||||
(void *)godotsharp_array_duplicate,
|
||||
(void *)godotsharp_array_fill,
|
||||
(void *)godotsharp_array_index_of,
|
||||
(void *)godotsharp_array_insert,
|
||||
(void *)godotsharp_array_last_index_of,
|
||||
(void *)godotsharp_array_make_read_only,
|
||||
(void *)godotsharp_array_max,
|
||||
(void *)godotsharp_array_min,
|
||||
(void *)godotsharp_array_pick_random,
|
||||
(void *)godotsharp_array_recursive_equal,
|
||||
(void *)godotsharp_array_remove_at,
|
||||
(void *)godotsharp_array_resize,
|
||||
(void *)godotsharp_array_make_read_only,
|
||||
(void *)godotsharp_array_reverse,
|
||||
(void *)godotsharp_array_shuffle,
|
||||
(void *)godotsharp_array_slice,
|
||||
(void *)godotsharp_array_sort,
|
||||
(void *)godotsharp_array_to_string,
|
||||
(void *)godotsharp_dictionary_try_get_value,
|
||||
(void *)godotsharp_dictionary_set_value,
|
||||
|
|
|
@ -115,7 +115,7 @@ void SplitContainerDragger::_notification(int p_what) {
|
|||
return;
|
||||
}
|
||||
|
||||
Ref<Texture2D> tex = sc->get_theme_icon(SNAME("grabber"));
|
||||
Ref<Texture2D> tex = sc->_get_grabber_icon();
|
||||
draw_texture(tex, (get_size() - tex->get_size()) / 2);
|
||||
} break;
|
||||
}
|
||||
|
|
|
@ -278,7 +278,7 @@ bool NavigationMesh::get_filter_walkable_low_height_spans() const {
|
|||
|
||||
void NavigationMesh::set_filter_baking_aabb(const AABB &p_aabb) {
|
||||
filter_baking_aabb = p_aabb;
|
||||
notify_property_list_changed();
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
AABB NavigationMesh::get_filter_baking_aabb() const {
|
||||
|
@ -287,7 +287,7 @@ AABB NavigationMesh::get_filter_baking_aabb() const {
|
|||
|
||||
void NavigationMesh::set_filter_baking_aabb_offset(const Vector3 &p_aabb_offset) {
|
||||
filter_baking_aabb_offset = p_aabb_offset;
|
||||
notify_property_list_changed();
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
Vector3 NavigationMesh::get_filter_baking_aabb_offset() const {
|
||||
|
|
|
@ -1805,8 +1805,12 @@ void MeshStorage::multimesh_set_visible_instances(RID p_multimesh, int p_visible
|
|||
}
|
||||
|
||||
if (multimesh->data_cache.size()) {
|
||||
//there is a data cache..
|
||||
// There is a data cache, but we may need to update some sections.
|
||||
_multimesh_mark_all_dirty(multimesh, false, true);
|
||||
int start = multimesh->visible_instances >= 0 ? multimesh->visible_instances : multimesh->instances;
|
||||
for (int i = start; i < p_visible; i++) {
|
||||
_multimesh_mark_dirty(multimesh, i, true);
|
||||
}
|
||||
}
|
||||
|
||||
multimesh->visible_instances = p_visible;
|
||||
|
|
|
@ -485,6 +485,7 @@ public:
|
|||
singleton->_instance_queue_update(instance, true, false);
|
||||
|
||||
} break;
|
||||
case Dependency::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES:
|
||||
case Dependency::DEPENDENCY_CHANGED_MATERIAL: {
|
||||
singleton->_instance_queue_update(instance, false, true);
|
||||
} break;
|
||||
|
@ -496,9 +497,6 @@ public:
|
|||
case Dependency::DEPENDENCY_CHANGED_REFLECTION_PROBE: {
|
||||
singleton->_instance_queue_update(instance, true, true);
|
||||
} break;
|
||||
case Dependency::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES: {
|
||||
//ignored
|
||||
} break;
|
||||
case Dependency::DEPENDENCY_CHANGED_LIGHT_SOFT_SHADOW_AND_PROJECTOR: {
|
||||
//requires repairing
|
||||
if (instance->indexer_id.is_valid()) {
|
||||
|
|
Loading…
Reference in a new issue