Use multiple light positions for CAO lighting
authorsfan5 <sfan5@live.de>
Sun, 7 Jun 2020 17:58:09 +0000 (19:58 +0200)
committersfan5 <sfan5@live.de>
Thu, 11 Jun 2020 19:13:26 +0000 (21:13 +0200)
src/client/clientobject.h
src/client/content_cao.cpp
src/client/content_cao.h

index 8e64b8406b1892e49c1f105310de7ccf933a8b5a..ecd8059ef758c2a556fd18ae2396acc7a5d9bd3d 100644 (file)
@@ -43,7 +43,6 @@ public:
        virtual void removeFromScene(bool permanent) {}
 
        virtual void updateLight(u32 day_night_ratio) {}
-       virtual v3s16 getLightPosition() { return v3s16(0, 0, 0); }
 
        virtual bool getCollisionBox(aabb3f *toset) const { return false; }
        virtual bool getSelectionBox(aabb3f *toset) const { return false; }
index 644a71e6ef17789bcbca7e56339e64440e307cbf..eec4e3de00a643c64df255c214e20ace82ad6713 100644 (file)
@@ -182,7 +182,6 @@ public:
        void addToScene(ITextureSource *tsrc);
        void removeFromScene(bool permanent);
        void updateLight(u32 day_night_ratio);
-       v3s16 getLightPosition();
        void updateNodePos();
 
        void step(float dtime, ClientEnvironment *env);
@@ -258,11 +257,6 @@ void TestCAO::updateLight(u32 day_night_ratio)
 {
 }
 
-v3s16 TestCAO::getLightPosition()
-{
-       return floatToInt(m_position, BS);
-}
-
 void TestCAO::updateNodePos()
 {
        if (!m_node)
@@ -799,13 +793,20 @@ void GenericCAO::updateLight(u32 day_night_ratio)
                return;
 
        u8 light_at_pos = 0;
-       bool pos_ok;
-
-       v3s16 p = getLightPosition();
-       MapNode n = m_env->getMap().getNode(p, &pos_ok);
-       if (pos_ok)
-               light_at_pos = n.getLightBlend(day_night_ratio, m_client->ndef());
-       else
+       bool pos_ok = false;
+
+       v3s16 pos[3];
+       u16 npos = getLightPosition(pos);
+       for (u16 i = 0; i < npos; i++) {
+               bool this_ok;
+               MapNode n = m_env->getMap().getNode(pos[i], &this_ok);
+               if (this_ok) {
+                       u8 this_light = n.getLightBlend(day_night_ratio, m_client->ndef());
+                       light_at_pos = MYMAX(light_at_pos, this_light);
+                       pos_ok = true;
+               }
+       }
+       if (!pos_ok)
                light_at_pos = blend_light(day_night_ratio, LIGHT_SUN, 0);
 
        u8 light = decode_light(light_at_pos + m_glow);
@@ -856,12 +857,17 @@ void GenericCAO::setNodeLight(u8 light)
        }
 }
 
-v3s16 GenericCAO::getLightPosition()
+u16 GenericCAO::getLightPosition(v3s16 *pos)
 {
-       if (m_is_player)
-               return floatToInt(m_position + v3f(0, 0.5 * BS, 0), BS);
-
-       return floatToInt(m_position, BS);
+       const auto &box = m_prop.collisionbox;
+       pos[0] = floatToInt(m_position + box.MinEdge * BS, BS);
+       pos[1] = floatToInt(m_position + box.MaxEdge * BS, BS);
+
+       // Skip center pos if it falls into the same node as Min or MaxEdge
+       if ((box.MaxEdge - box.MinEdge).getLengthSQ() < 3.0f)
+               return 2;
+       pos[2] = floatToInt(m_position + box.getCenter() * BS, BS);
+       return 3;
 }
 
 void GenericCAO::updateNametag()
index 7693dd3d248305e65113be836168b47ed8f16628..699148c52306416eaaa4ea318db4e04678afb888 100644 (file)
@@ -240,7 +240,10 @@ public:
 
        void setNodeLight(u8 light);
 
-       v3s16 getLightPosition();
+       /* Get light position(s).
+        * returns number of positions written into pos[], which must have space
+        * for at least 3 vectors. */
+       u16 getLightPosition(v3s16 *pos);
 
        void updateNametag();