Skip to content

Commit d4d3e10

Browse files
authored
Fixes and improvements for item image animations (#16620)
1 parent 97c9f8f commit d4d3e10

File tree

8 files changed

+38
-44
lines changed

8 files changed

+38
-44
lines changed

doc/lua_api.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5855,7 +5855,7 @@ Utilities
58555855
-- 'chunksize' mapgen setting can be a vector, instead of a single number (5.15.0)
58565856
chunksize_vector = true,
58575857
-- Item definition fields `inventory_image`, `inventory_overlay`, `wield_image`
5858-
-- and `wield_overlay` accept a table containing animation definitions. (5.16.0)
5858+
-- and `wield_overlay` accept a table containing animation definitions. (5.15.0)
58595859
item_image_animation = true,
58605860
}
58615861
```

src/client/item_visuals_manager.cpp

Lines changed: 14 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,16 @@ struct ItemVisualsManager::ItemVisuals
1818
AnimationInfo inventory_normal;
1919
AnimationInfo inventory_overlay;
2020

21+
// ItemVisuals owns the frames and AnimationInfo points to them
22+
std::vector<FrameSpec> frames_normal;
23+
std::vector<FrameSpec> frames_overlay;
24+
2125
ItemVisuals() :
2226
palette(nullptr)
2327
{}
2428

2529
~ItemVisuals()
2630
{
27-
inventory_normal.freeFrames();
28-
inventory_overlay.freeFrames();
2931
if (item_mesh.mesh)
3032
item_mesh.mesh->drop();
3133
}
@@ -65,30 +67,18 @@ ItemVisualsManager::ItemVisuals *ItemVisualsManager::createItemVisuals( const It
6567

6668
ITextureSource *tsrc = client->getTextureSource();
6769

68-
// Create new ItemVisuals
6970
auto iv = std::make_unique<ItemVisuals>();
7071

71-
auto populate_texture_and_animation = [tsrc](
72-
const ItemImageDef &image,
73-
AnimationInfo &animation)
74-
{
75-
int frame_length_ms = 0;
76-
auto frames = std::make_unique<std::vector<FrameSpec>>();
77-
if (image.name.empty()) {
78-
// no-op
79-
} else if (image.animation.type == TileAnimationType::TAT_NONE) {
80-
frames->push_back({0, tsrc->getTexture(image.name)});
81-
} else {
82-
// Animated
83-
// Get inventory texture frames
84-
*frames = createAnimationFrames(tsrc, image.name, image.animation, frame_length_ms);
85-
}
86-
animation = AnimationInfo(frames.release(), frame_length_ms);
87-
// `frames` are freed in `ItemVisuals::~ItemVisuals`
88-
};
89-
90-
populate_texture_and_animation(inventory_image, iv->inventory_normal);
91-
populate_texture_and_animation(inventory_overlay, iv->inventory_overlay);
72+
// Create inventory image textures
73+
int frame_length = 0;
74+
iv->frames_normal = createAnimationFrames(tsrc, inventory_image.name,
75+
inventory_image.animation, frame_length);
76+
iv->inventory_normal = AnimationInfo(&iv->frames_normal, frame_length);
77+
78+
// Create inventory overlay textures
79+
iv->frames_overlay = createAnimationFrames(tsrc, inventory_overlay.name,
80+
inventory_overlay.animation, frame_length);
81+
iv->inventory_overlay = AnimationInfo(&iv->frames_overlay, frame_length);
9282

9383
createItemMesh(client, def,
9484
iv->inventory_normal,

src/client/item_visuals_manager.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ struct ItemVisualsManager
4141
AnimationInfo *getInventoryOverlayAnimation(const ItemStack &item, Client *client) const;
4242

4343
// Get item mesh
44-
// Once said to return nullptr if there is an inventory image, but this is wrong
4544
ItemMesh *getItemMesh(const ItemStack &item, Client *client) const;
4645

4746
// Get item palette

src/client/tile.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
#include "tile.h"
66
#include <cassert>
77

8-
video::ITexture *AnimationInfo::getTexture(float animation_time)
8+
video::ITexture *AnimationInfo::getTexture(float animation_time) const
99
{
1010
if (getFrameCount() == 0)
1111
return nullptr;

src/client/tile.h

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -156,19 +156,13 @@ struct AnimationInfo {
156156
m_frame_length_ms(tile.animation_frame_length_ms),
157157
m_frame_count(tile.animation_frame_count),
158158
m_frames(tile.frames)
159-
{};
159+
{}
160160

161161
AnimationInfo(std::vector<FrameSpec> *frames, u16 frame_length_ms) :
162162
m_frame_length_ms(frame_length_ms),
163163
m_frame_count(frames->size()),
164164
m_frames(frames)
165-
{};
166-
167-
void freeFrames()
168-
{
169-
delete m_frames;
170-
m_frames = nullptr;
171-
}
165+
{}
172166

173167
size_t getFrameCount() const
174168
{
@@ -178,14 +172,13 @@ struct AnimationInfo {
178172
void updateTexture(video::SMaterial &material, float animation_time);
179173

180174
// Returns nullptr if texture did not change since last time
181-
video::ITexture *getTexture(float animation_time);
175+
video::ITexture *getTexture(float animation_time) const;
182176

183177
private:
184178
u16 m_frame_length_ms = 0;
185179
u16 m_frame_count = 1;
186180

187181
/// @note by default not owned by this struct
188-
/// TODO. Change this to a shared pointer.
189182
std::vector<FrameSpec> *m_frames = nullptr;
190183
};
191184

src/client/wieldmesh.cpp

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -415,9 +415,16 @@ std::vector<FrameSpec> createAnimationFrames(ITextureSource *tsrc,
415415
{
416416
result_frame_length_ms = 0;
417417

418-
if (image_name.empty() || animation.type == TileAnimationType::TAT_NONE)
418+
if (image_name.empty())
419419
return {};
420420

421+
// Still create texture if not animated
422+
if (animation.type == TileAnimationType::TAT_NONE) {
423+
u32 id;
424+
video::ITexture *texture = tsrc->getTextureForMesh(image_name, &id);
425+
return {{id, texture}};
426+
}
427+
421428
video::ITexture *orginal_texture = tsrc->getTexture(image_name);
422429
if (!orginal_texture)
423430
return {};
@@ -656,8 +663,8 @@ void WieldMeshSceneNode::changeToMesh(scene::IMesh *mesh)
656663
}
657664

658665
void createItemMesh(Client *client, const ItemDefinition &def,
659-
AnimationInfo &animation_normal,
660-
AnimationInfo &animation_overlay,
666+
const AnimationInfo &animation_normal,
667+
const AnimationInfo &animation_overlay,
661668
ItemMesh *result)
662669
{
663670
ITextureSource *tsrc = client->getTextureSource();
@@ -700,7 +707,9 @@ void createItemMesh(Client *client, const ItemDefinition &def,
700707
case NDT_PLANTLIKE: {
701708
const TileLayer &l0 = f.tiles[0].layers[0];
702709
const TileLayer &l1 = f.tiles[0].layers[1];
703-
mesh = getExtrudedMesh(l0.texture, l1.texture);
710+
mesh = getExtrudedMesh(
711+
extractTexture(f.tiledef[0], l0, tsrc),
712+
extractTexture(f.tiledef[1], l1, tsrc));
704713
// Add color
705714
result->buffer_info.emplace_back(0, l0);
706715
result->buffer_info.emplace_back(1, l1);
@@ -709,7 +718,9 @@ void createItemMesh(Client *client, const ItemDefinition &def,
709718
case NDT_PLANTLIKE_ROOTED: {
710719
// Use the plant tile
711720
const TileLayer &l0 = f.special_tiles[0].layers[0];
712-
mesh = getExtrudedMesh(l0.texture);
721+
mesh = getExtrudedMesh(
722+
extractTexture(f.tiledef_special[0], l0, tsrc)
723+
);
713724
result->buffer_info.emplace_back(0, l0);
714725
break;
715726
}

src/client/wieldmesh.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,6 @@ scene::SMesh *getExtrudedMesh(video::ITexture *texture,
187187
// This is only used to initially generate an ItemMesh
188188
// To get the mesh, use ItemVisualsManager::getItemMesh(item, client) instead
189189
void createItemMesh(Client *client, const ItemDefinition &def,
190-
AnimationInfo &animation_normal,
191-
AnimationInfo &animation_overlay,
190+
const AnimationInfo &animation_normal,
191+
const AnimationInfo &animation_overlay,
192192
ItemMesh *result);

src/tileanimation.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,5 +45,6 @@ struct TileAnimationParams
4545

4646
// Modifies the texture name such that it only contains the first frame
4747
// If the texture_size is know (client code), getTextureModifer should be used instead
48+
// This function only exists for compatibility with old clients
4849
void extractFirstFrame(std::string &name) const;
4950
};

0 commit comments

Comments
 (0)