aboutsummaryrefslogtreecommitdiff
path: root/src/client/hud.cpp
diff options
context:
space:
mode:
authorEvidenceB <49488517+EvidenceBKidscode@users.noreply.github.com>2020-08-29 20:13:30 +0200
committerGitHub <noreply@github.com>2020-08-29 20:13:30 +0200
commit5c4b560b6812bbdf7a9d3202c95bad5c9df97d66 (patch)
tree9e29fa859e14890e78cd215b25a0b822a0b37e8b /src/client/hud.cpp
parent386d5f778a299cc0d891eb476674f3eddb108376 (diff)
downloadminetest-5c4b560b6812bbdf7a9d3202c95bad5c9df97d66.tar.gz
minetest-5c4b560b6812bbdf7a9d3202c95bad5c9df97d66.tar.bz2
minetest-5c4b560b6812bbdf7a9d3202c95bad5c9df97d66.zip
Add compass HUD element (#9312)
Co-authored-by: Jean-Patrick Guerrero <jeanpatrick.guerrero@gmail.com> Co-authored-by: Pierre-Yves Rollo <dev@pyrollo.com> Co-authored-by: SmallJoker <SmallJoker@users.noreply.github.com>
Diffstat (limited to 'src/client/hud.cpp')
-rw-r--r--src/client/hud.cpp140
1 files changed, 140 insertions, 0 deletions
diff --git a/src/client/hud.cpp b/src/client/hud.cpp
index 2b347c1e0..d3038230c 100644
--- a/src/client/hud.cpp
+++ b/src/client/hud.cpp
@@ -114,6 +114,28 @@ Hud::Hud(gui::IGUIEnvironment *guienv, Client *client, LocalPlayer *player,
} else {
m_selection_material.MaterialType = video::EMT_SOLID;
}
+
+ // Prepare mesh for compass drawing
+ m_rotation_mesh_buffer.Vertices.set_used(4);
+ m_rotation_mesh_buffer.Indices.set_used(6);
+
+ video::SColor white(255, 255, 255, 255);
+ v3f normal(0.f, 0.f, 1.f);
+
+ m_rotation_mesh_buffer.Vertices[0] = video::S3DVertex(v3f(-1.f, -1.f, 0.f), normal, white, v2f(0.f, 1.f));
+ m_rotation_mesh_buffer.Vertices[1] = video::S3DVertex(v3f(-1.f, 1.f, 0.f), normal, white, v2f(0.f, 0.f));
+ m_rotation_mesh_buffer.Vertices[2] = video::S3DVertex(v3f( 1.f, 1.f, 0.f), normal, white, v2f(1.f, 0.f));
+ m_rotation_mesh_buffer.Vertices[3] = video::S3DVertex(v3f( 1.f, -1.f, 0.f), normal, white, v2f(1.f, 1.f));
+
+ m_rotation_mesh_buffer.Indices[0] = 0;
+ m_rotation_mesh_buffer.Indices[1] = 1;
+ m_rotation_mesh_buffer.Indices[2] = 2;
+ m_rotation_mesh_buffer.Indices[3] = 2;
+ m_rotation_mesh_buffer.Indices[4] = 3;
+ m_rotation_mesh_buffer.Indices[5] = 0;
+
+ m_rotation_mesh_buffer.getMaterial().Lighting = false;
+ m_rotation_mesh_buffer.getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
}
Hud::~Hud()
@@ -423,6 +445,54 @@ void Hud::drawLuaElements(const v3s16 &camera_offset)
core::rect<s32>(core::position2d<s32>(0,0), imgsize),
NULL, colors, true);
break; }
+ case HUD_ELEM_COMPASS: {
+ video::ITexture *texture = tsrc->getTexture(e->text);
+ if (!texture)
+ continue;
+
+ // Positionning :
+ v2s32 dstsize(e->size.X, e->size.Y);
+ if (e->size.X < 0)
+ dstsize.X = m_screensize.X * (e->size.X * -0.01);
+ if (e->size.Y < 0)
+ dstsize.Y = m_screensize.Y * (e->size.Y * -0.01);
+
+ if (dstsize.X <= 0 || dstsize.Y <= 0)
+ return; // Avoid zero divides
+
+ // Angle according to camera view
+ v3f fore(0.f, 0.f, 1.f);
+ scene::ICameraSceneNode *cam = RenderingEngine::get_scene_manager()->getActiveCamera();
+ cam->getAbsoluteTransformation().rotateVect(fore);
+ int angle = - fore.getHorizontalAngle().Y;
+
+ // Limit angle and ajust with given offset
+ angle = (angle + (int)e->number) % 360;
+
+ core::rect<s32> dstrect(0, 0, dstsize.X, dstsize.Y);
+ dstrect += pos + v2s32(
+ (e->align.X - 1.0) * dstsize.X / 2,
+ (e->align.Y - 1.0) * dstsize.Y / 2) +
+ v2s32(e->offset.X * m_hud_scaling, e->offset.Y * m_hud_scaling);
+
+ switch (e->dir) {
+ case HUD_COMPASS_ROTATE:
+ drawCompassRotate(e, texture, dstrect, angle);
+ break;
+ case HUD_COMPASS_ROTATE_REVERSE:
+ drawCompassRotate(e, texture, dstrect, -angle);
+ break;
+ case HUD_COMPASS_TRANSLATE:
+ drawCompassTranslate(e, texture, dstrect, angle);
+ break;
+ case HUD_COMPASS_TRANSLATE_REVERSE:
+ drawCompassTranslate(e, texture, dstrect, -angle);
+ break;
+ default:
+ break;
+ }
+
+ break; }
default:
infostream << "Hud::drawLuaElements: ignoring drawform " << e->type <<
" of hud element ID " << i << " due to unrecognized type" << std::endl;
@@ -430,6 +500,76 @@ void Hud::drawLuaElements(const v3s16 &camera_offset)
}
}
+void Hud::drawCompassTranslate(HudElement *e, video::ITexture *texture,
+ const core::rect<s32> &rect, int angle)
+{
+ const video::SColor color(255, 255, 255, 255);
+ const video::SColor colors[] = {color, color, color, color};
+
+ // Compute source image scaling
+ core::dimension2di imgsize(texture->getOriginalSize());
+ core::rect<s32> srcrect(0, 0, imgsize.Width, imgsize.Height);
+
+ v2s32 dstsize(rect.getHeight() * e->scale.X * imgsize.Width / imgsize.Height,
+ rect.getHeight() * e->scale.Y);
+
+ // Avoid infinite loop
+ if (dstsize.X <= 0 || dstsize.Y <= 0)
+ return;
+
+ core::rect<s32> tgtrect(0, 0, dstsize.X, dstsize.Y);
+ tgtrect += v2s32(
+ (rect.getWidth() - dstsize.X) / 2,
+ (rect.getHeight() - dstsize.Y) / 2) +
+ rect.UpperLeftCorner;
+
+ int offset = angle * dstsize.X / 360;
+
+ tgtrect += v2s32(offset, 0);
+
+ // Repeat image as much as needed
+ while (tgtrect.UpperLeftCorner.X > rect.UpperLeftCorner.X)
+ tgtrect -= v2s32(dstsize.X, 0);
+
+ draw2DImageFilterScaled(driver, texture, tgtrect, srcrect, &rect, colors, true);
+ tgtrect += v2s32(dstsize.X, 0);
+
+ while (tgtrect.UpperLeftCorner.X < rect.LowerRightCorner.X) {
+ draw2DImageFilterScaled(driver, texture, tgtrect, srcrect, &rect, colors, true);
+ tgtrect += v2s32(dstsize.X, 0);
+ }
+}
+
+void Hud::drawCompassRotate(HudElement *e, video::ITexture *texture,
+ const core::rect<s32> &rect, int angle)
+{
+ core::dimension2di imgsize(texture->getOriginalSize());
+
+ core::rect<s32> oldViewPort = driver->getViewPort();
+ core::matrix4 oldProjMat = driver->getTransform(video::ETS_PROJECTION);
+ core::matrix4 oldViewMat = driver->getTransform(video::ETS_VIEW);
+
+ core::matrix4 Matrix;
+ Matrix.makeIdentity();
+ Matrix.setRotationDegrees(v3f(0.f, 0.f, angle));
+
+ driver->setViewPort(rect);
+ driver->setTransform(video::ETS_PROJECTION, core::matrix4());
+ driver->setTransform(video::ETS_VIEW, core::matrix4());
+ driver->setTransform(video::ETS_WORLD, Matrix);
+
+ video::SMaterial &material = m_rotation_mesh_buffer.getMaterial();
+ material.TextureLayer[0].Texture = texture;
+ driver->setMaterial(material);
+ driver->drawMeshBuffer(&m_rotation_mesh_buffer);
+
+ driver->setTransform(video::ETS_WORLD, core::matrix4());
+ driver->setTransform(video::ETS_VIEW, oldViewMat);
+ driver->setTransform(video::ETS_PROJECTION, oldProjMat);
+
+ // restore the view area
+ driver->setViewPort(oldViewPort);
+}
void Hud::drawStatbar(v2s32 pos, u16 corner, u16 drawdir,
const std::string &texture, const std::string &bgtexture,