mirror of
https://github.com/minetest/minetest.git
synced 2024-07-04 15:05:27 +02:00
Use S3DVertexTangents for mapblocks & wield meshes for separate saving light and hardware colors
This commit is contained in:
parent
385bb3c801
commit
d3b63ba06f
@ -38,6 +38,7 @@ varying vec3 vPosition;
|
|||||||
// precision must be considered).
|
// precision must be considered).
|
||||||
varying vec3 worldPosition;
|
varying vec3 worldPosition;
|
||||||
varying lowp vec4 varColor;
|
varying lowp vec4 varColor;
|
||||||
|
varying lowp vec3 hwColor;
|
||||||
#ifdef GL_ES
|
#ifdef GL_ES
|
||||||
varying mediump vec2 varTexCoord;
|
varying mediump vec2 varTexCoord;
|
||||||
#else
|
#else
|
||||||
@ -375,7 +376,7 @@ void main(void)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
color = base.rgb;
|
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
|
#ifdef ENABLE_DYNAMIC_SHADOWS
|
||||||
if (f_shadow_strength > 0.0) {
|
if (f_shadow_strength > 0.0) {
|
||||||
|
@ -17,6 +17,7 @@ varying vec3 vPosition;
|
|||||||
// precision must be considered).
|
// precision must be considered).
|
||||||
varying vec3 worldPosition;
|
varying vec3 worldPosition;
|
||||||
varying lowp vec4 varColor;
|
varying lowp vec4 varColor;
|
||||||
|
varying lowp vec3 hwColor;
|
||||||
// The centroid keyword ensures that after interpolation the texture coordinates
|
// The centroid keyword ensures that after interpolation the texture coordinates
|
||||||
// lie within the same bounds when MSAA is en- and disabled.
|
// lie within the same bounds when MSAA is en- and disabled.
|
||||||
// This fixes the stripes problem with nearest-neighbor textures and MSAA.
|
// 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);
|
varColor = clamp(color, 0.0, 1.0);
|
||||||
|
|
||||||
|
hwColor = inVertexTangent.xyz;
|
||||||
|
|
||||||
#ifdef ENABLE_DYNAMIC_SHADOWS
|
#ifdef ENABLE_DYNAMIC_SHADOWS
|
||||||
if (f_shadow_strength > 0.0) {
|
if (f_shadow_strength > 0.0) {
|
||||||
#if MATERIAL_TYPE == TILE_MATERIAL_WAVING_PLANTS && ENABLE_WAVING_PLANTS
|
#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) {
|
if (m_wield_change_timer >= 0 && was_under_zero) {
|
||||||
m_wieldnode->setItem(m_wield_item_next, m_client);
|
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)
|
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_wieldnode->setRotation(wield_rotation);
|
||||||
|
|
||||||
m_player_light_color = player->light_color;
|
m_player_light_color = player->light_color;
|
||||||
m_wieldnode->setNodeLightColor(m_player_light_color);
|
m_wieldnode->setColor(m_player_light_color);
|
||||||
|
|
||||||
// Set render distance
|
// Set render distance
|
||||||
updateViewingRange();
|
updateViewingRange();
|
||||||
|
@ -922,11 +922,11 @@ void GenericCAO::setNodeLight(const video::SColor &light_color)
|
|||||||
{
|
{
|
||||||
if (m_prop.visual == "wielditem" || m_prop.visual == "item") {
|
if (m_prop.visual == "wielditem" || m_prop.visual == "item") {
|
||||||
if (m_wield_meshnode)
|
if (m_wield_meshnode)
|
||||||
m_wield_meshnode->setNodeLightColor(light_color);
|
m_wield_meshnode->setColor(light_color);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_enable_shaders) {
|
/*if (m_enable_shaders) {
|
||||||
if (m_prop.visual == "upright_sprite") {
|
if (m_prop.visual == "upright_sprite") {
|
||||||
if (!m_meshnode)
|
if (!m_meshnode)
|
||||||
return;
|
return;
|
||||||
@ -942,7 +942,7 @@ void GenericCAO::setNodeLight(const video::SColor &light_color)
|
|||||||
material.EmissiveColor = light_color;
|
material.EmissiveColor = light_color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {*/
|
||||||
if (m_meshnode) {
|
if (m_meshnode) {
|
||||||
setMeshColor(m_meshnode->getMesh(), light_color);
|
setMeshColor(m_meshnode->getMesh(), light_color);
|
||||||
} else if (m_animated_meshnode) {
|
} else if (m_animated_meshnode) {
|
||||||
@ -950,7 +950,7 @@ void GenericCAO::setNodeLight(const video::SColor &light_color)
|
|||||||
} else if (m_spritenode) {
|
} else if (m_spritenode) {
|
||||||
m_spritenode->setColor(light_color);
|
m_spritenode->setColor(light_color);
|
||||||
}
|
}
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
u16 GenericCAO::getLightPosition(v3s16 *pos)
|
u16 GenericCAO::getLightPosition(v3s16 *pos)
|
||||||
|
@ -1137,9 +1137,9 @@ void drawItemStack(
|
|||||||
if (p.needColorize(c)) {
|
if (p.needColorize(c)) {
|
||||||
buf->setDirty(scene::EBT_VERTEX);
|
buf->setDirty(scene::EBT_VERTEX);
|
||||||
if (imesh->needs_shading)
|
if (imesh->needs_shading)
|
||||||
colorizeMeshBuffer(buf, &c);
|
colorizeMeshBufferTangents(buf, &c);
|
||||||
else
|
else
|
||||||
setMeshBufferColor(buf, c);
|
setMeshBufferTangentsColor(buf, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
video::SMaterial &material = buf->getMaterial();
|
video::SMaterial &material = buf->getMaterial();
|
||||||
|
@ -630,7 +630,8 @@ MapBlockMesh::MapBlockMesh(Client *client, MeshMakeData *data, v3s16 camera_offs
|
|||||||
{
|
{
|
||||||
PreMeshBuffer &p = collector.prebuffers[layer][i];
|
PreMeshBuffer &p = collector.prebuffers[layer][i];
|
||||||
|
|
||||||
applyTileColor(p);
|
if (!m_enable_shaders)
|
||||||
|
applyTileColor(p);
|
||||||
|
|
||||||
// Generate animation data
|
// Generate animation data
|
||||||
// - Cracks
|
// - Cracks
|
||||||
@ -717,10 +718,25 @@ MapBlockMesh::MapBlockMesh(Client *client, MeshMakeData *data, v3s16 camera_offs
|
|||||||
p.layer.applyMaterialOptions(material);
|
p.layer.applyMaterialOptions(material);
|
||||||
}
|
}
|
||||||
|
|
||||||
scene::SMeshBuffer *buf = new scene::SMeshBuffer();
|
scene::SMeshBufferTangents *buf = new scene::SMeshBufferTangents();
|
||||||
buf->Material = material;
|
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()) {
|
if (p.layer.isTransparent()) {
|
||||||
buf->append(&p.vertices[0], p.vertices.size(), nullptr, 0);
|
buf->append(&tangents[0], tangents.size(), nullptr, 0);
|
||||||
|
|
||||||
MeshTriangle t;
|
MeshTriangle t;
|
||||||
t.buffer = buf;
|
t.buffer = buf;
|
||||||
@ -733,7 +749,7 @@ MapBlockMesh::MapBlockMesh(Client *client, MeshMakeData *data, v3s16 camera_offs
|
|||||||
m_transparent_triangles.push_back(t);
|
m_transparent_triangles.push_back(t);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
buf->append(&p.vertices[0], p.vertices.size(),
|
buf->append(&tangents[0], tangents.size(),
|
||||||
&p.indices[0], p.indices.size());
|
&p.indices[0], p.indices.size());
|
||||||
}
|
}
|
||||||
mesh->addMeshBuffer(buf);
|
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)) {
|
if (!m_enable_shaders && (daynight_ratio != m_last_daynight_ratio)) {
|
||||||
video::SColorf day_color;
|
video::SColorf day_color;
|
||||||
get_sunlight_color(&day_color, daynight_ratio);
|
get_sunlight_color(&day_color, daynight_ratio);
|
||||||
|
|
||||||
for (auto &daynight_diff : m_daynight_diffs) {
|
for (auto &daynight_diff : m_daynight_diffs) {
|
||||||
auto *mesh = m_mesh[daynight_diff.first.first];
|
auto *mesh = m_mesh[daynight_diff.first.first];
|
||||||
mesh->setDirty(scene::EBT_VERTEX); // force reload to VBO
|
mesh->setDirty(scene::EBT_VERTEX); // force reload to VBO
|
||||||
scene::IMeshBuffer *buf = mesh->
|
scene::IMeshBuffer *buf = mesh->
|
||||||
getMeshBuffer(daynight_diff.first.second);
|
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)
|
for (const auto &j : daynight_diff.second)
|
||||||
final_color_blend(&(vertices[j.first].Color), j.second,
|
final_color_blend(&(vertices[j.first].Color), j.second,
|
||||||
day_color);
|
day_color);
|
||||||
}
|
}
|
||||||
m_last_daynight_ratio = daynight_ratio;
|
m_last_daynight_ratio = daynight_ratio;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -861,7 +876,7 @@ void MapBlockMesh::updateTransparentBuffers(v3f camera_pos, v3s16 block_pos)
|
|||||||
// arrange index sequences into partial buffers
|
// arrange index sequences into partial buffers
|
||||||
m_transparent_buffers.clear();
|
m_transparent_buffers.clear();
|
||||||
|
|
||||||
scene::SMeshBuffer *current_buffer = nullptr;
|
scene::SMeshBufferTangents *current_buffer = nullptr;
|
||||||
std::vector<u16> current_strain;
|
std::vector<u16> current_strain;
|
||||||
for (auto i : triangle_refs) {
|
for (auto i : triangle_refs) {
|
||||||
const auto &t = m_transparent_triangles[i];
|
const auto &t = m_transparent_triangles[i];
|
||||||
@ -885,7 +900,7 @@ void MapBlockMesh::consolidateTransparentBuffers()
|
|||||||
{
|
{
|
||||||
m_transparent_buffers.clear();
|
m_transparent_buffers.clear();
|
||||||
|
|
||||||
scene::SMeshBuffer *current_buffer = nullptr;
|
scene::SMeshBufferTangents *current_buffer = nullptr;
|
||||||
std::vector<u16> current_strain;
|
std::vector<u16> current_strain;
|
||||||
|
|
||||||
// use the fact that m_transparent_triangles is already arranged by buffer
|
// use the fact that m_transparent_triangles is already arranged by buffer
|
||||||
|
@ -74,7 +74,7 @@ struct MeshMakeData
|
|||||||
class MeshTriangle
|
class MeshTriangle
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
scene::SMeshBuffer *buffer;
|
scene::SMeshBufferTangents *buffer;
|
||||||
u16 p1, p2, p3;
|
u16 p1, p2, p3;
|
||||||
v3f centroid;
|
v3f centroid;
|
||||||
float areaSQ;
|
float areaSQ;
|
||||||
@ -152,7 +152,7 @@ class MapBlockBspTree
|
|||||||
class PartialMeshBuffer
|
class PartialMeshBuffer
|
||||||
{
|
{
|
||||||
public:
|
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))
|
m_buffer(buffer), m_vertex_indexes(std::move(vertex_indexes))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
@ -162,7 +162,7 @@ class PartialMeshBuffer
|
|||||||
void beforeDraw() const;
|
void beforeDraw() const;
|
||||||
void afterDraw() const;
|
void afterDraw() const;
|
||||||
private:
|
private:
|
||||||
scene::SMeshBuffer *m_buffer;
|
scene::SMeshBufferTangents *m_buffer;
|
||||||
mutable std::vector<u16> m_vertex_indexes;
|
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);
|
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)
|
scene::IAnimatedMesh* createCubeMesh(v3f scale)
|
||||||
{
|
{
|
||||||
video::SColor c(255,255,255,255);
|
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};
|
u16 indices[6] = {0,1,2,2,3,0};
|
||||||
|
|
||||||
scene::SMesh *mesh = new scene::SMesh();
|
scene::SMesh *mesh = new scene::SMesh();
|
||||||
for (u32 i=0; i<6; ++i)
|
for (u32 i=0; i<6; ++i)
|
||||||
{
|
{
|
||||||
scene::IMeshBuffer *buf = new scene::SMeshBuffer();
|
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
|
// Set default material
|
||||||
buf->getMaterial().Lighting = false;
|
buf->getMaterial().Lighting = false;
|
||||||
buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
|
buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
|
||||||
@ -115,9 +120,39 @@ scene::IAnimatedMesh* createCubeMesh(v3f scale)
|
|||||||
return anim_mesh;
|
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)
|
void scaleMesh(scene::IMesh *mesh, v3f scale)
|
||||||
{
|
{
|
||||||
if (mesh == NULL)
|
if (!mesh)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
aabb3f bbox;
|
aabb3f bbox;
|
||||||
@ -126,11 +161,9 @@ void scaleMesh(scene::IMesh *mesh, v3f scale)
|
|||||||
u32 mc = mesh->getMeshBufferCount();
|
u32 mc = mesh->getMeshBufferCount();
|
||||||
for (u32 j = 0; j < mc; j++) {
|
for (u32 j = 0; j < mc; j++) {
|
||||||
scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
|
scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
|
||||||
const u32 stride = getVertexPitchFromType(buf->getVertexType());
|
video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices();
|
||||||
u32 vertex_count = buf->getVertexCount();
|
for (u32 i = 0; i < buf->getVertexCount(); i++)
|
||||||
u8 *vertices = (u8 *)buf->getVertices();
|
vertices[i].Pos *= scale;
|
||||||
for (u32 i = 0; i < vertex_count; i++)
|
|
||||||
((video::S3DVertex *)(vertices + i * stride))->Pos *= scale;
|
|
||||||
|
|
||||||
buf->recalculateBoundingBox();
|
buf->recalculateBoundingBox();
|
||||||
|
|
||||||
@ -143,9 +176,9 @@ void scaleMesh(scene::IMesh *mesh, v3f scale)
|
|||||||
mesh->setBoundingBox(bbox);
|
mesh->setBoundingBox(bbox);
|
||||||
}
|
}
|
||||||
|
|
||||||
void translateMesh(scene::IMesh *mesh, v3f vec)
|
void scaleMeshTangents(scene::IMesh *mesh, v3f scale)
|
||||||
{
|
{
|
||||||
if (mesh == NULL)
|
if (!mesh)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
aabb3f bbox;
|
aabb3f bbox;
|
||||||
@ -154,11 +187,35 @@ void translateMesh(scene::IMesh *mesh, v3f vec)
|
|||||||
u32 mc = mesh->getMeshBufferCount();
|
u32 mc = mesh->getMeshBufferCount();
|
||||||
for (u32 j = 0; j < mc; j++) {
|
for (u32 j = 0; j < mc; j++) {
|
||||||
scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
|
scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
|
||||||
const u32 stride = getVertexPitchFromType(buf->getVertexType());
|
video::S3DVertexTangents *vertices = (video::S3DVertexTangents*)buf->getVertices();
|
||||||
u32 vertex_count = buf->getVertexCount();
|
for (u32 i = 0; i < buf->getVertexCount(); i++)
|
||||||
u8 *vertices = (u8 *)buf->getVertices();
|
vertices[i].Pos *= scale;
|
||||||
for (u32 i = 0; i < vertex_count; i++)
|
|
||||||
((video::S3DVertex *)(vertices + i * stride))->Pos += vec;
|
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();
|
buf->recalculateBoundingBox();
|
||||||
|
|
||||||
@ -173,11 +230,20 @@ void translateMesh(scene::IMesh *mesh, v3f vec)
|
|||||||
|
|
||||||
void setMeshBufferColor(scene::IMeshBuffer *buf, const video::SColor &color)
|
void setMeshBufferColor(scene::IMeshBuffer *buf, const video::SColor &color)
|
||||||
{
|
{
|
||||||
const u32 stride = getVertexPitchFromType(buf->getVertexType());
|
video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices();
|
||||||
u32 vertex_count = buf->getVertexCount();
|
for (u32 i = 0; i < buf->getVertexCount(); i++)
|
||||||
u8 *vertices = (u8 *) buf->getVertices();
|
vertices[i].Color = color;
|
||||||
for (u32 i = 0; i < vertex_count; i++)
|
}
|
||||||
((video::S3DVertex *) (vertices + i * stride))->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)
|
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)
|
void setMeshColor(scene::IMesh *mesh, const video::SColor &color)
|
||||||
{
|
{
|
||||||
if (mesh == NULL)
|
if (!mesh)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
u32 mc = mesh->getMeshBufferCount();
|
for (u32 j = 0; j < mesh->getMeshBufferCount(); j++)
|
||||||
for (u32 j = 0; j < mc; j++)
|
|
||||||
setMeshBufferColor(mesh->getMeshBuffer(j), color);
|
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)
|
void setMeshBufferTextureCoords(scene::IMeshBuffer *buf, const v2f *uv, u32 count)
|
||||||
{
|
{
|
||||||
const u32 stride = getVertexPitchFromType(buf->getVertexType());
|
|
||||||
assert(buf->getVertexCount() >= count);
|
assert(buf->getVertexCount() >= count);
|
||||||
u8 *vertices = (u8 *) buf->getVertices();
|
video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices();
|
||||||
for (u32 i = 0; i < count; i++)
|
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)
|
static void applyToMesh(scene::IMesh *mesh, const F &fn)
|
||||||
{
|
{
|
||||||
u16 mc = mesh->getMeshBufferCount();
|
for (u16 j = 0; j < mesh->getMeshBufferCount(); j++) {
|
||||||
for (u16 j = 0; j < mc; j++) {
|
|
||||||
scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
|
scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
|
||||||
const u32 stride = getVertexPitchFromType(buf->getVertexType());
|
T *vertices = (T*)buf->getVertices();
|
||||||
u32 vertex_count = buf->getVertexCount();
|
for (u32 i = 0; i < buf->getVertexCount(); i++)
|
||||||
char *vertices = reinterpret_cast<char *>(buf->getVertices());
|
fn(&vertices[i]);
|
||||||
for (u32 i = 0; i < vertex_count; i++)
|
|
||||||
fn(reinterpret_cast<video::S3DVertex *>(vertices + i * stride));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void colorizeMeshBuffer(scene::IMeshBuffer *buf, const video::SColor *buffercolor)
|
void colorizeMeshBufferTangents(scene::IMeshBuffer *buf, const video::SColor *buffercolor)
|
||||||
{
|
{
|
||||||
const u32 stride = getVertexPitchFromType(buf->getVertexType());
|
video::S3DVertexTangents *vertices = (video::S3DVertexTangents*)buf->getVertices();
|
||||||
u32 vertex_count = buf->getVertexCount();
|
for (u32 i = 0; i < buf->getVertexCount(); i++) {
|
||||||
u8 *vertices = (u8 *) buf->getVertices();
|
video::S3DVertexTangents *vertex = &vertices[i];
|
||||||
for (u32 i = 0; i < vertex_count; i++) {
|
|
||||||
video::S3DVertex *vertex = (video::S3DVertex *) (vertices + i * stride);
|
|
||||||
video::SColor *vc = &(vertex->Color);
|
video::SColor *vc = &(vertex->Color);
|
||||||
// Reset color
|
// Reset color
|
||||||
*vc = *buffercolor;
|
*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,
|
void setMeshColorByNormal(scene::IMesh *mesh, const v3f &normal,
|
||||||
const video::SColor &color)
|
const video::SColor &color)
|
||||||
{
|
{
|
||||||
@ -265,37 +313,47 @@ void setMeshColorByNormal(scene::IMesh *mesh, const v3f &normal,
|
|||||||
if (vertex->Normal == normal)
|
if (vertex->Normal == normal)
|
||||||
vertex->Color = color;
|
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)
|
static void rotateMesh(scene::IMesh *mesh, float degrees)
|
||||||
{
|
{
|
||||||
degrees *= M_PI / 180.0f;
|
degrees *= M_PI / 180.0f;
|
||||||
float c = std::cos(degrees);
|
float c = std::cos(degrees);
|
||||||
float s = std::sin(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 u = vertex->Pos.*U;
|
||||||
float v = vertex->Pos.*V;
|
float v = vertex->Pos.*V;
|
||||||
vertex->Pos.*U = c * u - s * v;
|
vertex->Pos.*U = c * u - s * v;
|
||||||
vertex->Pos.*V = s * u + c * v;
|
vertex->Pos.*V = s * u + c * v;
|
||||||
};
|
};
|
||||||
applyToMesh(mesh, rotator);
|
applyToMesh<T>(mesh, rotator);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rotateMeshXYby(scene::IMesh *mesh, f64 degrees)
|
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)
|
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)
|
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)
|
void rotateMeshBy6dFacedir(scene::IMesh *mesh, int facedir)
|
||||||
@ -357,7 +415,7 @@ scene::IMeshBuffer* cloneMeshBuffer(scene::IMeshBuffer *mesh_buffer)
|
|||||||
{
|
{
|
||||||
switch (mesh_buffer->getVertexType()) {
|
switch (mesh_buffer->getVertexType()) {
|
||||||
case video::EVT_STANDARD: {
|
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();
|
u16 *indices = mesh_buffer->getIndices();
|
||||||
scene::SMeshBuffer *cloned_buffer = new scene::SMeshBuffer();
|
scene::SMeshBuffer *cloned_buffer = new scene::SMeshBuffer();
|
||||||
cloned_buffer->append(v, mesh_buffer->getVertexCount(), indices,
|
cloned_buffer->append(v, mesh_buffer->getVertexCount(), indices,
|
||||||
@ -366,7 +424,7 @@ scene::IMeshBuffer* cloneMeshBuffer(scene::IMeshBuffer *mesh_buffer)
|
|||||||
}
|
}
|
||||||
case video::EVT_2TCOORDS: {
|
case video::EVT_2TCOORDS: {
|
||||||
video::S3DVertex2TCoords *v =
|
video::S3DVertex2TCoords *v =
|
||||||
(video::S3DVertex2TCoords *) mesh_buffer->getVertices();
|
(video::S3DVertex2TCoords*)mesh_buffer->getVertices();
|
||||||
u16 *indices = mesh_buffer->getIndices();
|
u16 *indices = mesh_buffer->getIndices();
|
||||||
scene::SMeshBufferLightMap *cloned_buffer =
|
scene::SMeshBufferLightMap *cloned_buffer =
|
||||||
new scene::SMeshBufferLightMap();
|
new scene::SMeshBufferLightMap();
|
||||||
@ -376,7 +434,7 @@ scene::IMeshBuffer* cloneMeshBuffer(scene::IMeshBuffer *mesh_buffer)
|
|||||||
}
|
}
|
||||||
case video::EVT_TANGENTS: {
|
case video::EVT_TANGENTS: {
|
||||||
video::S3DVertexTangents *v =
|
video::S3DVertexTangents *v =
|
||||||
(video::S3DVertexTangents *) mesh_buffer->getVertices();
|
(video::S3DVertexTangents*)mesh_buffer->getVertices();
|
||||||
u16 *indices = mesh_buffer->getIndices();
|
u16 *indices = mesh_buffer->getIndices();
|
||||||
scene::SMeshBufferTangents *cloned_buffer =
|
scene::SMeshBufferTangents *cloned_buffer =
|
||||||
new scene::SMeshBufferTangents();
|
new scene::SMeshBufferTangents();
|
||||||
|
@ -38,27 +38,33 @@ void applyFacesShading(video::SColor &color, const v3f &normal);
|
|||||||
*/
|
*/
|
||||||
scene::IAnimatedMesh* createCubeMesh(v3f scale);
|
scene::IAnimatedMesh* createCubeMesh(v3f scale);
|
||||||
|
|
||||||
|
scene::IAnimatedMesh* createCubeMeshTangents(v3f scale);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Multiplies each vertex coordinate by the specified scaling factors
|
Multiplies each vertex coordinate by the specified scaling factors
|
||||||
(componentwise vector multiplication).
|
(componentwise vector multiplication).
|
||||||
*/
|
*/
|
||||||
void scaleMesh(scene::IMesh *mesh, v3f scale);
|
void scaleMesh(scene::IMesh *mesh, v3f scale);
|
||||||
|
void scaleMeshTangents(scene::IMesh *mesh, v3f scale);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Translate each vertex coordinate by the specified vector.
|
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.
|
* Sets a constant color for all vertices in the mesh buffer.
|
||||||
*/
|
*/
|
||||||
void setMeshBufferColor(scene::IMeshBuffer *buf, const video::SColor &color);
|
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
|
Set a constant color for all vertices in the mesh
|
||||||
*/
|
*/
|
||||||
void setMeshColor(scene::IMesh *mesh, const video::SColor &color);
|
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.
|
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.
|
* Overwrites the color of a mesh buffer.
|
||||||
* The color is darkened based on the normal vector of the vertices.
|
* The color is darkened based on the normal vector of the vertices.
|
||||||
*/
|
*/
|
||||||
void colorizeMeshBuffer(scene::IMeshBuffer *buf, const video::SColor *buffercolor);
|
void colorizeMeshBufferTangents(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 setMeshColorByNormal(scene::IMesh *mesh, const v3f &normal,
|
void setMeshColorByNormal(scene::IMesh *mesh, const v3f &normal,
|
||||||
const video::SColor &color);
|
const video::SColor &color);
|
||||||
@ -102,7 +97,9 @@ void rotateMeshBy6dFacedir(scene::IMesh *mesh, int facedir);
|
|||||||
*/
|
*/
|
||||||
void rotateMeshXYby (scene::IMesh *mesh, f64 degrees);
|
void rotateMeshXYby (scene::IMesh *mesh, f64 degrees);
|
||||||
void rotateMeshXZby (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 rotateMeshYZby (scene::IMesh *mesh, f64 degrees);
|
||||||
|
void rotateMeshTangentsYZby(scene::IMesh *mesh, f64 degrees);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Clone the mesh buffer.
|
* Clone the mesh buffer.
|
||||||
@ -139,5 +136,5 @@ bool checkMeshNormals(scene::IMesh *mesh);
|
|||||||
Set the MinFilter, MagFilter and AnisotropicFilter properties of a texture
|
Set the MinFilter, MagFilter and AnisotropicFilter properties of a texture
|
||||||
layer according to the three relevant boolean values found in the Minetest
|
layer according to the three relevant boolean values found in the Minetest
|
||||||
settings.
|
settings.
|
||||||
*/
|
*/
|
||||||
void setMaterialFilters(video::SMaterialLayer &tex, bool bilinear, bool trilinear, bool anisotropic);
|
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;
|
const f32 r = 0.5;
|
||||||
|
|
||||||
scene::IMeshBuffer *buf = new scene::SMeshBuffer();
|
scene::SMeshBufferTangents *buf = new scene::SMeshBufferTangents();
|
||||||
video::SColor c(255,255,255,255);
|
video::SColor c(255,255,255,255);
|
||||||
v3f scale(1.0, 1.0, 0.1);
|
v3f scale(1.0, 1.0, 0.1);
|
||||||
|
|
||||||
// Front and back
|
|
||||||
{
|
{
|
||||||
video::S3DVertex vertices[8] = {
|
video::S3DVertexTangents vertices[8] = {
|
||||||
// z-
|
// z-
|
||||||
video::S3DVertex(-r,+r,-r, 0,0,-1, c, 0,0),
|
video::S3DVertexTangents(-r,+r,-r, 0,0,-1, c, 0,0),
|
||||||
video::S3DVertex(+r,+r,-r, 0,0,-1, c, 1,0),
|
video::S3DVertexTangents(+r,+r,-r, 0,0,-1, c, 1,0),
|
||||||
video::S3DVertex(+r,-r,-r, 0,0,-1, c, 1,1),
|
video::S3DVertexTangents(+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,1),
|
||||||
// z+
|
// z+
|
||||||
video::S3DVertex(-r,+r,+r, 0,0,+1, c, 0,0),
|
video::S3DVertexTangents(-r,+r,+r, 0,0,+1, c, 0,0),
|
||||||
video::S3DVertex(-r,-r,+r, 0,0,+1, c, 0,1),
|
video::S3DVertexTangents(-r,-r,+r, 0,0,+1, c, 0,1),
|
||||||
video::S3DVertex(+r,-r,+r, 0,0,+1, c, 1,1),
|
video::S3DVertexTangents(+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, 1,0),
|
||||||
};
|
};
|
||||||
u16 indices[12] = {0,1,2,2,3,0,4,5,6,6,7,4};
|
u16 indices[12] = {0,1,2,2,3,0,4,5,6,6,7,4};
|
||||||
buf->append(vertices, 8, indices, 12);
|
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 x1 = pixelpos_x + pixelsize_x;
|
||||||
f32 tex0 = (i + 0.1) * pixelsize_x;
|
f32 tex0 = (i + 0.1) * pixelsize_x;
|
||||||
f32 tex1 = (i + 0.9) * pixelsize_x;
|
f32 tex1 = (i + 0.9) * pixelsize_x;
|
||||||
video::S3DVertex vertices[8] = {
|
video::S3DVertexTangents vertices[8] = {
|
||||||
// x-
|
// x-
|
||||||
video::S3DVertex(x0,-r,-r, -1,0,0, c, tex0,1),
|
video::S3DVertexTangents(x0,-r,-r, -1,0,0, c, tex0,1),
|
||||||
video::S3DVertex(x0,-r,+r, -1,0,0, c, tex1,1),
|
video::S3DVertexTangents(x0,-r,+r, -1,0,0, c, tex1,1),
|
||||||
video::S3DVertex(x0,+r,+r, -1,0,0, c, tex1,0),
|
video::S3DVertexTangents(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,0),
|
||||||
// x+
|
// x+
|
||||||
video::S3DVertex(x1,-r,-r, +1,0,0, c, tex0,1),
|
video::S3DVertexTangents(x1,-r,-r, +1,0,0, c, tex0,1),
|
||||||
video::S3DVertex(x1,+r,-r, +1,0,0, c, tex0,0),
|
video::S3DVertexTangents(x1,+r,-r, +1,0,0, c, tex0,0),
|
||||||
video::S3DVertex(x1,+r,+r, +1,0,0, c, tex1,0),
|
video::S3DVertexTangents(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, tex1,1),
|
||||||
};
|
};
|
||||||
u16 indices[12] = {0,1,2,2,3,0,4,5,6,6,7,4};
|
u16 indices[12] = {0,1,2,2,3,0,4,5,6,6,7,4};
|
||||||
buf->append(vertices, 8, indices, 12);
|
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 y1 = -pixelpos_y;
|
||||||
f32 tex0 = (i + 0.1) * pixelsize_y;
|
f32 tex0 = (i + 0.1) * pixelsize_y;
|
||||||
f32 tex1 = (i + 0.9) * pixelsize_y;
|
f32 tex1 = (i + 0.9) * pixelsize_y;
|
||||||
video::S3DVertex vertices[8] = {
|
video::S3DVertexTangents vertices[8] = {
|
||||||
// y-
|
// y-
|
||||||
video::S3DVertex(-r,y0,-r, 0,-1,0, c, 0,tex0),
|
video::S3DVertexTangents(-r,y0,-r, 0,-1,0, c, 0,tex0),
|
||||||
video::S3DVertex(+r,y0,-r, 0,-1,0, c, 1,tex0),
|
video::S3DVertexTangents(+r,y0,-r, 0,-1,0, c, 1,tex0),
|
||||||
video::S3DVertex(+r,y0,+r, 0,-1,0, c, 1,tex1),
|
video::S3DVertexTangents(+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,tex1),
|
||||||
// y+
|
// y+
|
||||||
video::S3DVertex(-r,y1,-r, 0,+1,0, c, 0,tex0),
|
video::S3DVertexTangents(-r,y1,-r, 0,+1,0, c, 0,tex0),
|
||||||
video::S3DVertex(-r,y1,+r, 0,+1,0, c, 0,tex1),
|
video::S3DVertexTangents(-r,y1,+r, 0,+1,0, c, 0,tex1),
|
||||||
video::S3DVertex(+r,y1,+r, 0,+1,0, c, 1,tex1),
|
video::S3DVertexTangents(+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, 1,tex0),
|
||||||
};
|
};
|
||||||
u16 indices[12] = {0,1,2,2,3,0,4,5,6,6,7,4};
|
u16 indices[12] = {0,1,2,2,3,0,4,5,6,6,7,4};
|
||||||
buf->append(vertices, 8, indices, 12);
|
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();
|
scene::SMesh *mesh = new scene::SMesh();
|
||||||
mesh->addMeshBuffer(buf);
|
mesh->addMeshBuffer(buf);
|
||||||
buf->drop();
|
buf->drop();
|
||||||
scaleMesh(mesh, scale); // also recalculates bounding box
|
scaleMeshTangents(mesh, scale); // also recalculates bounding box
|
||||||
return mesh;
|
return mesh;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,7 +143,7 @@ class ExtrusionMeshCache: public IReferenceCounted
|
|||||||
m_extrusion_meshes[resolution] =
|
m_extrusion_meshes[resolution] =
|
||||||
createExtrusionMesh(resolution, 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
|
// Destructor
|
||||||
virtual ~ExtrusionMeshCache()
|
virtual ~ExtrusionMeshCache()
|
||||||
@ -345,14 +344,16 @@ static scene::SMesh *createSpecialNodeMesh(Client *client, MapNode n,
|
|||||||
p.layer.texture = frame.texture;
|
p.layer.texture = frame.texture;
|
||||||
p.layer.normal_texture = frame.normal_texture;
|
p.layer.normal_texture = frame.normal_texture;
|
||||||
}
|
}
|
||||||
|
std::vector<video::S3DVertexTangents> tangents;
|
||||||
for (video::S3DVertex &v : p.vertices) {
|
for (video::S3DVertex &v : p.vertices) {
|
||||||
v.Color.setAlpha(255);
|
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);
|
buf->Material.setTexture(0, p.layer.texture);
|
||||||
p.layer.applyMaterialOptions(buf->Material);
|
p.layer.applyMaterialOptions(buf->Material);
|
||||||
mesh->addMeshBuffer(buf);
|
mesh->addMeshBuffer(buf);
|
||||||
buf->append(&p.vertices[0], p.vertices.size(),
|
buf->append(&tangents[0], tangents.size(),
|
||||||
&p.indices[0], p.indices.size());
|
&p.indices[0], p.indices.size());
|
||||||
buf->drop();
|
buf->drop();
|
||||||
colors->push_back(
|
colors->push_back(
|
||||||
@ -374,7 +375,7 @@ void WieldMeshSceneNode::setItem(const ItemStack &item, Client *client, bool che
|
|||||||
scene::SMesh *mesh = nullptr;
|
scene::SMesh *mesh = nullptr;
|
||||||
|
|
||||||
if (m_enable_shaders) {
|
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;
|
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)
|
void WieldMeshSceneNode::setColor(video::SColor c)
|
||||||
{
|
{
|
||||||
|
if (!m_meshnode)
|
||||||
|
return;
|
||||||
|
|
||||||
assert(!m_lighting);
|
assert(!m_lighting);
|
||||||
scene::IMesh *mesh = m_meshnode->getMesh();
|
scene::IMesh *mesh = m_meshnode->getMesh();
|
||||||
if (!mesh)
|
if (!mesh)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
u8 red = c.getRed();
|
|
||||||
u8 green = c.getGreen();
|
|
||||||
u8 blue = c.getBlue();
|
|
||||||
|
|
||||||
const u32 mc = mesh->getMeshBufferCount();
|
const u32 mc = mesh->getMeshBufferCount();
|
||||||
if (mc > m_colors.size())
|
if (mc > m_colors.size())
|
||||||
m_colors.resize(mc);
|
m_colors.resize(mc);
|
||||||
for (u32 j = 0; j < mc; j++) {
|
for (u32 j = 0; j < mc; j++) {
|
||||||
video::SColor bc(m_base_color);
|
video::SColor bc(m_base_color);
|
||||||
m_colors[j].applyOverride(bc);
|
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);
|
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)) {
|
if (m_colors[j].needColorize(buffercolor)) {
|
||||||
buf->setDirty(scene::EBT_VERTEX);
|
buf->setDirty(scene::EBT_VERTEX);
|
||||||
if (m_enable_shaders)
|
if (m_enable_shaders) {
|
||||||
setMeshBufferColor(buf, buffercolor);
|
setMeshBufferTangentsColor(buf,
|
||||||
|
video::SColor(255, c.getRed(), c.getGreen(), c.getBlue()),
|
||||||
|
video::SColor(255, bc.getRed() / 255, bc.getGreen() / 255, bc.getBlue() / 255));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
colorizeMeshBuffer(buf, &buffercolor);
|
colorizeMeshBufferTangents(buf, &buffercolor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -619,15 +624,15 @@ void getItemMesh(Client *client, const ItemStack &item, ItemMesh *result)
|
|||||||
mesh = cloneMesh(cube);
|
mesh = cloneMesh(cube);
|
||||||
cube->drop();
|
cube->drop();
|
||||||
if (f.drawtype == NDT_FLOWINGLIQUID) {
|
if (f.drawtype == NDT_FLOWINGLIQUID) {
|
||||||
scaleMesh(mesh, v3f(1.2, 0.03, 1.2));
|
scaleMeshTangents(mesh, v3f(1.2, 0.03, 1.2));
|
||||||
translateMesh(mesh, v3f(0, -0.57, 0));
|
translateMeshTangents(mesh, v3f(0, -0.57, 0));
|
||||||
} else
|
} else
|
||||||
scaleMesh(mesh, v3f(1.2, 1.2, 1.2));
|
scaleMeshTangents(mesh, v3f(1.2, 1.2, 1.2));
|
||||||
// add overlays
|
// add overlays
|
||||||
postProcessNodeMesh(mesh, f, false, false, nullptr,
|
postProcessNodeMesh(mesh, f, false, false, nullptr,
|
||||||
&result->buffer_colors, true);
|
&result->buffer_colors, true);
|
||||||
if (f.drawtype == NDT_ALLFACES)
|
if (f.drawtype == NDT_ALLFACES)
|
||||||
scaleMesh(mesh, v3f(f.visual_scale));
|
scaleMeshTangents(mesh, v3f(f.visual_scale));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NDT_PLANTLIKE: {
|
case NDT_PLANTLIKE: {
|
||||||
@ -656,7 +661,7 @@ void getItemMesh(Client *client, const ItemStack &item, ItemMesh *result)
|
|||||||
n.setParam2(*def.place_param2);
|
n.setParam2(*def.place_param2);
|
||||||
|
|
||||||
mesh = createSpecialNodeMesh(client, n, &result->buffer_colors, f);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -674,8 +679,8 @@ void getItemMesh(Client *client, const ItemStack &item, ItemMesh *result)
|
|||||||
material.Lighting = false;
|
material.Lighting = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
rotateMeshXZby(mesh, -45);
|
rotateMeshTangentsXZby(mesh, -45);
|
||||||
rotateMeshYZby(mesh, -30);
|
rotateMeshTangentsYZby(mesh, -30);
|
||||||
}
|
}
|
||||||
|
|
||||||
// might need to be re-colorized, this is done only when needed
|
// 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.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
|
||||||
material.MaterialTypeParam = 0.5f;
|
material.MaterialTypeParam = 0.5f;
|
||||||
}
|
}
|
||||||
scaleMesh(mesh, v3f(2.0, 2.0, 2.0));
|
scaleMeshTangents(mesh, v3f(2.0, 2.0, 2.0));
|
||||||
|
|
||||||
return mesh;
|
return mesh;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user