Use S3DVertexTangents for mapblocks & wield meshes for separate saving light and hardware colors

This commit is contained in:
Andrey2470T 2024-06-06 01:05:51 +03:00
parent 385bb3c801
commit d3b63ba06f
10 changed files with 271 additions and 192 deletions

@ -38,6 +38,7 @@ varying vec3 vPosition;
// precision must be considered).
varying vec3 worldPosition;
varying lowp vec4 varColor;
varying lowp vec3 hwColor;
#ifdef GL_ES
varying mediump vec2 varTexCoord;
#else
@ -375,7 +376,7 @@ void main(void)
#endif
color = base.rgb;
vec4 col = vec4(color.rgb * varColor.rgb, 1.0);
vec4 col = vec4(color * hwColor * varColor.rgb, 1.0);
#ifdef ENABLE_DYNAMIC_SHADOWS
if (f_shadow_strength > 0.0) {

@ -17,6 +17,7 @@ varying vec3 vPosition;
// precision must be considered).
varying vec3 worldPosition;
varying lowp vec4 varColor;
varying lowp vec3 hwColor;
// The centroid keyword ensures that after interpolation the texture coordinates
// lie within the same bounds when MSAA is en- and disabled.
// This fixes the stripes problem with nearest-neighbor textures and MSAA.
@ -226,6 +227,8 @@ void main(void)
varColor = clamp(color, 0.0, 1.0);
hwColor = inVertexTangent.xyz;
#ifdef ENABLE_DYNAMIC_SHADOWS
if (f_shadow_strength > 0.0) {
#if MATERIAL_TYPE == TILE_MATERIAL_WAVING_PLANTS && ENABLE_WAVING_PLANTS

@ -139,7 +139,7 @@ void Camera::step(f32 dtime)
if (m_wield_change_timer >= 0 && was_under_zero) {
m_wieldnode->setItem(m_wield_item_next, m_client);
m_wieldnode->setNodeLightColor(m_player_light_color);
m_wieldnode->setColor(m_player_light_color);
}
if (m_view_bobbing_state != 0)
@ -552,7 +552,7 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 tool_reload_ratio)
m_wieldnode->setRotation(wield_rotation);
m_player_light_color = player->light_color;
m_wieldnode->setNodeLightColor(m_player_light_color);
m_wieldnode->setColor(m_player_light_color);
// Set render distance
updateViewingRange();

@ -922,11 +922,11 @@ void GenericCAO::setNodeLight(const video::SColor &light_color)
{
if (m_prop.visual == "wielditem" || m_prop.visual == "item") {
if (m_wield_meshnode)
m_wield_meshnode->setNodeLightColor(light_color);
m_wield_meshnode->setColor(light_color);
return;
}
if (m_enable_shaders) {
/*if (m_enable_shaders) {
if (m_prop.visual == "upright_sprite") {
if (!m_meshnode)
return;
@ -942,7 +942,7 @@ void GenericCAO::setNodeLight(const video::SColor &light_color)
material.EmissiveColor = light_color;
}
}
} else {
} else {*/
if (m_meshnode) {
setMeshColor(m_meshnode->getMesh(), light_color);
} else if (m_animated_meshnode) {
@ -950,7 +950,7 @@ void GenericCAO::setNodeLight(const video::SColor &light_color)
} else if (m_spritenode) {
m_spritenode->setColor(light_color);
}
}
//}
}
u16 GenericCAO::getLightPosition(v3s16 *pos)

@ -1137,9 +1137,9 @@ void drawItemStack(
if (p.needColorize(c)) {
buf->setDirty(scene::EBT_VERTEX);
if (imesh->needs_shading)
colorizeMeshBuffer(buf, &c);
colorizeMeshBufferTangents(buf, &c);
else
setMeshBufferColor(buf, c);
setMeshBufferTangentsColor(buf, c);
}
video::SMaterial &material = buf->getMaterial();

@ -630,7 +630,8 @@ MapBlockMesh::MapBlockMesh(Client *client, MeshMakeData *data, v3s16 camera_offs
{
PreMeshBuffer &p = collector.prebuffers[layer][i];
applyTileColor(p);
if (!m_enable_shaders)
applyTileColor(p);
// Generate animation data
// - Cracks
@ -717,10 +718,25 @@ MapBlockMesh::MapBlockMesh(Client *client, MeshMakeData *data, v3s16 camera_offs
p.layer.applyMaterialOptions(material);
}
scene::SMeshBuffer *buf = new scene::SMeshBuffer();
scene::SMeshBufferTangents *buf = new scene::SMeshBufferTangents();
buf->Material = material;
std::vector<video::S3DVertexTangents> tangents;
// Copy S3DVertex to S3DVertexTangents
for (auto &v : p.vertices) {
video::SColor &c = p.layer.color;
v3f hw_color{0.0f};
if (m_enable_shaders) {
hw_color.X = c.getRed() / 255.0f;
hw_color.Y = c.getGreen() / 255.0f;
hw_color.Z = c.getBlue() / 255.0f;
}
tangents.emplace_back(v.Pos, v.Normal, v.Color, v.TCoords, hw_color);
}
if (p.layer.isTransparent()) {
buf->append(&p.vertices[0], p.vertices.size(), nullptr, 0);
buf->append(&tangents[0], tangents.size(), nullptr, 0);
MeshTriangle t;
t.buffer = buf;
@ -733,7 +749,7 @@ MapBlockMesh::MapBlockMesh(Client *client, MeshMakeData *data, v3s16 camera_offs
m_transparent_triangles.push_back(t);
}
} else {
buf->append(&p.vertices[0], p.vertices.size(),
buf->append(&tangents[0], tangents.size(),
&p.indices[0], p.indices.size());
}
mesh->addMeshBuffer(buf);
@ -829,20 +845,19 @@ bool MapBlockMesh::animate(bool faraway, float time, int crack,
if (!m_enable_shaders && (daynight_ratio != m_last_daynight_ratio)) {
video::SColorf day_color;
get_sunlight_color(&day_color, daynight_ratio);
for (auto &daynight_diff : m_daynight_diffs) {
auto *mesh = m_mesh[daynight_diff.first.first];
mesh->setDirty(scene::EBT_VERTEX); // force reload to VBO
scene::IMeshBuffer *buf = mesh->
getMeshBuffer(daynight_diff.first.second);
video::S3DVertex *vertices = (video::S3DVertex *)buf->getVertices();
video::S3DVertexTangents *vertices = (video::S3DVertexTangents*)buf->getVertices();
for (const auto &j : daynight_diff.second)
final_color_blend(&(vertices[j.first].Color), j.second,
day_color);
}
m_last_daynight_ratio = daynight_ratio;
}
return true;
}
@ -861,7 +876,7 @@ void MapBlockMesh::updateTransparentBuffers(v3f camera_pos, v3s16 block_pos)
// arrange index sequences into partial buffers
m_transparent_buffers.clear();
scene::SMeshBuffer *current_buffer = nullptr;
scene::SMeshBufferTangents *current_buffer = nullptr;
std::vector<u16> current_strain;
for (auto i : triangle_refs) {
const auto &t = m_transparent_triangles[i];
@ -885,7 +900,7 @@ void MapBlockMesh::consolidateTransparentBuffers()
{
m_transparent_buffers.clear();
scene::SMeshBuffer *current_buffer = nullptr;
scene::SMeshBufferTangents *current_buffer = nullptr;
std::vector<u16> current_strain;
// use the fact that m_transparent_triangles is already arranged by buffer

@ -74,7 +74,7 @@ struct MeshMakeData
class MeshTriangle
{
public:
scene::SMeshBuffer *buffer;
scene::SMeshBufferTangents *buffer;
u16 p1, p2, p3;
v3f centroid;
float areaSQ;
@ -152,7 +152,7 @@ class MapBlockBspTree
class PartialMeshBuffer
{
public:
PartialMeshBuffer(scene::SMeshBuffer *buffer, std::vector<u16> &&vertex_indexes) :
PartialMeshBuffer(scene::SMeshBufferTangents *buffer, std::vector<u16> &&vertex_indexes) :
m_buffer(buffer), m_vertex_indexes(std::move(vertex_indexes))
{}
@ -162,7 +162,7 @@ class PartialMeshBuffer
void beforeDraw() const;
void afterDraw() const;
private:
scene::SMeshBuffer *m_buffer;
scene::SMeshBufferTangents *m_buffer;
mutable std::vector<u16> m_vertex_indexes;
};

@ -53,50 +53,55 @@ void applyFacesShading(video::SColor &color, const v3f &normal)
applyShadeFactor(color, 0.670820f * x2 + 1.000000f * y2 + 0.836660f * z2);
}
template<typename T>
std::array<T, 24> getCubeVertices(video::SColor c)
{
return std::array<T, 24>{
// Up
T(-0.5,+0.5,-0.5, 0,1,0, c, 0,1),
T(-0.5,+0.5,+0.5, 0,1,0, c, 0,0),
T(+0.5,+0.5,+0.5, 0,1,0, c, 1,0),
T(+0.5,+0.5,-0.5, 0,1,0, c, 1,1),
// Down
T(-0.5,-0.5,-0.5, 0,-1,0, c, 0,0),
T(+0.5,-0.5,-0.5, 0,-1,0, c, 1,0),
T(+0.5,-0.5,+0.5, 0,-1,0, c, 1,1),
T(-0.5,-0.5,+0.5, 0,-1,0, c, 0,1),
// Right
T(+0.5,-0.5,-0.5, 1,0,0, c, 0,1),
T(+0.5,+0.5,-0.5, 1,0,0, c, 0,0),
T(+0.5,+0.5,+0.5, 1,0,0, c, 1,0),
T(+0.5,-0.5,+0.5, 1,0,0, c, 1,1),
// Left
T(-0.5,-0.5,-0.5, -1,0,0, c, 1,1),
T(-0.5,-0.5,+0.5, -1,0,0, c, 0,1),
T(-0.5,+0.5,+0.5, -1,0,0, c, 0,0),
T(-0.5,+0.5,-0.5, -1,0,0, c, 1,0),
// Back
T(-0.5,-0.5,+0.5, 0,0,1, c, 1,1),
T(+0.5,-0.5,+0.5, 0,0,1, c, 0,1),
T(+0.5,+0.5,+0.5, 0,0,1, c, 0,0),
T(-0.5,+0.5,+0.5, 0,0,1, c, 1,0),
// Front
T(-0.5,-0.5,-0.5, 0,0,-1, c, 0,1),
T(-0.5,+0.5,-0.5, 0,0,-1, c, 0,0),
T(+0.5,+0.5,-0.5, 0,0,-1, c, 1,0),
T(+0.5,-0.5,-0.5, 0,0,-1, c, 1,1),
};
}
scene::IAnimatedMesh* createCubeMesh(v3f scale)
{
video::SColor c(255,255,255,255);
video::S3DVertex vertices[24] =
{
// Up
video::S3DVertex(-0.5,+0.5,-0.5, 0,1,0, c, 0,1),
video::S3DVertex(-0.5,+0.5,+0.5, 0,1,0, c, 0,0),
video::S3DVertex(+0.5,+0.5,+0.5, 0,1,0, c, 1,0),
video::S3DVertex(+0.5,+0.5,-0.5, 0,1,0, c, 1,1),
// Down
video::S3DVertex(-0.5,-0.5,-0.5, 0,-1,0, c, 0,0),
video::S3DVertex(+0.5,-0.5,-0.5, 0,-1,0, c, 1,0),
video::S3DVertex(+0.5,-0.5,+0.5, 0,-1,0, c, 1,1),
video::S3DVertex(-0.5,-0.5,+0.5, 0,-1,0, c, 0,1),
// Right
video::S3DVertex(+0.5,-0.5,-0.5, 1,0,0, c, 0,1),
video::S3DVertex(+0.5,+0.5,-0.5, 1,0,0, c, 0,0),
video::S3DVertex(+0.5,+0.5,+0.5, 1,0,0, c, 1,0),
video::S3DVertex(+0.5,-0.5,+0.5, 1,0,0, c, 1,1),
// Left
video::S3DVertex(-0.5,-0.5,-0.5, -1,0,0, c, 1,1),
video::S3DVertex(-0.5,-0.5,+0.5, -1,0,0, c, 0,1),
video::S3DVertex(-0.5,+0.5,+0.5, -1,0,0, c, 0,0),
video::S3DVertex(-0.5,+0.5,-0.5, -1,0,0, c, 1,0),
// Back
video::S3DVertex(-0.5,-0.5,+0.5, 0,0,1, c, 1,1),
video::S3DVertex(+0.5,-0.5,+0.5, 0,0,1, c, 0,1),
video::S3DVertex(+0.5,+0.5,+0.5, 0,0,1, c, 0,0),
video::S3DVertex(-0.5,+0.5,+0.5, 0,0,1, c, 1,0),
// Front
video::S3DVertex(-0.5,-0.5,-0.5, 0,0,-1, c, 0,1),
video::S3DVertex(-0.5,+0.5,-0.5, 0,0,-1, c, 0,0),
video::S3DVertex(+0.5,+0.5,-0.5, 0,0,-1, c, 1,0),
video::S3DVertex(+0.5,-0.5,-0.5, 0,0,-1, c, 1,1),
};
std::array<video::S3DVertex, 24> vertices = getCubeVertices<video::S3DVertex>(c);
u16 indices[6] = {0,1,2,2,3,0};
scene::SMesh *mesh = new scene::SMesh();
for (u32 i=0; i<6; ++i)
{
scene::IMeshBuffer *buf = new scene::SMeshBuffer();
buf->append(vertices + 4 * i, 4, indices, 6);
buf->append(&vertices[0] + 4 * i, 4, indices, 6);
// Set default material
buf->getMaterial().Lighting = false;
buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
@ -115,9 +120,39 @@ scene::IAnimatedMesh* createCubeMesh(v3f scale)
return anim_mesh;
}
scene::IAnimatedMesh* createCubeMeshTangents(v3f scale)
{
video::SColor c(255,255,255,255);
std::array<video::S3DVertexTangents, 24> vertices = getCubeVertices<video::S3DVertexTangents>(c);
u16 indices[6] = {0,1,2,2,3,0};
scene::SMesh *mesh = new scene::SMesh();
for (u32 i=0; i<6; ++i)
{
scene::IMeshBuffer *buf = new scene::SMeshBufferTangents();
buf->append(&vertices[0] + 4 * i, 4, indices, 6);
// Set default material
buf->getMaterial().Lighting = false;
buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
buf->getMaterial().forEachTexture([] (auto &tex) {
tex.MinFilter = video::ETMINF_NEAREST_MIPMAP_NEAREST;
tex.MagFilter = video::ETMAGF_NEAREST;
});
// Add mesh buffer to mesh
mesh->addMeshBuffer(buf);
buf->drop();
}
scene::SAnimatedMesh *anim_mesh = new scene::SAnimatedMesh(mesh);
mesh->drop();
scaleMeshTangents(anim_mesh, scale); // also recalculates bounding box
return anim_mesh;
}
void scaleMesh(scene::IMesh *mesh, v3f scale)
{
if (mesh == NULL)
if (!mesh)
return;
aabb3f bbox;
@ -126,11 +161,9 @@ void scaleMesh(scene::IMesh *mesh, v3f scale)
u32 mc = mesh->getMeshBufferCount();
for (u32 j = 0; j < mc; j++) {
scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
const u32 stride = getVertexPitchFromType(buf->getVertexType());
u32 vertex_count = buf->getVertexCount();
u8 *vertices = (u8 *)buf->getVertices();
for (u32 i = 0; i < vertex_count; i++)
((video::S3DVertex *)(vertices + i * stride))->Pos *= scale;
video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices();
for (u32 i = 0; i < buf->getVertexCount(); i++)
vertices[i].Pos *= scale;
buf->recalculateBoundingBox();
@ -143,9 +176,9 @@ void scaleMesh(scene::IMesh *mesh, v3f scale)
mesh->setBoundingBox(bbox);
}
void translateMesh(scene::IMesh *mesh, v3f vec)
void scaleMeshTangents(scene::IMesh *mesh, v3f scale)
{
if (mesh == NULL)
if (!mesh)
return;
aabb3f bbox;
@ -154,11 +187,35 @@ void translateMesh(scene::IMesh *mesh, v3f vec)
u32 mc = mesh->getMeshBufferCount();
for (u32 j = 0; j < mc; j++) {
scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
const u32 stride = getVertexPitchFromType(buf->getVertexType());
u32 vertex_count = buf->getVertexCount();
u8 *vertices = (u8 *)buf->getVertices();
for (u32 i = 0; i < vertex_count; i++)
((video::S3DVertex *)(vertices + i * stride))->Pos += vec;
video::S3DVertexTangents *vertices = (video::S3DVertexTangents*)buf->getVertices();
for (u32 i = 0; i < buf->getVertexCount(); i++)
vertices[i].Pos *= scale;
buf->recalculateBoundingBox();
// calculate total bounding box
if (j == 0)
bbox = buf->getBoundingBox();
else
bbox.addInternalBox(buf->getBoundingBox());
}
mesh->setBoundingBox(bbox);
}
void translateMeshTangents(scene::IMesh *mesh, v3f vec)
{
if (!mesh)
return;
aabb3f bbox;
bbox.reset(0, 0, 0);
u32 mc = mesh->getMeshBufferCount();
for (u32 j = 0; j < mc; j++) {
scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
video::S3DVertex *vertices = (video::S3DVertexTangents*)buf->getVertices();
for (u32 i = 0; i < buf->getVertexCount(); i++)
vertices[i].Pos += vec;
buf->recalculateBoundingBox();
@ -173,11 +230,20 @@ void translateMesh(scene::IMesh *mesh, v3f vec)
void setMeshBufferColor(scene::IMeshBuffer *buf, const video::SColor &color)
{
const u32 stride = getVertexPitchFromType(buf->getVertexType());
u32 vertex_count = buf->getVertexCount();
u8 *vertices = (u8 *) buf->getVertices();
for (u32 i = 0; i < vertex_count; i++)
((video::S3DVertex *) (vertices + i * stride))->Color = color;
video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices();
for (u32 i = 0; i < buf->getVertexCount(); i++)
vertices[i].Color = color;
}
void setMeshBufferTangentsColor(scene::IMeshBuffer *buf,
const video::SColor &color, const video::SColor &hw_color)
{
video::S3DVertexTangents *vertices = (video::S3DVertexTangents*)buf->getVertices();
for (u32 i = 0; i < buf->getVertexCount(); i++) {
vertices[i].Color = color;
vertices[i].Tangent = v3f(hw_color.getRed(), hw_color.getGreen(), hw_color.getBlue());
}
}
void setAnimatedMeshColor(scene::IAnimatedMeshSceneNode *node, const video::SColor &color)
@ -189,44 +255,47 @@ void setAnimatedMeshColor(scene::IAnimatedMeshSceneNode *node, const video::SCol
void setMeshColor(scene::IMesh *mesh, const video::SColor &color)
{
if (mesh == NULL)
if (!mesh)
return;
u32 mc = mesh->getMeshBufferCount();
for (u32 j = 0; j < mc; j++)
for (u32 j = 0; j < mesh->getMeshBufferCount(); j++)
setMeshBufferColor(mesh->getMeshBuffer(j), color);
}
/*void setMeshTangentsColor(scene::IMesh *mesh, const video::SColor &color,
const video::SColor &hw_color)
{
if (!mesh)
return;
for (u32 j = 0; j < mesh->getMeshBufferCount(); j++)
setMeshBufferTangentsColor(mesh->getMeshBuffer(j), color, hw_color);
}*/
void setMeshBufferTextureCoords(scene::IMeshBuffer *buf, const v2f *uv, u32 count)
{
const u32 stride = getVertexPitchFromType(buf->getVertexType());
assert(buf->getVertexCount() >= count);
u8 *vertices = (u8 *) buf->getVertices();
video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices();
for (u32 i = 0; i < count; i++)
((video::S3DVertex*) (vertices + i * stride))->TCoords = uv[i];
vertices[i].TCoords = uv[i];
}
template <typename F>
template <typename T, typename F>
static void applyToMesh(scene::IMesh *mesh, const F &fn)
{
u16 mc = mesh->getMeshBufferCount();
for (u16 j = 0; j < mc; j++) {
for (u16 j = 0; j < mesh->getMeshBufferCount(); j++) {
scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
const u32 stride = getVertexPitchFromType(buf->getVertexType());
u32 vertex_count = buf->getVertexCount();
char *vertices = reinterpret_cast<char *>(buf->getVertices());
for (u32 i = 0; i < vertex_count; i++)
fn(reinterpret_cast<video::S3DVertex *>(vertices + i * stride));
T *vertices = (T*)buf->getVertices();
for (u32 i = 0; i < buf->getVertexCount(); i++)
fn(&vertices[i]);
}
}
void colorizeMeshBuffer(scene::IMeshBuffer *buf, const video::SColor *buffercolor)
void colorizeMeshBufferTangents(scene::IMeshBuffer *buf, const video::SColor *buffercolor)
{
const u32 stride = getVertexPitchFromType(buf->getVertexType());
u32 vertex_count = buf->getVertexCount();
u8 *vertices = (u8 *) buf->getVertices();
for (u32 i = 0; i < vertex_count; i++) {
video::S3DVertex *vertex = (video::S3DVertex *) (vertices + i * stride);
video::S3DVertexTangents *vertices = (video::S3DVertexTangents*)buf->getVertices();
for (u32 i = 0; i < buf->getVertexCount(); i++) {
video::S3DVertexTangents *vertex = &vertices[i];
video::SColor *vc = &(vertex->Color);
// Reset color
*vc = *buffercolor;
@ -235,27 +304,6 @@ void colorizeMeshBuffer(scene::IMeshBuffer *buf, const video::SColor *buffercolo
}
}
void setMeshColorByNormalXYZ(scene::IMesh *mesh,
const video::SColor &colorX,
const video::SColor &colorY,
const video::SColor &colorZ)
{
if (!mesh)
return;
auto colorizator = [=] (video::S3DVertex *vertex) {
f32 x = fabs(vertex->Normal.X);
f32 y = fabs(vertex->Normal.Y);
f32 z = fabs(vertex->Normal.Z);
if (x >= y && x >= z)
vertex->Color = colorX;
else if (y >= z)
vertex->Color = colorY;
else
vertex->Color = colorZ;
};
applyToMesh(mesh, colorizator);
}
void setMeshColorByNormal(scene::IMesh *mesh, const v3f &normal,
const video::SColor &color)
{
@ -265,37 +313,47 @@ void setMeshColorByNormal(scene::IMesh *mesh, const v3f &normal,
if (vertex->Normal == normal)
vertex->Color = color;
};
applyToMesh(mesh, colorizator);
applyToMesh<video::S3DVertex>(mesh, colorizator);
}
template <float v3f::*U, float v3f::*V>
template <typename T, float v3f::*U, float v3f::*V>
static void rotateMesh(scene::IMesh *mesh, float degrees)
{
degrees *= M_PI / 180.0f;
float c = std::cos(degrees);
float s = std::sin(degrees);
auto rotator = [c, s] (video::S3DVertex *vertex) {
auto rotator = [c, s] (T *vertex) {
float u = vertex->Pos.*U;
float v = vertex->Pos.*V;
vertex->Pos.*U = c * u - s * v;
vertex->Pos.*V = s * u + c * v;
};
applyToMesh(mesh, rotator);
applyToMesh<T>(mesh, rotator);
}
void rotateMeshXYby(scene::IMesh *mesh, f64 degrees)
{
rotateMesh<&v3f::X, &v3f::Y>(mesh, degrees);
rotateMesh<video::S3DVertex, &v3f::X, &v3f::Y>(mesh, degrees);
}
void rotateMeshXZby(scene::IMesh *mesh, f64 degrees)
{
rotateMesh<&v3f::X, &v3f::Z>(mesh, degrees);
rotateMesh<video::S3DVertex, &v3f::X, &v3f::Z>(mesh, degrees);
}
void rotateMeshTangentsXZby(scene::IMesh *mesh, f64 degrees)
{
rotateMesh<video::S3DVertexTangents, &v3f::X, &v3f::Z>(mesh, degrees);
}
void rotateMeshYZby(scene::IMesh *mesh, f64 degrees)
{
rotateMesh<&v3f::Y, &v3f::Z>(mesh, degrees);
rotateMesh<video::S3DVertex, &v3f::Y, &v3f::Z>(mesh, degrees);
}
void rotateMeshTangentsYZby(scene::IMesh *mesh, f64 degrees)
{
rotateMesh<video::S3DVertexTangents, &v3f::Y, &v3f::Z>(mesh, degrees);
}
void rotateMeshBy6dFacedir(scene::IMesh *mesh, int facedir)
@ -357,7 +415,7 @@ scene::IMeshBuffer* cloneMeshBuffer(scene::IMeshBuffer *mesh_buffer)
{
switch (mesh_buffer->getVertexType()) {
case video::EVT_STANDARD: {
video::S3DVertex *v = (video::S3DVertex *) mesh_buffer->getVertices();
video::S3DVertex *v = (video::S3DVertex*)mesh_buffer->getVertices();
u16 *indices = mesh_buffer->getIndices();
scene::SMeshBuffer *cloned_buffer = new scene::SMeshBuffer();
cloned_buffer->append(v, mesh_buffer->getVertexCount(), indices,
@ -366,7 +424,7 @@ scene::IMeshBuffer* cloneMeshBuffer(scene::IMeshBuffer *mesh_buffer)
}
case video::EVT_2TCOORDS: {
video::S3DVertex2TCoords *v =
(video::S3DVertex2TCoords *) mesh_buffer->getVertices();
(video::S3DVertex2TCoords*)mesh_buffer->getVertices();
u16 *indices = mesh_buffer->getIndices();
scene::SMeshBufferLightMap *cloned_buffer =
new scene::SMeshBufferLightMap();
@ -376,7 +434,7 @@ scene::IMeshBuffer* cloneMeshBuffer(scene::IMeshBuffer *mesh_buffer)
}
case video::EVT_TANGENTS: {
video::S3DVertexTangents *v =
(video::S3DVertexTangents *) mesh_buffer->getVertices();
(video::S3DVertexTangents*)mesh_buffer->getVertices();
u16 *indices = mesh_buffer->getIndices();
scene::SMeshBufferTangents *cloned_buffer =
new scene::SMeshBufferTangents();

@ -38,27 +38,33 @@ void applyFacesShading(video::SColor &color, const v3f &normal);
*/
scene::IAnimatedMesh* createCubeMesh(v3f scale);
scene::IAnimatedMesh* createCubeMeshTangents(v3f scale);
/*
Multiplies each vertex coordinate by the specified scaling factors
(componentwise vector multiplication).
*/
void scaleMesh(scene::IMesh *mesh, v3f scale);
void scaleMeshTangents(scene::IMesh *mesh, v3f scale);
/*
Translate each vertex coordinate by the specified vector.
*/
void translateMesh(scene::IMesh *mesh, v3f vec);
void translateMeshTangents(scene::IMesh *mesh, v3f vec);
/*!
* Sets a constant color for all vertices in the mesh buffer.
*/
void setMeshBufferColor(scene::IMeshBuffer *buf, const video::SColor &color);
void setMeshBufferTangentsColor(scene::IMeshBuffer *buf,
const video::SColor &color, const video::SColor &hw_color=video::SColor(0xFFFFFFFF));
/*
Set a constant color for all vertices in the mesh
*/
void setMeshColor(scene::IMesh *mesh, const video::SColor &color);
void setMeshTangentsColor(scene::IMesh *mesh, const video::SColor &color,
const video::SColor &hw_color=video::SColor(0xFFFFFFFF));
/*
Sets texture coords for vertices in the mesh buffer.
@ -75,18 +81,7 @@ void setAnimatedMeshColor(scene::IAnimatedMeshSceneNode *node, const video::SCol
* Overwrites the color of a mesh buffer.
* The color is darkened based on the normal vector of the vertices.
*/
void colorizeMeshBuffer(scene::IMeshBuffer *buf, const video::SColor *buffercolor);
/*
Set the color of all vertices in the mesh.
For each vertex, determine the largest absolute entry in
the normal vector, and choose one of colorX, colorY or
colorZ accordingly.
*/
void setMeshColorByNormalXYZ(scene::IMesh *mesh,
const video::SColor &colorX,
const video::SColor &colorY,
const video::SColor &colorZ);
void colorizeMeshBufferTangents(scene::IMeshBuffer *buf, const video::SColor *buffercolor);
void setMeshColorByNormal(scene::IMesh *mesh, const v3f &normal,
const video::SColor &color);
@ -102,7 +97,9 @@ void rotateMeshBy6dFacedir(scene::IMesh *mesh, int facedir);
*/
void rotateMeshXYby (scene::IMesh *mesh, f64 degrees);
void rotateMeshXZby (scene::IMesh *mesh, f64 degrees);
void rotateMeshTangentsXZby(scene::IMesh *mesh, f64 degrees);
void rotateMeshYZby (scene::IMesh *mesh, f64 degrees);
void rotateMeshTangentsYZby(scene::IMesh *mesh, f64 degrees);
/*
* Clone the mesh buffer.
@ -139,5 +136,5 @@ bool checkMeshNormals(scene::IMesh *mesh);
Set the MinFilter, MagFilter and AnisotropicFilter properties of a texture
layer according to the three relevant boolean values found in the Minetest
settings.
*/
*/
void setMaterialFilters(video::SMaterialLayer &tex, bool bilinear, bool trilinear, bool anisotropic);

@ -45,23 +45,22 @@ static scene::IMesh *createExtrusionMesh(int resolution_x, int resolution_y)
{
const f32 r = 0.5;
scene::IMeshBuffer *buf = new scene::SMeshBuffer();
scene::SMeshBufferTangents *buf = new scene::SMeshBufferTangents();
video::SColor c(255,255,255,255);
v3f scale(1.0, 1.0, 0.1);
// Front and back
{
video::S3DVertex vertices[8] = {
video::S3DVertexTangents vertices[8] = {
// z-
video::S3DVertex(-r,+r,-r, 0,0,-1, c, 0,0),
video::S3DVertex(+r,+r,-r, 0,0,-1, c, 1,0),
video::S3DVertex(+r,-r,-r, 0,0,-1, c, 1,1),
video::S3DVertex(-r,-r,-r, 0,0,-1, c, 0,1),
video::S3DVertexTangents(-r,+r,-r, 0,0,-1, c, 0,0),
video::S3DVertexTangents(+r,+r,-r, 0,0,-1, c, 1,0),
video::S3DVertexTangents(+r,-r,-r, 0,0,-1, c, 1,1),
video::S3DVertexTangents(-r,-r,-r, 0,0,-1, c, 0,1),
// z+
video::S3DVertex(-r,+r,+r, 0,0,+1, c, 0,0),
video::S3DVertex(-r,-r,+r, 0,0,+1, c, 0,1),
video::S3DVertex(+r,-r,+r, 0,0,+1, c, 1,1),
video::S3DVertex(+r,+r,+r, 0,0,+1, c, 1,0),
video::S3DVertexTangents(-r,+r,+r, 0,0,+1, c, 0,0),
video::S3DVertexTangents(-r,-r,+r, 0,0,+1, c, 0,1),
video::S3DVertexTangents(+r,-r,+r, 0,0,+1, c, 1,1),
video::S3DVertexTangents(+r,+r,+r, 0,0,+1, c, 1,0),
};
u16 indices[12] = {0,1,2,2,3,0,4,5,6,6,7,4};
buf->append(vertices, 8, indices, 12);
@ -76,17 +75,17 @@ static scene::IMesh *createExtrusionMesh(int resolution_x, int resolution_y)
f32 x1 = pixelpos_x + pixelsize_x;
f32 tex0 = (i + 0.1) * pixelsize_x;
f32 tex1 = (i + 0.9) * pixelsize_x;
video::S3DVertex vertices[8] = {
video::S3DVertexTangents vertices[8] = {
// x-
video::S3DVertex(x0,-r,-r, -1,0,0, c, tex0,1),
video::S3DVertex(x0,-r,+r, -1,0,0, c, tex1,1),
video::S3DVertex(x0,+r,+r, -1,0,0, c, tex1,0),
video::S3DVertex(x0,+r,-r, -1,0,0, c, tex0,0),
video::S3DVertexTangents(x0,-r,-r, -1,0,0, c, tex0,1),
video::S3DVertexTangents(x0,-r,+r, -1,0,0, c, tex1,1),
video::S3DVertexTangents(x0,+r,+r, -1,0,0, c, tex1,0),
video::S3DVertexTangents(x0,+r,-r, -1,0,0, c, tex0,0),
// x+
video::S3DVertex(x1,-r,-r, +1,0,0, c, tex0,1),
video::S3DVertex(x1,+r,-r, +1,0,0, c, tex0,0),
video::S3DVertex(x1,+r,+r, +1,0,0, c, tex1,0),
video::S3DVertex(x1,-r,+r, +1,0,0, c, tex1,1),
video::S3DVertexTangents(x1,-r,-r, +1,0,0, c, tex0,1),
video::S3DVertexTangents(x1,+r,-r, +1,0,0, c, tex0,0),
video::S3DVertexTangents(x1,+r,+r, +1,0,0, c, tex1,0),
video::S3DVertexTangents(x1,-r,+r, +1,0,0, c, tex1,1),
};
u16 indices[12] = {0,1,2,2,3,0,4,5,6,6,7,4};
buf->append(vertices, 8, indices, 12);
@ -97,17 +96,17 @@ static scene::IMesh *createExtrusionMesh(int resolution_x, int resolution_y)
f32 y1 = -pixelpos_y;
f32 tex0 = (i + 0.1) * pixelsize_y;
f32 tex1 = (i + 0.9) * pixelsize_y;
video::S3DVertex vertices[8] = {
video::S3DVertexTangents vertices[8] = {
// y-
video::S3DVertex(-r,y0,-r, 0,-1,0, c, 0,tex0),
video::S3DVertex(+r,y0,-r, 0,-1,0, c, 1,tex0),
video::S3DVertex(+r,y0,+r, 0,-1,0, c, 1,tex1),
video::S3DVertex(-r,y0,+r, 0,-1,0, c, 0,tex1),
video::S3DVertexTangents(-r,y0,-r, 0,-1,0, c, 0,tex0),
video::S3DVertexTangents(+r,y0,-r, 0,-1,0, c, 1,tex0),
video::S3DVertexTangents(+r,y0,+r, 0,-1,0, c, 1,tex1),
video::S3DVertexTangents(-r,y0,+r, 0,-1,0, c, 0,tex1),
// y+
video::S3DVertex(-r,y1,-r, 0,+1,0, c, 0,tex0),
video::S3DVertex(-r,y1,+r, 0,+1,0, c, 0,tex1),
video::S3DVertex(+r,y1,+r, 0,+1,0, c, 1,tex1),
video::S3DVertex(+r,y1,-r, 0,+1,0, c, 1,tex0),
video::S3DVertexTangents(-r,y1,-r, 0,+1,0, c, 0,tex0),
video::S3DVertexTangents(-r,y1,+r, 0,+1,0, c, 0,tex1),
video::S3DVertexTangents(+r,y1,+r, 0,+1,0, c, 1,tex1),
video::S3DVertexTangents(+r,y1,-r, 0,+1,0, c, 1,tex0),
};
u16 indices[12] = {0,1,2,2,3,0,4,5,6,6,7,4};
buf->append(vertices, 8, indices, 12);
@ -117,7 +116,7 @@ static scene::IMesh *createExtrusionMesh(int resolution_x, int resolution_y)
scene::SMesh *mesh = new scene::SMesh();
mesh->addMeshBuffer(buf);
buf->drop();
scaleMesh(mesh, scale); // also recalculates bounding box
scaleMeshTangents(mesh, scale); // also recalculates bounding box
return mesh;
}
@ -144,7 +143,7 @@ class ExtrusionMeshCache: public IReferenceCounted
m_extrusion_meshes[resolution] =
createExtrusionMesh(resolution, resolution);
}
m_cube = createCubeMesh(v3f(1.0, 1.0, 1.0));
m_cube = createCubeMeshTangents(v3f(1.0, 1.0, 1.0));
}
// Destructor
virtual ~ExtrusionMeshCache()
@ -345,14 +344,16 @@ static scene::SMesh *createSpecialNodeMesh(Client *client, MapNode n,
p.layer.texture = frame.texture;
p.layer.normal_texture = frame.normal_texture;
}
std::vector<video::S3DVertexTangents> tangents;
for (video::S3DVertex &v : p.vertices) {
v.Color.setAlpha(255);
tangents.emplace_back(v);
}
scene::SMeshBuffer *buf = new scene::SMeshBuffer();
scene::SMeshBufferTangents *buf = new scene::SMeshBufferTangents();
buf->Material.setTexture(0, p.layer.texture);
p.layer.applyMaterialOptions(buf->Material);
mesh->addMeshBuffer(buf);
buf->append(&p.vertices[0], p.vertices.size(),
buf->append(&tangents[0], tangents.size(),
&p.indices[0], p.indices.size());
buf->drop();
colors->push_back(
@ -374,7 +375,7 @@ void WieldMeshSceneNode::setItem(const ItemStack &item, Client *client, bool che
scene::SMesh *mesh = nullptr;
if (m_enable_shaders) {
u32 shader_id = shdrsrc->getShader("object_shader", TILE_MATERIAL_BASIC, NDT_NORMAL);
u32 shader_id = shdrsrc->getShader("nodes_shader", TILE_MATERIAL_BASIC, NDT_NORMAL);
m_material_type = shdrsrc->getShaderInfo(shader_id).material;
}
@ -500,33 +501,37 @@ void WieldMeshSceneNode::setItem(const ItemStack &item, Client *client, bool che
void WieldMeshSceneNode::setColor(video::SColor c)
{
if (!m_meshnode)
return;
assert(!m_lighting);
scene::IMesh *mesh = m_meshnode->getMesh();
if (!mesh)
return;
u8 red = c.getRed();
u8 green = c.getGreen();
u8 blue = c.getBlue();
const u32 mc = mesh->getMeshBufferCount();
if (mc > m_colors.size())
m_colors.resize(mc);
for (u32 j = 0; j < mc; j++) {
video::SColor bc(m_base_color);
m_colors[j].applyOverride(bc);
video::SColor buffercolor(255,
bc.getRed() * red / 255,
bc.getGreen() * green / 255,
bc.getBlue() * blue / 255);
scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
video::SColor buffercolor(255,
bc.getRed() * c.getRed() / 255,
bc.getGreen() * c.getGreen() / 255,
bc.getBlue() * c.getBlue() / 255);
if (m_colors[j].needColorize(buffercolor)) {
buf->setDirty(scene::EBT_VERTEX);
if (m_enable_shaders)
setMeshBufferColor(buf, buffercolor);
if (m_enable_shaders) {
setMeshBufferTangentsColor(buf,
video::SColor(255, c.getRed(), c.getGreen(), c.getBlue()),
video::SColor(255, bc.getRed() / 255, bc.getGreen() / 255, bc.getBlue() / 255));
}
else
colorizeMeshBuffer(buf, &buffercolor);
colorizeMeshBufferTangents(buf, &buffercolor);
}
}
}
@ -619,15 +624,15 @@ void getItemMesh(Client *client, const ItemStack &item, ItemMesh *result)
mesh = cloneMesh(cube);
cube->drop();
if (f.drawtype == NDT_FLOWINGLIQUID) {
scaleMesh(mesh, v3f(1.2, 0.03, 1.2));
translateMesh(mesh, v3f(0, -0.57, 0));
scaleMeshTangents(mesh, v3f(1.2, 0.03, 1.2));
translateMeshTangents(mesh, v3f(0, -0.57, 0));
} else
scaleMesh(mesh, v3f(1.2, 1.2, 1.2));
scaleMeshTangents(mesh, v3f(1.2, 1.2, 1.2));
// add overlays
postProcessNodeMesh(mesh, f, false, false, nullptr,
&result->buffer_colors, true);
if (f.drawtype == NDT_ALLFACES)
scaleMesh(mesh, v3f(f.visual_scale));
scaleMeshTangents(mesh, v3f(f.visual_scale));
break;
}
case NDT_PLANTLIKE: {
@ -656,7 +661,7 @@ void getItemMesh(Client *client, const ItemStack &item, ItemMesh *result)
n.setParam2(*def.place_param2);
mesh = createSpecialNodeMesh(client, n, &result->buffer_colors, f);
scaleMesh(mesh, v3f(0.12, 0.12, 0.12));
scaleMeshTangents(mesh, v3f(0.12, 0.12, 0.12));
break;
}
}
@ -674,8 +679,8 @@ void getItemMesh(Client *client, const ItemStack &item, ItemMesh *result)
material.Lighting = false;
}
rotateMeshXZby(mesh, -45);
rotateMeshYZby(mesh, -30);
rotateMeshTangentsXZby(mesh, -45);
rotateMeshTangentsYZby(mesh, -30);
}
// might need to be re-colorized, this is done only when needed
@ -728,7 +733,7 @@ scene::SMesh *getExtrudedMesh(ITextureSource *tsrc,
material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
material.MaterialTypeParam = 0.5f;
}
scaleMesh(mesh, v3f(2.0, 2.0, 2.0));
scaleMeshTangents(mesh, v3f(2.0, 2.0, 2.0));
return mesh;
}