Skip to content

Commit e190873

Browse files
committed
Fix headlight dislocation @ speed
1 parent d5f1217 commit e190873

File tree

3 files changed

+54
-61
lines changed

3 files changed

+54
-61
lines changed

Source/RunActivity/Viewer3D/Lights.cs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@ public class LightViewer
8585
public float LightConeMinDotProduct;
8686
public Vector4 LightConeColor;
8787

88+
bool PreviousIsLightConeActive; // previous IsLightConeActive
89+
ElapsedTime FadeTimer = ElapsedTime.Zero;
90+
8891
public LightViewer(Viewer viewer, TrainCar car, TrainCarViewer carViewer)
8992
{
9093
Viewer = viewer;
@@ -248,7 +251,9 @@ public void PrepareFrame(RenderFrame frame, ElapsedTime elapsedTime)
248251
frame.AddPrimitive(LightConeMaterial, lightPrimitive, RenderPrimitiveGroup.Lights, ref xnaDTileTranslation);
249252
#endif
250253

251-
// Set the active light cone info for the material code.
254+
FadeTimer += elapsedTime;
255+
256+
// TODO: Theoretically the headlight handling could be moved to the TrainCar level. Now we can have multiple of these.
252257
if (HasLightCone && ActiveLightCone != null)
253258
{
254259
int coneIndex = ActiveLightCone.Light.ShapeIndex;
@@ -260,6 +265,24 @@ public void PrepareFrame(RenderFrame frame, ElapsedTime elapsedTime)
260265
LightConeDistance = MathHelper.Lerp(ActiveLightCone.Distance1, ActiveLightCone.Distance2, ActiveLightCone.Fade.Y);
261266
LightConeMinDotProduct = (float)Math.Cos(MathHelper.Lerp(ActiveLightCone.Angle1, ActiveLightCone.Angle2, ActiveLightCone.Fade.Y));
262267
LightConeColor = Vector4.Lerp(ActiveLightCone.Color1, ActiveLightCone.Color2, ActiveLightCone.Fade.Y);
268+
269+
if (PreviousIsLightConeActive != IsLightConeActive)
270+
{
271+
PreviousIsLightConeActive = IsLightConeActive;
272+
FadeTimer = ElapsedTime.Zero;
273+
}
274+
275+
// The original shaders followed the phylisophy of wanting 50% brightness at half the range. (LightConeDistance is only the half)
276+
// For the new calculation method the full range is needed.
277+
var range = LightConeDistance * 2;
278+
var color = new Vector3(LightConeColor.X, LightConeColor.Y, LightConeColor.Z);
279+
280+
var fadingIntensity = FadeTimer.ClockSeconds / (Math.Max(LightConeFadeIn, LightConeFadeOut) + float.Epsilon);
281+
if (!IsLightConeActive)
282+
fadingIntensity = 1 - fadingIntensity;
283+
284+
if (fadingIntensity > 0)
285+
frame.AddLight(LightMode.Spot, LightConePosition, LightConeDirection, color, RenderFrame.HeadLightIntensity, range, 1, LightConeMinDotProduct, fadingIntensity, false);
263286
}
264287
}
265288

Source/RunActivity/Viewer3D/RenderFrame.cs

Lines changed: 28 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,9 @@ public class RenderFrame
390390
static readonly Vector3 MoonGlow = new Vector3(245f / 255f, 243f / 255f, 206f / 255f);
391391
const float SunIntensity = 1;
392392
const float MoonIntensity = SunIntensity / 380000;
393-
float HeadLightIntensity = 25000; // See some sample values: https://docs.unity3d.com/Packages/com.unity.cloud.gltfast@5.2/manual/LightUnits.html
393+
public const float HeadLightIntensity = 25000; // See some sample values: https://docs.unity3d.com/Packages/com.unity.cloud.gltfast@5.2/manual/LightUnits.html
394+
float LightClampTo = 1;
395+
float LightDayNightMultiplier = 1;
394396

395397
// Local shadow map data.
396398
Matrix[] ShadowMapLightView;
@@ -555,64 +557,27 @@ public void PrepareFrame(Viewer viewer)
555557

556558
// Ensure that the first light is always the sun/moon, because the ambient and shadow effects will be calculated based on the first light.
557559
if (SolarDirection.Y > -0.05)
558-
AddLight(-SolarDirection, SunColor, SunIntensity);
560+
AddLight(-SolarDirection, SunColor, SunIntensity, 1);
559561
else
560562
{
561563
var moonDirection = viewer.Settings.UseMSTSEnv ? viewer.World.MSTSSky.mstsskylunarDirection : viewer.World.Sky.LunarDirection;
562-
AddLight(-moonDirection, MoonGlow, MoonIntensity);
564+
AddLight(-moonDirection, MoonGlow, MoonIntensity, 1);
563565
}
564566

565-
// Headlight illumination
566-
if (viewer.PlayerLocomotiveViewer?.lightDrawer?.HasLightCone ?? false)
567+
if (SolarDirection.Y <= -0.05)
567568
{
568-
var clampValue = 1f;
569-
var dayNightMultiplier = 1f;
570-
var lightDrawer = viewer.PlayerLocomotiveViewer.lightDrawer;
571-
var lightState = lightDrawer.IsLightConeActive;
572-
if (lightState != lastLightState)
573-
{
574-
if (lightDrawer.LightConeFadeIn > 0)
575-
{
576-
fadeStartTimer = viewer.Simulator.GameTime;
577-
fadeDuration = lightDrawer.LightConeFadeIn;
578-
}
579-
else if (lightDrawer.LightConeFadeOut > 0)
580-
{
581-
fadeStartTimer = viewer.Simulator.GameTime;
582-
fadeDuration = lightDrawer.LightConeFadeOut;
583-
}
584-
lastLightState = lightState;
585-
}
586-
if (SolarDirection.Y <= -0.05)
587-
{
588-
clampValue = 1; // at nighttime max headlight
589-
dayNightMultiplier = 1;
590-
}
591-
else if (SolarDirection.Y >= 0.15)
592-
{
593-
clampValue = 0.5f; // at daytime min headlight
594-
dayNightMultiplier = 0.1f;
595-
}
596-
else
597-
{
598-
clampValue = 1 - 2.5f * (SolarDirection.Y + 0.05f); // in the meantime interpolate
599-
dayNightMultiplier = 1 - 4.5f * (SolarDirection.Y + 0.05f);
600-
}
601-
602-
// The original shaders followed the phylisophy of wanting 50% brightness at half the range. (LightConeDistance is only the half)
603-
// For the new calculation method the full range is needed.
604-
var range = lightDrawer.LightConeDistance * 2 * dayNightMultiplier;
605-
var color = new Vector3(lightDrawer.LightConeColor.X, lightDrawer.LightConeColor.Y, lightDrawer.LightConeColor.Z);
606-
607-
var intensity = (float)(viewer.Simulator.GameTime - fadeStartTimer) / (fadeDuration + float.Epsilon);
608-
if (!lightState)
609-
intensity = 1 - intensity;
610-
intensity = MathHelper.Clamp(intensity, 0, 1);
611-
intensity = MathHelper.Clamp(intensity * dayNightMultiplier * clampValue, 0, clampValue);
612-
intensity *= HeadLightIntensity;
613-
614-
if (intensity > 0)
615-
AddLight(LightMode.Spot, lightDrawer.LightConePosition, lightDrawer.LightConeDirection, color, intensity, range, 1, lightDrawer.LightConeMinDotProduct);
569+
LightClampTo = 1; // at nighttime max light
570+
LightDayNightMultiplier = 1;
571+
}
572+
else if (SolarDirection.Y >= 0.15)
573+
{
574+
LightClampTo = 0.5f; // at daytime min light
575+
LightDayNightMultiplier = 0.1f;
576+
}
577+
else
578+
{
579+
LightClampTo = 1 - 2.5f * (SolarDirection.Y + 0.05f); // in the meantime interpolate
580+
LightDayNightMultiplier = 1 - 4.5f * (SolarDirection.Y + 0.05f);
616581
}
617582
}
618583

@@ -1084,14 +1049,17 @@ void DrawSequencesDistantMountains(GraphicsDevice graphicsDevice, bool logging)
10841049
}
10851050
}
10861051

1087-
public void AddLight(ShapeLight light, ref Matrix worldMatrix, float lodBias)
1052+
public void AddLight(ShapeLight light, ref Matrix worldMatrix, float lodBias, float fadingIntensity)
10881053
{
10891054
// Do not allow directional light injection. That is reserved to the sun and the moon.
10901055
if (light != null && light.Type != LightMode.Directional)
1091-
AddLight(light.Type, worldMatrix.Translation, Vector3.TransformNormal(-Vector3.UnitZ, worldMatrix), light.Color, light.Intensity, light.Range, light.InnerConeCos, light.OuterConeCos);
1056+
AddLight(light.Type, worldMatrix.Translation, Vector3.TransformNormal(-Vector3.UnitZ, worldMatrix), light.Color, light.Intensity, light.Range, light.InnerConeCos, light.OuterConeCos, fadingIntensity, false);
10921057
}
1093-
public void AddLight(Vector3 direction, Vector3 color, float intensity) => AddLight(LightMode.Directional, Vector3.Zero, direction, color, intensity, -1, 0, 0);
1094-
public void AddLight(LightMode type, Vector3 position, Vector3 direction, Vector3 color, float intensity, float range, float innerConeCos, float outerConeCos)
1058+
/// <summary>
1059+
/// Used for Sun / Moon only
1060+
/// </summary>
1061+
public void AddLight(Vector3 direction, Vector3 color, float intensity, float fadingIntensity) => AddLight(LightMode.Directional, Vector3.Zero, direction, color, intensity, -1, 0, 0, fadingIntensity, true);
1062+
public void AddLight(LightMode type, Vector3 position, Vector3 direction, Vector3 color, float intensity, float range, float innerConeCos, float outerConeCos, float fadingIntensity, bool ignoreDayNight)
10951063
{
10961064
if (NumLights >= RenderProcess.MAX_LIGHTS)
10971065
return;
@@ -1100,8 +1068,9 @@ public void AddLight(LightMode type, Vector3 position, Vector3 direction, Vector
11001068
LightPositions[NumLights] = position;
11011069
LightDirections[NumLights] = direction;
11021070
LightColors[NumLights] = color;
1103-
LightIntensities[NumLights] = intensity;
1104-
LightRanges[NumLights] = range;
1071+
LightIntensities[NumLights] = intensity
1072+
* (ignoreDayNight ? MathHelper.Clamp(fadingIntensity, 0, 1) : MathHelper.Clamp(fadingIntensity * LightDayNightMultiplier * LightClampTo, 0, LightClampTo));
1073+
LightRanges[NumLights] = range * (ignoreDayNight ? 1 : LightDayNightMultiplier);
11051074
LightInnerConeCos[NumLights] = innerConeCos;
11061075
LightOuterConeCos[NumLights] = outerConeCos;
11071076
NumLights++;

Source/RunActivity/Viewer3D/Shapes.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ public SharedShape Get(string path)
7979
}
8080
catch (Exception error)
8181
{
82+
if (Debugger.IsAttached) Debugger.Break();
8283
Trace.WriteLine(new FileLoadException(path, error));
8384
Shapes.Add(path, EmptyShape);
8485
}
@@ -2659,7 +2660,7 @@ public void PrepareFrame(RenderFrame frame, WorldPosition location, Matrix[] ani
26592660

26602661
var interior = (flags & ShapeFlags.Interior) != 0;
26612662
frame.AddAutoPrimitive(mstsLocation, distanceDetail.ViewSphereRadius, distanceDetail.ViewingDistance * lodBias, shapePrimitive.Material, shapePrimitive, interior ? RenderPrimitiveGroup.Interior : RenderPrimitiveGroup.World, ref xnaMatrix, flags, bones);
2662-
frame.AddLight(shapePrimitive.Light, ref xnaMatrix, lodBias);
2663+
frame.AddLight(shapePrimitive.Light, ref xnaMatrix, lodBias, 1);
26632664
}
26642665
}
26652666
}

0 commit comments

Comments
 (0)