From 4089a6cb8c7f0794a77e0a7774d8c43612672bcf Mon Sep 17 00:00:00 2001 From: Rudolph Bester Date: Sat, 2 Nov 2024 16:48:08 +0200 Subject: [PATCH] Fixed occlusion culling for double builds by enforcing float conversion for Embree. --- modules/raycast/raycast_occlusion_cull.cpp | 15 ++++++++++----- modules/raycast/raycast_occlusion_cull.h | 6 +++--- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/modules/raycast/raycast_occlusion_cull.cpp b/modules/raycast/raycast_occlusion_cull.cpp index 3609f5a554d..ce780ca565c 100644 --- a/modules/raycast/raycast_occlusion_cull.cpp +++ b/modules/raycast/raycast_occlusion_cull.cpp @@ -334,10 +334,10 @@ void RaycastOcclusionCull::Scenario::_update_dirty_instance(int p_idx, RID *p_in int vertices_size = occ->vertices.size(); // Embree requires the last element to be readable by a 16-byte SSE load instruction, so we add padding to be safe. - occ_inst->xformed_vertices.resize(vertices_size + 1); + occ_inst->xformed_vertices.resize(3 * vertices_size + 3); const Vector3 *read_ptr = occ->vertices.ptr(); - Vector3 *write_ptr = occ_inst->xformed_vertices.ptr(); + float *write_ptr = occ_inst->xformed_vertices.ptr(); if (vertices_size > 1024) { TransformThreadData td; @@ -365,9 +365,14 @@ void RaycastOcclusionCull::Scenario::_transform_vertices_thread(uint32_t p_threa _transform_vertices_range(p_data->read, p_data->write, p_data->xform, from, to); } -void RaycastOcclusionCull::Scenario::_transform_vertices_range(const Vector3 *p_read, Vector3 *p_write, const Transform3D &p_xform, int p_from, int p_to) { +void RaycastOcclusionCull::Scenario::_transform_vertices_range(const Vector3 *p_read, float *p_write, const Transform3D &p_xform, int p_from, int p_to) { + float *floats_w = p_write; for (int i = p_from; i < p_to; i++) { - p_write[i] = p_xform.xform(p_read[i]); + const Vector3 p = p_xform.xform(p_read[i]); + floats_w[0] = p.x; + floats_w[1] = p.y; + floats_w[2] = p.z; + floats_w += 3; } } @@ -458,7 +463,7 @@ void RaycastOcclusionCull::Scenario::update() { } RTCGeometry geom = rtcNewGeometry(raycast_singleton->ebr_device, RTC_GEOMETRY_TYPE_TRIANGLE); - rtcSetSharedGeometryBuffer(geom, RTC_BUFFER_TYPE_VERTEX, 0, RTC_FORMAT_FLOAT3, occ_inst->xformed_vertices.ptr(), 0, sizeof(Vector3), occ_inst->xformed_vertices.size()); + rtcSetSharedGeometryBuffer(geom, RTC_BUFFER_TYPE_VERTEX, 0, RTC_FORMAT_FLOAT3, occ_inst->xformed_vertices.ptr(), 0, sizeof(float) * 3, occ_inst->xformed_vertices.size() / 3); rtcSetSharedGeometryBuffer(geom, RTC_BUFFER_TYPE_INDEX, 0, RTC_FORMAT_UINT3, occ_inst->indices.ptr(), 0, sizeof(uint32_t) * 3, occ_inst->indices.size() / 3); rtcCommitGeometry(geom); rtcAttachGeometry(next_scene, geom); diff --git a/modules/raycast/raycast_occlusion_cull.h b/modules/raycast/raycast_occlusion_cull.h index 335a6856728..347f3be2c99 100644 --- a/modules/raycast/raycast_occlusion_cull.h +++ b/modules/raycast/raycast_occlusion_cull.h @@ -109,7 +109,7 @@ private: struct OccluderInstance { RID occluder; LocalVector indices; - LocalVector xformed_vertices; + LocalVector xformed_vertices; Transform3D xform; bool enabled = true; bool removed = false; @@ -126,7 +126,7 @@ private: uint32_t vertex_count; Transform3D xform; const Vector3 *read; - Vector3 *write = nullptr; + float *write = nullptr; }; Thread *commit_thread = nullptr; @@ -144,7 +144,7 @@ private: void _update_dirty_instance_thread(int p_idx, RID *p_instances); 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); + void _transform_vertices_range(const Vector3 *p_read, float *p_write, const Transform3D &p_xform, int p_from, int p_to); static void _commit_scene(void *p_ud); void free(); void update();