diff --git a/examples/example/entities/changingAtmosphereExample.js b/examples/example/entities/changingAtmosphereExample.js new file mode 100644 index 0000000000..82689fa12b --- /dev/null +++ b/examples/example/entities/changingAtmosphereExample.js @@ -0,0 +1,69 @@ +// +// changingAtmosphereExample.js +// examples +// +// Created by Brad Hefta-Gaub on 4/16/15. +// Copyright 2015 High Fidelity, Inc. +// +// This is an example script that demonstrates creating a zone using the atmosphere features that changes scatter properties +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; + +var count = 0; +var stopAfter = 10000; + +var zoneEntityA = Entities.addEntity({ + type: "Zone", + position: { x: 1000, y: 1000, z: 1000}, + dimensions: { x: 2000, y: 2000, z: 2000 }, + keyLightColor: { red: 255, green: 0, blue: 0 }, + stageSunModelEnabled: false, + shapeType: "sphere", + skyboxMode: "atmosphere", + atmosphere: { + center: { x: 1000, y: 0, z: 1000}, + innerRadius: 1000.0, + outerRadius: 1025.0, + rayleighScattering: 0.0025, // Meaningful values 0 to ~0.01 + mieScattering: 0.0010, // Meaningful values 0 to ~0.01 + + // First two, Meaningful values 0 to 1 each, blue, purple; third meaningful 0.3 to 1 - affects shape + scatteringWavelengths: { x: 0.650, y: 0.570, z: 0.475 }, + hasStars: true + }, + stageLatitude: 37.777, + stageLongitude: 122.407, + stageAltitude: 0.03, + stageDay: 183, + stageHour: 5, + stageSunModelEnabled: true +}); + + +// register the call back so it fires before each data send +Script.update.connect(function(deltaTime) { + // stop it... + if (count >= stopAfter) { + print("calling Script.stop()"); + Script.stop(); + } + count++; + var rayleighScattering = (count / 100000) % 0.01; + var mieScattering = (count / 100000) % 0.01; + var waveX = (count / 2000) % 1; + var waveZ = ((count / 2000) % 0.7) + 0.3; + + Entities.editEntity(zoneEntityA, { + atmosphere: { + rayleighScattering: rayleighScattering, + mieScattering: mieScattering, + scatteringWavelengths: { x: waveX, y: waveX, z: waveZ } + }, + + }); +}); + diff --git a/examples/example/entities/zoneAtmosphereExample.js b/examples/example/entities/zoneAtmosphereExample.js new file mode 100644 index 0000000000..2f21ea3db2 --- /dev/null +++ b/examples/example/entities/zoneAtmosphereExample.js @@ -0,0 +1,63 @@ +// +// zoneAtmosphereExample.js +// examples +// +// Created by Brad Hefta-Gaub on 4/16/15. +// Copyright 2015 High Fidelity, Inc. +// +// This is an example script that demonstrates creating a zone using the atmosphere features +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; + +var count = 0; +var stopAfter = 10000; + +var zoneEntityA = Entities.addEntity({ + type: "Zone", + position: { x: 1000, y: 1000, z: 1000}, + dimensions: { x: 2000, y: 2000, z: 2000 }, + keyLightColor: { red: 255, green: 0, blue: 0 }, + stageSunModelEnabled: false, + shapeType: "sphere", + skyboxMode: "atmosphere", + atmosphere: { + center: { x: 1000, y: 0, z: 1000}, + innerRadius: 1000.0, + outerRadius: 1025.0, + rayleighScattering: 0.0025, + mieScattering: 0.0010, + scatteringWavelengths: { x: 0.650, y: 0.570, z: 0.475 }, + hasStars: false + }, + stageLatitude: 37.777, + stageLongitude: 122.407, + stageAltitude: 0.03, + stageDay: 60, + stageHour: 0, + stageSunModelEnabled: true +}); + + +// register the call back so it fires before each data send +Script.update.connect(function(deltaTime) { + // stop it... + if (count >= stopAfter) { + print("calling Script.stop()"); + Script.stop(); + } + count++; + var newHour = (count / 10) % 24; + var newIntensity = ((count / 10) % 24) / 24; + print("newHour:" + newHour); + print("newIntensity:" + newIntensity); + + Entities.editEntity(zoneEntityA, { + stageHour: newHour, + keyLightIntensity: newIntensity + }); +}); + diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 1447478b5f..e20ee73877 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3087,21 +3087,29 @@ void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, RenderArgs // compute starfield alpha based on distance from atmosphere float alpha = 1.0f; + bool hasStars = true; if (Menu::getInstance()->isOptionChecked(MenuOption::Atmosphere)) { + // TODO: handle this correctly for zones const EnvironmentData& closestData = _environment.getClosestData(theCamera.getPosition()); - float height = glm::distance(theCamera.getPosition(), - closestData.getAtmosphereCenter(theCamera.getPosition())); - if (height < closestData.getAtmosphereInnerRadius()) { - alpha = 0.0f; + + if (closestData.getHasStars()) { + float height = glm::distance(theCamera.getPosition(), closestData.getAtmosphereCenter()); + if (height < closestData.getAtmosphereInnerRadius()) { + alpha = 0.0f; - } else if (height < closestData.getAtmosphereOuterRadius()) { - alpha = (height - closestData.getAtmosphereInnerRadius()) / - (closestData.getAtmosphereOuterRadius() - closestData.getAtmosphereInnerRadius()); + } else if (height < closestData.getAtmosphereOuterRadius()) { + alpha = (height - closestData.getAtmosphereInnerRadius()) / + (closestData.getAtmosphereOuterRadius() - closestData.getAtmosphereInnerRadius()); + } + } else { + hasStars = false; } } // finally render the starfield - _stars.render(theCamera.getFieldOfView(), theCamera.getAspectRatio(), theCamera.getNearClip(), alpha); + if (hasStars) { + _stars.render(theCamera.getFieldOfView(), theCamera.getAspectRatio(), theCamera.getNearClip(), alpha); + } } if (Menu::getInstance()->isOptionChecked(MenuOption::Wireframe)) { diff --git a/interface/src/Application.h b/interface/src/Application.h index 7ae96de193..b432c581e4 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -282,6 +282,9 @@ public: virtual int getBoundaryLevelAdjust() const; virtual PickRay computePickRay(float x, float y); virtual const glm::vec3& getAvatarPosition() const { return _myAvatar->getPosition(); } + virtual void overrideEnvironmentData(const EnvironmentData& newData) { _environment.override(newData); } + virtual void endOverrideEnvironmentData() { _environment.endOverride(); } + NodeBounds& getNodeBoundsDisplay() { return _nodeBoundsDisplay; } diff --git a/interface/src/Environment.cpp b/interface/src/Environment.cpp index a08abfc920..a2b78c2ff5 100644 --- a/interface/src/Environment.cpp +++ b/interface/src/Environment.cpp @@ -71,15 +71,46 @@ void Environment::resetToDefault() { void Environment::renderAtmospheres(Camera& camera) { // get the lock for the duration of the call QMutexLocker locker(&_mutex); - - foreach (const ServerData& serverData, _data) { - // TODO: do something about EnvironmentData - foreach (const EnvironmentData& environmentData, serverData) { - renderAtmosphere(camera, environmentData); + + if (_environmentIsOverridden) { + renderAtmosphere(camera, _overrideData); + } else { + foreach (const ServerData& serverData, _data) { + // TODO: do something about EnvironmentData + foreach (const EnvironmentData& environmentData, serverData) { + renderAtmosphere(camera, environmentData); + } } } } +EnvironmentData Environment::getClosestData(const glm::vec3& position) { + if (_environmentIsOverridden) { + return _overrideData; + } + + // get the lock for the duration of the call + QMutexLocker locker(&_mutex); + + EnvironmentData closest; + float closestDistance = FLT_MAX; + foreach (const ServerData& serverData, _data) { + foreach (const EnvironmentData& environmentData, serverData) { + float distance = glm::distance(position, environmentData.getAtmosphereCenter(position)) - + environmentData.getAtmosphereOuterRadius(); + if (distance < closestDistance) { + closest = environmentData; + closestDistance = distance; + } + } + } + return closest; +} + + +// NOTE: Deprecated - I'm leaving this in for now, but it's not actually used. I made it private +// so that if anyone wants to start using this in the future they will consider how to make it +// work with new physics systems. glm::vec3 Environment::getGravity (const glm::vec3& position) { // // 'Default' gravity pulls you downward in Y when you are near the X/Z plane @@ -115,25 +146,6 @@ glm::vec3 Environment::getGravity (const glm::vec3& position) { return gravity; } -const EnvironmentData Environment::getClosestData(const glm::vec3& position) { - // get the lock for the duration of the call - QMutexLocker locker(&_mutex); - - EnvironmentData closest; - float closestDistance = FLT_MAX; - foreach (const ServerData& serverData, _data) { - foreach (const EnvironmentData& environmentData, serverData) { - float distance = glm::distance(position, environmentData.getAtmosphereCenter(position)) - - environmentData.getAtmosphereOuterRadius(); - if (distance < closestDistance) { - closest = environmentData; - closestDistance = distance; - } - } - } - return closest; -} - bool Environment::findCapsulePenetration(const glm::vec3& start, const glm::vec3& end, float radius, glm::vec3& penetration) { // collide with the "floor" @@ -217,14 +229,14 @@ ProgramObject* Environment::createSkyProgram(const char* from, int* locations) { } void Environment::renderAtmosphere(Camera& camera, const EnvironmentData& data) { - glm::vec3 center = data.getAtmosphereCenter(camera.getPosition()); + glm::vec3 center = data.getAtmosphereCenter(); glPushMatrix(); glTranslatef(center.x, center.y, center.z); glm::vec3 relativeCameraPos = camera.getPosition() - center; float height = glm::length(relativeCameraPos); - + // use the appropriate shader depending on whether we're inside or outside ProgramObject* program; int* locations; diff --git a/interface/src/Environment.h b/interface/src/Environment.h index 525f3b7eb4..1a46a10175 100644 --- a/interface/src/Environment.h +++ b/interface/src/Environment.h @@ -30,15 +30,19 @@ public: void init(); void resetToDefault(); void renderAtmospheres(Camera& camera); + + void override(const EnvironmentData& overrideData) { _overrideData = overrideData; _environmentIsOverridden = true; } + void endOverride() { _environmentIsOverridden = false; } - glm::vec3 getGravity (const glm::vec3& position); - const EnvironmentData getClosestData(const glm::vec3& position); + EnvironmentData getClosestData(const glm::vec3& position); - bool findCapsulePenetration(const glm::vec3& start, const glm::vec3& end, float radius, glm::vec3& penetration); int parseData(const HifiSockAddr& senderSockAddr, const QByteArray& packet); private: + glm::vec3 getGravity (const glm::vec3& position); // NOTE: Deprecated + bool findCapsulePenetration(const glm::vec3& start, + const glm::vec3& end, float radius, glm::vec3& penetration); // NOTE: Deprecated ProgramObject* createSkyProgram(const char* from, int* locations); @@ -74,6 +78,8 @@ private: typedef QHash ServerData; QHash _data; + EnvironmentData _overrideData; + bool _environmentIsOverridden = false; QMutex _mutex; }; diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index c9a968a58e..8c738fe366 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -427,6 +427,25 @@ void EntityTreeRenderer::render(RenderArgs::RenderMode renderMode, _bestZone->getStageAltitude()); scene->setStageDayTime(_bestZone->getStageHour()); scene->setStageYearTime(_bestZone->getStageDay()); + + if (_bestZone->getSkyboxMode() == SKYBOX_MODE_ATMOSPHERE) { + EnvironmentData data = _bestZone->getEnvironmentData(); + glm::vec3 keyLightDirection = scene->getKeyLightDirection(); + glm::vec3 inverseKeyLightDirection = keyLightDirection * -1.0f; + + // NOTE: is this right? It seems like the "sun" should be based on the center of the + // atmosphere, not where the camera is. + glm::vec3 keyLightLocation = _viewState->getAvatarPosition() + + (inverseKeyLightDirection * data.getAtmosphereOuterRadius()); + + data.setSunLocation(keyLightLocation); + + const float KEY_LIGHT_INTENSITY_TO_SUN_BRIGHTNESS_RATIO = 20.0f; + float sunBrightness = scene->getKeyLightIntensity() * KEY_LIGHT_INTENSITY_TO_SUN_BRIGHTNESS_RATIO; + data.setSunBrightness(sunBrightness); + + _viewState->overrideEnvironmentData(data); + } } else { if (_hasPreviousZone) { scene->setKeyLightColor(_previousKeyLightColor); @@ -440,6 +459,7 @@ void EntityTreeRenderer::render(RenderArgs::RenderMode renderMode, scene->setStageYearTime(_previousStageDay); _hasPreviousZone = false; } + _viewState->endOverrideEnvironmentData(); } // we must call endScene while we still have the tree locked so that no one deletes a model diff --git a/libraries/entities/CMakeLists.txt b/libraries/entities/CMakeLists.txt index e57bcf67fa..d21906fa3f 100644 --- a/libraries/entities/CMakeLists.txt +++ b/libraries/entities/CMakeLists.txt @@ -13,4 +13,4 @@ find_package(Bullet REQUIRED) target_include_directories(${TARGET_NAME} SYSTEM PRIVATE ${BULLET_INCLUDE_DIRS}) target_link_libraries(${TARGET_NAME} ${BULLET_LIBRARIES}) -link_hifi_libraries(avatars shared octree gpu model fbx networking animation) +link_hifi_libraries(avatars shared octree gpu model fbx networking animation environment) diff --git a/libraries/entities/src/AtmospherePropertyGroup.cpp b/libraries/entities/src/AtmospherePropertyGroup.cpp new file mode 100644 index 0000000000..54e48023b8 --- /dev/null +++ b/libraries/entities/src/AtmospherePropertyGroup.cpp @@ -0,0 +1,196 @@ +// +// AtmospherePropertyGroup.cpp +// libraries/entities/src +// +// Created by Brad Hefta-Gaub on 12/4/13. +// 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 "AtmospherePropertyGroup.h" +#include "EntityItemProperties.h" +#include "EntityItemPropertiesMacros.h" + +AtmospherePropertyGroup::AtmospherePropertyGroup() { + _center = glm::vec3(0.0f); + _innerRadius = 0.0f; + _outerRadius = 0.0f; + _mieScattering = 0.0f; + _rayleighScattering = 0.0f; + _scatteringWavelengths = glm::vec3(0.0f); + _hasStars = true; +} + +void AtmospherePropertyGroup::copyToScriptValue(QScriptValue& properties, QScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties) const { + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_VEC3(Atmosphere, Center, center); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(Atmosphere, InnerRadius, innerRadius); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(Atmosphere, OuterRadius, outerRadius); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(Atmosphere, MieScattering, mieScattering); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(Atmosphere, RayleighScattering, rayleighScattering); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_VEC3(Atmosphere, ScatteringWavelengths, scatteringWavelengths); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(Atmosphere, HasStars, hasStars); +} + +void AtmospherePropertyGroup::copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings) { + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE_VEC3(atmosphere, center, setCenter); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE_FLOAT(atmosphere, innerRadius, setInnerRadius); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE_FLOAT(atmosphere, outerRadius, setOuterRadius); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE_FLOAT(atmosphere, mieScattering, setMieScattering); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE_FLOAT(atmosphere, rayleighScattering, setRayleighScattering); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE_VEC3(atmosphere, scatteringWavelengths, setScatteringWavelengths); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE_BOOL(atmosphere, hasStars, setHasStars); +} + +void AtmospherePropertyGroup::debugDump() const { + qDebug() << " AtmospherePropertyGroup: ---------------------------------------------"; + qDebug() << " Center:" << getCenter() << " has changed:" << centerChanged(); + qDebug() << " Inner Radius:" << getInnerRadius() << " has changed:" << innerRadiusChanged(); + qDebug() << " Outer Radius:" << getOuterRadius() << " has changed:" << outerRadiusChanged(); + qDebug() << " Mie Scattering:" << getMieScattering() << " has changed:" << mieScatteringChanged(); + qDebug() << " Rayleigh Scattering:" << getRayleighScattering() << " has changed:" << rayleighScatteringChanged(); + qDebug() << " Scattering Wavelengths:" << getScatteringWavelengths() << " has changed:" << scatteringWavelengthsChanged(); + qDebug() << " Has Stars:" << getHasStars() << " has changed:" << hasStarsChanged(); +} + +bool AtmospherePropertyGroup::appentToEditPacket(OctreePacketData* packetData, + EntityPropertyFlags& requestedProperties, + EntityPropertyFlags& propertyFlags, + EntityPropertyFlags& propertiesDidntFit, + int& propertyCount, + OctreeElement::AppendState& appendState) const { + + bool successPropertyFits = true; + + APPEND_ENTITY_PROPERTY(PROP_ATMOSPHERE_CENTER, appendValue, getCenter()); + APPEND_ENTITY_PROPERTY(PROP_ATMOSPHERE_INNER_RADIUS, appendValue, getInnerRadius()); + APPEND_ENTITY_PROPERTY(PROP_ATMOSPHERE_OUTER_RADIUS, appendValue, getOuterRadius()); + APPEND_ENTITY_PROPERTY(PROP_ATMOSPHERE_MIE_SCATTERING, appendValue, getMieScattering()); + APPEND_ENTITY_PROPERTY(PROP_ATMOSPHERE_RAYLEIGH_SCATTERING, appendValue, getRayleighScattering()); + APPEND_ENTITY_PROPERTY(PROP_ATMOSPHERE_SCATTERING_WAVELENGTHS, appendValue, getScatteringWavelengths()); + APPEND_ENTITY_PROPERTY(PROP_ATMOSPHERE_HAS_STARS, appendValue, getHasStars()); + + return true; +} + + +bool AtmospherePropertyGroup::decodeFromEditPacket(EntityPropertyFlags& propertyFlags, const unsigned char*& dataAt , int& processedBytes) { + + int bytesRead = 0; + bool overwriteLocalData = true; + + READ_ENTITY_PROPERTY(PROP_ATMOSPHERE_CENTER, glm::vec3, _center); + READ_ENTITY_PROPERTY(PROP_ATMOSPHERE_INNER_RADIUS, float, _innerRadius); + READ_ENTITY_PROPERTY(PROP_ATMOSPHERE_OUTER_RADIUS, float, _outerRadius); + READ_ENTITY_PROPERTY(PROP_ATMOSPHERE_MIE_SCATTERING, float, _mieScattering); + READ_ENTITY_PROPERTY(PROP_ATMOSPHERE_RAYLEIGH_SCATTERING, float, _rayleighScattering); + READ_ENTITY_PROPERTY(PROP_ATMOSPHERE_SCATTERING_WAVELENGTHS, glm::vec3, _scatteringWavelengths); + READ_ENTITY_PROPERTY(PROP_ATMOSPHERE_HAS_STARS, bool, _hasStars); + + processedBytes += bytesRead; + + return true; +} + +void AtmospherePropertyGroup::markAllChanged() { + _centerChanged = true; + _innerRadiusChanged = true; + _outerRadiusChanged = true; + _mieScatteringChanged = true; + _rayleighScatteringChanged = true; + _scatteringWavelengthsChanged = true; + _hasStarsChanged = true; +} + +EntityPropertyFlags AtmospherePropertyGroup::getChangedProperties() const { + EntityPropertyFlags changedProperties; + + CHECK_PROPERTY_CHANGE(PROP_ATMOSPHERE_CENTER, center); + CHECK_PROPERTY_CHANGE(PROP_ATMOSPHERE_INNER_RADIUS, innerRadius); + CHECK_PROPERTY_CHANGE(PROP_ATMOSPHERE_OUTER_RADIUS, outerRadius); + CHECK_PROPERTY_CHANGE(PROP_ATMOSPHERE_MIE_SCATTERING, mieScattering); + CHECK_PROPERTY_CHANGE(PROP_ATMOSPHERE_RAYLEIGH_SCATTERING, rayleighScattering); + CHECK_PROPERTY_CHANGE(PROP_ATMOSPHERE_SCATTERING_WAVELENGTHS, scatteringWavelengths); + CHECK_PROPERTY_CHANGE(PROP_ATMOSPHERE_HAS_STARS, hasStars); + + return changedProperties; +} + +void AtmospherePropertyGroup::getProperties(EntityItemProperties& properties) const { + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Atmosphere, Center, getCenter); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Atmosphere, InnerRadius, getInnerRadius); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Atmosphere, OuterRadius, getOuterRadius); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Atmosphere, MieScattering, getMieScattering); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Atmosphere, MieScattering, getMieScattering); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Atmosphere, RayleighScattering, getRayleighScattering); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Atmosphere, ScatteringWavelengths, getScatteringWavelengths); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Atmosphere, HasStars, getHasStars); +} + +bool AtmospherePropertyGroup::setProperties(const EntityItemProperties& properties) { + bool somethingChanged = false; + + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Atmosphere, Center, center, setCenter); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Atmosphere, InnerRadius, innerRadius, setInnerRadius); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Atmosphere, OuterRadius, outerRadius, setOuterRadius); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Atmosphere, MieScattering, mieScattering, setMieScattering); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Atmosphere, RayleighScattering, rayleighScattering, setRayleighScattering); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Atmosphere, ScatteringWavelengths, scatteringWavelengths, setScatteringWavelengths); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Atmosphere, HasStars, hasStars, setHasStars); + + return somethingChanged; +} + +EntityPropertyFlags AtmospherePropertyGroup::getEntityProperties(EncodeBitstreamParams& params) const { + EntityPropertyFlags requestedProperties; + + requestedProperties += PROP_ATMOSPHERE_CENTER; + requestedProperties += PROP_ATMOSPHERE_INNER_RADIUS; + requestedProperties += PROP_ATMOSPHERE_OUTER_RADIUS; + requestedProperties += PROP_ATMOSPHERE_MIE_SCATTERING; + requestedProperties += PROP_ATMOSPHERE_RAYLEIGH_SCATTERING; + requestedProperties += PROP_ATMOSPHERE_SCATTERING_WAVELENGTHS; + requestedProperties += PROP_ATMOSPHERE_HAS_STARS; + + return requestedProperties; +} + +void AtmospherePropertyGroup::appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params, + EntityTreeElementExtraEncodeData* entityTreeElementExtraEncodeData, + EntityPropertyFlags& requestedProperties, + EntityPropertyFlags& propertyFlags, + EntityPropertyFlags& propertiesDidntFit, + int& propertyCount, + OctreeElement::AppendState& appendState) const { + + bool successPropertyFits = true; + + APPEND_ENTITY_PROPERTY(PROP_ATMOSPHERE_CENTER, appendValue, getCenter()); + APPEND_ENTITY_PROPERTY(PROP_ATMOSPHERE_INNER_RADIUS, appendValue, getInnerRadius()); + APPEND_ENTITY_PROPERTY(PROP_ATMOSPHERE_OUTER_RADIUS, appendValue, getOuterRadius()); + APPEND_ENTITY_PROPERTY(PROP_ATMOSPHERE_MIE_SCATTERING, appendValue, getMieScattering()); + APPEND_ENTITY_PROPERTY(PROP_ATMOSPHERE_RAYLEIGH_SCATTERING, appendValue, getRayleighScattering()); + APPEND_ENTITY_PROPERTY(PROP_ATMOSPHERE_SCATTERING_WAVELENGTHS, appendValue, getScatteringWavelengths()); + APPEND_ENTITY_PROPERTY(PROP_ATMOSPHERE_HAS_STARS, appendValue, getHasStars()); +} + +int AtmospherePropertyGroup::readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, + ReadBitstreamToTreeParams& args, + EntityPropertyFlags& propertyFlags, bool overwriteLocalData) { + + int bytesRead = 0; + const unsigned char* dataAt = data; + + READ_ENTITY_PROPERTY(PROP_ATMOSPHERE_CENTER, glm::vec3, _center); + READ_ENTITY_PROPERTY(PROP_ATMOSPHERE_INNER_RADIUS, float, _innerRadius); + READ_ENTITY_PROPERTY(PROP_ATMOSPHERE_OUTER_RADIUS, float, _outerRadius); + READ_ENTITY_PROPERTY(PROP_ATMOSPHERE_MIE_SCATTERING, float, _mieScattering); + READ_ENTITY_PROPERTY(PROP_ATMOSPHERE_RAYLEIGH_SCATTERING, float, _rayleighScattering); + READ_ENTITY_PROPERTY(PROP_ATMOSPHERE_SCATTERING_WAVELENGTHS, glm::vec3, _scatteringWavelengths); + READ_ENTITY_PROPERTY(PROP_ATMOSPHERE_HAS_STARS, bool, _hasStars); + + return bytesRead; +} diff --git a/libraries/entities/src/AtmospherePropertyGroup.h b/libraries/entities/src/AtmospherePropertyGroup.h new file mode 100644 index 0000000000..e081033cd6 --- /dev/null +++ b/libraries/entities/src/AtmospherePropertyGroup.h @@ -0,0 +1,102 @@ +// +// AtmospherePropertyGroup.h +// libraries/entities/src +// +// Created by Brad Hefta-Gaub on 12/4/13. +// 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_AtmospherePropertyGroup_h +#define hifi_AtmospherePropertyGroup_h + +#include + +#include "PropertyGroup.h" +#include "EntityItemPropertiesMacros.h" + +class EntityItemProperties; +class EncodeBitstreamParams; +class OctreePacketData; +class EntityTreeElementExtraEncodeData; +class ReadBitstreamToTreeParams; + +#include +#include + + +/* + +#include + +#include +#include +#include + +#include +#include // for SittingPoint +#include +#include +#include + +#include "EntityItemID.h" +#include "AtmospherePropertyGroupMacros.h" +#include "EntityTypes.h" +*/ + + +class AtmospherePropertyGroup : public PropertyGroup { +public: + AtmospherePropertyGroup(); + virtual ~AtmospherePropertyGroup() {} + + // EntityItemProperty related helpers + virtual void copyToScriptValue(QScriptValue& properties, QScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties) const; + virtual void copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings); + virtual void debugDump() const; + + virtual bool appentToEditPacket(OctreePacketData* packetData, + EntityPropertyFlags& requestedProperties, + EntityPropertyFlags& propertyFlags, + EntityPropertyFlags& propertiesDidntFit, + int& propertyCount, + OctreeElement::AppendState& appendState) const; + + virtual bool decodeFromEditPacket(EntityPropertyFlags& propertyFlags, const unsigned char*& dataAt , int& processedBytes); + virtual void markAllChanged(); + virtual EntityPropertyFlags getChangedProperties() const; + + // EntityItem related helpers + // methods for getting/setting all properties of an entity + virtual void getProperties(EntityItemProperties& propertiesOut) const; + + /// returns true if something changed + virtual bool setProperties(const EntityItemProperties& properties); + + virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const; + + virtual void appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params, + EntityTreeElementExtraEncodeData* entityTreeElementExtraEncodeData, + EntityPropertyFlags& requestedProperties, + EntityPropertyFlags& propertyFlags, + EntityPropertyFlags& propertiesDidntFit, + int& propertyCount, + OctreeElement::AppendState& appendState) const; + + virtual int readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, + ReadBitstreamToTreeParams& args, + EntityPropertyFlags& propertyFlags, bool overwriteLocalData); + + + DEFINE_PROPERTY_REF(PROP_ATMOSPHERE_CENTER, Center, center, glm::vec3); + DEFINE_PROPERTY(PROP_ATMOSPHERE_INNER_RADIUS, InnerRadius, innerRadius, float); + DEFINE_PROPERTY(PROP_ATMOSPHERE_OUTER_RADIUS, OuterRadius, outerRadius, float); + DEFINE_PROPERTY(PROP_ATMOSPHERE_MIE_SCATTERING, MieScattering, mieScattering, float); + DEFINE_PROPERTY(PROP_ATMOSPHERE_RAYLEIGH_SCATTERING, RayleighScattering, rayleighScattering, float); + DEFINE_PROPERTY_REF(PROP_ATMOSPHERE_SCATTERING_WAVELENGTHS, ScatteringWavelengths, scatteringWavelengths, glm::vec3); + DEFINE_PROPERTY(PROP_ATMOSPHERE_HAS_STARS, HasStars, hasStars, bool); +}; + +#endif // hifi_AtmospherePropertyGroup_h diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index 0a416aeaf5..7613f1912c 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -27,6 +27,8 @@ #include "TextEntityItem.h" #include "ZoneEntityItem.h" +AtmospherePropertyGroup EntityItemProperties::_staticAtmosphere; + EntityPropertyList PROP_LAST_ITEM = (EntityPropertyList)(PROP_AFTER_LAST_ITEM - 1); EntityItemProperties::EntityItemProperties() : @@ -87,6 +89,7 @@ EntityItemProperties::EntityItemProperties() : CONSTRUCT_PROPERTY(stageDay, ZoneEntityItem::DEFAULT_STAGE_DAY), CONSTRUCT_PROPERTY(stageHour, ZoneEntityItem::DEFAULT_STAGE_HOUR), CONSTRUCT_PROPERTY(name, ENTITY_ITEM_DEFAULT_NAME), + CONSTRUCT_PROPERTY(skyboxMode, SKYBOX_MODE_INHERIT), _id(UNKNOWN_ENTITY_ID), _idSet(false), @@ -234,6 +237,43 @@ void EntityItemProperties::setShapeTypeFromString(const QString& shapeName) { } } +const char* skyboxModeNames[] = {"inherit", "atmosphere", "texture" }; + +QHash stringToSkyboxModeLookup; + +void addSkyboxMode(SkyboxMode type) { + stringToSkyboxModeLookup[skyboxModeNames[type]] = type; +} + +void buildStringToSkyboxModeLookup() { + addSkyboxMode(SKYBOX_MODE_INHERIT); + addSkyboxMode(SKYBOX_MODE_ATMOSPHERE); + addSkyboxMode(SKYBOX_MODE_TEXTURE); +} + +QString EntityItemProperties::getSkyboxModeAsString() const { + if (_skyboxMode < sizeof(skyboxModeNames) / sizeof(char *)) + return QString(skyboxModeNames[_skyboxMode]); + return QString(skyboxModeNames[SKYBOX_MODE_INHERIT]); +} + +QString EntityItemProperties::getSkyboxModeString(SkyboxMode mode) { + if (mode < sizeof(skyboxModeNames) / sizeof(char *)) + return QString(skyboxModeNames[mode]); + return QString(skyboxModeNames[SKYBOX_MODE_INHERIT]); +} + +void EntityItemProperties::setSkyboxModeFromString(const QString& skyboxMode) { + if (stringToSkyboxModeLookup.empty()) { + buildStringToSkyboxModeLookup(); + } + auto skyboxModeItr = stringToSkyboxModeLookup.find(skyboxMode.toLower()); + if (skyboxModeItr != stringToSkyboxModeLookup.end()) { + _skyboxMode = skyboxModeItr.value(); + _skyboxModeChanged = true; + } +} + EntityPropertyFlags EntityItemProperties::getChangedProperties() const { EntityPropertyFlags changedProperties; @@ -294,6 +334,10 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { CHECK_PROPERTY_CHANGE(PROP_STAGE_DAY, stageDay); CHECK_PROPERTY_CHANGE(PROP_STAGE_HOUR, stageHour); + CHECK_PROPERTY_CHANGE(PROP_SKYBOX_MODE, skyboxMode); + + changedProperties += _atmosphere.getChangedProperties(); + return changedProperties; } @@ -375,6 +419,7 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool COPY_PROPERTY_TO_QSCRIPTVALUE(stageAltitude); COPY_PROPERTY_TO_QSCRIPTVALUE(stageDay); COPY_PROPERTY_TO_QSCRIPTVALUE(stageHour); + COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(skyboxMode, getSkyboxModeAsString()); // Sitting properties support if (!skipDefaults) { @@ -408,6 +453,8 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool if (!skipDefaults) { COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_NO_SKIP(originalTextures, textureNamesList); // gettable, but not settable } + + _atmosphere.copyToScriptValue(properties, engine, skipDefaults, defaultEntityProperties); return properties; } @@ -477,7 +524,8 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object) { COPY_PROPERTY_FROM_QSCRIPTVALUE_FLOAT(stageAltitude, setStageAltitude); COPY_PROPERTY_FROM_QSCRIPTVALUE_INT(stageDay, setStageDay); COPY_PROPERTY_FROM_QSCRIPTVALUE_FLOAT(stageHour, setStageHour); - + COPY_PROPERTY_FROM_QSCRITPTVALUE_ENUM(skyboxMode, SkyboxMode); + _atmosphere.copyFromScriptValue(object, _defaultSettings); _lastEdited = usecTimestampNow(); } @@ -682,6 +730,11 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem APPEND_ENTITY_PROPERTY(PROP_SHAPE_TYPE, appendValue, (uint32_t)properties.getShapeType()); APPEND_ENTITY_PROPERTY(PROP_COMPOUND_SHAPE_URL, appendValue, properties.getCompoundShapeURL()); + + APPEND_ENTITY_PROPERTY(PROP_SKYBOX_MODE, appendValue, (uint32_t)properties.getSkyboxMode()); + + _staticAtmosphere.setProperties(properties); + _staticAtmosphere.appentToEditPacket(packetData, requestedProperties, propertyFlags, propertiesDidntFit, propertyCount, appendState ); } APPEND_ENTITY_PROPERTY(PROP_MARKETPLACE_ID, appendValue, properties.getMarketplaceID()); @@ -931,6 +984,8 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_STAGE_HOUR, float, setStageHour); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_SHAPE_TYPE, ShapeType, setShapeType); READ_ENTITY_PROPERTY_STRING_TO_PROPERTIES(PROP_COMPOUND_SHAPE_URL, setCompoundShapeURL); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_SKYBOX_MODE, SkyboxMode, setSkyboxMode); + properties.getAtmosphere().decodeFromEditPacket(propertyFlags, dataAt , processedBytes); } READ_ENTITY_PROPERTY_STRING_TO_PROPERTIES(PROP_MARKETPLACE_ID, setMarketplaceID); @@ -1032,6 +1087,10 @@ void EntityItemProperties::markAllChanged() { _stageAltitudeChanged = true; _stageDayChanged = true; _stageHourChanged = true; + + _skyboxModeChanged = true; + _atmosphere.markAllChanged(); + } /// The maximum bounding cube for the entity, independent of it's rotation. diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index 8daf0169e8..95072f23a0 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -29,115 +29,11 @@ #include #include +#include "AtmospherePropertyGroup.h" #include "EntityItemID.h" #include "EntityItemPropertiesMacros.h" #include "EntityTypes.h" - -enum EntityPropertyList { - PROP_PAGED_PROPERTY, - PROP_CUSTOM_PROPERTIES_INCLUDED, - - // these properties are supported by the EntityItem base class - PROP_VISIBLE, - PROP_POSITION, - PROP_RADIUS, // NOTE: PROP_RADIUS is obsolete and only included in old format streams - PROP_DIMENSIONS = PROP_RADIUS, - PROP_ROTATION, - PROP_DENSITY, - PROP_VELOCITY, - PROP_GRAVITY, - PROP_DAMPING, - PROP_LIFETIME, - PROP_SCRIPT, - - // these properties are supported by some derived classes - PROP_COLOR, - PROP_MODEL_URL, - PROP_ANIMATION_URL, - PROP_ANIMATION_FPS, - PROP_ANIMATION_FRAME_INDEX, - PROP_ANIMATION_PLAYING, - - // these properties are supported by the EntityItem base class - PROP_REGISTRATION_POINT, - PROP_ANGULAR_VELOCITY, - PROP_ANGULAR_DAMPING, - PROP_IGNORE_FOR_COLLISIONS, - PROP_COLLISIONS_WILL_MOVE, - - // property used by Light entity - PROP_IS_SPOTLIGHT, - PROP_DIFFUSE_COLOR_UNUSED, - PROP_AMBIENT_COLOR_UNUSED, - PROP_SPECULAR_COLOR_UNUSED, - PROP_INTENSITY, // Previously PROP_CONSTANT_ATTENUATION - PROP_LINEAR_ATTENUATION_UNUSED, - PROP_QUADRATIC_ATTENUATION_UNUSED, - PROP_EXPONENT, - PROP_CUTOFF, - - // available to all entities - PROP_LOCKED, - - // used by Model entities - PROP_TEXTURES, - PROP_ANIMATION_SETTINGS, - PROP_USER_DATA, - PROP_SHAPE_TYPE, - - // used by ParticleEffect entities - PROP_MAX_PARTICLES, - PROP_LIFESPAN, - PROP_EMIT_RATE, - PROP_EMIT_DIRECTION, - PROP_EMIT_STRENGTH, - PROP_LOCAL_GRAVITY, - PROP_PARTICLE_RADIUS, - - PROP_COMPOUND_SHAPE_URL, - PROP_MARKETPLACE_ID, - PROP_ACCELERATION, - PROP_SIMULATOR_ID, - PROP_NAME, - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // ATTENTION: add new properties ABOVE this line - PROP_AFTER_LAST_ITEM, - //////////////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////////////////////////// - // WARNING! Do not add props here unless you intentionally mean to reuse PROP_ indexes - // - // These properties of TextEntity piggy back off of properties of ModelEntities, the type doesn't matter - // since the derived class knows how to interpret it's own properties and knows the types it expects - PROP_TEXT_COLOR = PROP_COLOR, - PROP_TEXT = PROP_MODEL_URL, - PROP_LINE_HEIGHT = PROP_ANIMATION_URL, - PROP_BACKGROUND_COLOR = PROP_ANIMATION_FPS, - PROP_COLLISION_MODEL_URL_OLD_VERSION = PROP_ANIMATION_FPS + 1, - - // Aliases/Piggyback properties for Zones. These properties intentionally reuse the enum values for - // other properties which will never overlap with each other. We do this so that we don't have to expand - // the size of the properties bitflags mask - PROP_KEYLIGHT_COLOR = PROP_COLOR, - PROP_KEYLIGHT_INTENSITY = PROP_INTENSITY, - PROP_KEYLIGHT_AMBIENT_INTENSITY = PROP_CUTOFF, - PROP_KEYLIGHT_DIRECTION = PROP_EXPONENT, - PROP_STAGE_SUN_MODEL_ENABLED = PROP_IS_SPOTLIGHT, - PROP_STAGE_LATITUDE = PROP_DIFFUSE_COLOR_UNUSED, - PROP_STAGE_LONGITUDE = PROP_AMBIENT_COLOR_UNUSED, - PROP_STAGE_ALTITUDE = PROP_SPECULAR_COLOR_UNUSED, - PROP_STAGE_DAY = PROP_LINEAR_ATTENUATION_UNUSED, - PROP_STAGE_HOUR = PROP_QUADRATIC_ATTENUATION_UNUSED, - - // WARNING!!! DO NOT ADD PROPS_xxx here unless you really really meant to.... Add them UP above -}; - -typedef PropertyFlags EntityPropertyFlags; - -// this is set at the top of EntityItemProperties.cpp to PROP_AFTER_LAST_ITEM - 1. PROP_AFTER_LAST_ITEM is always -// one greater than the last item property due to the enum's auto-incrementing. -extern EntityPropertyList PROP_LAST_ITEM; +#include "EntityPropertyFlags.h" const quint64 UNKNOWN_CREATED_TIME = 0; @@ -242,6 +138,10 @@ public: DEFINE_PROPERTY(PROP_STAGE_DAY, StageDay, stageDay, quint16); DEFINE_PROPERTY(PROP_STAGE_HOUR, StageHour, stageHour, float); DEFINE_PROPERTY_REF(PROP_NAME, Name, name, QString); + DEFINE_PROPERTY_GROUP(Atmosphere, atmosphere, AtmospherePropertyGroup); + DEFINE_PROPERTY_REF_ENUM(PROP_SKYBOX_MODE, SkyboxMode, skyboxMode, SkyboxMode); + + static QString getSkyboxModeString(SkyboxMode mode); public: @@ -376,6 +276,7 @@ inline QDebug operator<<(QDebug debug, const EntityItemProperties& properties) { DEBUG_PROPERTY_IF_CHANGED(debug, properties, LocalGravity, localGravity, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, ParticleRadius, particleRadius, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, MarketplaceID, marketplaceID, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, SkyboxMode, skyboxMode, ""); debug << " last edited:" << properties.getLastEdited() << "\n"; debug << " edited ago:" << properties.getEditedAgo() << "\n"; diff --git a/libraries/entities/src/EntityItemPropertiesMacros.h b/libraries/entities/src/EntityItemPropertiesMacros.h index 3fc6cfa85f..aa4bd674cd 100644 --- a/libraries/entities/src/EntityItemPropertiesMacros.h +++ b/libraries/entities/src/EntityItemPropertiesMacros.h @@ -51,7 +51,6 @@ } \ } - #define READ_ENTITY_PROPERTY_QUAT(P,M) \ if (propertyFlags.getHasProperty(P)) { \ glm::quat fromBuffer; \ @@ -181,15 +180,25 @@ somethingChanged = true; \ } +#define SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(G,P,p,M) \ + if (properties.get##G().p##Changed()) { \ + M(properties.get##G().get##P()); \ + somethingChanged = true; \ + } + #define SET_ENTITY_PROPERTY_FROM_PROPERTIES_GETTER(C,G,S) \ if (properties.C()) { \ S(properties.G()); \ somethingChanged = true; \ } -#define COPY_ENTITY_PROPERTY_TO_PROPERTIES(M,G) \ - properties._##M = G(); \ - properties._##M##Changed = false; +#define COPY_ENTITY_PROPERTY_TO_PROPERTIES(P,M) \ + properties._##P = M(); \ + properties._##P##Changed = false; + +#define COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(G,P,M) \ + properties.get##G().set##P(M()); \ + properties.get##G().set##P##Changed(false); #define CHECK_PROPERTY_CHANGE(P,M) \ if (_##M##Changed) { \ @@ -197,6 +206,27 @@ } +#define COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_VEC3(G,P,p) \ + if (!skipDefaults || defaultEntityProperties.get##G().get##P() != _##p) { \ + QScriptValue groupProperties = properties.property(#G); \ + if (!groupProperties.isValid()) { \ + groupProperties = engine->newObject(); \ + } \ + QScriptValue V = vec3toScriptValue(engine, _##p); \ + groupProperties.setProperty(#p, V); \ + properties.setProperty(#G, groupProperties); \ + } + +#define COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(G,P,p) \ + if (!skipDefaults || defaultEntityProperties.get##G().get##P() != _##p) { \ + QScriptValue groupProperties = properties.property(#G); \ + if (!groupProperties.isValid()) { \ + groupProperties = engine->newObject(); \ + } \ + groupProperties.setProperty(#p, _##p); \ + properties.setProperty(#G, groupProperties); \ + } + #define COPY_PROPERTY_TO_QSCRIPTVALUE_VEC3(P) \ if (!skipDefaults || defaultEntityProperties._##P != _##P) { \ QScriptValue P = vec3toScriptValue(engine, _##P); \ @@ -243,6 +273,20 @@ } \ } +#define COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE_FLOAT(G, P, S) \ + { \ + QScriptValue G = object.property(#G); \ + if (G.isValid()) { \ + QScriptValue P = G.property(#P); \ + if (P.isValid()) { \ + float newValue = P.toVariant().toFloat(); \ + if (_defaultSettings || newValue != _##P) { \ + S(newValue); \ + } \ + } \ + } \ + } + #define COPY_PROPERTY_FROM_QSCRIPTVALUE_INT(P, S) \ QScriptValue P = object.property(#P); \ if (P.isValid()) { \ @@ -261,6 +305,20 @@ } \ } +#define COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE_BOOL(G, P, S) \ + { \ + QScriptValue G = object.property(#G); \ + if (G.isValid()) { \ + QScriptValue P = G.property(#P); \ + if (P.isValid()) { \ + float newValue = P.toVariant().toBool(); \ + if (_defaultSettings || newValue != _##P) { \ + S(newValue); \ + } \ + } \ + } \ + } + #define COPY_PROPERTY_FROM_QSCRIPTVALUE_STRING(P, S)\ QScriptValue P = object.property(#P); \ if (P.isValid()) { \ @@ -299,6 +357,32 @@ } \ } \ } + +#define COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE_VEC3(G, P, S) \ + { \ + QScriptValue G = object.property(#G); \ + if (G.isValid()) { \ + QScriptValue P = G.property(#P); \ + if (P.isValid()) { \ + QScriptValue x = P.property("x"); \ + QScriptValue y = P.property("y"); \ + QScriptValue z = P.property("z"); \ + if (x.isValid() && y.isValid() && z.isValid()) { \ + glm::vec3 newValue; \ + newValue.x = x.toVariant().toFloat(); \ + newValue.y = y.toVariant().toFloat(); \ + newValue.z = z.toVariant().toFloat(); \ + bool isValid = !glm::isnan(newValue.x) && \ + !glm::isnan(newValue.y) && \ + !glm::isnan(newValue.z); \ + if (isValid && \ + (_defaultSettings || newValue != _##P)) { \ + S(newValue); \ + } \ + } \ + } \ + } \ + } #define COPY_PROPERTY_FROM_QSCRIPTVALUE_QUAT(P, S) \ QScriptValue P = object.property(#P); \ @@ -357,6 +441,14 @@ _##n(V), \ _##n##Changed(false) +#define DEFINE_PROPERTY_GROUP(N, n, T) \ + public: \ + const T& get##N() const { return _##n; } \ + T& get##N() { return _##n; } \ + private: \ + T _##n; \ + static T _static##N; + #define DEFINE_PROPERTY(P, N, n, T) \ public: \ T get##N() const { return _##n; } \ @@ -365,7 +457,7 @@ void set##N##Changed(bool value) { _##n##Changed = value; } \ private: \ T _##n; \ - bool _##n##Changed; + bool _##n##Changed = false; #define DEFINE_PROPERTY_REF(P, N, n, T) \ public: \ @@ -375,7 +467,7 @@ void set##N##Changed(bool value) { _##n##Changed = value; } \ private: \ T _##n; \ - bool _##n##Changed; + bool _##n##Changed = false; #define DEFINE_PROPERTY_REF_WITH_SETTER(P, N, n, T) \ public: \ diff --git a/libraries/entities/src/EntityPropertyFlags.h b/libraries/entities/src/EntityPropertyFlags.h new file mode 100644 index 0000000000..0b5d2ce805 --- /dev/null +++ b/libraries/entities/src/EntityPropertyFlags.h @@ -0,0 +1,167 @@ +// +// EntityPropertyFlags.h +// libraries/entities/src +// +// Created by Brad Hefta-Gaub on 12/4/13. +// 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_EntityPropertyFlags_h +#define hifi_EntityPropertyFlags_h + +/* +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include // for SittingPoint +*/ + +#include + +/* +#include +#include + +#include "AtmospherePropertyGroup.h" +#include "EntityItemID.h" +#include "EntityItemPropertiesMacros.h" +#include "EntityTypes.h" +*/ + +enum EntityPropertyList { + PROP_PAGED_PROPERTY, + PROP_CUSTOM_PROPERTIES_INCLUDED, + + // these properties are supported by the EntityItem base class + PROP_VISIBLE, + PROP_POSITION, + PROP_RADIUS, // NOTE: PROP_RADIUS is obsolete and only included in old format streams + PROP_DIMENSIONS = PROP_RADIUS, + PROP_ROTATION, + PROP_DENSITY, + PROP_VELOCITY, + PROP_GRAVITY, + PROP_DAMPING, + PROP_LIFETIME, + PROP_SCRIPT, + + // these properties are supported by some derived classes + PROP_COLOR, + + // these are used by models only + PROP_MODEL_URL, + PROP_ANIMATION_URL, + PROP_ANIMATION_FPS, + PROP_ANIMATION_FRAME_INDEX, + PROP_ANIMATION_PLAYING, + + // these properties are supported by the EntityItem base class + PROP_REGISTRATION_POINT, + PROP_ANGULAR_VELOCITY, + PROP_ANGULAR_DAMPING, + PROP_IGNORE_FOR_COLLISIONS, + PROP_COLLISIONS_WILL_MOVE, + + // property used by Light entity + PROP_IS_SPOTLIGHT, + PROP_DIFFUSE_COLOR_UNUSED, + PROP_AMBIENT_COLOR_UNUSED, + PROP_SPECULAR_COLOR_UNUSED, + PROP_INTENSITY, // Previously PROP_CONSTANT_ATTENUATION + PROP_LINEAR_ATTENUATION_UNUSED, + PROP_QUADRATIC_ATTENUATION_UNUSED, + PROP_EXPONENT, + PROP_CUTOFF, + + // available to all entities + PROP_LOCKED, + + PROP_TEXTURES, // used by Model entities + PROP_ANIMATION_SETTINGS, // used by Model entities + PROP_USER_DATA, // all entities + PROP_SHAPE_TYPE, // used by Model + zones entities + + // used by ParticleEffect entities + PROP_MAX_PARTICLES, + PROP_LIFESPAN, + PROP_EMIT_RATE, + PROP_EMIT_DIRECTION, + PROP_EMIT_STRENGTH, + PROP_LOCAL_GRAVITY, + PROP_PARTICLE_RADIUS, + + PROP_COMPOUND_SHAPE_URL, // used by Model + zones entities + PROP_MARKETPLACE_ID, // all entities + PROP_ACCELERATION, // all entities + PROP_SIMULATOR_ID, // all entities + PROP_NAME, // all entities + + //////////////////////////////////////////////////////////////////////////////////////////////////// + // ATTENTION: add new properties ABOVE this line + PROP_AFTER_LAST_ITEM, + //////////////////////////////////////////////////////////////////////////////////////////////////// + + //////////////////////////////////////////////////////////////////////////////////////////////////// + // WARNING! Do not add props here unless you intentionally mean to reuse PROP_ indexes + // + // These properties of TextEntity piggy back off of properties of ModelEntities, the type doesn't matter + // since the derived class knows how to interpret it's own properties and knows the types it expects + PROP_TEXT_COLOR = PROP_COLOR, + PROP_TEXT = PROP_MODEL_URL, + PROP_LINE_HEIGHT = PROP_ANIMATION_URL, + PROP_BACKGROUND_COLOR = PROP_ANIMATION_FPS, + PROP_COLLISION_MODEL_URL_OLD_VERSION = PROP_ANIMATION_FPS + 1, + + // Aliases/Piggyback properties for Zones. These properties intentionally reuse the enum values for + // other properties which will never overlap with each other. We do this so that we don't have to expand + // the size of the properties bitflags mask + PROP_KEYLIGHT_COLOR = PROP_COLOR, + PROP_KEYLIGHT_INTENSITY = PROP_INTENSITY, + PROP_KEYLIGHT_AMBIENT_INTENSITY = PROP_CUTOFF, + PROP_KEYLIGHT_DIRECTION = PROP_EXPONENT, + PROP_STAGE_SUN_MODEL_ENABLED = PROP_IS_SPOTLIGHT, + PROP_STAGE_LATITUDE = PROP_DIFFUSE_COLOR_UNUSED, + PROP_STAGE_LONGITUDE = PROP_AMBIENT_COLOR_UNUSED, + PROP_STAGE_ALTITUDE = PROP_SPECULAR_COLOR_UNUSED, + PROP_STAGE_DAY = PROP_LINEAR_ATTENUATION_UNUSED, + PROP_STAGE_HOUR = PROP_QUADRATIC_ATTENUATION_UNUSED, + PROP_ATMOSPHERE_CENTER = PROP_MAX_PARTICLES, + PROP_ATMOSPHERE_INNER_RADIUS = PROP_LIFESPAN, + PROP_ATMOSPHERE_OUTER_RADIUS = PROP_EMIT_RATE, + PROP_ATMOSPHERE_MIE_SCATTERING = PROP_EMIT_DIRECTION, + PROP_ATMOSPHERE_RAYLEIGH_SCATTERING = PROP_EMIT_STRENGTH, + PROP_ATMOSPHERE_SCATTERING_WAVELENGTHS = PROP_LOCAL_GRAVITY, + PROP_ATMOSPHERE_HAS_STARS = PROP_PARTICLE_RADIUS, + PROP_SKYBOX_MODE = PROP_MODEL_URL, + // SunBrightness - same as KeyLight Intensity? + // SunLocation (or direction) - same as KeyLight + + // WARNING!!! DO NOT ADD PROPS_xxx here unless you really really meant to.... Add them UP above +}; + +typedef PropertyFlags EntityPropertyFlags; + +// this is set at the top of EntityItemProperties.cpp to PROP_AFTER_LAST_ITEM - 1. PROP_AFTER_LAST_ITEM is always +// one greater than the last item property due to the enum's auto-incrementing. +extern EntityPropertyList PROP_LAST_ITEM; + + +enum SkyboxMode { + SKYBOX_MODE_INHERIT, + SKYBOX_MODE_ATMOSPHERE, + SKYBOX_MODE_TEXTURE, +}; + + +#endif // hifi_EntityPropertyFlags_h diff --git a/libraries/entities/src/PropertyGroup.h b/libraries/entities/src/PropertyGroup.h new file mode 100644 index 0000000000..7ac4b54a8e --- /dev/null +++ b/libraries/entities/src/PropertyGroup.h @@ -0,0 +1,100 @@ +// +// PropertyGroup.h +// libraries/entities/src +// +// Created by Brad Hefta-Gaub on 12/4/13. +// 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_PropertyGroup_h +#define hifi_PropertyGroup_h + +#include + +//#include "EntityItemProperties.h" +#include "EntityPropertyFlags.h" + +class EntityItemProperties; +class EncodeBitstreamParams; +class OctreePacketData; +class EntityTreeElementExtraEncodeData; +class ReadBitstreamToTreeParams; + +#include + +/* +#include + +#include +#include + +#include +#include +#include + +#include +#include // for SittingPoint +#include +#include +#include + +#include "EntityItemID.h" +#include "PropertyGroupMacros.h" +#include "EntityTypes.h" +*/ + +//typedef PropertyFlags EntityPropertyFlags; + + +class PropertyGroup { +public: + PropertyGroup() {} + virtual ~PropertyGroup() {} + + // EntityItemProperty related helpers + virtual void copyToScriptValue(QScriptValue& properties, QScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties) const = 0; + virtual void copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings) = 0; + virtual void debugDump() const { } + + virtual bool appentToEditPacket(OctreePacketData* packetData, + EntityPropertyFlags& requestedProperties, + EntityPropertyFlags& propertyFlags, + EntityPropertyFlags& propertiesDidntFit, + int& propertyCount, + OctreeElement::AppendState& appendState) const = 0; + + virtual bool decodeFromEditPacket(EntityPropertyFlags& propertyFlags, const unsigned char*& dataAt , int& processedBytes) = 0; + virtual void markAllChanged() = 0; + virtual EntityPropertyFlags getChangedProperties() const = 0; + + // EntityItem related helpers + // methods for getting/setting all properties of an entity + virtual void getProperties(EntityItemProperties& propertiesOut) const = 0; + + /// returns true if something changed + virtual bool setProperties(const EntityItemProperties& properties) = 0; + + /// Override this in your derived class if you'd like to be informed when something about the state of the entity + /// has changed. This will be called with properties change or when new data is loaded from a stream + virtual void somethingChangedNotification() { } + + + virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const = 0; + + virtual void appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params, + EntityTreeElementExtraEncodeData* entityTreeElementExtraEncodeData, + EntityPropertyFlags& requestedProperties, + EntityPropertyFlags& propertyFlags, + EntityPropertyFlags& propertiesDidntFit, + int& propertyCount, + OctreeElement::AppendState& appendState) const = 0; + + virtual int readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, + ReadBitstreamToTreeParams& args, + EntityPropertyFlags& propertyFlags, bool overwriteLocalData) = 0; +}; + +#endif // hifi_PropertyGroup_h diff --git a/libraries/entities/src/ZoneEntityItem.cpp b/libraries/entities/src/ZoneEntityItem.cpp index 4a8b60a28e..a6e11294b9 100644 --- a/libraries/entities/src/ZoneEntityItem.cpp +++ b/libraries/entities/src/ZoneEntityItem.cpp @@ -61,10 +61,32 @@ ZoneEntityItem::ZoneEntityItem(const EntityItemID& entityItemID, const EntityIte _stageHour = DEFAULT_STAGE_HOUR; _shapeType = DEFAULT_SHAPE_TYPE; _compoundShapeURL = DEFAULT_COMPOUND_SHAPE_URL; + + _skyboxMode = SKYBOX_MODE_INHERIT; setProperties(properties); } + +EnvironmentData ZoneEntityItem::getEnvironmentData() const { + EnvironmentData result; + + result.setAtmosphereCenter(_atmospherePropeties.getCenter()); + result.setAtmosphereInnerRadius(_atmospherePropeties.getInnerRadius()); + result.setAtmosphereOuterRadius(_atmospherePropeties.getOuterRadius()); + result.setRayleighScattering(_atmospherePropeties.getRayleighScattering()); + result.setMieScattering(_atmospherePropeties.getMieScattering()); + result.setScatteringWavelengths(_atmospherePropeties.getScatteringWavelengths()); + result.setHasStars(_atmospherePropeties.getHasStars()); + + // NOTE: The sunLocation and SunBrightness will be overwritten in the EntityTreeRenderer to use the + // keyLight details from the scene interface + //result.setSunLocation(1000, 900, 1000)); + //result.setSunBrightness(20.0f); + + return result; +} + EntityItemProperties ZoneEntityItem::getProperties() const { EntityItemProperties properties = EntityItem::getProperties(); // get the properties from our base class @@ -81,6 +103,10 @@ EntityItemProperties ZoneEntityItem::getProperties() const { COPY_ENTITY_PROPERTY_TO_PROPERTIES(shapeType, getShapeType); COPY_ENTITY_PROPERTY_TO_PROPERTIES(compoundShapeURL, getCompoundShapeURL); + COPY_ENTITY_PROPERTY_TO_PROPERTIES(skyboxMode, getSkyboxMode); + + _atmospherePropeties.getProperties(properties); + return properties; } @@ -100,6 +126,11 @@ bool ZoneEntityItem::setProperties(const EntityItemProperties& properties) { SET_ENTITY_PROPERTY_FROM_PROPERTIES(stageHour, setStageHour); SET_ENTITY_PROPERTY_FROM_PROPERTIES(shapeType, updateShapeType); SET_ENTITY_PROPERTY_FROM_PROPERTIES(compoundShapeURL, setCompoundShapeURL); + SET_ENTITY_PROPERTY_FROM_PROPERTIES(skyboxMode, setSkyboxMode); + + bool somethingChangedInAtmosphere = _atmospherePropeties.setProperties(properties); + + somethingChanged = somethingChanged || somethingChangedInAtmosphere; if (somethingChanged) { bool wantDebug = false; @@ -111,13 +142,13 @@ bool ZoneEntityItem::setProperties(const EntityItemProperties& properties) { } setLastEdited(properties._lastEdited); } + return somethingChanged; } int ZoneEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args, EntityPropertyFlags& propertyFlags, bool overwriteLocalData) { - int bytesRead = 0; const unsigned char* dataAt = data; @@ -133,6 +164,9 @@ int ZoneEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, READ_ENTITY_PROPERTY(PROP_STAGE_HOUR, float, _stageHour); READ_ENTITY_PROPERTY_SETTER(PROP_SHAPE_TYPE, ShapeType, updateShapeType); READ_ENTITY_PROPERTY_STRING(PROP_COMPOUND_SHAPE_URL, setCompoundShapeURL); + READ_ENTITY_PROPERTY_SETTER(PROP_SKYBOX_MODE, SkyboxMode, setSkyboxMode); + bytesRead += _atmospherePropeties.readEntitySubclassDataFromBuffer(dataAt, (bytesLeftToRead - bytesRead), args, + propertyFlags, overwriteLocalData); return bytesRead; } @@ -154,6 +188,8 @@ EntityPropertyFlags ZoneEntityItem::getEntityProperties(EncodeBitstreamParams& p requestedProperties += PROP_STAGE_HOUR; requestedProperties += PROP_SHAPE_TYPE; requestedProperties += PROP_COMPOUND_SHAPE_URL; + requestedProperties += PROP_SKYBOX_MODE; + requestedProperties += _atmospherePropeties.getEntityProperties(params); return requestedProperties; } @@ -180,6 +216,11 @@ void ZoneEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBits APPEND_ENTITY_PROPERTY(PROP_STAGE_HOUR, appendValue, getStageHour()); APPEND_ENTITY_PROPERTY(PROP_SHAPE_TYPE, appendValue, (uint32_t)getShapeType()); APPEND_ENTITY_PROPERTY(PROP_COMPOUND_SHAPE_URL, appendValue, getCompoundShapeURL()); + APPEND_ENTITY_PROPERTY(PROP_SKYBOX_MODE, appendValue, (uint32_t)getSkyboxMode()); // could this be a uint16?? + + _atmospherePropeties.appendSubclassData(packetData, params, modelTreeElementExtraEncodeData, requestedProperties, + propertyFlags, propertiesDidntFit, propertyCount, appendState); + } void ZoneEntityItem::debugDump() const { @@ -198,6 +239,9 @@ void ZoneEntityItem::debugDump() const { qCDebug(entities) << " _stageAltitude:" << _stageAltitude; qCDebug(entities) << " _stageDay:" << _stageDay; qCDebug(entities) << " _stageHour:" << _stageHour; + qCDebug(entities) << " _skyboxMode:" << EntityItemProperties::getSkyboxModeString(_skyboxMode); + + _atmospherePropeties.debugDump(); } ShapeType ZoneEntityItem::getShapeType() const { diff --git a/libraries/entities/src/ZoneEntityItem.h b/libraries/entities/src/ZoneEntityItem.h index 0744abf475..a136226346 100644 --- a/libraries/entities/src/ZoneEntityItem.h +++ b/libraries/entities/src/ZoneEntityItem.h @@ -12,6 +12,9 @@ #ifndef hifi_ZoneEntityItem_h #define hifi_ZoneEntityItem_h +#include + +#include "AtmospherePropertyGroup.h" #include "EntityItem.h" class ZoneEntityItem : public EntityItem { @@ -103,6 +106,11 @@ public: const QString getCompoundShapeURL() const { return _compoundShapeURL; } virtual void setCompoundShapeURL(const QString& url); + void setSkyboxMode(SkyboxMode value) { _skyboxMode = value; } + SkyboxMode getSkyboxMode() const { return _skyboxMode; } + + EnvironmentData getEnvironmentData() const; + virtual bool supportsDetailedRayIntersection() const { return true; } virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, bool& keepSearching, OctreeElement*& element, float& distance, BoxFace& face, @@ -138,6 +146,9 @@ protected: ShapeType _shapeType = SHAPE_TYPE_NONE; QString _compoundShapeURL; + + SkyboxMode _skyboxMode = SKYBOX_MODE_INHERIT; + AtmospherePropertyGroup _atmospherePropeties; static bool _drawZoneBoundaries; static bool _zonesArePickable; diff --git a/libraries/environment/src/EnvironmentData.cpp b/libraries/environment/src/EnvironmentData.cpp index 913841fe31..f703b667bc 100644 --- a/libraries/environment/src/EnvironmentData.cpp +++ b/libraries/environment/src/EnvironmentData.cpp @@ -27,7 +27,8 @@ EnvironmentData::EnvironmentData(int id) : _mieScattering(0.0010f), _scatteringWavelengths(0.650f, 0.570f, 0.475f), _sunLocation(1000, 900, 1000), - _sunBrightness(20.0f) { + _sunBrightness(20.0f), + _hasStars(true) { } glm::vec3 EnvironmentData::getAtmosphereCenter(const glm::vec3& cameraPosition) const { diff --git a/libraries/environment/src/EnvironmentData.h b/libraries/environment/src/EnvironmentData.h index 52297682fd..ebbb3d1fb0 100644 --- a/libraries/environment/src/EnvironmentData.h +++ b/libraries/environment/src/EnvironmentData.h @@ -28,6 +28,9 @@ public: void setGravity(float gravity) { _gravity = gravity; } float getGravity() const { return _gravity; } + void setHasStars(bool value) { _hasStars = value; } + bool getHasStars() const { return _hasStars; } + void setAtmosphereCenter(const glm::vec3& center) { _atmosphereCenter = center; } void setAtmosphereInnerRadius(float radius) { _atmosphereInnerRadius = radius; } void setAtmosphereOuterRadius(float radius) { _atmosphereOuterRadius = radius; } @@ -73,6 +76,8 @@ private: glm::vec3 _sunLocation; float _sunBrightness; + + bool _hasStars; }; #endif // hifi_EnvironmentData_h diff --git a/libraries/networking/src/PacketHeaders.cpp b/libraries/networking/src/PacketHeaders.cpp index a9ccec34bb..3f1c3fbbfa 100644 --- a/libraries/networking/src/PacketHeaders.cpp +++ b/libraries/networking/src/PacketHeaders.cpp @@ -74,7 +74,7 @@ PacketVersion versionForPacketType(PacketType type) { return 1; case PacketTypeEntityAddOrEdit: case PacketTypeEntityData: - return VERSION_ENTITIES_HAVE_NAMES; + return VERSION_ENTITIES_ZONE_ENTITIES_HAVE_ATMOSPHERE; case PacketTypeEntityErase: return 2; case PacketTypeAudioStreamStats: diff --git a/libraries/networking/src/PacketHeaders.h b/libraries/networking/src/PacketHeaders.h index 7b12b1a089..c43b98d41f 100644 --- a/libraries/networking/src/PacketHeaders.h +++ b/libraries/networking/src/PacketHeaders.h @@ -140,5 +140,6 @@ const PacketVersion VERSION_ENTITIES_HAVE_UUIDS = 16; const PacketVersion VERSION_ENTITIES_ZONE_ENTITIES_EXIST = 17; const PacketVersion VERSION_ENTITIES_ZONE_ENTITIES_HAVE_DYNAMIC_SHAPE = 18; const PacketVersion VERSION_ENTITIES_HAVE_NAMES = 19; +const PacketVersion VERSION_ENTITIES_ZONE_ENTITIES_HAVE_ATMOSPHERE = 20; #endif // hifi_PacketHeaders_h diff --git a/libraries/render-utils/src/AbstractViewStateInterface.h b/libraries/render-utils/src/AbstractViewStateInterface.h index 0d73614e7c..45cf634186 100644 --- a/libraries/render-utils/src/AbstractViewStateInterface.h +++ b/libraries/render-utils/src/AbstractViewStateInterface.h @@ -18,6 +18,7 @@ class Transform; class QThread; class ViewFrustum; class PickRay; +class EnvironmentData; /// Interface provided by Application to other objects that need access to the current view state details class AbstractViewStateInterface { @@ -32,6 +33,10 @@ public: /// gets the current view frustum for rendering the view state virtual ViewFrustum* getCurrentViewFrustum() = 0; + + /// overrides environment data + virtual void overrideEnvironmentData(const EnvironmentData& newData) = 0; + virtual void endOverrideEnvironmentData() = 0; /// gets the shadow view frustum for rendering the view state virtual ViewFrustum* getShadowViewFrustum() = 0; diff --git a/tests/octree/CMakeLists.txt b/tests/octree/CMakeLists.txt index ffd908741d..b5fb43c260 100644 --- a/tests/octree/CMakeLists.txt +++ b/tests/octree/CMakeLists.txt @@ -3,6 +3,6 @@ set(TARGET_NAME octree-tests) setup_hifi_project(Script Network) # link in the shared libraries -link_hifi_libraries(shared octree gpu model fbx networking entities avatars audio animation script-engine physics) +link_hifi_libraries(shared octree gpu model fbx networking environment entities avatars audio animation script-engine physics) copy_dlls_beside_windows_executable() \ No newline at end of file