mirror of
https://github.com/luanti-org/luanti.git
synced 2025-06-27 16:36:03 +00:00
Move client code out of ItemDefManager (#15967)
This commit is contained in:
parent
a6d4cd7c15
commit
52b974184d
10 changed files with 195 additions and 163 deletions
|
@ -56,6 +56,7 @@ set(client_SRCS
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/hud.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/hud.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/imagefilters.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/imagefilters.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/inputhandler.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/inputhandler.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/item_visuals_manager.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/joystick_controller.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/joystick_controller.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/keycode.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/keycode.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/localplayer.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/localplayer.cpp
|
||||||
|
|
|
@ -53,6 +53,7 @@
|
||||||
#include "translation.h"
|
#include "translation.h"
|
||||||
#include "content/mod_configuration.h"
|
#include "content/mod_configuration.h"
|
||||||
#include "mapnode.h"
|
#include "mapnode.h"
|
||||||
|
#include "item_visuals_manager.h"
|
||||||
|
|
||||||
extern gui::IGUIEnvironment* guienv;
|
extern gui::IGUIEnvironment* guienv;
|
||||||
|
|
||||||
|
@ -95,6 +96,7 @@ Client::Client(
|
||||||
ISoundManager *sound,
|
ISoundManager *sound,
|
||||||
MtEventManager *event,
|
MtEventManager *event,
|
||||||
RenderingEngine *rendering_engine,
|
RenderingEngine *rendering_engine,
|
||||||
|
ItemVisualsManager *item_visuals_manager,
|
||||||
ELoginRegister allow_login_or_register
|
ELoginRegister allow_login_or_register
|
||||||
):
|
):
|
||||||
m_tsrc(tsrc),
|
m_tsrc(tsrc),
|
||||||
|
@ -104,6 +106,7 @@ Client::Client(
|
||||||
m_sound(sound),
|
m_sound(sound),
|
||||||
m_event(event),
|
m_event(event),
|
||||||
m_rendering_engine(rendering_engine),
|
m_rendering_engine(rendering_engine),
|
||||||
|
m_item_visuals_manager(item_visuals_manager),
|
||||||
m_mesh_update_manager(std::make_unique<MeshUpdateManager>(this)),
|
m_mesh_update_manager(std::make_unique<MeshUpdateManager>(this)),
|
||||||
m_env(
|
m_env(
|
||||||
make_irr<ClientMap>(this, rendering_engine, control, 666),
|
make_irr<ClientMap>(this, rendering_engine, control, 666),
|
||||||
|
@ -346,6 +349,8 @@ Client::~Client()
|
||||||
// cleanup 3d model meshes on client shutdown
|
// cleanup 3d model meshes on client shutdown
|
||||||
m_rendering_engine->cleanupMeshCache();
|
m_rendering_engine->cleanupMeshCache();
|
||||||
|
|
||||||
|
m_item_visuals_manager->clear();
|
||||||
|
|
||||||
guiScalingCacheClear();
|
guiScalingCacheClear();
|
||||||
|
|
||||||
delete m_minimap;
|
delete m_minimap;
|
||||||
|
|
|
@ -55,6 +55,7 @@ struct MeshMakeData;
|
||||||
struct MinimapMapblock;
|
struct MinimapMapblock;
|
||||||
struct PlayerControl;
|
struct PlayerControl;
|
||||||
struct PointedThing;
|
struct PointedThing;
|
||||||
|
struct ItemVisualsManager;
|
||||||
|
|
||||||
namespace con {
|
namespace con {
|
||||||
class IConnection;
|
class IConnection;
|
||||||
|
@ -118,6 +119,7 @@ public:
|
||||||
ISoundManager *sound,
|
ISoundManager *sound,
|
||||||
MtEventManager *event,
|
MtEventManager *event,
|
||||||
RenderingEngine *rendering_engine,
|
RenderingEngine *rendering_engine,
|
||||||
|
ItemVisualsManager *item_visuals,
|
||||||
ELoginRegister allow_login_or_register
|
ELoginRegister allow_login_or_register
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -383,6 +385,8 @@ public:
|
||||||
const std::string* getModFile(std::string filename);
|
const std::string* getModFile(std::string filename);
|
||||||
ModStorageDatabase *getModStorageDatabase() override { return m_mod_storage_database; }
|
ModStorageDatabase *getModStorageDatabase() override { return m_mod_storage_database; }
|
||||||
|
|
||||||
|
ItemVisualsManager *getItemVisualsManager() { return m_item_visuals_manager; }
|
||||||
|
|
||||||
// Migrates away old files-based mod storage if necessary
|
// Migrates away old files-based mod storage if necessary
|
||||||
void migrateModStorage();
|
void migrateModStorage();
|
||||||
|
|
||||||
|
@ -480,6 +484,7 @@ private:
|
||||||
ISoundManager *m_sound;
|
ISoundManager *m_sound;
|
||||||
MtEventManager *m_event;
|
MtEventManager *m_event;
|
||||||
RenderingEngine *m_rendering_engine;
|
RenderingEngine *m_rendering_engine;
|
||||||
|
ItemVisualsManager *m_item_visuals_manager;
|
||||||
|
|
||||||
|
|
||||||
std::unique_ptr<MeshUpdateManager> m_mesh_update_manager;
|
std::unique_ptr<MeshUpdateManager> m_mesh_update_manager;
|
||||||
|
|
|
@ -60,6 +60,7 @@
|
||||||
#include "clientdynamicinfo.h"
|
#include "clientdynamicinfo.h"
|
||||||
#include <IAnimatedMeshSceneNode.h>
|
#include <IAnimatedMeshSceneNode.h>
|
||||||
#include "util/tracy_wrapper.h"
|
#include "util/tracy_wrapper.h"
|
||||||
|
#include "item_visuals_manager.h"
|
||||||
|
|
||||||
#if USE_SOUND
|
#if USE_SOUND
|
||||||
#include "client/sound/sound_openal.h"
|
#include "client/sound/sound_openal.h"
|
||||||
|
@ -692,6 +693,7 @@ private:
|
||||||
// When created, these will be filled with data received from the server
|
// When created, these will be filled with data received from the server
|
||||||
IWritableItemDefManager *itemdef_manager = nullptr;
|
IWritableItemDefManager *itemdef_manager = nullptr;
|
||||||
NodeDefManager *nodedef_manager = nullptr;
|
NodeDefManager *nodedef_manager = nullptr;
|
||||||
|
std::unique_ptr<ItemVisualsManager> m_item_visuals_manager;
|
||||||
|
|
||||||
std::unique_ptr<ISoundManager> sound_manager;
|
std::unique_ptr<ISoundManager> sound_manager;
|
||||||
SoundMaker *soundmaker = nullptr;
|
SoundMaker *soundmaker = nullptr;
|
||||||
|
@ -1125,6 +1127,8 @@ bool Game::init(
|
||||||
itemdef_manager = createItemDefManager();
|
itemdef_manager = createItemDefManager();
|
||||||
nodedef_manager = createNodeDefManager();
|
nodedef_manager = createNodeDefManager();
|
||||||
|
|
||||||
|
m_item_visuals_manager = std::make_unique<ItemVisualsManager>();
|
||||||
|
|
||||||
eventmgr = new EventManager();
|
eventmgr = new EventManager();
|
||||||
quicktune = new QuicktuneShortcutter();
|
quicktune = new QuicktuneShortcutter();
|
||||||
|
|
||||||
|
@ -1443,6 +1447,7 @@ bool Game::connectToServer(const GameStartData &start_data,
|
||||||
*draw_control, texture_src, shader_src,
|
*draw_control, texture_src, shader_src,
|
||||||
itemdef_manager, nodedef_manager, sound_manager.get(), eventmgr,
|
itemdef_manager, nodedef_manager, sound_manager.get(), eventmgr,
|
||||||
m_rendering_engine,
|
m_rendering_engine,
|
||||||
|
m_item_visuals_manager.get(),
|
||||||
start_data.allow_login_or_register);
|
start_data.allow_login_or_register);
|
||||||
} catch (const BaseException &e) {
|
} catch (const BaseException &e) {
|
||||||
*error_message = fmtgettext("Error creating client: %s", e.what());
|
*error_message = fmtgettext("Error creating client: %s", e.what());
|
||||||
|
|
102
src/client/item_visuals_manager.cpp
Normal file
102
src/client/item_visuals_manager.cpp
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
// Luanti
|
||||||
|
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
// Copyright (C) 2025 cx384
|
||||||
|
|
||||||
|
#include "item_visuals_manager.h"
|
||||||
|
|
||||||
|
#include "mesh.h"
|
||||||
|
#include "client.h"
|
||||||
|
#include "texturesource.h"
|
||||||
|
#include "itemdef.h"
|
||||||
|
#include "inventory.h"
|
||||||
|
|
||||||
|
ItemVisualsManager::ItemVisuals::~ItemVisuals() {
|
||||||
|
if (wield_mesh.mesh)
|
||||||
|
wield_mesh.mesh->drop();
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemVisualsManager::ItemVisuals *ItemVisualsManager::createItemVisuals( const ItemStack &item,
|
||||||
|
Client *client) const
|
||||||
|
{
|
||||||
|
// This is not thread-safe
|
||||||
|
sanity_check(std::this_thread::get_id() == m_main_thread);
|
||||||
|
|
||||||
|
IItemDefManager *idef = client->idef();
|
||||||
|
|
||||||
|
const ItemDefinition &def = item.getDefinition(idef);
|
||||||
|
std::string inventory_image = item.getInventoryImage(idef);
|
||||||
|
std::string inventory_overlay = item.getInventoryOverlay(idef);
|
||||||
|
std::string cache_key = def.name;
|
||||||
|
if (!inventory_image.empty())
|
||||||
|
cache_key += "/" + inventory_image;
|
||||||
|
if (!inventory_overlay.empty())
|
||||||
|
cache_key += ":" + inventory_overlay;
|
||||||
|
|
||||||
|
// Skip if already in cache
|
||||||
|
auto it = m_cached_item_visuals.find(cache_key);
|
||||||
|
if (it != m_cached_item_visuals.end())
|
||||||
|
return it->second.get();
|
||||||
|
|
||||||
|
infostream << "Lazily creating item texture and mesh for \""
|
||||||
|
<< cache_key << "\"" << std::endl;
|
||||||
|
|
||||||
|
ITextureSource *tsrc = client->getTextureSource();
|
||||||
|
|
||||||
|
// Create new ItemVisuals
|
||||||
|
auto cc = std::make_unique<ItemVisuals>();
|
||||||
|
|
||||||
|
cc->inventory_texture = NULL;
|
||||||
|
if (!inventory_image.empty())
|
||||||
|
cc->inventory_texture = tsrc->getTexture(inventory_image);
|
||||||
|
getItemMesh(client, item, &(cc->wield_mesh));
|
||||||
|
|
||||||
|
cc->palette = tsrc->getPalette(def.palette_image);
|
||||||
|
|
||||||
|
// Put in cache
|
||||||
|
ItemVisuals *ptr = cc.get();
|
||||||
|
m_cached_item_visuals[cache_key] = std::move(cc);
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
video::ITexture* ItemVisualsManager::getInventoryTexture(const ItemStack &item,
|
||||||
|
Client *client) const
|
||||||
|
{
|
||||||
|
ItemVisuals *iv = createItemVisuals(item, client);
|
||||||
|
if (!iv)
|
||||||
|
return nullptr;
|
||||||
|
return iv->inventory_texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemMesh* ItemVisualsManager::getWieldMesh(const ItemStack &item, Client *client) const
|
||||||
|
{
|
||||||
|
ItemVisuals *iv = createItemVisuals(item, client);
|
||||||
|
if (!iv)
|
||||||
|
return nullptr;
|
||||||
|
return &(iv->wield_mesh);
|
||||||
|
}
|
||||||
|
|
||||||
|
Palette* ItemVisualsManager::getPalette(const ItemStack &item, Client *client) const
|
||||||
|
{
|
||||||
|
ItemVisuals *iv = createItemVisuals(item, client);
|
||||||
|
if (!iv)
|
||||||
|
return nullptr;
|
||||||
|
return iv->palette;
|
||||||
|
}
|
||||||
|
|
||||||
|
video::SColor ItemVisualsManager::getItemstackColor(const ItemStack &stack,
|
||||||
|
Client *client) const
|
||||||
|
{
|
||||||
|
// Look for direct color definition
|
||||||
|
const std::string &colorstring = stack.metadata.getString("color", 0);
|
||||||
|
video::SColor directcolor;
|
||||||
|
if (!colorstring.empty() && parseColorString(colorstring, directcolor, true))
|
||||||
|
return directcolor;
|
||||||
|
// See if there is a palette
|
||||||
|
Palette *palette = getPalette(stack, client);
|
||||||
|
const std::string &index = stack.metadata.getString("palette_index", 0);
|
||||||
|
if (palette && !index.empty())
|
||||||
|
return (*palette)[mystoi(index, 0, 255)];
|
||||||
|
// Fallback color
|
||||||
|
return client->idef()->get(stack.name).color;
|
||||||
|
}
|
||||||
|
|
68
src/client/item_visuals_manager.h
Normal file
68
src/client/item_visuals_manager.h
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
// Luanti
|
||||||
|
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
// Copyright (C) 2025 cx384
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <map>
|
||||||
|
#include <thread>
|
||||||
|
#include "wieldmesh.h" // ItemMesh
|
||||||
|
#include "util/basic_macros.h"
|
||||||
|
|
||||||
|
class Client;
|
||||||
|
class ItemStack;
|
||||||
|
typedef std::vector<video::SColor> Palette; // copied from src/client/texturesource.h
|
||||||
|
namespace irr::video { class ITexture; }
|
||||||
|
|
||||||
|
// Caches data needed to draw an itemstack
|
||||||
|
|
||||||
|
struct ItemVisualsManager
|
||||||
|
{
|
||||||
|
ItemVisualsManager()
|
||||||
|
{
|
||||||
|
m_main_thread = std::this_thread::get_id();
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear() {
|
||||||
|
m_cached_item_visuals.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get item inventory texture
|
||||||
|
video::ITexture* getInventoryTexture(const ItemStack &item, Client *client) const;
|
||||||
|
|
||||||
|
// Get item wield mesh
|
||||||
|
// Once said to return nullptr if there is an inventory image, but this is wrong
|
||||||
|
ItemMesh* getWieldMesh(const ItemStack &item, Client *client) const;
|
||||||
|
|
||||||
|
// Get item palette
|
||||||
|
Palette* getPalette(const ItemStack &item, Client *client) const;
|
||||||
|
|
||||||
|
// Returns the base color of an item stack: the color of all
|
||||||
|
// tiles that do not define their own color.
|
||||||
|
video::SColor getItemstackColor(const ItemStack &stack, Client *client) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct ItemVisuals
|
||||||
|
{
|
||||||
|
video::ITexture *inventory_texture;
|
||||||
|
ItemMesh wield_mesh;
|
||||||
|
Palette *palette;
|
||||||
|
|
||||||
|
ItemVisuals():
|
||||||
|
inventory_texture(nullptr),
|
||||||
|
palette(nullptr)
|
||||||
|
{}
|
||||||
|
|
||||||
|
~ItemVisuals();
|
||||||
|
|
||||||
|
DISABLE_CLASS_COPY(ItemVisuals);
|
||||||
|
};
|
||||||
|
|
||||||
|
// The id of the thread that is allowed to use irrlicht directly
|
||||||
|
std::thread::id m_main_thread;
|
||||||
|
// Cached textures and meshes
|
||||||
|
mutable std::unordered_map<std::string, std::unique_ptr<ItemVisuals>> m_cached_item_visuals;
|
||||||
|
|
||||||
|
ItemVisuals* createItemVisuals(const ItemStack &item, Client *client) const;
|
||||||
|
};
|
|
@ -23,6 +23,7 @@
|
||||||
#include <SMesh.h>
|
#include <SMesh.h>
|
||||||
#include <IMeshBuffer.h>
|
#include <IMeshBuffer.h>
|
||||||
#include <SMeshBuffer.h>
|
#include <SMeshBuffer.h>
|
||||||
|
#include "item_visuals_manager.h"
|
||||||
|
|
||||||
#define WIELD_SCALE_FACTOR 30.0f
|
#define WIELD_SCALE_FACTOR 30.0f
|
||||||
#define WIELD_SCALE_FACTOR_EXTRUDED 40.0f
|
#define WIELD_SCALE_FACTOR_EXTRUDED 40.0f
|
||||||
|
@ -348,6 +349,7 @@ void WieldMeshSceneNode::setItem(const ItemStack &item, Client *client, bool che
|
||||||
{
|
{
|
||||||
ITextureSource *tsrc = client->getTextureSource();
|
ITextureSource *tsrc = client->getTextureSource();
|
||||||
IItemDefManager *idef = client->getItemDefManager();
|
IItemDefManager *idef = client->getItemDefManager();
|
||||||
|
ItemVisualsManager *item_visuals = client->getItemVisualsManager();
|
||||||
IShaderSource *shdrsrc = client->getShaderSource();
|
IShaderSource *shdrsrc = client->getShaderSource();
|
||||||
const NodeDefManager *ndef = client->getNodeDefManager();
|
const NodeDefManager *ndef = client->getNodeDefManager();
|
||||||
const ItemDefinition &def = item.getDefinition(idef);
|
const ItemDefinition &def = item.getDefinition(idef);
|
||||||
|
@ -361,7 +363,7 @@ void WieldMeshSceneNode::setItem(const ItemStack &item, Client *client, bool che
|
||||||
|
|
||||||
// Color-related
|
// Color-related
|
||||||
m_buffer_info.clear();
|
m_buffer_info.clear();
|
||||||
m_base_color = idef->getItemstackColor(item, client);
|
m_base_color = item_visuals->getItemstackColor(item, client);
|
||||||
|
|
||||||
const std::string wield_image = item.getWieldImage(idef);
|
const std::string wield_image = item.getWieldImage(idef);
|
||||||
const std::string wield_overlay = item.getWieldOverlay(idef);
|
const std::string wield_overlay = item.getWieldOverlay(idef);
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include "client/wieldmesh.h"
|
#include "client/wieldmesh.h"
|
||||||
#include "client/texturesource.h"
|
#include "client/texturesource.h"
|
||||||
#include "client/guiscalingfilter.h"
|
#include "client/guiscalingfilter.h"
|
||||||
|
#include "client/item_visuals_manager.h"
|
||||||
|
|
||||||
struct MeshTimeInfo {
|
struct MeshTimeInfo {
|
||||||
u64 time;
|
u64 time;
|
||||||
|
@ -43,6 +44,7 @@ void drawItemStack(
|
||||||
|
|
||||||
auto *idef = client->idef();
|
auto *idef = client->idef();
|
||||||
const ItemDefinition &def = item.getDefinition(idef);
|
const ItemDefinition &def = item.getDefinition(idef);
|
||||||
|
ItemVisualsManager* item_visuals = client->getItemVisualsManager();
|
||||||
|
|
||||||
bool draw_overlay = false;
|
bool draw_overlay = false;
|
||||||
|
|
||||||
|
@ -58,7 +60,7 @@ void drawItemStack(
|
||||||
|
|
||||||
// Render as mesh if animated or no inventory image
|
// Render as mesh if animated or no inventory image
|
||||||
if ((enable_animations && rotation_kind < IT_ROT_NONE) || inventory_image.empty()) {
|
if ((enable_animations && rotation_kind < IT_ROT_NONE) || inventory_image.empty()) {
|
||||||
imesh = idef->getWieldMesh(item, client);
|
imesh = item_visuals->getWieldMesh(item, client);
|
||||||
has_mesh = imesh && imesh->mesh;
|
has_mesh = imesh && imesh->mesh;
|
||||||
}
|
}
|
||||||
if (has_mesh) {
|
if (has_mesh) {
|
||||||
|
@ -114,8 +116,7 @@ void drawItemStack(
|
||||||
driver->setTransform(video::ETS_WORLD, matrix);
|
driver->setTransform(video::ETS_WORLD, matrix);
|
||||||
driver->setViewPort(viewrect);
|
driver->setViewPort(viewrect);
|
||||||
|
|
||||||
video::SColor basecolor =
|
video::SColor basecolor = item_visuals->getItemstackColor(item, client);
|
||||||
client->idef()->getItemstackColor(item, client);
|
|
||||||
|
|
||||||
const u32 mc = mesh->getMeshBufferCount();
|
const u32 mc = mesh->getMeshBufferCount();
|
||||||
if (mc > imesh->buffer_info.size())
|
if (mc > imesh->buffer_info.size())
|
||||||
|
@ -154,10 +155,10 @@ void drawItemStack(
|
||||||
|
|
||||||
draw_overlay = def.type == ITEM_NODE && inventory_image.empty();
|
draw_overlay = def.type == ITEM_NODE && inventory_image.empty();
|
||||||
} else { // Otherwise just draw as 2D
|
} else { // Otherwise just draw as 2D
|
||||||
video::ITexture *texture = client->idef()->getInventoryTexture(item, client);
|
video::ITexture *texture = item_visuals->getInventoryTexture(item, client);
|
||||||
video::SColor color;
|
video::SColor color;
|
||||||
if (texture) {
|
if (texture) {
|
||||||
color = client->idef()->getItemstackColor(item, client);
|
color = item_visuals->getItemstackColor(item, client);
|
||||||
} else {
|
} else {
|
||||||
color = video::SColor(255, 255, 255, 255);
|
color = video::SColor(255, 255, 255, 255);
|
||||||
ITextureSource *tsrc = client->getTextureSource();
|
ITextureSource *tsrc = client->getTextureSource();
|
||||||
|
|
126
src/itemdef.cpp
126
src/itemdef.cpp
|
@ -7,14 +7,6 @@
|
||||||
|
|
||||||
#include "nodedef.h"
|
#include "nodedef.h"
|
||||||
#include "tool.h"
|
#include "tool.h"
|
||||||
#include "inventory.h"
|
|
||||||
#if CHECK_CLIENT_BUILD()
|
|
||||||
#include "client/mapblock_mesh.h"
|
|
||||||
#include "client/mesh.h"
|
|
||||||
#include "client/wieldmesh.h"
|
|
||||||
#include "client/client.h"
|
|
||||||
#include "client/texturesource.h"
|
|
||||||
#endif
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "util/serialize.h"
|
#include "util/serialize.h"
|
||||||
|
@ -360,34 +352,10 @@ void ItemDefinition::deSerialize(std::istream &is, u16 protocol_version)
|
||||||
|
|
||||||
class CItemDefManager: public IWritableItemDefManager
|
class CItemDefManager: public IWritableItemDefManager
|
||||||
{
|
{
|
||||||
#if CHECK_CLIENT_BUILD()
|
|
||||||
struct ClientCached
|
|
||||||
{
|
|
||||||
video::ITexture *inventory_texture;
|
|
||||||
ItemMesh wield_mesh;
|
|
||||||
Palette *palette;
|
|
||||||
|
|
||||||
ClientCached():
|
|
||||||
inventory_texture(NULL),
|
|
||||||
palette(NULL)
|
|
||||||
{}
|
|
||||||
|
|
||||||
~ClientCached() {
|
|
||||||
if (wield_mesh.mesh)
|
|
||||||
wield_mesh.mesh->drop();
|
|
||||||
}
|
|
||||||
|
|
||||||
DISABLE_CLASS_COPY(ClientCached);
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CItemDefManager()
|
CItemDefManager()
|
||||||
{
|
{
|
||||||
|
|
||||||
#if CHECK_CLIENT_BUILD()
|
|
||||||
m_main_thread = std::this_thread::get_id();
|
|
||||||
#endif
|
|
||||||
clear();
|
clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -435,94 +403,6 @@ public:
|
||||||
return m_item_definitions.find(name) != m_item_definitions.cend();
|
return m_item_definitions.find(name) != m_item_definitions.cend();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CHECK_CLIENT_BUILD()
|
|
||||||
protected:
|
|
||||||
ClientCached* createClientCachedDirect(const ItemStack &item, Client *client) const
|
|
||||||
{
|
|
||||||
// This is not thread-safe
|
|
||||||
sanity_check(std::this_thread::get_id() == m_main_thread);
|
|
||||||
|
|
||||||
const ItemDefinition &def = item.getDefinition(this);
|
|
||||||
std::string inventory_image = item.getInventoryImage(this);
|
|
||||||
std::string inventory_overlay = item.getInventoryOverlay(this);
|
|
||||||
std::string cache_key = def.name;
|
|
||||||
if (!inventory_image.empty())
|
|
||||||
cache_key += "/" + inventory_image;
|
|
||||||
if (!inventory_overlay.empty())
|
|
||||||
cache_key += ":" + inventory_overlay;
|
|
||||||
|
|
||||||
// Skip if already in cache
|
|
||||||
auto it = m_clientcached.find(cache_key);
|
|
||||||
if (it != m_clientcached.end())
|
|
||||||
return it->second.get();
|
|
||||||
|
|
||||||
infostream << "Lazily creating item texture and mesh for \""
|
|
||||||
<< cache_key << "\"" << std::endl;
|
|
||||||
|
|
||||||
ITextureSource *tsrc = client->getTextureSource();
|
|
||||||
|
|
||||||
// Create new ClientCached
|
|
||||||
auto cc = std::make_unique<ClientCached>();
|
|
||||||
|
|
||||||
cc->inventory_texture = NULL;
|
|
||||||
if (!inventory_image.empty())
|
|
||||||
cc->inventory_texture = tsrc->getTexture(inventory_image);
|
|
||||||
getItemMesh(client, item, &(cc->wield_mesh));
|
|
||||||
|
|
||||||
cc->palette = tsrc->getPalette(def.palette_image);
|
|
||||||
|
|
||||||
// Put in cache
|
|
||||||
ClientCached *ptr = cc.get();
|
|
||||||
m_clientcached[cache_key] = std::move(cc);
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
// Get item inventory texture
|
|
||||||
virtual video::ITexture* getInventoryTexture(const ItemStack &item,
|
|
||||||
Client *client) const
|
|
||||||
{
|
|
||||||
ClientCached *cc = createClientCachedDirect(item, client);
|
|
||||||
if (!cc)
|
|
||||||
return nullptr;
|
|
||||||
return cc->inventory_texture;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get item wield mesh
|
|
||||||
virtual ItemMesh* getWieldMesh(const ItemStack &item, Client *client) const
|
|
||||||
{
|
|
||||||
ClientCached *cc = createClientCachedDirect(item, client);
|
|
||||||
if (!cc)
|
|
||||||
return nullptr;
|
|
||||||
return &(cc->wield_mesh);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get item palette
|
|
||||||
virtual Palette* getPalette(const ItemStack &item, Client *client) const
|
|
||||||
{
|
|
||||||
ClientCached *cc = createClientCachedDirect(item, client);
|
|
||||||
if (!cc)
|
|
||||||
return nullptr;
|
|
||||||
return cc->palette;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual video::SColor getItemstackColor(const ItemStack &stack,
|
|
||||||
Client *client) const
|
|
||||||
{
|
|
||||||
// Look for direct color definition
|
|
||||||
const std::string &colorstring = stack.metadata.getString("color", 0);
|
|
||||||
video::SColor directcolor;
|
|
||||||
if (!colorstring.empty() && parseColorString(colorstring, directcolor, true))
|
|
||||||
return directcolor;
|
|
||||||
// See if there is a palette
|
|
||||||
Palette *palette = getPalette(stack, client);
|
|
||||||
const std::string &index = stack.metadata.getString("palette_index", 0);
|
|
||||||
if (palette && !index.empty())
|
|
||||||
return (*palette)[mystoi(index, 0, 255)];
|
|
||||||
// Fallback color
|
|
||||||
return get(stack.name).color;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
void applyTextureOverrides(const std::vector<TextureOverride> &overrides)
|
void applyTextureOverrides(const std::vector<TextureOverride> &overrides)
|
||||||
{
|
{
|
||||||
infostream << "ItemDefManager::applyTextureOverrides(): Applying "
|
infostream << "ItemDefManager::applyTextureOverrides(): Applying "
|
||||||
|
@ -666,12 +546,6 @@ private:
|
||||||
std::map<std::string, ItemDefinition*> m_item_definitions;
|
std::map<std::string, ItemDefinition*> m_item_definitions;
|
||||||
// Aliases
|
// Aliases
|
||||||
StringMap m_aliases;
|
StringMap m_aliases;
|
||||||
#if CHECK_CLIENT_BUILD()
|
|
||||||
// The id of the thread that is allowed to use irrlicht directly
|
|
||||||
std::thread::id m_main_thread;
|
|
||||||
// Cached textures and meshes
|
|
||||||
mutable std::unordered_map<std::string, std::unique_ptr<ClientCached>> m_clientcached;
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
IWritableItemDefManager* createItemDefManager()
|
IWritableItemDefManager* createItemDefManager()
|
||||||
|
|
|
@ -17,14 +17,7 @@
|
||||||
#include "util/pointabilities.h"
|
#include "util/pointabilities.h"
|
||||||
#include "util/pointedthing.h"
|
#include "util/pointedthing.h"
|
||||||
|
|
||||||
class IGameDef;
|
|
||||||
class Client;
|
|
||||||
struct ToolCapabilities;
|
struct ToolCapabilities;
|
||||||
struct ItemMesh;
|
|
||||||
struct ItemStack;
|
|
||||||
typedef std::vector<video::SColor> Palette; // copied from src/client/texturesource.h
|
|
||||||
namespace irr::video { class ITexture; }
|
|
||||||
using namespace irr;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Base item definition
|
Base item definition
|
||||||
|
@ -142,30 +135,6 @@ public:
|
||||||
virtual bool isKnown(const std::string &name) const=0;
|
virtual bool isKnown(const std::string &name) const=0;
|
||||||
|
|
||||||
virtual void serialize(std::ostream &os, u16 protocol_version)=0;
|
virtual void serialize(std::ostream &os, u16 protocol_version)=0;
|
||||||
|
|
||||||
/* Client-specific methods */
|
|
||||||
// TODO: should be moved elsewhere in the future
|
|
||||||
|
|
||||||
// Get item inventory texture
|
|
||||||
virtual video::ITexture* getInventoryTexture(const ItemStack &item, Client *client) const
|
|
||||||
{ return nullptr; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get wield mesh
|
|
||||||
* @returns nullptr if there is an inventory image
|
|
||||||
*/
|
|
||||||
virtual ItemMesh* getWieldMesh(const ItemStack &item, Client *client) const
|
|
||||||
{ return nullptr; }
|
|
||||||
|
|
||||||
// Get item palette
|
|
||||||
virtual Palette* getPalette(const ItemStack &item, Client *client) const
|
|
||||||
{ return nullptr; }
|
|
||||||
|
|
||||||
// Returns the base color of an item stack: the color of all
|
|
||||||
// tiles that do not define their own color.
|
|
||||||
virtual video::SColor getItemstackColor(const ItemStack &stack,
|
|
||||||
Client *client) const
|
|
||||||
{ return video::SColor(0); }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class IWritableItemDefManager : public IItemDefManager
|
class IWritableItemDefManager : public IItemDefManager
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue