diff --git a/meshers/mesh_simplifier/mesh_simplifier.cpp b/meshers/mesh_simplifier/mesh_simplifier.cpp index 9ed9273..e1fc0f4 100644 --- a/meshers/mesh_simplifier/mesh_simplifier.cpp +++ b/meshers/mesh_simplifier/mesh_simplifier.cpp @@ -1,10 +1,21 @@ #include "mesh_simplifier.h" +#include "../voxel_mesher.h" + //Mesh Simplification //Mesh Simplification //Ported from https://github.com/Whinarn/UnityMeshSimplifier //Original license: MIT License Copyright (c) 2017 Mattias Edlund -void MeshSimplifier::initialize_mesh_simplify() { +void MeshSimplifier::initialize(Ref mesher) { + _mesher = mesher; + + _vertices = mesher->get_vertices(); + _normals = mesher->get_normals(); + _colors = mesher->get_colors(); + _uvs = mesher->get_uvs(); + _uv2s = mesher->get_uv2s(); + _indices = mesher->get_indices(); + if ((_indices.size() % 3) != 0) ERR_FAIL_MSG("The index array length must be a multiple of 3 in order to represent triangles."); @@ -18,6 +29,10 @@ void MeshSimplifier::initialize_mesh_simplify() { int v2 = _indices[offset + 2]; _mu_triangles[i] = MUTriangle(v0, v1, v2, 0); } + + for (int i = 0; i < _vertices.size(); ++i) { + _mu_vertices.append(MUVertex(_vertices[i])); + } } //private ResizableArray triangles = null; @@ -359,9 +374,6 @@ void MeshSimplifier::CompactMesh() { _mu_vertices[i].tcount = 0; } - //int lastSubMeshIndex = -1; - //subMeshOffsets = new int[subMeshCount]; - for (int i = 0; i < _mu_triangles.size(); i++) { MUTriangle triangle = _mu_triangles[i]; @@ -370,9 +382,7 @@ void MeshSimplifier::CompactMesh() { int iDest = triangle.va0; int iSrc = triangle.v0; _mu_vertices[iDest].p = _mu_vertices[iSrc].p; - if (vertBoneWeights != null) { - vertBoneWeights[iDest] = vertBoneWeights[iSrc]; - } + triangle.v0 = triangle.va0; } @@ -380,9 +390,7 @@ void MeshSimplifier::CompactMesh() { int iDest = triangle.va1; int iSrc = triangle.v1; _mu_vertices[iDest].p = _mu_vertices[iSrc].p; - if (vertBoneWeights != null) { - vertBoneWeights[iDest] = vertBoneWeights[iSrc]; - } + triangle.v1 = triangle.va1; } @@ -390,80 +398,40 @@ void MeshSimplifier::CompactMesh() { int iDest = triangle.va2; int iSrc = triangle.v2; _mu_vertices[iDest].p = _mu_vertices[iSrc].p; - if (vertBoneWeights != null) { - vertBoneWeights[iDest] = vertBoneWeights[iSrc]; - } + triangle.v2 = triangle.va2; } - int newTriangleIndex = dst++; + int newTriangleIndex = ++dst; _mu_triangles[newTriangleIndex] = triangle; _mu_vertices[triangle.v0].tcount = 1; _mu_vertices[triangle.v1].tcount = 1; _mu_vertices[triangle.v2].tcount = 1; - - //if (triangle.subMeshIndex > lastSubMeshIndex) { - // for (int j = lastSubMeshIndex + 1; j < triangle.subMeshIndex; j++) { - // subMeshOffsets[j] = newTriangleIndex; - // } - // subMeshOffsets[triangle.subMeshIndex] = newTriangleIndex; - // lastSubMeshIndex = triangle.subMeshIndex; - //} } } - //triangleCount = dst; - //for (int i = lastSubMeshIndex + 1; i < subMeshCount; i++) { - // subMeshOffsets[i] = triangleCount; - //} - _mu_triangles.resize(dst); dst = 0; - for (int i = 0; i < vertexCount; i++) { - var vert = vertices[i]; + for (int i = 0; i < _mu_vertices.size(); i++) { + MUVertex vert = _mu_vertices[i]; + if (vert.tcount > 0) { vert.tstart = dst; - vertices[i] = vert; + _mu_vertices[i] = vert; if (dst != i) { - vertices[dst].p = vert.p; - if (vertNormals != null) vertNormals[dst] = vertNormals[i]; - if (vertTangents != null) vertTangents[dst] = vertTangents[i]; - if (vertUV2D != null) { - for (int j = 0; j < UVChannelCount; j++) { - var vertUV = vertUV2D[j]; - if (vertUV != null) { - vertUV[dst] = vertUV[i]; - } - } - } - if (vertUV3D != null) { - for (int j = 0; j < UVChannelCount; j++) { - var vertUV = vertUV3D[j]; - if (vertUV != null) { - vertUV[dst] = vertUV[i]; - } - } - } - if (vertUV4D != null) { - for (int j = 0; j < UVChannelCount; j++) { - var vertUV = vertUV4D[j]; - if (vertUV != null) { - vertUV[dst] = vertUV[i]; - } - } - } - if (vertColors != null) vertColors[dst] = vertColors[i]; - if (vertBoneWeights != null) vertBoneWeights[dst] = vertBoneWeights[i]; + _mu_vertices[dst].p = vert.p; - if (blendShapes != null) { - for (int shapeIndex = 0; shapeIndex < this.blendShapes.Length; shapeIndex++) { - blendShapes[shapeIndex].MoveVertexElement(dst, i); - } - } + if (_normals.size() > 0) _normals[dst] = _normals[i]; + + if (_colors.size() > 0) _colors.set(dst, _colors[i]); + if (_uvs.size() > 0) _uvs.set(dst, _uvs[i]); + if (_uv2s.size() > 0) _uv2s.set(dst, _uv2s[i]); + if (_indices.size() > 0) _indices.set(dst, _indices[i]); } + ++dst; } } @@ -477,20 +445,12 @@ void MeshSimplifier::CompactMesh() { } //vertexCount = dst; - this.vertices.Resize(dst); - if (vertNormals != null) this.vertNormals.Resize(vertexCount, true); - if (vertTangents != null) this.vertTangents.Resize(vertexCount, true); - if (vertUV2D != null) this.vertUV2D.Resize(vertexCount, true); - if (vertUV3D != null) this.vertUV3D.Resize(vertexCount, true); - if (vertUV4D != null) this.vertUV4D.Resize(vertexCount, true); - if (vertColors != null) this.vertColors.Resize(vertexCount, true); - if (vertBoneWeights != null) this.vertBoneWeights.Resize(vertexCount, true); - - if (blendShapes != null) { - for (int i = 0; i < this.blendShapes.Length; i++) { - blendShapes[i].Resize(vertexCount, false); - } - } + _vertices.resize(dst); + if (_normals.size() > 0) _normals.resize(dst); + if (_colors.size() > 0) _colors.resize(dst); + if (_uvs.size() > 0) _uvs.resize(dst); + if (_uv2s.size() > 0) _uv2s.resize(dst); + if (_indices.size() > 0) _indices.resize(dst); } bool MeshSimplifier::AreUVsTheSame(int channel, int indexA, int indexB) { @@ -581,8 +541,10 @@ int MeshSimplifier::RemoveVertexPass(int startTrisCount, int targetTrisCount, do if (tcount <= _mu_vertices[i0].tcount) { // save ram if (tcount > 0) { - var refsArr = refs.Data; - Array.Copy(refsArr, tstart, refsArr, _mu_vertices[i0].tstart, tcount); + int dests = _mu_vertices[i0].tstart; + for (int v = 0; v < tcount; ++v) { + _mu_refs[v + tstart] = _mu_refs[v + dests]; + } } } else { // append @@ -736,32 +698,28 @@ Vector3 MeshSimplifier::CalculateBarycentricCoords(Vector3 const &point, Vector3 } void MeshSimplifier::InterpolateVertexAttributes(int dst, int i0, int i1, int i2, Vector3 &barycentricCoord) { - if (vertNormals != null) { - vertNormals[dst] = Vector3.Normalize((vertNormals[i0] * barycentricCoord.x) + (vertNormals[i1] * barycentricCoord.y) + (vertNormals[i2] * barycentricCoord.z)); + if (_normals.size() > 0) { + _normals[dst] = (_normals[i0] * barycentricCoord.x) + (_normals[i1] * barycentricCoord.y) + (_normals[i2] * barycentricCoord.z).normalized(); } - if (vertTangents != null) { - vertTangents[dst] = NormalizeTangent((vertTangents[i0] * barycentricCoord.x) + (vertTangents[i1] * barycentricCoord.y) + (vertTangents[i2] * barycentricCoord.z)); + if (_uvs.size() > 0) { + _uvs[dst] = (_uvs[i0] * barycentricCoord.x) + (_uvs[i1] * barycentricCoord.y) + (_uvs[i2] * barycentricCoord.z); } - if (vertUV2D != null) { - for (int i = 0; i < UVChannelCount; i++) { - var vertUV = vertUV2D[i]; - if (vertUV != null) { - vertUV[dst] = (vertUV[i0] * barycentricCoord.x) + (vertUV[i1] * barycentricCoord.y) + (vertUV[i2] * barycentricCoord.z); - } - } + if (_uv2s.size() > 0) { + _uv2s[dst] = (_uv2s[i0] * barycentricCoord.x) + (_uv2s[i1] * barycentricCoord.y) + (_uv2s[i2] * barycentricCoord.z); } - if (vertColors != null) { - vertColors[dst] = (vertColors[i0] * barycentricCoord.x) + (vertColors[i1] * barycentricCoord.y) + (vertColors[i2] * barycentricCoord.z); + if (_colors.size() > 0) { + _colors[dst] = (_colors[i0] * barycentricCoord.x) + (_colors[i1] * barycentricCoord.y) + (_colors[i2] * barycentricCoord.z); } - - if (blendShapes != null) { - for (int i = 0; i < blendShapes.Length; i++) { - blendShapes[i].InterpolateVertexAttributes(dst, i0, i1, i2, barycentricCoord); - } - } - - // TODO: How do we interpolate the bone weights? Do we have to? } + +MeshSimplifier::MeshSimplifier() { + maxIterationCount = 100; + agressiveness = 7.0; + enableSmartLink = true; + preserveBorderEdges = false; + preserveUVSeamEdges = false; + preserveUVFoldoverEdges = false; +} \ No newline at end of file diff --git a/meshers/mesh_simplifier/mesh_simplifier.h b/meshers/mesh_simplifier/mesh_simplifier.h index dc13074..861dd64 100644 --- a/meshers/mesh_simplifier/mesh_simplifier.h +++ b/meshers/mesh_simplifier/mesh_simplifier.h @@ -4,10 +4,14 @@ #include "mesh_utils.h" #include "core/pool_vector.h" +#include "core/resource.h" + +class VoxelMesher; class MeshSimplifier { - void initialize_mesh_simplify(); +public: + void initialize(Ref mesher); void SimplifyMesh(float quality); void SimplifyMeshLossless(); void UpdateMesh(int iteration); @@ -26,10 +30,22 @@ class MeshSimplifier { return (val1 < val2 ? (val1 < val3 ? val1 : val3) : (val2 < val3 ? val2 : val3)); } + MeshSimplifier(); + +private: + PoolVector _vertices; + PoolVector _normals; + PoolVector _colors; + PoolVector _uvs; + PoolVector _uv2s; + PoolVector _indices; + PoolVector _mu_triangles; PoolVector _mu_vertices; PoolVector _mu_refs; + Ref _mesher; + double vertexLinkDistanceSqr = std::numeric_limits::epsilon(); int maxIterationCount; double agressiveness; diff --git a/meshers/mesh_simplifier/mesh_utils.h b/meshers/mesh_simplifier/mesh_utils.h index 0c8c9a9..71a16bb 100644 --- a/meshers/mesh_simplifier/mesh_utils.h +++ b/meshers/mesh_simplifier/mesh_utils.h @@ -353,6 +353,15 @@ struct MUVertex { bool uvSeamEdge; bool uvFoldoverEdge; + MUVertex(float x, float y, float z) { + p = Vector3(x, y, z); + tstart = 0; + tcount = 0; + borderEdge = true; + uvSeamEdge = false; + uvFoldoverEdge = false; + } + MUVertex(Vector3 point) { p = point; tstart = 0; diff --git a/meshers/voxel_mesher.cpp b/meshers/voxel_mesher.cpp index c679c34..789f314 100644 --- a/meshers/voxel_mesher.cpp +++ b/meshers/voxel_mesher.cpp @@ -537,7 +537,7 @@ PoolVector VoxelMesher::get_vertices() { return _vertices; } -void VoxelMesher::set_vertices(PoolVector values) { +void VoxelMesher::set_vertices(const PoolVector &values) { _vertices = values; } @@ -561,7 +561,7 @@ PoolVector VoxelMesher::get_normals() { return _normals; } -void VoxelMesher::set_normals(PoolVector values) { +void VoxelMesher::set_normals(const PoolVector &values) { _normals = values; } @@ -585,7 +585,7 @@ PoolVector VoxelMesher::get_colors() { return _colors; } -void VoxelMesher::set_colors(PoolVector values) { +void VoxelMesher::set_colors(const PoolVector &values) { _colors = values; } @@ -609,7 +609,7 @@ PoolVector VoxelMesher::get_uvs() { return _uvs; } -void VoxelMesher::set_uvs(PoolVector values) { +void VoxelMesher::set_uvs(const PoolVector &values) { _uvs = values; } @@ -633,7 +633,7 @@ PoolVector VoxelMesher::get_uv2s() { return _uv2s; } -void VoxelMesher::set_uv2s(PoolVector values) { +void VoxelMesher::set_uv2s(const PoolVector &values) { _uv2s = values; } @@ -657,7 +657,7 @@ PoolVector VoxelMesher::get_indices() { return _indices; } -void VoxelMesher::set_indices(PoolVector values) { +void VoxelMesher::set_indices(const PoolVector values) { _indices = values; } @@ -695,13 +695,6 @@ VoxelMesher::VoxelMesher() { _uv_margin = Rect2(0, 0, 1, 1); _surface_tool.instance(); - - maxIterationCount = 100; - agressiveness = 7.0; - enableSmartLink = true; - preserveBorderEdges = false; - preserveUVSeamEdges = false; - preserveUVFoldoverEdges = false; } VoxelMesher::~VoxelMesher() { diff --git a/meshers/voxel_mesher.h b/meshers/voxel_mesher.h index 2ead453..5d755ad 100644 --- a/meshers/voxel_mesher.h +++ b/meshers/voxel_mesher.h @@ -17,8 +17,6 @@ #include "scene/resources/mesh.h" #include "scene/resources/surface_tool.h" -#include "mesh_utils.h" - #include "../../mesh_data_resource/mesh_data_resource.h" #include "../library/voxelman_library.h" @@ -79,42 +77,42 @@ public: void build_mesh(RID mesh); PoolVector get_vertices(); - void set_vertices(PoolVector values); + void set_vertices(const PoolVector &values); int get_vertex_count(); Vector3 get_vertex(int idx); void remove_vertex(int idx); void add_vertex(Vector3 vertex); PoolVector get_normals(); - void set_normals(PoolVector values); + void set_normals(const PoolVector &values); int get_normal_count(); Vector3 get_normal(int idx); void remove_normal(int idx); void add_normal(Vector3 normal); PoolVector get_colors(); - void set_colors(PoolVector values); + void set_colors(const PoolVector &values); int get_color_count(); Color get_color(int idx); void remove_color(int idx); void add_color(Color color); PoolVector get_uvs(); - void set_uvs(PoolVector values); + void set_uvs(const PoolVector &values); int get_uv_count(); Vector2 get_uv(int idx); void remove_uv(int idx); void add_uv(Vector2 vector); PoolVector get_uv2s(); - void set_uv2s(PoolVector values); + void set_uv2s(const PoolVector &values); int get_uv2_count(); Vector2 get_uv2(int idx); void remove_uv2(int idx); void add_uv2(Vector2 vector); PoolVector get_indices(); - void set_indices(PoolVector values); + void set_indices(const PoolVector values); int get_indices_count(); int get_indice(int idx); void remove_indices(int idx);