diff options
Diffstat (limited to 'src/client/content_cao.cpp')
-rw-r--r-- | src/client/content_cao.cpp | 214 |
1 files changed, 128 insertions, 86 deletions
diff --git a/src/client/content_cao.cpp b/src/client/content_cao.cpp index 5521a6cf1..d148df522 100644 --- a/src/client/content_cao.cpp +++ b/src/client/content_cao.cpp @@ -46,6 +46,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "wieldmesh.h" #include <algorithm> #include <cmath> +#include "client/shader.h" class Settings; struct ToolCapabilities; @@ -352,6 +353,8 @@ void GenericCAO::initialize(const std::string &data) player->setCAO(this); } } + + m_enable_shaders = g_settings->getBool("enable_shaders"); } void GenericCAO::processInitData(const std::string &data) @@ -403,13 +406,17 @@ bool GenericCAO::getSelectionBox(aabb3f *toset) const const v3f GenericCAO::getPosition() const { - if (getParent() != nullptr) { - if (m_matrixnode) - return m_matrixnode->getAbsolutePosition(); + if (!getParent()) + return pos_translator.val_current; - return m_position; + // Calculate real position in world based on MatrixNode + if (m_matrixnode) { + v3s16 camera_offset = m_env->getCameraOffset(); + return m_matrixnode->getAbsolutePosition() + + intToFloat(camera_offset, BS); } - return pos_translator.val_current; + + return m_position; } const bool GenericCAO::isImmortal() @@ -417,7 +424,7 @@ const bool GenericCAO::isImmortal() return itemgroup_get(getGroups(), "immortal"); } -scene::ISceneNode* GenericCAO::getSceneNode() +scene::ISceneNode *GenericCAO::getSceneNode() const { if (m_meshnode) { return m_meshnode; @@ -437,7 +444,7 @@ scene::ISceneNode* GenericCAO::getSceneNode() return NULL; } -scene::IAnimatedMeshSceneNode* GenericCAO::getAnimatedMeshSceneNode() +scene::IAnimatedMeshSceneNode *GenericCAO::getAnimatedMeshSceneNode() const { return m_animated_meshnode; } @@ -573,25 +580,47 @@ void GenericCAO::addToScene(ITextureSource *tsrc) return; } - video::E_MATERIAL_TYPE material_type = (m_prop.use_texture_alpha) ? - video::EMT_TRANSPARENT_ALPHA_CHANNEL : video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; + if (m_enable_shaders) { + IShaderSource *shader_source = m_client->getShaderSource(); + u32 shader_id = shader_source->getShader( + "object_shader", + TILE_MATERIAL_BASIC, + NDT_NORMAL); + m_material_type = shader_source->getShaderInfo(shader_id).material; + } else { + m_material_type = (m_prop.use_texture_alpha) ? + video::EMT_TRANSPARENT_ALPHA_CHANNEL : video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; + } - if (m_prop.visual == "sprite") { - infostream<<"GenericCAO::addToScene(): single_sprite"<<std::endl; + auto grabMatrixNode = [this] { + infostream << "GenericCAO::addToScene(): " << m_prop.visual << std::endl; m_matrixnode = RenderingEngine::get_scene_manager()-> addDummyTransformationSceneNode(); m_matrixnode->grab(); + }; + + auto setSceneNodeMaterial = [this] (scene::ISceneNode *node) { + node->setMaterialFlag(video::EMF_LIGHTING, false); + node->setMaterialFlag(video::EMF_BILINEAR_FILTER, false); + node->setMaterialFlag(video::EMF_FOG_ENABLE, true); + node->setMaterialType(m_material_type); + + if (m_enable_shaders) { + node->setMaterialFlag(video::EMF_GOURAUD_SHADING, false); + node->setMaterialFlag(video::EMF_NORMALIZE_NORMALS, true); + } + }; + + if (m_prop.visual == "sprite") { + grabMatrixNode(); m_spritenode = RenderingEngine::get_scene_manager()->addBillboardSceneNode( m_matrixnode, v2f(1, 1), v3f(0,0,0), -1); m_spritenode->grab(); m_spritenode->setMaterialTexture(0, tsrc->getTextureForMesh("unknown_node.png")); - m_spritenode->setMaterialFlag(video::EMF_LIGHTING, false); - m_spritenode->setMaterialFlag(video::EMF_BILINEAR_FILTER, false); - m_spritenode->setMaterialType(material_type); - m_spritenode->setMaterialFlag(video::EMF_FOG_ENABLE, true); - u8 li = m_last_light; - m_spritenode->setColor(video::SColor(255,li,li,li)); + + setSceneNodeMaterial(m_spritenode); + m_spritenode->setSize(v2f(m_prop.visual_size.X, m_prop.visual_size.Y) * BS); { @@ -601,19 +630,19 @@ void GenericCAO::addToScene(ITextureSource *tsrc) txs, tys, 0, 0); } } else if (m_prop.visual == "upright_sprite") { + grabMatrixNode(); scene::SMesh *mesh = new scene::SMesh(); double dx = BS * m_prop.visual_size.X / 2; double dy = BS * m_prop.visual_size.Y / 2; - u8 li = m_last_light; - video::SColor c(255, li, li, li); + video::SColor c(0xFFFFFFFF); { // Front scene::IMeshBuffer *buf = new scene::SMeshBuffer(); video::S3DVertex vertices[4] = { - video::S3DVertex(-dx, -dy, 0, 0,0,0, c, 1,1), - video::S3DVertex( dx, -dy, 0, 0,0,0, c, 0,1), - video::S3DVertex( dx, dy, 0, 0,0,0, c, 0,0), - video::S3DVertex(-dx, dy, 0, 0,0,0, c, 1,0), + video::S3DVertex(-dx, -dy, 0, 0,0,1, c, 1,1), + video::S3DVertex( dx, -dy, 0, 0,0,1, c, 0,1), + video::S3DVertex( dx, dy, 0, 0,0,1, c, 0,0), + video::S3DVertex(-dx, dy, 0, 0,0,1, c, 1,0), }; if (m_is_player) { // Move minimal Y position to 0 (feet position) @@ -626,7 +655,14 @@ void GenericCAO::addToScene(ITextureSource *tsrc) buf->getMaterial().setFlag(video::EMF_LIGHTING, false); buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false); buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true); - buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; + buf->getMaterial().MaterialType = m_material_type; + + if (m_enable_shaders) { + buf->getMaterial().EmissiveColor = c; + buf->getMaterial().setFlag(video::EMF_GOURAUD_SHADING, false); + buf->getMaterial().setFlag(video::EMF_NORMALIZE_NORMALS, true); + } + // Add to mesh mesh->addMeshBuffer(buf); buf->drop(); @@ -634,10 +670,10 @@ void GenericCAO::addToScene(ITextureSource *tsrc) { // Back scene::IMeshBuffer *buf = new scene::SMeshBuffer(); video::S3DVertex vertices[4] = { - video::S3DVertex( dx,-dy, 0, 0,0,0, c, 1,1), - video::S3DVertex(-dx,-dy, 0, 0,0,0, c, 0,1), - video::S3DVertex(-dx, dy, 0, 0,0,0, c, 0,0), - video::S3DVertex( dx, dy, 0, 0,0,0, c, 1,0), + video::S3DVertex( dx,-dy, 0, 0,0,-1, c, 1,1), + video::S3DVertex(-dx,-dy, 0, 0,0,-1, c, 0,1), + video::S3DVertex(-dx, dy, 0, 0,0,-1, c, 0,0), + video::S3DVertex( dx, dy, 0, 0,0,-1, c, 1,0), }; if (m_is_player) { // Move minimal Y position to 0 (feet position) @@ -650,14 +686,18 @@ void GenericCAO::addToScene(ITextureSource *tsrc) buf->getMaterial().setFlag(video::EMF_LIGHTING, false); buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false); buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true); - buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; + buf->getMaterial().MaterialType = m_material_type; + + if (m_enable_shaders) { + buf->getMaterial().EmissiveColor = c; + buf->getMaterial().setFlag(video::EMF_GOURAUD_SHADING, false); + buf->getMaterial().setFlag(video::EMF_NORMALIZE_NORMALS, true); + } + // Add to mesh mesh->addMeshBuffer(buf); buf->drop(); } - m_matrixnode = RenderingEngine::get_scene_manager()-> - addDummyTransformationSceneNode(); - m_matrixnode->grab(); m_meshnode = RenderingEngine::get_scene_manager()-> addMeshSceneNode(mesh, m_matrixnode); m_meshnode->grab(); @@ -666,55 +706,41 @@ void GenericCAO::addToScene(ITextureSource *tsrc) // This is needed for changing the texture in the future m_meshnode->setReadOnlyMaterials(true); } else if (m_prop.visual == "cube") { - infostream<<"GenericCAO::addToScene(): cube"<<std::endl; + grabMatrixNode(); scene::IMesh *mesh = createCubeMesh(v3f(BS,BS,BS)); - m_matrixnode = RenderingEngine::get_scene_manager()-> - addDummyTransformationSceneNode(nullptr); - m_matrixnode->grab(); m_meshnode = RenderingEngine::get_scene_manager()-> addMeshSceneNode(mesh, m_matrixnode); m_meshnode->grab(); mesh->drop(); m_meshnode->setScale(m_prop.visual_size); - u8 li = m_last_light; - setMeshColor(m_meshnode->getMesh(), video::SColor(255,li,li,li)); - m_meshnode->setMaterialFlag(video::EMF_LIGHTING, false); - m_meshnode->setMaterialFlag(video::EMF_BILINEAR_FILTER, false); - m_meshnode->setMaterialType(material_type); - m_meshnode->setMaterialFlag(video::EMF_FOG_ENABLE, true); + setSceneNodeMaterial(m_meshnode); } else if (m_prop.visual == "mesh") { - infostream<<"GenericCAO::addToScene(): mesh"<<std::endl; + grabMatrixNode(); scene::IAnimatedMesh *mesh = m_client->getMesh(m_prop.mesh, true); if (mesh) { - m_matrixnode = RenderingEngine::get_scene_manager()-> - addDummyTransformationSceneNode(nullptr); - m_matrixnode->grab(); m_animated_meshnode = RenderingEngine::get_scene_manager()-> addAnimatedMeshSceneNode(mesh, m_matrixnode); m_animated_meshnode->grab(); mesh->drop(); // The scene node took hold of it m_animated_meshnode->animateJoints(); // Needed for some animations m_animated_meshnode->setScale(m_prop.visual_size); - u8 li = m_last_light; // set vertex colors to ensure alpha is set - setMeshColor(m_animated_meshnode->getMesh(), video::SColor(255,li,li,li)); + setMeshColor(m_animated_meshnode->getMesh(), video::SColor(0xFFFFFFFF)); + + setAnimatedMeshColor(m_animated_meshnode, video::SColor(0xFFFFFFFF)); - setAnimatedMeshColor(m_animated_meshnode, video::SColor(255,li,li,li)); + setSceneNodeMaterial(m_animated_meshnode); - m_animated_meshnode->setMaterialFlag(video::EMF_LIGHTING, true); - m_animated_meshnode->setMaterialFlag(video::EMF_BILINEAR_FILTER, false); - m_animated_meshnode->setMaterialType(material_type); - m_animated_meshnode->setMaterialFlag(video::EMF_FOG_ENABLE, true); m_animated_meshnode->setMaterialFlag(video::EMF_BACK_FACE_CULLING, m_prop.backface_culling); } else errorstream<<"GenericCAO::addToScene(): Could not load mesh "<<m_prop.mesh<<std::endl; } else if (m_prop.visual == "wielditem" || m_prop.visual == "item") { + grabMatrixNode(); ItemStack item; - infostream << "GenericCAO::addToScene(): wielditem" << std::endl; if (m_prop.wield_item.empty()) { // Old format, only textures are specified. infostream << "textures: " << m_prop.textures.size() << std::endl; @@ -728,18 +754,13 @@ void GenericCAO::addToScene(ITextureSource *tsrc) infostream << "serialized form: " << m_prop.wield_item << std::endl; item.deSerialize(m_prop.wield_item, m_client->idef()); } - m_matrixnode = RenderingEngine::get_scene_manager()-> - addDummyTransformationSceneNode(nullptr); - m_matrixnode->grab(); m_wield_meshnode = new WieldMeshSceneNode( RenderingEngine::get_scene_manager(), -1); - m_wield_meshnode->setParent(m_matrixnode); m_wield_meshnode->setItem(item, m_client, (m_prop.visual == "wielditem")); m_wield_meshnode->setScale(m_prop.visual_size / 2.0f); - u8 li = m_last_light; - m_wield_meshnode->setColor(video::SColor(255, li, li, li)); + m_wield_meshnode->setColor(video::SColor(0xFFFFFFFF)); } else { infostream<<"GenericCAO::addToScene(): \""<<m_prop.visual <<"\" not supported"<<std::endl; @@ -751,6 +772,9 @@ void GenericCAO::addToScene(ITextureSource *tsrc) scene::ISceneNode *node = getSceneNode(); + if (node && m_matrixnode) + node->setParent(m_matrixnode); + if (node && !m_prop.nametag.empty() && !m_is_local_player) { // Add nametag v3f pos; @@ -764,6 +788,7 @@ void GenericCAO::addToScene(ITextureSource *tsrc) updateAnimation(); updateBonePosition(); updateAttachments(); + setNodeLight(m_last_light); } void GenericCAO::updateLight(u8 light_at_pos) @@ -790,15 +815,46 @@ void GenericCAO::updateLightNoCheck(u8 light_at_pos) return; u8 li = decode_light(light_at_pos + m_glow); + if (li != m_last_light) { m_last_light = li; - video::SColor color(255,li,li,li); + setNodeLight(li); + } +} + +void GenericCAO::setNodeLight(u8 light) +{ + video::SColor color(255, light, light, light); + + if (m_prop.visual == "wielditem" || m_prop.visual == "item") { + // Since these types of visuals are using their own shader + // they should be handled separately + if (m_wield_meshnode) + m_wield_meshnode->setColor(color); + } else if (m_enable_shaders) { + scene::ISceneNode *node = getSceneNode(); + + if (node == nullptr) + return; + + if (m_prop.visual == "upright_sprite") { + scene::IMesh *mesh = m_meshnode->getMesh(); + for (u32 i = 0; i < mesh->getMeshBufferCount(); ++i) { + scene::IMeshBuffer *buf = mesh->getMeshBuffer(i); + video::SMaterial &material = buf->getMaterial(); + material.EmissiveColor = color; + } + } else { + for (u32 i = 0; i < node->getMaterialCount(); ++i) { + video::SMaterial &material = node->getMaterial(i); + material.EmissiveColor = color; + } + } + } else { if (m_meshnode) { setMeshColor(m_meshnode->getMesh(), color); } else if (m_animated_meshnode) { setAnimatedMeshColor(m_animated_meshnode, color); - } else if (m_wield_meshnode) { - m_wield_meshnode->setColor(color); } else if (m_spritenode) { m_spritenode->setColor(color); } @@ -884,7 +940,7 @@ void GenericCAO::step(float dtime, ClientEnvironment *env) // Apply animations if input detected and not attached // or set idle animation - if ((new_anim.X + new_anim.Y) > 0 && !player->isAttached) { + if ((new_anim.X + new_anim.Y) > 0 && !getParent()) { allow_update = true; m_animation_range = new_anim; m_animation_speed = new_speed; @@ -946,12 +1002,7 @@ void GenericCAO::step(float dtime, ClientEnvironment *env) m_velocity = v3f(0,0,0); m_acceleration = v3f(0,0,0); pos_translator.val_current = m_position; - - if(m_is_local_player) // Update local player attachment position - { - LocalPlayer *player = m_env->getLocalPlayer(); - player->overridePosition = getParent()->getPosition(); - } + pos_translator.val_target = m_position; } else { rot_translator.translate(dtime); v3f lastpos = pos_translator.val_current; @@ -975,16 +1026,14 @@ void GenericCAO::step(float dtime, ClientEnvironment *env) bool is_end_position = moveresult.collides; pos_translator.update(m_position, is_end_position, dtime); - pos_translator.translate(dtime); - updateNodePos(); } else { m_position += dtime * m_velocity + 0.5 * dtime * dtime * m_acceleration; m_velocity += dtime * m_acceleration; pos_translator.update(m_position, pos_translator.aim_is_end, pos_translator.anim_time); - pos_translator.translate(dtime); - updateNodePos(); } + pos_translator.translate(dtime); + updateNodePos(); float moved = lastpos.getDistanceFrom(pos_translator.val_current); m_step_distance_counter += moved; @@ -1109,16 +1158,13 @@ void GenericCAO::updateTextures(std::string mod) m_current_texture_modifier = mod; m_glow = m_prop.glow; - video::E_MATERIAL_TYPE material_type = (m_prop.use_texture_alpha) ? - video::EMT_TRANSPARENT_ALPHA_CHANNEL : video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; - if (m_spritenode) { if (m_prop.visual == "sprite") { std::string texturestring = "unknown_node.png"; if (!m_prop.textures.empty()) texturestring = m_prop.textures[0]; texturestring += mod; - m_spritenode->getMaterial(0).MaterialType = material_type; + m_spritenode->getMaterial(0).MaterialType = m_material_type; m_spritenode->getMaterial(0).MaterialTypeParam = 0.5f; m_spritenode->setMaterialTexture(0, tsrc->getTextureForMesh(texturestring)); @@ -1154,7 +1200,7 @@ void GenericCAO::updateTextures(std::string mod) // Set material flags and texture video::SMaterial& material = m_animated_meshnode->getMaterial(i); - material.MaterialType = material_type; + material.MaterialType = m_material_type; material.MaterialTypeParam = 0.5f; material.TextureLayer[0].Texture = texture; material.setFlag(video::EMF_LIGHTING, true); @@ -1201,7 +1247,7 @@ void GenericCAO::updateTextures(std::string mod) // Set material flags and texture video::SMaterial& material = m_meshnode->getMaterial(i); - material.MaterialType = material_type; + material.MaterialType = m_material_type; material.MaterialTypeParam = 0.5f; material.setFlag(video::EMF_LIGHTING, false); material.setFlag(video::EMF_BILINEAR_FILTER, false); @@ -1348,7 +1394,8 @@ void GenericCAO::updateAttachments() if (!parent) { // Detach or don't attach if (m_matrixnode) { - v3f old_pos = m_matrixnode->getAbsolutePosition(); + v3f old_pos = getPosition(); + m_matrixnode->setParent(m_smgr->getRootSceneNode()); getPosRotMatrix().setTranslation(old_pos); m_matrixnode->updateAbsolutePosition(); @@ -1372,11 +1419,6 @@ void GenericCAO::updateAttachments() m_matrixnode->updateAbsolutePosition(); } } - if (m_is_local_player) { - LocalPlayer *player = m_env->getLocalPlayer(); - player->isAttached = parent; - player->parent = parent; - } } void GenericCAO::processMessage(const std::string &data) |