Move updateTextures and fillTileAttribs to ContentFeatures
parent
423d8c1b0d
commit
725edc78b2
534
src/nodedef.cpp
534
src/nodedef.cpp
|
@ -247,6 +247,28 @@ static void deSerializeSimpleSoundSpec(SimpleSoundSpec &ss, std::istream &is)
|
||||||
ss.gain = readF1000(is);
|
ss.gain = readF1000(is);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TextureSettings::readSettings()
|
||||||
|
{
|
||||||
|
connected_glass = g_settings->getBool("connected_glass");
|
||||||
|
opaque_water = g_settings->getBool("opaque_water");
|
||||||
|
bool enable_shaders = g_settings->getBool("enable_shaders");
|
||||||
|
bool enable_bumpmapping = g_settings->getBool("enable_bumpmapping");
|
||||||
|
bool enable_parallax_occlusion = g_settings->getBool("enable_parallax_occlusion");
|
||||||
|
enable_mesh_cache = g_settings->getBool("enable_mesh_cache");
|
||||||
|
enable_minimap = g_settings->getBool("enable_minimap");
|
||||||
|
std::string leaves_style_str = g_settings->get("leaves_style");
|
||||||
|
|
||||||
|
use_normal_texture = enable_shaders &&
|
||||||
|
(enable_bumpmapping || enable_parallax_occlusion);
|
||||||
|
if (leaves_style_str == "fancy") {
|
||||||
|
leaves_style = LEAVES_FANCY;
|
||||||
|
} else if (leaves_style_str == "simple") {
|
||||||
|
leaves_style = LEAVES_SIMPLE;
|
||||||
|
} else {
|
||||||
|
leaves_style = LEAVES_OPAQUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
ContentFeatures
|
ContentFeatures
|
||||||
*/
|
*/
|
||||||
|
@ -486,6 +508,254 @@ void ContentFeatures::deSerialize(std::istream &is)
|
||||||
}catch(SerializationError &e) {};
|
}catch(SerializationError &e) {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef SERVER
|
||||||
|
void ContentFeatures::fillTileAttribs(ITextureSource *tsrc, TileSpec *tile,
|
||||||
|
TileDef *tiledef, u32 shader_id, bool use_normal_texture,
|
||||||
|
bool backface_culling, u8 alpha, u8 material_type)
|
||||||
|
{
|
||||||
|
tile->shader_id = shader_id;
|
||||||
|
tile->texture = tsrc->getTextureForMesh(tiledef->name, &tile->texture_id);
|
||||||
|
tile->alpha = alpha;
|
||||||
|
tile->material_type = material_type;
|
||||||
|
|
||||||
|
// Normal texture and shader flags texture
|
||||||
|
if (use_normal_texture) {
|
||||||
|
tile->normal_texture = tsrc->getNormalTexture(tiledef->name);
|
||||||
|
}
|
||||||
|
tile->flags_texture = tsrc->getShaderFlagsTexture(tile->normal_texture ? true : false);
|
||||||
|
|
||||||
|
// Material flags
|
||||||
|
tile->material_flags = 0;
|
||||||
|
if (backface_culling)
|
||||||
|
tile->material_flags |= MATERIAL_FLAG_BACKFACE_CULLING;
|
||||||
|
if (tiledef->animation.type == TAT_VERTICAL_FRAMES)
|
||||||
|
tile->material_flags |= MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES;
|
||||||
|
if (tiledef->tileable_horizontal)
|
||||||
|
tile->material_flags |= MATERIAL_FLAG_TILEABLE_HORIZONTAL;
|
||||||
|
if (tiledef->tileable_vertical)
|
||||||
|
tile->material_flags |= MATERIAL_FLAG_TILEABLE_VERTICAL;
|
||||||
|
|
||||||
|
// Animation parameters
|
||||||
|
int frame_count = 1;
|
||||||
|
if (tile->material_flags & MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES) {
|
||||||
|
// Get texture size to determine frame count by aspect ratio
|
||||||
|
v2u32 size = tile->texture->getOriginalSize();
|
||||||
|
int frame_height = (float)size.X /
|
||||||
|
(float)tiledef->animation.aspect_w *
|
||||||
|
(float)tiledef->animation.aspect_h;
|
||||||
|
frame_count = size.Y / frame_height;
|
||||||
|
int frame_length_ms = 1000.0 * tiledef->animation.length / frame_count;
|
||||||
|
tile->animation_frame_count = frame_count;
|
||||||
|
tile->animation_frame_length_ms = frame_length_ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (frame_count == 1) {
|
||||||
|
tile->material_flags &= ~MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES;
|
||||||
|
} else {
|
||||||
|
std::ostringstream os(std::ios::binary);
|
||||||
|
tile->frames.resize(frame_count);
|
||||||
|
|
||||||
|
for (int i = 0; i < frame_count; i++) {
|
||||||
|
|
||||||
|
FrameSpec frame;
|
||||||
|
|
||||||
|
os.str("");
|
||||||
|
os << tiledef->name << "^[verticalframe:"
|
||||||
|
<< frame_count << ":" << i;
|
||||||
|
|
||||||
|
frame.texture = tsrc->getTextureForMesh(os.str(), &frame.texture_id);
|
||||||
|
if (tile->normal_texture)
|
||||||
|
frame.normal_texture = tsrc->getNormalTexture(os.str());
|
||||||
|
frame.flags_texture = tile->flags_texture;
|
||||||
|
tile->frames[i] = frame;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SERVER
|
||||||
|
void ContentFeatures::updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc,
|
||||||
|
scene::ISceneManager *smgr, scene::IMeshManipulator *meshmanip,
|
||||||
|
IGameDef *gamedef, const TextureSettings &tsettings)
|
||||||
|
{
|
||||||
|
// minimap pixel color - the average color of a texture
|
||||||
|
if (tsettings.enable_minimap && tiledef[0].name != "")
|
||||||
|
minimap_color = tsrc->getTextureAverageColor(tiledef[0].name);
|
||||||
|
|
||||||
|
// Figure out the actual tiles to use
|
||||||
|
TileDef tdef[6];
|
||||||
|
for (u32 j = 0; j < 6; j++) {
|
||||||
|
tdef[j] = tiledef[j];
|
||||||
|
if (tdef[j].name == "")
|
||||||
|
tdef[j].name = "unknown_node.png";
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_liquid = false;
|
||||||
|
bool is_water_surface = false;
|
||||||
|
|
||||||
|
u8 material_type = (alpha == 255) ?
|
||||||
|
TILE_MATERIAL_BASIC : TILE_MATERIAL_ALPHA;
|
||||||
|
|
||||||
|
switch (drawtype) {
|
||||||
|
default:
|
||||||
|
case NDT_NORMAL:
|
||||||
|
solidness = 2;
|
||||||
|
break;
|
||||||
|
case NDT_AIRLIKE:
|
||||||
|
solidness = 0;
|
||||||
|
break;
|
||||||
|
case NDT_LIQUID:
|
||||||
|
assert(liquid_type == LIQUID_SOURCE);
|
||||||
|
if (tsettings.opaque_water)
|
||||||
|
alpha = 255;
|
||||||
|
solidness = 1;
|
||||||
|
is_liquid = true;
|
||||||
|
break;
|
||||||
|
case NDT_FLOWINGLIQUID:
|
||||||
|
assert(liquid_type == LIQUID_FLOWING);
|
||||||
|
solidness = 0;
|
||||||
|
if (tsettings.opaque_water)
|
||||||
|
alpha = 255;
|
||||||
|
is_liquid = true;
|
||||||
|
break;
|
||||||
|
case NDT_GLASSLIKE:
|
||||||
|
solidness = 0;
|
||||||
|
visual_solidness = 1;
|
||||||
|
break;
|
||||||
|
case NDT_GLASSLIKE_FRAMED:
|
||||||
|
solidness = 0;
|
||||||
|
visual_solidness = 1;
|
||||||
|
break;
|
||||||
|
case NDT_GLASSLIKE_FRAMED_OPTIONAL:
|
||||||
|
solidness = 0;
|
||||||
|
visual_solidness = 1;
|
||||||
|
drawtype = tsettings.connected_glass ? NDT_GLASSLIKE_FRAMED : NDT_GLASSLIKE;
|
||||||
|
break;
|
||||||
|
case NDT_ALLFACES:
|
||||||
|
solidness = 0;
|
||||||
|
visual_solidness = 1;
|
||||||
|
break;
|
||||||
|
case NDT_ALLFACES_OPTIONAL:
|
||||||
|
if (tsettings.leaves_style == LEAVES_FANCY) {
|
||||||
|
drawtype = NDT_ALLFACES;
|
||||||
|
solidness = 0;
|
||||||
|
visual_solidness = 1;
|
||||||
|
} else if (tsettings.leaves_style == LEAVES_SIMPLE) {
|
||||||
|
for (u32 j = 0; j < 6; j++) {
|
||||||
|
if (tiledef_special[j].name != "")
|
||||||
|
tdef[j].name = tiledef_special[j].name;
|
||||||
|
}
|
||||||
|
drawtype = NDT_GLASSLIKE;
|
||||||
|
solidness = 0;
|
||||||
|
visual_solidness = 1;
|
||||||
|
} else {
|
||||||
|
drawtype = NDT_NORMAL;
|
||||||
|
solidness = 2;
|
||||||
|
for (u32 i = 0; i < 6; i++)
|
||||||
|
tdef[i].name += std::string("^[noalpha");
|
||||||
|
}
|
||||||
|
if (waving == 1)
|
||||||
|
material_type = TILE_MATERIAL_WAVING_LEAVES;
|
||||||
|
break;
|
||||||
|
case NDT_PLANTLIKE:
|
||||||
|
solidness = 0;
|
||||||
|
if (waving == 1)
|
||||||
|
material_type = TILE_MATERIAL_WAVING_PLANTS;
|
||||||
|
break;
|
||||||
|
case NDT_FIRELIKE:
|
||||||
|
solidness = 0;
|
||||||
|
break;
|
||||||
|
case NDT_MESH:
|
||||||
|
solidness = 0;
|
||||||
|
break;
|
||||||
|
case NDT_TORCHLIKE:
|
||||||
|
case NDT_SIGNLIKE:
|
||||||
|
case NDT_FENCELIKE:
|
||||||
|
case NDT_RAILLIKE:
|
||||||
|
case NDT_NODEBOX:
|
||||||
|
solidness = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_liquid) {
|
||||||
|
material_type = (alpha == 255) ?
|
||||||
|
TILE_MATERIAL_LIQUID_OPAQUE : TILE_MATERIAL_LIQUID_TRANSPARENT;
|
||||||
|
if (name == "default:water_source")
|
||||||
|
is_water_surface = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 tile_shader[6];
|
||||||
|
for (u16 j = 0; j < 6; j++) {
|
||||||
|
tile_shader[j] = shdsrc->getShader("nodes_shader",
|
||||||
|
material_type, drawtype);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_water_surface) {
|
||||||
|
tile_shader[0] = shdsrc->getShader("water_surface_shader",
|
||||||
|
material_type, drawtype);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tiles (fill in f->tiles[])
|
||||||
|
for (u16 j = 0; j < 6; j++) {
|
||||||
|
fillTileAttribs(tsrc, &tiles[j], &tdef[j], tile_shader[j],
|
||||||
|
tsettings.use_normal_texture,
|
||||||
|
tiledef[j].backface_culling, alpha, material_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Special tiles (fill in f->special_tiles[])
|
||||||
|
for (u16 j = 0; j < CF_SPECIAL_COUNT; j++) {
|
||||||
|
fillTileAttribs(tsrc, &special_tiles[j], &tiledef_special[j],
|
||||||
|
tile_shader[j], tsettings.use_normal_texture,
|
||||||
|
tiledef_special[j].backface_culling, alpha, material_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((drawtype == NDT_MESH) && (mesh != "")) {
|
||||||
|
// Meshnode drawtype
|
||||||
|
// Read the mesh and apply scale
|
||||||
|
mesh_ptr[0] = gamedef->getMesh(mesh);
|
||||||
|
if (mesh_ptr[0]){
|
||||||
|
v3f scale = v3f(1.0, 1.0, 1.0) * BS * visual_scale;
|
||||||
|
scaleMesh(mesh_ptr[0], scale);
|
||||||
|
recalculateBoundingBox(mesh_ptr[0]);
|
||||||
|
meshmanip->recalculateNormals(mesh_ptr[0], true, false);
|
||||||
|
}
|
||||||
|
} else if ((drawtype == NDT_NODEBOX) &&
|
||||||
|
((node_box.type == NODEBOX_REGULAR) ||
|
||||||
|
(node_box.type == NODEBOX_FIXED)) &&
|
||||||
|
(!node_box.fixed.empty())) {
|
||||||
|
//Convert regular nodebox nodes to meshnodes
|
||||||
|
//Change the drawtype and apply scale
|
||||||
|
drawtype = NDT_MESH;
|
||||||
|
mesh_ptr[0] = convertNodeboxesToMesh(node_box.fixed);
|
||||||
|
v3f scale = v3f(1.0, 1.0, 1.0) * visual_scale;
|
||||||
|
scaleMesh(mesh_ptr[0], scale);
|
||||||
|
recalculateBoundingBox(mesh_ptr[0]);
|
||||||
|
meshmanip->recalculateNormals(mesh_ptr[0], true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Cache 6dfacedir and wallmounted rotated clones of meshes
|
||||||
|
if (tsettings.enable_mesh_cache && mesh_ptr[0] && (param_type_2 == CPT2_FACEDIR)) {
|
||||||
|
for (u16 j = 1; j < 24; j++) {
|
||||||
|
mesh_ptr[j] = cloneMesh(mesh_ptr[0]);
|
||||||
|
rotateMeshBy6dFacedir(mesh_ptr[j], j);
|
||||||
|
recalculateBoundingBox(mesh_ptr[j]);
|
||||||
|
meshmanip->recalculateNormals(mesh_ptr[j], true, false);
|
||||||
|
}
|
||||||
|
} else if (tsettings.enable_mesh_cache && mesh_ptr[0] && (param_type_2 == CPT2_WALLMOUNTED)) {
|
||||||
|
static const u8 wm_to_6d[6] = {20, 0, 16+1, 12+3, 8, 4+2};
|
||||||
|
for (u16 j = 1; j < 6; j++) {
|
||||||
|
mesh_ptr[j] = cloneMesh(mesh_ptr[0]);
|
||||||
|
rotateMeshBy6dFacedir(mesh_ptr[j], wm_to_6d[j]);
|
||||||
|
recalculateBoundingBox(mesh_ptr[j]);
|
||||||
|
meshmanip->recalculateNormals(mesh_ptr[j], true, false);
|
||||||
|
}
|
||||||
|
rotateMeshBy6dFacedir(mesh_ptr[0], wm_to_6d[0]);
|
||||||
|
recalculateBoundingBox(mesh_ptr[0]);
|
||||||
|
meshmanip->recalculateNormals(mesh_ptr[0], true, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
CNodeDefManager
|
CNodeDefManager
|
||||||
*/
|
*/
|
||||||
|
@ -525,11 +795,6 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void addNameIdMapping(content_t i, std::string name);
|
void addNameIdMapping(content_t i, std::string name);
|
||||||
#ifndef SERVER
|
|
||||||
void fillTileAttribs(ITextureSource *tsrc, TileSpec *tile, TileDef *tiledef,
|
|
||||||
u32 shader_id, bool use_normal_texture, bool backface_culling,
|
|
||||||
u8 alpha, u8 material_type);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Features indexed by id
|
// Features indexed by id
|
||||||
std::vector<ContentFeatures> m_content_features;
|
std::vector<ContentFeatures> m_content_features;
|
||||||
|
@ -890,271 +1155,18 @@ void CNodeDefManager::updateTextures(IGameDef *gamedef,
|
||||||
IShaderSource *shdsrc = gamedef->getShaderSource();
|
IShaderSource *shdsrc = gamedef->getShaderSource();
|
||||||
scene::ISceneManager* smgr = gamedef->getSceneManager();
|
scene::ISceneManager* smgr = gamedef->getSceneManager();
|
||||||
scene::IMeshManipulator* meshmanip = smgr->getMeshManipulator();
|
scene::IMeshManipulator* meshmanip = smgr->getMeshManipulator();
|
||||||
|
TextureSettings tsettings;
|
||||||
bool connected_glass = g_settings->getBool("connected_glass");
|
tsettings.readSettings();
|
||||||
bool opaque_water = g_settings->getBool("opaque_water");
|
|
||||||
bool enable_shaders = g_settings->getBool("enable_shaders");
|
|
||||||
bool enable_bumpmapping = g_settings->getBool("enable_bumpmapping");
|
|
||||||
bool enable_parallax_occlusion = g_settings->getBool("enable_parallax_occlusion");
|
|
||||||
bool enable_mesh_cache = g_settings->getBool("enable_mesh_cache");
|
|
||||||
bool enable_minimap = g_settings->getBool("enable_minimap");
|
|
||||||
std::string leaves_style = g_settings->get("leaves_style");
|
|
||||||
|
|
||||||
bool use_normal_texture = enable_shaders &&
|
|
||||||
(enable_bumpmapping || enable_parallax_occlusion);
|
|
||||||
|
|
||||||
u32 size = m_content_features.size();
|
u32 size = m_content_features.size();
|
||||||
|
|
||||||
for (u32 i = 0; i < size; i++) {
|
for (u32 i = 0; i < size; i++) {
|
||||||
ContentFeatures *f = &m_content_features[i];
|
m_content_features[i].updateTextures(tsrc, shdsrc, smgr, meshmanip, gamedef, tsettings);
|
||||||
|
|
||||||
// minimap pixel color - the average color of a texture
|
|
||||||
if (enable_minimap && f->tiledef[0].name != "")
|
|
||||||
f->minimap_color = tsrc->getTextureAverageColor(f->tiledef[0].name);
|
|
||||||
|
|
||||||
// Figure out the actual tiles to use
|
|
||||||
TileDef tiledef[6];
|
|
||||||
for (u32 j = 0; j < 6; j++) {
|
|
||||||
tiledef[j] = f->tiledef[j];
|
|
||||||
if (tiledef[j].name == "")
|
|
||||||
tiledef[j].name = "unknown_node.png";
|
|
||||||
}
|
|
||||||
|
|
||||||
bool is_liquid = false;
|
|
||||||
bool is_water_surface = false;
|
|
||||||
|
|
||||||
u8 material_type = (f->alpha == 255) ?
|
|
||||||
TILE_MATERIAL_BASIC : TILE_MATERIAL_ALPHA;
|
|
||||||
|
|
||||||
switch (f->drawtype) {
|
|
||||||
default:
|
|
||||||
case NDT_NORMAL:
|
|
||||||
f->solidness = 2;
|
|
||||||
break;
|
|
||||||
case NDT_AIRLIKE:
|
|
||||||
f->solidness = 0;
|
|
||||||
break;
|
|
||||||
case NDT_LIQUID:
|
|
||||||
assert(f->liquid_type == LIQUID_SOURCE);
|
|
||||||
if (opaque_water)
|
|
||||||
f->alpha = 255;
|
|
||||||
f->solidness = 1;
|
|
||||||
is_liquid = true;
|
|
||||||
break;
|
|
||||||
case NDT_FLOWINGLIQUID:
|
|
||||||
assert(f->liquid_type == LIQUID_FLOWING);
|
|
||||||
f->solidness = 0;
|
|
||||||
if (opaque_water)
|
|
||||||
f->alpha = 255;
|
|
||||||
is_liquid = true;
|
|
||||||
break;
|
|
||||||
case NDT_GLASSLIKE:
|
|
||||||
f->solidness = 0;
|
|
||||||
f->visual_solidness = 1;
|
|
||||||
break;
|
|
||||||
case NDT_GLASSLIKE_FRAMED:
|
|
||||||
f->solidness = 0;
|
|
||||||
f->visual_solidness = 1;
|
|
||||||
break;
|
|
||||||
case NDT_GLASSLIKE_FRAMED_OPTIONAL:
|
|
||||||
f->solidness = 0;
|
|
||||||
f->visual_solidness = 1;
|
|
||||||
f->drawtype = connected_glass ? NDT_GLASSLIKE_FRAMED : NDT_GLASSLIKE;
|
|
||||||
break;
|
|
||||||
case NDT_ALLFACES:
|
|
||||||
f->solidness = 0;
|
|
||||||
f->visual_solidness = 1;
|
|
||||||
break;
|
|
||||||
case NDT_ALLFACES_OPTIONAL:
|
|
||||||
if (leaves_style == "fancy") {
|
|
||||||
f->drawtype = NDT_ALLFACES;
|
|
||||||
f->solidness = 0;
|
|
||||||
f->visual_solidness = 1;
|
|
||||||
} else if (leaves_style == "simple") {
|
|
||||||
for (u32 j = 0; j < 6; j++) {
|
|
||||||
if (f->tiledef_special[j].name != "")
|
|
||||||
tiledef[j].name = f->tiledef_special[j].name;
|
|
||||||
}
|
|
||||||
f->drawtype = NDT_GLASSLIKE;
|
|
||||||
f->solidness = 0;
|
|
||||||
f->visual_solidness = 1;
|
|
||||||
} else {
|
|
||||||
f->drawtype = NDT_NORMAL;
|
|
||||||
f->solidness = 2;
|
|
||||||
for (u32 i = 0; i < 6; i++)
|
|
||||||
tiledef[i].name += std::string("^[noalpha");
|
|
||||||
}
|
|
||||||
if (f->waving == 1)
|
|
||||||
material_type = TILE_MATERIAL_WAVING_LEAVES;
|
|
||||||
break;
|
|
||||||
case NDT_PLANTLIKE:
|
|
||||||
f->solidness = 0;
|
|
||||||
if (f->waving == 1)
|
|
||||||
material_type = TILE_MATERIAL_WAVING_PLANTS;
|
|
||||||
break;
|
|
||||||
case NDT_FIRELIKE:
|
|
||||||
f->solidness = 0;
|
|
||||||
break;
|
|
||||||
case NDT_MESH:
|
|
||||||
f->solidness = 0;
|
|
||||||
break;
|
|
||||||
case NDT_TORCHLIKE:
|
|
||||||
case NDT_SIGNLIKE:
|
|
||||||
case NDT_FENCELIKE:
|
|
||||||
case NDT_RAILLIKE:
|
|
||||||
case NDT_NODEBOX:
|
|
||||||
f->solidness = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_liquid) {
|
|
||||||
material_type = (f->alpha == 255) ?
|
|
||||||
TILE_MATERIAL_LIQUID_OPAQUE : TILE_MATERIAL_LIQUID_TRANSPARENT;
|
|
||||||
if (f->name == "default:water_source")
|
|
||||||
is_water_surface = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 tile_shader[6];
|
|
||||||
for (u16 j = 0; j < 6; j++) {
|
|
||||||
tile_shader[j] = shdsrc->getShader("nodes_shader",
|
|
||||||
material_type, f->drawtype);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_water_surface) {
|
|
||||||
tile_shader[0] = shdsrc->getShader("water_surface_shader",
|
|
||||||
material_type, f->drawtype);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tiles (fill in f->tiles[])
|
|
||||||
for (u16 j = 0; j < 6; j++) {
|
|
||||||
fillTileAttribs(tsrc, &f->tiles[j], &tiledef[j], tile_shader[j],
|
|
||||||
use_normal_texture, f->tiledef[j].backface_culling, f->alpha, material_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Special tiles (fill in f->special_tiles[])
|
|
||||||
for (u16 j = 0; j < CF_SPECIAL_COUNT; j++) {
|
|
||||||
fillTileAttribs(tsrc, &f->special_tiles[j], &f->tiledef_special[j],
|
|
||||||
tile_shader[j], use_normal_texture,
|
|
||||||
f->tiledef_special[j].backface_culling, f->alpha, material_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((f->drawtype == NDT_MESH) && (f->mesh != "")) {
|
|
||||||
// Meshnode drawtype
|
|
||||||
// Read the mesh and apply scale
|
|
||||||
f->mesh_ptr[0] = gamedef->getMesh(f->mesh);
|
|
||||||
if (f->mesh_ptr[0]){
|
|
||||||
v3f scale = v3f(1.0, 1.0, 1.0) * BS * f->visual_scale;
|
|
||||||
scaleMesh(f->mesh_ptr[0], scale);
|
|
||||||
recalculateBoundingBox(f->mesh_ptr[0]);
|
|
||||||
meshmanip->recalculateNormals(f->mesh_ptr[0], true, false);
|
|
||||||
}
|
|
||||||
} else if ((f->drawtype == NDT_NODEBOX) &&
|
|
||||||
((f->node_box.type == NODEBOX_REGULAR) ||
|
|
||||||
(f->node_box.type == NODEBOX_FIXED)) &&
|
|
||||||
(!f->node_box.fixed.empty())) {
|
|
||||||
//Convert regular nodebox nodes to meshnodes
|
|
||||||
//Change the drawtype and apply scale
|
|
||||||
f->drawtype = NDT_MESH;
|
|
||||||
f->mesh_ptr[0] = convertNodeboxesToMesh(f->node_box.fixed);
|
|
||||||
v3f scale = v3f(1.0, 1.0, 1.0) * f->visual_scale;
|
|
||||||
scaleMesh(f->mesh_ptr[0], scale);
|
|
||||||
recalculateBoundingBox(f->mesh_ptr[0]);
|
|
||||||
meshmanip->recalculateNormals(f->mesh_ptr[0], true, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Cache 6dfacedir and wallmounted rotated clones of meshes
|
|
||||||
if (enable_mesh_cache && f->mesh_ptr[0] && (f->param_type_2 == CPT2_FACEDIR)) {
|
|
||||||
for (u16 j = 1; j < 24; j++) {
|
|
||||||
f->mesh_ptr[j] = cloneMesh(f->mesh_ptr[0]);
|
|
||||||
rotateMeshBy6dFacedir(f->mesh_ptr[j], j);
|
|
||||||
recalculateBoundingBox(f->mesh_ptr[j]);
|
|
||||||
meshmanip->recalculateNormals(f->mesh_ptr[j], true, false);
|
|
||||||
}
|
|
||||||
} else if (enable_mesh_cache && f->mesh_ptr[0] && (f->param_type_2 == CPT2_WALLMOUNTED)) {
|
|
||||||
static const u8 wm_to_6d[6] = {20, 0, 16+1, 12+3, 8, 4+2};
|
|
||||||
for (u16 j = 1; j < 6; j++) {
|
|
||||||
f->mesh_ptr[j] = cloneMesh(f->mesh_ptr[0]);
|
|
||||||
rotateMeshBy6dFacedir(f->mesh_ptr[j], wm_to_6d[j]);
|
|
||||||
recalculateBoundingBox(f->mesh_ptr[j]);
|
|
||||||
meshmanip->recalculateNormals(f->mesh_ptr[j], true, false);
|
|
||||||
}
|
|
||||||
rotateMeshBy6dFacedir(f->mesh_ptr[0], wm_to_6d[0]);
|
|
||||||
recalculateBoundingBox(f->mesh_ptr[0]);
|
|
||||||
meshmanip->recalculateNormals(f->mesh_ptr[0], true, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
progress_callback(progress_callback_args, i, size);
|
progress_callback(progress_callback_args, i, size);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifndef SERVER
|
|
||||||
void CNodeDefManager::fillTileAttribs(ITextureSource *tsrc, TileSpec *tile,
|
|
||||||
TileDef *tiledef, u32 shader_id, bool use_normal_texture,
|
|
||||||
bool backface_culling, u8 alpha, u8 material_type)
|
|
||||||
{
|
|
||||||
tile->shader_id = shader_id;
|
|
||||||
tile->texture = tsrc->getTextureForMesh(tiledef->name, &tile->texture_id);
|
|
||||||
tile->alpha = alpha;
|
|
||||||
tile->material_type = material_type;
|
|
||||||
|
|
||||||
// Normal texture and shader flags texture
|
|
||||||
if (use_normal_texture) {
|
|
||||||
tile->normal_texture = tsrc->getNormalTexture(tiledef->name);
|
|
||||||
}
|
|
||||||
tile->flags_texture = tsrc->getShaderFlagsTexture(tile->normal_texture ? true : false);
|
|
||||||
|
|
||||||
// Material flags
|
|
||||||
tile->material_flags = 0;
|
|
||||||
if (backface_culling)
|
|
||||||
tile->material_flags |= MATERIAL_FLAG_BACKFACE_CULLING;
|
|
||||||
if (tiledef->animation.type == TAT_VERTICAL_FRAMES)
|
|
||||||
tile->material_flags |= MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES;
|
|
||||||
if (tiledef->tileable_horizontal)
|
|
||||||
tile->material_flags |= MATERIAL_FLAG_TILEABLE_HORIZONTAL;
|
|
||||||
if (tiledef->tileable_vertical)
|
|
||||||
tile->material_flags |= MATERIAL_FLAG_TILEABLE_VERTICAL;
|
|
||||||
|
|
||||||
// Animation parameters
|
|
||||||
int frame_count = 1;
|
|
||||||
if (tile->material_flags & MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES) {
|
|
||||||
// Get texture size to determine frame count by aspect ratio
|
|
||||||
v2u32 size = tile->texture->getOriginalSize();
|
|
||||||
int frame_height = (float)size.X /
|
|
||||||
(float)tiledef->animation.aspect_w *
|
|
||||||
(float)tiledef->animation.aspect_h;
|
|
||||||
frame_count = size.Y / frame_height;
|
|
||||||
int frame_length_ms = 1000.0 * tiledef->animation.length / frame_count;
|
|
||||||
tile->animation_frame_count = frame_count;
|
|
||||||
tile->animation_frame_length_ms = frame_length_ms;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (frame_count == 1) {
|
|
||||||
tile->material_flags &= ~MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES;
|
|
||||||
} else {
|
|
||||||
std::ostringstream os(std::ios::binary);
|
|
||||||
tile->frames.resize(frame_count);
|
|
||||||
|
|
||||||
for (int i = 0; i < frame_count; i++) {
|
|
||||||
|
|
||||||
FrameSpec frame;
|
|
||||||
|
|
||||||
os.str("");
|
|
||||||
os << tiledef->name << "^[verticalframe:"
|
|
||||||
<< frame_count << ":" << i;
|
|
||||||
|
|
||||||
frame.texture = tsrc->getTextureForMesh(os.str(), &frame.texture_id);
|
|
||||||
if (tile->normal_texture)
|
|
||||||
frame.normal_texture = tsrc->getNormalTexture(os.str());
|
|
||||||
frame.flags_texture = tile->flags_texture;
|
|
||||||
tile->frames[i] = frame;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
void CNodeDefManager::serialize(std::ostream &os, u16 protocol_version) const
|
void CNodeDefManager::serialize(std::ostream &os, u16 protocol_version) const
|
||||||
{
|
{
|
||||||
writeU8(os, 1); // version
|
writeU8(os, 1); // version
|
||||||
|
|
|
@ -112,6 +112,26 @@ struct NodeBox
|
||||||
struct MapNode;
|
struct MapNode;
|
||||||
class NodeMetadata;
|
class NodeMetadata;
|
||||||
|
|
||||||
|
enum LeavesStyle {
|
||||||
|
LEAVES_FANCY,
|
||||||
|
LEAVES_SIMPLE,
|
||||||
|
LEAVES_OPAQUE,
|
||||||
|
};
|
||||||
|
|
||||||
|
class TextureSettings {
|
||||||
|
public:
|
||||||
|
LeavesStyle leaves_style;
|
||||||
|
bool opaque_water;
|
||||||
|
bool connected_glass;
|
||||||
|
bool use_normal_texture;
|
||||||
|
bool enable_mesh_cache;
|
||||||
|
bool enable_minimap;
|
||||||
|
|
||||||
|
TextureSettings() {}
|
||||||
|
|
||||||
|
void readSettings();
|
||||||
|
};
|
||||||
|
|
||||||
enum NodeDrawType
|
enum NodeDrawType
|
||||||
{
|
{
|
||||||
NDT_NORMAL, // A basic solid block
|
NDT_NORMAL, // A basic solid block
|
||||||
|
@ -304,6 +324,15 @@ struct ContentFeatures
|
||||||
if(!isLiquid() || !f.isLiquid()) return false;
|
if(!isLiquid() || !f.isLiquid()) return false;
|
||||||
return (liquid_alternative_flowing == f.liquid_alternative_flowing);
|
return (liquid_alternative_flowing == f.liquid_alternative_flowing);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef SERVER
|
||||||
|
void fillTileAttribs(ITextureSource *tsrc, TileSpec *tile, TileDef *tiledef,
|
||||||
|
u32 shader_id, bool use_normal_texture, bool backface_culling,
|
||||||
|
u8 alpha, u8 material_type);
|
||||||
|
void updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc,
|
||||||
|
scene::ISceneManager *smgr, scene::IMeshManipulator *meshmanip,
|
||||||
|
IGameDef *gamedef, const TextureSettings &tsettings);
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
class INodeDefManager {
|
class INodeDefManager {
|
||||||
|
|
Loading…
Reference in New Issue