From 821311c96935f0e941c3a50a24b03aae77ffe88e Mon Sep 17 00:00:00 2001
From: EndrII <EndrIIMail@gmail.com>
Date: Fri, 16 Jul 2021 02:26:41 +0300
Subject: [PATCH] ref #88 added light objects

---
 src/Core/Crawl.qrc                  |   1 +
 src/Core/Crawl/defaultlight.cpp     |  30 ++++++
 src/Core/Crawl/defaultlight.h       |  34 ++++++
 src/Core/Crawl/groundclaster.cpp    |   2 +-
 src/Core/Crawl/iworld.h             |   1 +
 src/Core/Crawl/iworlditem.cpp       |  10 +-
 src/Core/Crawl/iworldlight.cpp      |  84 +++++++++++++++
 src/Core/Crawl/iworldlight.h        | 154 ++++++++++++++++++++++++++++
 src/Core/CrawlModule/Light.qml      |  33 ++++++
 src/Core/CrawlModule/Scene.qml      |   7 --
 src/CrawlTestLvl/private/world.cpp  |   4 +-
 src/JungleLvl/CrawlJungleLvlAssests |   2 +-
 src/JungleLvl/private/world.cpp     |   6 +-
 13 files changed, 352 insertions(+), 16 deletions(-)
 create mode 100644 src/Core/Crawl/defaultlight.cpp
 create mode 100644 src/Core/Crawl/defaultlight.h
 create mode 100644 src/Core/Crawl/iworldlight.cpp
 create mode 100644 src/Core/Crawl/iworldlight.h
 create mode 100644 src/Core/CrawlModule/Light.qml

diff --git a/src/Core/Crawl.qrc b/src/Core/Crawl.qrc
index f13c238..49e3d61 100644
--- a/src/Core/Crawl.qrc
+++ b/src/Core/Crawl.qrc
@@ -13,5 +13,6 @@
         <file>CrawlModule/SelectLvlView.qml</file>
         <file>CrawlModule/DefaultMenu.qml</file>
         <file>CrawlModule/AbstractMenuView.qml</file>
+        <file>CrawlModule/Light.qml</file>
     </qresource>
 </RCC>
diff --git a/src/Core/Crawl/defaultlight.cpp b/src/Core/Crawl/defaultlight.cpp
new file mode 100644
index 0000000..b307003
--- /dev/null
+++ b/src/Core/Crawl/defaultlight.cpp
@@ -0,0 +1,30 @@
+//#
+//# Copyright (C) 2021-2021 QuasarApp.
+//# Distributed under the GPLv3 software license, see the accompanying
+//# Everyone is permitted to copy and distribute verbatim copies
+//# of this license document, but changing it is not allowed.
+//#
+
+#include "defaultlight.h"
+
+namespace CRAWL {
+
+DefaultLight::DefaultLight(): IWorldLight(AUTO_CLASS_NAME) {
+    setColor("#fff8e7");
+    setposition({10000, 0, 10000});
+    setRatation(QQuaternion::fromEulerAngles({0,0,-90}));
+    setLightForce(110);
+}
+
+void DefaultLight::render(unsigned int) {
+
+}
+
+void DefaultLight::init() {
+
+}
+
+void DefaultLight::onIntersects(const IWorldItem *) {
+
+}
+}
diff --git a/src/Core/Crawl/defaultlight.h b/src/Core/Crawl/defaultlight.h
new file mode 100644
index 0000000..4764537
--- /dev/null
+++ b/src/Core/Crawl/defaultlight.h
@@ -0,0 +1,34 @@
+//#
+//# Copyright (C) 2021-2021 QuasarApp.
+//# Distributed under the GPLv3 software license, see the accompanying
+//# Everyone is permitted to copy and distribute verbatim copies
+//# of this license document, but changing it is not allowed.
+//#
+
+
+#ifndef DEFAULTLIGHT_H
+#define DEFAULTLIGHT_H
+
+#include "iworldlight.h"
+
+namespace CRAWL {
+
+/**
+ * @brief The DefaultLight class This is default implementation of the wirld light.
+ */
+class DefaultLight final:  public IWorldLight
+{
+    Q_OBJECT
+public:
+    DefaultLight();
+
+    void render(unsigned int tbfMsec) override;
+    void init() override;
+
+    // IWorldItem interface
+protected:
+    void onIntersects(const IWorldItem *item) override;
+};
+
+}
+#endif // DEFAULTLIGHT_H
diff --git a/src/Core/Crawl/groundclaster.cpp b/src/Core/Crawl/groundclaster.cpp
index d2bc391..f559989 100644
--- a/src/Core/Crawl/groundclaster.cpp
+++ b/src/Core/Crawl/groundclaster.cpp
@@ -31,7 +31,7 @@ void GroundClaster::render(unsigned int ) {
 
     auto object = _itemsOrder.at(_index % _itemsOrder.size());
 
-    if (playerObject->position().x() - object->position().x() >
+    if (playerObject->position().distanceToPoint(object->position()) >
             newObjectDistance()) {
 
         auto prewObject = _itemsOrder.at((_index - 1) % _itemsOrder.size());
diff --git a/src/Core/Crawl/iworld.h b/src/Core/Crawl/iworld.h
index 3e22042..d6e0384 100644
--- a/src/Core/Crawl/iworld.h
+++ b/src/Core/Crawl/iworld.h
@@ -30,6 +30,7 @@ class IPlayer;
 class GroundClaster;
 class IControl;
 class IAI;
+class IWorldLight;
 
 /**
  * @brief WorldObjects This is map list of the avalable objects and its count on a lvl-long point.
diff --git a/src/Core/Crawl/iworlditem.cpp b/src/Core/Crawl/iworlditem.cpp
index 05e2c98..e6a06f3 100644
--- a/src/Core/Crawl/iworlditem.cpp
+++ b/src/Core/Crawl/iworlditem.cpp
@@ -34,16 +34,16 @@ const IWorldItem *IWorldItem::getPlayer() const {
 }
 
 void IWorldItem::render(unsigned int) {
-    if (_playerObject->position().x() - _world->cameraReleativePosition().z() >
-            position().x()) {
+    if (_playerObject->position().distanceToPoint(position()) >
+            _world->cameraReleativePosition().z() * 2) {
 
-        float dX = _world->cameraReleativePosition().z() * 2 +
+        float dX = _world->cameraReleativePosition().z() +
                 (rand() % static_cast<int>(_world->cameraReleativePosition().z()));
 
         setX(_playerObject->position().x() + dX);
 
-        float dY = (rand() % static_cast<int>(_world->cameraReleativePosition().z() * 4)
-                                             - _world->cameraReleativePosition().z() * 2);
+        float dY = (rand() % static_cast<int>(_world->cameraReleativePosition().z() * 2)
+                                             - _world->cameraReleativePosition().z());
 
         setY(_playerObject->position().y() + dY);
     }
diff --git a/src/Core/Crawl/iworldlight.cpp b/src/Core/Crawl/iworldlight.cpp
new file mode 100644
index 0000000..5a93306
--- /dev/null
+++ b/src/Core/Crawl/iworldlight.cpp
@@ -0,0 +1,84 @@
+//#
+//# Copyright (C) 2021-2021 QuasarApp.
+//# Distributed under the GPLv3 software license, see the accompanying
+//# Everyone is permitted to copy and distribute verbatim copies
+//# of this license document, but changing it is not allowed.
+//#
+
+#include "iworldlight.h"
+namespace CRAWL {
+
+IWorldLight::IWorldLight(const QString &name,
+                         const QString &viewTempalte,
+                         QObject *ptr):
+    IWorldItem(name, viewTempalte, ptr) {
+
+}
+
+int IWorldLight::lightForce() const {
+    return _lightForce;
+}
+
+void IWorldLight::setLightForce(int newLightForce) {
+    if (_lightForce == newLightForce)
+        return;
+    _lightForce = newLightForce;
+    emit lightForceChanged();
+}
+
+bool IWorldLight::castsShadow() const {
+    return _castsShadow;
+}
+
+void IWorldLight::setCastsShadow(bool newCastsShadow) {
+    if (_castsShadow == newCastsShadow)
+        return;
+    _castsShadow = newCastsShadow;
+    emit castsShadowChanged();
+}
+
+float IWorldLight::shadowFactor() const {
+    return _shadowFactor;
+}
+
+void IWorldLight::setShadowFactor(float newShadowFactor) {
+    if (qFuzzyCompare(_shadowFactor, newShadowFactor))
+        return;
+    _shadowFactor = newShadowFactor;
+    emit shadowFactorChanged();
+}
+
+float IWorldLight::shadowFilter() const {
+    return _shadowFilter;
+}
+
+void IWorldLight::setShadowFilter(float newShadowFilter) {
+    if (qFuzzyCompare(_shadowFilter, newShadowFilter))
+        return;
+    _shadowFilter = newShadowFilter;
+    emit shadowFilterChanged();
+}
+
+float IWorldLight::shadowMapFar() const {
+    return _shadowMapFar;
+}
+
+void IWorldLight::setShadowMapFar(float newShadowMapFar) {
+    if (qFuzzyCompare(_shadowMapFar, newShadowMapFar))
+        return;
+    _shadowMapFar = newShadowMapFar;
+    emit shadowMapFarChanged();
+}
+
+float IWorldLight::shadowBias() const {
+    return _shadowBias;
+}
+
+void IWorldLight::setShadowBias(float newShadowBias) {
+    if (qFuzzyCompare(_shadowBias, newShadowBias))
+        return;
+    _shadowBias = newShadowBias;
+    emit shadowBiasChanged();
+}
+
+}
diff --git a/src/Core/Crawl/iworldlight.h b/src/Core/Crawl/iworldlight.h
new file mode 100644
index 0000000..d520062
--- /dev/null
+++ b/src/Core/Crawl/iworldlight.h
@@ -0,0 +1,154 @@
+//#
+//# Copyright (C) 2021-2021 QuasarApp.
+//# Distributed under the GPLv3 software license, see the accompanying
+//# Everyone is permitted to copy and distribute verbatim copies
+//# of this license document, but changing it is not allowed.
+//#
+
+#include "iworlditem.h"
+
+#ifndef IWORLDLIGHT_H
+#define IWORLDLIGHT_H
+
+namespace CRAWL {
+
+/**
+ * @brief The IWorldLight class Is base interaface of the light object.
+ * Override this class for the create own light system for level.
+ * You need to create own qml file with light.
+ *
+ * @note If you wnat to create a new qml file the you need to inherit from the Light.qml file.
+ */
+class CRAWL_EXPORT IWorldLight: public IWorldItem
+{
+    Q_OBJECT
+    Q_PROPERTY(int lightForce READ lightForce WRITE setLightForce NOTIFY lightForceChanged)
+    Q_PROPERTY(bool castsShadow READ castsShadow WRITE setCastsShadow NOTIFY castsShadowChanged)
+    Q_PROPERTY(float shadowFactor READ shadowFactor WRITE setShadowFactor NOTIFY shadowFactorChanged)
+    Q_PROPERTY(float shadowFilter READ shadowFilter WRITE setShadowFilter NOTIFY shadowFilterChanged)
+    Q_PROPERTY(float shadowMapFar READ shadowMapFar WRITE setShadowMapFar NOTIFY shadowMapFarChanged)
+    Q_PROPERTY(float shadowBias READ shadowBias WRITE setShadowBias NOTIFY shadowBiasChanged)
+
+public:
+    IWorldLight(const QString& name,
+                const QString& viewTempalte = "qrc:/CrawlModule/Light.qml",
+                QObject *ptr = nullptr);
+
+    /**
+     * @brief lightForce This method return light force
+     * @return light force value.
+     */
+    int lightForce() const;
+
+    /**
+     * @brief setLightForce This method sets new value for the light force.
+     * @param newLightForce this is new value of the light force.
+     */
+    void setLightForce(int newLightForce);
+
+    /**
+     * @brief castsShadow When this property is enabled, the light will cast shadows. The default value is false.
+     * @return current value of the castsShadow property.
+     */
+    bool castsShadow() const;
+
+    /**
+     * @brief setCastsShadow This method sets new value of the castsShadow property. for get more information see the castsShadow method.
+     * @param newCastsShadow this is new value of the castsShadow property.
+     */
+    void setCastsShadow(bool newCastsShadow);
+
+    /**
+     * @brief shadowFactor This property determines how dark the cast shadows should be. The value range is [0, 100], where 0 mean no shadows and 100 means the light is fully shadowed. The default value is 5.
+     * @return current value of the shadow factor
+     */
+    float shadowFactor() const;
+
+    /**
+     * @brief setShadowFactor This method return current value of the shadow factor.
+     * @param newShadowFactor This is new value of the shadow factor property.
+     * @note for get more information see the shadowFactor method.
+     */
+    void setShadowFactor(float newShadowFactor);
+
+    /**
+     * @brief shadowFilter This property sets how much blur is applied to the shadows. The default value is 5.
+     * @return current value of the shadow filter property.
+     */
+    float shadowFilter() const;
+
+    /**
+     * @brief setShadowFilter This method return current value of the shadow filter property.
+     * @param newShadowFilter This is new value of the shadow filter property.
+     * @note for get more information see the shadowFilter method.
+     */
+    void setShadowFilter(float newShadowFilter);
+
+    /**
+     * @brief shadowMapFar The property determines the maximum distance for the shadow map. Smaller values improve the precision and effects of the map. The default value is 5000.
+     * @return current value of the shadow map far property.
+     */
+    float shadowMapFar() const;
+
+    /**
+     * @brief setShadowMapFar This method return current value of the shadow map far property.
+     * @param newShadowMapFar This is new value of the shadow map far property.
+     * @note for get more information see the shadowMapFar method.
+     */
+    void setShadowMapFar(float newShadowMapFar);
+
+    /**
+     * @brief shadowBias This property is used to tweak the shadowing effect when when objects are casting shadows on themselves. The value range is [-1.0, 1.0]. Generally value inside [-0.1, 0.1] is sufficient. The default value is 0.
+     * @return current value of the shadow bias property.
+     */
+    float shadowBias() const;
+
+    /**
+     * @brief setShadowBias This method return current value of the shadow bias property.
+     * @param newShadowBias This is new value of the shadow bias property.
+     * @note for get more information see the shadowBias method.
+     */
+    void setShadowBias(float newShadowBias);
+
+signals:
+
+    /**
+     * @brief lightForceChanged This signal emits when light force has changed.
+     */
+    void lightForceChanged();
+
+    /**
+     * @brief castsShadowChanged This signal emits when the castsShadow property has changed.
+     */
+    void castsShadowChanged();
+
+    /**
+     * @brief shadowFactorChanged This signal emits when the shadowFactor propertye has changed.
+     */
+    void shadowFactorChanged();
+
+    /**
+     * @brief shadowFilterChanged This signal emits when the shadowFilter propertye has changed.
+     */
+    void shadowFilterChanged();
+
+    /**
+     * @brief shadowMapFarChanged This signal emits when the shadowMapFar propertye has changed.
+     */
+    void shadowMapFarChanged();
+
+    /**
+     * @brief shadowBiasChanged This signal emits when the shadowBias propertye has changed.
+     */
+    void shadowBiasChanged();
+
+private:
+    int _lightForce = 100;
+    bool _castsShadow = false;
+    float _shadowFactor = 5;
+    float _shadowFilter = 5;
+    float _shadowMapFar = 5000;
+    float _shadowBias = 0;
+};
+}
+#endif // IWORLDLIGHT_H
diff --git a/src/Core/CrawlModule/Light.qml b/src/Core/CrawlModule/Light.qml
new file mode 100644
index 0000000..4310ef4
--- /dev/null
+++ b/src/Core/CrawlModule/Light.qml
@@ -0,0 +1,33 @@
+//#
+//# Copyright (C) 2021-2021 QuasarApp.
+//# Distributed under the GPLv3 software license, see the accompanying
+//# Everyone is permitted to copy and distribute verbatim copies
+//# of this license document, but changing it is not allowed.
+//#
+
+import QtQuick 2.15
+import QtQuick3D 1.15
+
+Node {
+    id: graphicItem
+
+    property var model: null
+    property int guiId: (model) ? model.guiId : -1;
+
+    DirectionalLight {
+        position: Qt.vector3d(0, 0, 0);
+        brightness: (model)? model.lightForce: 100
+        color: (model)? model.color: "#ffffff"
+        castsShadow: (model)? model.castsShadow: 0
+        shadowFactor: (model)? model.shadowFactor: 0
+        shadowFilter: (model)? model.shadowFilter: 0
+        shadowMapFar: (model)? model.shadowMapFar: 0
+        shadowBias: (model)? model.shadowBias: 0
+
+    }
+
+    rotation: (model)? model.ratation: Qt.quaternion(0, 0, 0, 0)
+    scale: (model)? model.size: Qt.vector3d(0, 0, 0);
+    position: (model) ? model.position: Qt.vector3d(0,0,0);
+
+}
diff --git a/src/Core/CrawlModule/Scene.qml b/src/Core/CrawlModule/Scene.qml
index 06db392..229cb0d 100644
--- a/src/Core/CrawlModule/Scene.qml
+++ b/src/Core/CrawlModule/Scene.qml
@@ -27,13 +27,6 @@ View3D {
 
     }
 
-    DirectionalLight {
-        position: Qt.vector3d(10000, 0, 10000);
-        rotation: camera.rotation
-
-        brightness: 120
-    }
-
     environment: SceneEnvironment {
         id: background
         backgroundMode: SceneEnvironment.SkyBox
diff --git a/src/CrawlTestLvl/private/world.cpp b/src/CrawlTestLvl/private/world.cpp
index c8d4504..cd8438a 100644
--- a/src/CrawlTestLvl/private/world.cpp
+++ b/src/CrawlTestLvl/private/world.cpp
@@ -12,6 +12,7 @@
 #include "world.h"
 #include <testsnake.h>
 #include "Crawl/iworlditem.h"
+#include <Crawl/defaultlight.h>
 
 namespace TestLvl {
 
@@ -24,7 +25,8 @@ World::World() {
 CRAWL::WorldRule *World::initWorldRules() {
     return new CRAWL::WorldRule {
         {0, {{registerObject<Box>(), 1000},
-             {registerObject<Background>(), 1}}}
+             {registerObject<Background>(), 1},
+             {registerObject<CRAWL::DefaultLight>(), 1}}}
     };
 }
 
diff --git a/src/JungleLvl/CrawlJungleLvlAssests b/src/JungleLvl/CrawlJungleLvlAssests
index 858c0f9..9b108d2 160000
--- a/src/JungleLvl/CrawlJungleLvlAssests
+++ b/src/JungleLvl/CrawlJungleLvlAssests
@@ -1 +1 @@
-Subproject commit 858c0f949ac542d8a4c00b07bfb74ae5091d456c
+Subproject commit 9b108d2698eda11bd7b263c2dd0a0d46cfa877d3
diff --git a/src/JungleLvl/private/world.cpp b/src/JungleLvl/private/world.cpp
index 36891fd..dad93e1 100644
--- a/src/JungleLvl/private/world.cpp
+++ b/src/JungleLvl/private/world.cpp
@@ -20,6 +20,7 @@
 #include "purpleegg.h"
 #include "blueegg.h"
 
+#include <Crawl/defaultlight.h>
 #include <Crawl/snake.h>
 namespace JungleLvl {
 
@@ -31,14 +32,16 @@ World::World() {
 CRAWL::WorldRule *World::initWorldRules() {
     return new CRAWL::WorldRule {
         {0, {
+                {registerObject<CRAWL::DefaultLight>(), 1},
                 {registerObject<Ground>(), 1},
                 {registerObject<Grees>(), 500},
-                {registerObject<LongGress>(), 100}
+                {registerObject<LongGress>(), 100},
 
 
             }
         },
         {1000, {
+                {registerObject<CRAWL::DefaultLight>(), 1},
                 {registerObject<Ground>(), 1},
                 {registerObject<Grees>(), 500},
                 {registerObject<LongGress>(), 100},
@@ -49,6 +52,7 @@ CRAWL::WorldRule *World::initWorldRules() {
             }
         },
         {2000, {
+                {registerObject<CRAWL::DefaultLight>(), 1},
                 {registerObject<Ground>(), 1},
                 {registerObject<Grees>(), 500},
                 {registerObject<LongGress>(), 100},