diff options
-rw-r--r-- | src/content_cao.cpp | 61 | ||||
-rw-r--r-- | src/itemdef.cpp | 110 | ||||
-rw-r--r-- | src/itemdef.h | 9 | ||||
-rw-r--r-- | src/script/common/c_content.cpp | 2 | ||||
-rw-r--r-- | src/wieldmesh.cpp | 14 |
5 files changed, 186 insertions, 10 deletions
diff --git a/src/content_cao.cpp b/src/content_cao.cpp index 1b8e84c8f..bde0dd320 100644 --- a/src/content_cao.cpp +++ b/src/content_cao.cpp @@ -954,15 +954,43 @@ void GenericCAO::addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc, IItemDefManager *idef = m_gamedef->idef(); ItemStack item(m_prop.textures[0], 1, 0, "", idef); - m_wield_meshnode = new WieldMeshSceneNode( - smgr->getRootSceneNode(), smgr, -1); - m_wield_meshnode->setItem(item, m_gamedef); - - m_wield_meshnode->setScale(v3f(m_prop.visual_size.X/2, - m_prop.visual_size.Y/2, - m_prop.visual_size.X/2)); - u8 li = m_last_light; - m_wield_meshnode->setColor(video::SColor(255,li,li,li)); + if (!item.getDefinition(idef).meshname.empty()) + { + scene::IAnimatedMesh *mesh = m_gamedef->getMesh(item.getDefinition(idef).meshname); + if(mesh) + { + m_animated_meshnode = smgr->addAnimatedMeshSceneNode(mesh, NULL); + + m_animated_meshnode->grab(); + mesh->drop(); // The scene node took hold of it + m_animated_meshnode->animateJoints(); // Needed for some animations + m_animated_meshnode->setScale(v3f(m_prop.visual_size.X, + m_prop.visual_size.Y, + m_prop.visual_size.X)); + u8 li = m_last_light; + setMeshColor(m_animated_meshnode->getMesh(), video::SColor(255,li,li,li)); + + bool backface_culling = m_prop.backface_culling; + if (m_is_player) + backface_culling = false; + + m_animated_meshnode->setMaterialFlag(video::EMF_LIGHTING, false); + m_animated_meshnode->setMaterialFlag(video::EMF_BILINEAR_FILTER, false); + m_animated_meshnode->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF); + m_animated_meshnode->setMaterialFlag(video::EMF_FOG_ENABLE, true); + m_animated_meshnode->setMaterialFlag(video::EMF_BACK_FACE_CULLING, backface_culling); + } + } + else { + m_wield_meshnode = new WieldMeshSceneNode( + smgr->getRootSceneNode(), smgr, -1); + m_wield_meshnode->setItem(item, m_gamedef); + m_wield_meshnode->setScale(v3f(m_prop.visual_size.X/2, + m_prop.visual_size.Y/2, + m_prop.visual_size.X/2)); + u8 li = m_last_light; + m_wield_meshnode->setColor(video::SColor(255,li,li,li)); + } } } else { infostream<<"GenericCAO::addToScene(): \""<<m_prop.visual @@ -1402,6 +1430,21 @@ void GenericCAO::updateTextures(const std::string &mod) m_animated_meshnode->getMaterial(i).SpecularColor = m_prop.colors[i]; } } + else if (m_prop.visual == "wielditem") { + IItemDefManager *idef = m_gamedef->idef(); + ItemStack item(m_prop.textures[0], 1, 0, "", idef); + + if (!item.getDefinition(idef).meshname.empty()) { + + unsigned int materialcount = m_animated_meshnode->getMaterialCount(); + + for (unsigned int i = 0; i < materialcount; i++) { + m_animated_meshnode->getMaterial(i) + .setTexture(0, tsrc->getTexture(item + .getDefinition(idef).meshtexture)); + } + } + } } if(m_meshnode) { diff --git a/src/itemdef.cpp b/src/itemdef.cpp index fa277f4ff..e37f10d61 100644 --- a/src/itemdef.cpp +++ b/src/itemdef.cpp @@ -77,6 +77,8 @@ ItemDefinition& ItemDefinition::operator=(const ItemDefinition &def) sound_place = def.sound_place; sound_place_failed = def.sound_place_failed; range = def.range; + meshname = def.meshname; + meshtexture = def.meshtexture; return *this; } @@ -157,6 +159,10 @@ void ItemDefinition::serialize(std::ostream &os, u16 protocol_version) const os << serializeString(sound_place_failed.name); writeF1000(os, sound_place_failed.gain); } + + //TODO check for protocol version? + os<<serializeString(meshname); + os<<serializeString(meshtexture); } void ItemDefinition::deSerialize(std::istream &is) @@ -214,6 +220,10 @@ void ItemDefinition::deSerialize(std::istream &is) sound_place_failed.name = deSerializeString(is); sound_place_failed.gain = readF1000(is); } catch(SerializationError &e) {}; + + //TODO check for protocol? + meshname = deSerializeString(is); + meshtexture = deSerializeString(is); } /* @@ -341,7 +351,7 @@ CItemDefManager::ClientCached* CItemDefManager::createClientCachedDirect(const s // Create an inventory texture cc->inventory_texture = NULL; - if (def.inventory_image != "") + if (!def.inventory_image.empty()) cc->inventory_texture = tsrc->getTexture(def.inventory_image); // Additional processing for nodes: @@ -352,6 +362,10 @@ CItemDefManager::ClientCached* CItemDefManager::createClientCachedDirect(const s if (def.type == ITEM_NODE) { createNodeItemTexture(name, def, nodedef, cc, gamedef, tsrc); } + else if (def.type == ITEM_CRAFT) { + if ( !def.meshname.empty()) + createMeshItemTexture(name, def, nodedef, cc, gamedef, tsrc); + } // Put in cache m_clientcached.set(name, cc); @@ -650,6 +664,100 @@ void CItemDefManager::createNodeItemTexture(const std::string& name, if (node_mesh) node_mesh->drop(); } + +/******************************************************************************/ +void CItemDefManager::renderMeshToTexture(const ItemDefinition& def, scene::IMesh* mesh, + ClientCached* cc, ITextureSource* tsrc) const +{ + video::ITexture *itemimage = cc->inventory_texture; + + /* + Draw node mesh into a render target texture + */ + TextureFromMeshParams params; + params.mesh = mesh; + params.dim.set(64, 64); + params.rtt_texture_name = "INVENTORY_" + def.name + "_RTT"; + params.delete_texture_on_shutdown = true; + params.camera_position.set(0, 1.0, -1.5); + params.camera_position.rotateXZBy(45); + params.camera_lookat.set(0, 0, 0); + // Set orthogonal projection + params.camera_projection_matrix.buildProjectionMatrixOrthoLH(1.65, 1.65, 0, + 100); + params.ambient_light.set(1.0, 0.9, 0.9, 0.9); + params.light_position.set(10, 100, -50); + params.light_color.set(1.0, 0.5, 0.5, 0.5); + params.light_radius = 1000; + cc->inventory_texture = tsrc->generateTextureFromMesh(params); + + // render-to-target didn't work + if (cc->inventory_texture == NULL) { + + cc->inventory_texture = itemimage; + } +} + +/******************************************************************************/ +void CItemDefManager::createMeshItemTexture(const std::string& name, + const ItemDefinition& def, INodeDefManager* nodedef, + ClientCached* cc, IGameDef* gamedef, ITextureSource* tsrc) const +{ + // Get node properties + content_t id = nodedef->getId(name); + const ContentFeatures& f = nodedef->get(id); + + if (def.meshname == "") + return; + + video::ITexture *texture = tsrc->getTexture(def.meshtexture); + + infostream<<"CItemDefManager::createMeshItemTexture(): mesh"<<std::endl; + + scene::IAnimatedMesh *mesh = gamedef->getMesh(def.meshname); + if(mesh) + { + + video::SColor c(255, 255, 255, 255); + setMeshColor(mesh, c); + + rotateMeshXZby(mesh, 180); + + // scale and translate the mesh so it's a + // unit cube centered on the origin + scaleMesh(mesh, v3f(1.0 / BS, 1.0 / BS, 1.0 / BS)); + + // Customize materials + for (u32 i = 0; i < mesh->getMeshBufferCount(); ++i) { + + video::SMaterial &material = mesh->getMeshBuffer(i)->getMaterial(); + material.setTexture(0, texture); + material.setFlag(video::EMF_BACK_FACE_CULLING, true); + material.setFlag(video::EMF_BILINEAR_FILTER, false); + material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; + } + + /* + Draw node mesh into a render target texture + */ + renderMeshToTexture(def, mesh, cc, tsrc); + + /* + Use the ingot mesh as the wield mesh + */ + + cc->wield_mesh = mesh; + cc->wield_mesh->grab(); + // no way reference count can be smaller than 2 in this place! + assert(cc->wield_mesh->getReferenceCount() >= 2); + + if (mesh) + mesh->drop(); + + } + else + errorstream<<"CItemDefManager::createMeshItemTexture(): Could not load mesh "<<def.meshname<<std::endl; +} #endif /******************************************************************************/ diff --git a/src/itemdef.h b/src/itemdef.h index fb157705f..74c6d0b3e 100644 --- a/src/itemdef.h +++ b/src/itemdef.h @@ -66,6 +66,8 @@ struct ItemDefinition std::string inventory_image; // Optional for nodes, mandatory for tools/craftitems std::string wield_image; // If empty, inventory_image or mesh (only nodes) is used v3f wield_scale; + std::string meshname; // name of internal mesh (or meshfile to use TBD) + std::string meshtexture; // meshtexture /* Item stack and interaction properties @@ -211,6 +213,13 @@ private: const ItemDefinition& def, INodeDefManager* nodedef, ClientCached* cc, IGameDef* gamedef, ITextureSource* tsrc) const; + void createMeshItemTexture(const std::string& name, + const ItemDefinition& def, INodeDefManager* nodedef, + ClientCached* cc, IGameDef* gamedef, ITextureSource* tsrc) const; + + void renderMeshToTexture(const ItemDefinition& def, scene::IMesh* mesh, + ClientCached* cc, ITextureSource* tsrc) const; + ClientCached* createClientCachedDirect(const std::string &name, IGameDef *gamedef) const; diff --git a/src/script/common/c_content.cpp b/src/script/common/c_content.cpp index 36a5c2ddd..78f3c943f 100644 --- a/src/script/common/c_content.cpp +++ b/src/script/common/c_content.cpp @@ -58,6 +58,8 @@ ItemDefinition read_item_definition(lua_State* L,int index, getstringfield(L, index, "description", def.description); getstringfield(L, index, "inventory_image", def.inventory_image); getstringfield(L, index, "wield_image", def.wield_image); + getstringfield(L, index, "mesh", def.meshname); + getstringfield(L, index, "meshtexture", def.meshtexture); lua_getfield(L, index, "wield_scale"); if(lua_istable(L, -1)){ diff --git a/src/wieldmesh.cpp b/src/wieldmesh.cpp index a022754a6..77a5cf73a 100644 --- a/src/wieldmesh.cpp +++ b/src/wieldmesh.cpp @@ -386,6 +386,20 @@ void WieldMeshSceneNode::setItem(const ItemStack &item, IGameDef *gamedef) } return; } + else if (idef->getWieldMesh(def.name, gamedef) != 0) { + irr::scene::IMesh * mesh = idef->getWieldMesh(def.name, gamedef); + m_meshnode->setMesh(mesh); + u32 material_count = m_meshnode->getMaterialCount(); + for (u32 i = 0; i < material_count; ++i) { + video::SMaterial &material = m_meshnode->getMaterial(i); + material.setFlag(video::EMF_BACK_FACE_CULLING, true); + material.setFlag(video::EMF_BILINEAR_FILTER, m_bilinear_filter); + material.setFlag(video::EMF_TRILINEAR_FILTER, m_trilinear_filter); + material.MaterialType = m_material_type; + material.setTexture(0, tsrc->getTexture(def.meshtexture)); + } + return; + } else if (def.inventory_image != "") { setExtruded(def.inventory_image, def.wield_scale, tsrc, 1); return; |