muffin v7.5.5
This commit is contained in:
parent
a8f2c1df37
commit
6266f9e6b7
110 changed files with 14907 additions and 6073 deletions
205
Auspex/Auspex.Lighting.Internal/NativeLightHandle.cs
Normal file
205
Auspex/Auspex.Lighting.Internal/NativeLightHandle.cs
Normal file
|
|
@ -0,0 +1,205 @@
|
|||
using System;
|
||||
using System.Numerics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using FFXIVClientStructs.FFXIV.Client.System.Memory;
|
||||
|
||||
namespace Auspex.Lighting.Internal;
|
||||
|
||||
internal sealed class NativeLightHandle : IDisposable
|
||||
{
|
||||
private unsafe GameLightData* data;
|
||||
|
||||
private Vector3 position;
|
||||
|
||||
private Quaternion rotation;
|
||||
|
||||
private Vector3 color;
|
||||
|
||||
private float intensity;
|
||||
|
||||
private float range;
|
||||
|
||||
private float lightAngle;
|
||||
|
||||
private float falloffAngle;
|
||||
|
||||
private AxLightFlags flags;
|
||||
|
||||
private AxFalloffType falloffType;
|
||||
|
||||
private float falloffPower;
|
||||
|
||||
private float shadowNear;
|
||||
|
||||
private float shadowFar;
|
||||
|
||||
private float charaShadowRange;
|
||||
|
||||
public unsafe static NativeLightHandle Create(Vector3 position, AxLightType lightType, AxLightConfig config)
|
||||
{
|
||||
GameLightData* ptr = IMemorySpace.GetDefaultSpace()->Malloc<GameLightData>(8uL);
|
||||
if (LightNativeBridge.Spawn(ptr) == null)
|
||||
{
|
||||
IMemorySpace.Free(ptr, (ulong)sizeof(GameLightData));
|
||||
throw new InvalidOperationException("Failed to spawn game light");
|
||||
}
|
||||
LightNativeBridge.Create(ptr);
|
||||
LightNativeBridge.Finalize(ptr);
|
||||
((long*)ptr)[7] |= 2L;
|
||||
LightRenderData* renderObject = ptr->RenderObject;
|
||||
if (renderObject == null)
|
||||
{
|
||||
IMemorySpace.Free(ptr, (ulong)sizeof(GameLightData));
|
||||
throw new InvalidOperationException("Game did not create RenderObject for light");
|
||||
}
|
||||
renderObject->Transform = &ptr->Transform;
|
||||
renderObject->EmissionType = lightType;
|
||||
renderObject->Color = config.Color;
|
||||
renderObject->Intensity = config.Intensity;
|
||||
renderObject->Range = config.Range;
|
||||
renderObject->FalloffType = config.FalloffType;
|
||||
renderObject->Falloff = config.FalloffPower;
|
||||
renderObject->LightAngle = config.LightAngle;
|
||||
renderObject->FalloffAngle = config.FalloffAngle;
|
||||
renderObject->CharacterShadowRange = config.CharaShadowRange;
|
||||
renderObject->ShadowPlaneNear = config.ShadowNear;
|
||||
renderObject->ShadowPlaneFar = config.ShadowFar;
|
||||
renderObject->Flags = config.Flags;
|
||||
LightNativeBridge.UpdateRange(renderObject);
|
||||
Quaternion quaternion = config.Rotation ?? Quaternion.Identity;
|
||||
Unsafe.Write<Vector3>((void*)(&ptr->Transform.Position), position);
|
||||
Unsafe.Write<Quaternion>((void*)(&ptr->Transform.Rotation), quaternion);
|
||||
ptr->Scale = Vector3.One;
|
||||
return new NativeLightHandle
|
||||
{
|
||||
data = ptr,
|
||||
position = position,
|
||||
rotation = quaternion,
|
||||
color = config.Color,
|
||||
intensity = config.Intensity,
|
||||
range = config.Range,
|
||||
lightAngle = config.LightAngle,
|
||||
falloffAngle = config.FalloffAngle,
|
||||
flags = config.Flags,
|
||||
falloffType = config.FalloffType,
|
||||
falloffPower = config.FalloffPower,
|
||||
shadowNear = config.ShadowNear,
|
||||
shadowFar = config.ShadowFar,
|
||||
charaShadowRange = config.CharaShadowRange
|
||||
};
|
||||
}
|
||||
|
||||
public unsafe void UpdatePosition(Vector3 newPosition)
|
||||
{
|
||||
if (data != null && !(position == newPosition))
|
||||
{
|
||||
position = newPosition;
|
||||
Unsafe.Write<Vector3>((void*)(&data->Transform.Position), newPosition);
|
||||
}
|
||||
}
|
||||
|
||||
public unsafe void UpdateRotation(Quaternion newRotation)
|
||||
{
|
||||
if (data != null && !(rotation == newRotation))
|
||||
{
|
||||
rotation = newRotation;
|
||||
Unsafe.Write<Quaternion>((void*)(&data->Transform.Rotation), newRotation);
|
||||
}
|
||||
}
|
||||
|
||||
public unsafe void UpdateColor(Vector3 newColor)
|
||||
{
|
||||
if (data != null && data->RenderObject != null && !(color == newColor))
|
||||
{
|
||||
color = newColor;
|
||||
data->RenderObject->Color = newColor;
|
||||
}
|
||||
}
|
||||
|
||||
public unsafe void UpdateIntensity(float newIntensity)
|
||||
{
|
||||
if (data != null && data->RenderObject != null && intensity != newIntensity)
|
||||
{
|
||||
intensity = newIntensity;
|
||||
data->RenderObject->Intensity = newIntensity;
|
||||
}
|
||||
}
|
||||
|
||||
public unsafe void UpdateRange(float newRange)
|
||||
{
|
||||
if (data != null && data->RenderObject != null && range != newRange)
|
||||
{
|
||||
range = newRange;
|
||||
data->RenderObject->Range = newRange;
|
||||
LightNativeBridge.UpdateRange(data->RenderObject);
|
||||
}
|
||||
}
|
||||
|
||||
public unsafe void UpdateFlags(AxLightFlags newFlags)
|
||||
{
|
||||
if (data != null && data->RenderObject != null && flags != newFlags)
|
||||
{
|
||||
flags = newFlags;
|
||||
data->RenderObject->Flags = newFlags;
|
||||
}
|
||||
}
|
||||
|
||||
public unsafe void UpdateAngles(float newLightAngle, float newFalloffAngle)
|
||||
{
|
||||
if (data != null && data->RenderObject != null && (lightAngle != newLightAngle || falloffAngle != newFalloffAngle))
|
||||
{
|
||||
lightAngle = newLightAngle;
|
||||
falloffAngle = newFalloffAngle;
|
||||
data->RenderObject->LightAngle = newLightAngle;
|
||||
data->RenderObject->FalloffAngle = newFalloffAngle;
|
||||
}
|
||||
}
|
||||
|
||||
public unsafe void UpdateFalloff(AxFalloffType newFalloffType, float newFalloffPower)
|
||||
{
|
||||
if (data != null && data->RenderObject != null && (falloffType != newFalloffType || falloffPower != newFalloffPower))
|
||||
{
|
||||
falloffType = newFalloffType;
|
||||
falloffPower = newFalloffPower;
|
||||
data->RenderObject->FalloffType = newFalloffType;
|
||||
data->RenderObject->Falloff = newFalloffPower;
|
||||
}
|
||||
}
|
||||
|
||||
public unsafe void UpdateShadow(float newShadowNear, float newShadowFar, float newCharaShadowRange)
|
||||
{
|
||||
if (data != null && data->RenderObject != null && (shadowNear != newShadowNear || shadowFar != newShadowFar || charaShadowRange != newCharaShadowRange))
|
||||
{
|
||||
shadowNear = newShadowNear;
|
||||
shadowFar = newShadowFar;
|
||||
charaShadowRange = newCharaShadowRange;
|
||||
data->RenderObject->ShadowPlaneNear = newShadowNear;
|
||||
data->RenderObject->ShadowPlaneFar = newShadowFar;
|
||||
data->RenderObject->CharacterShadowRange = newCharaShadowRange;
|
||||
}
|
||||
}
|
||||
|
||||
internal unsafe void Tick()
|
||||
{
|
||||
if (data != null)
|
||||
{
|
||||
LightNativeBridge.UpdateCulling(data);
|
||||
LightNativeBridge.UpdateMaterial(data);
|
||||
}
|
||||
}
|
||||
|
||||
public unsafe void Dispose()
|
||||
{
|
||||
if (data != null)
|
||||
{
|
||||
GameLightVTable* virtualTable = data->VirtualTable;
|
||||
if (virtualTable != null)
|
||||
{
|
||||
virtualTable->Cleanup(data);
|
||||
virtualTable->Destructor(data, false);
|
||||
}
|
||||
data = null;
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue