aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas--S <Thomas--S@users.noreply.github.com>2020-12-15 19:06:36 +0100
committerGitHub <noreply@github.com>2020-12-15 19:06:36 +0100
commitd0a38f694d483fbd9c0554c8d7175a94097fd67e (patch)
tree67ab895363386282115cf6c0b34a9303c38b9a15
parent3ed940ff13fc2b4ef4b63f2c506ed9e5ab59f54f (diff)
downloadminetest-d0a38f694d483fbd9c0554c8d7175a94097fd67e.tar.gz
minetest-d0a38f694d483fbd9c0554c8d7175a94097fd67e.tar.bz2
minetest-d0a38f694d483fbd9c0554c8d7175a94097fd67e.zip
Formspec: Allow to specify frame loop for model[] (#10679)
Add the ability to specify an animation frame loop range for the model[] formspec element.
-rw-r--r--doc/lua_api.txt6
-rw-r--r--src/gui/guiFormSpecMenu.cpp21
-rw-r--r--src/gui/guiScene.cpp9
-rw-r--r--src/gui/guiScene.h1
4 files changed, 31 insertions, 6 deletions
diff --git a/doc/lua_api.txt b/doc/lua_api.txt
index f5c07fe85..ddb6d4e19 100644
--- a/doc/lua_api.txt
+++ b/doc/lua_api.txt
@@ -2277,7 +2277,7 @@ Elements
* `frame duration`: Milliseconds between each frame. `0` means the frames don't advance.
* `frame start` (Optional): The index of the frame to start on. Default `1`.
-### `model[<X>,<Y>;<W>,<H>;<name>;<mesh>;<textures>;<rotation X,Y>;<continuous>;<mouse control>]`
+### `model[<X>,<Y>;<W>,<H>;<name>;<mesh>;<textures>;<rotation X,Y>;<continuous>;<mouse control>;<frame loop range>]`
* Show a mesh model.
* `name`: Element name that can be used for styling
@@ -2288,6 +2288,9 @@ Elements
The axes are euler angles in degrees.
* `continuous` (Optional): Whether the rotation is continuous. Default `false`.
* `mouse control` (Optional): Whether the model can be controlled with the mouse. Default `true`.
+* `frame loop range` (Optional): Range of the animation frames.
+ * Defaults to the full range of all available frames.
+ * Syntax: `<begin>,<end>`
### `item_image[<X>,<Y>;<W>,<H>;<item name>]`
@@ -2789,6 +2792,7 @@ Some types may inherit styles from parent types.
* image_button
* item_image_button
* label
+* model
* pwdfield, inherits from field
* scrollbar
* tabheader
diff --git a/src/gui/guiFormSpecMenu.cpp b/src/gui/guiFormSpecMenu.cpp
index 632b15992..ed197d0d1 100644
--- a/src/gui/guiFormSpecMenu.cpp
+++ b/src/gui/guiFormSpecMenu.cpp
@@ -70,7 +70,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#define MY_CHECKPOS(a,b) \
if (v_pos.size() != 2) { \
- errorstream<< "Invalid pos for element " << a << "specified: \"" \
+ errorstream<< "Invalid pos for element " << a << " specified: \"" \
<< parts[b] << "\"" << std::endl; \
return; \
}
@@ -78,7 +78,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#define MY_CHECKGEOM(a,b) \
if (v_geom.size() != 2) { \
errorstream<< "Invalid geometry for element " << a << \
- "specified: \"" << parts[b] << "\"" << std::endl; \
+ " specified: \"" << parts[b] << "\"" << std::endl; \
return; \
}
/*
@@ -2725,7 +2725,7 @@ void GUIFormSpecMenu::parseModel(parserData *data, const std::string &element)
{
std::vector<std::string> parts = split(element, ';');
- if (parts.size() < 5 || (parts.size() > 8 &&
+ if (parts.size() < 5 || (parts.size() > 9 &&
m_formspec_version <= FORMSPEC_API_VERSION)) {
errorstream << "Invalid model element (" << parts.size() << "): '" << element
<< "'" << std::endl;
@@ -2733,8 +2733,8 @@ void GUIFormSpecMenu::parseModel(parserData *data, const std::string &element)
}
// Avoid length checks by resizing
- if (parts.size() < 8)
- parts.resize(8);
+ if (parts.size() < 9)
+ parts.resize(9);
std::vector<std::string> v_pos = split(parts[0], ',');
std::vector<std::string> v_geom = split(parts[1], ',');
@@ -2744,6 +2744,7 @@ void GUIFormSpecMenu::parseModel(parserData *data, const std::string &element)
std::vector<std::string> vec_rot = split(parts[5], ',');
bool inf_rotation = is_yes(parts[6]);
bool mousectrl = is_yes(parts[7]) || parts[7].empty(); // default true
+ std::vector<std::string> frame_loop = split(parts[8], ',');
MY_CHECKPOS("model", 0);
MY_CHECKGEOM("model", 1);
@@ -2794,6 +2795,16 @@ void GUIFormSpecMenu::parseModel(parserData *data, const std::string &element)
e->enableContinuousRotation(inf_rotation);
e->enableMouseControl(mousectrl);
+ s32 frame_loop_begin = 0;
+ s32 frame_loop_end = 0x7FFFFFFF;
+
+ if (frame_loop.size() == 2) {
+ frame_loop_begin = stoi(frame_loop[0]);
+ frame_loop_end = stoi(frame_loop[1]);
+ }
+
+ e->setFrameLoop(frame_loop_begin, frame_loop_end);
+
auto style = getStyleForElement("model", spec.fname);
e->setStyles(style);
e->drop();
diff --git a/src/gui/guiScene.cpp b/src/gui/guiScene.cpp
index 08f119e07..5f4c50b91 100644
--- a/src/gui/guiScene.cpp
+++ b/src/gui/guiScene.cpp
@@ -152,6 +152,15 @@ void GUIScene::setStyles(const std::array<StyleSpec, StyleSpec::NUM_STATES> &sty
setBackgroundColor(style.getColor(StyleSpec::BGCOLOR, m_bgcolor));
}
+/**
+ * Sets the frame loop range for the mesh
+ */
+void GUIScene::setFrameLoop(s32 begin, s32 end)
+{
+ if (m_mesh->getStartFrame() != begin || m_mesh->getEndFrame() != end)
+ m_mesh->setFrameLoop(begin, end);
+}
+
/* Camera control functions */
inline void GUIScene::calcOptimalDistance()
diff --git a/src/gui/guiScene.h b/src/gui/guiScene.h
index 707e6f66a..08eb7f350 100644
--- a/src/gui/guiScene.h
+++ b/src/gui/guiScene.h
@@ -36,6 +36,7 @@ public:
scene::IAnimatedMeshSceneNode *setMesh(scene::IAnimatedMesh *mesh = nullptr);
void setTexture(u32 idx, video::ITexture *texture);
void setBackgroundColor(const video::SColor &color) noexcept { m_bgcolor = color; };
+ void setFrameLoop(s32 begin, s32 end);
void enableMouseControl(bool enable) noexcept { m_mouse_ctrl = enable; };
void setRotation(v2f rot) noexcept { m_custom_rot = rot; };
void enableContinuousRotation(bool enable) noexcept { m_inf_rot = enable; };