Starry sky (#418)
This commit is contained in:
+48
-43
@@ -27,14 +27,14 @@ void TerrainGenerator::init()
|
||||
|
||||
if (lod == 0)
|
||||
{
|
||||
for (int x = 0; x < width - 1; x++)
|
||||
for (int x = 0; x < chunk_width - 1; x++)
|
||||
{
|
||||
for (int z = 0; z < width - 1; z++)
|
||||
for (int z = 0; z < chunk_width - 1; z++)
|
||||
{
|
||||
int lowerLeft = x + z * width;
|
||||
int lowerRight = (x + 1) + z * width;
|
||||
int topLeft = x + (z + 1) * width;
|
||||
int topRight = (x + 1) + (z + 1) * width;
|
||||
int lowerLeft = x + z * chunk_width;
|
||||
int lowerRight = (x + 1) + z * chunk_width;
|
||||
int topLeft = x + (z + 1) * chunk_width;
|
||||
int topRight = (x + 1) + (z + 1) * chunk_width;
|
||||
|
||||
indices.push_back(topLeft);
|
||||
indices.push_back(lowerLeft);
|
||||
@@ -50,14 +50,14 @@ void TerrainGenerator::init()
|
||||
{
|
||||
const int step = 1 << lod;
|
||||
// inner grid:
|
||||
for (int x = 1; x < width - 2; x += step)
|
||||
for (int x = 1; x < chunk_width - 2; x += step)
|
||||
{
|
||||
for (int z = 1; z < width - 2; z += step)
|
||||
for (int z = 1; z < chunk_width - 2; z += step)
|
||||
{
|
||||
int lowerLeft = x + z * width;
|
||||
int lowerRight = (x + step) + z * width;
|
||||
int topLeft = x + (z + step) * width;
|
||||
int topRight = (x + step) + (z + step) * width;
|
||||
int lowerLeft = x + z * chunk_width;
|
||||
int lowerRight = (x + step) + z * chunk_width;
|
||||
int topLeft = x + (z + step) * chunk_width;
|
||||
int topRight = (x + step) + (z + step) * chunk_width;
|
||||
|
||||
indices.push_back(topLeft);
|
||||
indices.push_back(lowerLeft);
|
||||
@@ -69,12 +69,12 @@ void TerrainGenerator::init()
|
||||
}
|
||||
}
|
||||
// bottom border:
|
||||
for (int x = 0; x < width - 1; ++x)
|
||||
for (int x = 0; x < chunk_width - 1; ++x)
|
||||
{
|
||||
const int z = 0;
|
||||
int current = x + z * width;
|
||||
int neighbor = x + 1 + z * width;
|
||||
int connection = 1 + ((x + (step + 1) / 2 - 1) / step) * step + (z + 1) * width;
|
||||
int current = x + z * chunk_width;
|
||||
int neighbor = x + 1 + z * chunk_width;
|
||||
int connection = 1 + ((x + (step + 1) / 2 - 1) / step) * step + (z + 1) * chunk_width;
|
||||
|
||||
indices.push_back(current);
|
||||
indices.push_back(neighbor);
|
||||
@@ -82,7 +82,7 @@ void TerrainGenerator::init()
|
||||
|
||||
if (((x - 1) % (step)) == step / 2) // halfway fill triangle
|
||||
{
|
||||
int connection1 = 1 + (((x - 1) + (step + 1) / 2 - 1) / step) * step + (z + 1) * width;
|
||||
int connection1 = 1 + (((x - 1) + (step + 1) / 2 - 1) / step) * step + (z + 1) * chunk_width;
|
||||
|
||||
indices.push_back(current);
|
||||
indices.push_back(connection);
|
||||
@@ -90,12 +90,12 @@ void TerrainGenerator::init()
|
||||
}
|
||||
}
|
||||
// top border:
|
||||
for (int x = 0; x < width - 1; ++x)
|
||||
for (int x = 0; x < chunk_width - 1; ++x)
|
||||
{
|
||||
const int z = width - 1;
|
||||
int current = x + z * width;
|
||||
int neighbor = x + 1 + z * width;
|
||||
int connection = 1 + ((x + (step + 1) / 2 - 1) / step) * step + (z - 1) * width;
|
||||
const int z = chunk_width - 1;
|
||||
int current = x + z * chunk_width;
|
||||
int neighbor = x + 1 + z * chunk_width;
|
||||
int connection = 1 + ((x + (step + 1) / 2 - 1) / step) * step + (z - 1) * chunk_width;
|
||||
|
||||
indices.push_back(current);
|
||||
indices.push_back(connection);
|
||||
@@ -103,7 +103,7 @@ void TerrainGenerator::init()
|
||||
|
||||
if (((x - 1) % (step)) == step / 2) // halfway fill triangle
|
||||
{
|
||||
int connection1 = 1 + (((x - 1) + (step + 1) / 2 - 1) / step) * step + (z - 1) * width;
|
||||
int connection1 = 1 + (((x - 1) + (step + 1) / 2 - 1) / step) * step + (z - 1) * chunk_width;
|
||||
|
||||
indices.push_back(current);
|
||||
indices.push_back(connection1);
|
||||
@@ -111,12 +111,12 @@ void TerrainGenerator::init()
|
||||
}
|
||||
}
|
||||
// left border:
|
||||
for (int z = 0; z < width - 1; ++z)
|
||||
for (int z = 0; z < chunk_width - 1; ++z)
|
||||
{
|
||||
const int x = 0;
|
||||
int current = x + z * width;
|
||||
int neighbor = x + (z + 1) * width;
|
||||
int connection = x + 1 + (((z + (step + 1) / 2 - 1) / step) * step + 1) * width;
|
||||
int current = x + z * chunk_width;
|
||||
int neighbor = x + (z + 1) * chunk_width;
|
||||
int connection = x + 1 + (((z + (step + 1) / 2 - 1) / step) * step + 1) * chunk_width;
|
||||
|
||||
indices.push_back(current);
|
||||
indices.push_back(connection);
|
||||
@@ -124,7 +124,7 @@ void TerrainGenerator::init()
|
||||
|
||||
if (((z - 1) % (step)) == step / 2) // halfway fill triangle
|
||||
{
|
||||
int connection1 = x + 1 + ((((z - 1) + (step + 1) / 2 - 1) / step) * step + 1) * width;
|
||||
int connection1 = x + 1 + ((((z - 1) + (step + 1) / 2 - 1) / step) * step + 1) * chunk_width;
|
||||
|
||||
indices.push_back(current);
|
||||
indices.push_back(connection1);
|
||||
@@ -132,12 +132,12 @@ void TerrainGenerator::init()
|
||||
}
|
||||
}
|
||||
// right border:
|
||||
for (int z = 0; z < width - 1; ++z)
|
||||
for (int z = 0; z < chunk_width - 1; ++z)
|
||||
{
|
||||
const int x = width - 1;
|
||||
int current = x + z * width;
|
||||
int neighbor = x + (z + 1) * width;
|
||||
int connection = x - 1 + (((z + (step + 1) / 2 - 1) / step) * step + 1) * width;
|
||||
const int x = chunk_width - 1;
|
||||
int current = x + z * chunk_width;
|
||||
int neighbor = x + (z + 1) * chunk_width;
|
||||
int connection = x - 1 + (((z + (step + 1) / 2 - 1) / step) * step + 1) * chunk_width;
|
||||
|
||||
indices.push_back(current);
|
||||
indices.push_back(neighbor);
|
||||
@@ -145,7 +145,7 @@ void TerrainGenerator::init()
|
||||
|
||||
if (((z - 1) % (step)) == step / 2) // halfway fill triangle
|
||||
{
|
||||
int connection1 = x - 1 + ((((z - 1) + (step + 1) / 2 - 1) / step) * step + 1) * width;
|
||||
int connection1 = x - 1 + ((((z - 1) + (step + 1) / 2 - 1) / step) * step + 1) * chunk_width;
|
||||
|
||||
indices.push_back(current);
|
||||
indices.push_back(connection);
|
||||
@@ -547,6 +547,7 @@ void TerrainGenerator::Generation_Restart()
|
||||
weather.cloud_shadow_amount = 0.5f;
|
||||
weather.cloud_shadow_scale = 0.003f;
|
||||
weather.cloud_shadow_speed = 0.25f;
|
||||
weather.stars = 0.6f;
|
||||
}
|
||||
if (scene->lights.GetCount() == 0)
|
||||
{
|
||||
@@ -559,6 +560,7 @@ void TerrainGenerator::Generation_Restart()
|
||||
//light.SetVolumetricsEnabled(true);
|
||||
TransformComponent& transform = *scene->transforms.GetComponent(sunEntity);
|
||||
transform.RotateRollPitchYaw(XMFLOAT3(XM_PIDIV4, 0, XM_PIDIV4));
|
||||
transform.Translate(XMFLOAT3(0, 2, 0));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -579,8 +581,8 @@ void TerrainGenerator::Generation_Update()
|
||||
if (centerToCamCheckBox.GetCheck())
|
||||
{
|
||||
const CameraComponent& camera = GetCamera();
|
||||
center_chunk.x = (int)std::floor((camera.Eye.x + half_width) * width_rcp);
|
||||
center_chunk.z = (int)std::floor((camera.Eye.z + half_width) * width_rcp);
|
||||
center_chunk.x = (int)std::floor((camera.Eye.x + chunk_half_width) * chunk_width_rcp);
|
||||
center_chunk.z = (int)std::floor((camera.Eye.z + chunk_half_width) * chunk_width_rcp);
|
||||
}
|
||||
|
||||
// Chunk removal checks:
|
||||
@@ -641,6 +643,7 @@ void TerrainGenerator::Generation_Update()
|
||||
const float region1 = region1Slider.GetValue();
|
||||
const float region2 = region2Slider.GetValue();
|
||||
const float region3 = region3Slider.GetValue();
|
||||
bool generated_something = false;
|
||||
|
||||
auto request_chunk = [&](int offset_x, int offset_z)
|
||||
{
|
||||
@@ -660,7 +663,7 @@ void TerrainGenerator::Generation_Update()
|
||||
|
||||
TransformComponent& transform = *generation_scene.transforms.GetComponent(chunk_data.entity);
|
||||
transform.ClearTransform();
|
||||
const XMFLOAT3 chunk_pos = XMFLOAT3(float(chunk.x * (width - 1)), 0, float(chunk.z * (width - 1)));
|
||||
const XMFLOAT3 chunk_pos = XMFLOAT3(float(chunk.x * (chunk_width - 1)), 0, float(chunk.z * (chunk_width - 1)));
|
||||
transform.Translate(chunk_pos);
|
||||
transform.UpdateTransform();
|
||||
|
||||
@@ -690,10 +693,10 @@ void TerrainGenerator::Generation_Update()
|
||||
|
||||
// Do a parallel for loop over all the chunk's vertices and compute their properties:
|
||||
wi::jobsystem::context ctx;
|
||||
wi::jobsystem::Dispatch(ctx, vertexCount, width, [&](wi::jobsystem::JobArgs args) {
|
||||
wi::jobsystem::Dispatch(ctx, vertexCount, chunk_width, [&](wi::jobsystem::JobArgs args) {
|
||||
uint32_t index = args.jobIndex;
|
||||
const float x = float(index % width) - half_width;
|
||||
const float z = float(index / width) - half_width;
|
||||
const float x = float(index % chunk_width) - chunk_half_width;
|
||||
const float z = float(index / chunk_width) - chunk_half_width;
|
||||
XMVECTOR corners[3];
|
||||
XMFLOAT2 corner_offsets[3] = {
|
||||
XMFLOAT2(0, 0),
|
||||
@@ -763,7 +766,7 @@ void TerrainGenerator::Generation_Update()
|
||||
mesh.vertex_positions[index] = XMFLOAT3(x, height, z);
|
||||
mesh.vertex_normals[index] = normal;
|
||||
mesh.vertex_colors[index] = wi::Color::fromFloat4(materialBlendWeights);
|
||||
const XMFLOAT2 uv = XMFLOAT2(x * width_rcp + 0.5f, z * width_rcp + 0.5f);
|
||||
const XMFLOAT2 uv = XMFLOAT2(x * chunk_width_rcp + 0.5f, z * chunk_width_rcp + 0.5f);
|
||||
mesh.vertex_uvset_0[index] = uv;
|
||||
|
||||
XMFLOAT3 vertex_pos(chunk_pos.x + x, height, chunk_pos.z + z);
|
||||
@@ -793,7 +796,7 @@ void TerrainGenerator::Generation_Update()
|
||||
chunk_data.grass = std::move(grass); // the grass will be added to the scene later, only when the chunk is close to the camera (center chunk's neighbors)
|
||||
chunk_data.grass.meshID = chunk_data.entity;
|
||||
chunk_data.grass.strandCount = grass_valid_vertex_count.load() * 3;
|
||||
chunk_data.grass.viewDistance = width;
|
||||
chunk_data.grass.viewDistance = chunk_width;
|
||||
generation_scene.materials.Create(chunk_data.entity) = material_GrassParticle;
|
||||
}
|
||||
|
||||
@@ -861,6 +864,7 @@ void TerrainGenerator::Generation_Update()
|
||||
}
|
||||
|
||||
wi::jobsystem::Wait(ctx); // wait until mesh.CreateRenderData() async task finishes
|
||||
generated_something = true;
|
||||
}
|
||||
|
||||
// Grass patch placement:
|
||||
@@ -884,12 +888,13 @@ void TerrainGenerator::Generation_Update()
|
||||
grass.CreateRenderData(*mesh);
|
||||
}
|
||||
chunk_data.grass_exists = true; // don't generate more grass here
|
||||
generated_something = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (timer.elapsed_milliseconds() > generation_time_budget_milliseconds)
|
||||
if (generated_something && timer.elapsed_milliseconds() > generation_time_budget_milliseconds)
|
||||
{
|
||||
generation_cancelled.store(true);
|
||||
}
|
||||
|
||||
@@ -39,11 +39,11 @@ struct ChunkData
|
||||
|
||||
struct TerrainGenerator : public wi::gui::Window
|
||||
{
|
||||
inline static const int width = 64 + 3; // + 3: filler vertices for lod apron and grid perimeter
|
||||
inline static const float half_width = (width - 1) * 0.5f;
|
||||
inline static const float width_rcp = 1.0f / (width - 1);
|
||||
inline static const uint32_t vertexCount = width * width;
|
||||
inline static const int max_lod = (int)std::log2(width - 3) + 1;
|
||||
inline static const int chunk_width = 64 + 3; // + 3: filler vertices for lod apron and grid perimeter
|
||||
inline static const float chunk_half_width = (chunk_width - 1) * 0.5f;
|
||||
inline static const float chunk_width_rcp = 1.0f / (chunk_width - 1);
|
||||
inline static const uint32_t vertexCount = chunk_width * chunk_width;
|
||||
inline static const int max_lod = (int)std::log2(chunk_width - 3) + 1;
|
||||
wi::scene::Scene* scene = &wi::scene::GetScene(); // by default it uses the global scene, but this can be changed
|
||||
wi::ecs::Entity terrainEntity = wi::ecs::INVALID_ENTITY;
|
||||
wi::ecs::Entity materialEntity_Base = wi::ecs::INVALID_ENTITY;
|
||||
|
||||
@@ -162,6 +162,15 @@ void WeatherWindow::Create(EditorComponent* editor)
|
||||
});
|
||||
AddWidget(&skyExposureSlider);
|
||||
|
||||
starsSlider.Create(0, 1, 0.5f, 10000, "Stars: ");
|
||||
starsSlider.SetTooltip("Amount of stars in the night sky (0 to disable). \nIt will only work with the realistic sky enabled. \nThey will be more visible at night time.");
|
||||
starsSlider.SetSize(XMFLOAT2(100, hei));
|
||||
starsSlider.SetPos(XMFLOAT2(x, y += step));
|
||||
starsSlider.OnSlide([&](wi::gui::EventArgs args) {
|
||||
GetWeather().stars = args.fValue;
|
||||
});
|
||||
AddWidget(&starsSlider);
|
||||
|
||||
simpleskyCheckBox.Create("Simple sky: ");
|
||||
simpleskyCheckBox.SetTooltip("Simple sky will simply blend horizon and zenith color from bottom to top.");
|
||||
simpleskyCheckBox.SetSize(XMFLOAT2(hei, hei));
|
||||
@@ -686,6 +695,7 @@ void WeatherWindow::Update()
|
||||
windWaveSizeSlider.SetValue(weather.windWaveSize);
|
||||
windRandomnessSlider.SetValue(weather.windRandomness);
|
||||
skyExposureSlider.SetValue(weather.skyExposure);
|
||||
starsSlider.SetValue(weather.stars);
|
||||
windMagnitudeSlider.SetValue(XMVectorGetX(XMVector3Length(XMLoadFloat3(&weather.windDirection))));
|
||||
|
||||
switch (colorComboBox.GetSelected())
|
||||
|
||||
@@ -32,6 +32,7 @@ public:
|
||||
wi::gui::Slider windWaveSizeSlider;
|
||||
wi::gui::Slider windRandomnessSlider;
|
||||
wi::gui::Slider skyExposureSlider;
|
||||
wi::gui::Slider starsSlider;
|
||||
wi::gui::CheckBox simpleskyCheckBox;
|
||||
wi::gui::CheckBox realisticskyCheckBox;
|
||||
wi::gui::Button skyButton;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
This file contains changelog of wi::Archive versions
|
||||
|
||||
78: serialized stars parameter in weather
|
||||
77: serialized cloud shadow properties
|
||||
76: serialized LOD parameters
|
||||
75: PreviousFrameTransformComponent is no longer serialized
|
||||
|
||||
@@ -303,6 +303,11 @@ struct ShaderWeather
|
||||
float cloud_shadow_scale;
|
||||
float cloud_shadow_speed;
|
||||
|
||||
float3 padding;
|
||||
float stars; // number of stars (0: disable stars, >0: increase number of stars)
|
||||
|
||||
float4x4 stars_rotation;
|
||||
|
||||
ShaderFog fog;
|
||||
ShaderWind wind;
|
||||
ShaderOcean ocean;
|
||||
|
||||
@@ -411,22 +411,35 @@ float3 GetSunLuminance(float3 worldPosition, float3 worldDirection, float3 sunDi
|
||||
float sunHalfApexAngleRadian = 0.5 * sunApexAngleDegree * PI / 180.0;
|
||||
float sunCosHalfApexAngle = cos(sunHalfApexAngleRadian);
|
||||
|
||||
float VdotL = dot(worldDirection, normalize(sunDirection)); // weird... the sun disc shrinks near the horizon if we don't normalize sun direction
|
||||
|
||||
float3 retval = 0;
|
||||
if (VdotL > sunCosHalfApexAngle)
|
||||
{
|
||||
float t = RaySphereIntersectNearest(worldPosition, worldDirection, float3(0.0f, 0.0f, 0.0f), atmosphere.bottomRadius);
|
||||
if (t < 0.0f) // no intersection
|
||||
{
|
||||
const float3 atmosphereTransmittance = GetAtmosphereTransmittance(worldPosition, worldDirection, atmosphere, transmittanceLutTexture);
|
||||
|
||||
// Edge fade
|
||||
float t = RaySphereIntersectNearest(worldPosition, worldDirection, float3(0.0f, 0.0f, 0.0f), atmosphere.bottomRadius);
|
||||
if (t < 0.0f) // no intersection
|
||||
{
|
||||
float VdotL = dot(worldDirection, normalize(sunDirection)); // weird... the sun disc shrinks near the horizon if we don't normalize sun direction
|
||||
if (VdotL > sunCosHalfApexAngle)
|
||||
{
|
||||
// Edge fade
|
||||
const float halfCosHalfApex = sunCosHalfApexAngle + (1.0f - sunCosHalfApexAngle) * 0.25; // Start fading when at 75% distance from light disk center
|
||||
const float weight = 1.0 - saturate((halfCosHalfApex - VdotL) / (halfCosHalfApex - sunCosHalfApexAngle));
|
||||
|
||||
retval = atmosphereTransmittance * weight * sunIlluminance;
|
||||
|
||||
retval = weight * sunIlluminance;
|
||||
}
|
||||
|
||||
if (GetWeather().stars > 0)
|
||||
{
|
||||
float3 stars_direction = mul(worldDirection, (float3x3)GetWeather().stars_rotation);
|
||||
float stars_visibility = pow(saturate(1 - sunDirection.y), 2);
|
||||
float stars_density_at_maximum = lerp(22, 8, GetWeather().stars);
|
||||
float stars_threshold = lerp(32, stars_density_at_maximum, stars_visibility); // modifies the number of stars that are visible
|
||||
float stars_exposure = lerp(0, 512, stars_visibility); // modifies the overall strength of the stars
|
||||
float stars = saturate(pow(noise_gradient_3D(stars_direction * 300), stars_threshold)) * stars_exposure;
|
||||
stars *= lerp(0.4, 1.4, noise_gradient_3D(stars_direction * 256 + GetTime())); // time based flickering
|
||||
retval += stars;
|
||||
}
|
||||
|
||||
const float3 atmosphereTransmittance = GetAtmosphereTransmittance(worldPosition, worldDirection, atmosphere, transmittanceLutTexture);
|
||||
retval *= atmosphereTransmittance;
|
||||
}
|
||||
|
||||
return retval;
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace wi
|
||||
{
|
||||
|
||||
// this should always be only INCREMENTED and only if a new serialization is implemeted somewhere!
|
||||
static constexpr uint64_t __archiveVersion = 77;
|
||||
static constexpr uint64_t __archiveVersion = 78;
|
||||
// this is the version number of which below the archive is not compatible with the current version
|
||||
static constexpr uint64_t __archiveVersionBarrier = 22;
|
||||
|
||||
|
||||
@@ -1906,6 +1906,8 @@ namespace wi::scene
|
||||
shaderscene.weather.ocean.patch_size_rcp = 1.0f / weather.oceanParameters.patch_length;
|
||||
shaderscene.weather.ocean.texture_displacementmap = device->GetDescriptorIndex(ocean.getDisplacementMap(), SubresourceType::SRV);
|
||||
shaderscene.weather.ocean.texture_gradientmap = device->GetDescriptorIndex(ocean.getGradientMap(), SubresourceType::SRV);
|
||||
shaderscene.weather.stars = weather.stars;
|
||||
XMStoreFloat4x4(&shaderscene.weather.stars_rotation, XMMatrixRotationQuaternion(XMLoadFloat4(&weather.stars_rotation_quaternion)));
|
||||
|
||||
shaderscene.ddgi.color_texture = device->GetDescriptorIndex(&ddgiColorTexture[0], SubresourceType::SRV);
|
||||
shaderscene.ddgi.depth_texture = device->GetDescriptorIndex(&ddgiDepthTexture[0], SubresourceType::SRV);
|
||||
@@ -3755,6 +3757,7 @@ namespace wi::scene
|
||||
weather.sunColor = light.color;
|
||||
weather.sunDirection = light.direction;
|
||||
weather.sunEnergy = light.energy;
|
||||
weather.stars_rotation_quaternion = light.rotation;
|
||||
}
|
||||
locker.unlock();
|
||||
break;
|
||||
|
||||
@@ -1172,6 +1172,7 @@ namespace wi::scene
|
||||
float windRandomness = 5;
|
||||
float windWaveSize = 1;
|
||||
float windSpeed = 1;
|
||||
float stars = 0.5f;
|
||||
|
||||
wi::Ocean::OceanParameters oceanParameters;
|
||||
AtmosphereParameters atmosphereParameters;
|
||||
@@ -1184,6 +1185,7 @@ namespace wi::scene
|
||||
uint32_t most_important_light_index = ~0u;
|
||||
wi::Resource skyMap;
|
||||
wi::Resource colorGradingMap;
|
||||
XMFLOAT4 stars_rotation_quaternion = XMFLOAT4(0, 0, 0, 1);
|
||||
|
||||
void Serialize(wi::Archive& archive, wi::ecs::EntitySerializer& seri);
|
||||
};
|
||||
|
||||
@@ -1114,6 +1114,11 @@ namespace wi::scene
|
||||
archive >> cloud_shadow_scale;
|
||||
archive >> cloud_shadow_speed;
|
||||
}
|
||||
|
||||
if (archive.GetVersion() >= 78)
|
||||
{
|
||||
archive >> stars;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1254,6 +1259,11 @@ namespace wi::scene
|
||||
archive << cloud_shadow_scale;
|
||||
archive << cloud_shadow_speed;
|
||||
}
|
||||
|
||||
if (archive.GetVersion() >= 78)
|
||||
{
|
||||
archive << stars;
|
||||
}
|
||||
}
|
||||
}
|
||||
void SoundComponent::Serialize(wi::Archive& archive, EntitySerializer& seri)
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace wi::version
|
||||
// minor features, major updates, breaking compatibility changes
|
||||
const int minor = 60;
|
||||
// minor bug fixes, alterations, refactors, updates
|
||||
const int revision = 59;
|
||||
const int revision = 60;
|
||||
|
||||
const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user