1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-11 13:10:58 +00:00

Improvements and fixes to occluders

Improvements:
* Occluder3D is now an abstract type inherited by: ArrayOccluder3D, QuadOccluder3D, BoxOccluder3D, SphereOccluder3D and PolygonOccluder3D. ArrayOccluder3D serves the same purpose as the old Occluder3D (triangle mesh occluder) while the rest are primitives that can be used to manually place simple occluders.
* Occluder baking can now apply simplification. The "bake_simplification_distance" property can be used to set a world-space distance as the desired maximum error, set to 0.1 by default.
* Occluders can now be generated on import. Using the "occ" and "occonly" keywords (similar to "col" and "colonly" for colliders) or by enabling on MeshInstance3Ds in the scene's import window.

Fixes:
* Fixed saving of occluder files after bake.
* Fixed a small error where occluders didn't correctly update in the rendering server.

Bonus content:
* Generalized "CollisionPolygon3DEditor" so it can also be used to edit Resources. Renamed it to "Polygon3DEditor" since it was already being used by other things, not just colliders.
* Fixed a small bug in "EditorPropertyArray" where a call to "remove" was left after the "remove_at" rename.
This commit is contained in:
jfons
2022-02-04 16:28:18 +01:00
parent 6f425242dc
commit dd970482c5
23 changed files with 1198 additions and 189 deletions

View File

@@ -37,6 +37,44 @@ SurfaceTool::SimplifyFunc SurfaceTool::simplify_func = nullptr;
SurfaceTool::SimplifyWithAttribFunc SurfaceTool::simplify_with_attrib_func = nullptr;
SurfaceTool::SimplifyScaleFunc SurfaceTool::simplify_scale_func = nullptr;
SurfaceTool::SimplifySloppyFunc SurfaceTool::simplify_sloppy_func = nullptr;
SurfaceTool::GenerateRemapFunc SurfaceTool::generate_remap_func = nullptr;
SurfaceTool::RemapVertexFunc SurfaceTool::remap_vertex_func = nullptr;
SurfaceTool::RemapIndexFunc SurfaceTool::remap_index_func = nullptr;
void SurfaceTool::strip_mesh_arrays(PackedVector3Array &r_vertices, PackedInt32Array &r_indices) {
ERR_FAIL_COND_MSG(!generate_remap_func || !remap_vertex_func || !remap_index_func, "Meshoptimizer library is not initialized.");
Vector<uint32_t> remap;
remap.resize(r_vertices.size());
uint32_t new_vertex_count = generate_remap_func(remap.ptrw(), (unsigned int *)r_indices.ptr(), r_indices.size(), (float *)r_vertices.ptr(), r_vertices.size(), sizeof(Vector3));
remap_vertex_func(r_vertices.ptrw(), r_vertices.ptr(), r_vertices.size(), sizeof(Vector3), remap.ptr());
r_vertices.resize(new_vertex_count);
remap_index_func((unsigned int *)r_indices.ptrw(), (unsigned int *)r_indices.ptr(), r_indices.size(), remap.ptr());
HashMap<const int *, bool, TriangleHasher, TriangleHasher> found_triangles;
int *idx_ptr = r_indices.ptrw();
int filtered_indices_count = 0;
for (int i = 0; i < r_indices.size() / 3; i++) {
const int *tri = idx_ptr + (i * 3);
if (tri[0] == tri[1] || tri[1] == tri[2] || tri[2] == tri[0]) {
continue;
}
if (found_triangles.has(tri)) {
continue;
}
if (i != filtered_indices_count) {
memcpy(idx_ptr + (filtered_indices_count * 3), tri, sizeof(int) * 3);
}
found_triangles[tri] = true;
filtered_indices_count++;
}
r_indices.resize(filtered_indices_count * 3);
}
bool SurfaceTool::Vertex::operator==(const Vertex &p_vertex) const {
if (vertex != p_vertex.vertex) {
@@ -107,6 +145,47 @@ uint32_t SurfaceTool::VertexHasher::hash(const Vertex &p_vtx) {
return h;
}
uint32_t SurfaceTool::TriangleHasher::hash(const int *p_triangle) {
int t0 = p_triangle[0];
int t1 = p_triangle[1];
int t2 = p_triangle[2];
if (t0 > t1)
SWAP(t0, t1);
if (t1 > t2)
SWAP(t1, t2);
if (t0 > t1)
SWAP(t0, t1);
return (t0 * 73856093) ^ (t1 * 19349663) ^ (t2 * 83492791);
}
bool SurfaceTool::TriangleHasher::compare(const int *p_lhs, const int *p_rhs) {
int r0 = p_rhs[0];
int r1 = p_rhs[1];
int r2 = p_rhs[2];
if (r0 > r1)
SWAP(r0, r1);
if (r1 > r2)
SWAP(r1, r2);
if (r0 > r1)
SWAP(r0, r1);
int l0 = p_lhs[0];
int l1 = p_lhs[1];
int l2 = p_lhs[2];
if (l0 > l1)
SWAP(l0, l1);
if (l1 > l2)
SWAP(l1, l2);
if (l0 > l1)
SWAP(l0, l1);
return l0 == r0 && l1 == r1 && l2 == r2;
}
void SurfaceTool::begin(Mesh::PrimitiveType p_primitive) {
clear();