X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Fmapblock_mesh.cpp;h=8e3ae9f35d9702c8585a4baaaf39f80c0d10e53c;hb=de2c40c8fc189eeeeba010a0aaa1d28aed588c68;hp=7708fb43878e60779130bd0c187374cea16ddc21;hpb=2cf9014160085303cda333334784ac4938edc086;p=oweals%2Fminetest.git diff --git a/src/mapblock_mesh.cpp b/src/mapblock_mesh.cpp index 7708fb438..8e3ae9f35 100644 --- a/src/mapblock_mesh.cpp +++ b/src/mapblock_mesh.cpp @@ -196,7 +196,7 @@ u16 getFaceLight(MapNode n, MapNode n2, v3s16 face_dir, INodeDefManager *ndef) Both light banks */ static u16 getSmoothLightCombined(const v3s16 &p, - const std::array &dirs, MeshMakeData *data, bool node_solid) + const std::array &dirs, MeshMakeData *data) { INodeDefManager *ndef = data->m_client->ndef(); @@ -206,8 +206,14 @@ static u16 getSmoothLightCombined(const v3s16 &p, u16 light_day = 0; u16 light_night = 0; - auto add_node = [&] (int i) -> const ContentFeatures& { + auto add_node = [&] (u8 i, bool obstructed = false) -> bool { + if (obstructed) { + ambient_occlusion++; + return false; + } MapNode n = data->m_vmanip.getNodeNoExNoEmerge(p + dirs[i]); + if (n.getContent() == CONTENT_IGNORE) + return true; const ContentFeatures &f = ndef->get(n); if (f.light_source > light_source_max) light_source_max = f.light_source; @@ -219,37 +225,24 @@ static u16 getSmoothLightCombined(const v3s16 &p, } else { ambient_occlusion++; } - return f; + return f.light_propagates; }; - if (node_solid) { - ambient_occlusion = 3; - bool corner_obstructed = true; - for (int i = 0; i < 2; ++i) { - if (add_node(i).light_propagates) - corner_obstructed = false; - } - add_node(2); - add_node(3); - if (corner_obstructed) - ambient_occlusion++; - else - add_node(4); - } else { - std::array obstructed = {{ 1, 1, 1, 1 }}; - add_node(0); - bool opaque1 = !add_node(1).light_propagates; - bool opaque2 = !add_node(2).light_propagates; - bool opaque3 = !add_node(3).light_propagates; - obstructed[0] = opaque1 && opaque2; - obstructed[1] = opaque1 && opaque3; - obstructed[2] = opaque2 && opaque3; - for (int k = 0; k < 4; ++k) { - if (obstructed[k]) - ambient_occlusion++; - else if (add_node(k + 4).light_propagates) - obstructed[3] = false; - } + std::array obstructed = {{ 1, 1, 1, 1 }}; + add_node(0); + bool opaque1 = !add_node(1); + bool opaque2 = !add_node(2); + bool opaque3 = !add_node(3); + obstructed[0] = opaque1 && opaque2; + obstructed[1] = opaque1 && opaque3; + obstructed[2] = opaque2 && opaque3; + for (u8 k = 0; k < 3; ++k) + if (add_node(k + 4, obstructed[k])) + obstructed[3] = false; + if (add_node(7, obstructed[3])) { // wrap light around nodes + ambient_occlusion -= 3; + for (u8 k = 0; k < 3; ++k) + add_node(k + 4, !obstructed[k]); } if (light_count == 0) { @@ -277,7 +270,7 @@ static u16 getSmoothLightCombined(const v3s16 &p, g_settings->getFloat("ambient_occlusion_gamma"), 0.25, 4.0); // Table of gamma space multiply factors. - static const float light_amount[3] = { + static thread_local const float light_amount[3] = { powf(0.75, 1.0 / ao_gamma), powf(0.5, 1.0 / ao_gamma), powf(0.25, 1.0 / ao_gamma) @@ -304,43 +297,7 @@ static u16 getSmoothLightCombined(const v3s16 &p, */ u16 getSmoothLightSolid(const v3s16 &p, const v3s16 &face_dir, const v3s16 &corner, MeshMakeData *data) { - v3s16 neighbor_offset1, neighbor_offset2; - - /* - * face_dir, neighbor_offset1 and neighbor_offset2 define an - * orthonormal basis which is used to define the offsets of the 8 - * surrounding nodes and to differentiate the "distance" (by going only - * along directly neighboring nodes) relative to the node at p. - * Apart from the node at p, only the 4 nodes which contain face_dir - * can contribute light. - */ - if (face_dir.X != 0) { - neighbor_offset1 = v3s16(0, corner.Y, 0); - neighbor_offset2 = v3s16(0, 0, corner.Z); - } else if (face_dir.Y != 0) { - neighbor_offset1 = v3s16(0, 0, corner.Z); - neighbor_offset2 = v3s16(corner.X, 0, 0); - } else if (face_dir.Z != 0) { - neighbor_offset1 = v3s16(corner.X,0,0); - neighbor_offset2 = v3s16(0,corner.Y,0); - } - - const std::array dirs = {{ - // Always shine light - neighbor_offset1 + face_dir, - neighbor_offset2 + face_dir, - v3s16(0,0,0), - face_dir, - - // Can be obstructed - neighbor_offset1 + neighbor_offset2 + face_dir, - - // Do not shine light, only for ambient occlusion - neighbor_offset1, - neighbor_offset2, - neighbor_offset1 + neighbor_offset2 - }}; - return getSmoothLightCombined(p, dirs, data, true); + return getSmoothLightTransparent(p + face_dir, corner - 2 * face_dir, data); } /* @@ -363,7 +320,7 @@ u16 getSmoothLightTransparent(const v3s16 &p, const v3s16 &corner, MeshMakeData v3s16(0,corner.Y,corner.Z), v3s16(corner.X,corner.Y,corner.Z) }}; - return getSmoothLightCombined(p, dirs, data, false); + return getSmoothLightCombined(p, dirs, data); } void get_sunlight_color(video::SColorf *sunlight, u32 daynight_ratio){ @@ -466,6 +423,31 @@ static void getNodeVertexDirs(v3s16 dir, v3s16 *vertex_dirs) } } +static void getNodeTextureCoords(v3f base, const v3f &scale, v3s16 dir, float *u, float *v) +{ + if (dir.X > 0 || dir.Y > 0 || dir.Z < 0) + base -= scale; + if (dir == v3s16(0,0,1)) { + *u = -base.X - 1; + *v = -base.Y - 1; + } else if (dir == v3s16(0,0,-1)) { + *u = base.X + 1; + *v = -base.Y - 2; + } else if (dir == v3s16(1,0,0)) { + *u = base.Z + 1; + *v = -base.Y - 2; + } else if (dir == v3s16(-1,0,0)) { + *u = -base.Z - 1; + *v = -base.Y - 1; + } else if (dir == v3s16(0,1,0)) { + *u = base.X + 1; + *v = -base.Z - 2; + } else if (dir == v3s16(0,-1,0)) { + *u = base.X; + *v = base.Z; + } +} + struct FastFace { TileLayer layer; @@ -477,10 +459,11 @@ struct FastFace */ bool vertex_0_2_connected; u8 layernum; + bool world_aligned; }; static void makeFastFace(const TileSpec &tile, u16 li0, u16 li1, u16 li2, u16 li3, - const v3f &p, v3s16 dir, v3f scale, std::vector &dest) + v3f tp, v3f p, v3s16 dir, v3f scale, std::vector &dest) { // Position is at the center of the cube. v3f pos = p * BS; @@ -493,6 +476,8 @@ static void makeFastFace(const TileSpec &tile, u16 li0, u16 li1, u16 li2, u16 li v3f vertex_pos[4]; v3s16 vertex_dirs[4]; getNodeVertexDirs(dir, vertex_dirs); + if (tile.world_aligned) + getNodeTextureCoords(tp, scale, dir, &x0, &y0); v3s16 t; u16 t1; @@ -671,6 +656,8 @@ static void makeFastFace(const TileSpec &tile, u16 li0, u16 li1, u16 li2, u16 li face.layer = *layer; face.layernum = layernum; + + face.world_aligned = tile.world_aligned; } } @@ -806,7 +793,7 @@ void getNodeTile(MapNode mn, v3s16 p, v3s16 dir, MeshMakeData *data, TileSpec &t }; u16 tile_index = facedir * 16 + dir_i; getNodeTileN(mn, p, dir_to_tile[tile_index], data, tile); - tile.rotation = dir_to_tile[tile_index + 1]; + tile.rotation = tile.world_aligned ? 0 : dir_to_tile[tile_index + 1]; } static void getTileInfo( @@ -965,7 +952,7 @@ static void updateFastFaceRow( scale.Z = continuous_tiles_count; makeFastFace(tile, lights[0], lights[1], lights[2], lights[3], - sp, face_dir_corrected, scale, dest); + pf, sp, face_dir_corrected, scale, dest); g_profiler->avg("Meshgen: faces drawn by tiling", 0); for (int i = 1; i < continuous_tiles_count; i++) @@ -1092,7 +1079,7 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset): f.vertex_0_2_connected ? indices : indices_alternate; collector.append(f.layer, f.vertices, 4, indices_p, 6, - f.layernum); + f.layernum, f.world_aligned); } } @@ -1128,6 +1115,9 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset): os << m_tsrc->getTextureName(p.layer.texture_id) << "^[crack"; if (p.layer.material_flags & MATERIAL_FLAG_CRACK_OVERLAY) os << "o"; // use ^[cracko + u8 tiles = p.layer.scale; + if (tiles > 1) + os << ":" << (u32)tiles; os << ":" << (u32)p.layer.animation_frame_count << ":"; m_crack_materials.insert(std::make_pair( std::pair(layer, i), os.str())); @@ -1392,13 +1382,15 @@ void MeshCollector::append(const TileSpec &tile, const TileLayer *layer = &tile.layers[layernum]; if (layer->texture_id == 0) continue; - append(*layer, vertices, numVertices, indices, numIndices, layernum); + append(*layer, vertices, numVertices, indices, numIndices, + layernum, tile.world_aligned); } } void MeshCollector::append(const TileLayer &layer, const video::S3DVertex *vertices, u32 numVertices, - const u16 *indices, u32 numIndices, u8 layernum) + const u16 *indices, u32 numIndices, u8 layernum, + bool use_scale) { if (numIndices > 65535) { dstream << "FIXME: MeshCollector::append() called with numIndices=" @@ -1422,20 +1414,24 @@ void MeshCollector::append(const TileLayer &layer, p = &(*buffers)[buffers->size() - 1]; } + f32 scale = 1.0; + if (use_scale) + scale = 1.0 / layer.scale; + u32 vertex_count; if (m_use_tangent_vertices) { vertex_count = p->tangent_vertices.size(); for (u32 i = 0; i < numVertices; i++) { video::S3DVertexTangents vert(vertices[i].Pos, vertices[i].Normal, - vertices[i].Color, vertices[i].TCoords); + vertices[i].Color, scale * vertices[i].TCoords); p->tangent_vertices.push_back(vert); } } else { vertex_count = p->vertices.size(); for (u32 i = 0; i < numVertices; i++) { video::S3DVertex vert(vertices[i].Pos, vertices[i].Normal, - vertices[i].Color, vertices[i].TCoords); + vertices[i].Color, scale * vertices[i].TCoords); p->vertices.push_back(vert); } @@ -1461,14 +1457,15 @@ void MeshCollector::append(const TileSpec &tile, if (layer->texture_id == 0) continue; append(*layer, vertices, numVertices, indices, numIndices, pos, - c, light_source, layernum); + c, light_source, layernum, tile.world_aligned); } } void MeshCollector::append(const TileLayer &layer, const video::S3DVertex *vertices, u32 numVertices, const u16 *indices, u32 numIndices, - v3f pos, video::SColor c, u8 light_source, u8 layernum) + v3f pos, video::SColor c, u8 light_source, u8 layernum, + bool use_scale) { if (numIndices > 65535) { dstream << "FIXME: MeshCollector::append() called with numIndices=" @@ -1492,6 +1489,10 @@ void MeshCollector::append(const TileLayer &layer, p = &(*buffers)[buffers->size() - 1]; } + f32 scale = 1.0; + if (use_scale) + scale = 1.0 / layer.scale; + video::SColor original_c = c; u32 vertex_count; if (m_use_tangent_vertices) { @@ -1502,7 +1503,7 @@ void MeshCollector::append(const TileLayer &layer, applyFacesShading(c, vertices[i].Normal); } video::S3DVertexTangents vert(vertices[i].Pos + pos, - vertices[i].Normal, c, vertices[i].TCoords); + vertices[i].Normal, c, scale * vertices[i].TCoords); p->tangent_vertices.push_back(vert); } } else { @@ -1513,7 +1514,7 @@ void MeshCollector::append(const TileLayer &layer, applyFacesShading(c, vertices[i].Normal); } video::S3DVertex vert(vertices[i].Pos + pos, vertices[i].Normal, c, - vertices[i].TCoords); + scale * vertices[i].TCoords); p->vertices.push_back(vert); } }