Interact with Materials from scripts

This commit is contained in:
Simon Lübeß
2025-02-14 11:54:07 +01:00
parent e5437c6ff6
commit aaed4199d3
24 changed files with 739 additions and 64 deletions
+36 -3
View File
@@ -276,9 +276,12 @@ internal class EntityEditor
var value = (T)reference!;
if (format == null && value is float || value is double || value is Half)
if (format == null)
{
format = "0.#####";
if (value is float || value is double || value is Half)
format = "0.#####";
else
format = "0";
}
if (!format.StartsWith("%"))
@@ -512,14 +515,44 @@ internal class EntityEditor
{
newValue = ShowDecimalEditor(reference, fieldType, fieldName, attributes);
}
else if (fieldType == typeof(ColorHSV))
{
string fieldId = StartNewProperty(fieldName, attributes);
ColorHSV value = (ColorHSV)reference!;
value.H /= 360.0f;
if (ImGui.ColorEdit3(fieldId, ref Unsafe.As<ColorHSV, Vector3>(ref value),
ImGuiColorEditFlags.DisplayHSV | ImGuiColorEditFlags.InputHSV | ImGuiColorEditFlags.Float))
{
value.H *= 360.0f;
newValue = value;
}
}
else if (fieldType == typeof(ColorRGB))
{
string fieldId = StartNewProperty(fieldName, attributes);
ColorRGB value = (ColorRGB)reference!;
if (ImGui.ColorEdit3(fieldId, ref Unsafe.As<ColorRGB, Vector3>(ref value), ImGuiColorEditFlags.Float))
newValue = value;
}
else if (fieldType == typeof(ColorRGBA))
{
string fieldId = StartNewProperty(fieldName, attributes);
ColorRGBA value = (ColorRGBA)reference!;
if (ImGui.ColorEdit4(fieldId, ref Unsafe.As<ColorRGBA, Vector4>(ref value)))
if (ImGui.ColorEdit4(fieldId, ref Unsafe.As<ColorRGBA, Vector4>(ref value), ImGuiColorEditFlags.Float))
newValue = value;
}
else if (fieldType == typeof(Color))
{
string fieldId = StartNewProperty(fieldName, attributes);
Color value = (Color)reference!;
ColorRGBA color = (ColorRGBA)value;
if (ImGui.ColorEdit4(fieldId, ref Unsafe.As<ColorRGBA, Vector4>(ref color)))
newValue = (Color)color;
}
else if (fieldType.TryGetCustomAttribute(out VectorAttribute vectorAttribute))
{
newValue = ShowVectorEditor(reference, fieldType, fieldName, vectorAttribute, attributes);
+22
View File
@@ -0,0 +1,22 @@
using GlitchyEngine.Core;
namespace GlitchyEngine.Graphics;
/// <summary>
/// The base class for all assets.
/// </summary>
public class Asset : EngineObject
{
/// <summary>
/// Gets or sets the Identifier of the asset.
/// </summary>
public string Identifier
{
get
{
ScriptGlue.Asset_GetIdentifier(_uuid, out string identifier);
return identifier;
}
set => ScriptGlue.Asset_SetIdentifier(_uuid, value);
}
}
+1 -1
View File
@@ -26,7 +26,7 @@ public class CircleRenderer : Component
/// <summary>
/// Gets or sets the UV transform for the texture. XY are an offset, ZW are scaling
/// </summary>
public float4 UvTransform
public float4 UVTransform
{
get
{
+15
View File
@@ -0,0 +1,15 @@
using System.Diagnostics.SymbolStore;
using GlitchyEngine.Math;
namespace GlitchyEngine.Graphics;
public class Material : Asset
{
public void SetVariable(string name, float4 value)
{
unsafe
{
ScriptGlue.Material_SetVariable(_uuid, name, ScriptGlue.ShaderVariableType.Float, 1, 4, 1, &value, sizeof(float4));
}
}
}
+12
View File
@@ -0,0 +1,12 @@
using GlitchyEngine.Core;
namespace GlitchyEngine.Graphics;
/// <summary>
/// Holds a reference to a Mesh.
/// Can be used in combination with a <see cref="MeshRenderer"/> on the same <see cref="Entity"/> to render the mesh.
/// </summary>
public class Mesh : Component
{
}
+23
View File
@@ -0,0 +1,23 @@
using GlitchyEngine.Core;
namespace GlitchyEngine.Graphics;
/// <summary>
/// Renders a Mesh. The Mesh can be specified by adding a <see cref="Mesh"/> component to the same <see cref="Entity"/>.
/// </summary>
public class MeshRenderer : Component
{
/// <summary>
/// Gets or sets the Material of this <see cref="MeshRenderer"/>.
/// </summary>
public Material Material
{
get
{
ScriptGlue.MeshRenderer_GetMaterial(_uuid, out UUID materialHandle);
return new Material { _uuid = materialHandle };
}
set => ScriptGlue.MeshRenderer_SetMaterial(_uuid, value._uuid);
}
}
+52
View File
@@ -0,0 +1,52 @@
using GlitchyEngine.Core;
using GlitchyEngine.Math;
namespace GlitchyEngine.Graphics;
/// <summary>
/// Component that renders a sprite.
/// </summary>
public class SpriteRenderer : Component
{
// TODO: Texture2D/Sprite
/// <summary>
/// Gets or sets the tint color.
/// </summary>
public ColorRGBA Color
{
get
{
ScriptGlue.SpriteRenderer_GetColor(_uuid, out ColorRGBA color);
return color;
}
set => ScriptGlue.SpriteRenderer_SetColor(_uuid, value);
}
/// <summary>
/// Gets or sets the UV-transform.
/// </summary>
public UVTransform UVTransform
{
get
{
ScriptGlue.SpriteRenderer_GetUvTransform(_uuid, out UVTransform uvTransform);
return uvTransform;
}
set => ScriptGlue.SpriteRenderer_SetUvTransform(_uuid, value);
}
/// <summary>
/// Gets or sets the Material of this SpriteRenderer.
/// </summary>
public Material Material
{
get
{
ScriptGlue.SpriteRenderer_GetMaterial(_uuid, out UUID materialHandle);
return new Material { _uuid = materialHandle };
}
set => ScriptGlue.SpriteRenderer_SetMaterial(_uuid, value._uuid);
}
}
+39
View File
@@ -0,0 +1,39 @@
using System.Runtime.InteropServices;
using GlitchyEngine.Math;
namespace GlitchyEngine.Graphics;
/// <summary>
/// Stores transformations that can be applied to UV-Coordinates.
/// </summary>
[StructLayout(LayoutKind.Sequential, Pack=1)]
public struct UVTransform
{
/// <summary>
/// The offset that will be added to the UV-Coordinate.
/// </summary>
public float2 Offset;
/// <summary>
/// The scaling that will be applied to the UV-Coordinate.
/// </summary>
public float2 Scale;
/// <summary>
/// Creates a new instance of <see cref="UVTransform"/> with the given scale and offset.
/// </summary>
/// <param name="offset"><inheritdoc cref="Offset"/></param>
/// <param name="scale"><inheritdoc cref="Scale"/></param>
public UVTransform(float2 offset, float2 scale)
{
Offset = offset;
Scale = scale;
}
/// <summary>
/// Transforms the given uv-coordinate.
/// </summary>
public float2 Transform(float2 uvCoordinate)
{
return Offset + uvCoordinate * Scale;
}
}
+115
View File
@@ -0,0 +1,115 @@
namespace GlitchyEngine.Math;
/// <summary>
/// Represents a color with hue, saturation and value.
/// </summary>
public struct ColorHSV
{
/// <summary>
/// The hue of the color. Range: 0 - 360°
/// </summary>
public float H;
/// <summary>
/// The saturation of the color. Range: 0 - 1
/// </summary>
public float S;
/// <summary>
/// The value of the color. Range: 0 - 1
/// </summary>
public float V;
/// <summary>
/// Creates a new instance of a <see cref="ColorHSV"/> based on the given hue, saturation and value.
/// </summary>
/// <param name="h"><inheritdoc cref="H"/></param>
/// <param name="s"><inheritdoc cref="S"/></param>
/// <param name="v"><inheritdoc cref="V"/></param>
public ColorHSV(float h, float s, float v)
{
H = h;
S = s;
V = v;
}
/// <summary>
/// Creates a new instance of a <see cref="ColorHSV"/> based on the given <see cref="ColorRGB"/>.
/// </summary>
/// <param name="colorRGB">The RGB color that is to be converted to an HSV color</param>
public ColorHSV(ColorRGB colorRGB)
{
this = (ColorHSV)colorRGB;
}
public static explicit operator ColorRGB(ColorHSV hsv)
{
float c = hsv.V * hsv.S;
float x = c * (1.0f - Math.abs((hsv.H / 60.0f) % 2.0f - 1.0f));
float m = hsv.V - c;
ColorRGB rgb = new ColorRGB();
hsv.H %= 360.0f;
if (hsv.H < 60.0f)
rgb = new ColorRGB(c, x, 0);
else if (hsv.H < 120.0f)
rgb = new ColorRGB(x, c, 0);
else if (hsv.H < 180.0f)
rgb = new ColorRGB(0, c, x);
else if (hsv.H < 240.0f)
rgb = new ColorRGB(0, x, c);
else if (hsv.H < 300.0f)
rgb = new ColorRGB(x, 0, c);
else if (hsv.H < 360.0f)
rgb = new ColorRGB(c, 0, x);
return new ColorRGB(rgb.R + m, rgb.G + m, rgb.B + m);
}
public static explicit operator ColorHSV(ColorRGB rgb)
{
float r = rgb.R;
float g = rgb.G;
float b = rgb.B;
float h;
float s;
float v;
float maxChannel = Math.max(r, Math.max(g, b));
float minChannel = Math.min(r, Math.min(g, b));
v = maxChannel;
if (minChannel == maxChannel)
{
h = 0.0f;
s = 0.0f;
}
else
{
s = (maxChannel - minChannel) / maxChannel;
float rc = (maxChannel - r) / (maxChannel - minChannel);
float gc = (maxChannel - g) / (maxChannel - minChannel);
float bc = (maxChannel - b) / (maxChannel - minChannel);
if (r == maxChannel)
{
h = 0.0f + bc - gc;
}
else if (g == maxChannel)
{
h = 2.0f + rc - bc;
}
else
{
h = 4.0f + gc - rc;
}
h = (h / 6.0f) % 1.0f;
h *= 360.0f;
}
return new ColorHSV(h, s, v);
}
}
+63 -4
View File
@@ -3,6 +3,7 @@ using System.Numerics;
using System.Runtime.CompilerServices;
using GlitchyEngine.Core;
using GlitchyEngine.Editor;
using GlitchyEngine.Graphics;
using GlitchyEngine.Graphics.Text;
using GlitchyEngine.Math;
using GlitchyEngine.Physics;
@@ -256,6 +257,28 @@ internal static class ScriptGlue
#endregion
#region SpriteRenderer
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void SpriteRenderer_GetColor(UUID entityId, out ColorRGBA color);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void SpriteRenderer_SetColor(UUID entityId, ColorRGBA color);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void SpriteRenderer_GetUvTransform(UUID entityId, out UVTransform uvTransform);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void SpriteRenderer_SetUvTransform(UUID entityId, UVTransform uvTransform);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void SpriteRenderer_GetMaterial(UUID entityId, out UUID materialId);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void SpriteRenderer_SetMaterial(UUID entityId, UUID materialId);
#endregion
#region TextRenderer
[MethodImpl(MethodImplOptions.InternalCall)]
@@ -290,6 +313,17 @@ internal static class ScriptGlue
#endregion
#region MeshRenderer
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void MeshRenderer_GetMaterial(UUID entityId, out UUID materialId);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void MeshRenderer_SetMaterial(UUID entityId, UUID materialId);
#endregion
#region Math
[MethodImpl(MethodImplOptions.InternalCall)]
@@ -309,7 +343,7 @@ internal static class ScriptGlue
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void UUID_CreateNew(out UUID uuid);
#region Application
#region Application
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern bool Application_IsEditor();
@@ -323,9 +357,9 @@ internal static class ScriptGlue
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern bool Application_IsInPlayMode();
#endregion
#endregion
#region Serialization
#region Serialization
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void Serialization_SerializeField(IntPtr serializationContext, SerializationType type, string name, object? value, string? fullTypeName = null);
@@ -342,7 +376,32 @@ internal static class ScriptGlue
[MethodImpl(MethodImplOptions.InternalCall)]
public static extern void Serialization_GetObjectTypeName(IntPtr internalContext, out string fullTypeName);
#endregion
#endregion
#region Asset
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void Asset_GetIdentifier(UUID assetId, out string text);
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void Asset_SetIdentifier(UUID assetId, string text);
#endregion
#region Material
public enum ShaderVariableType : byte
{
Bool,
Float,
Int,
UInt
}
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern unsafe bool Material_SetVariable(UUID assetId, String variableName, ShaderVariableType elementType, int rows, int columns, int arrayLength, void* rawData, int dataLength);
#endregion
#region ImGui