Compare commits
5 Commits
9976f36b18
...
d3d218940b
Author | SHA1 | Date |
---|---|---|
|
d3d218940b | |
|
c18dbadcb8 | |
|
5c4b560b68 | |
|
386d5f778a | |
|
28e87ce9d5 |
|
@ -44,6 +44,10 @@ describe("vector", function()
|
|||
assert.same({ x = 2, y = 4, z = 6 }, vector.add(vector.new(1, 2, 3), { x = 1, y = 2, z = 3 }))
|
||||
end)
|
||||
|
||||
it("offset()", function()
|
||||
assert.same({ x = 41, y = 52, z = 63 }, vector.offset(vector.new(1, 2, 3), 40, 50, 60))
|
||||
end)
|
||||
|
||||
-- This function is needed because of floating point imprecision.
|
||||
local function almost_equal(a, b)
|
||||
if type(a) == "number" then
|
||||
|
|
|
@ -137,6 +137,12 @@ function vector.divide(a, b)
|
|||
end
|
||||
end
|
||||
|
||||
function vector.offset(v, x, y, z)
|
||||
return {x = v.x + x,
|
||||
y = v.y + y,
|
||||
z = v.z + z}
|
||||
end
|
||||
|
||||
function vector.sort(a, b)
|
||||
return {x = math.min(a.x, b.x), y = math.min(a.y, b.y), z = math.min(a.z, b.z)},
|
||||
{x = math.max(a.x, b.x), y = math.max(a.y, b.y), z = math.max(a.z, b.z)}
|
||||
|
|
|
@ -54,8 +54,9 @@ core.register_entity(":__builtin:item", {
|
|||
local max_count = stack:get_stack_max()
|
||||
local count = math.min(stack:get_count(), max_count)
|
||||
local size = 0.2 + 0.1 * (count / max_count) ^ (1 / 3)
|
||||
local def = core.registered_nodes[itemname]
|
||||
local glow = def and math.floor(def.light_source / 2 + 0.5)
|
||||
local def = core.registered_items[itemname]
|
||||
local glow = def and def.light_source and
|
||||
math.floor(def.light_source / 2 + 0.5)
|
||||
|
||||
self.object:set_properties({
|
||||
is_visible = true,
|
||||
|
|
|
@ -152,6 +152,7 @@ Mod directory structure
|
|||
│ ├── models
|
||||
│ ├── textures
|
||||
│ │ ├── modname_stuff.png
|
||||
│ │ ├── modname_stuff_normal.png
|
||||
│ │ ├── modname_something_else.png
|
||||
│ │ ├── subfolder_foo
|
||||
│ │ │ ├── modname_more_stuff.png
|
||||
|
@ -384,6 +385,36 @@ stripping out the file extension:
|
|||
* e.g. `foomod_foothing.png`
|
||||
* e.g. `foomod_foothing`
|
||||
|
||||
|
||||
Normalmap Textures
|
||||
------------------
|
||||
|
||||
If shaders and bumpmapping or parallax occlusion is enabled, Minetest tries
|
||||
to load normalmaps.
|
||||
Those image files have to end with `_normal.png` and start with the same name
|
||||
as their corresponding texture.
|
||||
For example a normalmap for `foomod_foothing.png` has to be called
|
||||
`foomod_foothing_normal.png`.
|
||||
|
||||
The sRGB R, G and B colour values of a normalmap pixel are each directly
|
||||
mapped from `{0, ..., 255}` to `[-1, 1]` and, taken together,
|
||||
define the normal vector.
|
||||
The alpha channel defines the heightmap for parallax occlusion.
|
||||
To be safe, the alpha values should always be bigger than zero
|
||||
because the colour values, which define the normal vector,
|
||||
may be undefined for image formats where colour is discarded in fully
|
||||
transparent pixels.
|
||||
|
||||
Bumpmapping and parallax occlusion are currently experimental features:
|
||||
|
||||
* Bumpmapping in Minetest happens in an obscure way; there are no light sources
|
||||
defined in the shaders except the sunlight direction.
|
||||
* Parallax occlusion with relief-mapping mode does not yet work correctly
|
||||
together with Minetest's Fastfaces.
|
||||
* The normalmap files must end with `.png`, so other image files are not
|
||||
supported.
|
||||
|
||||
|
||||
Texture modifiers
|
||||
-----------------
|
||||
|
||||
|
@ -1420,7 +1451,23 @@ Same as `image`, but does not accept a `position`; the position is instead deter
|
|||
* `world_pos`: World position of the waypoint.
|
||||
* `offset`: offset in pixels from position.
|
||||
|
||||
### `compass`
|
||||
|
||||
Displays an image oriented or translated according to current heading direction.
|
||||
|
||||
* `size`: The size of this element. Negative values represent percentage
|
||||
of the screen; e.g. `x=-100` means 100% (width).
|
||||
* `scale`: Scale of the translated image (used only for dir = 2 or dir = 3).
|
||||
* `text`: The name of the texture to use.
|
||||
* `alignment`: The alignment of the image.
|
||||
* `offset`: Offset in pixels from position.
|
||||
* `dir`: How the image is rotated/translated:
|
||||
* 0 - Rotate as heading direction
|
||||
* 1 - Rotate in reverse direction
|
||||
* 2 - Translate as landscape direction
|
||||
* 3 - Translate in reverse direction
|
||||
|
||||
If translation is chosen, texture is repeated horizontally to fill the whole element.
|
||||
|
||||
Representations of simple things
|
||||
================================
|
||||
|
@ -3062,10 +3109,12 @@ For the following functions, `v`, `v1`, `v2` are vectors,
|
|||
* Returns in order minp, maxp vectors of the cuboid defined by `v1`, `v2`.
|
||||
* `vector.angle(v1, v2)`:
|
||||
* Returns the angle between `v1` and `v2` in radians.
|
||||
* `vector.dot(v1, v2)`
|
||||
* Returns the dot product of `v1` and `v2`
|
||||
* `vector.cross(v1, v2)`
|
||||
* Returns the cross product of `v1` and `v2`
|
||||
* `vector.dot(v1, v2)`:
|
||||
* Returns the dot product of `v1` and `v2`.
|
||||
* `vector.cross(v1, v2)`:
|
||||
* Returns the cross product of `v1` and `v2`.
|
||||
* `vector.offset(v, x, y, z)`:
|
||||
* Returns the sum of the vectors `v` and `{x = x, y = y, z = z}`.
|
||||
|
||||
For the following functions `x` can be either a vector or a number:
|
||||
|
||||
|
@ -6977,6 +7026,13 @@ Used by `minetest.register_node`, `minetest.register_craftitem`, and
|
|||
|
||||
liquids_pointable = false,
|
||||
|
||||
light_source = 0,
|
||||
-- When used for nodes: Defines amount of light emitted by node.
|
||||
-- Otherwise: Defines texture glow when viewed as a dropped item
|
||||
-- To set the maximum (14), use the value 'minetest.LIGHT_MAX'.
|
||||
-- A value outside the range 0 to minetest.LIGHT_MAX causes undefined
|
||||
-- behavior.
|
||||
|
||||
-- See "Tools" section for an example including explanation
|
||||
tool_capabilities = {
|
||||
full_punch_interval = 1.0,
|
||||
|
@ -7176,12 +7232,6 @@ Used by `minetest.register_node`.
|
|||
drowning = 0,
|
||||
-- Player will take this amount of damage if no bubbles are left
|
||||
|
||||
light_source = 0,
|
||||
-- Amount of light emitted by node.
|
||||
-- To set the maximum (14), use the value 'minetest.LIGHT_MAX'.
|
||||
-- A value outside the range 0 to minetest.LIGHT_MAX causes undefined
|
||||
-- behavior.
|
||||
|
||||
damage_per_second = 0,
|
||||
-- If player is inside node, this damage is caused
|
||||
|
||||
|
@ -7935,7 +7985,7 @@ Used by `Player:hud_add`. Returned by `Player:hud_get`.
|
|||
|
||||
{
|
||||
hud_elem_type = "image", -- See HUD element types
|
||||
-- Type of element, can be "image", "text", "statbar", or "inventory"
|
||||
-- Type of element, can be "image", "text", "statbar", "inventory" or "compass"
|
||||
|
||||
position = {x=0.5, y=0.5},
|
||||
-- Left corner position of element
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -95,6 +95,12 @@ private:
|
|||
|
||||
void drawItem(const ItemStack &item, const core::rect<s32> &rect, bool selected);
|
||||
|
||||
void drawCompassTranslate(HudElement *e, video::ITexture *texture,
|
||||
const core::rect<s32> &rect, int way);
|
||||
|
||||
void drawCompassRotate(HudElement *e, video::ITexture *texture,
|
||||
const core::rect<s32> &rect, int way);
|
||||
|
||||
float m_hud_scaling; // cached minetest setting
|
||||
float m_scale_factor;
|
||||
v3s16 m_camera_offset;
|
||||
|
@ -115,6 +121,8 @@ private:
|
|||
|
||||
video::SMaterial m_selection_material;
|
||||
|
||||
scene::SMeshBuffer m_rotation_mesh_buffer;
|
||||
|
||||
enum
|
||||
{
|
||||
HIGHLIGHT_BOX,
|
||||
|
|
|
@ -28,6 +28,7 @@ const struct EnumString es_HudElementType[] =
|
|||
{HUD_ELEM_INVENTORY, "inventory"},
|
||||
{HUD_ELEM_WAYPOINT, "waypoint"},
|
||||
{HUD_ELEM_IMAGE_WAYPOINT, "image_waypoint"},
|
||||
{HUD_ELEM_COMPASS, "compass"},
|
||||
{0, NULL},
|
||||
};
|
||||
|
||||
|
|
10
src/hud.h
10
src/hud.h
|
@ -60,7 +60,8 @@ enum HudElementType {
|
|||
HUD_ELEM_STATBAR = 2,
|
||||
HUD_ELEM_INVENTORY = 3,
|
||||
HUD_ELEM_WAYPOINT = 4,
|
||||
HUD_ELEM_IMAGE_WAYPOINT = 5
|
||||
HUD_ELEM_IMAGE_WAYPOINT = 5,
|
||||
HUD_ELEM_COMPASS = 6
|
||||
};
|
||||
|
||||
enum HudElementStat {
|
||||
|
@ -79,6 +80,13 @@ enum HudElementStat {
|
|||
HUD_STAT_TEXT2,
|
||||
};
|
||||
|
||||
enum HudCompassDir {
|
||||
HUD_COMPASS_ROTATE = 0,
|
||||
HUD_COMPASS_ROTATE_REVERSE,
|
||||
HUD_COMPASS_TRANSLATE,
|
||||
HUD_COMPASS_TRANSLATE_REVERSE,
|
||||
};
|
||||
|
||||
struct HudElement {
|
||||
HudElementType type;
|
||||
v2f pos;
|
||||
|
|
Loading…
Reference in New Issue