]> git.lizzy.rs Git - minetest.git/blobdiff - src/mesh.cpp
Dungeongen: Fix out-of-voxelmanip access segfault
[minetest.git] / src / mesh.cpp
index 3c39322044f78d35c14a25d7d917ac649dcab488..84689b6319f1f39e875301850913ebb4527c9f94 100644 (file)
@@ -33,13 +33,25 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #define MY_ETLM_READ_ONLY video::ETLM_READ_ONLY
 #endif
 
-static void applyFacesShading(video::SColor& color, float factor)
+inline static void applyShadeFactor(video::SColor& color, 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.setBlue(core::clamp(core::round32(color.getBlue()*factor), 0, 255));
 }
 
+void applyFacesShading(video::SColor &color, const v3f &normal)
+{
+       // Many special drawtypes have normals set to 0,0,0 and this
+       // must result in maximum brightness (no face shadng).
+       if (normal.Y < -0.5f)
+               applyShadeFactor (color, 0.447213f);
+       else if (normal.X > 0.5f || normal.X < -0.5f)
+               applyShadeFactor (color, 0.670820f);
+       else if (normal.Z > 0.5f || normal.Z < -0.5f)
+               applyShadeFactor (color, 0.836660f);
+}
+
 scene::IAnimatedMesh* createCubeMesh(v3f scale)
 {
        video::SColor c(255,255,255,255);
@@ -104,7 +116,7 @@ void scaleMesh(scene::IMesh *mesh, v3f scale)
        if (mesh == NULL)
                return;
 
-       core::aabbox3d<f32> bbox;
+       aabb3f bbox;
        bbox.reset(0, 0, 0);
 
        u32 mc = mesh->getMeshBufferCount();
@@ -132,7 +144,7 @@ void translateMesh(scene::IMesh *mesh, v3f vec)
        if (mesh == NULL)
                return;
 
-       core::aabbox3d<f32> bbox;
+       aabb3f bbox;
        bbox.reset(0, 0, 0);
 
        u32 mc = mesh->getMeshBufferCount();
@@ -172,32 +184,18 @@ void setMeshColor(scene::IMesh *mesh, const video::SColor &color)
        }
 }
 
-void shadeMeshFaces(scene::IMesh *mesh)
+void colorizeMeshBuffer(scene::IMeshBuffer *buf, const video::SColor *buffercolor)
 {
-       if (mesh == NULL)
-               return;
-
-       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 *vertex = (video::S3DVertex *)(vertices + i * stride);
-                       video::SColor &vc = vertex->Color;
-                       if (vertex->Normal.Y < -0.5) {
-                               applyFacesShading (vc, 0.447213);
-                       } else if (vertex->Normal.Z > 0.5) {
-                               applyFacesShading (vc, 0.670820);
-                       } else if (vertex->Normal.Z < -0.5) {
-                               applyFacesShading (vc, 0.670820);
-                       } else if (vertex->Normal.X > 0.5) {
-                               applyFacesShading (vc, 0.836660);
-                       } else if (vertex->Normal.X < -0.5) {
-                               applyFacesShading (vc, 0.836660);
-                       }
-               }
+       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::SColor *vc = &(vertex->Color);
+               // Reset color
+               *vc = *buffercolor;
+               // Apply shading
+               applyFacesShading(*vc, vertex->Normal);
        }
 }
 
@@ -226,7 +224,27 @@ void setMeshColorByNormalXYZ(scene::IMesh *mesh,
                                vertex->Color = colorY;
                        else
                                vertex->Color = colorZ;
+               }
+       }
+}
+
+void setMeshColorByNormal(scene::IMesh *mesh, const v3f &normal,
+               const video::SColor &color)
+{
+       if (!mesh)
+               return;
 
+       u16 mc = mesh->getMeshBufferCount();
+       for (u16 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 *vertex = (video::S3DVertex *)(vertices + i * stride);
+                       if (normal == vertex->Normal) {
+                               vertex->Color = color;
+                       }
                }
        }
 }
@@ -346,7 +364,7 @@ void rotateMeshBy6dFacedir(scene::IMesh *mesh, int facedir)
 
 void recalculateBoundingBox(scene::IMesh *src_mesh)
 {
-       core::aabbox3d<f32> bbox;
+       aabb3f bbox;
        bbox.reset(0,0,0);
        for (u16 j = 0; j < src_mesh->getMeshBufferCount(); j++) {
                scene::IMeshBuffer *buf = src_mesh->getMeshBuffer(j);