150 lines
3.5 KiB
C#
150 lines
3.5 KiB
C#
using System;
|
|
using System.Numerics;
|
|
using System.Text;
|
|
using Auspex.Vfx.Native;
|
|
|
|
namespace Auspex.Vfx.Internal;
|
|
|
|
public sealed class VfxInstance : IDisposable
|
|
{
|
|
internal string? path;
|
|
|
|
internal Vector3 position;
|
|
|
|
internal Vector3 size;
|
|
|
|
internal float rotation;
|
|
|
|
internal Vector4 color;
|
|
|
|
internal unsafe VfxData* data;
|
|
|
|
internal bool libOwned;
|
|
|
|
public unsafe bool IsValid
|
|
{
|
|
get
|
|
{
|
|
if (data != null)
|
|
{
|
|
return data->Instance != null;
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public unsafe static VfxInstance Create(string path, Vector3 position, Vector3 size, float rotation, Vector4? color = null)
|
|
{
|
|
VfxData* ptr = CreateVfxInternal(path, position, size, rotation, color ?? Vector4.One);
|
|
return new VfxInstance(path, ptr, position, size, rotation, color ?? Vector4.One)
|
|
{
|
|
libOwned = true
|
|
};
|
|
}
|
|
|
|
public unsafe static VfxInstance Wrap(VfxData* data, Vector3 position, Vector3 size, float rotation, Vector4? color = null)
|
|
{
|
|
return new VfxInstance(null, data, position, size, rotation, color ?? Vector4.One);
|
|
}
|
|
|
|
private unsafe VfxInstance(string? path, VfxData* data, Vector3 position, Vector3 size, float rotation, Vector4 color)
|
|
{
|
|
if (data == null)
|
|
{
|
|
throw new ArgumentNullException("data");
|
|
}
|
|
this.path = path;
|
|
this.data = data;
|
|
this.position = position;
|
|
this.size = size;
|
|
this.rotation = rotation;
|
|
this.color = color;
|
|
}
|
|
|
|
public unsafe void Dispose()
|
|
{
|
|
if (libOwned && IsValid)
|
|
{
|
|
VfxNativeBridge.DestroyVfx(data);
|
|
}
|
|
data = null;
|
|
GC.SuppressFinalize(this);
|
|
}
|
|
|
|
private unsafe static VfxData* CreateVfxInternal(string path, Vector3 position, Vector3 size, float rotation, Vector4 color)
|
|
{
|
|
byte[] bytes = Encoding.UTF8.GetBytes(path + "\0");
|
|
VfxInitData vfxInitData = default(VfxInitData);
|
|
VfxNativeBridge.VfxInitDataCtor(&vfxInitData);
|
|
fixed (byte* ptr = bytes)
|
|
{
|
|
VfxData* intPtr = VfxNativeBridge.CreateVfx(ptr, &vfxInitData, 2, 0, position.X, position.Y, position.Z, size.X, size.Y, size.Z, rotation, 1f, -1);
|
|
intPtr->Instance->Color = color;
|
|
return intPtr;
|
|
}
|
|
}
|
|
|
|
public void UpdatePosition(Vector3 position)
|
|
{
|
|
UpdateTransform(position, size, rotation);
|
|
}
|
|
|
|
public void UpdateScale(Vector3 scale)
|
|
{
|
|
UpdateTransform(position, scale, rotation);
|
|
}
|
|
|
|
public void UpdateRotation(float rotation)
|
|
{
|
|
UpdateTransform(position, size, rotation);
|
|
}
|
|
|
|
public unsafe void UpdateTransform(Vector3 position, Vector3 size, float rotation)
|
|
{
|
|
MaybeRefreshVfxResourceInstance();
|
|
if (!IsValid || (this.position == position && this.rotation == rotation && this.size == size))
|
|
{
|
|
return;
|
|
}
|
|
this.position = position;
|
|
this.size = size;
|
|
this.rotation = rotation;
|
|
using PinnedAlignedMatrix pinnedAlignedMatrix = new PinnedAlignedMatrix();
|
|
Matrix4x4* get = pinnedAlignedMatrix.Get;
|
|
get->M11 = size.X;
|
|
get->M12 = 0f;
|
|
get->M13 = 0f;
|
|
get->M14 = 0f;
|
|
get->M21 = 0f;
|
|
get->M22 = size.Y;
|
|
get->M23 = 0f;
|
|
get->M24 = 0f;
|
|
get->M31 = 0f;
|
|
get->M32 = 0f;
|
|
get->M33 = size.Z;
|
|
get->M34 = 0f;
|
|
VfxNativeBridge.RotateMatrix(get, rotation);
|
|
get->M41 = position.X;
|
|
get->M42 = position.Y;
|
|
get->M43 = position.Z;
|
|
get->M44 = 1f;
|
|
VfxNativeBridge.UpdateVfxTransform(data->Instance, get);
|
|
}
|
|
|
|
public unsafe void UpdateColor(Vector4 color)
|
|
{
|
|
if (IsValid && !(this.color == color))
|
|
{
|
|
this.color = color;
|
|
VfxNativeBridge.UpdateVfxColor(data->Instance, color.X, color.Y, color.Z, color.W);
|
|
}
|
|
}
|
|
|
|
private unsafe void MaybeRefreshVfxResourceInstance()
|
|
{
|
|
if (!IsValid && libOwned && path != null)
|
|
{
|
|
data = CreateVfxInternal(path, position, size, rotation, color);
|
|
}
|
|
}
|
|
}
|