game: fancy clouds

This commit is contained in:
Crypto City 2020-01-10 13:09:40 +00:00
parent 289d9c134b
commit b857530615
9 changed files with 409 additions and 16 deletions

View File

@ -135,7 +135,7 @@ void PS() {
vec3 color = vec3(spot*mieCollected + mieFactor*mieCollected + rayleighFactor*rayleighCollected);
vec4 daySky = vec4(color, 1.0) + mix(vec4(0.0, 0.0, 0.0, 1.0), vec4(0.1, 0.2, 0.4, 1.0), interp);
vec4 nightSky = textureCube(sDiffCubeMap, eyeDir);
vec4 nightSky = textureCube(sDiffCubeMap, eyeDir) * .25;
gl_FragColor = mix(nightSky, daySky, interp);
}

View File

@ -51,6 +51,7 @@ target_link_libraries(game_util
set(game_sources
citymesh-urho3d.cc
cloud-cover.cc
free-camera.cc
game-wallet.cc
main-urho3d.cc
@ -77,6 +78,7 @@ set(game_sources
set(game_headers
camera-controller.h
citymesh-urho3d.h
cloud-cover.h
game-wallet.h
map.h
free-camera.h

234
src/game/cloud-cover.cc Normal file
View File

@ -0,0 +1,234 @@
#include <Urho3D/Resource/ResourceCache.h>
#include <Urho3D/Core/Context.h>
#include <Urho3D/Graphics/Model.h>
#include <Urho3D/Graphics/StaticModel.h>
#include <Urho3D/Graphics/Material.h>
#include <Urho3D/Graphics/Octree.h>
#include <Urho3D/Graphics/OctreeQuery.h>
#include <Urho3D/Graphics/Texture2D.h>
#include <Urho3D/Resource/Image.h>
#include "cloud-cover.h"
using namespace Urho3D;
#define DOME_HEIGHT 2000.0f
#define DOME_HORIZON 10000.0f
#define DOME_RADIUS 250.0f
#define HEIGHT_BIAS -20.0f
static const float HORIZON_ANGLE = acosf((DOME_RADIUS - 1.0f) / DOME_RADIUS);
static float rnd(float modulus)
{
uint32_t r = rand() >> 8;
r &= 1023;
return (r - 512.0f) / 512.0f * modulus;
}
CloudCover::CloudCover():
wind(Vector3::ZERO),
jitter(Vector3::ZERO),
n_clouds(0)
{
}
void CloudCover::SetPositionAndRotation(Node *node, float angle, float distance, float dh, const Vector3 &direction, bool rotation_only)
{
// sphere with radius 10 * distance, and origin -9 * distance
// flattened dome (/-----\ shape)
const float alpha = distance / DOME_HORIZON * HORIZON_ANGLE;
const float height = (DOME_HEIGHT + dh) * cosf(M_PI / 2 * alpha / HORIZON_ANGLE);
Vector3 pos(distance * cosf(angle), height + HEIGHT_BIAS, distance * sinf(angle));
if (rotation_only)
{
Vector3 cpos = node->GetPosition();
pos.x_ = cpos.x_;
pos.z_ = cpos.z_;
}
node->SetPosition(pos);
float t = distance / DOME_HORIZON;
Vector3 normal((pos - Vector3(0.0f, DOME_HEIGHT * (1 - DOME_RADIUS), 0.0f)).Normalized());
Quaternion q;
if (!q.FromLookRotation(-normal, direction))
printf("warning: quaternion construction failed\n");
Quaternion more;
more.FromRotationTo(Vector3::FORWARD, Vector3::DOWN);
q = q * more;
node->SetRotation(q);
}
void CloudCover::Init(Scene *scene, const Urho3D::Vector3 &cameraPos)
{
Context *context = scene->GetContext();
ResourceCache* cache = context->GetSubsystem<ResourceCache>();
cloudsNode = scene->CreateChild("clouds");
for (unsigned i = 0; i < n_clouds; ++i)
AddCloud(true);
prevCameraPos = cameraPos;
}
void CloudCover::SetWind(const Vector3 &velocity, const Vector3 &jitter)
{
wind = velocity;
this->jitter = jitter;
}
void CloudCover::SetClouds(unsigned n)
{
n_clouds = n;
}
void CloudCover::AddCloud(bool init)
{
Context *context = cloudsNode->GetContext();
ResourceCache* cache = context->GetSubsystem<ResourceCache>();
auto plane = cache->GetResource<Model>("Models/Plane.mdl");
auto material = cache->GetResource<Material>("Materials/Cloud.xml");
SharedPtr<Node> node(cloudsNode->CreateChild("cloud"));
auto model = node->CreateComponent<StaticModel>();
model->SetModel(plane);
model->SetMaterial(material);
model->SetLightMask(LIGHT_MASK_CLOUDS);
model->SetCastShadows(false);
Vector3 velocity(rnd(jitter.x_), 0.0f, rnd(jitter.z_));
float x, y, distance, angle;
if (init)
{
x = rnd(DOME_HORIZON);
y = rnd(DOME_HORIZON);
distance = sqrt(x * x + y * y);
}
else
{
angle = rnd(80);
Quaternion q;
q.FromAngleAxis(angle, Vector3::UP);
Vector3 target = q * - wind.Normalized() * DOME_HORIZON * .999f;
distance = DOME_HORIZON * .999f;
x = target.x_;
y = target.z_;
}
if (y > 0)
angle = Vector3(1.0f, 0.0f, 0.0f).Angle(Vector3(x, 0.0f, y)) * M_PI / 180.0f;
else
angle = 2 * M_PI - Vector3(1.0f, 0.0f, 0.0f).Angle(Vector3(x, 0.0f, y)) * M_PI / 180.0f;
SetPositionAndRotation(node, angle, distance, clouds.size() * 100.0f, wind+velocity);
node->SetScale(DOME_HEIGHT * (1.4f + rnd(2.6f)));
clouds.push_back({node, velocity, wind.Normalized(), clouds.size() * 100.0f});
}
void CloudCover::Update(float timeStep, const Urho3D::Vector3 &cameraPos)
{
const Vector3 dpos = cameraPos - prevCameraPos;
size_t i;
for (size_t i = 0; i < clouds.size(); ++i)
{
auto &cloud = clouds[i];
Vector3 pos = cloud.node->GetPosition();
pos.y_ = 0.0f;
pos += (cloud.velocity + wind) * timeStep + dpos;
const float angle = Vector3(1.0f, 0.0f, 0.0f).Angle(pos) * M_PI / 180.0f;
const float distance = pos.DistanceToPoint(Vector3::ZERO);
if (distance > DOME_HORIZON)
{
cloud.node->Remove();
if (i != clouds.size() - 1)
cloud = std::move(clouds.back());
--i;
clouds.pop_back();
continue;
}
cloud.node->SetPosition(pos);
SetPositionAndRotation(cloud.node, angle, distance, cloud.dh, cloud.original_direction, true);
}
if (clouds.size() < n_clouds)
AddCloud(false);
prevCameraPos = cameraPos;
}
float CloudCover::GetCover(const Urho3D::Vector3 &position, const Urho3D::Vector3 &direction) const
{
static const float delta = 1.811927f;
static const float deltas[5][2] = {
{ -delta, 0.0f },
{ delta, 0.0f },
{ 0.0f, 0.0f },
{ 0.0f, -delta },
{ 0.0f, delta },
};
float overall_alpha = 0.0f;
for (const auto &delta: deltas)
{
float alpha = 0.0;
Vector3 ray_direction = direction;
Quaternion qx, qy;
qx.FromAngleAxis(delta[0], Vector3::FORWARD);
qy.FromAngleAxis(delta[1], Vector3::RIGHT);
ray_direction = qx * qy * ray_direction;
Ray ray(position, ray_direction);
PODVector<RayQueryResult> results;
RayOctreeQuery query(results, ray, RAY_TRIANGLE_UV, 100000, DRAWABLE_GEOMETRY);
for (const auto &cloud: clouds)
{
Drawable *drawable = cloud.node->GetComponent<StaticModel>();
if (drawable)
drawable->ProcessRayQuery(query, query.result_);
}
for (const auto &result: results)
{
const Drawable *d = result.drawable_;
if (!d)
continue;
const StaticModel *model = dynamic_cast<const StaticModel*>(d);
if (!model)
continue;
const Material *material = model->GetMaterial();
if (!material)
continue;
const Texture *texture = material->GetTexture(TU_DIFFUSE);
if (!texture)
continue;
const Texture2D *texture2d = dynamic_cast<const Texture2D*>(texture);
if (!texture2d)
continue;
SharedPtr<Image> image = texture2d->GetImage();
if (!image)
continue;
int x = result.textureUV_.x_ * image->GetWidth();
if (x < 0)
x = 0;
if (x >= image->GetWidth())
x = image->GetWidth() - 1;
int y = result.textureUV_.y_ * image->GetHeight();
if (y < 0)
y = 0;
if (y >= image->GetHeight())
y = image->GetHeight() - 1;
const Color color = image->GetPixel(x, y);
alpha = 1.0f - (1.0f - alpha) * (1.0f - color.a_);
}
overall_alpha += alpha;
}
return overall_alpha / 5;
}
void CloudCover::RemoveAll()
{
for (auto &cloud: clouds)
{
cloud.node->Remove();
}
clouds.clear();
}

43
src/game/cloud-cover.h Normal file
View File

@ -0,0 +1,43 @@
#pragma once
#include <vector>
#include <Urho3D/Container/Ptr.h>
#include <Urho3D/Scene/Scene.h>
#include <Urho3D/Scene/Node.h>
#include <Urho3D/Graphics/Octree.h>
#include <Urho3D/Graphics/OctreeQuery.h>
#define DRAWABLE_USER_CLOUD 16
#define LIGHT_MASK_CLOUDS 0x10000
class CloudCover
{
public:
CloudCover();
void Init(Urho3D::Scene *scene, const Urho3D::Vector3 &cameraPos);
void Update(float timeStep, const Urho3D::Vector3 &cameraPos);
float GetCover(const Urho3D::Vector3 &position, const Urho3D::Vector3 &direction) const;
void SetWind(const Urho3D::Vector3 &velocity, const Urho3D::Vector3 &jitter = Urho3D::Vector3::ZERO);
void SetClouds(unsigned n);
void RemoveAll();
size_t GetNumActiveClouds() const { return clouds.size(); }
private:
struct Cloud
{
Urho3D::SharedPtr<Urho3D::Node> node;
Urho3D::Vector3 velocity;
Urho3D::Vector3 original_direction;
float dh;
};
void SetPositionAndRotation(Urho3D::Node *node, float angle, float distance, float dh, const Urho3D::Vector3 &direction, bool rotation_only = false);
void AddCloud(bool init);
Urho3D::SharedPtr<Urho3D::Node> cloudsNode;
std::vector<Cloud> clouds;
Urho3D::Vector3 prevCameraPos;
Urho3D::Vector3 wind;
Urho3D::Vector3 jitter;
unsigned n_clouds;
};

View File

@ -42,6 +42,7 @@
#include "camera-controller.h"
#include "free-camera.h"
#include "walker-camera.h"
#include "cloud-cover.h"
#define USE_PROC_SKY
@ -49,8 +50,12 @@ using namespace Urho3D;
const float TOUCH_SENSITIVITY = 2.0f;
#define CLOUDS_LIGHT_DISTANCE 12000.0f
#define CONFIG_SHADOWS "shadows"
#define DEFAULT_SHADOWS false
#define DEFAULT_SHADOWS true
#define CONFIG_CLOUDS "clouds"
#define DEFAULT_CLOUDS false
#define CONFIG_DYNAMIC_SKY "dynamic-sky"
#define DEFAULT_DYNAMIC_SKY true
#define CONFIG_TIME_OF_DAY "time-of-day"
@ -151,6 +156,7 @@ public:
void HandleResearch(StringHash eventType, VariantMap& eventData);
void HandleResized(StringHash eventType, VariantMap& eventData);
void HandleEnableShadows(StringHash eventType, VariantMap& eventData);
void HandleEnableClouds(StringHash eventType, VariantMap& eventData);
void HandleEnableDynamicSky(StringHash eventType, VariantMap& eventData);
void HandleTimeOfDay(StringHash eventType, VariantMap& eventData);
@ -195,6 +201,7 @@ private:
void RemoveBlock(bool use_selection);
Vector<Pair<SharedPtr<Texture>, unsigned int>> LoadImage(const String &filename);
void EnableShadows(bool enable);
void EnableClouds(bool enable);
void EnableDynamicSky(bool enable);
void SetTimeOfDay(float t);
void UpdateSky();
@ -208,6 +215,7 @@ private:
SharedPtr<Scene> scene_;
SharedPtr<Node> cameraNode_;
SharedPtr<Node> cloudsLightNode_;
SharedPtr<CameraController> camera_;
SharedPtr<Viewport> viewport;
@ -250,6 +258,7 @@ private:
UIConsole console;
Urho3D::SharedPtr<Node> mainLightNode;
Urho3D::SharedPtr<Node> procskyNode;
CloudCover clouds;
};
CryptoCityUrho3D::CryptoCityUrho3D(Context *ctx):
@ -614,6 +623,7 @@ void CryptoCityUrho3D::SetupUI()
SubscribeToEvent(ui, E_CRYPTOCITY_CHAT, URHO3D_HANDLER(CryptoCityUrho3D, HandleChat));
SubscribeToEvent(ui, E_CRYPTOCITY_RESEARCH, URHO3D_HANDLER(CryptoCityUrho3D, HandleResearch));
SubscribeToEvent(ui, E_CRYPTOCITY_ENABLE_SHADOWS, URHO3D_HANDLER(CryptoCityUrho3D, HandleEnableShadows));
SubscribeToEvent(ui, E_CRYPTOCITY_ENABLE_CLOUDS, URHO3D_HANDLER(CryptoCityUrho3D, HandleEnableClouds));
SubscribeToEvent(ui, E_CRYPTOCITY_ENABLE_DYNAMIC_SKY, URHO3D_HANDLER(CryptoCityUrho3D, HandleEnableDynamicSky));
SubscribeToEvent(ui, E_CRYPTOCITY_TIME_OF_DAY, URHO3D_HANDLER(CryptoCityUrho3D, HandleTimeOfDay));
SubscribeToEvent(&gameState, E_CRYPTOCITY_REQUEST_PLAYER_DATA, URHO3D_HANDLER(CryptoCityUrho3D, HandleRequestPlayerData));
@ -813,6 +823,28 @@ void CryptoCityUrho3D::EnableShadows(bool enable)
}
}
void CryptoCityUrho3D::EnableClouds(bool enable)
{
if (enable)
{
if (clouds.GetNumActiveClouds() == 0)
{
clouds.SetWind(Vector3(10, 0, 4), Vector3(6, 0, 3));
clouds.SetClouds(40);
clouds.Init(scene_, cameraNode_->GetPosition());
}
if (cloudsLightNode_)
scene_->AddChild(cloudsLightNode_);
}
else
{
clouds.SetClouds(0);
clouds.RemoveAll();
if (cloudsLightNode_)
scene_->RemoveChild(cloudsLightNode_);
}
}
void CryptoCityUrho3D::EnableDynamicSky(bool enable)
{
auto* cache = GetSubsystem<ResourceCache>();
@ -879,15 +911,36 @@ void CryptoCityUrho3D::CreateScene()
// Create a Zone for ambient light & fog control
Node* zoneNode = scene_->CreateChild("Zone");
auto* zone = zoneNode->CreateComponent<Zone>();
zone->SetBoundingBox(BoundingBox(-1000.0f, 1000.0f));
zone->SetBoundingBox(BoundingBox(Vector3(-2000.0f, -1.0f, -2000.0f), Vector3(2000.0f, 999.0f, 2000.0f)));
zone->SetAmbientColor(Color(0.7f, 0.7f, 0.7f));
zone->SetFogColor(Color(0.2f, 0.2f, 0.2f));
zone->SetFogStart(2000.0f);
zone->SetFogEnd(2500.0f);
zone->SetFogStart(1750.0f);
zone->SetFogEnd(2000.0f);
zone->SetPriority(100);
// Create a Zone for clouds only
Node* cloudsZoneNode = scene_->CreateChild("CloudsZone");
auto* cloudsZone = cloudsZoneNode->CreateComponent<Zone>();
cloudsZone->SetBoundingBox(BoundingBox(Vector3(-200000.0f, -1000.0f, -200000.0f), Vector3(200000.0f, 2000000.0f, 200000.0f)));
cloudsZone->SetLightMask(0xffff | LIGHT_MASK_CLOUDS);
cloudsZone->SetFogStart(2000000.0f);
cloudsZone->SetFogEnd(2500000.0f);
cloudsZone->SetPriority(20);
// Create a node for the directional light, UpdateSky will take care of the rest
mainLightNode = scene_->CreateChild("DirectionalLight");
// A light just for clouds
cloudsLightNode_ = scene_->CreateChild("CloudsLight");
Light *cloudsLight = cloudsLightNode_->CreateComponent<Light>();
cloudsLight->SetLightMask(LIGHT_MASK_CLOUDS);
cloudsLight->SetLightType(LIGHT_POINT);
cloudsLight->SetColor(Color(1.0f, .0f, .0f, 1.0f));
cloudsLight->SetSpecularIntensity(0.0f);
cloudsLight->SetRange(CLOUDS_LIGHT_DISTANCE * 0.95f);
cloudsLight->SetCastShadows(false);
cloudsLight->SetPerVertex(true);
#define FIRST_CITY_X ((uint32_t)466920160)
#define FIRST_CITY_Y ((uint32_t)2502907875)
const uint32_t ox = FIRST_CITY_X, oy = FIRST_CITY_Y;
@ -942,6 +995,7 @@ printf("%d plots, origin %u %u\n", plots, ox, oy);
camera_ = new FreeCamera(cameraNode_);
EnableShadows(GetConfigValue(CONFIG_SHADOWS, DEFAULT_SHADOWS));
EnableClouds(GetConfigValue(CONFIG_CLOUDS, DEFAULT_CLOUDS));
EnableDynamicSky(GetConfigValue(CONFIG_DYNAMIC_SKY, DEFAULT_DYNAMIC_SKY));
SetTimeOfDay(GetConfigValue(CONFIG_TIME_OF_DAY, DEFAULT_TIME_OF_DAY));
}
@ -957,7 +1011,7 @@ void CryptoCityUrho3D::SetupViewport()
cameraNode_->SetPosition(Vector3(0.0f, 10.0f, -100.0f));
cameraNode_->LookAt(Vector3(0.0f, cameraNode_->GetPosition().y_, 0.0f));
auto* camera = cameraNode_->CreateComponent<Camera>();
camera->SetFarClip(2600.0f);
camera->SetFarClip(260000.0f);
}
// Set up a viewport to the Renderer subsystem so that the 3D scene can be seen
@ -1050,6 +1104,7 @@ void CryptoCityUrho3D::UpdateSky()
{
const bool realtime_sky = GetConfigValue(CONFIG_TIME_OF_DAY, DEFAULT_TIME_OF_DAY) == -1.0f;
time_t now = time(NULL);
bool disable_procsky = true;
if (realtime_sky)
{
@ -1063,8 +1118,10 @@ void CryptoCityUrho3D::UpdateSky()
float sin_timeOfDay = sin(timeOfDay);
float interp = fmax(sin_timeOfDay, 0.0f);
float evening = fmax(cos(M_PI * .65f + timeOfDay), 0);
evening = std::min(evening, (interp - 0.0f) * 12.0f);
float evening = fmax(cos(M_PI * .55f + timeOfDay), 0);
float clouds_reddening = 4 * fmax((cos(M_PI * 1.0f + timeOfDay) - .75f), 0.0f);
clouds_reddening *= clouds_reddening * clouds_reddening * clouds_reddening;
clouds_reddening *= clouds_reddening * clouds_reddening * clouds_reddening;
Color DARK_SUN(0.0, 0.0, 0.0);
//Color LIGHT_SUN(1, .9, .9);
@ -1075,15 +1132,20 @@ void CryptoCityUrho3D::UpdateSky()
Color LIGHT_AMBIENT(.75, .6, .675, 1);
//Color LIGHT_AMBIENT(1, .8, .9, 5);
Color EVENING_AMBIENT_INFLUENCE(.9, .2, .3, 1);
Color EVENING_CLOUDS_AMBIENT(1.1, .0, .0, 1);
Node *zoneNode = scene_->GetChild("Zone");
Zone* zone = zoneNode->GetComponent<Zone>();
Node *cloudsZoneNode = scene_->GetChild("CloudsZone");
Zone* cloudsZone = cloudsZoneNode->GetComponent<Zone>();
Light* sun = mainLightNode->GetComponent<Light>();
Light* cameraLight = cameraNode_->GetComponent<Light>();
Light* cloudsLight = cloudsLightNode_->GetComponent<Light>();
Color ambient = DARK_AMBIENT.Lerp(LIGHT_AMBIENT, interp);
zone->SetAmbientColor(ambient);
zone->SetFogColor(DARK_FOG.Lerp(LIGHT_FOG, interp));
Color cloudsColor = EVENING_CLOUDS_AMBIENT * clouds_reddening;
Color sunColor = DARK_SUN.Lerp(LIGHT_SUN, interp).Lerp(EVENING_AMBIENT_INFLUENCE, evening);
if (interp == 0.0f)
@ -1104,9 +1166,13 @@ void CryptoCityUrho3D::UpdateSky()
}
}
const float cloud_cover = clouds.GetCover(cameraNode_->GetPosition(), mainLightNode->GetRotation() * - Vector3::FORWARD);
if (sun)
{
sun->SetColor(sunColor);
sun->SetBrightness(1.0f - cloud_cover / 2);
sun->SetShadowIntensity(0.35f + cloud_cover * (1.0f - 0.35f));
sun->SetShadowCascade(CascadeParameters(25.0f, 100.0f, 400.0f, 0.0f, 0.8f));
}
@ -1138,7 +1204,7 @@ void CryptoCityUrho3D::UpdateSky()
Quaternion newRot((timeOfDay / M_PI) * 180, Vector3(1, 0.3f, 0));
mainLightNode->SetRotation(-newRot); //inverted since we are looking at direction from sun
if (procskyNode)
if (procskyNode && needSkyUpdate_)
{
auto procsky = procskyNode->GetComponent<ProcSky>();
if (procsky)
@ -1146,8 +1212,21 @@ void CryptoCityUrho3D::UpdateSky()
viewport->GetRenderPath()->SetEnabled("ProcSky", true);
procsky->SetTimeOfDay(timeOfDay);
procsky->Update();
needSkyUpdate_ = false;
disable_procsky = false;
}
}
Vector3 cloudsLightPosition = newRot * - Vector3::FORWARD * CLOUDS_LIGHT_DISTANCE;
cloudsLightPosition.y_ -= 1000;
cloudsLightNode_->SetPosition(cloudsLightPosition);
cloudsLight->SetColor(cloudsColor);
float cloudsInterp = std::max(0.0f, std::min(1.0f, (sin_timeOfDay + .1f) * 6));
Color cloudsAmbient = Color::BLACK.Lerp(Color::WHITE, cloudsInterp);
cloudsZone->SetAmbientColor(cloudsAmbient);
if (disable_procsky)
viewport->GetRenderPath()->SetEnabled("ProcSky", false);
}
void CryptoCityUrho3D::HandleUpdate(StringHash eventType, VariantMap& eventData)
@ -1164,13 +1243,7 @@ void CryptoCityUrho3D::HandleUpdate(StringHash eventType, VariantMap& eventData)
cityMesh->Update(timeStep, mark_new_block);
cityMesh->setHighlight(GetEffectiveSelection(), GetHoverFlag(), flagUnderConstruction, mouse_x, mouse_y, mouse_h, top_x, top_y, top_h);
if (needSkyUpdate_)
{
UpdateSky();
needSkyUpdate_ = false;
}
else
viewport->GetRenderPath()->SetEnabled("ProcSky", false);
UpdateSky();
auto* input = GetSubsystem<Input>();
@ -1201,6 +1274,8 @@ void CryptoCityUrho3D::HandleUpdate(StringHash eventType, VariantMap& eventData)
// Move the camera, scale movement with time step
MoveCamera(timeStep);
clouds.Update(timeStep, cameraNode_->GetPosition());
ui->Update(mouse_x, mouse_y, selection.x0, selection.y0, selection.x1, selection.y1, cityMesh->getDisplayMode() == DisplayModeShowFlags, flagUnderConstruction != boost::none, console.GetNumUnreadLines(), wallet);
mark_new_block = false;
@ -2239,6 +2314,14 @@ void CryptoCityUrho3D::HandleEnableShadows(StringHash eventType, VariantMap& eve
eventData[EnableShadows::P_ENABLE] = GetConfigValue(CONFIG_SHADOWS, DEFAULT_SHADOWS);
}
void CryptoCityUrho3D::HandleEnableClouds(StringHash eventType, VariantMap& eventData)
{
if (eventData.Contains(EnableClouds::P_ENABLE))
EnableClouds(SetConfigValue(CONFIG_CLOUDS, eventData[EnableClouds::P_ENABLE].GetBool()));
else
eventData[EnableClouds::P_ENABLE] = GetConfigValue(CONFIG_CLOUDS, DEFAULT_CLOUDS);
}
void CryptoCityUrho3D::HandleEnableDynamicSky(StringHash eventType, VariantMap& eventData)
{
if (eventData.Contains(EnableDynamicSky::P_ENABLE))

View File

@ -100,6 +100,18 @@ UIOptionsDialog::UIOptionsDialog(Context *ctx):
row->AddChild(shadowsWidget);
shadowsWidget->SetStyleAuto(style);
// clouds
row = new UIElement(context_);
row->SetStyleAuto(style);
row->SetLayout(LM_HORIZONTAL, 6, IntRect(0, 0, 0, 0));
window->AddChild(row);
AddText(row, "Clouds");
cloudsWidget = new CheckBox(context_);
cloudsWidget->SetName("CloudsWidget");
row->AddChild(cloudsWidget);
cloudsWidget->SetStyleAuto(style);
// dynamic sky
row = new UIElement(context_);
row->SetStyleAuto(style);
@ -166,6 +178,7 @@ UIOptionsDialog::UIOptionsDialog(Context *ctx):
SubscribeToEvent(buttonCancel, E_RELEASED, URHO3D_HANDLER(UIOptionsDialog, HandleCancel));
SubscribeToEvent(buttonClose, E_RELEASED, URHO3D_HANDLER(UIOptionsDialog, HandleCancel));
SubscribeToEvent(shadowsWidget, E_TOGGLED, URHO3D_HANDLER(UIOptionsDialog, HandleShadowsChanged));
SubscribeToEvent(cloudsWidget, E_TOGGLED, URHO3D_HANDLER(UIOptionsDialog, HandleCloudsChanged));
SubscribeToEvent(dynamicSkyWidget, E_TOGGLED, URHO3D_HANDLER(UIOptionsDialog, HandleDynamicSkyChanged));
SubscribeToEvent(timeOfDayWidget, E_TEXTCHANGED, URHO3D_HANDLER(UIOptionsDialog, HandleTimeOfDayChanged));
@ -189,6 +202,10 @@ void UIOptionsDialog::Configure()
SendEvent(E_OPTIONS_ENABLE_SHADOWS, newEventData);
shadowsWidget->SetChecked(newEventData[OptionsEnableShadows::P_ENABLE].GetBool());
newEventData = {};
SendEvent(E_OPTIONS_ENABLE_CLOUDS, newEventData);
cloudsWidget->SetChecked(newEventData[OptionsEnableClouds::P_ENABLE].GetBool());
newEventData = {};
SendEvent(E_OPTIONS_ENABLE_DYNAMIC_SKY, newEventData);
dynamicSkyWidget->SetChecked(newEventData[OptionsEnableDynamicSky::P_ENABLE].GetBool());
@ -205,6 +222,13 @@ void UIOptionsDialog::HandleShadowsChanged(StringHash eventType, VariantMap& eve
SendEvent(E_OPTIONS_ENABLE_SHADOWS, newEventData);
}
void UIOptionsDialog::HandleCloudsChanged(StringHash eventType, VariantMap& eventData)
{
VariantMap newEventData;
newEventData[OptionsEnableClouds::P_ENABLE] = cloudsWidget->IsChecked();
SendEvent(E_OPTIONS_ENABLE_CLOUDS, newEventData);
}
void UIOptionsDialog::HandleDynamicSkyChanged(StringHash eventType, VariantMap& eventData)
{
VariantMap newEventData;

View File

@ -21,6 +21,7 @@ URHO3D_EVENT(E_OPTIONS_OKAYED, OptionsOkayed) { }
URHO3D_EVENT(E_OPTIONS_CANCELLED, OptionsCancelled) {}
URHO3D_EVENT(E_OPTIONS_ENABLE_SHADOWS, OptionsEnableShadows) { URHO3D_PARAM(P_ENABLE, Enable); }
URHO3D_EVENT(E_OPTIONS_ENABLE_CLOUDS, OptionsEnableClouds) { URHO3D_PARAM(P_ENABLE, Enable); }
URHO3D_EVENT(E_OPTIONS_ENABLE_DYNAMIC_SKY, OptionsEnableDynamicSky) { URHO3D_PARAM(P_ENABLE, Enable); }
URHO3D_EVENT(E_OPTIONS_TIME_OF_DAY, OptionsTimeOfDay) { URHO3D_PARAM(P_TIME_OF_DAY, TimeOfDay); }
@ -43,12 +44,14 @@ private:
void HandleCancel(Urho3D::StringHash eventType, Urho3D::VariantMap& eventData);
void HandleShadowsChanged(Urho3D::StringHash eventType, Urho3D::VariantMap& eventData);
void HandleCloudsChanged(Urho3D::StringHash eventType, Urho3D::VariantMap& eventData);
void HandleDynamicSkyChanged(Urho3D::StringHash eventType, Urho3D::VariantMap& eventData);
void HandleTimeOfDayChanged(Urho3D::StringHash eventType, Urho3D::VariantMap& eventData);
private:
Urho3D::SharedPtr<Urho3D::Window> window;
Urho3D::SharedPtr<Urho3D::CheckBox> shadowsWidget;
Urho3D::SharedPtr<Urho3D::CheckBox> cloudsWidget;
Urho3D::SharedPtr<Urho3D::CheckBox> dynamicSkyWidget;
Urho3D::SharedPtr<Urho3D::LineEdit> timeOfDayWidget;
};

View File

@ -1125,6 +1125,9 @@ void UIUrho3D::HandleOptions(StringHash eventType, VariantMap& eventData)
SubscribeToEvent(optionsDialog, E_OPTIONS_ENABLE_SHADOWS, [this](StringHash eventType, VariantMap& eventData) {
SendEvent(E_CRYPTOCITY_ENABLE_SHADOWS, eventData);
});
SubscribeToEvent(optionsDialog, E_OPTIONS_ENABLE_CLOUDS, [this](StringHash eventType, VariantMap& eventData) {
SendEvent(E_CRYPTOCITY_ENABLE_CLOUDS, eventData);
});
SubscribeToEvent(optionsDialog, E_OPTIONS_ENABLE_DYNAMIC_SKY, [this](StringHash eventType, VariantMap& eventData) {
SendEvent(E_CRYPTOCITY_ENABLE_DYNAMIC_SKY, eventData);
});

View File

@ -61,6 +61,7 @@ URHO3D_EVENT(E_CRYPTOCITY_DEMOLISH_FLAG, DemolishFlag) { }
URHO3D_EVENT(E_CRYPTOCITY_CHAT, Chat) { }
URHO3D_EVENT(E_CRYPTOCITY_RESEARCH, Research) { URHO3D_PARAM(P_DISCOVERY, Discovery); URHO3D_PARAM(P_AMOUNT, Amount); }
URHO3D_EVENT(E_CRYPTOCITY_ENABLE_SHADOWS, EnableShadows) { URHO3D_PARAM(P_ENABLE, Enable); }
URHO3D_EVENT(E_CRYPTOCITY_ENABLE_CLOUDS, EnableClouds) { URHO3D_PARAM(P_ENABLE, Enable); }
URHO3D_EVENT(E_CRYPTOCITY_ENABLE_DYNAMIC_SKY, EnableDynamicSky) { URHO3D_PARAM(P_ENABLE, Enable); }
URHO3D_EVENT(E_CRYPTOCITY_TIME_OF_DAY, TimeOfDay) { URHO3D_PARAM(P_TIME_OF_DAY, TimeOfDay); }