diff options
Diffstat (limited to 'modules/raycast')
-rw-r--r-- | modules/raycast/lightmap_raycaster.cpp | 9 | ||||
-rw-r--r-- | modules/raycast/lightmap_raycaster.h | 2 | ||||
-rw-r--r-- | modules/raycast/register_types.cpp | 5 | ||||
-rw-r--r-- | modules/raycast/static_raycaster.cpp | 137 | ||||
-rw-r--r-- | modules/raycast/static_raycaster.h | 64 |
5 files changed, 209 insertions, 8 deletions
diff --git a/modules/raycast/lightmap_raycaster.cpp b/modules/raycast/lightmap_raycaster.cpp index 0583acc119..fdcf509da8 100644 --- a/modules/raycast/lightmap_raycaster.cpp +++ b/modules/raycast/lightmap_raycaster.cpp @@ -168,7 +168,7 @@ void LightmapRaycasterEmbree::clear_mesh_filter() { filter_meshes.clear(); } -void embree_error_handler(void *p_user_data, RTCError p_code, const char *p_str) { +void embree_lm_error_handler(void *p_user_data, RTCError p_code, const char *p_str) { print_error("Embree error: " + String(p_str)); } @@ -179,16 +179,11 @@ LightmapRaycasterEmbree::LightmapRaycasterEmbree() { #endif embree_device = rtcNewDevice(nullptr); - rtcSetDeviceErrorFunction(embree_device, &embree_error_handler, nullptr); + rtcSetDeviceErrorFunction(embree_device, &embree_lm_error_handler, nullptr); embree_scene = rtcNewScene(embree_device); } LightmapRaycasterEmbree::~LightmapRaycasterEmbree() { -#ifdef __SSE2__ - _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_OFF); - _MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_OFF); -#endif - if (embree_scene != nullptr) { rtcReleaseScene(embree_scene); } diff --git a/modules/raycast/lightmap_raycaster.h b/modules/raycast/lightmap_raycaster.h index 4c3de27837..290b0a1cf3 100644 --- a/modules/raycast/lightmap_raycaster.h +++ b/modules/raycast/lightmap_raycaster.h @@ -30,9 +30,9 @@ #ifdef TOOLS_ENABLED +#include "core/io/image.h" #include "core/object/object.h" #include "scene/3d/lightmapper.h" -#include "scene/resources/mesh.h" #include <embree3/rtcore.h> diff --git a/modules/raycast/register_types.cpp b/modules/raycast/register_types.cpp index 78ca91309f..ed99e635e1 100644 --- a/modules/raycast/register_types.cpp +++ b/modules/raycast/register_types.cpp @@ -32,12 +32,14 @@ #include "lightmap_raycaster.h" #include "raycast_occlusion_cull.h" +#include "static_raycaster.h" RaycastOcclusionCull *raycast_occlusion_cull = nullptr; void register_raycast_types() { #ifdef TOOLS_ENABLED LightmapRaycasterEmbree::make_default_raycaster(); + StaticRaycasterEmbree::make_default_raycaster(); #endif raycast_occlusion_cull = memnew(RaycastOcclusionCull); } @@ -46,4 +48,7 @@ void unregister_raycast_types() { if (raycast_occlusion_cull) { memdelete(raycast_occlusion_cull); } +#ifdef TOOLS_ENABLED + StaticRaycasterEmbree::free(); +#endif } diff --git a/modules/raycast/static_raycaster.cpp b/modules/raycast/static_raycaster.cpp new file mode 100644 index 0000000000..2ba65eebf8 --- /dev/null +++ b/modules/raycast/static_raycaster.cpp @@ -0,0 +1,137 @@ +/*************************************************************************/ +/* static_raycaster.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 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 <pmmintrin.h> +#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<Ray> &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 Set<int> &p_mesh_ids) { + for (Set<int>::Element *E = p_mesh_ids.front(); E; E = E->next()) { + rtcDisableGeometry(rtcGetGeometry(embree_scene, E->get())); + } + 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())); + } + 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 new file mode 100644 index 0000000000..6b13ecf690 --- /dev/null +++ b/modules/raycast/static_raycaster.h @@ -0,0 +1,64 @@ +/*************************************************************************/ +/* static_raycaster.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 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 <embree3/rtcore.h> + +class StaticRaycasterEmbree : public StaticRaycaster { + GDCLASS(StaticRaycasterEmbree, StaticRaycaster); + +private: + static RTCDevice embree_device; + RTCScene embree_scene; + + Set<int> filter_meshes; + +public: + virtual bool intersect(Ray &p_ray) override; + virtual void intersect(Vector<Ray> &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 Set<int> &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 |