Skip to content

Commit

Permalink
Fix item and wield meshes (#6596)
Browse files Browse the repository at this point in the history
  • Loading branch information
numberZero authored and sfan5 committed Nov 14, 2017
1 parent 8ea8633 commit ee6bb5a
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 35 deletions.
10 changes: 9 additions & 1 deletion src/content_mapblock.cpp
Expand Up @@ -725,7 +725,7 @@ void MapblockMeshGenerator::drawGlasslikeFramedNode()
v3s16 n2p = blockpos_nodes + p + g_26dirs[i];
MapNode n2 = data->m_vmanip.getNodeNoEx(n2p);
content_t n2c = n2.getContent();
if (n2c == current || n2c == CONTENT_IGNORE)
if (n2c == current)
nb[i] = 1;
}
}
Expand Down Expand Up @@ -1363,3 +1363,11 @@ void MapblockMeshGenerator::generate()
drawNode();
}
}

void MapblockMeshGenerator::renderSingle(content_t node)
{
p = {0, 0, 0};
n = MapNode(node, 0xff, 0x00);
f = &nodedef->get(n);
drawNode();
}
1 change: 1 addition & 0 deletions src/content_mapblock.h
Expand Up @@ -145,4 +145,5 @@ class MapblockMeshGenerator
public:
MapblockMeshGenerator(MeshMakeData *input, MeshCollector *output);
void generate();
void renderSingle(content_t node);
};
3 changes: 2 additions & 1 deletion src/mapblock_mesh.h
Expand Up @@ -22,6 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "irrlichttypes_extrabloated.h"
#include "client/tile.h"
#include "voxel.h"
#include <array>
#include <map>

class Client;
Expand Down Expand Up @@ -187,7 +188,7 @@ struct PreMeshBuffer

struct MeshCollector
{
std::vector<PreMeshBuffer> prebuffers[MAX_TILE_LAYERS];
std::array<std::vector<PreMeshBuffer>, MAX_TILE_LAYERS> prebuffers;
bool m_use_tangent_vertices;

MeshCollector(bool use_tangent_vertices):
Expand Down
78 changes: 45 additions & 33 deletions src/wieldmesh.cpp
Expand Up @@ -25,6 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "itemdef.h"
#include "nodedef.h"
#include "mesh.h"
#include "content_mapblock.h"
#include "mapblock_mesh.h"
#include "client/tile.h"
#include "log.h"
Expand Down Expand Up @@ -300,6 +301,41 @@ void WieldMeshSceneNode::setExtruded(const std::string &imagename,
}
}

scene::SMesh *createSpecialNodeMesh(Client *client, content_t id, std::vector<ItemPartColor> *colors)
{
MeshMakeData mesh_make_data(client, false, false);
MeshCollector collector(false);
mesh_make_data.setSmoothLighting(false);
MapblockMeshGenerator gen(&mesh_make_data, &collector);
gen.renderSingle(id);
colors->clear();
scene::SMesh *mesh = new scene::SMesh();
for (auto &prebuffers : collector.prebuffers)
for (PreMeshBuffer &p : prebuffers) {
if (p.layer.material_flags & MATERIAL_FLAG_ANIMATION) {
const FrameSpec &frame = (*p.layer.frames)[0];
p.layer.texture = frame.texture;
p.layer.normal_texture = frame.normal_texture;
}
for (video::S3DVertex &v : p.vertices)
v.Color.setAlpha(255);
scene::SMeshBuffer *buf = new scene::SMeshBuffer();
// always set all textures
// with no shaders only texture 0 is ever actually used
buf->Material.setTexture(0, p.layer.texture);
buf->Material.setTexture(1, p.layer.normal_texture);
buf->Material.setTexture(2, p.layer.flags_texture);
p.layer.applyMaterialOptions(buf->Material);
mesh->addMeshBuffer(buf);
buf->append(&p.vertices[0], p.vertices.size(),
&p.indices[0], p.indices.size());
buf->drop();
colors->push_back(
ItemPartColor(p.layer.has_color, p.layer.color));
}
return mesh;
}

void WieldMeshSceneNode::setItem(const ItemStack &item, Client *client)
{
ITextureSource *tsrc = client->getTextureSource();
Expand All @@ -310,6 +346,8 @@ void WieldMeshSceneNode::setItem(const ItemStack &item, Client *client)
const ContentFeatures &f = ndef->get(def.name);
content_t id = ndef->getId(def.name);

scene::SMesh *mesh = nullptr;

if (m_enable_shaders) {
u32 shader_id = shdrsrc->getShader("wielded_shader", TILE_MATERIAL_BASIC, NDT_NORMAL);
m_material_type = shdrsrc->getShaderInfo(shader_id).material;
Expand All @@ -334,7 +372,7 @@ void WieldMeshSceneNode::setItem(const ItemStack &item, Client *client)
if (def.type == ITEM_NODE) {
if (f.mesh_ptr[0]) {
// e.g. mesh nodes and nodeboxes
scene::SMesh *mesh = cloneMesh(f.mesh_ptr[0]);
mesh = cloneMesh(f.mesh_ptr[0]);
postProcessNodeMesh(mesh, f, m_enable_shaders, true,
&m_material_type, &m_colors);
changeToMesh(mesh);
Expand Down Expand Up @@ -371,19 +409,14 @@ void WieldMeshSceneNode::setItem(const ItemStack &item, Client *client)
break;
}
case NDT_NORMAL:
case NDT_ALLFACES: {
case NDT_ALLFACES:
case NDT_LIQUID:
case NDT_FLOWINGLIQUID: {
setCube(f, def.wield_scale);
break;
}
default: {
MeshMakeData mesh_make_data(client, false);
MapNode mesh_make_node(id, 255, 0);
mesh_make_data.fillSingleNode(&mesh_make_node);
MapBlockMesh mapblock_mesh(&mesh_make_data, v3s16(0, 0, 0));
scene::SMesh *mesh = cloneMesh(mapblock_mesh.getMesh());
translateMesh(mesh, v3f(-BS, -BS, -BS));
postProcessNodeMesh(mesh, f, m_enable_shaders, true,
&m_material_type, &m_colors);
mesh = createSpecialNodeMesh(client, id, &m_colors);
changeToMesh(mesh);
mesh->drop();
m_meshnode->setScale(
Expand All @@ -395,6 +428,7 @@ void WieldMeshSceneNode::setItem(const ItemStack &item, Client *client)
u32 material_count = m_meshnode->getMaterialCount();
for (u32 i = 0; i < material_count; ++i) {
video::SMaterial &material = m_meshnode->getMaterial(i);
material.MaterialType = m_material_type;
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);
Expand Down Expand Up @@ -531,30 +565,8 @@ void getItemMesh(Client *client, const ItemStack &item, ItemMesh *result)
break;
}
default: {
MeshMakeData mesh_make_data(client, false);
MapNode mesh_make_node(id, 255, 0);
mesh_make_data.fillSingleNode(&mesh_make_node);
MapBlockMesh mapblock_mesh(&mesh_make_data, v3s16(0, 0, 0));
mesh = cloneMesh(mapblock_mesh.getMesh());
translateMesh(mesh, v3f(-BS, -BS, -BS));
mesh = createSpecialNodeMesh(client, id, &result->buffer_colors);
scaleMesh(mesh, v3f(0.12, 0.12, 0.12));

u32 mc = mesh->getMeshBufferCount();
for (u32 i = 0; i < mc; ++i) {
video::SMaterial &material1 =
mesh->getMeshBuffer(i)->getMaterial();
video::SMaterial &material2 =
mapblock_mesh.getMesh()->getMeshBuffer(i)->getMaterial();
material1.setTexture(0, material2.getTexture(0));
material1.setTexture(1, material2.getTexture(1));
material1.setTexture(2, material2.getTexture(2));
material1.setTexture(3, material2.getTexture(3));
material1.MaterialType = material2.MaterialType;
}
// add overlays (since getMesh() returns
// the base layer only)
postProcessNodeMesh(mesh, f, false, false, nullptr,
&result->buffer_colors, f.drawtype == NDT_NORMAL);
}
}
}
Expand Down

0 comments on commit ee6bb5a

Please sign in to comment.