]> git.lizzy.rs Git - dragonfireclient.git/blobdiff - src/mesh.cpp
Full viewing range key message clarified
[dragonfireclient.git] / src / mesh.cpp
index d79f545f3cca8c9040f5767e849594dd9a7211af..3ab67510a258893808fbd9c96a70a75896927506 100644 (file)
@@ -33,13 +33,33 @@ 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)
+{
+       /*
+               Some drawtypes have normals set to (0, 0, 0), this must result in
+               maximum brightness: shade factor 1.0.
+               Shade factors for aligned cube faces are:
+               +Y 1.000000 sqrt(1.0)
+               -Y 0.447213 sqrt(0.2)
+               +-X 0.670820 sqrt(0.45)
+               +-Z 0.836660 sqrt(0.7)
+       */
+       float x2 = normal.X * normal.X;
+       float y2 = normal.Y * normal.Y;
+       float z2 = normal.Z * normal.Z;
+       if (normal.Y < 0)
+               applyShadeFactor(color, 0.670820f * x2 + 0.447213f * y2 + 0.836660f * z2);
+       else if ((x2 > 1e-3) || (z2 > 1e-3))
+               applyShadeFactor(color, 0.670820f * x2 + 1.000000f * y2 + 0.836660f * z2);
+}
+
 scene::IAnimatedMesh* createCubeMesh(v3f scale)
 {
        video::SColor c(255,255,255,255);
@@ -104,7 +124,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 +152,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();
@@ -155,6 +175,14 @@ void translateMesh(scene::IMesh *mesh, v3f vec)
        mesh->setBoundingBox(bbox);
 }
 
+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;
+}
 
 void setMeshColor(scene::IMesh *mesh, const video::SColor &color)
 {
@@ -162,42 +190,22 @@ void setMeshColor(scene::IMesh *mesh, const video::SColor &color)
                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 *)(vertices + i * stride))->Color = color;
-       }
+       for (u32 j = 0; j < mc; j++)
+               setMeshBufferColor(mesh->getMeshBuffer(j), 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 +234,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 +374,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);
@@ -359,54 +387,58 @@ void recalculateBoundingBox(scene::IMesh *src_mesh)
        src_mesh->setBoundingBox(bbox);
 }
 
-scene::IMesh* cloneMesh(scene::IMesh *src_mesh)
+scene::IMeshBuffer* cloneMeshBuffer(scene::IMeshBuffer *mesh_buffer)
+{
+       switch (mesh_buffer->getVertexType()) {
+       case video::EVT_STANDARD: {
+               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,
+                       mesh_buffer->getIndexCount());
+               return cloned_buffer;
+       }
+       case video::EVT_2TCOORDS: {
+               video::S3DVertex2TCoords *v =
+                       (video::S3DVertex2TCoords *) mesh_buffer->getVertices();
+               u16 *indices = mesh_buffer->getIndices();
+               scene::SMeshBufferTangents *cloned_buffer =
+                       new scene::SMeshBufferTangents();
+               cloned_buffer->append(v, mesh_buffer->getVertexCount(), indices,
+                       mesh_buffer->getIndexCount());
+               return cloned_buffer;
+       }
+       case video::EVT_TANGENTS: {
+               video::S3DVertexTangents *v =
+                       (video::S3DVertexTangents *) mesh_buffer->getVertices();
+               u16 *indices = mesh_buffer->getIndices();
+               scene::SMeshBufferTangents *cloned_buffer =
+                       new scene::SMeshBufferTangents();
+               cloned_buffer->append(v, mesh_buffer->getVertexCount(), indices,
+                       mesh_buffer->getIndexCount());
+               return cloned_buffer;
+       }
+       }
+       // This should not happen.
+       sanity_check(false);
+       return NULL;
+}
+
+scene::SMesh* cloneMesh(scene::IMesh *src_mesh)
 {
        scene::SMesh* dst_mesh = new scene::SMesh();
        for (u16 j = 0; j < src_mesh->getMeshBufferCount(); j++) {
-               scene::IMeshBuffer *buf = src_mesh->getMeshBuffer(j);
-               switch (buf->getVertexType()) {
-                       case video::EVT_STANDARD: {
-                               video::S3DVertex *v =
-                                       (video::S3DVertex *) buf->getVertices();
-                               u16 *indices = (u16*)buf->getIndices();
-                               scene::SMeshBuffer *temp_buf = new scene::SMeshBuffer();
-                               temp_buf->append(v, buf->getVertexCount(),
-                                       indices, buf->getIndexCount());
-                               dst_mesh->addMeshBuffer(temp_buf);
-                               temp_buf->drop();
-                               break;
-                       }
-                       case video::EVT_2TCOORDS: {
-                               video::S3DVertex2TCoords *v =
-                                       (video::S3DVertex2TCoords *) buf->getVertices();
-                               u16 *indices = (u16*)buf->getIndices();
-                               scene::SMeshBufferTangents *temp_buf =
-                                       new scene::SMeshBufferTangents();
-                               temp_buf->append(v, buf->getVertexCount(),
-                                       indices, buf->getIndexCount());
-                               dst_mesh->addMeshBuffer(temp_buf);
-                               temp_buf->drop();
-                               break;
-                       }
-                       case video::EVT_TANGENTS: {
-                               video::S3DVertexTangents *v =
-                                       (video::S3DVertexTangents *) buf->getVertices();
-                               u16 *indices = (u16*)buf->getIndices();
-                               scene::SMeshBufferTangents *temp_buf =
-                                       new scene::SMeshBufferTangents();
-                               temp_buf->append(v, buf->getVertexCount(),
-                                       indices, buf->getIndexCount());
-                               dst_mesh->addMeshBuffer(temp_buf);
-                               temp_buf->drop();
-                               break;
-                       }
-               }
+               scene::IMeshBuffer *temp_buf = cloneMeshBuffer(
+                       src_mesh->getMeshBuffer(j));
+               dst_mesh->addMeshBuffer(temp_buf);
+               temp_buf->drop();
+
        }
        return dst_mesh;
 }
 
 scene::IMesh* convertNodeboxesToMesh(const std::vector<aabb3f> &boxes,
-               const f32 *uv_coords)
+               const f32 *uv_coords, float expand)
 {
        scene::SMesh* dst_mesh = new scene::SMesh();
 
@@ -419,33 +451,21 @@ scene::IMesh* convertNodeboxesToMesh(const std::vector<aabb3f> &boxes,
                buf->drop();
        }
 
-       video::SColor c(255,255,255,255);       
+       video::SColor c(255,255,255,255);
 
-       for(std::vector<aabb3f>::const_iterator
+       for (std::vector<aabb3f>::const_iterator
                        i = boxes.begin();
                        i != boxes.end(); ++i)
        {
                aabb3f box = *i;
+               box.repair();
 
-               f32 temp;
-               if (box.MinEdge.X > box.MaxEdge.X)
-                       {
-                               temp=box.MinEdge.X;
-                               box.MinEdge.X=box.MaxEdge.X;
-                               box.MaxEdge.X=temp;
-                       }
-               if (box.MinEdge.Y > box.MaxEdge.Y)
-                       {
-                               temp=box.MinEdge.Y;
-                               box.MinEdge.Y=box.MaxEdge.Y;
-                               box.MaxEdge.Y=temp;
-                       }
-               if (box.MinEdge.Z > box.MaxEdge.Z)
-                       {
-                               temp=box.MinEdge.Z;
-                               box.MinEdge.Z=box.MaxEdge.Z;
-                               box.MaxEdge.Z=temp;
-                       }
+               box.MinEdge.X -= expand;
+               box.MinEdge.Y -= expand;
+               box.MinEdge.Z -= expand;
+               box.MaxEdge.X += expand;
+               box.MaxEdge.Y += expand;
+               box.MaxEdge.Z += expand;
 
                // Compute texture UV coords
                f32 tx1 = (box.MinEdge.X / BS) + 0.5;
@@ -518,7 +538,7 @@ scene::IMesh* convertNodeboxesToMesh(const std::vector<aabb3f> &boxes,
                        buf->append(vertices + j, 4, indices, 6);
                }
        }
-       return dst_mesh;                                        
+       return dst_mesh;
 }
 
 struct vcache