diff options
Diffstat (limited to 'modules/raycast')
-rw-r--r-- | modules/raycast/lightmap_raycaster.cpp | 10 | ||||
-rw-r--r-- | modules/raycast/lightmap_raycaster.h | 8 | ||||
-rw-r--r-- | modules/raycast/raycast_occlusion_cull.cpp | 72 | ||||
-rw-r--r-- | modules/raycast/raycast_occlusion_cull.h | 35 | ||||
-rw-r--r-- | modules/raycast/register_types.cpp | 12 | ||||
-rw-r--r-- | modules/raycast/register_types.h | 6 | ||||
-rw-r--r-- | modules/raycast/static_raycaster.cpp | 10 | ||||
-rw-r--r-- | modules/raycast/static_raycaster.h | 6 |
8 files changed, 88 insertions, 71 deletions
diff --git a/modules/raycast/lightmap_raycaster.cpp b/modules/raycast/lightmap_raycaster.cpp index ecc256bff9..9b35b5616e 100644 --- a/modules/raycast/lightmap_raycaster.cpp +++ b/modules/raycast/lightmap_raycaster.cpp @@ -152,17 +152,17 @@ void LightmapRaycasterEmbree::commit() { rtcCommitScene(embree_scene); } -void LightmapRaycasterEmbree::set_mesh_filter(const Set<int> &p_mesh_ids) { - for (Set<int>::Element *E = p_mesh_ids.front(); E; E = E->next()) { - rtcDisableGeometry(rtcGetGeometry(embree_scene, E->get())); +void LightmapRaycasterEmbree::set_mesh_filter(const HashSet<int> &p_mesh_ids) { + for (const int &E : p_mesh_ids) { + rtcDisableGeometry(rtcGetGeometry(embree_scene, E)); } rtcCommitScene(embree_scene); filter_meshes = p_mesh_ids; } void LightmapRaycasterEmbree::clear_mesh_filter() { - for (Set<int>::Element *E = filter_meshes.front(); E; E = E->next()) { - rtcEnableGeometry(rtcGetGeometry(embree_scene, E->get())); + for (const int &E : filter_meshes) { + rtcEnableGeometry(rtcGetGeometry(embree_scene, E)); } rtcCommitScene(embree_scene); filter_meshes.clear(); diff --git a/modules/raycast/lightmap_raycaster.h b/modules/raycast/lightmap_raycaster.h index c420e617e5..2e9f59dda4 100644 --- a/modules/raycast/lightmap_raycaster.h +++ b/modules/raycast/lightmap_raycaster.h @@ -52,8 +52,8 @@ private: static void filter_function(const struct RTCFilterFunctionNArguments *p_args); - Map<unsigned int, AlphaTextureData> alpha_textures; - Set<int> filter_meshes; + HashMap<unsigned int, AlphaTextureData> alpha_textures; + HashSet<int> filter_meshes; public: virtual bool intersect(Ray &p_ray) override; @@ -64,7 +64,7 @@ public: virtual void set_mesh_alpha_texture(Ref<Image> p_alpha_texture, unsigned int p_id) override; virtual void commit() override; - virtual void set_mesh_filter(const Set<int> &p_mesh_ids) override; + virtual void set_mesh_filter(const HashSet<int> &p_mesh_ids) override; virtual void clear_mesh_filter() override; static LightmapRaycaster *create_embree_raycaster(); @@ -74,4 +74,4 @@ public: ~LightmapRaycasterEmbree(); }; -#endif +#endif // LIGHTMAP_RAYCASTER_H diff --git a/modules/raycast/raycast_occlusion_cull.cpp b/modules/raycast/raycast_occlusion_cull.cpp index 2e0d17fb28..13824c3830 100644 --- a/modules/raycast/raycast_occlusion_cull.cpp +++ b/modules/raycast/raycast_occlusion_cull.cpp @@ -30,6 +30,7 @@ #include "raycast_occlusion_cull.h" #include "core/config/project_settings.h" +#include "core/object/worker_thread_pool.h" #include "core/templates/local_vector.h" #ifdef __SSE2__ @@ -78,17 +79,17 @@ void RaycastOcclusionCull::RaycastHZBuffer::resize(const Size2i &p_size) { memset(camera_ray_masks.ptr(), ~0, camera_rays_tile_count * TILE_RAYS * sizeof(uint32_t)); } -void RaycastOcclusionCull::RaycastHZBuffer::update_camera_rays(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, ThreadWorkPool &p_thread_work_pool) { +void RaycastOcclusionCull::RaycastHZBuffer::update_camera_rays(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal) { CameraRayThreadData td; - td.thread_count = p_thread_work_pool.get_thread_count(); + td.thread_count = WorkerThreadPool::get_singleton()->get_thread_count(); td.z_near = p_cam_projection.get_z_near(); td.z_far = p_cam_projection.get_z_far() * 1.05f; td.camera_pos = p_cam_transform.origin; - td.camera_dir = -p_cam_transform.basis.get_axis(2); + td.camera_dir = -p_cam_transform.basis.get_column(2); td.camera_orthogonal = p_cam_orthogonal; - CameraMatrix inv_camera_matrix = p_cam_projection.inverse(); + Projection inv_camera_matrix = p_cam_projection.inverse(); Vector3 camera_corner_proj = Vector3(-1.0f, -1.0f, -1.0f); Vector3 camera_corner_view = inv_camera_matrix.xform(camera_corner_proj); td.pixel_corner = p_cam_transform.xform(camera_corner_view); @@ -106,7 +107,8 @@ void RaycastOcclusionCull::RaycastHZBuffer::update_camera_rays(const Transform3D debug_tex_range = td.z_far; - p_thread_work_pool.do_work(td.thread_count, this, &RaycastHZBuffer::_camera_rays_threaded, &td); + WorkerThreadPool::GroupID group_task = WorkerThreadPool::get_singleton()->add_template_group_task(this, &RaycastHZBuffer::_camera_rays_threaded, &td, td.thread_count, -1, true, SNAME("RaycastOcclusionCullUpdateCamera")); + WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group_task); } void RaycastOcclusionCull::RaycastHZBuffer::_camera_rays_threaded(uint32_t p_thread, const CameraRayThreadData *p_data) { @@ -223,9 +225,9 @@ void RaycastOcclusionCull::occluder_set_mesh(RID p_occluder, const PackedVector3 occluder->vertices = p_vertices; occluder->indices = p_indices; - for (Set<InstanceID>::Element *E = occluder->users.front(); E; E = E->next()) { - RID scenario_rid = E->get().scenario; - RID instance_rid = E->get().instance; + for (const InstanceID &E : occluder->users) { + RID scenario_rid = E.scenario; + RID instance_rid = E.instance; ERR_CONTINUE(!scenarios.has(scenario_rid)); Scenario &scenario = scenarios[scenario_rid]; ERR_CONTINUE(!scenario.instances.has(instance_rid)); @@ -331,10 +333,10 @@ void RaycastOcclusionCull::scenario_remove_instance(RID p_scenario, RID p_instan } void RaycastOcclusionCull::Scenario::_update_dirty_instance_thread(int p_idx, RID *p_instances) { - _update_dirty_instance(p_idx, p_instances, nullptr); + _update_dirty_instance(p_idx, p_instances); } -void RaycastOcclusionCull::Scenario::_update_dirty_instance(int p_idx, RID *p_instances, ThreadWorkPool *p_thread_pool) { +void RaycastOcclusionCull::Scenario::_update_dirty_instance(int p_idx, RID *p_instances) { OccluderInstance *occ_inst = instances.getptr(p_instances[p_idx]); if (!occ_inst) { @@ -355,14 +357,16 @@ void RaycastOcclusionCull::Scenario::_update_dirty_instance(int p_idx, RID *p_in const Vector3 *read_ptr = occ->vertices.ptr(); Vector3 *write_ptr = occ_inst->xformed_vertices.ptr(); - if (p_thread_pool && vertices_size > 1024) { + if (vertices_size > 1024) { TransformThreadData td; td.xform = occ_inst->xform; td.read = read_ptr; td.write = write_ptr; td.vertex_count = vertices_size; - td.thread_count = p_thread_pool->get_thread_count(); - p_thread_pool->do_work(td.thread_count, this, &Scenario::_transform_vertices_thread, &td); + td.thread_count = WorkerThreadPool::get_singleton()->get_thread_count(); + WorkerThreadPool::GroupID group_task = WorkerThreadPool::get_singleton()->add_template_group_task(this, &Scenario::_transform_vertices_thread, &td, td.thread_count, -1, true, SNAME("RaycastOcclusionCull")); + WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group_task); + } else { _transform_vertices_range(read_ptr, write_ptr, occ_inst->xform, 0, vertices_size); } @@ -392,7 +396,7 @@ void RaycastOcclusionCull::Scenario::_commit_scene(void *p_ud) { scenario->commit_done = true; } -bool RaycastOcclusionCull::Scenario::update(ThreadWorkPool &p_thread_pool) { +bool RaycastOcclusionCull::Scenario::update() { ERR_FAIL_COND_V(singleton == nullptr, false); if (commit_thread == nullptr) { @@ -426,13 +430,15 @@ bool RaycastOcclusionCull::Scenario::update(ThreadWorkPool &p_thread_pool) { instances.erase(removed_instances[i]); } - if (dirty_instances_array.size() / p_thread_pool.get_thread_count() > 128) { + if (dirty_instances_array.size() / WorkerThreadPool::get_singleton()->get_thread_count() > 128) { // Lots of instances, use per-instance threading - p_thread_pool.do_work(dirty_instances_array.size(), this, &Scenario::_update_dirty_instance_thread, dirty_instances_array.ptr()); + WorkerThreadPool::GroupID group_task = WorkerThreadPool::get_singleton()->add_template_group_task(this, &Scenario::_update_dirty_instance_thread, dirty_instances_array.ptr(), dirty_instances_array.size(), -1, true, SNAME("RaycastOcclusionCullUpdate")); + WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group_task); + } else { // Few instances, use threading on the vertex transforms for (unsigned int i = 0; i < dirty_instances_array.size(); i++) { - _update_dirty_instance(i, dirty_instances_array.ptr(), &p_thread_pool); + _update_dirty_instance(i, dirty_instances_array.ptr()); } } @@ -454,10 +460,9 @@ bool RaycastOcclusionCull::Scenario::update(ThreadWorkPool &p_thread_pool) { next_scene = rtcNewScene(raycast_singleton->ebr_device); rtcSetSceneBuildQuality(next_scene, RTCBuildQuality(raycast_singleton->build_quality)); - const RID *inst_rid = nullptr; - while ((inst_rid = instances.next(inst_rid))) { - OccluderInstance *occ_inst = instances.getptr(*inst_rid); - Occluder *occ = raycast_singleton->occluder_owner.get_or_null(occ_inst->occluder); + for (const KeyValue<RID, OccluderInstance> &E : instances) { + const OccluderInstance *occ_inst = &E.value; + const Occluder *occ = raycast_singleton->occluder_owner.get_or_null(occ_inst->occluder); if (!occ || !occ_inst->enabled) { continue; @@ -485,7 +490,7 @@ void RaycastOcclusionCull::Scenario::_raycast(uint32_t p_idx, const RaycastThrea rtcIntersect16((const int *)&p_raycast_data->masks[p_idx * TILE_RAYS], ebr_scene[current_scene_idx], &ctx, &p_raycast_data->rays[p_idx]); } -void RaycastOcclusionCull::Scenario::raycast(CameraRayTile *r_rays, const uint32_t *p_valid_masks, uint32_t p_tile_count, ThreadWorkPool &p_thread_pool) const { +void RaycastOcclusionCull::Scenario::raycast(CameraRayTile *r_rays, const uint32_t *p_valid_masks, uint32_t p_tile_count) const { ERR_FAIL_COND(singleton == nullptr); if (raycast_singleton->ebr_device == nullptr) { return; // Embree is initialized on demand when there is some scenario with occluders in it. @@ -499,7 +504,8 @@ void RaycastOcclusionCull::Scenario::raycast(CameraRayTile *r_rays, const uint32 td.rays = r_rays; td.masks = p_valid_masks; - p_thread_pool.do_work(p_tile_count, this, &Scenario::_raycast, &td); + WorkerThreadPool::GroupID group_task = WorkerThreadPool::get_singleton()->add_template_group_task(this, &Scenario::_raycast, &td, p_tile_count, -1, true, SNAME("RaycastOcclusionCullRaycast")); + WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group_task); } //////////////////////////////////////////////////////// @@ -525,7 +531,7 @@ void RaycastOcclusionCull::buffer_set_size(RID p_buffer, const Vector2i &p_size) buffers[p_buffer].resize(p_size); } -void RaycastOcclusionCull::buffer_update(RID p_buffer, const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, ThreadWorkPool &p_thread_pool) { +void RaycastOcclusionCull::buffer_update(RID p_buffer, const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal) { if (!buffers.has(p_buffer)) { return; } @@ -538,17 +544,17 @@ void RaycastOcclusionCull::buffer_update(RID p_buffer, const Transform3D &p_cam_ Scenario &scenario = scenarios[buffer.scenario_rid]; - bool removed = scenario.update(p_thread_pool); + bool removed = scenario.update(); if (removed) { scenarios.erase(buffer.scenario_rid); return; } - buffer.update_camera_rays(p_cam_transform, p_cam_projection, p_cam_orthogonal, p_thread_pool); + buffer.update_camera_rays(p_cam_transform, p_cam_projection, p_cam_orthogonal); - scenario.raycast(buffer.camera_rays, buffer.camera_ray_masks.ptr(), buffer.camera_rays_tile_count, p_thread_pool); - buffer.sort_rays(-p_cam_transform.basis.get_axis(2), p_cam_orthogonal); + scenario.raycast(buffer.camera_rays, buffer.camera_ray_masks.ptr(), buffer.camera_rays_tile_count); + buffer.sort_rays(-p_cam_transform.basis.get_column(2), p_cam_orthogonal); buffer.update_mips(); } @@ -573,9 +579,8 @@ void RaycastOcclusionCull::set_build_quality(RS::ViewportOcclusionCullingBuildQu build_quality = p_quality; - const RID *scenario_rid = nullptr; - while ((scenario_rid = scenarios.next(scenario_rid))) { - scenarios[*scenario_rid].dirty = true; + for (KeyValue<RID, Scenario> &K : scenarios) { + K.value.dirty = true; } } @@ -596,9 +601,8 @@ RaycastOcclusionCull::RaycastOcclusionCull() { } RaycastOcclusionCull::~RaycastOcclusionCull() { - const RID *scenario_rid = nullptr; - while ((scenario_rid = scenarios.next(scenario_rid))) { - Scenario &scenario = scenarios[*scenario_rid]; + for (KeyValue<RID, Scenario> &K : scenarios) { + Scenario &scenario = K.value; if (scenario.commit_thread) { scenario.commit_thread->wait_to_finish(); memdelete(scenario.commit_thread); diff --git a/modules/raycast/raycast_occlusion_cull.h b/modules/raycast/raycast_occlusion_cull.h index 8453c5341d..056b808640 100644 --- a/modules/raycast/raycast_occlusion_cull.h +++ b/modules/raycast/raycast_occlusion_cull.h @@ -28,11 +28,11 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef OCCLUSION_CULL_RAYCASTER_H -#define OCCLUSION_CULL_RAYCASTER_H +#ifndef RAYCAST_OCCLUSION_CULL_H +#define RAYCAST_OCCLUSION_CULL_H #include "core/io/image.h" -#include "core/math/camera_matrix.h" +#include "core/math/projection.h" #include "core/object/object.h" #include "core/object/ref_counted.h" #include "core/templates/local_vector.h" @@ -76,7 +76,7 @@ public: virtual void clear() override; virtual void resize(const Size2i &p_size) override; void sort_rays(const Vector3 &p_camera_dir, bool p_orthogonal); - void update_camera_rays(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, ThreadWorkPool &p_thread_work_pool); + void update_camera_rays(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal); ~RaycastHZBuffer(); }; @@ -86,11 +86,13 @@ private: RID scenario; RID instance; - bool operator<(const InstanceID &rhs) const { - if (instance == rhs.instance) { - return rhs.scenario < scenario; - } - return instance < rhs.instance; + static uint32_t hash(const InstanceID &p_ins) { + uint32_t h = hash_murmur3_one_64(p_ins.scenario.get_id()); + return hash_fmix32(hash_murmur3_one_64(p_ins.instance.get_id(), h)); + } + bool operator==(const InstanceID &rhs) const { + return instance == rhs.instance && rhs.scenario == scenario; + ; } InstanceID() {} @@ -101,7 +103,7 @@ private: struct Occluder { PackedVector3Array vertices; PackedInt32Array indices; - Set<InstanceID> users; + HashSet<InstanceID, InstanceID> users; }; struct OccluderInstance { @@ -136,19 +138,19 @@ private: int current_scene_idx = 0; HashMap<RID, OccluderInstance> instances; - Set<RID> dirty_instances; // To avoid duplicates + HashSet<RID> dirty_instances; // To avoid duplicates LocalVector<RID> dirty_instances_array; // To iterate and split into threads LocalVector<RID> removed_instances; void _update_dirty_instance_thread(int p_idx, RID *p_instances); - void _update_dirty_instance(int p_idx, RID *p_instances, ThreadWorkPool *p_thread_pool); + void _update_dirty_instance(int p_idx, RID *p_instances); void _transform_vertices_thread(uint32_t p_thread, TransformThreadData *p_data); void _transform_vertices_range(const Vector3 *p_read, Vector3 *p_write, const Transform3D &p_xform, int p_from, int p_to); static void _commit_scene(void *p_ud); - bool update(ThreadWorkPool &p_thread_pool); + bool update(); void _raycast(uint32_t p_thread, const RaycastThreadData *p_raycast_data) const; - void raycast(CameraRayTile *r_rays, const uint32_t *p_valid_masks, uint32_t p_tile_count, ThreadWorkPool &p_thread_pool) const; + void raycast(CameraRayTile *r_rays, const uint32_t *p_valid_masks, uint32_t p_tile_count) const; }; static RaycastOcclusionCull *raycast_singleton; @@ -181,7 +183,8 @@ public: virtual HZBuffer *buffer_get_ptr(RID p_buffer) override; virtual void buffer_set_scenario(RID p_buffer, RID p_scenario) override; virtual void buffer_set_size(RID p_buffer, const Vector2i &p_size) override; - virtual void buffer_update(RID p_buffer, const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, ThreadWorkPool &p_thread_pool) override; + virtual void buffer_update(RID p_buffer, const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal) override; + virtual RID buffer_get_debug_texture(RID p_buffer) override; virtual void set_build_quality(RS::ViewportOcclusionCullingBuildQuality p_quality) override; @@ -190,4 +193,4 @@ public: ~RaycastOcclusionCull(); }; -#endif // OCCLUSION_CULL_RAYCASTER_H +#endif // RAYCAST_OCCLUSION_CULL_H diff --git a/modules/raycast/register_types.cpp b/modules/raycast/register_types.cpp index 053039a85b..42de1d971d 100644 --- a/modules/raycast/register_types.cpp +++ b/modules/raycast/register_types.cpp @@ -36,7 +36,11 @@ RaycastOcclusionCull *raycast_occlusion_cull = nullptr; -void register_raycast_types() { +void initialize_raycast_module(ModuleInitializationLevel p_level) { + if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) { + return; + } + #ifdef TOOLS_ENABLED LightmapRaycasterEmbree::make_default_raycaster(); StaticRaycasterEmbree::make_default_raycaster(); @@ -44,7 +48,11 @@ void register_raycast_types() { raycast_occlusion_cull = memnew(RaycastOcclusionCull); } -void unregister_raycast_types() { +void uninitialize_raycast_module(ModuleInitializationLevel p_level) { + if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) { + return; + } + if (raycast_occlusion_cull) { memdelete(raycast_occlusion_cull); } diff --git a/modules/raycast/register_types.h b/modules/raycast/register_types.h index 0abc5eb63a..a917285390 100644 --- a/modules/raycast/register_types.h +++ b/modules/raycast/register_types.h @@ -28,5 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -void register_raycast_types(); -void unregister_raycast_types(); +#include "modules/register_module_types.h" + +void initialize_raycast_module(ModuleInitializationLevel p_level); +void uninitialize_raycast_module(ModuleInitializationLevel p_level); diff --git a/modules/raycast/static_raycaster.cpp b/modules/raycast/static_raycaster.cpp index 9df6d5ff43..7659eea27f 100644 --- a/modules/raycast/static_raycaster.cpp +++ b/modules/raycast/static_raycaster.cpp @@ -94,17 +94,17 @@ void StaticRaycasterEmbree::commit() { rtcCommitScene(embree_scene); } -void StaticRaycasterEmbree::set_mesh_filter(const Set<int> &p_mesh_ids) { - for (Set<int>::Element *E = p_mesh_ids.front(); E; E = E->next()) { - rtcDisableGeometry(rtcGetGeometry(embree_scene, E->get())); +void StaticRaycasterEmbree::set_mesh_filter(const HashSet<int> &p_mesh_ids) { + for (const int &E : p_mesh_ids) { + rtcDisableGeometry(rtcGetGeometry(embree_scene, E)); } rtcCommitScene(embree_scene); filter_meshes = p_mesh_ids; } void StaticRaycasterEmbree::clear_mesh_filter() { - for (Set<int>::Element *E = filter_meshes.front(); E; E = E->next()) { - rtcEnableGeometry(rtcGetGeometry(embree_scene, E->get())); + for (const int &E : filter_meshes) { + rtcEnableGeometry(rtcGetGeometry(embree_scene, E)); } rtcCommitScene(embree_scene); filter_meshes.clear(); diff --git a/modules/raycast/static_raycaster.h b/modules/raycast/static_raycaster.h index cce19ba60d..607a392683 100644 --- a/modules/raycast/static_raycaster.h +++ b/modules/raycast/static_raycaster.h @@ -41,7 +41,7 @@ private: static RTCDevice embree_device; RTCScene embree_scene; - Set<int> filter_meshes; + HashSet<int> filter_meshes; public: virtual bool intersect(Ray &p_ray) override; @@ -50,7 +50,7 @@ public: virtual void add_mesh(const PackedVector3Array &p_vertices, const PackedInt32Array &p_indices, unsigned int p_id) override; virtual void commit() override; - virtual void set_mesh_filter(const Set<int> &p_mesh_ids) override; + virtual void set_mesh_filter(const HashSet<int> &p_mesh_ids) override; virtual void clear_mesh_filter() override; static StaticRaycaster *create_embree_raycaster(); @@ -61,4 +61,4 @@ public: ~StaticRaycasterEmbree(); }; -#endif +#endif // STATIC_RAYCASTER_H |