X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fnodedef.cpp;h=bcf51a072e1429e9f75d8c93b6e1e1786564fa6b;hb=5b55deb1ebfd55562a6a57fbdbf5dce86015ca86;hp=ef61d0722a5b34314f14017ea80ae8b8bb127f74;hpb=0066bd77d25793b76fdaa9a62755cca934f0121d;p=dragonfireclient.git diff --git a/src/nodedef.cpp b/src/nodedef.cpp index ef61d0722..bcf51a072 100644 --- a/src/nodedef.cpp +++ b/src/nodedef.cpp @@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #ifndef SERVER #include "tile.h" #include "mesh.h" +#include #endif #include "log.h" #include "settings.h" @@ -226,13 +227,13 @@ void ContentFeatures::reset() liquid_alternative_source = ""; liquid_viscosity = 0; liquid_renewable = true; - freezemelt = ""; liquid_range = LIQUID_LEVEL_MAX+1; drowning = 0; light_source = 0; damage_per_second = 0; node_box = NodeBox(); selection_box = NodeBox(); + collision_box = NodeBox(); waving = 0; legacy_facedir_simple = false; legacy_wallmounted = false; @@ -303,6 +304,7 @@ void ContentFeatures::serialize(std::ostream &os, u16 protocol_version) // Stuff below should be moved to correct place in a version that otherwise changes // the protocol version os< &result) const; @@ -399,6 +402,18 @@ class CNodeDefManager: public IWritableNodeDefManager { void serialize(std::ostream &os, u16 protocol_version); void deSerialize(std::istream &is); + inline virtual bool getNodeRegistrationStatus() const; + inline virtual void setNodeRegistrationStatus(bool completed); + + virtual void pendNodeResolve(NodeResolveInfo *nri); + virtual void cancelNodeResolve(NodeResolver *resolver); + virtual void runNodeResolverCallbacks(); + + virtual bool getIdFromResolveInfo(NodeResolveInfo *nri, + const std::string &node_alt, content_t c_fallback, content_t &result); + virtual bool getIdsFromResolveInfo(NodeResolveInfo *nri, + std::vector &result); + private: void addNameIdMapping(content_t i, std::string name); #ifndef SERVER @@ -426,6 +441,12 @@ class CNodeDefManager: public IWritableNodeDefManager { // Next possibly free id content_t m_next_id; + + // List of node strings and node resolver callbacks to perform + std::list m_pending_node_lookups; + + // True when all nodes have been registered + bool m_node_registration_complete; }; @@ -437,6 +458,15 @@ CNodeDefManager::CNodeDefManager() CNodeDefManager::~CNodeDefManager() { +#ifndef SERVER + for (u32 i = 0; i < m_content_features.size(); i++) { + ContentFeatures *f = &m_content_features[i]; + for (u32 j = 0; j < 24; j++) { + if (f->mesh_ptr[j]) + f->mesh_ptr[j]->drop(); + } + } +#endif } @@ -448,6 +478,14 @@ void CNodeDefManager::clear() m_group_to_items.clear(); m_next_id = 0; + m_node_registration_complete = false; + for (std::list::iterator + it = m_pending_node_lookups.begin(); + it != m_pending_node_lookups.end(); + ++it) + delete *it; + m_pending_node_lookups.clear(); + u32 initial_length = 0; initial_length = MYMAX(initial_length, CONTENT_UNKNOWN + 1); initial_length = MYMAX(initial_length, CONTENT_AIR + 1); @@ -512,16 +550,14 @@ IWritableNodeDefManager *CNodeDefManager::clone() } -const ContentFeatures& CNodeDefManager::get(content_t c) const +inline const ContentFeatures& CNodeDefManager::get(content_t c) const { - if (c < m_content_features.size()) - return m_content_features[c]; - else - return m_content_features[CONTENT_UNKNOWN]; + return c < m_content_features.size() + ? m_content_features[c] : m_content_features[CONTENT_UNKNOWN]; } -const ContentFeatures& CNodeDefManager::get(const MapNode &n) const +inline const ContentFeatures& CNodeDefManager::get(const MapNode &n) const { return get(n.getContent()); } @@ -683,9 +719,11 @@ void CNodeDefManager::updateTextures(IGameDef *gamedef) #ifndef SERVER infostream << "CNodeDefManager::updateTextures(): Updating " "textures in node definitions" << std::endl; - + ITextureSource *tsrc = gamedef->tsrc(); IShaderSource *shdsrc = gamedef->getShaderSource(); + scene::ISceneManager* smgr = gamedef->getSceneManager(); + scene::IMeshManipulator* meshmanip = smgr->getMeshManipulator(); bool new_style_water = g_settings->getBool("new_style_water"); bool new_style_leaves = g_settings->getBool("new_style_leaves"); @@ -694,6 +732,7 @@ void CNodeDefManager::updateTextures(IGameDef *gamedef) bool enable_shaders = g_settings->getBool("enable_shaders"); bool enable_bumpmapping = g_settings->getBool("enable_bumpmapping"); bool enable_parallax_occlusion = g_settings->getBool("enable_parallax_occlusion"); + bool enable_mesh_cache = g_settings->getBool("enable_mesh_cache"); bool use_normal_texture = enable_shaders && (enable_bumpmapping || enable_parallax_occlusion); @@ -827,33 +866,50 @@ void CNodeDefManager::updateTextures(IGameDef *gamedef) f->tiledef_special[j].backface_culling, f->alpha, material_type); } - // Meshnode drawtype - // Read the mesh and apply scale if ((f->drawtype == NDT_MESH) && (f->mesh != "")) { + // Meshnode drawtype + // Read the mesh and apply scale f->mesh_ptr[0] = gamedef->getMesh(f->mesh); - scaleMesh(f->mesh_ptr[0], v3f(f->visual_scale,f->visual_scale,f->visual_scale)); - recalculateBoundingBox(f->mesh_ptr[0]); - } - - //Convert regular nodebox nodes to meshnodes - //Change the drawtype and apply scale - if ((f->drawtype == NDT_NODEBOX) && - ((f->node_box.type == NODEBOX_REGULAR) || (f->node_box.type == NODEBOX_FIXED)) && + if (f->mesh_ptr[0]){ + v3f scale = v3f(1.0, 1.0, 1.0) * BS * f->visual_scale; + scaleMesh(f->mesh_ptr[0], scale); + recalculateBoundingBox(f->mesh_ptr[0]); + meshmanip->recalculateNormals(f->mesh_ptr[0], true, false); + } + } else if ((f->drawtype == NDT_NODEBOX) && + ((f->node_box.type == NODEBOX_REGULAR) || + (f->node_box.type == NODEBOX_FIXED)) && (!f->node_box.fixed.empty())) { + //Convert regular nodebox nodes to meshnodes + //Change the drawtype and apply scale f->drawtype = NDT_MESH; f->mesh_ptr[0] = convertNodeboxNodeToMesh(f); - scaleMesh(f->mesh_ptr[0], v3f(f->visual_scale,f->visual_scale,f->visual_scale)); + v3f scale = v3f(1.0, 1.0, 1.0) * f->visual_scale; + scaleMesh(f->mesh_ptr[0], scale); recalculateBoundingBox(f->mesh_ptr[0]); + meshmanip->recalculateNormals(f->mesh_ptr[0], true, false); } - //Cache 6dfacedir rotated clones of meshes - if (f->mesh_ptr[0] && (f->param_type_2 == CPT2_FACEDIR)) { - for (u16 j = 1; j < 24; j++) { - f->mesh_ptr[j] = cloneMesh(f->mesh_ptr[0]); - rotateMeshBy6dFacedir(f->mesh_ptr[j], j); - recalculateBoundingBox(f->mesh_ptr[j]); - } + //Cache 6dfacedir and wallmounted rotated clones of meshes + if (enable_mesh_cache && f->mesh_ptr[0] && (f->param_type_2 == CPT2_FACEDIR)) { + for (u16 j = 1; j < 24; j++) { + f->mesh_ptr[j] = cloneMesh(f->mesh_ptr[0]); + rotateMeshBy6dFacedir(f->mesh_ptr[j], j); + recalculateBoundingBox(f->mesh_ptr[j]); + meshmanip->recalculateNormals(f->mesh_ptr[j], true, false); + } + } else if (enable_mesh_cache && f->mesh_ptr[0] && (f->param_type_2 == CPT2_WALLMOUNTED)) { + static const u8 wm_to_6d[6] = {20, 0, 16+1, 12+3, 8, 4+2}; + for (u16 j = 1; j < 6; j++) { + f->mesh_ptr[j] = cloneMesh(f->mesh_ptr[0]); + rotateMeshBy6dFacedir(f->mesh_ptr[j], wm_to_6d[j]); + recalculateBoundingBox(f->mesh_ptr[j]); + meshmanip->recalculateNormals(f->mesh_ptr[j], true, false); } + rotateMeshBy6dFacedir(f->mesh_ptr[0], wm_to_6d[0]); + recalculateBoundingBox(f->mesh_ptr[0]); + meshmanip->recalculateNormals(f->mesh_ptr[0], true, false); + } } #endif } @@ -898,7 +954,10 @@ void CNodeDefManager::fillTileAttribs(ITextureSource *tsrc, TileSpec *tile, tile->material_flags &= ~MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES; } else { std::ostringstream os(std::ios::binary); + tile->frames.resize(frame_count); + for (int i = 0; i < frame_count; i++) { + FrameSpec frame; os.str(""); @@ -1106,7 +1165,7 @@ void ContentFeatures::serializeOld(std::ostream &os, u16 protocol_version) writeU8(os, drowning); writeU8(os, leveled); writeU8(os, liquid_range); - } else + } else throw SerializationError("ContentFeatures::serialize(): " "Unsupported version requested"); } @@ -1221,3 +1280,130 @@ void ContentFeatures::deSerializeOld(std::istream &is, int version) throw SerializationError("unsupported ContentFeatures version"); } } + + +inline bool CNodeDefManager::getNodeRegistrationStatus() const +{ + return m_node_registration_complete; +} + + +inline void CNodeDefManager::setNodeRegistrationStatus(bool completed) +{ + m_node_registration_complete = completed; +} + + +void CNodeDefManager::pendNodeResolve(NodeResolveInfo *nri) +{ + nri->resolver->m_ndef = this; + if (m_node_registration_complete) { + nri->resolver->resolveNodeNames(nri); + nri->resolver->m_lookup_done = true; + delete nri; + } else { + m_pending_node_lookups.push_back(nri); + } +} + + +void CNodeDefManager::cancelNodeResolve(NodeResolver *resolver) +{ + for (std::list::iterator + it = m_pending_node_lookups.begin(); + it != m_pending_node_lookups.end(); + ++it) { + NodeResolveInfo *nri = *it; + if (resolver == nri->resolver) { + it = m_pending_node_lookups.erase(it); + delete nri; + } + } +} + + +void CNodeDefManager::runNodeResolverCallbacks() +{ + while (!m_pending_node_lookups.empty()) { + NodeResolveInfo *nri = m_pending_node_lookups.front(); + m_pending_node_lookups.pop_front(); + nri->resolver->resolveNodeNames(nri); + nri->resolver->m_lookup_done = true; + delete nri; + } +} + + +bool CNodeDefManager::getIdFromResolveInfo(NodeResolveInfo *nri, + const std::string &node_alt, content_t c_fallback, content_t &result) +{ + if (nri->nodenames.empty()) { + result = c_fallback; + errorstream << "Resolver empty nodename list" << std::endl; + return false; + } + + content_t c; + std::string name = nri->nodenames.front(); + nri->nodenames.pop_front(); + + bool success = getId(name, c); + if (!success && node_alt != "") { + name = node_alt; + success = getId(name, c); + } + + if (!success) { + errorstream << "Resolver: Failed to resolve node name '" << name + << "'." << std::endl; + c = c_fallback; + } + + result = c; + return success; +} + + +bool CNodeDefManager::getIdsFromResolveInfo(NodeResolveInfo *nri, + std::vector &result) +{ + bool success = true; + + if (nri->nodelistinfo.empty()) { + errorstream << "Resolver: Empty nodelistinfo list" << std::endl; + return false; + } + + NodeListInfo listinfo = nri->nodelistinfo.front(); + nri->nodelistinfo.pop_front(); + + while (listinfo.length--) { + if (nri->nodenames.empty()) { + errorstream << "Resolver: Empty nodename list" << std::endl; + return false; + } + + content_t c; + std::string name = nri->nodenames.front(); + nri->nodenames.pop_front(); + + if (name.substr(0,6) != "group:") { + if (getId(name, c)) { + result.push_back(c); + } else if (listinfo.all_required) { + errorstream << "Resolver: Failed to resolve node name '" << name + << "'." << std::endl; + result.push_back(listinfo.c_fallback); + success = false; + } + } else { + std::set cids; + std::set::iterator it; + getIds(name, cids); + for (it = cids.begin(); it != cids.end(); ++it) + result.push_back(*it); + } + } + + return success; +}