Skip to content

Commit 6d7067f

Browse files
authoredDec 5, 2020
Implement mapblock camera offset correctly (#10702)
Implement mapblock camera offset correctly - reduce client jitter Co-authored-by: hecktest <>
1 parent 07e0b52 commit 6d7067f

File tree

4 files changed

+63
-74
lines changed

4 files changed

+63
-74
lines changed
 

‎src/client/clientmap.cpp

+44-51
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,37 @@ with this program; if not, write to the Free Software Foundation, Inc.,
3131
#include <algorithm>
3232
#include "client/renderingengine.h"
3333

34+
// struct MeshBufListList
35+
void MeshBufListList::clear()
36+
{
37+
for (auto &list : lists)
38+
list.clear();
39+
}
40+
41+
void MeshBufListList::add(scene::IMeshBuffer *buf, v3s16 position, u8 layer)
42+
{
43+
// Append to the correct layer
44+
std::vector<MeshBufList> &list = lists[layer];
45+
const video::SMaterial &m = buf->getMaterial();
46+
for (MeshBufList &l : list) {
47+
// comparing a full material is quite expensive so we don't do it if
48+
// not even first texture is equal
49+
if (l.m.TextureLayer[0].Texture != m.TextureLayer[0].Texture)
50+
continue;
51+
52+
if (l.m == m) {
53+
l.bufs.emplace_back(position, buf);
54+
return;
55+
}
56+
}
57+
MeshBufList l;
58+
l.m = m;
59+
l.bufs.emplace_back(position, buf);
60+
list.emplace_back(l);
61+
}
62+
63+
// ClientMap
64+
3465
ClientMap::ClientMap(
3566
Client *client,
3667
MapDrawControl &control,
@@ -182,9 +213,7 @@ void ClientMap::updateDrawList()
182213
if not seen on display
183214
*/
184215

185-
if (block->mesh) {
186-
block->mesh->updateCameraOffset(m_camera_offset);
187-
} else {
216+
if (!block->mesh) {
188217
// Ignore if mesh doesn't exist
189218
continue;
190219
}
@@ -229,50 +258,6 @@ void ClientMap::updateDrawList()
229258
g_profiler->avg("MapBlocks loaded [#]", blocks_loaded);
230259
}
231260

232-
struct MeshBufList
233-
{
234-
video::SMaterial m;
235-
std::vector<scene::IMeshBuffer*> bufs;
236-
};
237-
238-
struct MeshBufListList
239-
{
240-
/*!
241-
* Stores the mesh buffers of the world.
242-
* The array index is the material's layer.
243-
* The vector part groups vertices by material.
244-
*/
245-
std::vector<MeshBufList> lists[MAX_TILE_LAYERS];
246-
247-
void clear()
248-
{
249-
for (auto &list : lists)
250-
list.clear();
251-
}
252-
253-
void add(scene::IMeshBuffer *buf, u8 layer)
254-
{
255-
// Append to the correct layer
256-
std::vector<MeshBufList> &list = lists[layer];
257-
const video::SMaterial &m = buf->getMaterial();
258-
for (MeshBufList &l : list) {
259-
// comparing a full material is quite expensive so we don't do it if
260-
// not even first texture is equal
261-
if (l.m.TextureLayer[0].Texture != m.TextureLayer[0].Texture)
262-
continue;
263-
264-
if (l.m == m) {
265-
l.bufs.push_back(buf);
266-
return;
267-
}
268-
}
269-
MeshBufList l;
270-
l.m = m;
271-
l.bufs.push_back(buf);
272-
list.push_back(l);
273-
}
274-
};
275-
276261
void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
277262
{
278263
bool is_transparent_pass = pass == scene::ESNRP_TRANSPARENT;
@@ -317,6 +302,7 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
317302
MeshBufListList drawbufs;
318303

319304
for (auto &i : m_drawlist) {
305+
v3s16 block_pos = i.first;
320306
MapBlock *block = i.second;
321307

322308
// If the mesh of the block happened to get deleted, ignore it
@@ -382,7 +368,7 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
382368
material.setFlag(video::EMF_WIREFRAME,
383369
m_control.show_wireframe);
384370

385-
drawbufs.add(buf, layer);
371+
drawbufs.add(buf, block_pos, layer);
386372
}
387373
}
388374
}
@@ -391,6 +377,9 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
391377

392378
TimeTaker draw("Drawing mesh buffers");
393379

380+
core::matrix4 m; // Model matrix
381+
v3f offset = intToFloat(m_camera_offset, BS);
382+
394383
// Render all layers in order
395384
for (auto &lists : drawbufs.lists) {
396385
for (MeshBufList &list : lists) {
@@ -402,7 +391,13 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
402391
}
403392
driver->setMaterial(list.m);
404393

405-
for (scene::IMeshBuffer *buf : list.bufs) {
394+
for (auto &pair : list.bufs) {
395+
scene::IMeshBuffer *buf = pair.second;
396+
397+
v3f block_wpos = intToFloat(pair.first * MAP_BLOCKSIZE, BS);
398+
m.setTranslation(block_wpos - offset);
399+
400+
driver->setTransform(video::ETS_WORLD, m);
406401
driver->drawMeshBuffer(buf);
407402
vertex_count += buf->getVertexCount();
408403
}
@@ -607,5 +602,3 @@ void ClientMap::PrintInfo(std::ostream &out)
607602
{
608603
out<<"ClientMap: ";
609604
}
610-
611-

‎src/client/clientmap.h

+19
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,25 @@ struct MapDrawControl
3535
bool show_wireframe = false;
3636
};
3737

38+
struct MeshBufList
39+
{
40+
video::SMaterial m;
41+
std::vector<std::pair<v3s16,scene::IMeshBuffer*>> bufs;
42+
};
43+
44+
struct MeshBufListList
45+
{
46+
/*!
47+
* Stores the mesh buffers of the world.
48+
* The array index is the material's layer.
49+
* The vector part groups vertices by material.
50+
*/
51+
std::vector<MeshBufList> lists[MAX_TILE_LAYERS];
52+
53+
void clear();
54+
void add(scene::IMeshBuffer *buf, v3s16 position, u8 layer);
55+
};
56+
3857
class Client;
3958
class ITextureSource;
4059

‎src/client/mapblock_mesh.cpp

-20
Original file line numberDiff line numberDiff line change
@@ -1175,13 +1175,6 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset):
11751175
buf->drop();
11761176
}
11771177

1178-
/*
1179-
Do some stuff to the mesh
1180-
*/
1181-
m_camera_offset = camera_offset;
1182-
translateMesh(m_mesh[layer],
1183-
intToFloat(data->m_blockpos * MAP_BLOCKSIZE - camera_offset, BS));
1184-
11851178
if (m_mesh[layer]) {
11861179
#if 0
11871180
// Usually 1-700 faces and 1-7 materials
@@ -1308,19 +1301,6 @@ bool MapBlockMesh::animate(bool faraway, float time, int crack,
13081301
return true;
13091302
}
13101303

1311-
void MapBlockMesh::updateCameraOffset(v3s16 camera_offset)
1312-
{
1313-
if (camera_offset != m_camera_offset) {
1314-
for (scene::IMesh *layer : m_mesh) {
1315-
translateMesh(layer,
1316-
intToFloat(m_camera_offset - camera_offset, BS));
1317-
if (m_enable_vbo)
1318-
layer->setDirty();
1319-
}
1320-
m_camera_offset = camera_offset;
1321-
}
1322-
}
1323-
13241304
video::SColor encode_light(u16 light, u8 emissive_light)
13251305
{
13261306
// Get components

‎src/client/mapblock_mesh.h

-3
Original file line numberDiff line numberDiff line change
@@ -160,9 +160,6 @@ class MapBlockMesh
160160
// of sunlit vertices
161161
// Keys are pairs of (mesh index, buffer index in the mesh)
162162
std::map<std::pair<u8, u32>, std::map<u32, video::SColor > > m_daynight_diffs;
163-
164-
// Camera offset info -> do we have to translate the mesh?
165-
v3s16 m_camera_offset;
166163
};
167164

168165
/*!

0 commit comments

Comments
 (0)
Please sign in to comment.