104 lines
3 KiB
C#
104 lines
3 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Numerics;
|
|
using Auspex.Lighting.Internal;
|
|
using Auspex.Vfx.Internal;
|
|
|
|
namespace Auspex;
|
|
|
|
public sealed class LightRenderer : IDisposable
|
|
{
|
|
private static readonly Dictionary<AxLightType, string> LightTypeNames = Enum.GetValues<AxLightType>().ToDictionary((AxLightType v) => v, (AxLightType v) => v.ToString());
|
|
|
|
private FrameLifetimeTracker<NativeLightHandle> trackedLights;
|
|
|
|
public LightRenderer()
|
|
{
|
|
trackedLights = new FrameLifetimeTracker<NativeLightHandle>();
|
|
}
|
|
|
|
public static Vector3 LinearToGameHDR(Vector3 linearRgb)
|
|
{
|
|
linearRgb *= 4f;
|
|
return linearRgb * linearRgb;
|
|
}
|
|
|
|
public static Vector3 GameHDRToLinear(Vector3 gameHdr)
|
|
{
|
|
return Vector3.SquareRoot(gameHdr) / 4f;
|
|
}
|
|
|
|
public void AddDirectionalLight(string id, Vector3 position, AxLightConfig? config = null)
|
|
{
|
|
ArgumentNullException.ThrowIfNull((object)id, "id");
|
|
CreateOrUpdateLight(id, AxLightType.Directional, position, config ?? AxLightConfig.Default);
|
|
}
|
|
|
|
public void AddPointLight(string id, Vector3 position, AxLightConfig? config = null)
|
|
{
|
|
ArgumentNullException.ThrowIfNull((object)id, "id");
|
|
CreateOrUpdateLight(id, AxLightType.PointLight, position, config ?? AxLightConfig.Default);
|
|
}
|
|
|
|
public void AddSpotLight(string id, Vector3 position, AxLightConfig? config = null)
|
|
{
|
|
ArgumentNullException.ThrowIfNull((object)id, "id");
|
|
CreateOrUpdateLight(id, AxLightType.SpotLight, position, config ?? AxLightConfig.Default);
|
|
}
|
|
|
|
public void AddAreaLight(string id, Vector3 position, AxLightConfig? config = null)
|
|
{
|
|
ArgumentNullException.ThrowIfNull((object)id, "id");
|
|
CreateOrUpdateLight(id, AxLightType.AreaLight, position, config ?? AxLightConfig.Default);
|
|
}
|
|
|
|
private void CreateOrUpdateLight(string id, AxLightType lightType, Vector3 position, AxLightConfig config)
|
|
{
|
|
(string, string) key = (id, LightTypeNames[lightType]);
|
|
if (trackedLights.IsTouched(key))
|
|
{
|
|
return;
|
|
}
|
|
if (trackedLights.TryTouchExisting(key, out NativeLightHandle o))
|
|
{
|
|
o.UpdatePosition(position);
|
|
if (config.Rotation.HasValue)
|
|
{
|
|
o.UpdateRotation(config.Rotation.Value);
|
|
}
|
|
o.UpdateColor(config.Color);
|
|
o.UpdateIntensity(config.Intensity);
|
|
o.UpdateRange(config.Range);
|
|
o.UpdateAngles(config.LightAngle, config.FalloffAngle);
|
|
o.UpdateFlags(config.Flags);
|
|
o.UpdateFalloff(config.FalloffType, config.FalloffPower);
|
|
o.UpdateShadow(config.ShadowNear, config.ShadowFar, config.CharaShadowRange);
|
|
}
|
|
else
|
|
{
|
|
trackedLights.TouchNew(key, NativeLightHandle.Create(position, lightType, config));
|
|
}
|
|
}
|
|
|
|
public bool RemoveLight(string id, AxLightType lightType)
|
|
{
|
|
ArgumentNullException.ThrowIfNull((object)id, "id");
|
|
return trackedLights.Remove((id, LightTypeNames[lightType]));
|
|
}
|
|
|
|
internal void Update()
|
|
{
|
|
trackedLights.Update();
|
|
trackedLights.ForEachActive(delegate(NativeLightHandle light)
|
|
{
|
|
light.Tick();
|
|
});
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
trackedLights.Dispose();
|
|
GC.SuppressFinalize(this);
|
|
}
|
|
}
|