aboutsummaryrefslogtreecommitdiff
path: root/src/client
diff options
context:
space:
mode:
authorhecks <42101236+hecktest@users.noreply.github.com>2020-12-06 00:03:40 +0100
committerGitHub <noreply@github.com>2020-12-05 15:03:40 -0800
commit6d7067fd37a8084aca139ecab552982e0ee99582 (patch)
tree415c1659d452873b575703beed9001c3bc00cf08 /src/client
parent07e0b527cf3e6e4f1bf36823940216efef59d8c9 (diff)
downloadminetest-6d7067fd37a8084aca139ecab552982e0ee99582.tar.gz
minetest-6d7067fd37a8084aca139ecab552982e0ee99582.tar.bz2
minetest-6d7067fd37a8084aca139ecab552982e0ee99582.zip
Implement mapblock camera offset correctly (#10702)
Implement mapblock camera offset correctly - reduce client jitter Co-authored-by: hecktest <>
Diffstat (limited to 'src/client')
-rw-r--r--src/client/clientmap.cpp95
-rw-r--r--src/client/clientmap.h19
-rw-r--r--src/client/mapblock_mesh.cpp20
-rw-r--r--src/client/mapblock_mesh.h3
4 files changed, 63 insertions, 74 deletions
diff --git a/src/client/clientmap.cpp b/src/client/clientmap.cpp
index 09072858a..fa47df3f4 100644
--- a/src/client/clientmap.cpp
+++ b/src/client/clientmap.cpp
@@ -31,6 +31,37 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <algorithm>
#include "client/renderingengine.h"
+// struct MeshBufListList
+void MeshBufListList::clear()
+{
+ for (auto &list : lists)
+ list.clear();
+}
+
+void MeshBufListList::add(scene::IMeshBuffer *buf, v3s16 position, u8 layer)
+{
+ // Append to the correct layer
+ std::vector<MeshBufList> &list = lists[layer];
+ const video::SMaterial &m = buf->getMaterial();
+ for (MeshBufList &l : list) {
+ // comparing a full material is quite expensive so we don't do it if
+ // not even first texture is equal
+ if (l.m.TextureLayer[0].Texture != m.TextureLayer[0].Texture)
+ continue;
+
+ if (l.m == m) {
+ l.bufs.emplace_back(position, buf);
+ return;
+ }
+ }
+ MeshBufList l;
+ l.m = m;
+ l.bufs.emplace_back(position, buf);
+ list.emplace_back(l);
+}
+
+// ClientMap
+
ClientMap::ClientMap(
Client *client,
MapDrawControl &control,
@@ -182,9 +213,7 @@ void ClientMap::updateDrawList()
if not seen on display
*/
- if (block->mesh) {
- block->mesh->updateCameraOffset(m_camera_offset);
- } else {
+ if (!block->mesh) {
// Ignore if mesh doesn't exist
continue;
}
@@ -229,50 +258,6 @@ void ClientMap::updateDrawList()
g_profiler->avg("MapBlocks loaded [#]", blocks_loaded);
}
-struct MeshBufList
-{
- video::SMaterial m;
- std::vector<scene::IMeshBuffer*> bufs;
-};
-
-struct MeshBufListList
-{
- /*!
- * Stores the mesh buffers of the world.
- * The array index is the material's layer.
- * The vector part groups vertices by material.
- */
- std::vector<MeshBufList> lists[MAX_TILE_LAYERS];
-
- void clear()
- {
- for (auto &list : lists)
- list.clear();
- }
-
- void add(scene::IMeshBuffer *buf, u8 layer)
- {
- // Append to the correct layer
- std::vector<MeshBufList> &list = lists[layer];
- const video::SMaterial &m = buf->getMaterial();
- for (MeshBufList &l : list) {
- // comparing a full material is quite expensive so we don't do it if
- // not even first texture is equal
- if (l.m.TextureLayer[0].Texture != m.TextureLayer[0].Texture)
- continue;
-
- if (l.m == m) {
- l.bufs.push_back(buf);
- return;
- }
- }
- MeshBufList l;
- l.m = m;
- l.bufs.push_back(buf);
- list.push_back(l);
- }
-};
-
void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
{
bool is_transparent_pass = pass == scene::ESNRP_TRANSPARENT;
@@ -317,6 +302,7 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
MeshBufListList drawbufs;
for (auto &i : m_drawlist) {
+ v3s16 block_pos = i.first;
MapBlock *block = i.second;
// If the mesh of the block happened to get deleted, ignore it
@@ -382,7 +368,7 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
material.setFlag(video::EMF_WIREFRAME,
m_control.show_wireframe);
- drawbufs.add(buf, layer);
+ drawbufs.add(buf, block_pos, layer);
}
}
}
@@ -391,6 +377,9 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
TimeTaker draw("Drawing mesh buffers");
+ core::matrix4 m; // Model matrix
+ v3f offset = intToFloat(m_camera_offset, BS);
+
// Render all layers in order
for (auto &lists : drawbufs.lists) {
for (MeshBufList &list : lists) {
@@ -402,7 +391,13 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
}
driver->setMaterial(list.m);
- for (scene::IMeshBuffer *buf : list.bufs) {
+ for (auto &pair : list.bufs) {
+ scene::IMeshBuffer *buf = pair.second;
+
+ v3f block_wpos = intToFloat(pair.first * MAP_BLOCKSIZE, BS);
+ m.setTranslation(block_wpos - offset);
+
+ driver->setTransform(video::ETS_WORLD, m);
driver->drawMeshBuffer(buf);
vertex_count += buf->getVertexCount();
}
@@ -607,5 +602,3 @@ void ClientMap::PrintInfo(std::ostream &out)
{
out<<"ClientMap: ";
}
-
-
diff --git a/src/client/clientmap.h b/src/client/clientmap.h
index 172e3a1d6..57cc4427e 100644
--- a/src/client/clientmap.h
+++ b/src/client/clientmap.h
@@ -35,6 +35,25 @@ struct MapDrawControl
bool show_wireframe = false;
};
+struct MeshBufList
+{
+ video::SMaterial m;
+ std::vector<std::pair<v3s16,scene::IMeshBuffer*>> bufs;
+};
+
+struct MeshBufListList
+{
+ /*!
+ * Stores the mesh buffers of the world.
+ * The array index is the material's layer.
+ * The vector part groups vertices by material.
+ */
+ std::vector<MeshBufList> lists[MAX_TILE_LAYERS];
+
+ void clear();
+ void add(scene::IMeshBuffer *buf, v3s16 position, u8 layer);
+};
+
class Client;
class ITextureSource;
diff --git a/src/client/mapblock_mesh.cpp b/src/client/mapblock_mesh.cpp
index 6a59fabe3..dac25a066 100644
--- a/src/client/mapblock_mesh.cpp
+++ b/src/client/mapblock_mesh.cpp
@@ -1175,13 +1175,6 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset):
buf->drop();
}
- /*
- Do some stuff to the mesh
- */
- m_camera_offset = camera_offset;
- translateMesh(m_mesh[layer],
- intToFloat(data->m_blockpos * MAP_BLOCKSIZE - camera_offset, BS));
-
if (m_mesh[layer]) {
#if 0
// Usually 1-700 faces and 1-7 materials
@@ -1308,19 +1301,6 @@ bool MapBlockMesh::animate(bool faraway, float time, int crack,
return true;
}
-void MapBlockMesh::updateCameraOffset(v3s16 camera_offset)
-{
- if (camera_offset != m_camera_offset) {
- for (scene::IMesh *layer : m_mesh) {
- translateMesh(layer,
- intToFloat(m_camera_offset - camera_offset, BS));
- if (m_enable_vbo)
- layer->setDirty();
- }
- m_camera_offset = camera_offset;
- }
-}
-
video::SColor encode_light(u16 light, u8 emissive_light)
{
// Get components
diff --git a/src/client/mapblock_mesh.h b/src/client/mapblock_mesh.h
index 6a9c00ed5..0308b8161 100644
--- a/src/client/mapblock_mesh.h
+++ b/src/client/mapblock_mesh.h
@@ -160,9 +160,6 @@ 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;
-
- // Camera offset info -> do we have to translate the mesh?
- v3s16 m_camera_offset;
};
/*!