X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fcontent_mapblock.cpp;h=0c96c568f7b5d2cf1c84935efb798a3f1a37bec4;hb=3f58028d3198e77ce26d09680f0a637188610871;hp=4c28fe3c60866bb971439b2764deaf4e3b778635;hpb=8bfa56648d42d1ad264b9754ea00d336c8ee471c;p=dragonfireclient.git diff --git a/src/content_mapblock.cpp b/src/content_mapblock.cpp index 4c28fe3c6..0c96c568f 100644 --- a/src/content_mapblock.cpp +++ b/src/content_mapblock.cpp @@ -21,6 +21,8 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "content_mapnode.h" #include "main.h" // For g_settings and g_texturesource #include "mineral.h" +#include "mapblock_mesh.h" // For MapBlock_LightColor() +#include "settings.h" #ifndef SERVER // Create a cuboid. @@ -127,28 +129,17 @@ void mapblock_mesh_generate_special(MeshMakeData *data, /* Some settings */ - bool new_style_water = g_settings.getBool("new_style_water"); - bool new_style_leaves = g_settings.getBool("new_style_leaves"); - //bool smooth_lighting = g_settings.getBool("smooth_lighting"); - bool invisible_stone = g_settings.getBool("invisible_stone"); + bool new_style_water = g_settings->getBool("new_style_water"); + bool new_style_leaves = g_settings->getBool("new_style_leaves"); + //bool smooth_lighting = g_settings->getBool("smooth_lighting"); + bool invisible_stone = g_settings->getBool("invisible_stone"); - float node_water_level = 1.0; + float node_liquid_level = 1.0; if(new_style_water) - node_water_level = 0.85; + node_liquid_level = 0.85; v3s16 blockpos_nodes = data->m_blockpos*MAP_BLOCKSIZE; - // Flowing water material - video::SMaterial material_water1; - material_water1.setFlag(video::EMF_LIGHTING, false); - material_water1.setFlag(video::EMF_BACK_FACE_CULLING, false); - material_water1.setFlag(video::EMF_BILINEAR_FILTER, false); - material_water1.setFlag(video::EMF_FOG_ENABLE, true); - material_water1.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA; - AtlasPointer pa_water1 = g_texturesource->getTexture( - g_texturesource->getTextureId("water.png")); - material_water1.setTexture(0, pa_water1.atlas); - // New-style leaves material video::SMaterial material_leaves1; material_leaves1.setFlag(video::EMF_LIGHTING, false); @@ -198,6 +189,39 @@ void mapblock_mesh_generate_special(MeshMakeData *data, AtlasPointer pa_papyrus = g_texturesource->getTexture( g_texturesource->getTextureId("papyrus.png")); material_papyrus.setTexture(0, pa_papyrus.atlas); + + // Apple material + video::SMaterial material_apple; + material_apple.setFlag(video::EMF_LIGHTING, false); + material_apple.setFlag(video::EMF_BILINEAR_FILTER, false); + material_apple.setFlag(video::EMF_FOG_ENABLE, true); + material_apple.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; + AtlasPointer pa_apple = g_texturesource->getTexture( + g_texturesource->getTextureId("apple.png")); + material_apple.setTexture(0, pa_apple.atlas); + + + // Sapling material + video::SMaterial material_sapling; + material_sapling.setFlag(video::EMF_LIGHTING, false); + material_sapling.setFlag(video::EMF_BILINEAR_FILTER, false); + material_sapling.setFlag(video::EMF_FOG_ENABLE, true); + material_sapling.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; + AtlasPointer pa_sapling = g_texturesource->getTexture( + g_texturesource->getTextureId("sapling.png")); + material_sapling.setTexture(0, pa_sapling.atlas); + + + // junglegrass material + video::SMaterial material_junglegrass; + material_junglegrass.setFlag(video::EMF_LIGHTING, false); + material_junglegrass.setFlag(video::EMF_BILINEAR_FILTER, false); + material_junglegrass.setFlag(video::EMF_FOG_ENABLE, true); + material_junglegrass.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; + AtlasPointer pa_junglegrass = g_texturesource->getTexture( + g_texturesource->getTextureId("junglegrass.png")); + material_junglegrass.setTexture(0, pa_junglegrass.atlas); + for(s16 z=0; zm_daynight_ratio)); - video::SColor c(255,l,l,l); + video::SColor c = MapBlock_LightColor(255, l); float d = (float)BS/16; // Wall at X+ of node @@ -287,7 +311,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data, video::S3DVertex(BS/2-d,BS/2,-BS/2, 0,0,0, c, 0,0), }; - v3s16 dir = unpackDir(n.dir); + v3s16 dir = unpackDir(n.param2); for(s32 i=0; i<4; i++) { @@ -325,30 +349,40 @@ void mapblock_mesh_generate_special(MeshMakeData *data, collector.append(material, vertices, 4, indices, 6); } /* - Add flowing water to mesh + Add flowing liquid to mesh */ - else if(n.d == CONTENT_WATER) + else if(content_features(n).liquid_type == LIQUID_FLOWING) { - bool top_is_water = false; + assert(content_features(n).special_material); + video::SMaterial &liquid_material = + *content_features(n).special_material; + assert(content_features(n).special_atlas); + AtlasPointer &pa_liquid1 = + *content_features(n).special_atlas; + + bool top_is_same_liquid = false; MapNode ntop = data->m_vmanip.getNodeNoEx(blockpos_nodes + v3s16(x,y+1,z)); - if(ntop.d == CONTENT_WATER || ntop.d == CONTENT_WATERSOURCE) - top_is_water = true; + content_t c_flowing = content_features(n).liquid_alternative_flowing; + content_t c_source = content_features(n).liquid_alternative_source; + if(ntop.getContent() == c_flowing || ntop.getContent() == c_source) + top_is_same_liquid = true; u8 l = 0; // Use the light of the node on top if possible - if(content_features(ntop.d).param_type == CPT_LIGHT) + if(content_features(ntop).param_type == CPT_LIGHT) l = decode_light(ntop.getLightBlend(data->m_daynight_ratio)); - // Otherwise use the light of this node (the water) + // Otherwise use the light of this node (the liquid) else l = decode_light(n.getLightBlend(data->m_daynight_ratio)); - video::SColor c(WATER_ALPHA,l,l,l); + video::SColor c = MapBlock_LightColor( + content_features(n).vertex_alpha, l); - // Neighbor water levels (key = relative position) + // Neighbor liquid levels (key = relative position) // Includes current node core::map neighbor_levels; - core::map neighbor_contents; + core::map neighbor_contents; core::map neighbor_flags; - const u8 neighborflag_top_is_water = 0x01; + const u8 neighborflag_top_is_same_liquid = 0x01; v3s16 neighbor_dirs[9] = { v3s16(0,0,0), v3s16(0,0,1), @@ -362,29 +396,30 @@ void mapblock_mesh_generate_special(MeshMakeData *data, }; for(u32 i=0; i<9; i++) { - u8 content = CONTENT_AIR; + content_t content = CONTENT_AIR; float level = -0.5 * BS; u8 flags = 0; // Check neighbor v3s16 p2 = p + neighbor_dirs[i]; MapNode n2 = data->m_vmanip.getNodeNoEx(blockpos_nodes + p2); - if(n2.d != CONTENT_IGNORE) + if(n2.getContent() != CONTENT_IGNORE) { - content = n2.d; + content = n2.getContent(); - if(n2.d == CONTENT_WATERSOURCE) - level = (-0.5+node_water_level) * BS; - else if(n2.d == CONTENT_WATER) - level = (-0.5 + ((float)n2.param2 + 0.5) / 8.0 - * node_water_level) * BS; + if(n2.getContent() == c_source) + level = (-0.5+node_liquid_level) * BS; + else if(n2.getContent() == c_flowing) + level = (-0.5 + ((float)(n2.param2&LIQUID_LEVEL_MASK) + + 0.5) / 8.0 * node_liquid_level) * BS; // Check node above neighbor. // NOTE: This doesn't get executed if neighbor // doesn't exist p2.Y += 1; n2 = data->m_vmanip.getNodeNoEx(blockpos_nodes + p2); - if(n2.d == CONTENT_WATERSOURCE || n2.d == CONTENT_WATER) - flags |= neighborflag_top_is_water; + if(n2.getContent() == c_source || + n2.getContent() == c_flowing) + flags |= neighborflag_top_is_same_liquid; } neighbor_levels.insert(neighbor_dirs[i], level); @@ -392,10 +427,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data, neighbor_flags.insert(neighbor_dirs[i], flags); } - //float water_level = (-0.5 + ((float)n.param2 + 0.5) / 8.0) * BS; - //float water_level = neighbor_levels[v3s16(0,0,0)]; - - // Corner heights (average between four waters) + // Corner heights (average between four liquids) f32 corner_levels[4]; v3s16 halfdirs[4] = { @@ -409,29 +441,40 @@ void mapblock_mesh_generate_special(MeshMakeData *data, v3s16 cornerdir = halfdirs[i]; float cornerlevel = 0; u32 valid_count = 0; + u32 air_count = 0; for(u32 j=0; j<4; j++) { v3s16 neighbordir = cornerdir - halfdirs[j]; - u8 content = neighbor_contents[neighbordir]; - // Special case for source nodes - if(content == CONTENT_WATERSOURCE) + content_t content = neighbor_contents[neighbordir]; + // If top is liquid, draw starting from top of node + if(neighbor_flags[neighbordir] & + neighborflag_top_is_same_liquid) + { + cornerlevel = 0.5*BS; + valid_count = 1; + break; + } + // Source is always the same height + else if(content == c_source) { - cornerlevel = (-0.5+node_water_level)*BS; + cornerlevel = (-0.5+node_liquid_level)*BS; valid_count = 1; break; } - else if(content == CONTENT_WATER) + // Flowing liquid has level information + else if(content == c_flowing) { cornerlevel += neighbor_levels[neighbordir]; valid_count++; } else if(content == CONTENT_AIR) { - cornerlevel += -0.5*BS; - valid_count++; + air_count++; } } - if(valid_count > 0) + if(air_count >= 2) + cornerlevel = -0.5*BS; + else if(valid_count > 0) cornerlevel /= valid_count; corner_levels[i] = cornerlevel; } @@ -457,24 +500,27 @@ void mapblock_mesh_generate_special(MeshMakeData *data, v3s16 dir = side_dirs[i]; /* - If our topside is water and neighbor's topside - is water, don't draw side face + If our topside is liquid and neighbor's topside + is liquid, don't draw side face */ - if(top_is_water && - neighbor_flags[dir] & neighborflag_top_is_water) + if(top_is_same_liquid && + neighbor_flags[dir] & neighborflag_top_is_same_liquid) continue; - u8 neighbor_content = neighbor_contents[dir]; + content_t neighbor_content = neighbor_contents[dir]; - // Don't draw face if neighbor is not air or water + // Don't draw face if neighbor is not air or liquid if(neighbor_content != CONTENT_AIR - && neighbor_content != CONTENT_WATER) + && content_liquid(neighbor_content) == false) continue; - bool neighbor_is_water = (neighbor_content == CONTENT_WATER); + bool neighbor_is_same_liquid = (neighbor_content == c_source + || neighbor_content == c_flowing); - // Don't draw any faces if neighbor is water and top is water - if(neighbor_is_water == true && top_is_water == false) + // Don't draw any faces if neighbor same is liquid and top is + // same liquid + if(neighbor_is_same_liquid == true + && top_is_same_liquid == false) continue; video::S3DVertex vertices[4] = @@ -484,20 +530,20 @@ void mapblock_mesh_generate_special(MeshMakeData *data, video::S3DVertex(BS/2,0,BS/2, 0,0,0, c, 1,0), video::S3DVertex(-BS/2,0,BS/2, 0,0,0, c, 0,0),*/ video::S3DVertex(-BS/2,0,BS/2, 0,0,0, c, - pa_water1.x0(), pa_water1.y1()), + pa_liquid1.x0(), pa_liquid1.y1()), video::S3DVertex(BS/2,0,BS/2, 0,0,0, c, - pa_water1.x1(), pa_water1.y1()), + pa_liquid1.x1(), pa_liquid1.y1()), video::S3DVertex(BS/2,0,BS/2, 0,0,0, c, - pa_water1.x1(), pa_water1.y0()), + pa_liquid1.x1(), pa_liquid1.y0()), video::S3DVertex(-BS/2,0,BS/2, 0,0,0, c, - pa_water1.x0(), pa_water1.y0()), + pa_liquid1.x0(), pa_liquid1.y0()), }; /* - If our topside is water, set upper border of face + If our topside is liquid, set upper border of face at upper border of node */ - if(top_is_water) + if(top_is_same_liquid) { vertices[2].Pos.Y = 0.5*BS; vertices[3].Pos.Y = 0.5*BS; @@ -512,16 +558,16 @@ void mapblock_mesh_generate_special(MeshMakeData *data, } /* - If neighbor is water, lower border of face is corner - water levels + If neighbor is liquid, lower border of face is corner + liquid levels */ - if(neighbor_is_water) + if(neighbor_is_same_liquid) { vertices[0].Pos.Y = corner_levels[side_corners[i][1]]; vertices[1].Pos.Y = corner_levels[side_corners[i][0]]; } /* - If neighbor is not water, lower border of face is + If neighbor is not liquid, lower border of face is lower border of node */ else @@ -540,20 +586,27 @@ void mapblock_mesh_generate_special(MeshMakeData *data, vertices[j].Pos.rotateXZBy(90); if(dir == v3s16(1,0,-0)) vertices[j].Pos.rotateXZBy(-90); + + // Do this to not cause glitches when two liquids are + // side-by-side + if(neighbor_is_same_liquid == false){ + vertices[j].Pos.X *= 0.98; + vertices[j].Pos.Z *= 0.98; + } vertices[j].Pos += intToFloat(p + blockpos_nodes, BS); } u16 indices[] = {0,1,2,2,3,0}; // Add to mesh collector - collector.append(material_water1, vertices, 4, indices, 6); + collector.append(liquid_material, vertices, 4, indices, 6); } /* Generate top side, if appropriate */ - if(top_is_water == false) + if(top_is_same_liquid == false) { video::S3DVertex vertices[4] = { @@ -562,13 +615,13 @@ void mapblock_mesh_generate_special(MeshMakeData *data, video::S3DVertex(BS/2,0,BS/2, 0,0,0, c, 1,0), video::S3DVertex(-BS/2,0,BS/2, 0,0,0, c, 0,0),*/ video::S3DVertex(-BS/2,0,BS/2, 0,0,0, c, - pa_water1.x0(), pa_water1.y1()), + pa_liquid1.x0(), pa_liquid1.y1()), video::S3DVertex(BS/2,0,BS/2, 0,0,0, c, - pa_water1.x1(), pa_water1.y1()), + pa_liquid1.x1(), pa_liquid1.y1()), video::S3DVertex(BS/2,0,-BS/2, 0,0,0, c, - pa_water1.x1(), pa_water1.y0()), + pa_liquid1.x1(), pa_liquid1.y0()), video::S3DVertex(-BS/2,0,-BS/2, 0,0,0, c, - pa_water1.x0(), pa_water1.y0()), + pa_liquid1.x0(), pa_liquid1.y0()), }; // This fixes a strange bug @@ -576,7 +629,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data, for(s32 i=0; i<4; i++) { - //vertices[i].Pos.Y += water_level; + //vertices[i].Pos.Y += liquid_level; //vertices[i].Pos.Y += neighbor_levels[v3s16(0,0,0)]; s32 j = corner_resolve[i]; vertices[i].Pos.Y += corner_levels[j]; @@ -585,29 +638,33 @@ void mapblock_mesh_generate_special(MeshMakeData *data, u16 indices[] = {0,1,2,2,3,0}; // Add to mesh collector - collector.append(material_water1, vertices, 4, indices, 6); + collector.append(liquid_material, vertices, 4, indices, 6); } } /* Add water sources to mesh if using new style */ - else if(n.d == CONTENT_WATERSOURCE && new_style_water) + else if(content_features(n).liquid_type == LIQUID_SOURCE + && new_style_water) { - //bool top_is_water = false; + assert(content_features(n).special_material); + video::SMaterial &liquid_material = + *content_features(n).special_material; + assert(content_features(n).special_atlas); + AtlasPointer &pa_liquid1 = + *content_features(n).special_atlas; + bool top_is_air = false; MapNode n = data->m_vmanip.getNodeNoEx(blockpos_nodes + v3s16(x,y+1,z)); - /*if(n.d == CONTENT_WATER || n.d == CONTENT_WATERSOURCE) - top_is_water = true;*/ - if(n.d == CONTENT_AIR) + if(n.getContent() == CONTENT_AIR) top_is_air = true; - /*if(top_is_water == true) - continue;*/ if(top_is_air == false) continue; u8 l = decode_light(n.getLightBlend(data->m_daynight_ratio)); - video::SColor c(WATER_ALPHA,l,l,l); + video::SColor c = MapBlock_LightColor( + content_features(n).vertex_alpha, l); video::S3DVertex vertices[4] = { @@ -616,33 +673,33 @@ void mapblock_mesh_generate_special(MeshMakeData *data, video::S3DVertex(BS/2,0,BS/2, 0,0,0, c, 1,0), video::S3DVertex(-BS/2,0,BS/2, 0,0,0, c, 0,0),*/ video::S3DVertex(-BS/2,0,BS/2, 0,0,0, c, - pa_water1.x0(), pa_water1.y1()), + pa_liquid1.x0(), pa_liquid1.y1()), video::S3DVertex(BS/2,0,BS/2, 0,0,0, c, - pa_water1.x1(), pa_water1.y1()), + pa_liquid1.x1(), pa_liquid1.y1()), video::S3DVertex(BS/2,0,-BS/2, 0,0,0, c, - pa_water1.x1(), pa_water1.y0()), + pa_liquid1.x1(), pa_liquid1.y0()), video::S3DVertex(-BS/2,0,-BS/2, 0,0,0, c, - pa_water1.x0(), pa_water1.y0()), + pa_liquid1.x0(), pa_liquid1.y0()), }; for(s32 i=0; i<4; i++) { - vertices[i].Pos.Y += (-0.5+node_water_level)*BS; + vertices[i].Pos.Y += (-0.5+node_liquid_level)*BS; vertices[i].Pos += intToFloat(p + blockpos_nodes, BS); } u16 indices[] = {0,1,2,2,3,0}; // Add to mesh collector - collector.append(material_water1, vertices, 4, indices, 6); + collector.append(liquid_material, vertices, 4, indices, 6); } /* Add leaves if using new style */ - else if(n.d == CONTENT_LEAVES && new_style_leaves) + else if(n.getContent() == CONTENT_LEAVES && new_style_leaves) { /*u8 l = decode_light(n.getLightBlend(data->m_daynight_ratio));*/ u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio))); - video::SColor c(255,l,l,l); + video::SColor c = MapBlock_LightColor(255, l); for(u32 j=0; j<6; j++) { @@ -706,10 +763,10 @@ void mapblock_mesh_generate_special(MeshMakeData *data, /* Add glass */ - else if(n.d == CONTENT_GLASS) + else if(n.getContent() == CONTENT_GLASS) { u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio))); - video::SColor c(255,l,l,l); + video::SColor c = MapBlock_LightColor(255, l); for(u32 j=0; j<6; j++) { @@ -769,10 +826,10 @@ void mapblock_mesh_generate_special(MeshMakeData *data, /* Add fence */ - else if(n.d == CONTENT_FENCE) + else if(n.getContent() == CONTENT_FENCE) { u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio))); - video::SColor c(255,l,l,l); + video::SColor c = MapBlock_LightColor(255, l); const f32 post_rad=(f32)BS/10; const f32 bar_rad=(f32)BS/20; @@ -795,7 +852,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data, v3s16 p2 = p; p2.X++; MapNode n2 = data->m_vmanip.getNodeNoEx(blockpos_nodes + p2); - if(n2.d == CONTENT_FENCE) + if(n2.getContent() == CONTENT_FENCE) { pos = intToFloat(p+blockpos_nodes, BS); pos.X += BS/2; @@ -821,7 +878,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data, p2 = p; p2.Z++; n2 = data->m_vmanip.getNodeNoEx(blockpos_nodes + p2); - if(n2.d == CONTENT_FENCE) + if(n2.getContent() == CONTENT_FENCE) { pos = intToFloat(p+blockpos_nodes, BS); pos.Z += BS/2; @@ -848,7 +905,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data, /* Add stones with minerals if stone is invisible */ - else if(n.d == CONTENT_STONE && invisible_stone && n.getMineral() != MINERAL_NONE) + else if(n.getContent() == CONTENT_STONE && invisible_stone && n.getMineral() != MINERAL_NONE) { for(u32 j=0; j<6; j++) { @@ -856,19 +913,20 @@ void mapblock_mesh_generate_special(MeshMakeData *data, v3s16 dir = g_6dirs[j]; /*u8 l = 0; MapNode n2 = data->m_vmanip.getNodeNoEx(blockpos_nodes + dir); - if(content_features(n2.d).param_type == CPT_LIGHT) + if(content_features(n2).param_type == CPT_LIGHT) l = decode_light(n2.getLightBlend(data->m_daynight_ratio)); else l = 255;*/ u8 l = 255; - video::SColor c(255,l,l,l); + video::SColor c = MapBlock_LightColor(255, l); // Get the right texture TileSpec ts = n.getTile(dir); AtlasPointer ap = ts.texture; material_general.setTexture(0, ap.atlas); + video::S3DVertex vertices[4] = - { + { /*video::S3DVertex(-BS/2,-BS/2,BS/2, 0,0,0, c, 0,1), video::S3DVertex(BS/2,-BS/2,BS/2, 0,0,0, c, 1,1), video::S3DVertex(BS/2,BS/2,BS/2, 0,0,0, c, 1,0), @@ -916,10 +974,10 @@ void mapblock_mesh_generate_special(MeshMakeData *data, } } #endif - else if(n.d == CONTENT_PAPYRUS) + else if(n.getContent() == CONTENT_PAPYRUS) { u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio))); - video::SColor c(255,l,l,l); + video::SColor c = MapBlock_LightColor(255, l); for(u32 j=0; j<4; j++) { @@ -966,10 +1024,61 @@ void mapblock_mesh_generate_special(MeshMakeData *data, collector.append(material_papyrus, vertices, 4, indices, 6); } } - else if(n.d == CONTENT_RAIL) + else if(n.getContent() == CONTENT_JUNGLEGRASS) + { + u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio))); + video::SColor c = MapBlock_LightColor(255, l); + + for(u32 j=0; j<4; j++) + { + video::S3DVertex vertices[4] = + { + video::S3DVertex(-BS/2,-BS/2,0, 0,0,0, c, + pa_papyrus.x0(), pa_papyrus.y1()), + video::S3DVertex(BS/2,-BS/2,0, 0,0,0, c, + pa_papyrus.x1(), pa_papyrus.y1()), + video::S3DVertex(BS/2,BS/1,0, 0,0,0, c, + pa_papyrus.x1(), pa_papyrus.y0()), + video::S3DVertex(-BS/2,BS/1,0, 0,0,0, c, + pa_papyrus.x0(), pa_papyrus.y0()), + }; + + if(j == 0) + { + for(u16 i=0; i<4; i++) + vertices[i].Pos.rotateXZBy(45); + } + else if(j == 1) + { + for(u16 i=0; i<4; i++) + vertices[i].Pos.rotateXZBy(-45); + } + else if(j == 2) + { + for(u16 i=0; i<4; i++) + vertices[i].Pos.rotateXZBy(135); + } + else if(j == 3) + { + for(u16 i=0; i<4; i++) + vertices[i].Pos.rotateXZBy(-135); + } + + for(u16 i=0; i<4; i++) + { + vertices[i].Pos *= 1.3; + vertices[i].Pos += intToFloat(p + blockpos_nodes, BS); + } + + u16 indices[] = {0,1,2,2,3,0}; + // Add to mesh collector + collector.append(material_junglegrass, vertices, 4, indices, 6); + } + } + else if(n.getContent() == CONTENT_RAIL) { u8 l = decode_light(n.getLightBlend(data->m_daynight_ratio)); - video::SColor c(255,l,l,l); + video::SColor c = MapBlock_LightColor(255, l); bool is_rail_x [] = { false, false }; /* x-1, x+1 */ bool is_rail_z [] = { false, false }; /* z-1, z+1 */ @@ -979,13 +1088,13 @@ void mapblock_mesh_generate_special(MeshMakeData *data, MapNode n_minus_z = data->m_vmanip.getNodeNoEx(blockpos_nodes + v3s16(x,y,z-1)); MapNode n_plus_z = data->m_vmanip.getNodeNoEx(blockpos_nodes + v3s16(x,y,z+1)); - if(n_minus_x.d == CONTENT_RAIL) + if(n_minus_x.getContent() == CONTENT_RAIL) is_rail_x[0] = true; - if(n_plus_x.d == CONTENT_RAIL) + if(n_plus_x.getContent() == CONTENT_RAIL) is_rail_x[1] = true; - if(n_minus_z.d == CONTENT_RAIL) + if(n_minus_z.getContent() == CONTENT_RAIL) is_rail_z[0] = true; - if(n_plus_z.d == CONTENT_RAIL) + if(n_plus_z.getContent() == CONTENT_RAIL) is_rail_z[1] = true; float d = (float)BS/16; @@ -1070,6 +1179,152 @@ void mapblock_mesh_generate_special(MeshMakeData *data, u16 indices[] = {0,1,2,2,3,0}; collector.append(material_rail, vertices, 4, indices, 6); } + else if (n.getContent() == CONTENT_LADDER) { + u8 l = decode_light(n.getLightBlend(data->m_daynight_ratio)); + video::SColor c(255,l,l,l); + + float d = (float)BS/16; + + // Assume wall is at X+ + video::S3DVertex vertices[4] = + { + video::S3DVertex(BS/2-d,-BS/2,-BS/2, 0,0,0, c, 0,1), + video::S3DVertex(BS/2-d,-BS/2,BS/2, 0,0,0, c, 1,1), + video::S3DVertex(BS/2-d,BS/2,BS/2, 0,0,0, c, 1,0), + video::S3DVertex(BS/2-d,BS/2,-BS/2, 0,0,0, c, 0,0), + }; + + v3s16 dir = unpackDir(n.param2); + + for(s32 i=0; i<4; i++) + { + if(dir == v3s16(1,0,0)) + vertices[i].Pos.rotateXZBy(0); + if(dir == v3s16(-1,0,0)) + vertices[i].Pos.rotateXZBy(180); + if(dir == v3s16(0,0,1)) + vertices[i].Pos.rotateXZBy(90); + if(dir == v3s16(0,0,-1)) + vertices[i].Pos.rotateXZBy(-90); + if(dir == v3s16(0,-1,0)) + vertices[i].Pos.rotateXYBy(-90); + if(dir == v3s16(0,1,0)) + vertices[i].Pos.rotateXYBy(90); + + vertices[i].Pos += intToFloat(p + blockpos_nodes, BS); + } + + video::SMaterial material_ladder; + material_ladder.setFlag(video::EMF_LIGHTING, false); + material_ladder.setFlag(video::EMF_BACK_FACE_CULLING, false); + material_ladder.setFlag(video::EMF_BILINEAR_FILTER, false); + material_ladder.setFlag(video::EMF_FOG_ENABLE, true); + material_ladder.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; + material_ladder.setTexture(0, g_texturesource->getTextureRaw("ladder.png")); + + u16 indices[] = {0,1,2,2,3,0}; + // Add to mesh collector + collector.append(material_ladder, vertices, 4, indices, 6); + } + else if(n.getContent() == CONTENT_APPLE) + { + u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio))); + video::SColor c = MapBlock_LightColor(255, l); + + for(u32 j=0; j<4; j++) + { + video::S3DVertex vertices[4] = + { + video::S3DVertex(-BS/2,-BS/2,0, 0,0,0, c, + pa_apple.x0(), pa_apple.y1()), + video::S3DVertex(BS/2,-BS/2,0, 0,0,0, c, + pa_apple.x1(), pa_apple.y1()), + video::S3DVertex(BS/2,BS/2,0, 0,0,0, c, + pa_apple.x1(), pa_apple.y0()), + video::S3DVertex(-BS/2,BS/2,0, 0,0,0, c, + pa_apple.x0(), pa_apple.y0()), + }; + + if(j == 0) + { + for(u16 i=0; i<4; i++) + vertices[i].Pos.rotateXZBy(45); + } + else if(j == 1) + { + for(u16 i=0; i<4; i++) + vertices[i].Pos.rotateXZBy(-45); + } + else if(j == 2) + { + for(u16 i=0; i<4; i++) + vertices[i].Pos.rotateXZBy(135); + } + else if(j == 3) + { + for(u16 i=0; i<4; i++) + vertices[i].Pos.rotateXZBy(-135); + } + + for(u16 i=0; i<4; i++) + { + vertices[i].Pos += intToFloat(p + blockpos_nodes, BS); + } + + u16 indices[] = {0,1,2,2,3,0}; + // Add to mesh collector + collector.append(material_apple, vertices, 4, indices, 6); + } + } + else if(n.getContent() == CONTENT_SAPLING) { + u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio))); + video::SColor c = MapBlock_LightColor(255, l); + + for(u32 j=0; j<4; j++) + { + video::S3DVertex vertices[4] = + { + video::S3DVertex(-BS/2,-BS/2,0, 0,0,0, c, + pa_sapling.x0(), pa_sapling.y1()), + video::S3DVertex(BS/2,-BS/2,0, 0,0,0, c, + pa_sapling.x1(), pa_sapling.y1()), + video::S3DVertex(BS/2,BS/1,0, 0,0,0, c, + pa_sapling.x1(), pa_sapling.y0()), + video::S3DVertex(-BS/2,BS/1,0, 0,0,0, c, + pa_sapling.x0(), pa_sapling.y0()), + }; + + if(j == 0) + { + for(u16 i=0; i<4; i++) + vertices[i].Pos.rotateXZBy(45); + } + else if(j == 1) + { + for(u16 i=0; i<4; i++) + vertices[i].Pos.rotateXZBy(-45); + } + else if(j == 2) + { + for(u16 i=0; i<4; i++) + vertices[i].Pos.rotateXZBy(135); + } + else if(j == 3) + { + for(u16 i=0; i<4; i++) + vertices[i].Pos.rotateXZBy(-135); + } + + for(u16 i=0; i<4; i++) + { + vertices[i].Pos += intToFloat(p + blockpos_nodes, BS); + } + + u16 indices[] = {0,1,2,2,3,0}; + // Add to mesh collector + collector.append(material_sapling, vertices, 4, indices, 6); + } + } } } #endif