]> git.lizzy.rs Git - dragonfireclient.git/blobdiff - src/client/mapblock_mesh.h
Merge branch 'master' of https://github.com/minetest/minetest
[dragonfireclient.git] / src / client / mapblock_mesh.h
index dd08433a193a15c6308f52cce8abafc433dacebd..5e2d70b755a204622131c7f389249a42ecb80a0d 100644 (file)
@@ -32,21 +32,21 @@ class IShaderSource;
        Mesh making stuff
 */
 
+
 class MapBlock;
 struct MinimapMapblock;
 
 struct MeshMakeData
 {
        VoxelManipulator m_vmanip;
-       v3s16 m_blockpos = v3s16(-1337, -1337, -1337);
-       v3s16 m_crack_pos_relative = v3s16(-1337, -1337, -1337);
+       v3s16 m_blockpos = v3s16(-1337,-1337,-1337);
+       v3s16 m_crack_pos_relative = v3s16(-1337,-1337,-1337);
        bool m_smooth_lighting = false;
 
        Client *m_client;
        bool m_use_shaders;
-       bool m_use_tangent_vertices;
 
-       MeshMakeData(Client *client, bool use_shaders, bool use_tangent_vertices = false);
+       MeshMakeData(Client *client, bool use_shaders);
 
        /*
                Copy block data manually (to allow optimizations by the caller)
@@ -60,11 +60,6 @@ struct MeshMakeData
        */
        void fill(MapBlock *block);
 
-       /*
-               Set up with only a single node at (1,1,1)
-       */
-       void fillSingleNode(MapNode *node);
-
        /*
                Set the (node) position of a crack
        */
@@ -76,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.
 
@@ -102,9 +182,15 @@ class MapBlockMesh
        // Returns true if anything has been changed.
        bool animate(bool faraway, float time, int crack, u32 daynight_ratio);
 
-       scene::IMesh *getMesh() { return m_mesh[0]; }
+       scene::IMesh *getMesh()
+       {
+               return m_mesh[0];
+       }
 
-       scene::IMesh *getMesh(u8 layer) { return m_mesh[layer]; }
+       scene::IMesh *getMesh(u8 layer)
+       {
+               return m_mesh[layer];
+       }
 
        MinimapMapblock *moveMinimapMapblock()
        {
@@ -113,24 +199,42 @@ class MapBlockMesh
                return p;
        }
 
-       bool isAnimationForced() const { return m_animation_force_timer == 0; }
+       bool isAnimationForced() const
+       {
+               return m_animation_force_timer == 0;
+       }
 
        void decreaseAnimationForceTimer()
        {
-               if (m_animation_force_timer > 0)
+               if(m_animation_force_timer > 0)
                        m_animation_force_timer--;
        }
 
-       void updateCameraOffset(v3s16 camera_offset);
+       /// 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;
+       }
+
+       std::set<v3s16> esp_nodes;
 
 private:
+       struct AnimationInfo {
+               int frame; // last animation frame
+               int frame_offset;
+               TileLayer tile;
+       };
+
        scene::IMesh *m_mesh[MAX_TILE_LAYERS];
        MinimapMapblock *m_minimap_mapblock;
        ITextureSource *m_tsrc;
        IShaderSource *m_shdrsrc;
 
        bool m_enable_shaders;
-       bool m_use_tangent_vertices;
        bool m_enable_vbo;
 
        // Must animate() be called before rendering?
@@ -143,12 +247,10 @@ class MapBlockMesh
        // Maps mesh and mesh buffer (i.e. material) indices to base texture names
        std::map<std::pair<u8, u32>, std::string> m_crack_materials;
 
-       // Animation info: texture animationi
+       // Animation info: texture animation
        // Maps mesh and mesh buffer indices to TileSpecs
        // Keys are pairs of (mesh index, buffer index in the mesh)
-       std::map<std::pair<u8, u32>, TileLayer> m_animation_tiles;
-       std::map<std::pair<u8, u32>, int> m_animation_frames; // last animation frame
-       std::map<std::pair<u8, u32>, int> m_animation_frame_offsets;
+       std::map<std::pair<u8, u32>, AnimationInfo> m_animation_info;
 
        // Animation info: day/night transitions
        // Last daynight_ratio value passed to animate()
@@ -156,10 +258,14 @@ class MapBlockMesh
        // For each mesh and mesh buffer, stores pre-baked colors
        // 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;
-
-       // Camera offset info -> do we have to translate the mesh?
-       v3s16 m_camera_offset;
+       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;
 };
 
 /*!
@@ -178,10 +284,9 @@ video::SColor encode_light(u16 light, u8 emissive_light);
 
 // Compute light at node
 u16 getInteriorLight(MapNode n, s32 increment, const NodeDefManager *ndef);
-u16 getFaceLight(
-               MapNode n, MapNode n2, const v3s16 &face_dir, const NodeDefManager *ndef);
-u16 getSmoothLightSolid(const v3s16 &p, const v3s16 &face_dir, const v3s16 &corner,
-               MeshMakeData *data);
+u16 getFaceLight(MapNode n, MapNode n2, const v3s16 &face_dir,
+       const NodeDefManager *ndef);
+u16 getSmoothLightSolid(const v3s16 &p, const v3s16 &face_dir, const v3s16 &corner, MeshMakeData *data);
 u16 getSmoothLightTransparent(const v3s16 &p, const v3s16 &corner, MeshMakeData *data);
 
 /*!
@@ -197,7 +302,8 @@ void get_sunlight_color(video::SColorf *sunlight, u32 daynight_ratio);
  * \param light first 8 bits are day light, second 8 bits are
  * night light
  */
-void final_color_blend(video::SColor *result, u16 light, u32 daynight_ratio);
+void final_color_blend(video::SColor *result,
+               u16 light, u32 daynight_ratio);
 
 /*!
  * Gives the final  SColor shown on screen.
@@ -206,14 +312,12 @@ void final_color_blend(video::SColor *result, u16 light, u32 daynight_ratio);
  * \param data the half-baked vertex color
  * \param dayLight color of the sunlight
  */
-void final_color_blend(video::SColor *result, const video::SColor &data,
-               const video::SColorf &dayLight);
+void final_color_blend(video::SColor *result,
+               const video::SColor &data, const video::SColorf &dayLight);
 
 // Retrieves the TileSpec of a face of a node
 // Adds MATERIAL_FLAG_CRACK if the node is cracked
 // TileSpec should be passed as reference due to the underlying TileFrame and its vector
 // TileFrame vector copy cost very much to client
-void getNodeTileN(MapNode mn, const v3s16 &p, u8 tileindex, MeshMakeData *data,
-               TileSpec &tile);
-void getNodeTile(MapNode mn, const v3s16 &p, const v3s16 &dir, MeshMakeData *data,
-               TileSpec &tile);
+void getNodeTileN(MapNode mn, const v3s16 &p, u8 tileindex, MeshMakeData *data, TileSpec &tile);
+void getNodeTile(MapNode mn, const v3s16 &p, const v3s16 &dir, MeshMakeData *data, TileSpec &tile);