godot_voxel/meshers/transvoxel/voxel_mesher_transvoxel.h
Marc Gilleron d4986489cf Fix rare bug with vertex sharing causing long spiky artifacts
Basically we were checking case code of the ReuseCell to know if we can
re-use a vertex from it, but sometimes the associated cell did not write
a re-usable vertex, and we were not resetting such vertex indices.
So in some cases, we were accessing a very old index.
The case code doesn't need to be remembered, we just reset the first vertex.
No need to check if the ReuseCell was empty, we can read the vertex directly,
as it will be -1 anyways if it isn't re-usable. At least, this fixed the bug
and did not reproduce after testing a lot of noise data sets.
2020-01-01 00:41:21 +00:00

62 lines
1.8 KiB
C++

#ifndef VOXEL_MESHER_TRANSVOXEL_H
#define VOXEL_MESHER_TRANSVOXEL_H
#include "../../cube_tables.h"
#include "../../util/fixed_array.h"
#include "../voxel_mesher.h"
#include <scene/resources/mesh.h>
class VoxelMesherTransvoxel : public VoxelMesher {
GDCLASS(VoxelMesherTransvoxel, VoxelMesher)
public:
static const int MIN_PADDING = 1;
static const int MAX_PADDING = 2;
VoxelMesherTransvoxel();
void build(VoxelMesher::Output &output, const VoxelBuffer &voxels) override;
VoxelMesher *clone() override;
protected:
static void _bind_methods();
private:
struct ReuseCell {
FixedArray<int, 4> vertices;
};
struct ReuseTransitionCell {
FixedArray<int, 12> vertices;
};
struct TransitionVoxels {
const VoxelBuffer *full_resolution_neighbor_voxels[Cube::SIDE_COUNT] = { nullptr };
};
void build_internal(const VoxelBuffer &voxels, unsigned int channel);
void build_transitions(const TransitionVoxels &p_voxels, unsigned int channel);
void build_transition(const VoxelBuffer &voxels, unsigned int channel, int direction);
Ref<ArrayMesh> build_transition_mesh(Ref<VoxelBuffer> voxels, int direction);
void reset_reuse_cells(Vector3i block_size);
void reset_reuse_cells_2d(Vector3i block_size);
ReuseCell &get_reuse_cell(Vector3i pos);
ReuseTransitionCell &get_reuse_cell_2d(int x, int y);
int emit_vertex(Vector3 primary, Vector3 normal, uint16_t border_mask, Vector3 secondary);
void clear_output();
void fill_surface_arrays(Array &arrays);
private:
FixedArray<std::vector<ReuseCell>, 2> _cache;
FixedArray<std::vector<ReuseTransitionCell>, 2> _cache_2d;
Vector3i _block_size;
std::vector<Vector3> _output_vertices;
std::vector<Vector3> _output_normals;
std::vector<Color> _output_extra;
std::vector<int> _output_indices;
};
#endif // VOXEL_MESHER_TRANSVOXEL_H