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)
*/
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
*/
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.
// 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()
{
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?
// 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()
// 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;
};
/*!
// 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);
/*!
* \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.
* \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);