diff --git a/libraries/entities-renderer/src/RenderableZoneEntityItem.h b/libraries/entities-renderer/src/RenderableZoneEntityItem.h index 80fe393f48..9b2de86173 100644 --- a/libraries/entities-renderer/src/RenderableZoneEntityItem.h +++ b/libraries/entities-renderer/src/RenderableZoneEntityItem.h @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -57,7 +58,7 @@ private: model::LightPointer editAmbientLight() { _needAmbientUpdate = true; return _ambientLight; } model::SunSkyStagePointer editBackground() { _needBackgroundUpdate = true; return _background; } model::SkyboxPointer editSkybox() { return editBackground()->getSkybox(); } - + model::HazePointer editHaze() { return editBackground()->getHaze(); } bool _needsInitialSimulation{ true }; glm::vec3 _lastPosition; diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index d6de4ec614..bfbcfa0d22 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -71,6 +71,7 @@ void EntityItemProperties::debugDump() const { getAnimation().debugDump(); getSkybox().debugDump(); + getHaze().debugDump(); getKeyLight().debugDump(); qCDebug(entities) << " changed properties..."; @@ -1588,7 +1589,8 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_SHAPE_TYPE, ShapeType, setShapeType); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_COMPOUND_SHAPE_URL, QString, setCompoundShapeURL); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_BACKGROUND_MODE, BackgroundMode, setBackgroundMode); - properties.getSkybox().decodeFromEditPacket(propertyFlags, dataAt , processedBytes); + properties.getSkybox().decodeFromEditPacket(propertyFlags, dataAt, processedBytes); + properties.getHaze().decodeFromEditPacket(propertyFlags, dataAt, processedBytes); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_FLYING_ALLOWED, bool, setFlyingAllowed); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_GHOSTING_ALLOWED, bool, setGhostingAllowed); @@ -2153,6 +2155,7 @@ QList EntityItemProperties::listChangedProperties() { getAnimation().listChangedProperties(out); getKeyLight().listChangedProperties(out); getSkybox().listChangedProperties(out); + getHaze().listChangedProperties(out); getStage().listChangedProperties(out); return out; diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index dd8ce952d3..891558f314 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -40,6 +40,7 @@ #include "PolyVoxEntityItem.h" #include "SimulationOwner.h" #include "SkyboxPropertyGroup.h" +#include "HazePropertyGroup.h" #include "StagePropertyGroup.h" #include "TextEntityItem.h" #include "ZoneEntityItem.h" @@ -179,6 +180,7 @@ public: DEFINE_PROPERTY_REF_ENUM(PROP_BACKGROUND_MODE, BackgroundMode, backgroundMode, BackgroundMode, BACKGROUND_MODE_INHERIT); DEFINE_PROPERTY_GROUP(Stage, stage, StagePropertyGroup); DEFINE_PROPERTY_GROUP(Skybox, skybox, SkyboxPropertyGroup); + DEFINE_PROPERTY_GROUP(Haze, haze, HazePropertyGroup); DEFINE_PROPERTY_GROUP(Animation, animation, AnimationPropertyGroup); DEFINE_PROPERTY_REF(PROP_SOURCE_URL, SourceUrl, sourceUrl, QString, ""); DEFINE_PROPERTY(PROP_LINE_WIDTH, LineWidth, lineWidth, float, LineEntityItem::DEFAULT_LINE_WIDTH); diff --git a/libraries/entities/src/EntityPropertyFlags.h b/libraries/entities/src/EntityPropertyFlags.h index d97be6348f..a5867f2edf 100644 --- a/libraries/entities/src/EntityPropertyFlags.h +++ b/libraries/entities/src/EntityPropertyFlags.h @@ -221,6 +221,8 @@ enum EntityPropertyList { PROP_BACKGROUND_MODE = PROP_MODEL_URL, PROP_SKYBOX_COLOR = PROP_ANIMATION_URL, PROP_SKYBOX_URL = PROP_ANIMATION_FPS, + PROP_HAZE_COLOR = PROP_ANIMATION_URL, + PROP_HAZE_URL = PROP_ANIMATION_FPS, PROP_KEYLIGHT_AMBIENT_URL = PROP_ANIMATION_PLAYING, // Aliases/Piggyback properties for Web. These properties intentionally reuse the enum values for diff --git a/libraries/entities/src/HazePropertyGroup.cpp b/libraries/entities/src/HazePropertyGroup.cpp new file mode 100644 index 0000000000..ab3cb53901 --- /dev/null +++ b/libraries/entities/src/HazePropertyGroup.cpp @@ -0,0 +1,149 @@ +// +// HazePropertyGroup.h +// libraries/entities/src +// +// Created by Nissim hadar on 9/21/17. +// Copyright 2013 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include + +#include "HazePropertyGroup.h" +#include "EntityItemProperties.h" +#include "EntityItemPropertiesMacros.h" + +const xColor HazePropertyGroup::DEFAULT_COLOR = { 0, 0, 0 }; + +void HazePropertyGroup::copyToScriptValue(const EntityPropertyFlags& desiredProperties, QScriptValue& properties, QScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties) const { + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_HAZE_COLOR, Haze, haze, Color, color); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_HAZE_URL, Haze, haze, URL, url); +} + +void HazePropertyGroup::copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings) { + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(haze, color, xColor, setColor); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(haze, url, QString, setURL); +} + +void HazePropertyGroup::merge(const HazePropertyGroup& other) { + COPY_PROPERTY_IF_CHANGED(color); + COPY_PROPERTY_IF_CHANGED(url); +} + + +void HazePropertyGroup::debugDump() const { + qCDebug(entities) << " HazePropertyGroup: ---------------------------------------------"; + qCDebug(entities) << " Color:" << getColor() << " has changed:" << colorChanged(); + qCDebug(entities) << " URL:" << getURL() << " has changed:" << urlChanged(); +} + +void HazePropertyGroup::listChangedProperties(QList& out) { + if (colorChanged()) { + out << "haze-color"; + } + if (urlChanged()) { + out << "haze-url"; + } +} + +bool HazePropertyGroup::appendToEditPacket(OctreePacketData* packetData, + EntityPropertyFlags& requestedProperties, + EntityPropertyFlags& propertyFlags, + EntityPropertyFlags& propertiesDidntFit, + int& propertyCount, + OctreeElement::AppendState& appendState) const { + + bool successPropertyFits = true; + + APPEND_ENTITY_PROPERTY(PROP_HAZE_COLOR, getColor()); + APPEND_ENTITY_PROPERTY(PROP_HAZE_URL, getURL()); + + return true; +} + + +bool HazePropertyGroup::decodeFromEditPacket(EntityPropertyFlags& propertyFlags, const unsigned char*& dataAt , int& processedBytes) { + + int bytesRead = 0; + bool overwriteLocalData = true; + bool somethingChanged = false; + + READ_ENTITY_PROPERTY(PROP_HAZE_COLOR, xColor, setColor); + READ_ENTITY_PROPERTY(PROP_HAZE_URL, QString, setURL); + + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_HAZE_COLOR, Color); + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_HAZE_URL, URL); + + processedBytes += bytesRead; + + Q_UNUSED(somethingChanged); + + return true; +} + +void HazePropertyGroup::markAllChanged() { + _colorChanged = true; + _urlChanged = true; +} + +EntityPropertyFlags HazePropertyGroup::getChangedProperties() const { + EntityPropertyFlags changedProperties; + + CHECK_PROPERTY_CHANGE(PROP_HAZE_COLOR, color); + CHECK_PROPERTY_CHANGE(PROP_HAZE_URL, url); + + return changedProperties; +} + +void HazePropertyGroup::getProperties(EntityItemProperties& properties) const { + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Haze, Color, getColor); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Haze, URL, getURL); +} + +bool HazePropertyGroup::setProperties(const EntityItemProperties& properties) { + bool somethingChanged = false; + + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Haze, Color, color, setColor); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Haze, URL, url, setURL); + + return somethingChanged; +} + +EntityPropertyFlags HazePropertyGroup::getEntityProperties(EncodeBitstreamParams& params) const { + EntityPropertyFlags requestedProperties; + + requestedProperties += PROP_HAZE_COLOR; + requestedProperties += PROP_HAZE_URL; + + return requestedProperties; +} + +void HazePropertyGroup::appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params, + EntityTreeElementExtraEncodeDataPointer entityTreeElementExtraEncodeData, + EntityPropertyFlags& requestedProperties, + EntityPropertyFlags& propertyFlags, + EntityPropertyFlags& propertiesDidntFit, + int& propertyCount, + OctreeElement::AppendState& appendState) const { + + bool successPropertyFits = true; + + APPEND_ENTITY_PROPERTY(PROP_HAZE_COLOR, getColor()); + APPEND_ENTITY_PROPERTY(PROP_HAZE_URL, getURL()); +} + +int HazePropertyGroup::readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, + ReadBitstreamToTreeParams& args, + EntityPropertyFlags& propertyFlags, bool overwriteLocalData, + bool& somethingChanged) { + + int bytesRead = 0; + const unsigned char* dataAt = data; + + READ_ENTITY_PROPERTY(PROP_HAZE_COLOR, xColor, setColor); + READ_ENTITY_PROPERTY(PROP_HAZE_URL, QString, setURL); + + return bytesRead; +} diff --git a/libraries/entities/src/HazePropertyGroup.h b/libraries/entities/src/HazePropertyGroup.h new file mode 100644 index 0000000000..72ec2d7aad --- /dev/null +++ b/libraries/entities/src/HazePropertyGroup.h @@ -0,0 +1,90 @@ +// +// HazePropertyGroup.h +// libraries/entities/src +// +// Created by Nissim hadar on 9/21/17. +// Copyright 2013 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_HazePropertyGroup_h +#define hifi_HazePropertyGroup_h + +#include + +#include + +#include + +#include "PropertyGroup.h" +#include "EntityItemPropertiesMacros.h" + +class EntityItemProperties; +class EncodeBitstreamParams; +class OctreePacketData; +class EntityTreeElementExtraEncodeData; +class ReadBitstreamToTreeParams; + +class HazePropertyGroup : public PropertyGroup { +public: + // EntityItemProperty related helpers + virtual void copyToScriptValue(const EntityPropertyFlags& desiredProperties, QScriptValue& properties, + QScriptEngine* engine, bool skipDefaults, + EntityItemProperties& defaultEntityProperties) const override; + virtual void copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings) override; + + void merge(const HazePropertyGroup& other); + + virtual void debugDump() const override; + virtual void listChangedProperties(QList& out) override; + + virtual bool appendToEditPacket(OctreePacketData* packetData, + EntityPropertyFlags& requestedProperties, + EntityPropertyFlags& propertyFlags, + EntityPropertyFlags& propertiesDidntFit, + int& propertyCount, + OctreeElement::AppendState& appendState) const override; + + virtual bool decodeFromEditPacket(EntityPropertyFlags& propertyFlags, + const unsigned char*& dataAt, int& processedBytes) override; + virtual void markAllChanged() override; + virtual EntityPropertyFlags getChangedProperties() const override; + + // EntityItem related helpers + // methods for getting/setting all properties of an entity + virtual void getProperties(EntityItemProperties& propertiesOut) const override; + + /// returns true if something changed + virtual bool setProperties(const EntityItemProperties& properties) override; + + virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const override; + + virtual void appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params, + EntityTreeElementExtraEncodeDataPointer entityTreeElementExtraEncodeData, + EntityPropertyFlags& requestedProperties, + EntityPropertyFlags& propertyFlags, + EntityPropertyFlags& propertiesDidntFit, + int& propertyCount, + OctreeElement::AppendState& appendState) const override; + + virtual int readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, + ReadBitstreamToTreeParams& args, + EntityPropertyFlags& propertyFlags, bool overwriteLocalData, + bool& somethingChanged) override; + + glm::vec3 getColorVec3() const { + const quint8 MAX_COLOR = 255; + glm::vec3 color = { (float)_color.red / (float)MAX_COLOR, + (float)_color.green / (float)MAX_COLOR, + (float)_color.blue / (float)MAX_COLOR }; + return color; + } + + static const xColor DEFAULT_COLOR; + DEFINE_PROPERTY_REF(PROP_HAZE_COLOR, Color, color, xColor, DEFAULT_COLOR); + DEFINE_PROPERTY_REF(PROP_HAZE_URL, URL, url, QString, ""); +}; + +#endif // hifi_HazePropertyGroup_h diff --git a/libraries/entities/src/ZoneEntityItem.h b/libraries/entities/src/ZoneEntityItem.h index 14e7cd2f40..93c3b7286d 100644 --- a/libraries/entities/src/ZoneEntityItem.h +++ b/libraries/entities/src/ZoneEntityItem.h @@ -16,6 +16,7 @@ #include "EntityItem.h" #include "EntityTree.h" #include "SkyboxPropertyGroup.h" +#include "HazePropertyGroup.h" #include "StagePropertyGroup.h" class ZoneEntityItem : public EntityItem { @@ -68,7 +69,12 @@ public: void setBackgroundMode(BackgroundMode value) { _backgroundMode = value; _backgroundPropertiesChanged = true; } BackgroundMode getBackgroundMode() const { return _backgroundMode; } + void setHazeMode(HazeMode value) { _hazeMode = value; _hazePropertiesChanged = true; } + HazeMode getHazeMode() const { return _hazeMode; } + SkyboxPropertyGroup getSkyboxProperties() const { return resultWithReadLock([&] { return _skyboxProperties; }); } + HazePropertyGroup getHazeProperties() const { return resultWithReadLock([&] { return _hazeProperties; }); } + const StagePropertyGroup& getStageProperties() const { return _stageProperties; } bool getFlyingAllowed() const { return _flyingAllowed; } @@ -106,9 +112,11 @@ protected: QString _compoundShapeURL; BackgroundMode _backgroundMode = BACKGROUND_MODE_INHERIT; + HazeMode _hazeMode = HAZE_MODE_INHERIT; StagePropertyGroup _stageProperties; SkyboxPropertyGroup _skyboxProperties; + HazePropertyGroup _hazeProperties; bool _flyingAllowed { DEFAULT_FLYING_ALLOWED }; bool _ghostingAllowed { DEFAULT_GHOSTING_ALLOWED }; @@ -116,7 +124,8 @@ protected: // Dirty flags turn true when either keylight properties is changing values. bool _keyLightPropertiesChanged { false }; - bool _backgroundPropertiesChanged { false }; + bool _backgroundPropertiesChanged{ false }; + bool _hazePropertiesChanged{ false }; bool _skyboxPropertiesChanged { false }; bool _stagePropertiesChanged { false }; diff --git a/libraries/model/src/model/Haze.cpp b/libraries/model/src/model/Haze.cpp new file mode 100644 index 0000000000..9844579af2 --- /dev/null +++ b/libraries/model/src/model/Haze.cpp @@ -0,0 +1,163 @@ +// +// Haze.cpp +// libraries/model/src/model +// +// Created by Nissim Hadar on 9/13/2017. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +#include +#include + +#include "Haze.h" + +using namespace model; + +Haze::Haze() { + Parameters parameters; + _parametersBuffer = gpu::BufferView(std::make_shared(sizeof(Parameters), (const gpu::Byte*) ¶meters)); +} + +enum HazeModes { + HAZE_MODE_IS_ACTIVE = 1 << 0, + HAZE_MODE_IS_ALTITUDE_BASED = 1 << 1, + HAZE_MODE_IS_DIRECTIONAL_LIGHT_ATTENUATED = 1 << 2, + HAZE_MODE_IS_MODULATE_COLOR = 1 << 3 +}; + + +// For color modulated mode, the colour values are used as range values, which are then converted to range factors +// This is separate for each colour. +// The colour value is converted from [0.0 .. 1.0] to [5.0 .. 3000.0] +void Haze::setHazeColor(const glm::vec3 hazeColor) { + auto& params = _parametersBuffer.get(); + + if (params.hazeColor.r != hazeColor.r) { + _parametersBuffer.edit().hazeColor.r = hazeColor.r; + + float range = hazeColor.r * 2995.0f + 5.0f; + float factor = convertHazeRangeToHazeRangeFactor(range); + _parametersBuffer.edit().colorModulationFactor.r = factor; + } + if (params.hazeColor.g != hazeColor.g) { + _parametersBuffer.edit().hazeColor.g = hazeColor.g; + + float range = hazeColor.g * 2995.0f + 5.0f; + float factor = convertHazeRangeToHazeRangeFactor(range); + _parametersBuffer.edit().colorModulationFactor.g = factor; + } + + if (params.hazeColor.b != hazeColor.b) { + _parametersBuffer.edit().hazeColor.b = hazeColor.b; + + float range = hazeColor.b * 2995.0f + 5.0f; + float factor = convertHazeRangeToHazeRangeFactor(range); + _parametersBuffer.edit().colorModulationFactor.b = factor; + } +} + +void Haze::setDirectionalLightBlend(const float directionalLightBlend) { + auto& params = _parametersBuffer.get(); + + if (params.directionalLightBlend != directionalLightBlend) { + _parametersBuffer.edit().directionalLightBlend = directionalLightBlend; + } +} + +void Haze::setDirectionalLightColor(const glm::vec3 directionalLightColor) { + auto& params = _parametersBuffer.get(); + + if (params.directionalLightColor.r != directionalLightColor.r) { + _parametersBuffer.edit().directionalLightColor.r = directionalLightColor.r; + } + if (params.directionalLightColor.g != directionalLightColor.g) { + _parametersBuffer.edit().directionalLightColor.g = directionalLightColor.g; + } + if (params.directionalLightColor.b != directionalLightColor.b) { + _parametersBuffer.edit().directionalLightColor.b = directionalLightColor.b; + } +} +void Haze::setIsHazeActive(const bool isHazeActive) { + auto& params = _parametersBuffer.get(); + + if (((params.hazeMode & HAZE_MODE_IS_ACTIVE) == HAZE_MODE_IS_ACTIVE )&& !isHazeActive) { + _parametersBuffer.edit().hazeMode &= ~HAZE_MODE_IS_ACTIVE; + } + else if (((params.hazeMode & HAZE_MODE_IS_ACTIVE) != HAZE_MODE_IS_ACTIVE) && isHazeActive) { + _parametersBuffer.edit().hazeMode |= HAZE_MODE_IS_ACTIVE; + } +} + +void Haze::setIsAltitudeBased(const bool isAltitudeBased) { + auto& params = _parametersBuffer.get(); + + if (((params.hazeMode & HAZE_MODE_IS_ALTITUDE_BASED) == HAZE_MODE_IS_ALTITUDE_BASED )&& !isAltitudeBased) { + _parametersBuffer.edit().hazeMode &= ~HAZE_MODE_IS_ALTITUDE_BASED; + } + else if (((params.hazeMode & HAZE_MODE_IS_ALTITUDE_BASED) != HAZE_MODE_IS_ALTITUDE_BASED) && isAltitudeBased) { + _parametersBuffer.edit().hazeMode |= HAZE_MODE_IS_ALTITUDE_BASED; + } +} + +void Haze::setIsDirectionaLightAttenuationActive(const bool isDirectionaLightAttenuationActive) { + auto& params = _parametersBuffer.get(); + + if (((params.hazeMode & HAZE_MODE_IS_DIRECTIONAL_LIGHT_ATTENUATED) == HAZE_MODE_IS_DIRECTIONAL_LIGHT_ATTENUATED ) && !isDirectionaLightAttenuationActive) { + _parametersBuffer.edit().hazeMode &= ~HAZE_MODE_IS_DIRECTIONAL_LIGHT_ATTENUATED; + } + else if (((params.hazeMode & HAZE_MODE_IS_DIRECTIONAL_LIGHT_ATTENUATED) != HAZE_MODE_IS_DIRECTIONAL_LIGHT_ATTENUATED) && isDirectionaLightAttenuationActive) { + _parametersBuffer.edit().hazeMode |= HAZE_MODE_IS_DIRECTIONAL_LIGHT_ATTENUATED; + } +} + +void Haze::setIsModulateColorActive(const bool isModulateColorActive) { + auto& params = _parametersBuffer.get(); + + if (((params.hazeMode & HAZE_MODE_IS_MODULATE_COLOR) == HAZE_MODE_IS_MODULATE_COLOR ) && !isModulateColorActive) { + _parametersBuffer.edit().hazeMode &= ~HAZE_MODE_IS_MODULATE_COLOR; + } + else if (((params.hazeMode & HAZE_MODE_IS_MODULATE_COLOR) != HAZE_MODE_IS_MODULATE_COLOR) && isModulateColorActive) { + _parametersBuffer.edit().hazeMode |= HAZE_MODE_IS_MODULATE_COLOR; + } +} + +void Haze::setHazeRangeFactor(const float hazeRangeFactor) { + auto& params = _parametersBuffer.get(); + + if (params.hazeRangeFactor != hazeRangeFactor) { + _parametersBuffer.edit().hazeRangeFactor = hazeRangeFactor; + } +} + +void Haze::setHazeAltitudeFactor(const float hazeAltitudeFactor) { + auto& params = _parametersBuffer.get(); + + if (params.hazeAltitudeFactor != hazeAltitudeFactor) { + _parametersBuffer.edit().hazeAltitudeFactor = hazeAltitudeFactor; + } +} + +void Haze::setHazeRangeFactorKeyLight(const float hazeRangeFactorKeyLight) { + auto& params = _parametersBuffer.get(); + + if (params.hazeRangeFactorKeyLight != hazeRangeFactorKeyLight) { + _parametersBuffer.edit().hazeRangeFactorKeyLight = hazeRangeFactorKeyLight; + } +} + +void Haze::setHazeAltitudeFactorKeyLight(const float hazeAltitudeFactorKeyLight) { + auto& params = _parametersBuffer.get(); + + if (params.hazeAltitudeFactorKeyLight != hazeAltitudeFactorKeyLight) { + _parametersBuffer.edit().hazeAltitudeFactorKeyLight = hazeAltitudeFactorKeyLight; + } +} +void Haze::setHazeBaseReference(const float hazeBaseReference) { + auto& params = _parametersBuffer.get(); + + if (params.hazeBaseReference != hazeBaseReference) { + _parametersBuffer.edit().hazeBaseReference = hazeBaseReference; + } +} diff --git a/libraries/model/src/model/Haze.h b/libraries/model/src/model/Haze.h new file mode 100644 index 0000000000..de026bd4ea --- /dev/null +++ b/libraries/model/src/model/Haze.h @@ -0,0 +1,115 @@ +// +// MakeHaze.h +// libraries/model/src/model +// +// Created by Nissim Hadar on 9/13/2017. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +#ifndef hifi_model_Haze_h +#define hifi_model_Haze_h + +#include +#include "NumericalConstants.h" + +namespace model { + + const double p_005 = 0.05; + + // Derivation (d is distance, b is haze coefficient, f is attenuation, solve for f = 0.05 + // f = exp(-d * b) + // ln(f) = -d * b + // b = -ln(f)/d + inline float convertHazeRangeToHazeRangeFactor(const float hazeRange_m) { return (float)-log(p_005) / hazeRange_m; } + + inline float convertHazeAltitudeToHazeAltitudeFactor(const float hazeAltitude_m) { + return (float)-log(p_005) / hazeAltitude_m; + } + + // Derivation (s is th proportion of sun blend, a is the angle at which the blend is 50%, solve for m = 0.5 + // s = dot(lookAngle, sunAngle) = cos(a) + // m = pow(s, p) + // log(m) = p * log(s) + // p = log(m) / log(s) + inline float convertDirectionalLightAngleToPower(const float directionalLightAngle) { + return log(0.5) / log(cos(RADIANS_PER_DEGREE * directionalLightAngle)); + } + + const glm::vec3 initialHazeColor{ 0.5, 0.6, 0.7 }; + const float initialDirectionalLightAngle_degs{ 30.0f }; + + const glm::vec3 initialDirectionalLightColor{ 1.0, 0.9, 0.7 }; + const float initialHazeBaseReference{ 0.0f }; + + // Haze range is defined here as the range the visibility is reduced by 95% + // Haze altitude is defined here as the altitude (above 0) that the haze is reduced by 95% + const float initialHazeRange_m = 150.0f; + const float initialHazeAltitude_m = 150.0f; + + const float initialHazeRangeKeyLight_m = 150.0f; + const float initialHazeAltitudeKeyLight_m = 150.0f; + + const glm::vec3 initialColorModulationFactor{ + convertHazeRangeToHazeRangeFactor(initialHazeRange_m), + convertHazeRangeToHazeRangeFactor(initialHazeRange_m), + convertHazeRangeToHazeRangeFactor(initialHazeRange_m) + }; + + class Haze { + public: + using UniformBufferView = gpu::BufferView; + + Haze(); + + void setHazeColor(const glm::vec3 hazeColor); + void setDirectionalLightBlend(const float directionalLightBlend); + + void setDirectionalLightColor(const glm::vec3 directionalLightColor); + void setHazeBaseReference(const float hazeBaseReference); + + void setIsHazeActive(const bool isHazeActive); + void setIsAltitudeBased(const bool isAltitudeBased); + void setIsDirectionaLightAttenuationActive(const bool isDirectionaLightAttenuationActive); + void setIsModulateColorActive(const bool isModulateColorActive); + + void setHazeRangeFactor(const float hazeRange); + void setHazeAltitudeFactor(const float hazeAltitude); + + void setHazeRangeFactorKeyLight(const float hazeRangeKeyLight); + void setHazeAltitudeFactorKeyLight(const float hazeAltitudeKeyLight); + + UniformBufferView getParametersBuffer() const { return _parametersBuffer; } + + protected: + class Parameters { + public: + // DO NOT CHANGE ORDER HERE WITHOUT UNDERSTANDING THE std140 LAYOUT + glm::vec3 hazeColor{ initialHazeColor }; + float directionalLightBlend{ convertDirectionalLightAngleToPower(initialDirectionalLightAngle_degs) }; + + glm::vec3 directionalLightColor{ initialDirectionalLightColor }; + float hazeBaseReference{ initialHazeBaseReference }; + + glm::vec3 colorModulationFactor{ initialColorModulationFactor }; + int hazeMode{ 0 }; // bit 0 - set to activate haze attenuation of fragment color + // bit 1 - set to add the effect of altitude to the haze attenuation + // bit 2 - set to activate directional light attenuation mode + + // The haze attenuation exponents used by both fragment and directional light attenuation + float hazeRangeFactor{ convertHazeRangeToHazeRangeFactor(initialHazeRange_m) }; + float hazeAltitudeFactor{ convertHazeAltitudeToHazeAltitudeFactor(initialHazeAltitude_m) }; + + float hazeRangeFactorKeyLight{ convertHazeRangeToHazeRangeFactor(initialHazeRangeKeyLight_m) }; + float hazeAltitudeFactorKeyLight{ convertHazeAltitudeToHazeAltitudeFactor(initialHazeAltitudeKeyLight_m) }; + + Parameters() {} + }; + + UniformBufferView _parametersBuffer; + }; + + using HazePointer = std::shared_ptr; +} +#endif // hifi_model_Haze_h diff --git a/libraries/model/src/model/Stage.cpp b/libraries/model/src/model/Stage.cpp index 6cfb77f2b2..62e9e6adda 100644 --- a/libraries/model/src/model/Stage.cpp +++ b/libraries/model/src/model/Stage.cpp @@ -255,3 +255,14 @@ void SunSkyStage::setSkybox(const SkyboxPointer& skybox) { _skybox = skybox; invalidate(); } + +// Haze +void SunSkyStage::setHazeMode(HazeMode mode) { + _hazeMode = mode; + invalidate(); +} + +void SunSkyStage::setHaze(const HazePointer& haze) { + _haze = haze; + invalidate(); +} diff --git a/libraries/model/src/model/Stage.h b/libraries/model/src/model/Stage.h index 5f48824568..5074bc7a67 100644 --- a/libraries/model/src/model/Stage.h +++ b/libraries/model/src/model/Stage.h @@ -15,6 +15,7 @@ #include "Light.h" #include "Skybox.h" +#include "Haze.h" namespace model { @@ -174,11 +175,27 @@ public: void setSkybox(const SkyboxPointer& skybox); const SkyboxPointer& getSkybox() const { valid(); return _skybox; } + // Haze + enum HazeMode { + NO_HAZE, + YES_HAZE, + + NUM_HAZE_MODES + }; + + void setHazeMode(HazeMode mode); + HazeMode gethazeMode() const { return _hazeMode; } + + void setHaze(const HazePointer& haze); + const HazePointer& getHaze() const { valid(); return _haze; } + protected: BackgroundMode _backgroundMode = SKY_DEFAULT; + HazeMode _hazeMode = NO_HAZE; LightPointer _sunLight; mutable SkyboxPointer _skybox; + mutable HazePointer _haze; float _dayTime = 12.0f; int _yearTime = 0; diff --git a/libraries/octree/src/OctreePacketData.h b/libraries/octree/src/OctreePacketData.h index ed6a49941b..d0255d60ab 100644 --- a/libraries/octree/src/OctreePacketData.h +++ b/libraries/octree/src/OctreePacketData.h @@ -29,6 +29,7 @@ #include #include +#include #include #include #include diff --git a/libraries/shared/src/HazeMode.h b/libraries/shared/src/HazeMode.h new file mode 100644 index 0000000000..ff0caef36b --- /dev/null +++ b/libraries/shared/src/HazeMode.h @@ -0,0 +1,24 @@ +// +// HazeMode.h +// libraries/entities/src +// +// Created by Nissim hadar on 9/21/17. +// Copyright 2013 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_HazeMode_h +#define hifi_HazeMode_h + +enum HazeMode { + HAZE_MODE_INHERIT, + HAZE_MODE_SKYBOX, + + HAZE_MODE_ITEM_COUNT, +}; + + +#endif // hifi_HazeMode_h +