Consolidate some data structures in MapBlockMesh

This commit is contained in:
sfan5 2022-05-06 09:54:04 +02:00
parent 1fa4f58080
commit a66e6d4dff
2 changed files with 44 additions and 38 deletions

@ -1252,6 +1252,9 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset):
Convert MeshCollector to SMesh Convert MeshCollector to SMesh
*/ */
const bool desync_animations = g_settings->getBool(
"desynchronize_mapblock_texture_animation");
for (int layer = 0; layer < MAX_TILE_LAYERS; layer++) { for (int layer = 0; layer < MAX_TILE_LAYERS; layer++) {
for(u32 i = 0; i < collector.prebuffers[layer].size(); i++) for(u32 i = 0; i < collector.prebuffers[layer].size(); i++)
{ {
@ -1281,18 +1284,18 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset):
// - Texture animation // - Texture animation
if (p.layer.material_flags & MATERIAL_FLAG_ANIMATION) { if (p.layer.material_flags & MATERIAL_FLAG_ANIMATION) {
// Add to MapBlockMesh in order to animate these tiles // Add to MapBlockMesh in order to animate these tiles
m_animation_tiles[std::pair<u8, u32>(layer, i)] = p.layer; auto &info = m_animation_info[{layer, i}];
m_animation_frames[std::pair<u8, u32>(layer, i)] = 0; info.tile = p.layer;
if (g_settings->getBool( info.frame = 0;
"desynchronize_mapblock_texture_animation")) { if (desync_animations) {
// Get starting position from noise // Get starting position from noise
m_animation_frame_offsets[std::pair<u8, u32>(layer, i)] = info.frame_offset =
100000 * (2.0 + noise3d( 100000 * (2.0 + noise3d(
data->m_blockpos.X, data->m_blockpos.Y, data->m_blockpos.X, data->m_blockpos.Y,
data->m_blockpos.Z, 0)); data->m_blockpos.Z, 0));
} else { } else {
// Play all synchronized // Play all synchronized
m_animation_frame_offsets[std::pair<u8, u32>(layer, i)] = 0; info.frame_offset = 0;
} }
// Replace tile texture with the first animation frame // Replace tile texture with the first animation frame
p.layer.texture = (*p.layer.frames)[0].texture; p.layer.texture = (*p.layer.frames)[0].texture;
@ -1303,19 +1306,23 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset):
// Dummy sunlight to handle non-sunlit areas // Dummy sunlight to handle non-sunlit areas
video::SColorf sunlight; video::SColorf sunlight;
get_sunlight_color(&sunlight, 0); get_sunlight_color(&sunlight, 0);
u32 vertex_count = p.vertices.size();
std::map<u32, video::SColor> colors;
const u32 vertex_count = p.vertices.size();
for (u32 j = 0; j < vertex_count; j++) { for (u32 j = 0; j < vertex_count; j++) {
video::SColor *vc = &p.vertices[j].Color; video::SColor *vc = &p.vertices[j].Color;
video::SColor copy = *vc; video::SColor copy = *vc;
if (vc->getAlpha() == 0) // No sunlight - no need to animate if (vc->getAlpha() == 0) // No sunlight - no need to animate
final_color_blend(vc, copy, sunlight); // Finalize color final_color_blend(vc, copy, sunlight); // Finalize color
else // Record color to animate else // Record color to animate
m_daynight_diffs[std::pair<u8, u32>(layer, i)][j] = copy; colors[j] = copy;
// The sunlight ratio has been stored, // The sunlight ratio has been stored,
// delete alpha (for the final rendering). // delete alpha (for the final rendering).
vc->setAlpha(255); vc->setAlpha(255);
} }
if (!colors.empty())
m_daynight_diffs[{layer, i}] = std::move(colors);
} }
// Create material // Create material
@ -1384,7 +1391,7 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset):
m_has_animation = m_has_animation =
!m_crack_materials.empty() || !m_crack_materials.empty() ||
!m_daynight_diffs.empty() || !m_daynight_diffs.empty() ||
!m_animation_tiles.empty(); !m_animation_info.empty();
} }
MapBlockMesh::~MapBlockMesh() MapBlockMesh::~MapBlockMesh()
@ -1418,25 +1425,22 @@ bool MapBlockMesh::animate(bool faraway, float time, int crack,
for (auto &crack_material : m_crack_materials) { for (auto &crack_material : m_crack_materials) {
scene::IMeshBuffer *buf = m_mesh[crack_material.first.first]-> scene::IMeshBuffer *buf = m_mesh[crack_material.first.first]->
getMeshBuffer(crack_material.first.second); getMeshBuffer(crack_material.first.second);
std::string basename = crack_material.second;
// Create new texture name from original // Create new texture name from original
std::ostringstream os; std::string s = crack_material.second + itos(crack);
os << basename << crack;
u32 new_texture_id = 0; u32 new_texture_id = 0;
video::ITexture *new_texture = video::ITexture *new_texture =
m_tsrc->getTextureForMesh(os.str(), &new_texture_id); m_tsrc->getTextureForMesh(s, &new_texture_id);
buf->getMaterial().setTexture(0, new_texture); buf->getMaterial().setTexture(0, new_texture);
// If the current material is also animated, // If the current material is also animated, update animation info
// update animation info auto anim_it = m_animation_info.find(crack_material.first);
auto anim_iter = m_animation_tiles.find(crack_material.first); if (anim_it != m_animation_info.end()) {
if (anim_iter != m_animation_tiles.end()) { TileLayer &tile = anim_it->second.tile;
TileLayer &tile = anim_iter->second;
tile.texture = new_texture; tile.texture = new_texture;
tile.texture_id = new_texture_id; tile.texture_id = new_texture_id;
// force animation update // force animation update
m_animation_frames[crack_material.first] = -1; anim_it->second.frame = -1;
} }
} }
@ -1444,28 +1448,25 @@ bool MapBlockMesh::animate(bool faraway, float time, int crack,
} }
// Texture animation // Texture animation
for (auto &animation_tile : m_animation_tiles) { for (auto &it : m_animation_info) {
const TileLayer &tile = animation_tile.second; const TileLayer &tile = it.second.tile;
// Figure out current frame // Figure out current frame
int frameoffset = m_animation_frame_offsets[animation_tile.first]; int frameno = (int)(time * 1000 / tile.animation_frame_length_ms
int frame = (int)(time * 1000 / tile.animation_frame_length_ms + it.second.frame_offset) % tile.animation_frame_count;
+ frameoffset) % tile.animation_frame_count;
// If frame doesn't change, skip // If frame doesn't change, skip
if (frame == m_animation_frames[animation_tile.first]) if (frameno == it.second.frame)
continue; continue;
m_animation_frames[animation_tile.first] = frame; it.second.frame = frameno;
scene::IMeshBuffer *buf = m_mesh[animation_tile.first.first]-> scene::IMeshBuffer *buf = m_mesh[it.first.first]->getMeshBuffer(it.first.second);
getMeshBuffer(animation_tile.first.second);
const FrameSpec &animation_frame = (*tile.frames)[frame]; const FrameSpec &frame = (*tile.frames)[frameno];
buf->getMaterial().setTexture(0, animation_frame.texture); buf->getMaterial().setTexture(0, frame.texture);
if (m_enable_shaders) { if (m_enable_shaders) {
if (animation_frame.normal_texture) if (frame.normal_texture)
buf->getMaterial().setTexture(1, buf->getMaterial().setTexture(1, frame.normal_texture);
animation_frame.normal_texture); buf->getMaterial().setTexture(2, frame.flags_texture);
buf->getMaterial().setTexture(2, animation_frame.flags_texture);
} }
} }

@ -219,7 +219,14 @@ public:
{ {
return this->m_transparent_buffers; return this->m_transparent_buffers;
} }
private: private:
struct AnimationInfo {
int frame; // last animation frame
int frame_offset;
TileLayer tile;
};
scene::IMesh *m_mesh[MAX_TILE_LAYERS]; scene::IMesh *m_mesh[MAX_TILE_LAYERS];
MinimapMapblock *m_minimap_mapblock; MinimapMapblock *m_minimap_mapblock;
ITextureSource *m_tsrc; ITextureSource *m_tsrc;
@ -238,12 +245,10 @@ private:
// Maps mesh and mesh buffer (i.e. material) indices to base texture names // Maps mesh and mesh buffer (i.e. material) indices to base texture names
std::map<std::pair<u8, u32>, std::string> m_crack_materials; 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 // Maps mesh and mesh buffer indices to TileSpecs
// Keys are pairs of (mesh index, buffer index in the mesh) // 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>, AnimationInfo> m_animation_info;
std::map<std::pair<u8, u32>, int> m_animation_frames; // last animation frame
std::map<std::pair<u8, u32>, int> m_animation_frame_offsets;
// Animation info: day/night transitions // Animation info: day/night transitions
// Last daynight_ratio value passed to animate() // Last daynight_ratio value passed to animate()