Merge pull request #55096 from lawnjelly/bvh_expanded_leaf
BVH - add option for expanded AABBs in leaves
This commit is contained in:
commit
3970f28f67
10 changed files with 74 additions and 1 deletions
|
@ -704,6 +704,11 @@ private:
|
|||
// Note that non pairable items can pair with pairable,
|
||||
// so all types must be added to the list
|
||||
|
||||
#ifdef BVH_EXPAND_LEAF_AABBS
|
||||
// if using expanded AABB in the leaf, the redundancy check will already have been made
|
||||
BOUNDS &expanded_aabb = tree._pairs[p_handle.id()].expanded_aabb;
|
||||
item_get_AABB(p_handle, expanded_aabb);
|
||||
#else
|
||||
// aabb check with expanded aabb. This greatly decreases processing
|
||||
// at the cost of slightly less accurate pairing checks
|
||||
// Note this pairing AABB is separate from the AABB in the actual tree
|
||||
|
@ -720,6 +725,7 @@ private:
|
|||
// this tick, because it is vital that the AABB is kept up to date
|
||||
expanded_aabb = aabb;
|
||||
expanded_aabb.grow_by(tree._pairing_expansion);
|
||||
#endif
|
||||
|
||||
// this code is to ensure that changed items only appear once on the updated list
|
||||
// collision checking them multiple times is not needed, and repeats the same thing
|
||||
|
|
|
@ -59,4 +59,14 @@ struct ItemPairs {
|
|||
|
||||
return userdata;
|
||||
}
|
||||
|
||||
// experiment : scale the pairing expansion by the number of pairs.
|
||||
// when the number of pairs is high, the density is high and a lower collision margin is better.
|
||||
// when there are few local pairs, a larger margin is more optimal.
|
||||
real_t scale_expansion_margin(real_t p_margin) const {
|
||||
real_t x = real_t(num_pairs) * (1.0 / 9.0);
|
||||
x = MIN(x, 1.0);
|
||||
x = 1.0 - x;
|
||||
return p_margin * x;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -9,6 +9,13 @@ BVHHandle item_add(T *p_userdata, bool p_active, const BOUNDS &p_aabb, int32_t p
|
|||
BVHABB_CLASS abb;
|
||||
abb.from(p_aabb);
|
||||
|
||||
// NOTE that we do not expand the AABB for the first create even if
|
||||
// leaf expansion is switched on. This is for two reasons:
|
||||
// (1) We don't know if this object will move in future, in which case a non-expanded
|
||||
// bound would be better...
|
||||
// (2) We don't yet know how many objects will be paired, which is used to modify
|
||||
// the expansion margin.
|
||||
|
||||
// handle to be filled with the new item ref
|
||||
BVHHandle handle;
|
||||
|
||||
|
@ -115,6 +122,15 @@ bool item_move(BVHHandle p_handle, const BOUNDS &p_aabb) {
|
|||
BVHABB_CLASS abb;
|
||||
abb.from(p_aabb);
|
||||
|
||||
#ifdef BVH_EXPAND_LEAF_AABBS
|
||||
if (USE_PAIRS) {
|
||||
// scale the pairing expansion by the number of pairs.
|
||||
abb.expand(_pairs[ref_id].scale_expansion_margin(_pairing_expansion));
|
||||
} else {
|
||||
abb.expand(_pairing_expansion);
|
||||
}
|
||||
#endif
|
||||
|
||||
BVH_ASSERT(ref.tnode_id != BVHCommon::INVALID);
|
||||
TNode &tnode = _nodes[ref.tnode_id];
|
||||
|
||||
|
@ -129,9 +145,20 @@ bool item_move(BVHHandle p_handle, const BOUNDS &p_aabb) {
|
|||
BVHABB_CLASS &leaf_abb = leaf.get_aabb(ref.item_id);
|
||||
|
||||
// no change?
|
||||
#ifdef BVH_EXPAND_LEAF_AABBS
|
||||
BOUNDS leaf_aabb;
|
||||
leaf_abb.to(leaf_aabb);
|
||||
|
||||
// This test should pass in a lot of cases, and by returning false we can avoid
|
||||
// collision pairing checks later, which greatly reduces processing.
|
||||
if (expanded_aabb_encloses_not_shrink(leaf_aabb, p_aabb)) {
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
if (leaf_abb == abb) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BVH_VERBOSE_MOVES
|
||||
print_line("item_move " + itos(p_handle.id()) + "(within tnode aabb) : " + _debug_aabb_to_string(abb));
|
||||
|
|
|
@ -50,6 +50,9 @@
|
|||
|
||||
#define BVHABB_CLASS BVH_ABB<BOUNDS, POINT>
|
||||
|
||||
// not sure if this is better yet so making optional
|
||||
#define BVH_EXPAND_LEAF_AABBS
|
||||
|
||||
// never do these checks in release
|
||||
#if defined(TOOLS_ENABLED) && defined(DEBUG_ENABLED)
|
||||
//#define BVH_VERBOSE
|
||||
|
|
|
@ -1030,6 +1030,11 @@
|
|||
Size of the hash table used for the broad-phase 2D hash grid algorithm.
|
||||
[b]Note:[/b] Not used if [member ProjectSettings.physics/2d/use_bvh] is enabled.
|
||||
</member>
|
||||
<member name="physics/2d/bvh_collision_margin" type="float" setter="" getter="" default="1.0">
|
||||
Additional expansion applied to object bounds in the 2D physics bounding volume hierarchy. This can reduce BVH processing at the cost of a slightly coarser broadphase, which can stress the physics more in some situations.
|
||||
The default value will work well in most situations. A value of 0.0 will turn this optimization off, and larger values may work better for larger, faster moving objects.
|
||||
[b]Note:[/b] Used only if [member ProjectSettings.physics/2d/use_bvh] is enabled.
|
||||
</member>
|
||||
<member name="physics/2d/cell_size" type="int" setter="" getter="" default="128">
|
||||
Cell size used for the broad-phase 2D hash grid algorithm (in pixels).
|
||||
[b]Note:[/b] Not used if [member ProjectSettings.physics/2d/use_bvh] is enabled.
|
||||
|
@ -1109,6 +1114,11 @@
|
|||
The default linear damp in 3D.
|
||||
[b]Note:[/b] Good values are in the range [code]0[/code] to [code]1[/code]. At value [code]0[/code] objects will keep moving with the same velocity. Values greater than [code]1[/code] will aim to reduce the velocity to [code]0[/code] in less than a second e.g. a value of [code]2[/code] will aim to reduce the velocity to [code]0[/code] in half a second. A value equal to or greater than the physics frame rate ([member ProjectSettings.physics/common/physics_fps], [code]60[/code] by default) will bring the object to a stop in one iteration.
|
||||
</member>
|
||||
<member name="physics/3d/godot_physics/bvh_collision_margin" type="float" setter="" getter="" default="0.1">
|
||||
Additional expansion applied to object bounds in the 3D physics bounding volume hierarchy. This can reduce BVH processing at the cost of a slightly coarser broadphase, which can stress the physics more in some situations.
|
||||
The default value will work well in most situations. A value of 0.0 will turn this optimization off, and larger values may work better for larger, faster moving objects.
|
||||
[b]Note:[/b] Used only if [member ProjectSettings.physics/3d/godot_physics/use_bvh] is enabled.
|
||||
</member>
|
||||
<member name="physics/3d/godot_physics/use_bvh" type="bool" setter="" getter="" default="true">
|
||||
Enables the use of bounding volume hierarchy instead of octree for 3D physics spatial partitioning. This may give better performance.
|
||||
</member>
|
||||
|
@ -1477,9 +1487,15 @@
|
|||
See also [member rendering/quality/skinning/force_software_skinning].
|
||||
[b]Note:[/b] When the software skinning fallback is triggered, custom vertex shaders will behave in a different way, because the bone transform will be already applied to the modelview matrix.
|
||||
</member>
|
||||
<member name="rendering/quality/spatial_partitioning/bvh_collision_margin" type="float" setter="" getter="" default="0.1">
|
||||
Additional expansion applied to object bounds in the 3D rendering bounding volume hierarchy. This can reduce BVH processing at the cost of a slightly reduced accuracy.
|
||||
The default value will work well in most situations. A value of 0.0 will turn this optimization off, and larger values may work better for larger, faster moving objects.
|
||||
[b]Note:[/b] Used only if [member ProjectSettings.rendering/quality/spatial_partitioning/use_bvh] is enabled.
|
||||
</member>
|
||||
<member name="rendering/quality/spatial_partitioning/render_tree_balance" type="float" setter="" getter="" default="0.0">
|
||||
The rendering octree balance can be changed to favor smaller ([code]0[/code]), or larger ([code]1[/code]) branches.
|
||||
Larger branches can increase performance significantly in some projects.
|
||||
[b]Note:[/b] Not used if [member ProjectSettings.rendering/quality/spatial_partitioning/use_bvh] is enabled.
|
||||
</member>
|
||||
<member name="rendering/quality/spatial_partitioning/use_bvh" type="bool" setter="" getter="" default="true">
|
||||
Enables the use of bounding volume hierarchy instead of octree for rendering spatial partitioning. This may give better performance.
|
||||
|
|
|
@ -176,8 +176,11 @@ static String get_full_version_string() {
|
|||
// FIXME: Could maybe be moved to PhysicsServerManager and Physics2DServerManager directly
|
||||
// to have less code in main.cpp.
|
||||
void initialize_physics() {
|
||||
// This must be defined BEFORE the 3d physics server is created
|
||||
// This must be defined BEFORE the 3d physics server is created,
|
||||
// otherwise it won't always show up in the project settings page.
|
||||
GLOBAL_DEF("physics/3d/godot_physics/use_bvh", true);
|
||||
GLOBAL_DEF("physics/3d/godot_physics/bvh_collision_margin", 0.1);
|
||||
ProjectSettings::get_singleton()->set_custom_property_info("physics/3d/godot_physics/bvh_collision_margin", PropertyInfo(Variant::REAL, "physics/3d/godot_physics/bvh_collision_margin", PROPERTY_HINT_RANGE, "0.0,2.0,0.01"));
|
||||
|
||||
/// 3D Physics Server
|
||||
physics_server = PhysicsServerManager::new_server(ProjectSettings::get_singleton()->get(PhysicsServerManager::setting_property_name));
|
||||
|
|
|
@ -127,6 +127,7 @@ BroadPhaseSW *BroadPhaseBVH::_create() {
|
|||
|
||||
BroadPhaseBVH::BroadPhaseBVH() {
|
||||
bvh.params_set_thread_safe(GLOBAL_GET("rendering/threads/thread_safe_bvh"));
|
||||
bvh.params_set_pairing_expansion(GLOBAL_GET("physics/3d/godot_physics/bvh_collision_margin"));
|
||||
bvh.set_pair_callback(_pair_callback, this);
|
||||
bvh.set_unpair_callback(_unpair_callback, this);
|
||||
bvh.set_check_pair_callback(_check_pair_callback, this);
|
||||
|
|
|
@ -123,6 +123,7 @@ BroadPhase2DSW *BroadPhase2DBVH::_create() {
|
|||
|
||||
BroadPhase2DBVH::BroadPhase2DBVH() {
|
||||
bvh.params_set_thread_safe(GLOBAL_GET("rendering/threads/thread_safe_bvh"));
|
||||
bvh.params_set_pairing_expansion(GLOBAL_GET("physics/2d/bvh_collision_margin"));
|
||||
bvh.set_pair_callback(_pair_callback, this);
|
||||
bvh.set_unpair_callback(_unpair_callback, this);
|
||||
bvh.set_check_pair_callback(_check_pair_callback, this);
|
||||
|
|
|
@ -1317,6 +1317,8 @@ Physics2DServerSW::Physics2DServerSW() {
|
|||
GLOBAL_DEF("physics/2d/bp_hash_table_size", 4096);
|
||||
GLOBAL_DEF("physics/2d/cell_size", 128);
|
||||
GLOBAL_DEF("physics/2d/large_object_surface_threshold_in_cells", 512);
|
||||
GLOBAL_DEF("physics/2d/bvh_collision_margin", 1.0);
|
||||
ProjectSettings::get_singleton()->set_custom_property_info("physics/2d/bvh_collision_margin", PropertyInfo(Variant::REAL, "physics/2d/bvh_collision_margin", PROPERTY_HINT_RANGE, "0.0,20.0,0.1"));
|
||||
|
||||
bool use_bvh = GLOBAL_GET("physics/2d/use_bvh");
|
||||
|
||||
|
|
|
@ -100,6 +100,7 @@ void VisualServerScene::camera_set_use_vertical_aspect(RID p_camera, bool p_enab
|
|||
|
||||
VisualServerScene::SpatialPartitioningScene_BVH::SpatialPartitioningScene_BVH() {
|
||||
_bvh.params_set_thread_safe(GLOBAL_GET("rendering/threads/thread_safe_bvh"));
|
||||
_bvh.params_set_pairing_expansion(GLOBAL_GET("rendering/quality/spatial_partitioning/bvh_collision_margin"));
|
||||
}
|
||||
|
||||
VisualServerScene::SpatialPartitionID VisualServerScene::SpatialPartitioningScene_BVH::create(Instance *p_userdata, const AABB &p_aabb, int p_subindex, bool p_pairable, uint32_t p_pairable_type, uint32_t p_pairable_mask) {
|
||||
|
@ -4119,6 +4120,9 @@ VisualServerScene::VisualServerScene() {
|
|||
render_pass = 1;
|
||||
singleton = this;
|
||||
_use_bvh = GLOBAL_DEF("rendering/quality/spatial_partitioning/use_bvh", true);
|
||||
GLOBAL_DEF("rendering/quality/spatial_partitioning/bvh_collision_margin", 0.1);
|
||||
ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/spatial_partitioning/bvh_collision_margin", PropertyInfo(Variant::REAL, "rendering/quality/spatial_partitioning/bvh_collision_margin", PROPERTY_HINT_RANGE, "0.0,2.0,0.01"));
|
||||
|
||||
_visual_server_callbacks = nullptr;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue