1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-08-01 17:38:41 +00:00

Add depth sorting for node faces (#11696)

Use BSP tree to order transparent triangles
https://en.wikipedia.org/wiki/Binary_space_partitioning
This commit is contained in:
x2048 2022-04-02 10:42:27 +02:00 committed by GitHub
parent 26c046a563
commit b0b9732359
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 628 additions and 92 deletions

View file

@ -71,6 +71,91 @@ struct MeshMakeData
void setSmoothLighting(bool smooth_lighting);
};
// represents a triangle as indexes into the vertex buffer in SMeshBuffer
class MeshTriangle
{
public:
scene::SMeshBuffer *buffer;
u16 p1, p2, p3;
v3f centroid;
float areaSQ;
void updateAttributes()
{
v3f v1 = buffer->getPosition(p1);
v3f v2 = buffer->getPosition(p2);
v3f v3 = buffer->getPosition(p3);
centroid = (v1 + v2 + v3) / 3;
areaSQ = (v2-v1).crossProduct(v3-v1).getLengthSQ() / 4;
}
v3f getNormal() const {
v3f v1 = buffer->getPosition(p1);
v3f v2 = buffer->getPosition(p2);
v3f v3 = buffer->getPosition(p3);
return (v2-v1).crossProduct(v3-v1);
}
};
/**
* Implements a binary space partitioning tree
* See also: https://en.wikipedia.org/wiki/Binary_space_partitioning
*/
class MapBlockBspTree
{
public:
MapBlockBspTree() {}
void buildTree(const std::vector<MeshTriangle> *triangles);
void traverse(v3f viewpoint, std::vector<s32> &output) const
{
traverse(root, viewpoint, output);
}
private:
// Tree node definition;
struct TreeNode
{
v3f normal;
v3f origin;
std::vector<s32> triangle_refs;
s32 front_ref;
s32 back_ref;
TreeNode() = default;
TreeNode(v3f normal, v3f origin, const std::vector<s32> &triangle_refs, s32 front_ref, s32 back_ref) :
normal(normal), origin(origin), triangle_refs(triangle_refs), front_ref(front_ref), back_ref(back_ref)
{}
};
s32 buildTree(v3f normal, v3f origin, float delta, const std::vector<s32> &list, u32 depth);
void traverse(s32 node, v3f viewpoint, std::vector<s32> &output) const;
const std::vector<MeshTriangle> *triangles = nullptr; // this reference is managed externally
std::vector<TreeNode> nodes; // list of nodes
s32 root = -1; // index of the root node
};
class PartialMeshBuffer
{
public:
PartialMeshBuffer(scene::SMeshBuffer *buffer, const std::vector<u16> &vertex_indexes) :
m_buffer(buffer), m_vertex_indexes(vertex_indexes)
{}
scene::IMeshBuffer *getBuffer() const { return m_buffer; }
const std::vector<u16> &getVertexIndexes() const { return m_vertex_indexes; }
void beforeDraw() const;
private:
scene::SMeshBuffer *m_buffer;
std::vector<u16> m_vertex_indexes;
};
/*
Holds a mesh for a mapblock.
@ -125,6 +210,15 @@ public:
m_animation_force_timer--;
}
/// update transparent buffers to render towards the camera
void updateTransparentBuffers(v3f camera_pos, v3s16 block_pos);
void consolidateTransparentBuffers();
/// get the list of transparent buffers
const std::vector<PartialMeshBuffer> &getTransparentBuffers() const
{
return this->m_transparent_buffers;
}
private:
scene::IMesh *m_mesh[MAX_TILE_LAYERS];
MinimapMapblock *m_minimap_mapblock;
@ -158,6 +252,13 @@ private:
// of sunlit vertices
// Keys are pairs of (mesh index, buffer index in the mesh)
std::map<std::pair<u8, u32>, std::map<u32, video::SColor > > m_daynight_diffs;
// list of all semitransparent triangles in the mapblock
std::vector<MeshTriangle> m_transparent_triangles;
// Binary Space Partitioning tree for the block
MapBlockBspTree m_bsp_tree;
// Ordered list of references to parts of transparent buffers to draw
std::vector<PartialMeshBuffer> m_transparent_buffers;
};
/*!