From 9b551d5cbcaf71a8c39bbf7e886290649aed4799 Mon Sep 17 00:00:00 2001 From: Kahrl Date: Sun, 2 Nov 2014 03:47:43 +0100 Subject: Implement WieldMeshSceneNode which improves wield mesh rendering - Don't create and cache an extruded mesh for every (non-node) item. Instead use a single one per image resolution. - For cubic nodes reuse a single wield mesh too - Improve lighting of the wielded item - Increase far value of wield mesh scene camera, fixes #1770 - Also includes some minor refactorings of Camera and GenericCAO. --- src/itemdef.cpp | 150 +++++++++++++++++++++++--------------------------------- 1 file changed, 62 insertions(+), 88 deletions(-) (limited to 'src/itemdef.cpp') diff --git a/src/itemdef.cpp b/src/itemdef.cpp index f976c3eb7..ac67c5b27 100644 --- a/src/itemdef.cpp +++ b/src/itemdef.cpp @@ -27,6 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #ifndef SERVER #include "mapblock_mesh.h" #include "mesh.h" +#include "wieldmesh.h" #include "tile.h" #endif #include "log.h" @@ -330,104 +331,78 @@ public: ITextureSource *tsrc = gamedef->getTextureSource(); INodeDefManager *nodedef = gamedef->getNodeDefManager(); - IrrlichtDevice *device = tsrc->getDevice(); - video::IVideoDriver *driver = device->getVideoDriver(); - const ItemDefinition *def = &get(name); + const ItemDefinition &def = get(name); // Create new ClientCached cc = new ClientCached(); - bool need_node_mesh = false; - // Create an inventory texture cc->inventory_texture = NULL; - if(def->inventory_image != "") - { - cc->inventory_texture = tsrc->getTexture(def->inventory_image); - } - else if(def->type == ITEM_NODE) - { - need_node_mesh = true; - } + if(def.inventory_image != "") + cc->inventory_texture = tsrc->getTexture(def.inventory_image); + + // Additional processing for nodes: + // - Create a wield mesh if WieldMeshSceneNode can't render + // the node on its own. + // - If inventory_texture isn't set yet, create one using + // render-to-texture. + if (def.type == ITEM_NODE) { + // Get node properties + content_t id = nodedef->getId(name); + const ContentFeatures &f = nodedef->get(id); - // Create a wield mesh - assert(cc->wield_mesh == NULL); - if(def->type == ITEM_NODE && def->wield_image == "") - { - need_node_mesh = true; - } - else if(def->wield_image != "" || def->inventory_image != "") - { - // Extrude the wield image into a mesh - - std::string imagename; - if(def->wield_image != "") - imagename = def->wield_image; - else - imagename = def->inventory_image; - - cc->wield_mesh = createExtrudedMesh( - tsrc->getTexture(imagename), - driver, - def->wield_scale * v3f(40.0, 40.0, 4.0)); - if(cc->wield_mesh == NULL) - { - infostream<<"ItemDefManager: WARNING: " - <<"updateTexturesAndMeshes(): " - <<"Unable to create extruded mesh for item " - <name<inventory_texture == NULL; - if(need_node_mesh) - { - /* - Get node properties - */ - content_t id = nodedef->getId(def->name); - const ContentFeatures &f = nodedef->get(id); + // Keep this in sync with WieldMeshSceneNode::setItem() + bool need_wield_mesh = + !(f.mesh_ptr[0] || + f.drawtype == NDT_NORMAL || + f.drawtype == NDT_ALLFACES || + f.drawtype == NDT_AIRLIKE); - u8 param1 = 0; - if(f.param_type == CPT_LIGHT) - param1 = 0xee; + scene::IMesh *node_mesh = NULL; - /* - Make a mesh from the node - */ bool reenable_shaders = false; - if(g_settings->getBool("enable_shaders")){ - reenable_shaders = true; - g_settings->setBool("enable_shaders",false); - } - MeshMakeData mesh_make_data(gamedef); - u8 param2 = 0; - if (f.param_type_2 == CPT2_WALLMOUNTED) - param2 = 1; - MapNode mesh_make_node(id, param1, param2); - mesh_make_data.fillSingleNode(&mesh_make_node); - MapBlockMesh mapblock_mesh(&mesh_make_data, v3s16(0, 0, 0)); - scene::IMesh *node_mesh = mapblock_mesh.getMesh(); - assert(node_mesh); - video::SColor c(255, 255, 255, 255); - setMeshColor(node_mesh, c); - /* - Scale and translate the mesh so it's a unit cube - centered on the origin - */ - scaleMesh(node_mesh, v3f(1.0/BS, 1.0/BS, 1.0/BS)); - translateMesh(node_mesh, v3f(-1.0, -1.0, -1.0)); + if (need_rtt_mesh || need_wield_mesh) { + u8 param1 = 0; + if (f.param_type == CPT_LIGHT) + param1 = 0xee; + + /* + Make a mesh from the node + */ + if (g_settings->getBool("enable_shaders")) { + reenable_shaders = true; + g_settings->setBool("enable_shaders", false); + } + MeshMakeData mesh_make_data(gamedef); + u8 param2 = 0; + if (f.param_type_2 == CPT2_WALLMOUNTED) + param2 = 1; + MapNode mesh_make_node(id, param1, param2); + mesh_make_data.fillSingleNode(&mesh_make_node); + MapBlockMesh mapblock_mesh(&mesh_make_data, v3s16(0, 0, 0)); + node_mesh = mapblock_mesh.getMesh(); + node_mesh->grab(); + video::SColor c(255, 255, 255, 255); + setMeshColor(node_mesh, c); + + // scale and translate the mesh so it's a + // unit cube centered on the origin + scaleMesh(node_mesh, v3f(1.0/BS, 1.0/BS, 1.0/BS)); + translateMesh(node_mesh, v3f(-1.0, -1.0, -1.0)); + } /* Draw node mesh into a render target texture */ - if(cc->inventory_texture == NULL) - { + if (need_rtt_mesh) { TextureFromMeshParams params; params.mesh = node_mesh; params.dim.set(64, 64); params.rtt_texture_name = "INVENTORY_" - + def->name + "_RTT"; + + def.name + "_RTT"; params.delete_texture_on_shutdown = true; params.camera_position.set(0, 1.0, -1.5); params.camera_position.rotateXZBy(45); @@ -449,8 +424,7 @@ public: tsrc->generateTextureFromMesh(params); // render-to-target didn't work - if(cc->inventory_texture == NULL) - { + if (cc->inventory_texture == NULL) { cc->inventory_texture = tsrc->getTexture(f.tiledef[0].name); } @@ -459,16 +433,16 @@ public: /* Use the node mesh as the wield mesh */ + if (need_wield_mesh) { + cc->wield_mesh = node_mesh; + cc->wield_mesh->grab(); - // Scale to proper wield mesh proportions - scaleMesh(node_mesh, v3f(30.0, 30.0, 30.0) - * def->wield_scale); - - cc->wield_mesh = node_mesh; - cc->wield_mesh->grab(); + // no way reference count can be smaller than 2 in this place! + assert(cc->wield_mesh->getReferenceCount() >= 2); + } - //no way reference count can be smaller than 2 in this place! - assert(cc->wield_mesh->getReferenceCount() >= 2); + if (node_mesh) + node_mesh->drop(); if (reenable_shaders) g_settings->setBool("enable_shaders",true); -- cgit v1.2.3