Fix 3d thumbnails some more

Relax some fire restrictions

Finale graphical effects

Should only activate on finale.
This commit is contained in:
riperiperi 2024-12-08 13:45:11 +00:00
parent 182dc48e60
commit 9df7ec4613
30 changed files with 154 additions and 20 deletions

View file

@ -1212,9 +1212,11 @@ namespace FSO.Client.Rendering.City
public void SetTimeOfDay(double time)
{
time = Math.Min(0.999999999, time);
Time = (float)time;
m_TintColor = TimeOfDayConfig.ColorFromTime(time);
Time = (float)time;
time = FinaleUtils.BiasSunTime(time);
if (Weather.Darken > 0)
{
//tint the outside colour, usually with some darkening effect.
@ -1240,6 +1242,8 @@ namespace FSO.Client.Rendering.City
modTime = (time - DayOffset) * 0.5 / DayDuration;
}
modTime = FinaleUtils.BiasSunTime(modTime);
Transform *= Matrix.CreateRotationY((float)((modTime+0.5) * Math.PI * 2.0)); //Controls the rotation of the sun/moon around the city.
Transform *= Matrix.CreateRotationZ((float)(Math.PI*(45.0/180.0))); //Sun is at an angle of 45 degrees to horizon at it's peak. idk why, it's winter maybe? looks nice either way
Transform *= Matrix.CreateRotationY((float)(Math.PI * 0.3)); //Offset from front-back a little. This might need some adjusting for the nicest sunset/sunrise locations.
@ -1820,7 +1824,9 @@ namespace FSO.Client.Rendering.City
VertexShader.CurrentTechnique = VertexShader.Techniques[1];
VertexShader.CurrentTechnique.Passes[passIndex].Apply();
var night = Time < 0.25f || Time > 0.75f;
double biasTime = FinaleUtils.BiasSunTime(Time);
var night = biasTime < 0.25f || biasTime > 0.75f;
if (!useLocked || NearFacades == null)
{

View file

@ -162,6 +162,7 @@
<Compile Include="Rendering\Emoji\EmojiCache.cs" />
<Compile Include="Rendering\Emoji\EmojiDictionary.cs" />
<Compile Include="Rendering\Emoji\EmojiProvider.cs" />
<Compile Include="Rendering\FinaleUtils.cs" />
<Compile Include="Rendering\Framework\3DComponent.cs" />
<Compile Include="Rendering\Framework\3DLayer.cs" />
<Compile Include="Rendering\Framework\3DScene.cs" />

View file

@ -0,0 +1,88 @@
using Microsoft.Xna.Framework;
using System;
namespace FSO.Common.Rendering
{
public static class FinaleUtils
{
private static Color[] FinaleColors = new Color[]
{
new Color(2, 2, 2),
new Color(2, 2, 2),
Color.Lerp(new Color(0, 0, 0), new Color(50, 70, 122)*1.25f, 0.5f),
new Color(70, 70, 70)*1.25f,
new Color(217, 109, 50), //sunrise
new Color(255, 255, 255),
new Color(255, 255, 255), //peak
new Color(255, 255, 255), //peak
new Color(255, 255, 255),
new Color(255, 255, 255),
Color.Lerp(new Color(255, 255, 255), new Color(217, 109, 50), 0.33f),
Color.Lerp(new Color(255, 255, 255), new Color(217, 109, 25), 0.66f),
new Color(225, 64, 0), //sunset
new Color(0, 0, 0)
};
private static double DayOffset = 0.25;
private static double DayDuration = 0.60;
private static double TargetEnd = 1.04;
public static double BiasSunTime(double modTime)
{
if (IsFinale())
{
double dayMid = DayOffset + DayDuration / 2;
double mainEnd = DayOffset + DayDuration;
double rescaleDay = (TargetEnd - dayMid) / (mainEnd - dayMid);
if (modTime > dayMid)
{
modTime = dayMid + (modTime - dayMid) / rescaleDay;
}
}
return modTime;
}
public static Vector3 BiasSunIntensity(Vector3 intensity, float time)
{
if (IsFinale())
{
if (time > 0.70)
{
intensity = Vector3.Lerp(new Vector3(0.6f), new Vector3(1, 0.2f, 0.1f), (time - 0.70f) / 0.25f);
}
else if (time > 0.5)
{
intensity = Vector3.Lerp(intensity, new Vector3(0.6f), (time - 0.5f) / 0.2f);
}
if (time > 0.995)
{
intensity *= (1f - time) * 200f;
}
}
return intensity;
}
public static bool IsFinale()
{
var time = DateTime.UtcNow;
return time.Year == 2024 && time.Month == 12 && ((time.Day == 8 && time.Hour == 23) || (time.Day == 9 && time.Hour == 0));
}
public static float GetDarkness()
{
return IsFinale() ? 1.0f : 0.8f;
}
public static Color[] SwapFinaleColors(Color[] colors)
{
return IsFinale() ? FinaleColors : colors;
}
}
}

View file

@ -54,14 +54,19 @@ namespace FSO.Common.Rendering
public static Color ColorFromTime(double time)
{
Color col1 = m_TimeColors[(int)Math.Floor(time * (m_TimeColors.Length - 1))]; //first colour
Color col2 = m_TimeColors[(int)Math.Floor(time * (m_TimeColors.Length - 1)) + 1]; //second colour
if (DarknessMultiplier != 1.0)
Color[] colors = FinaleUtils.SwapFinaleColors(m_TimeColors);
Color col1 = colors[(int)Math.Floor(time * (colors.Length - 1))]; //first colour
Color col2 = colors[(int)Math.Floor(time * (colors.Length - 1)) + 1]; //second colour
float darkness = FinaleUtils.GetDarkness();
if (darkness != 1.0)
{
col1 = Color.Lerp(Color.White, col1, DarknessMultiplier);
col2 = Color.Lerp(Color.White, col2, DarknessMultiplier);
col1 = Color.Lerp(Color.White, col1, darkness);
col2 = Color.Lerp(Color.White, col2, darkness);
}
double Progress = (time * (m_TimeColors.Length - 1)) % 1; //interpolation progress (mod 1)
double Progress = (time * (colors.Length - 1)) % 1; //interpolation progress (mod 1)
return PowColor(Color.Lerp(col1, col2, (float)Progress), 2.2f); //linearly interpolate between the two colours for this specific time.
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -35,14 +35,14 @@ float4 lightColorFloor(float4 intensities) {
float avg = (intensities.r + intensities.g + intensities.b) / 3;
//floor shadow is how much less than average the alpha component is
float fshad = intensities.a / avg;
float fshad = intensities.a / max(0.0001, avg);
return lerp(OutsideDark, float4(intensities.rgb * LightingAdjust, 1), (fshad - MinAvg.x) * MinAvg.y);
}
float4 lightColorIAvg(float4 intensities, float i, float avg) {
float fshad = intensities.a / avg;
float fshad = intensities.a / max(0.0001, avg);
fshad = lerp(fshad, 1, i);
return lerp(OutsideDark, float4(intensities.rgb * LightingAdjust, 1), (fshad - MinAvg.x) * MinAvg.y);
@ -53,7 +53,7 @@ float4 lightColorI(float4 intensities, float i) {
float avg = (intensities.r + intensities.g + intensities.b) / 3;
//floor shadow is how much less than average the alpha component is
float fshad = intensities.a / avg;
float fshad = intensities.a / max(0.0001, avg);
fshad = lerp(fshad, 1, i);
return lerp(OutsideDark, float4(intensities.rgb * LightingAdjust, 1), (fshad - MinAvg.x) * MinAvg.y);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 304 KiB

After

Width:  |  Height:  |  Size: 305 KiB

View file

@ -14,10 +14,12 @@ namespace FSO.SimAntics.Primitives
public override VMPrimitiveExitCode Execute(VMStackFrame context, VMPrimitiveOperand args)
{
var operand = (VMBurnOperand)args;
if (!context.VM.TS1 && (context.VM.Tuning.GetTuning("special", 0, 0) != 1f || context.VM.TSOState.CommunityLot))
if (!context.VM.TS1 && (context.VM.Tuning.GetTuning("special", 0, 0) != 1f))
return VMPrimitiveExitCode.GOTO_FALSE; //fire disabled for now
if ((int)context.VM.Context.NextRandom(10000) >= context.VM.Context.Clock.FirePercent)
bool isSpread = operand.Type != VMBurnType.StackObject;
if (isSpread && (int)context.VM.Context.NextRandom(10000) >= context.VM.Context.Clock.FirePercent)
{
return VMPrimitiveExitCode.GOTO_FALSE;
}
@ -26,7 +28,7 @@ namespace FSO.SimAntics.Primitives
if (context.VM.Context.RoomInfo[myRoom].Room.IsPool) return VMPrimitiveExitCode.GOTO_FALSE;
//as fires burn, the chance they can spread lowers dramatically.
context.VM.Context.Clock.FirePercent -= 500; // lower by 5% every spread. 40 spreads reaches 0.
if (isSpread) context.VM.Context.Clock.FirePercent -= 500; // lower by 5% every spread. 40 spreads reaches 0.
if (context.VM.Context.Clock.FirePercent < 0) context.VM.Context.Clock.FirePercent = 0;
//begin the burn setup.

View file

@ -15,7 +15,7 @@ namespace FSO.SimAntics
public int Month = 6;
public int Year = 1997;
public int FirePercent;
public int FirePercent = 20000;
public long UTCStart = DateTime.UtcNow.Ticks;
public int TimeOfDay

View file

@ -1,5 +1,6 @@
using FSO.Common;
using FSO.Common.Model;
using FSO.Common.Rendering;
using FSO.Common.Utils;
using FSO.Files;
using FSO.LotView.Model;
@ -14,6 +15,7 @@ namespace FSO.LotView.Components
public class AbstractSkyDome : IDisposable
{
private static string DefaultSkyCol = "Textures/skycol.png";
private static string FinalSkyCol = "Textures/skycolfinal.png";
private VertexBuffer Verts;
private IndexBuffer Indices;
@ -24,6 +26,8 @@ namespace FSO.LotView.Components
private VertexPositionTexture[] VertexData;
private int[] IndexData;
private bool IsFinal;
public AbstractSkyDome(GraphicsDevice GD, float time)
{
float? customSky = DynamicTuning.Global?.GetTuning("city", 0, 2);
@ -33,10 +37,27 @@ namespace FSO.LotView.Components
TryLoadSkyColor(GD, DefaultSkyCol);
}
LoadFinalIfNeeded(GD);
InitArrays();
BuildSkyDome(GD, time);
}
public void LoadFinalIfNeeded(GraphicsDevice GD)
{
bool needsFinal = FinaleUtils.IsFinale();
if (!IsFinal && needsFinal)
{
using (var file = File.OpenRead(Path.Combine(FSOEnvironment.ContentDir, FinalSkyCol)))
{
GradTex = ImageLoader.FromStream(GD, file);
};
IsFinal = true;
}
}
private bool TryLoadSkyColor(GraphicsDevice GD, string path)
{
try
@ -111,6 +132,8 @@ namespace FSO.LotView.Components
public void BuildSkyDome(GraphicsDevice GD, float time)
{
LoadFinalIfNeeded(GD);
//generate sky dome geometry
var subdivs = 65;
VertexPositionTexture[] verts = VertexData;
@ -224,7 +247,7 @@ namespace FSO.LotView.Components
}
gd.BlendState = BlendState.NonPremultiplied;
var night = Night(time);
var night = Night((float)FinaleUtils.BiasSunTime(time));
//draw the sun or moon
var pos = sunVector;
var z = -pos.X;
@ -241,7 +264,7 @@ namespace FSO.LotView.Components
effect.VertexColorEnabled = false;
effect.TextureEnabled = true;
effect.Texture = (night) ? TextureGenerator.GetMoon(gd) : TextureGenerator.GetSun(gd);
effect.DiffuseColor = new Vector3(color.X, color.Y, color.Z) * ((night) ? 2f : 0.6f);
effect.DiffuseColor = FinaleUtils.BiasSunIntensity(new Vector3(color.X, color.Y, color.Z) * ((night) ? 2f : 0.6f), time);
gd.BlendState = (night) ? BlendState.NonPremultiplied : BlendState.Additive;
foreach (var pass in effect.CurrentTechnique.Passes)

View file

@ -1,4 +1,5 @@
using FSO.Common;
using FSO.Common.Rendering;
using FSO.Common.Utils;
using FSO.LotView.Components;
using FSO.LotView.Effects;
@ -375,6 +376,8 @@ namespace FSO.LotView.LMap
DayOffset = 0.25f;
DayDuration = 0.60f;
tod = FinaleUtils.BiasSunTime(tod);
bool night = false;
double modTime;
var offStart = 1 - (DayOffset + DayDuration);

View file

@ -1,4 +1,5 @@
using FSO.LotView.Components;
using FSO.Common.Rendering;
using FSO.LotView.Components;
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
@ -88,7 +89,7 @@ namespace FSO.LotView.Model
ParticleType ptype;
if (IsManual)
if (IsManual && !FinaleUtils.IsFinale())
{
if (WeatherData == LastWeatherData && enabled == LastEnabled) return;
LastWeatherData = WeatherData;
@ -167,6 +168,11 @@ namespace FSO.LotView.Model
private int GetAutoWeatherIntensity(DateTime time)
{
if (FinaleUtils.IsFinale())
{
return 0;
}
var distance = time - new DateTime(2019, 1, 26);
var halfDay = (int)distance.TotalHours;

View file

@ -275,7 +275,7 @@ namespace FSO.LotView.Platform
obj.OnRotationChanged(state);
obj.OnZoomChanged(state);
obj.Container = null;
obj.Position = tilePosition;
obj.UnmoddedPosition = tilePosition;
obj.Draw(gd, state);
var mat = obj.World * vp;