-
Notifications
You must be signed in to change notification settings - Fork 131
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
Navmesh baking optimization #451
base: main
Are you sure you want to change the base?
Conversation
… though it doesn't make a big difference here), avoid 6 control map lookups when generating triangles if p_require_nav is false, and 2 lookups if true.
…d casting them to Image*, instead of wrapping in a godot::Ref.
return nullptr; | ||
} | ||
} | ||
|
||
Ref<Image> Terrain3DStorage::get_map_region(const MapType p_map_type, const int p_region_index) const { |
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.
Why not remove the code redundancy by having this function call the other?
This builds, but I didn't test it. And it could be done inline.
Image *Terrain3DStorage::_get_map_region_ptr(const MapType p_map_type, const int p_region_index) const {
return (Image *)&(_height_maps[p_region_index]);
}
Ref<Image> Terrain3DStorage::get_map_region(const MapType p_map_type, const int p_region_index) const {
return _get_map_region_ptr(p_map_type, p_region_index);
}
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.
Mainly because I am not entirely sure yet what my version does. Having one function call the other might mean having a redundant cast (not that big a deal, since it should really only be for calls from outside the extension), or messing up the reference counting somehow (pretty big deal, seems kinda unlikely, not 100% sure).
get_map_region has been dropped. You can see here in set/get_pixel how the general API focus is changing towards selecting regions by location (fixed) rather than ids (mutable) and working with Regions. So the ptr function probably needs to be moved to Terrain3DRegion. 6d77480#diff-f5a6479fa5fc2f89383edd16b70ed900e9b288af17f42366f3ac1bdb5a19306a Although we are keeping the typedarrays referenced by ID, which are updated by update_maps, and then sent to the shader. So if more optimal we could undo these changes to set/get_pixel and reference the maps directly bypassing regions and refs. Read the comments here Terrain3D/src/terrain_3d_storage.h Lines 48 to 79 in 6d77480
I'd recommend just waiting until I finish my PR before spending any more time on it, but wanted to share the information to get you thinking about it. |
Now that my PRs are merged in, let's revisit this and look at optimizing set_pixel, get_pixel and refs. |
This PR should cut down navigation mesh baking time by about half. Terrain3D::_generate_triangle_pair uses fewer control map lookups (-6 when p_require_nav is false, -2 if true), and Terrain3DStorage::get_pixel uses a modified private version of get_map_region that returns an Image* and skips converting it to a godot::Ref, reducing the time spent on get_pixel by about 1/3rd. This is based on the assumption that nobody will put anything other than godot::Image in the height/control/color map arrays, which should be true because they're TypedArrays and they're not directly accessible from outside the extension.
The modified version of get_map_region introduces some code duplication, and it might be good to use this modified version in other places where a Ref really isn't needed, so this PR isn't as clean as it perhaps could've been. I'm personally unlikely to even use it in my project, as it should be much faster to just directly sample the physics shapes I'm making, which can also be generated in a thread, unlike Terrain3D.