X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Fclient%2Fclientenvironment.cpp;h=44ea1e4a157a53282300c203988bc1e2c9177790;hb=a08d18a;hp=7c2ec099ce017fff7f4afc37433e7838cd4aef9f;hpb=eda35100b6c6f7d9b01c257557147545b563dc74;p=oweals%2Fminetest.git diff --git a/src/client/clientenvironment.cpp b/src/client/clientenvironment.cpp index 7c2ec099c..44ea1e4a1 100644 --- a/src/client/clientenvironment.cpp +++ b/src/client/clientenvironment.cpp @@ -32,10 +32,65 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "raycast.h" #include "voxelalgorithms.h" #include "settings.h" +#include "shader.h" #include "content_cao.h" #include #include "client/renderingengine.h" +/* + CAOShaderConstantSetter +*/ + +//! Shader constant setter for passing material emissive color to the CAO object_shader +class CAOShaderConstantSetter : public IShaderConstantSetter +{ +public: + CAOShaderConstantSetter(): + m_emissive_color_setting("emissiveColor") + {} + + ~CAOShaderConstantSetter() override = default; + + void onSetConstants(video::IMaterialRendererServices *services, + bool is_highlevel) override + { + if (!is_highlevel) + return; + + // Ambient color + video::SColorf emissive_color(m_emissive_color); + + float as_array[4] = { + emissive_color.r, + emissive_color.g, + emissive_color.b, + emissive_color.a, + }; + m_emissive_color_setting.set(as_array, services); + } + + void onSetMaterial(const video::SMaterial& material) override + { + m_emissive_color = material.EmissiveColor; + } + +private: + video::SColor m_emissive_color; + CachedPixelShaderSetting m_emissive_color_setting; +}; + +class CAOShaderConstantSetterFactory : public IShaderConstantSetterFactory +{ +public: + CAOShaderConstantSetterFactory() + {} + + virtual IShaderConstantSetter* create() + { + return new CAOShaderConstantSetter(); + } +}; + /* ClientEnvironment */ @@ -47,8 +102,8 @@ ClientEnvironment::ClientEnvironment(ClientMap *map, m_texturesource(texturesource), m_client(client) { - char zero = 0; - memset(attachement_parent_ids, zero, sizeof(attachement_parent_ids)); + auto *shdrsrc = m_client->getShaderSource(); + shdrsrc->addShaderConstantSetterFactory(new CAOShaderConstantSetterFactory()); } ClientEnvironment::~ClientEnvironment() @@ -170,7 +225,8 @@ void ClientEnvironment::step(float dtime) lplayer->physics_override_gravity * dtime_part * 2.0f; // Liquid floating / sinking - if (lplayer->in_liquid && !lplayer->swimming_vertical) + if (lplayer->in_liquid && !lplayer->swimming_vertical && + !lplayer->swimming_pitch) speed.Y -= lplayer->movement_liquid_sink * dtime_part * 2.0f; // Liquid resistance @@ -219,7 +275,7 @@ void ClientEnvironment::step(float dtime) f32 post_factor = 1; // 1 hp per node/s if (info.type == COLLISION_NODE) { const ContentFeatures &f = m_client->ndef()-> - get(m_map->getNodeNoEx(info.node_p)); + get(m_map->getNode(info.node_p)); // Determine fall damage multiplier int addp = itemgroup_get(f.groups, "fall_damage_add_percent"); pre_factor = 1.0f + (float)addp / 100.0f; @@ -227,7 +283,7 @@ void ClientEnvironment::step(float dtime) float speed = pre_factor * speed_diff.getLength(); if (speed > tolerance && !player_immortal) { f32 damage_f = (speed - tolerance) / BS * post_factor; - u8 damage = (u8)MYMIN(damage_f + 0.5, 255); + u16 damage = (u16)MYMIN(damage_f + 0.5, U16_MAX); if (damage != 0) { damageLocalPlayer(damage, true); m_client->getEventManager()->put( @@ -249,7 +305,7 @@ void ClientEnvironment::step(float dtime) MapNode node_at_lplayer(CONTENT_AIR, 0x0f, 0); v3s16 p = lplayer->getLightPosition(); - node_at_lplayer = m_map->getNodeNoEx(p); + node_at_lplayer = m_map->getNode(p); u16 light = getInteriorLight(node_at_lplayer, 0, m_client->ndef()); final_color_blend(&lplayer->light_color, light, day_night_ratio); @@ -264,21 +320,8 @@ void ClientEnvironment::step(float dtime) // Step object cao->step(dtime, this); - if (update_lighting) { - // Update lighting - u8 light = 0; - bool pos_ok; - - // Get node at head - v3s16 p = cao->getLightPosition(); - MapNode n = this->m_map->getNodeNoEx(p, &pos_ok); - if (pos_ok) - light = n.getLightBlend(day_night_ratio, m_client->ndef()); - else - light = blend_light(day_night_ratio, LIGHT_SUN, 0); - - cao->updateLight(light); - } + if (update_lighting) + cao->updateLight(day_night_ratio); }; m_ao_manager.step(dtime, cb_state); @@ -286,15 +329,14 @@ void ClientEnvironment::step(float dtime) /* Step and handle simple objects */ - g_profiler->avg("CEnv: num of simple objects", m_simple_objects.size()); + g_profiler->avg("ClientEnv: CSO count [#]", m_simple_objects.size()); for (auto i = m_simple_objects.begin(); i != m_simple_objects.end();) { - auto cur = i; - ClientSimpleObject *simple = *cur; + ClientSimpleObject *simple = *i; simple->step(dtime); if(simple->m_to_be_removed) { delete simple; - i = m_simple_objects.erase(cur); + i = m_simple_objects.erase(i); } else { ++i; @@ -347,18 +389,7 @@ u16 ClientEnvironment::addActiveObject(ClientActiveObject *object) object->addToScene(m_texturesource); // Update lighting immediately - u8 light = 0; - bool pos_ok; - - // Get node at head - v3s16 p = object->getLightPosition(); - MapNode n = m_map->getNodeNoEx(p, &pos_ok); - if (pos_ok) - light = n.getLightBlend(getDayNightRatio(), m_client->ndef()); - else - light = blend_light(getDayNightRatio(), LIGHT_SUN, 0); - - object->updateLight(light); + object->updateLight(getDayNightRatio()); return object->getId(); } @@ -391,7 +422,34 @@ void ClientEnvironment::addActiveObject(u16 id, u8 type, <getAttachmentChildIds(); + for (auto c_id : children) { + if (auto *o = getActiveObject(c_id)) + o->updateAttachments(); + } + } +} + + +void ClientEnvironment::removeActiveObject(u16 id) +{ + // Get current attachment childs to detach them visually + std::unordered_set attachment_childs; + if (auto *obj = getActiveObject(id)) + attachment_childs = obj->getAttachmentChildIds(); + + m_ao_manager.removeObject(id); + + // Perform a proper detach in Irrlicht + for (auto c_id : attachment_childs) { + if (ClientActiveObject *child = getActiveObject(c_id)) + child->updateAttachments(); + } } void ClientEnvironment::processActiveObjectMessage(u16 id, const std::string &data) @@ -418,7 +476,7 @@ void ClientEnvironment::processActiveObjectMessage(u16 id, const std::string &da Callbacks for activeobjects */ -void ClientEnvironment::damageLocalPlayer(u8 damage, bool handle_hp) +void ClientEnvironment::damageLocalPlayer(u16 damage, bool handle_hp) { LocalPlayer *lplayer = getLocalPlayer(); assert(lplayer);