mirror of https://github.com/minetest/minetest.git
Merge 8109f07a43
into b23042839b
This commit is contained in:
commit
280acfc7c4
|
@ -617,6 +617,7 @@ void Client::step(float dtime)
|
|||
else {
|
||||
// Replace with the new mesh
|
||||
block->mesh = r.mesh;
|
||||
getEnv().getClientMap().updateMesh(block->mesh);
|
||||
if (r.urgent)
|
||||
force_update_shadows = true;
|
||||
}
|
||||
|
|
|
@ -137,7 +137,8 @@ ClientMap::~ClientMap()
|
|||
|
||||
void ClientMap::updateCamera(v3f pos, v3f dir, f32 fov, v3s16 offset, video::SColor light_color)
|
||||
{
|
||||
v3s16 previous_node = floatToInt(m_camera_position, BS) + m_camera_offset;
|
||||
v3s16 prev_pos = floatToInt(m_camera_position, BS);
|
||||
v3s16 previous_node = prev_pos + m_camera_offset;
|
||||
v3s16 previous_block = getContainerPos(previous_node, MAP_BLOCKSIZE);
|
||||
|
||||
m_camera_position = pos;
|
||||
|
@ -146,7 +147,8 @@ void ClientMap::updateCamera(v3f pos, v3f dir, f32 fov, v3s16 offset, video::SCo
|
|||
m_camera_offset = offset;
|
||||
m_camera_light_color = light_color;
|
||||
|
||||
v3s16 current_node = floatToInt(m_camera_position, BS) + m_camera_offset;
|
||||
v3s16 curr_pos = floatToInt(m_camera_position, BS);
|
||||
v3s16 current_node = curr_pos + m_camera_offset;
|
||||
v3s16 current_block = getContainerPos(current_node, MAP_BLOCKSIZE);
|
||||
|
||||
// reorder the blocks when camera crosses block boundary
|
||||
|
@ -156,6 +158,33 @@ void ClientMap::updateCamera(v3f pos, v3f dir, f32 fov, v3s16 offset, video::SCo
|
|||
// reorder transparent meshes when camera crosses node boundary
|
||||
if (previous_node != current_node)
|
||||
m_needs_update_transparent_meshes = true;
|
||||
|
||||
/* update liquid hideable sides materials if neccessary
|
||||
* This is used to hide specific liquid sides on a liquid-glass boundary
|
||||
* if the player is in the specific liquid.
|
||||
*/
|
||||
if (prev_pos != curr_pos) {
|
||||
MapNode prev_node = getNode(prev_pos);
|
||||
MapNode curr_node = getNode(curr_pos);
|
||||
|
||||
const NodeDefManager *ndef = m_client->getNodeDefManager();
|
||||
const ContentFeatures &prev_f = ndef->get(prev_node.getContent());
|
||||
const ContentFeatures &curr_f = ndef->get(curr_node.getContent());
|
||||
|
||||
if ( (prev_f.liquid_alternative_source_id != curr_f.liquid_alternative_source_id) ||
|
||||
(prev_f.liquid_alternative_flowing_id != curr_f.liquid_alternative_flowing_id)) {
|
||||
m_camera_liquid_source_id = curr_f.liquid_alternative_source_id;
|
||||
m_camera_liquid_flowing_id = curr_f.liquid_alternative_flowing_id;
|
||||
for (auto &i : m_drawlist) {
|
||||
i.second->mesh->updateHideable(m_camera_liquid_source_id, m_camera_liquid_flowing_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ClientMap::updateMesh(MapBlockMesh *mesh)
|
||||
{
|
||||
mesh->updateHideable(m_camera_liquid_source_id, m_camera_liquid_flowing_id);
|
||||
}
|
||||
|
||||
MapSector * ClientMap::emergeSector(v2s16 p2d)
|
||||
|
@ -263,6 +292,13 @@ private:
|
|||
v3s16 volume;
|
||||
};
|
||||
|
||||
void ClientMap::addBlockToDrawList(v3s16 pos, MapBlock *block)
|
||||
{
|
||||
block->refGrab();
|
||||
block->mesh->updateHideable(m_camera_liquid_source_id, m_camera_liquid_flowing_id);
|
||||
m_drawlist.emplace(pos, block);
|
||||
}
|
||||
|
||||
void ClientMap::updateDrawList()
|
||||
{
|
||||
ScopeProfiler sp(g_profiler, "CM::updateDrawList()", SPT_AVG);
|
||||
|
@ -398,8 +434,7 @@ void ClientMap::updateDrawList()
|
|||
block->refGrab();
|
||||
} else if (mesh) {
|
||||
// without mesh chunking we can add the block to the drawlist
|
||||
block->refGrab();
|
||||
m_drawlist.emplace(block->getPos(), block);
|
||||
addBlockToDrawList(block->getPos(), block);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -506,8 +541,7 @@ void ClientMap::updateDrawList()
|
|||
}
|
||||
} else if (mesh) {
|
||||
// without mesh chunking we can add the block to the drawlist
|
||||
block->refGrab();
|
||||
m_drawlist.emplace(block_coord, block);
|
||||
addBlockToDrawList(block_coord, block);
|
||||
}
|
||||
|
||||
// Decide which sides to traverse next or to block away
|
||||
|
@ -618,8 +652,7 @@ void ClientMap::updateDrawList()
|
|||
for (auto pos : shortlist) {
|
||||
MapBlock *block = getBlockNoCreateNoEx(pos);
|
||||
if (block) {
|
||||
block->refGrab();
|
||||
m_drawlist.emplace(pos, block);
|
||||
addBlockToDrawList(pos, block);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -63,6 +63,7 @@ public:
|
|||
}
|
||||
|
||||
void updateCamera(v3f pos, v3f dir, f32 fov, v3s16 offset, video::SColor light_color);
|
||||
void updateMesh(MapBlockMesh *mesh);
|
||||
|
||||
/*
|
||||
Forcefully get a sector from somewhere
|
||||
|
@ -125,6 +126,8 @@ private:
|
|||
// update the vertex order in transparent mesh buffers
|
||||
void updateTransparentMeshBuffers();
|
||||
|
||||
// help method for updateDrawList
|
||||
void addBlockToDrawList(v3s16 pos, MapBlock *block);
|
||||
|
||||
// Orders blocks by distance to the camera
|
||||
class MapBlockComparer
|
||||
|
@ -181,6 +184,9 @@ private:
|
|||
video::SColor m_camera_light_color = video::SColor(0xFFFFFFFF);
|
||||
bool m_needs_update_transparent_meshes = true;
|
||||
|
||||
content_t m_camera_liquid_source_id = CONTENT_IGNORE;
|
||||
content_t m_camera_liquid_flowing_id = CONTENT_IGNORE;
|
||||
|
||||
std::map<v3s16, MapBlock*, MapBlockComparer> m_drawlist;
|
||||
std::vector<MapBlock*> m_keeplist;
|
||||
std::map<v3s16, MapBlock*> m_drawlist_shadow;
|
||||
|
|
|
@ -83,6 +83,7 @@ MapblockMeshGenerator::MapblockMeshGenerator(MeshMakeData *input, MeshCollector
|
|||
enable_mesh_cache(g_settings->getBool("enable_mesh_cache") &&
|
||||
!data->m_smooth_lighting) // Mesh cache is not supported with smooth lighting
|
||||
{
|
||||
cam_f = &nodedef->get(data->m_cameranode);
|
||||
}
|
||||
|
||||
void MapblockMeshGenerator::useTile(int index, u8 set_flags, u8 reset_flags, bool special)
|
||||
|
@ -425,6 +426,7 @@ void MapblockMeshGenerator::drawSolidNode()
|
|||
MapNode neighbor = data->m_vmanip.getNodeNoEx(p2);
|
||||
content_t n2 = neighbor.getContent();
|
||||
bool backface_culling = cur_node.f->drawtype == NDT_NORMAL;
|
||||
bool is_hideable = false;
|
||||
if (n2 == n1)
|
||||
continue;
|
||||
if (n2 == CONTENT_IGNORE)
|
||||
|
@ -436,6 +438,9 @@ void MapblockMeshGenerator::drawSolidNode()
|
|||
if (cur_node.f->drawtype == NDT_LIQUID) {
|
||||
if (cur_node.f->sameLiquidRender(f2))
|
||||
continue;
|
||||
if (f2.drawtype == NDT_GLASSLIKE) {
|
||||
is_hideable = true;
|
||||
}
|
||||
backface_culling = f2.solidness || f2.visual_solidness;
|
||||
}
|
||||
}
|
||||
|
@ -446,6 +451,11 @@ void MapblockMeshGenerator::drawSolidNode()
|
|||
layer.material_flags |= MATERIAL_FLAG_BACKFACE_CULLING;
|
||||
layer.material_flags |= MATERIAL_FLAG_TILEABLE_HORIZONTAL;
|
||||
layer.material_flags |= MATERIAL_FLAG_TILEABLE_VERTICAL;
|
||||
if (is_hideable) {
|
||||
layer.material_flags |= MATERIAL_FLAG_HIDDABLE;
|
||||
layer.liquid_source_id = cur_node.f->liquid_alternative_source_id;
|
||||
layer.liquid_flowing_id = cur_node.f->liquid_alternative_flowing_id;
|
||||
}
|
||||
}
|
||||
if (!data->m_smooth_lighting) {
|
||||
lights[face] = getFaceLight(cur_node.n, neighbor, nodedef);
|
||||
|
|
|
@ -91,6 +91,9 @@ private:
|
|||
f32 scale;
|
||||
} cur_node;
|
||||
|
||||
// camera node
|
||||
const ContentFeatures *cam_f;
|
||||
|
||||
// lighting
|
||||
void getSmoothLightFrame();
|
||||
LightInfo blendLight(const v3f &vertex_pos);
|
||||
|
|
|
@ -19,6 +19,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
|
||||
#include "mapblock_mesh.h"
|
||||
#include "client.h"
|
||||
#include "camera.h"
|
||||
#include "mapblock.h"
|
||||
#include "map.h"
|
||||
#include "noise.h"
|
||||
|
@ -39,11 +40,21 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
MeshMakeData
|
||||
*/
|
||||
|
||||
MeshMakeData::MeshMakeData(const NodeDefManager *ndef, u16 side_length, bool use_shaders):
|
||||
MeshMakeData::MeshMakeData(Client *client, u16 side_length, bool use_shaders):
|
||||
side_length(side_length),
|
||||
nodedef(client->getNodeDefManager()),
|
||||
m_use_shaders(use_shaders)
|
||||
{
|
||||
v3s16 pos = floatToInt(client->getCamera()->getPosition(), BS);
|
||||
m_cameranode = client->getEnv().getMap().getNode(pos);
|
||||
}
|
||||
MeshMakeData::MeshMakeData(const NodeDefManager *ndef, MapNode &cameranode, u16 side_length, bool use_shaders):
|
||||
side_length(side_length),
|
||||
nodedef(ndef),
|
||||
m_cameranode(cameranode),
|
||||
m_use_shaders(use_shaders)
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
void MeshMakeData::fillBlockDataBegin(const v3s16 &blockpos)
|
||||
{
|
||||
|
@ -617,6 +628,7 @@ MapBlockMesh::MapBlockMesh(Client *client, MeshMakeData *data, v3s16 camera_offs
|
|||
m_last_crack(-1),
|
||||
m_last_daynight_ratio((u32) -1)
|
||||
{
|
||||
m_texture_blank = m_tsrc->getTextureForMesh("blank.png", &m_texture_blank_id);
|
||||
for (auto &m : m_mesh)
|
||||
m = new scene::SMesh();
|
||||
m_enable_shaders = data->m_use_shaders;
|
||||
|
@ -713,6 +725,16 @@ MapBlockMesh::MapBlockMesh(Client *client, MeshMakeData *data, v3s16 camera_offs
|
|||
p.layer.texture = (*p.layer.frames)[0].texture;
|
||||
}
|
||||
|
||||
// - Texture hideable
|
||||
if (p.layer.material_flags & MATERIAL_FLAG_HIDDABLE) {
|
||||
// Add to MapBlockMesh to hideable
|
||||
auto &info = m_hideable_info[{layer, i}];
|
||||
info.hidden = false;
|
||||
info.liquid_source_id = p.layer.liquid_source_id;
|
||||
info.liquid_flowing_id = p.layer.liquid_flowing_id;
|
||||
info.tile = p.layer;
|
||||
}
|
||||
|
||||
if (!m_enable_shaders) {
|
||||
// Extract colors for day-night animation
|
||||
// Dummy sunlight to handle non-sunlit areas
|
||||
|
@ -888,6 +910,28 @@ bool MapBlockMesh::animate(bool faraway, float time, int crack,
|
|||
return true;
|
||||
}
|
||||
|
||||
void MapBlockMesh::updateHideable(content_t liquid_source_id, content_t liquid_flowing_id)
|
||||
{
|
||||
// Texture animation
|
||||
for (auto &it : m_hideable_info) {
|
||||
const TileLayer &tile = it.second.tile;
|
||||
|
||||
scene::IMeshBuffer *buf = m_mesh[it.first.first]->getMeshBuffer(it.first.second);
|
||||
|
||||
bool hide = (it.second.liquid_source_id == liquid_source_id) &&
|
||||
(it.second.liquid_flowing_id == liquid_flowing_id);
|
||||
if (it.second.hidden != hide) {
|
||||
buf->getMaterial().setTexture(0, hide ? m_texture_blank : tile.texture);
|
||||
if (m_enable_shaders) {
|
||||
if (tile.normal_texture)
|
||||
buf->getMaterial().setTexture(1, hide ? m_texture_blank : tile.normal_texture);
|
||||
buf->getMaterial().setTexture(2, hide ? m_texture_blank : tile.flags_texture);
|
||||
}
|
||||
it.second.hidden = hide;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MapBlockMesh::updateTransparentBuffers(v3f camera_pos, v3s16 block_pos)
|
||||
{
|
||||
// nothing to do if the entire block is opaque
|
||||
|
|
|
@ -49,9 +49,11 @@ struct MeshMakeData
|
|||
u16 side_length;
|
||||
|
||||
const NodeDefManager *nodedef;
|
||||
MapNode m_cameranode;
|
||||
bool m_use_shaders;
|
||||
|
||||
MeshMakeData(const NodeDefManager *ndef, u16 side_length, bool use_shaders);
|
||||
MeshMakeData(Client *client, u16 side_length, bool use_shaders);
|
||||
MeshMakeData(const NodeDefManager *ndef, MapNode &cameranode, u16 side_length, bool use_shaders);
|
||||
|
||||
/*
|
||||
Copy block data manually (to allow optimizations by the caller)
|
||||
|
@ -192,6 +194,8 @@ public:
|
|||
// Returns true if anything has been changed.
|
||||
bool animate(bool faraway, float time, int crack, u32 daynight_ratio);
|
||||
|
||||
void updateHideable(content_t liquid_source_id, content_t liquid_flowing_id);
|
||||
|
||||
scene::IMesh *getMesh()
|
||||
{
|
||||
return m_mesh[0];
|
||||
|
@ -242,11 +246,19 @@ private:
|
|||
int frame_offset;
|
||||
TileLayer tile;
|
||||
};
|
||||
struct HideableInfo {
|
||||
bool hidden;
|
||||
content_t liquid_source_id;
|
||||
content_t liquid_flowing_id;
|
||||
TileLayer tile;
|
||||
};
|
||||
|
||||
scene::IMesh *m_mesh[MAX_TILE_LAYERS];
|
||||
std::vector<MinimapMapblock*> m_minimap_mapblocks;
|
||||
ITextureSource *m_tsrc;
|
||||
IShaderSource *m_shdrsrc;
|
||||
video::ITexture *m_texture_blank;
|
||||
u32 m_texture_blank_id;
|
||||
|
||||
f32 m_bounding_radius;
|
||||
v3f m_bounding_sphere_center;
|
||||
|
@ -268,6 +280,10 @@ private:
|
|||
// Keys are pairs of (mesh index, buffer index in the mesh)
|
||||
std::map<std::pair<u8, u32>, AnimationInfo> m_animation_info;
|
||||
|
||||
// Hideable info: hideable textures
|
||||
// Used for better rendering under liquids
|
||||
std::map<std::pair<u8, u32>, HideableInfo> m_hideable_info;
|
||||
|
||||
// Animation info: day/night transitions
|
||||
// Last daynight_ratio value passed to animate()
|
||||
u32 m_last_daynight_ratio;
|
||||
|
|
|
@ -190,7 +190,7 @@ void MeshUpdateQueue::done(v3s16 pos)
|
|||
void MeshUpdateQueue::fillDataFromMapBlocks(QueuedMeshUpdate *q)
|
||||
{
|
||||
auto mesh_grid = m_client->getMeshGrid();
|
||||
MeshMakeData *data = new MeshMakeData(m_client->ndef(), MAP_BLOCKSIZE * mesh_grid.cell_size, m_cache_enable_shaders);
|
||||
MeshMakeData *data = new MeshMakeData(m_client, MAP_BLOCKSIZE * mesh_grid.cell_size, m_cache_enable_shaders);
|
||||
q->data = data;
|
||||
|
||||
data->fillBlockDataBegin(q->p);
|
||||
|
|
|
@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#include <ITexture.h>
|
||||
#include <vector>
|
||||
#include <SMaterial.h>
|
||||
#include "mapnode.h"
|
||||
|
||||
enum MaterialType{
|
||||
TILE_MATERIAL_BASIC,
|
||||
|
@ -51,6 +52,7 @@ enum MaterialType{
|
|||
//#define MATERIAL_FLAG_HIGHLIGHTED 0x10
|
||||
#define MATERIAL_FLAG_TILEABLE_HORIZONTAL 0x20
|
||||
#define MATERIAL_FLAG_TILEABLE_VERTICAL 0x40
|
||||
#define MATERIAL_FLAG_HIDDABLE 0x80
|
||||
|
||||
/*
|
||||
This fully defines the looks of a tile.
|
||||
|
@ -121,6 +123,9 @@ struct TileLayer
|
|||
|
||||
u32 texture_id = 0;
|
||||
|
||||
content_t liquid_source_id;
|
||||
content_t liquid_flowing_id;
|
||||
|
||||
u16 animation_frame_length_ms = 0;
|
||||
u16 animation_frame_count = 1;
|
||||
|
||||
|
@ -167,4 +172,7 @@ struct TileSpec
|
|||
u8 emissive_light = 0;
|
||||
//! The first is base texture, the second is overlay.
|
||||
TileLayer layers[MAX_TILE_LAYERS];
|
||||
//Specify liquid for hide
|
||||
content_t liquid_source_id = CONTENT_IGNORE;
|
||||
content_t liquid_flowing_id = CONTENT_IGNORE;
|
||||
};
|
||||
|
|
|
@ -315,7 +315,7 @@ void WieldMeshSceneNode::setExtruded(const std::string &imagename,
|
|||
static scene::SMesh *createSpecialNodeMesh(Client *client, MapNode n,
|
||||
std::vector<ItemPartColor> *colors, const ContentFeatures &f)
|
||||
{
|
||||
MeshMakeData mesh_make_data(client->ndef(), 1, false);
|
||||
MeshMakeData mesh_make_data(client, 1, false);
|
||||
MeshCollector collector(v3f(0.0f * BS), v3f());
|
||||
mesh_make_data.setSmoothLighting(false);
|
||||
MapblockMeshGenerator gen(&mesh_make_data, &collector,
|
||||
|
|
|
@ -53,7 +53,8 @@ public:
|
|||
|
||||
MeshMakeData makeSingleNodeMMD(bool smooth_lighting = true, bool for_shaders = true)
|
||||
{
|
||||
MeshMakeData data{ndef(), 1, for_shaders};
|
||||
MapNode cameranode(CONTENT_AIR);
|
||||
MeshMakeData data{ndef(), cameranode, 1, for_shaders};
|
||||
data.setSmoothLighting(smooth_lighting);
|
||||
data.m_blockpos = {0, 0, 0};
|
||||
for (s16 x = -1; x <= 1; x++)
|
||||
|
|
Loading…
Reference in New Issue