|
@@ -33,24 +33,26 @@ with this program; if not, write to the Free Software Foundation, Inc., |
|
|
#include "util/directiontables.h" |
|
|
#include <IMeshManipulator.h> |
|
|
|
|
|
static void applyFacesShading(video::SColor& color, float factor) |
|
|
static void applyFacesShading(video::SColor &color, const float factor) |
|
|
{ |
|
|
color.setRed(core::clamp(core::round32(color.getRed()*factor), 0, 255)); |
|
|
color.setGreen(core::clamp(core::round32(color.getGreen()*factor), 0, 255)); |
|
|
color.setRed(core::clamp(core::round32(color.getRed() * factor), 0, 255)); |
|
|
color.setGreen(core::clamp(core::round32(color.getGreen() * factor), 0, 255)); |
|
|
} |
|
|
|
|
|
/* |
|
|
MeshMakeData |
|
|
*/ |
|
|
|
|
|
MeshMakeData::MeshMakeData(IGameDef *gamedef, bool use_shaders): |
|
|
MeshMakeData::MeshMakeData(IGameDef *gamedef, bool use_shaders, |
|
|
bool use_tangent_vertices): |
|
|
m_vmanip(), |
|
|
m_blockpos(-1337,-1337,-1337), |
|
|
m_crack_pos_relative(-1337, -1337, -1337), |
|
|
m_smooth_lighting(false), |
|
|
m_show_hud(false), |
|
|
m_gamedef(gamedef), |
|
|
m_use_shaders(use_shaders) |
|
|
m_use_shaders(use_shaders), |
|
|
m_use_tangent_vertices(use_tangent_vertices) |
|
|
{} |
|
|
|
|
|
void MeshMakeData::fill(MapBlock *block) |
|
@@ -1032,6 +1034,7 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset): |
|
|
m_daynight_diffs() |
|
|
{ |
|
|
m_enable_shaders = data->m_use_shaders; |
|
|
m_use_tangent_vertices = data->m_use_tangent_vertices; |
|
|
|
|
|
if (g_settings->getBool("enable_minimap")) { |
|
|
m_minimap_mapblock = new MinimapMapblock; |
|
@@ -1064,15 +1067,14 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset): |
|
|
Convert FastFaces to MeshCollector |
|
|
*/ |
|
|
|
|
|
MeshCollector collector; |
|
|
MeshCollector collector(m_use_tangent_vertices); |
|
|
|
|
|
{ |
|
|
// avg 0ms (100ms spikes when loading textures the first time) |
|
|
// (NOTE: probably outdated) |
|
|
//TimeTaker timer2("MeshCollector building"); |
|
|
|
|
|
for(u32 i=0; i<fastfaces_new.size(); i++) |
|
|
{ |
|
|
for (u32 i = 0; i < fastfaces_new.size(); i++) { |
|
|
FastFace &f = fastfaces_new[i]; |
|
|
|
|
|
const u16 indices[] = {0,1,2,2,3,0}; |
|
@@ -1150,35 +1152,43 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset): |
|
|
p.tile.texture = animation_frame.texture; |
|
|
} |
|
|
|
|
|
for(u32 j = 0; j < p.vertices.size(); j++) |
|
|
{ |
|
|
video::S3DVertex *vertex = &p.vertices[j]; |
|
|
u32 vertex_count = m_use_tangent_vertices ? |
|
|
p.tangent_vertices.size() : p.vertices.size(); |
|
|
for (u32 j = 0; j < vertex_count; j++) { |
|
|
v3f *Normal; |
|
|
video::SColor *vc; |
|
|
if (m_use_tangent_vertices) { |
|
|
vc = &p.tangent_vertices[j].Color; |
|
|
Normal = &p.tangent_vertices[j].Normal; |
|
|
} else { |
|
|
vc = &p.vertices[j].Color; |
|
|
Normal = &p.vertices[j].Normal; |
|
|
} |
|
|
// Note applyFacesShading second parameter is precalculated sqrt |
|
|
// value for speed improvement |
|
|
// Skip it for lightsources and top faces. |
|
|
video::SColor &vc = vertex->Color; |
|
|
if (!vc.getBlue()) { |
|
|
if (vertex->Normal.Y < -0.5) { |
|
|
applyFacesShading (vc, 0.447213); |
|
|
} else if (vertex->Normal.X > 0.5) { |
|
|
applyFacesShading (vc, 0.670820); |
|
|
} else if (vertex->Normal.X < -0.5) { |
|
|
applyFacesShading (vc, 0.670820); |
|
|
} else if (vertex->Normal.Z > 0.5) { |
|
|
applyFacesShading (vc, 0.836660); |
|
|
} else if (vertex->Normal.Z < -0.5) { |
|
|
applyFacesShading (vc, 0.836660); |
|
|
if (!vc->getBlue()) { |
|
|
if (Normal->Y < -0.5) { |
|
|
applyFacesShading(*vc, 0.447213); |
|
|
} else if (Normal->X > 0.5) { |
|
|
applyFacesShading(*vc, 0.670820); |
|
|
} else if (Normal->X < -0.5) { |
|
|
applyFacesShading(*vc, 0.670820); |
|
|
} else if (Normal->Z > 0.5) { |
|
|
applyFacesShading(*vc, 0.836660); |
|
|
} else if (Normal->Z < -0.5) { |
|
|
applyFacesShading(*vc, 0.836660); |
|
|
} |
|
|
} |
|
|
if(!m_enable_shaders) |
|
|
{ |
|
|
if (!m_enable_shaders) { |
|
|
// - Classic lighting (shaders handle this by themselves) |
|
|
// Set initial real color and store for later updates |
|
|
u8 day = vc.getRed(); |
|
|
u8 night = vc.getGreen(); |
|
|
finalColorBlend(vc, day, night, 1000); |
|
|
if(day != night) |
|
|
u8 day = vc->getRed(); |
|
|
u8 night = vc->getGreen(); |
|
|
finalColorBlend(*vc, day, night, 1000); |
|
|
if (day != night) { |
|
|
m_daynight_diffs[i][j] = std::make_pair(day, night); |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
@@ -1201,34 +1211,46 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset): |
|
|
p.tile.applyMaterialOptions(material); |
|
|
} |
|
|
|
|
|
// Create meshbuffer |
|
|
scene::SMeshBuffer *buf = new scene::SMeshBuffer(); |
|
|
// Set material |
|
|
buf->Material = material; |
|
|
// Add to mesh |
|
|
scene::SMesh *mesh = (scene::SMesh *)m_mesh; |
|
|
mesh->addMeshBuffer(buf); |
|
|
// Mesh grabbed it |
|
|
buf->drop(); |
|
|
buf->append(&p.vertices[0], p.vertices.size(), |
|
|
&p.indices[0], p.indices.size()); |
|
|
} |
|
|
m_camera_offset = camera_offset; |
|
|
scene::SMesh *mesh = (scene::SMesh *)m_mesh; |
|
|
|
|
|
// Create meshbuffer, add to mesh |
|
|
if (m_use_tangent_vertices) { |
|
|
scene::SMeshBufferTangents *buf = new scene::SMeshBufferTangents(); |
|
|
// Set material |
|
|
buf->Material = material; |
|
|
// Add to mesh |
|
|
mesh->addMeshBuffer(buf); |
|
|
// Mesh grabbed it |
|
|
buf->drop(); |
|
|
buf->append(&p.tangent_vertices[0], p.tangent_vertices.size(), |
|
|
&p.indices[0], p.indices.size()); |
|
|
} else { |
|
|
scene::SMeshBuffer *buf = new scene::SMeshBuffer(); |
|
|
// Set material |
|
|
buf->Material = material; |
|
|
// Add to mesh |
|
|
mesh->addMeshBuffer(buf); |
|
|
// Mesh grabbed it |
|
|
buf->drop(); |
|
|
buf->append(&p.vertices[0], p.vertices.size(), |
|
|
&p.indices[0], p.indices.size()); |
|
|
} |
|
|
} |
|
|
|
|
|
/* |
|
|
Do some stuff to the mesh |
|
|
*/ |
|
|
m_camera_offset = camera_offset; |
|
|
translateMesh(m_mesh, |
|
|
intToFloat(data->m_blockpos * MAP_BLOCKSIZE - camera_offset, BS)); |
|
|
|
|
|
translateMesh(m_mesh, intToFloat(data->m_blockpos * MAP_BLOCKSIZE - camera_offset, BS)); |
|
|
|
|
|
if (m_enable_shaders) { |
|
|
scene::IMeshManipulator* meshmanip = m_gamedef->getSceneManager()->getMeshManipulator(); |
|
|
scene::IMesh* tangentMesh = meshmanip->createMeshWithTangents(m_mesh); |
|
|
m_mesh->drop(); |
|
|
m_mesh = tangentMesh; |
|
|
if (m_use_tangent_vertices) { |
|
|
scene::IMeshManipulator* meshmanip = |
|
|
m_gamedef->getSceneManager()->getMeshManipulator(); |
|
|
meshmanip->recalculateTangents(m_mesh, true, false, false); |
|
|
} |
|
|
|
|
|
if(m_mesh) |
|
|
if (m_mesh) |
|
|
{ |
|
|
#if 0 |
|
|
// Usually 1-700 faces and 1-7 materials |
|
@@ -1400,17 +1422,30 @@ void MeshCollector::append(const TileSpec &tile, |
|
|
p = &prebuffers[prebuffers.size() - 1]; |
|
|
} |
|
|
|
|
|
u32 vertex_count = p->vertices.size(); |
|
|
for (u32 i = 0; i < numIndices; i++) { |
|
|
u32 vertex_count; |
|
|
if (m_use_tangent_vertices) { |
|
|
vertex_count = p->tangent_vertices.size(); |
|
|
p->tangent_vertices.reserve(vertex_count + numVertices); |
|
|
for (u32 i = 0; i < numVertices; i++) { |
|
|
video::S3DVertexTangents vert(vertices[i].Pos, vertices[i].Normal, |
|
|
vertices[i].Color, vertices[i].TCoords); |
|
|
p->tangent_vertices.push_back(vert); |
|
|
} |
|
|
} else { |
|
|
vertex_count = p->vertices.size(); |
|
|
p->vertices.reserve(vertex_count + numVertices); |
|
|
for (u32 i = 0; i < numVertices; i++) { |
|
|
video::S3DVertex vert(vertices[i].Pos, vertices[i].Normal, |
|
|
vertices[i].Color, vertices[i].TCoords); |
|
|
p->vertices.push_back(vert); |
|
|
} |
|
|
} |
|
|
|
|
|
p->indices.reserve(p->indices.size() + numIndices); |
|
|
for (u32 i = 0; i < numIndices; i++) { |
|
|
u32 j = indices[i] + vertex_count; |
|
|
p->indices.push_back(j); |
|
|
} |
|
|
|
|
|
for (u32 i = 0; i < numVertices; i++) { |
|
|
video::S3DVertex vert(vertices[i].Pos, vertices[i].Normal, |
|
|
vertices[i].Color, vertices[i].TCoords); |
|
|
p->vertices.push_back(vert); |
|
|
} |
|
|
} |
|
|
|
|
|
/* |
|
@@ -1446,15 +1481,28 @@ void MeshCollector::append(const TileSpec &tile, |
|
|
p = &prebuffers[prebuffers.size() - 1]; |
|
|
} |
|
|
|
|
|
u32 vertex_count = p->vertices.size(); |
|
|
u32 vertex_count; |
|
|
if (m_use_tangent_vertices) { |
|
|
vertex_count = p->tangent_vertices.size(); |
|
|
p->tangent_vertices.reserve(vertex_count + numVertices); |
|
|
for (u32 i = 0; i < numVertices; i++) { |
|
|
video::S3DVertexTangents vert(vertices[i].Pos + pos, |
|
|
vertices[i].Normal, c, vertices[i].TCoords); |
|
|
p->tangent_vertices.push_back(vert); |
|
|
} |
|
|
} else { |
|
|
vertex_count = p->vertices.size(); |
|
|
p->vertices.reserve(vertex_count + numVertices); |
|
|
for (u32 i = 0; i < numVertices; i++) { |
|
|
video::S3DVertex vert(vertices[i].Pos + pos, |
|
|
vertices[i].Normal, c, vertices[i].TCoords); |
|
|
p->vertices.push_back(vert); |
|
|
} |
|
|
} |
|
|
|
|
|
p->indices.reserve(p->indices.size() + numIndices); |
|
|
for (u32 i = 0; i < numIndices; i++) { |
|
|
u32 j = indices[i] + vertex_count; |
|
|
p->indices.push_back(j); |
|
|
} |
|
|
|
|
|
for (u32 i = 0; i < numVertices; i++) { |
|
|
video::S3DVertex vert(vertices[i].Pos + pos, vertices[i].Normal, |
|
|
c, vertices[i].TCoords); |
|
|
p->vertices.push_back(vert); |
|
|
} |
|
|
} |