From 49fcf4ffad4172c2e9dd2249222b628e420c3cc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Verschelde?= Date: Mon, 26 Sep 2022 13:03:44 +0200 Subject: Style: Cleanup header guards for consistency Fix file names for {Static,Lightmap}RaycasterEmbree. --- modules/raycast/lightmap_raycaster.cpp | 196 -------------------------- modules/raycast/lightmap_raycaster.h | 77 ---------- modules/raycast/lightmap_raycaster_embree.cpp | 196 ++++++++++++++++++++++++++ modules/raycast/lightmap_raycaster_embree.h | 82 +++++++++++ modules/raycast/register_types.cpp | 4 +- modules/raycast/register_types.h | 5 + modules/raycast/static_raycaster.cpp | 137 ------------------ modules/raycast/static_raycaster.h | 64 --------- modules/raycast/static_raycaster_embree.cpp | 137 ++++++++++++++++++ modules/raycast/static_raycaster_embree.h | 69 +++++++++ 10 files changed, 491 insertions(+), 476 deletions(-) delete mode 100644 modules/raycast/lightmap_raycaster.cpp delete mode 100644 modules/raycast/lightmap_raycaster.h create mode 100644 modules/raycast/lightmap_raycaster_embree.cpp create mode 100644 modules/raycast/lightmap_raycaster_embree.h delete mode 100644 modules/raycast/static_raycaster.cpp delete mode 100644 modules/raycast/static_raycaster.h create mode 100644 modules/raycast/static_raycaster_embree.cpp create mode 100644 modules/raycast/static_raycaster_embree.h (limited to 'modules/raycast') diff --git a/modules/raycast/lightmap_raycaster.cpp b/modules/raycast/lightmap_raycaster.cpp deleted file mode 100644 index 9b35b5616e..0000000000 --- a/modules/raycast/lightmap_raycaster.cpp +++ /dev/null @@ -1,196 +0,0 @@ -/*************************************************************************/ -/* lightmap_raycaster.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifdef TOOLS_ENABLED - -#include "lightmap_raycaster.h" - -#ifdef __SSE2__ -#include -#endif - -LightmapRaycaster *LightmapRaycasterEmbree::create_embree_raycaster() { - return memnew(LightmapRaycasterEmbree); -} - -void LightmapRaycasterEmbree::make_default_raycaster() { - create_function = create_embree_raycaster; -} - -void LightmapRaycasterEmbree::filter_function(const struct RTCFilterFunctionNArguments *p_args) { - RTCHit *hit = (RTCHit *)p_args->hit; - - unsigned int geomID = hit->geomID; - float u = hit->u; - float v = hit->v; - - LightmapRaycasterEmbree *scene = (LightmapRaycasterEmbree *)p_args->geometryUserPtr; - RTCGeometry geom = rtcGetGeometry(scene->embree_scene, geomID); - - rtcInterpolate0(geom, hit->primID, hit->u, hit->v, RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE, 0, &hit->u, 2); - - if (scene->alpha_textures.has(geomID)) { - const AlphaTextureData &alpha_texture = scene->alpha_textures[geomID]; - - if (alpha_texture.sample(hit->u, hit->v) < 128) { - p_args->valid[0] = 0; - return; - } - } - - rtcInterpolate0(geom, hit->primID, u, v, RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE, 1, &hit->Ng_x, 3); -} - -bool LightmapRaycasterEmbree::intersect(Ray &r_ray) { - RTCIntersectContext context; - - rtcInitIntersectContext(&context); - - rtcIntersect1(embree_scene, &context, (RTCRayHit *)&r_ray); - return r_ray.geomID != RTC_INVALID_GEOMETRY_ID; -} - -void LightmapRaycasterEmbree::intersect(Vector &r_rays) { - Ray *rays = r_rays.ptrw(); - for (int i = 0; i < r_rays.size(); ++i) { - intersect(rays[i]); - } -} - -void LightmapRaycasterEmbree::set_mesh_alpha_texture(Ref p_alpha_texture, unsigned int p_id) { - if (p_alpha_texture.is_valid() && p_alpha_texture->get_size() != Vector2i()) { - AlphaTextureData tex; - tex.size = p_alpha_texture->get_size(); - tex.data = p_alpha_texture->get_data(); - alpha_textures.insert(p_id, tex); - } -} - -float blerp(float c00, float c10, float c01, float c11, float tx, float ty) { - return Math::lerp(Math::lerp(c00, c10, tx), Math::lerp(c01, c11, tx), ty); -} - -uint8_t LightmapRaycasterEmbree::AlphaTextureData::sample(float u, float v) const { - float x = u * size.x; - float y = v * size.y; - int xi = (int)x; - int yi = (int)y; - - uint8_t texels[4]; - - for (int i = 0; i < 4; ++i) { - int sample_x = CLAMP(xi + i % 2, 0, size.x - 1); - int sample_y = CLAMP(yi + i / 2, 0, size.y - 1); - texels[i] = data[sample_y * size.x + sample_x]; - } - - return Math::round(blerp(texels[0], texels[1], texels[2], texels[3], x - xi, y - yi)); -} - -void LightmapRaycasterEmbree::add_mesh(const Vector &p_vertices, const Vector &p_normals, const Vector &p_uv2s, unsigned int p_id) { - RTCGeometry embree_mesh = rtcNewGeometry(embree_device, RTC_GEOMETRY_TYPE_TRIANGLE); - - rtcSetGeometryVertexAttributeCount(embree_mesh, 2); - - int vertex_count = p_vertices.size(); - - ERR_FAIL_COND(vertex_count % 3 != 0); - ERR_FAIL_COND(vertex_count != p_uv2s.size()); - ERR_FAIL_COND(!p_normals.is_empty() && vertex_count != p_normals.size()); - - Vector3 *embree_vertices = (Vector3 *)rtcSetNewGeometryBuffer(embree_mesh, RTC_BUFFER_TYPE_VERTEX, 0, RTC_FORMAT_FLOAT3, sizeof(Vector3), vertex_count); - memcpy(embree_vertices, p_vertices.ptr(), sizeof(Vector3) * vertex_count); - - Vector2 *embree_light_uvs = (Vector2 *)rtcSetNewGeometryBuffer(embree_mesh, RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE, 0, RTC_FORMAT_FLOAT2, sizeof(Vector2), vertex_count); - memcpy(embree_light_uvs, p_uv2s.ptr(), sizeof(Vector2) * vertex_count); - - uint32_t *embree_triangles = (uint32_t *)rtcSetNewGeometryBuffer(embree_mesh, RTC_BUFFER_TYPE_INDEX, 0, RTC_FORMAT_UINT3, sizeof(uint32_t) * 3, vertex_count / 3); - for (int i = 0; i < vertex_count; i++) { - embree_triangles[i] = i; - } - - if (!p_normals.is_empty()) { - Vector3 *embree_normals = (Vector3 *)rtcSetNewGeometryBuffer(embree_mesh, RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE, 1, RTC_FORMAT_FLOAT3, sizeof(Vector3), vertex_count); - memcpy(embree_normals, p_normals.ptr(), sizeof(Vector3) * vertex_count); - } - - rtcCommitGeometry(embree_mesh); - rtcSetGeometryIntersectFilterFunction(embree_mesh, filter_function); - rtcSetGeometryUserData(embree_mesh, this); - rtcAttachGeometryByID(embree_scene, embree_mesh, p_id); - rtcReleaseGeometry(embree_mesh); -} - -void LightmapRaycasterEmbree::commit() { - rtcCommitScene(embree_scene); -} - -void LightmapRaycasterEmbree::set_mesh_filter(const HashSet &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 (const int &E : filter_meshes) { - rtcEnableGeometry(rtcGetGeometry(embree_scene, E)); - } - rtcCommitScene(embree_scene); - filter_meshes.clear(); -} - -void embree_lm_error_handler(void *p_user_data, RTCError p_code, const char *p_str) { - print_error("Embree error: " + String(p_str)); -} - -LightmapRaycasterEmbree::LightmapRaycasterEmbree() { -#ifdef __SSE2__ - _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON); - _MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_ON); -#endif - - embree_device = rtcNewDevice(nullptr); - rtcSetDeviceErrorFunction(embree_device, &embree_lm_error_handler, nullptr); - embree_scene = rtcNewScene(embree_device); -} - -LightmapRaycasterEmbree::~LightmapRaycasterEmbree() { - if (embree_scene != nullptr) { - rtcReleaseScene(embree_scene); - } - - if (embree_device != nullptr) { - rtcReleaseDevice(embree_device); - } -} - -#endif diff --git a/modules/raycast/lightmap_raycaster.h b/modules/raycast/lightmap_raycaster.h deleted file mode 100644 index 2e9f59dda4..0000000000 --- a/modules/raycast/lightmap_raycaster.h +++ /dev/null @@ -1,77 +0,0 @@ -/*************************************************************************/ -/* lightmap_raycaster.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifdef TOOLS_ENABLED - -#include "core/io/image.h" -#include "core/object/object.h" -#include "scene/3d/lightmapper.h" - -#include - -class LightmapRaycasterEmbree : public LightmapRaycaster { - GDCLASS(LightmapRaycasterEmbree, LightmapRaycaster); - -private: - struct AlphaTextureData { - Vector data; - Vector2i size; - - uint8_t sample(float u, float v) const; - }; - - RTCDevice embree_device; - RTCScene embree_scene; - - static void filter_function(const struct RTCFilterFunctionNArguments *p_args); - - HashMap alpha_textures; - HashSet filter_meshes; - -public: - virtual bool intersect(Ray &p_ray) override; - - virtual void intersect(Vector &r_rays) override; - - virtual void add_mesh(const Vector &p_vertices, const Vector &p_normals, const Vector &p_uv2s, unsigned int p_id) override; - virtual void set_mesh_alpha_texture(Ref p_alpha_texture, unsigned int p_id) override; - virtual void commit() override; - - virtual void set_mesh_filter(const HashSet &p_mesh_ids) override; - virtual void clear_mesh_filter() override; - - static LightmapRaycaster *create_embree_raycaster(); - static void make_default_raycaster(); - - LightmapRaycasterEmbree(); - ~LightmapRaycasterEmbree(); -}; - -#endif // LIGHTMAP_RAYCASTER_H diff --git a/modules/raycast/lightmap_raycaster_embree.cpp b/modules/raycast/lightmap_raycaster_embree.cpp new file mode 100644 index 0000000000..e6a579bd3a --- /dev/null +++ b/modules/raycast/lightmap_raycaster_embree.cpp @@ -0,0 +1,196 @@ +/*************************************************************************/ +/* lightmap_raycaster_embree.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifdef TOOLS_ENABLED + +#include "lightmap_raycaster_embree.h" + +#ifdef __SSE2__ +#include +#endif + +LightmapRaycaster *LightmapRaycasterEmbree::create_embree_raycaster() { + return memnew(LightmapRaycasterEmbree); +} + +void LightmapRaycasterEmbree::make_default_raycaster() { + create_function = create_embree_raycaster; +} + +void LightmapRaycasterEmbree::filter_function(const struct RTCFilterFunctionNArguments *p_args) { + RTCHit *hit = (RTCHit *)p_args->hit; + + unsigned int geomID = hit->geomID; + float u = hit->u; + float v = hit->v; + + LightmapRaycasterEmbree *scene = (LightmapRaycasterEmbree *)p_args->geometryUserPtr; + RTCGeometry geom = rtcGetGeometry(scene->embree_scene, geomID); + + rtcInterpolate0(geom, hit->primID, hit->u, hit->v, RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE, 0, &hit->u, 2); + + if (scene->alpha_textures.has(geomID)) { + const AlphaTextureData &alpha_texture = scene->alpha_textures[geomID]; + + if (alpha_texture.sample(hit->u, hit->v) < 128) { + p_args->valid[0] = 0; + return; + } + } + + rtcInterpolate0(geom, hit->primID, u, v, RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE, 1, &hit->Ng_x, 3); +} + +bool LightmapRaycasterEmbree::intersect(Ray &r_ray) { + RTCIntersectContext context; + + rtcInitIntersectContext(&context); + + rtcIntersect1(embree_scene, &context, (RTCRayHit *)&r_ray); + return r_ray.geomID != RTC_INVALID_GEOMETRY_ID; +} + +void LightmapRaycasterEmbree::intersect(Vector &r_rays) { + Ray *rays = r_rays.ptrw(); + for (int i = 0; i < r_rays.size(); ++i) { + intersect(rays[i]); + } +} + +void LightmapRaycasterEmbree::set_mesh_alpha_texture(Ref p_alpha_texture, unsigned int p_id) { + if (p_alpha_texture.is_valid() && p_alpha_texture->get_size() != Vector2i()) { + AlphaTextureData tex; + tex.size = p_alpha_texture->get_size(); + tex.data = p_alpha_texture->get_data(); + alpha_textures.insert(p_id, tex); + } +} + +float blerp(float c00, float c10, float c01, float c11, float tx, float ty) { + return Math::lerp(Math::lerp(c00, c10, tx), Math::lerp(c01, c11, tx), ty); +} + +uint8_t LightmapRaycasterEmbree::AlphaTextureData::sample(float u, float v) const { + float x = u * size.x; + float y = v * size.y; + int xi = (int)x; + int yi = (int)y; + + uint8_t texels[4]; + + for (int i = 0; i < 4; ++i) { + int sample_x = CLAMP(xi + i % 2, 0, size.x - 1); + int sample_y = CLAMP(yi + i / 2, 0, size.y - 1); + texels[i] = data[sample_y * size.x + sample_x]; + } + + return Math::round(blerp(texels[0], texels[1], texels[2], texels[3], x - xi, y - yi)); +} + +void LightmapRaycasterEmbree::add_mesh(const Vector &p_vertices, const Vector &p_normals, const Vector &p_uv2s, unsigned int p_id) { + RTCGeometry embree_mesh = rtcNewGeometry(embree_device, RTC_GEOMETRY_TYPE_TRIANGLE); + + rtcSetGeometryVertexAttributeCount(embree_mesh, 2); + + int vertex_count = p_vertices.size(); + + ERR_FAIL_COND(vertex_count % 3 != 0); + ERR_FAIL_COND(vertex_count != p_uv2s.size()); + ERR_FAIL_COND(!p_normals.is_empty() && vertex_count != p_normals.size()); + + Vector3 *embree_vertices = (Vector3 *)rtcSetNewGeometryBuffer(embree_mesh, RTC_BUFFER_TYPE_VERTEX, 0, RTC_FORMAT_FLOAT3, sizeof(Vector3), vertex_count); + memcpy(embree_vertices, p_vertices.ptr(), sizeof(Vector3) * vertex_count); + + Vector2 *embree_light_uvs = (Vector2 *)rtcSetNewGeometryBuffer(embree_mesh, RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE, 0, RTC_FORMAT_FLOAT2, sizeof(Vector2), vertex_count); + memcpy(embree_light_uvs, p_uv2s.ptr(), sizeof(Vector2) * vertex_count); + + uint32_t *embree_triangles = (uint32_t *)rtcSetNewGeometryBuffer(embree_mesh, RTC_BUFFER_TYPE_INDEX, 0, RTC_FORMAT_UINT3, sizeof(uint32_t) * 3, vertex_count / 3); + for (int i = 0; i < vertex_count; i++) { + embree_triangles[i] = i; + } + + if (!p_normals.is_empty()) { + Vector3 *embree_normals = (Vector3 *)rtcSetNewGeometryBuffer(embree_mesh, RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE, 1, RTC_FORMAT_FLOAT3, sizeof(Vector3), vertex_count); + memcpy(embree_normals, p_normals.ptr(), sizeof(Vector3) * vertex_count); + } + + rtcCommitGeometry(embree_mesh); + rtcSetGeometryIntersectFilterFunction(embree_mesh, filter_function); + rtcSetGeometryUserData(embree_mesh, this); + rtcAttachGeometryByID(embree_scene, embree_mesh, p_id); + rtcReleaseGeometry(embree_mesh); +} + +void LightmapRaycasterEmbree::commit() { + rtcCommitScene(embree_scene); +} + +void LightmapRaycasterEmbree::set_mesh_filter(const HashSet &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 (const int &E : filter_meshes) { + rtcEnableGeometry(rtcGetGeometry(embree_scene, E)); + } + rtcCommitScene(embree_scene); + filter_meshes.clear(); +} + +void embree_lm_error_handler(void *p_user_data, RTCError p_code, const char *p_str) { + print_error("Embree error: " + String(p_str)); +} + +LightmapRaycasterEmbree::LightmapRaycasterEmbree() { +#ifdef __SSE2__ + _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON); + _MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_ON); +#endif + + embree_device = rtcNewDevice(nullptr); + rtcSetDeviceErrorFunction(embree_device, &embree_lm_error_handler, nullptr); + embree_scene = rtcNewScene(embree_device); +} + +LightmapRaycasterEmbree::~LightmapRaycasterEmbree() { + if (embree_scene != nullptr) { + rtcReleaseScene(embree_scene); + } + + if (embree_device != nullptr) { + rtcReleaseDevice(embree_device); + } +} + +#endif // TOOLS_ENABLED diff --git a/modules/raycast/lightmap_raycaster_embree.h b/modules/raycast/lightmap_raycaster_embree.h new file mode 100644 index 0000000000..0c3371f07c --- /dev/null +++ b/modules/raycast/lightmap_raycaster_embree.h @@ -0,0 +1,82 @@ +/*************************************************************************/ +/* lightmap_raycaster_embree.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef LIGHTMAP_RAYCASTER_EMBREE_H +#define LIGHTMAP_RAYCASTER_EMBREE_H + +#ifdef TOOLS_ENABLED + +#include "core/io/image.h" +#include "core/object/object.h" +#include "scene/3d/lightmapper.h" + +#include + +class LightmapRaycasterEmbree : public LightmapRaycaster { + GDCLASS(LightmapRaycasterEmbree, LightmapRaycaster); + +private: + struct AlphaTextureData { + Vector data; + Vector2i size; + + uint8_t sample(float u, float v) const; + }; + + RTCDevice embree_device; + RTCScene embree_scene; + + static void filter_function(const struct RTCFilterFunctionNArguments *p_args); + + HashMap alpha_textures; + HashSet filter_meshes; + +public: + virtual bool intersect(Ray &p_ray) override; + + virtual void intersect(Vector &r_rays) override; + + virtual void add_mesh(const Vector &p_vertices, const Vector &p_normals, const Vector &p_uv2s, unsigned int p_id) override; + virtual void set_mesh_alpha_texture(Ref p_alpha_texture, unsigned int p_id) override; + virtual void commit() override; + + virtual void set_mesh_filter(const HashSet &p_mesh_ids) override; + virtual void clear_mesh_filter() override; + + static LightmapRaycaster *create_embree_raycaster(); + static void make_default_raycaster(); + + LightmapRaycasterEmbree(); + ~LightmapRaycasterEmbree(); +}; + +#endif // TOOLS_ENABLED + +#endif // LIGHTMAP_RAYCASTER_EMBREE_H diff --git a/modules/raycast/register_types.cpp b/modules/raycast/register_types.cpp index 42de1d971d..a8380b00ba 100644 --- a/modules/raycast/register_types.cpp +++ b/modules/raycast/register_types.cpp @@ -30,9 +30,9 @@ #include "register_types.h" -#include "lightmap_raycaster.h" +#include "lightmap_raycaster_embree.h" #include "raycast_occlusion_cull.h" -#include "static_raycaster.h" +#include "static_raycaster_embree.h" RaycastOcclusionCull *raycast_occlusion_cull = nullptr; diff --git a/modules/raycast/register_types.h b/modules/raycast/register_types.h index a917285390..25a6c346b9 100644 --- a/modules/raycast/register_types.h +++ b/modules/raycast/register_types.h @@ -28,7 +28,12 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ +#ifndef RAYCAST_REGISTER_TYPES_H +#define RAYCAST_REGISTER_TYPES_H + #include "modules/register_module_types.h" void initialize_raycast_module(ModuleInitializationLevel p_level); void uninitialize_raycast_module(ModuleInitializationLevel p_level); + +#endif // RAYCAST_REGISTER_TYPES_H diff --git a/modules/raycast/static_raycaster.cpp b/modules/raycast/static_raycaster.cpp deleted file mode 100644 index 7659eea27f..0000000000 --- a/modules/raycast/static_raycaster.cpp +++ /dev/null @@ -1,137 +0,0 @@ -/*************************************************************************/ -/* static_raycaster.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifdef TOOLS_ENABLED - -#include "static_raycaster.h" - -#ifdef __SSE2__ -#include -#endif - -RTCDevice StaticRaycasterEmbree::embree_device; - -StaticRaycaster *StaticRaycasterEmbree::create_embree_raycaster() { - return memnew(StaticRaycasterEmbree); -} - -void StaticRaycasterEmbree::make_default_raycaster() { - create_function = create_embree_raycaster; -} - -void StaticRaycasterEmbree::free() { - if (embree_device) { - rtcReleaseDevice(embree_device); - } -} - -bool StaticRaycasterEmbree::intersect(Ray &r_ray) { - RTCIntersectContext context; - rtcInitIntersectContext(&context); - rtcIntersect1(embree_scene, &context, (RTCRayHit *)&r_ray); - return r_ray.geomID != RTC_INVALID_GEOMETRY_ID; -} - -void StaticRaycasterEmbree::intersect(Vector &r_rays) { - Ray *rays = r_rays.ptrw(); - for (int i = 0; i < r_rays.size(); ++i) { - intersect(rays[i]); - } -} - -void StaticRaycasterEmbree::add_mesh(const PackedVector3Array &p_vertices, const PackedInt32Array &p_indices, unsigned int p_id) { - RTCGeometry embree_mesh = rtcNewGeometry(embree_device, RTC_GEOMETRY_TYPE_TRIANGLE); - - int vertex_count = p_vertices.size(); - - Vector3 *embree_vertices = (Vector3 *)rtcSetNewGeometryBuffer(embree_mesh, RTC_BUFFER_TYPE_VERTEX, 0, RTC_FORMAT_FLOAT3, sizeof(Vector3), vertex_count); - memcpy(embree_vertices, p_vertices.ptr(), sizeof(Vector3) * vertex_count); - - if (p_indices.is_empty()) { - ERR_FAIL_COND(vertex_count % 3 != 0); - uint32_t *embree_triangles = (uint32_t *)rtcSetNewGeometryBuffer(embree_mesh, RTC_BUFFER_TYPE_INDEX, 0, RTC_FORMAT_UINT3, sizeof(uint32_t) * 3, vertex_count / 3); - for (int i = 0; i < vertex_count; i++) { - embree_triangles[i] = i; - } - } else { - uint32_t *embree_triangles = (uint32_t *)rtcSetNewGeometryBuffer(embree_mesh, RTC_BUFFER_TYPE_INDEX, 0, RTC_FORMAT_UINT3, sizeof(uint32_t) * 3, p_indices.size() / 3); - memcpy(embree_triangles, p_indices.ptr(), sizeof(uint32_t) * p_indices.size()); - } - - rtcCommitGeometry(embree_mesh); - rtcAttachGeometryByID(embree_scene, embree_mesh, p_id); - rtcReleaseGeometry(embree_mesh); -} - -void StaticRaycasterEmbree::commit() { - rtcCommitScene(embree_scene); -} - -void StaticRaycasterEmbree::set_mesh_filter(const HashSet &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 (const int &E : filter_meshes) { - rtcEnableGeometry(rtcGetGeometry(embree_scene, E)); - } - rtcCommitScene(embree_scene); - filter_meshes.clear(); -} - -void embree_error_handler(void *p_user_data, RTCError p_code, const char *p_str) { - print_error("Embree error: " + String(p_str)); -} - -StaticRaycasterEmbree::StaticRaycasterEmbree() { -#ifdef __SSE2__ - _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON); - _MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_ON); -#endif - - if (!embree_device) { - embree_device = rtcNewDevice(nullptr); - rtcSetDeviceErrorFunction(embree_device, &embree_error_handler, nullptr); - } - - embree_scene = rtcNewScene(embree_device); -} - -StaticRaycasterEmbree::~StaticRaycasterEmbree() { - if (embree_scene != nullptr) { - rtcReleaseScene(embree_scene); - } -} - -#endif diff --git a/modules/raycast/static_raycaster.h b/modules/raycast/static_raycaster.h deleted file mode 100644 index 607a392683..0000000000 --- a/modules/raycast/static_raycaster.h +++ /dev/null @@ -1,64 +0,0 @@ -/*************************************************************************/ -/* static_raycaster.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifdef TOOLS_ENABLED - -#include "core/math/static_raycaster.h" - -#include - -class StaticRaycasterEmbree : public StaticRaycaster { - GDCLASS(StaticRaycasterEmbree, StaticRaycaster); - -private: - static RTCDevice embree_device; - RTCScene embree_scene; - - HashSet filter_meshes; - -public: - virtual bool intersect(Ray &p_ray) override; - virtual void intersect(Vector &r_rays) override; - - 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 HashSet &p_mesh_ids) override; - virtual void clear_mesh_filter() override; - - static StaticRaycaster *create_embree_raycaster(); - static void make_default_raycaster(); - static void free(); - - StaticRaycasterEmbree(); - ~StaticRaycasterEmbree(); -}; - -#endif // STATIC_RAYCASTER_H diff --git a/modules/raycast/static_raycaster_embree.cpp b/modules/raycast/static_raycaster_embree.cpp new file mode 100644 index 0000000000..b5a4ab42d4 --- /dev/null +++ b/modules/raycast/static_raycaster_embree.cpp @@ -0,0 +1,137 @@ +/*************************************************************************/ +/* static_raycaster_embree.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifdef TOOLS_ENABLED + +#include "static_raycaster_embree.h" + +#ifdef __SSE2__ +#include +#endif + +RTCDevice StaticRaycasterEmbree::embree_device; + +StaticRaycaster *StaticRaycasterEmbree::create_embree_raycaster() { + return memnew(StaticRaycasterEmbree); +} + +void StaticRaycasterEmbree::make_default_raycaster() { + create_function = create_embree_raycaster; +} + +void StaticRaycasterEmbree::free() { + if (embree_device) { + rtcReleaseDevice(embree_device); + } +} + +bool StaticRaycasterEmbree::intersect(Ray &r_ray) { + RTCIntersectContext context; + rtcInitIntersectContext(&context); + rtcIntersect1(embree_scene, &context, (RTCRayHit *)&r_ray); + return r_ray.geomID != RTC_INVALID_GEOMETRY_ID; +} + +void StaticRaycasterEmbree::intersect(Vector &r_rays) { + Ray *rays = r_rays.ptrw(); + for (int i = 0; i < r_rays.size(); ++i) { + intersect(rays[i]); + } +} + +void StaticRaycasterEmbree::add_mesh(const PackedVector3Array &p_vertices, const PackedInt32Array &p_indices, unsigned int p_id) { + RTCGeometry embree_mesh = rtcNewGeometry(embree_device, RTC_GEOMETRY_TYPE_TRIANGLE); + + int vertex_count = p_vertices.size(); + + Vector3 *embree_vertices = (Vector3 *)rtcSetNewGeometryBuffer(embree_mesh, RTC_BUFFER_TYPE_VERTEX, 0, RTC_FORMAT_FLOAT3, sizeof(Vector3), vertex_count); + memcpy(embree_vertices, p_vertices.ptr(), sizeof(Vector3) * vertex_count); + + if (p_indices.is_empty()) { + ERR_FAIL_COND(vertex_count % 3 != 0); + uint32_t *embree_triangles = (uint32_t *)rtcSetNewGeometryBuffer(embree_mesh, RTC_BUFFER_TYPE_INDEX, 0, RTC_FORMAT_UINT3, sizeof(uint32_t) * 3, vertex_count / 3); + for (int i = 0; i < vertex_count; i++) { + embree_triangles[i] = i; + } + } else { + uint32_t *embree_triangles = (uint32_t *)rtcSetNewGeometryBuffer(embree_mesh, RTC_BUFFER_TYPE_INDEX, 0, RTC_FORMAT_UINT3, sizeof(uint32_t) * 3, p_indices.size() / 3); + memcpy(embree_triangles, p_indices.ptr(), sizeof(uint32_t) * p_indices.size()); + } + + rtcCommitGeometry(embree_mesh); + rtcAttachGeometryByID(embree_scene, embree_mesh, p_id); + rtcReleaseGeometry(embree_mesh); +} + +void StaticRaycasterEmbree::commit() { + rtcCommitScene(embree_scene); +} + +void StaticRaycasterEmbree::set_mesh_filter(const HashSet &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 (const int &E : filter_meshes) { + rtcEnableGeometry(rtcGetGeometry(embree_scene, E)); + } + rtcCommitScene(embree_scene); + filter_meshes.clear(); +} + +void embree_error_handler(void *p_user_data, RTCError p_code, const char *p_str) { + print_error("Embree error: " + String(p_str)); +} + +StaticRaycasterEmbree::StaticRaycasterEmbree() { +#ifdef __SSE2__ + _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON); + _MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_ON); +#endif + + if (!embree_device) { + embree_device = rtcNewDevice(nullptr); + rtcSetDeviceErrorFunction(embree_device, &embree_error_handler, nullptr); + } + + embree_scene = rtcNewScene(embree_device); +} + +StaticRaycasterEmbree::~StaticRaycasterEmbree() { + if (embree_scene != nullptr) { + rtcReleaseScene(embree_scene); + } +} + +#endif // TOOLS_ENABLED diff --git a/modules/raycast/static_raycaster_embree.h b/modules/raycast/static_raycaster_embree.h new file mode 100644 index 0000000000..4d631e3ca0 --- /dev/null +++ b/modules/raycast/static_raycaster_embree.h @@ -0,0 +1,69 @@ +/*************************************************************************/ +/* static_raycaster_embree.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef STATIC_RAYCASTER_EMBREE_H +#define STATIC_RAYCASTER_EMBREE_H + +#ifdef TOOLS_ENABLED + +#include "core/math/static_raycaster.h" + +#include + +class StaticRaycasterEmbree : public StaticRaycaster { + GDCLASS(StaticRaycasterEmbree, StaticRaycaster); + +private: + static RTCDevice embree_device; + RTCScene embree_scene; + + HashSet filter_meshes; + +public: + virtual bool intersect(Ray &p_ray) override; + virtual void intersect(Vector &r_rays) override; + + 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 HashSet &p_mesh_ids) override; + virtual void clear_mesh_filter() override; + + static StaticRaycaster *create_embree_raycaster(); + static void make_default_raycaster(); + static void free(); + + StaticRaycasterEmbree(); + ~StaticRaycasterEmbree(); +}; + +#endif // TOOLS_ENABLED + +#endif // STATIC_RAYCASTER_EMBREE_H -- cgit v1.2.3