-
Notifications
You must be signed in to change notification settings - Fork 125
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WIP: Make collision generation dynamic #278
base: main
Are you sure you want to change the base?
Changes from 4 commits
ba18b2f
de592db
ab616ac
4c7b7c5
a5f3850
6807c9a
f5842a0
efad1e7
553da7a
ecc5292
25c9c5a
5102686
f970779
d720d55
2ba52c8
f9da3c6
d3b097f
be00711
90d78e9
4556f8f
f73f4ca
d7c0944
623f9c7
cf717d8
0efbc88
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -293,123 +293,201 @@ void Terrain3D::_update_collision() { | |
|
||
int time = Time::get_singleton()->get_ticks_msec(); | ||
int region_size = _storage->get_region_size(); | ||
int shape_size = region_size + 1; | ||
int collision_shape_size = region_size; | ||
if (_dynamic_collision) { | ||
if (!UtilityFunctions::is_instance_valid(_camera) || !_camera->is_inside_tree()) { | ||
return; | ||
} | ||
collision_shape_size = _collision_dynamic_shape_size; | ||
} | ||
int shapes_per_region = region_size / collision_shape_size; | ||
int shape_size = collision_shape_size + 1; | ||
float hole_const = NAN; | ||
if (ProjectSettings::get_singleton()->get_setting("physics/3d/physics_engine") == "JoltPhysics3D") { | ||
hole_const = __FLT_MAX__; | ||
} | ||
|
||
for (int i = 0; i < _storage->get_region_count(); i++) { | ||
PackedFloat32Array map_data = PackedFloat32Array(); | ||
map_data.resize(shape_size * shape_size); | ||
|
||
Vector2i global_offset = Vector2i(_storage->get_region_offsets()[i]) * region_size; | ||
Vector3 global_pos = Vector3(global_offset.x, 0, global_offset.y); | ||
|
||
Ref<Image> map, map_x, map_z, map_xz; | ||
Ref<Image> cmap, cmap_x, cmap_z, cmap_xz; | ||
map = _storage->get_map_region(Terrain3DStorage::TYPE_HEIGHT, i); | ||
cmap = _storage->get_map_region(Terrain3DStorage::TYPE_CONTROL, i); | ||
int region = _storage->get_region_index(Vector3(global_pos.x + region_size, 0, global_pos.z)); | ||
if (region >= 0) { | ||
map_x = _storage->get_map_region(Terrain3DStorage::TYPE_HEIGHT, region); | ||
cmap_x = _storage->get_map_region(Terrain3DStorage::TYPE_CONTROL, region); | ||
} | ||
region = _storage->get_region_index(Vector3(global_pos.x, 0, global_pos.z + region_size)); | ||
if (region >= 0) { | ||
map_z = _storage->get_map_region(Terrain3DStorage::TYPE_HEIGHT, region); | ||
cmap_z = _storage->get_map_region(Terrain3DStorage::TYPE_CONTROL, region); | ||
Vector3 camera_pos; | ||
Array existing = Array(); | ||
if (_dynamic_collision) { | ||
camera_pos = _camera->get_global_position(); | ||
camera_pos.y = 0.0f; | ||
} | ||
|
||
// destroy previous collision shapes | ||
if (_debug_static_body != nullptr) { | ||
for (int i = _debug_static_body->get_child_count() - 1; i >= 0; i--) { | ||
Node3D *child = (Node3D *)_debug_static_body->get_child(i); | ||
Vector3 child_pos = child->get_global_position(); | ||
if (_dynamic_collision && child_pos.distance_to(camera_pos) <= _collision_dynamic_distance) { | ||
existing.append(child_pos); | ||
continue; | ||
} | ||
LOG(DEBUG, "Freeing dsb child ", i, " ", child->get_name()); | ||
_debug_static_body->remove_child(child); | ||
_unused_collision_shapes.append(child); | ||
} | ||
region = _storage->get_region_index(Vector3(global_pos.x + region_size, 0, global_pos.z + region_size)); | ||
if (region >= 0) { | ||
map_xz = _storage->get_map_region(Terrain3DStorage::TYPE_HEIGHT, region); | ||
cmap_xz = _storage->get_map_region(Terrain3DStorage::TYPE_CONTROL, region); | ||
} | ||
if (_static_body.is_valid() && PhysicsServer3D::get_singleton()->body_get_shape_count(_static_body) > 0) { | ||
for (int i = PhysicsServer3D::get_singleton()->body_get_shape_count(_static_body) - 1; i >= 0; i--) { | ||
RID shape = PhysicsServer3D::get_singleton()->body_get_shape(_static_body, i); | ||
Vector3 position = PhysicsServer3D::get_singleton()->body_get_shape_transform(_static_body, i).origin; | ||
if (_dynamic_collision && position.distance_to(camera_pos) <= _collision_dynamic_distance) { | ||
existing.append(position); | ||
continue; | ||
} | ||
_unused_collision_shapes.append(shape); | ||
} | ||
} | ||
|
||
for (int i = 0; i < _storage->get_region_count(); i++) { | ||
for (int jx = 0; jx < shapes_per_region; jx++) { | ||
for (int jz = 0; jz < shapes_per_region; jz++) { | ||
Vector2i global_offset = Vector2i(_storage->get_region_offsets()[i]) * region_size + Vector2i(collision_shape_size * jx, collision_shape_size * jz); | ||
Vector3 global_pos = Vector3(global_offset.x, 0, global_offset.y); | ||
Vector3 global_middle_pos = global_pos + Vector3(collision_shape_size, 0, collision_shape_size) * .5; | ||
|
||
if (_dynamic_collision && (global_middle_pos.distance_to(camera_pos) > _collision_dynamic_distance || existing.has(global_middle_pos))) { | ||
continue; | ||
} | ||
|
||
for (int z = 0; z < shape_size; z++) { | ||
for (int x = 0; x < shape_size; x++) { | ||
// Choose array indexing to match triangulation of heightmapshape with the mesh | ||
// https://stackoverflow.com/questions/16684856/rotating-a-2d-pixel-array-by-90-degrees | ||
// Normal array index rotated Y=0 - shape rotation Y=0 (xform below) | ||
// int index = z * shape_size + x; | ||
// Array Index Rotated Y=-90 - must rotate shape Y=+90 (xform below) | ||
int index = shape_size - 1 - z + x * shape_size; | ||
|
||
// Set heights on local map, or adjacent maps if on the last row/col | ||
if (x < region_size && z < region_size) { | ||
map_data[index] = (Util::is_hole(cmap->get_pixel(x, z).r)) ? hole_const : map->get_pixel(x, z).r; | ||
} else if (x == region_size && z < region_size) { | ||
if (map_x.is_valid()) { | ||
map_data[index] = (Util::is_hole(cmap_x->get_pixel(0, z).r)) ? hole_const : map_x->get_pixel(0, z).r; | ||
PackedFloat32Array map_data; | ||
CollisionShape3D *debug_col_shape = nullptr; | ||
RID col_shape = RID(); | ||
if (_dynamic_collision && !_unused_collision_shapes.is_empty()) { | ||
if (!_show_debug_collision) { | ||
col_shape = _unused_collision_shapes.pop_back(); | ||
Dictionary shape_data = PhysicsServer3D::get_singleton()->shape_get_data(col_shape); | ||
map_data = shape_data["heights"]; | ||
} else { | ||
map_data[index] = 0.0f; | ||
debug_col_shape = Object::cast_to<CollisionShape3D>(_unused_collision_shapes.pop_back()); | ||
Ref<HeightMapShape3D> hshape = debug_col_shape->get_shape(); | ||
map_data = hshape->get_map_data(); | ||
} | ||
} else { | ||
map_data = PackedFloat32Array(); | ||
map_data.resize(shape_size * shape_size); | ||
} | ||
|
||
Ref<Image> map, map_x, map_z, map_xz; | ||
Ref<Image> cmap, cmap_x, cmap_z, cmap_xz; | ||
map = _storage->get_map_region(Terrain3DStorage::TYPE_HEIGHT, i); | ||
cmap = _storage->get_map_region(Terrain3DStorage::TYPE_CONTROL, i); | ||
int region = _storage->get_region_index(Vector3(global_pos.x + region_size, 0, global_pos.z)); | ||
if (region >= 0) { | ||
map_x = _storage->get_map_region(Terrain3DStorage::TYPE_HEIGHT, region); | ||
cmap_x = _storage->get_map_region(Terrain3DStorage::TYPE_CONTROL, region); | ||
} | ||
region = _storage->get_region_index(Vector3(global_pos.x, 0, global_pos.z + region_size)); | ||
if (region >= 0) { | ||
map_z = _storage->get_map_region(Terrain3DStorage::TYPE_HEIGHT, region); | ||
cmap_z = _storage->get_map_region(Terrain3DStorage::TYPE_CONTROL, region); | ||
} | ||
region = _storage->get_region_index(Vector3(global_pos.x + region_size, 0, global_pos.z + region_size)); | ||
if (region >= 0) { | ||
map_xz = _storage->get_map_region(Terrain3DStorage::TYPE_HEIGHT, region); | ||
cmap_xz = _storage->get_map_region(Terrain3DStorage::TYPE_CONTROL, region); | ||
} | ||
|
||
for (int z = 0; z < shape_size; z++) { | ||
for (int x = 0; x < shape_size; x++) { | ||
// Choose array indexing to match triangulation of heightmapshape with the mesh | ||
// https://stackoverflow.com/questions/16684856/rotating-a-2d-pixel-array-by-90-degrees | ||
// Normal array index rotated Y=0 - shape rotation Y=0 (xform below) | ||
// int index = z * shape_size + x; | ||
// Array Index Rotated Y=-90 - must rotate shape Y=+90 (xform below) | ||
int index = shape_size - 1 - z + x * shape_size; | ||
|
||
int shape_global_x = x + jx * collision_shape_size; | ||
int shape_global_z = z + jz * collision_shape_size; | ||
// Set heights on local map, or adjacent maps if on the last row/col | ||
if (shape_global_x < region_size && shape_global_z < region_size) { | ||
map_data[index] = (Util::is_hole(cmap->get_pixel(shape_global_x, shape_global_z).r)) ? hole_const : map->get_pixel(shape_global_x, shape_global_z).r; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As soon as I switched to Dynamic / Editor running the demo crashes on this line. The camera is outside of the terrain. The reason is: Region is currently -1, which means no region. So if region == -1 after line 427, you can skip all of the code down to L558 probably. Though you may want to disable that shape. That should allow shapes to be generated on the terrain if the player is near the sculpted regions, just not in the areas outside of that. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Adding this in L428 is sufficient to have it work. However I haven't looked yet to see if this properly disables the shapes or if it needs to do more.
|
||
} else if (shape_global_x == region_size && shape_global_z < region_size) { | ||
if (map_x.is_valid()) { | ||
map_data[index] = (Util::is_hole(cmap_x->get_pixel(0, shape_global_z).r)) ? hole_const : map_x->get_pixel(0, shape_global_z).r; | ||
} else { | ||
map_data[index] = 0.0f; | ||
} | ||
} else if (shape_global_z == region_size && shape_global_x < region_size) { | ||
if (map_z.is_valid()) { | ||
map_data[index] = (Util::is_hole(cmap_z->get_pixel(shape_global_x, 0).r)) ? hole_const : map_z->get_pixel(shape_global_x, 0).r; | ||
} else { | ||
map_data[index] = 0.0f; | ||
} | ||
} else if (shape_global_x == region_size && shape_global_z == region_size) { | ||
if (map_xz.is_valid()) { | ||
map_data[index] = (Util::is_hole(cmap_xz->get_pixel(0, 0).r)) ? hole_const : map_xz->get_pixel(0, 0).r; | ||
} else { | ||
map_data[index] = 0.0f; | ||
} | ||
} | ||
} | ||
} else if (z == region_size && x < region_size) { | ||
if (map_z.is_valid()) { | ||
map_data[index] = (Util::is_hole(cmap_z->get_pixel(x, 0).r)) ? hole_const : map_z->get_pixel(x, 0).r; | ||
} | ||
|
||
// Non rotated shape for normal array index above | ||
//Transform3D xform = Transform3D(Basis(), global_pos); | ||
// Rotated shape Y=90 for -90 rotated array index | ||
Transform3D xform = Transform3D(Basis(Vector3(0, 1.0, 0), Math_PI * .5), global_middle_pos); | ||
|
||
if (!_show_debug_collision) { | ||
if (_dynamic_collision && col_shape.is_valid()) { | ||
} else { | ||
map_data[index] = 0.0f; | ||
col_shape = PhysicsServer3D::get_singleton()->heightmap_shape_create(); | ||
Dictionary shape_data; | ||
shape_data["width"] = shape_size; | ||
shape_data["depth"] = shape_size; | ||
shape_data["heights"] = map_data; | ||
Vector2 min_max = _storage->get_height_range(); | ||
shape_data["min_height"] = min_max.x; | ||
shape_data["max_height"] = min_max.y; | ||
PhysicsServer3D::get_singleton()->shape_set_data(col_shape, shape_data); | ||
} | ||
} else if (x == region_size && z == region_size) { | ||
if (map_xz.is_valid()) { | ||
map_data[index] = (Util::is_hole(cmap_xz->get_pixel(0, 0).r)) ? hole_const : map_xz->get_pixel(0, 0).r; | ||
int shape_id = PhysicsServer3D::get_singleton()->body_get_shape_count(_static_body); | ||
PhysicsServer3D::get_singleton()->body_set_shape(_static_body, shape_id, col_shape); | ||
PhysicsServer3D::get_singleton()->body_set_shape_transform(_static_body, shape_id, xform); | ||
lw64 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
PhysicsServer3D::get_singleton()->body_set_collision_mask(_static_body, _collision_mask); | ||
PhysicsServer3D::get_singleton()->body_set_collision_layer(_static_body, _collision_layer); | ||
PhysicsServer3D::get_singleton()->body_set_collision_priority(_static_body, _collision_priority); | ||
} else { | ||
Ref<HeightMapShape3D> hshape; | ||
if (_dynamic_collision && debug_col_shape != nullptr) { | ||
hshape = debug_col_shape->get_shape(); | ||
lw64 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} else { | ||
map_data[index] = 0.0f; | ||
debug_col_shape = memnew(CollisionShape3D); | ||
debug_col_shape->set_name("CollisionShape3D"); | ||
hshape.instantiate(); | ||
hshape->set_map_width(shape_size); | ||
hshape->set_map_depth(shape_size); | ||
debug_col_shape->set_shape(hshape); | ||
} | ||
_debug_static_body->add_child(debug_col_shape, true); | ||
debug_col_shape->set_owner(this); | ||
hshape->set_map_data(map_data); | ||
debug_col_shape->set_global_transform(xform); | ||
_debug_static_body->set_collision_mask(_collision_mask); | ||
_debug_static_body->set_collision_layer(_collision_layer); | ||
_debug_static_body->set_collision_priority(_collision_priority); | ||
} | ||
} | ||
} | ||
|
||
// Non rotated shape for normal array index above | ||
//Transform3D xform = Transform3D(Basis(), global_pos); | ||
// Rotated shape Y=90 for -90 rotated array index | ||
Transform3D xform = Transform3D(Basis(Vector3(0, 1.0, 0), Math_PI * .5), | ||
global_pos + Vector3(region_size, 0, region_size) * .5); | ||
|
||
if (!_show_debug_collision) { | ||
RID shape = PhysicsServer3D::get_singleton()->heightmap_shape_create(); | ||
Dictionary shape_data; | ||
shape_data["width"] = shape_size; | ||
shape_data["depth"] = shape_size; | ||
shape_data["heights"] = map_data; | ||
Vector2 min_max = _storage->get_height_range(); | ||
shape_data["min_height"] = min_max.x; | ||
shape_data["max_height"] = min_max.y; | ||
PhysicsServer3D::get_singleton()->shape_set_data(shape, shape_data); | ||
PhysicsServer3D::get_singleton()->body_add_shape(_static_body, shape); | ||
PhysicsServer3D::get_singleton()->body_set_shape_transform(_static_body, i, xform); | ||
PhysicsServer3D::get_singleton()->body_set_collision_mask(_static_body, _collision_mask); | ||
PhysicsServer3D::get_singleton()->body_set_collision_layer(_static_body, _collision_layer); | ||
PhysicsServer3D::get_singleton()->body_set_collision_priority(_static_body, _collision_priority); | ||
} else { | ||
CollisionShape3D *debug_col_shape; | ||
debug_col_shape = memnew(CollisionShape3D); | ||
debug_col_shape->set_name("CollisionShape3D"); | ||
_debug_static_body->add_child(debug_col_shape, true); | ||
debug_col_shape->set_owner(this); | ||
|
||
Ref<HeightMapShape3D> hshape; | ||
hshape.instantiate(); | ||
hshape->set_map_width(shape_size); | ||
hshape->set_map_depth(shape_size); | ||
hshape->set_map_data(map_data); | ||
debug_col_shape->set_shape(hshape); | ||
debug_col_shape->set_global_transform(xform); | ||
_debug_static_body->set_collision_mask(_collision_mask); | ||
_debug_static_body->set_collision_layer(_collision_layer); | ||
_debug_static_body->set_collision_priority(_collision_priority); | ||
} | ||
} | ||
LOG(DEBUG, "Collision creation time: ", Time::get_singleton()->get_ticks_msec() - time, " ms"); | ||
} | ||
|
||
void Terrain3D::_destroy_collision() { | ||
if (_static_body.is_valid()) { | ||
LOG(INFO, "Freeing physics body"); | ||
RID shape = PhysicsServer3D::get_singleton()->body_get_shape(_static_body, 0); | ||
PhysicsServer3D::get_singleton()->free_rid(shape); | ||
for (int i = PhysicsServer3D::get_singleton()->body_get_shape_count(_static_body) - 1; i >= 0; i--) { | ||
RID shape = PhysicsServer3D::get_singleton()->body_get_shape(_static_body, i); | ||
PhysicsServer3D::get_singleton()->free_rid(shape); | ||
} | ||
PhysicsServer3D::get_singleton()->free_rid(_static_body); | ||
_static_body = RID(); | ||
|
||
for (int i = _unused_collision_shapes.size() - 1; i >= 0; i--) { | ||
PhysicsServer3D::get_singleton()->free_rid(_unused_collision_shapes.pop_at(i)); | ||
} | ||
} | ||
|
||
if (_debug_static_body != nullptr) { | ||
|
@@ -421,6 +499,12 @@ void Terrain3D::_destroy_collision() { | |
memfree(child); | ||
} | ||
|
||
for (int i = _unused_collision_shapes.size() - 1; i >= 0; i--) { | ||
Node *child = Object::cast_to<Node>(_unused_collision_shapes.pop_at(i)); | ||
LOG(DEBUG, "Freeing cached dsb child ", i, " ", child->get_name()); | ||
memfree(child); | ||
} | ||
|
||
LOG(DEBUG, "Freeing static body"); | ||
remove_child(_debug_static_body); | ||
memfree(_debug_static_body); | ||
|
@@ -693,6 +777,24 @@ void Terrain3D::set_show_debug_collision(bool p_enabled) { | |
} | ||
} | ||
|
||
void Terrain3D::set_dynamic_collision(bool p_enabled) { | ||
LOG(INFO, "Setting dynamic collision: ", p_enabled); | ||
_dynamic_collision = p_enabled; | ||
_update_collision(); | ||
} | ||
|
||
void Terrain3D::set_collision_dynamic_shape_size(int size) { | ||
LOG(INFO, "Setting collision dynamic shape size: ", size); | ||
_collision_dynamic_shape_size = size; | ||
_update_collision(); | ||
} | ||
|
||
void Terrain3D::set_collision_dynamic_distance(float distance) { | ||
LOG(INFO, "Setting collision dynamic distance: ", distance); | ||
_collision_dynamic_distance = distance; | ||
_update_collision(); | ||
} | ||
|
||
/** | ||
* Centers the terrain and LODs on a provided position. Y height is ignored. | ||
*/ | ||
|
@@ -769,6 +871,10 @@ void Terrain3D::snap(Vector3 p_cam_pos) { | |
edge++; | ||
} | ||
} | ||
|
||
if (_dynamic_collision) { | ||
_update_collision(); | ||
} | ||
} | ||
|
||
void Terrain3D::update_aabbs() { | ||
|
@@ -1045,12 +1151,18 @@ void Terrain3D::_bind_methods() { | |
ClassDB::bind_method(D_METHOD("get_collision_enabled"), &Terrain3D::get_collision_enabled); | ||
ClassDB::bind_method(D_METHOD("set_show_debug_collision", "enabled"), &Terrain3D::set_show_debug_collision); | ||
ClassDB::bind_method(D_METHOD("get_show_debug_collision"), &Terrain3D::get_show_debug_collision); | ||
ClassDB::bind_method(D_METHOD("set_dynamic_collision", "enabled"), &Terrain3D::set_dynamic_collision); | ||
ClassDB::bind_method(D_METHOD("get_dynamic_collision"), &Terrain3D::get_dynamic_collision); | ||
ClassDB::bind_method(D_METHOD("set_collision_layer", "layers"), &Terrain3D::set_collision_layer); | ||
ClassDB::bind_method(D_METHOD("get_collision_layer"), &Terrain3D::get_collision_layer); | ||
ClassDB::bind_method(D_METHOD("set_collision_mask", "mask"), &Terrain3D::set_collision_mask); | ||
ClassDB::bind_method(D_METHOD("get_collision_mask"), &Terrain3D::get_collision_mask); | ||
ClassDB::bind_method(D_METHOD("set_collision_priority", "priority"), &Terrain3D::set_collision_priority); | ||
ClassDB::bind_method(D_METHOD("get_collision_priority"), &Terrain3D::get_collision_priority); | ||
ClassDB::bind_method(D_METHOD("set_collision_dynamic_shape_size", "size"), &Terrain3D::set_collision_dynamic_shape_size); | ||
ClassDB::bind_method(D_METHOD("get_collision_dynamic_shape_size"), &Terrain3D::get_collision_dynamic_shape_size); | ||
ClassDB::bind_method(D_METHOD("set_collision_dynamic_distance", "distance"), &Terrain3D::set_collision_dynamic_distance); | ||
ClassDB::bind_method(D_METHOD("get_collision_dynamic_distance"), &Terrain3D::get_collision_dynamic_distance); | ||
|
||
// Utility functions | ||
ClassDB::bind_static_method("Terrain3D", D_METHOD("get_min_max", "image"), &Util::get_min_max); | ||
|
@@ -1075,9 +1187,12 @@ void Terrain3D::_bind_methods() { | |
|
||
ADD_GROUP("Collision", "collision_"); | ||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collision_enabled"), "set_collision_enabled", "get_collision_enabled"); | ||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "dynamic_collision"), "set_dynamic_collision", "get_dynamic_collision"); | ||
lw64 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_layer", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_layer", "get_collision_layer"); | ||
ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_mask", "get_collision_mask"); | ||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "collision_priority"), "set_collision_priority", "get_collision_priority"); | ||
ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_dynamic_shape_size"), "set_collision_dynamic_shape_size", "get_collision_dynamic_shape_size"); | ||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "collision_dynamic_distance"), "set_collision_dynamic_distance", "get_collision_dynamic_distance"); | ||
|
||
ADD_GROUP("Mesh", "mesh_"); | ||
ADD_PROPERTY(PropertyInfo(Variant::INT, "mesh_lods", PROPERTY_HINT_RANGE, "1,10,1"), "set_mesh_lods", "get_mesh_lods"); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not entirely sure this avoids allocations. But I also don't see another method. the map_data gets assigned back later again.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The allocations and deallocations we want to avoid in update_collision are
memnew
andmemfree
. Creating a PackedFloat32Array here is fine. This gets created on the stack which is designed for frequent, rapid creation/destruction. The other two allocate memory on the heap, which should not be as frequent.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Which other two?
Dictionary
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By other two, I mean the general usage of memnew and memfree. Not referring to lines specifically.