Serialize Mesh and MeshRenderer in scene + fixed Light serialization

This commit is contained in:
Simon Lübeß
2023-01-08 19:31:01 +01:00
parent b5ca86d8de
commit e38373dccf
8 changed files with 204 additions and 42 deletions
+76 -3
View File
@@ -14,7 +14,7 @@
A = 1 A = 1
}, },
IsCircle = false, IsCircle = false,
Sprite = null, Sprite = "\\Textures\\TestMat\\rustediron2_albedo.png",
UvTransform = { UvTransform = {
X = 0, X = 0,
Y = 0, Y = 0,
@@ -164,7 +164,7 @@
OrthographicHeight = 10, OrthographicHeight = 10,
OrthographicNearPlane = 0, OrthographicNearPlane = 0,
OrthographicFarPlane = 10, OrthographicFarPlane = 10,
AspectRatio = 2.156692, AspectRatio = 2.969697,
FixedAspectRatio = false FixedAspectRatio = false
} }
}, },
@@ -181,7 +181,7 @@
A = 1 A = 1
}, },
IsCircle = true, IsCircle = true,
Sprite = "Textures/rocket.png", Sprite = "\\Textures\\rocket.png",
UvTransform = { UvTransform = {
X = 0, X = 0,
Y = 0, Y = 0,
@@ -227,6 +227,79 @@
Restitution = 0, Restitution = 0,
RestitutionThreshold = 0.5 RestitutionThreshold = 0.5
} }
},
{
Id = 935640822766280888,
NameComponent = {
Name = "Light"
},
TransformComponent = {
Position = {
X = 3.883276,
Y = 0,
Z = -0.808795
},
Rotation = {
X = 0.497987,
Y = -0.103421,
Z = 0.15538,
W = 0.846859
},
Scale = {
X = 0.999998,
Y = 1,
Z = 1
},
EditorEulerRotation = {
X = 1.090894,
Y = -0.340794,
Z = 0.160858
}
},
LightComponent = {
LightType = .Directional,
Illuminance = 12.9,
Color = {
R = 0.985467,
G = 1,
B = 0.569979
}
}
},
{
Id = 721949523193525565,
NameComponent = {
Name = "Sphere"
},
TransformComponent = {
Position = {
X = 0,
Y = 0,
Z = -1.523338
},
Rotation = {
X = 0,
Y = 0,
Z = 0,
W = 1
},
Scale = {
X = 1,
Y = 1,
Z = 1
},
EditorEulerRotation = {
X = 0,
Y = 0,
Z = 0
}
},
MeshComponent = {
Mesh = "\\Models\\sphere.glb"
},
MeshRendererComponent = {
Material = "\\Textures\\TestMaterial.mat"
}
} }
] ]
} }
@@ -77,15 +77,16 @@ class MaterialAssetLoader : IAssetLoader //, IReloadingAssetLoader
for (let (slotName, textureIdentifier) in materialFile.Textures) for (let (slotName, textureIdentifier) in materialFile.Textures)
{ {
Texture texture = contentManager.LoadAsset(textureIdentifier) as Texture; using (Texture texture = contentManager.LoadAsset(textureIdentifier) as Texture)
if (texture == null)
{ {
Log.EngineLogger.Error("Failed to load texture."); if (texture == null)
// TODO: LoadAsset should return an error texture. {
} Log.EngineLogger.Error("Failed to load texture.");
// TODO: LoadAsset should return an error texture.
}
material.SetTexture(slotName, texture); material.SetTexture(slotName, texture);
}
} }
fx.ReleaseRef(); fx.ReleaseRef();
@@ -268,10 +268,10 @@ namespace GlitchyEditor.EditWindows
StringView path = .((char8*)payload.Data, (int)payload.DataSize); StringView path = .((char8*)payload.Data, (int)payload.DataSize);
Texture2D texture = Content.LoadAsset<Texture2D>(path);//new Texture2D(path, true); using (Texture2D texture = Content.LoadAsset<Texture2D>(path))
{
spriteRendererComponent.Sprite?.ReleaseRef(); spriteRendererComponent.Sprite = texture;
spriteRendererComponent.Sprite = texture; }
} }
ImGui.EndDragDropTarget(); ImGui.EndDragDropTarget();
+45
View File
@@ -1,8 +1,12 @@
using GlitchyEngine.Core; using GlitchyEngine.Core;
using System; using System;
using Bon;
using Bon.Integrated;
using System.Reflection;
namespace GlitchyEngine.Content; namespace GlitchyEngine.Content;
[BonTarget]
class Asset : RefCounter class Asset : RefCounter
{ {
private append String _identifier; private append String _identifier;
@@ -28,10 +32,51 @@ class Asset : RefCounter
/// Gets the content manager that manages this asset; or null if this asset isn't managed. /// Gets the content manager that manages this asset; or null if this asset isn't managed.
public IContentManager ContentManager => _contentManager; public IContentManager ContentManager => _contentManager;
static this
{
gBonEnv.typeHandlers.Add(typeof(Asset),
((.)new => AssetSerialize, new => AssetDeserialize));
}
protected ~this() protected ~this()
{ {
// TODO: crash when _contentManager is deleted first... // TODO: crash when _contentManager is deleted first...
// TODO: unregister from content manager // TODO: unregister from content manager
_contentManager?.UnmanageAsset(this); _contentManager?.UnmanageAsset(this);
} }
static void AssetSerialize(BonWriter writer, ValueView value, BonEnvironment environment)
{
Log.EngineLogger.Assert(value.type == typeof(Asset));
let identifier = value.Get<Asset>().Identifier;
writer.String(identifier);
}
static Result<void> AssetDeserialize(BonReader reader, ValueView value, BonEnvironment environment)//, DeserializeFieldState state)
{
Log.EngineLogger.Assert(value.type == typeof(Asset));
String identifier = scope .();
Deserialize.String!(reader, ref identifier, environment);
Asset asset = Application.Get().ContentManager.LoadAsset(identifier);
if (asset != null)
{
Asset oldAsset = value.Get<Asset>();
oldAsset.ReleaseRef();
value.Assign(asset);
return .Ok;
}
else
{
Deserialize.Error!("Invalid resource path", reader, value.type);
}
}
//gBonEnv.typeHandlers.Add(typeof(Resource<>),
// ((.)new => ResourceSerialize, (.)new => ResourceDeserialize));
} }
+2
View File
@@ -1,9 +1,11 @@
using Bon;
using System; using System;
namespace GlitchyEngine.Math namespace GlitchyEngine.Math
{ {
/// Represents a four component color with 8 bit per channel /// Represents a four component color with 8 bit per channel
[CRepr] [CRepr]
[BonTarget]
public struct Color public struct Color
{ {
// from DirectXColors.h // from DirectXColors.h
+2
View File
@@ -1,3 +1,4 @@
using Bon;
using System; using System;
using internal GlitchyEngine.Math; using internal GlitchyEngine.Math;
@@ -6,6 +7,7 @@ namespace GlitchyEngine.Math
{ {
/// Represents an RGB color. /// Represents an RGB color.
[CRepr] [CRepr]
[BonTarget]
public struct ColorRGB public struct ColorRGB
{ {
/** /**
+15 -2
View File
@@ -46,7 +46,20 @@ namespace GlitchyEngine.World
[Component("Sprite Renderer")] [Component("Sprite Renderer")]
struct SpriterRendererComponent : IDisposableComponent struct SpriterRendererComponent : IDisposableComponent
{ {
public Texture2D Sprite = null; private Texture2D _sprite = null;
public Texture2D Sprite
{
get => _sprite;
set mut
{
if (_sprite == value)
return;
SetReference!(_sprite, value);
}
}
public ColorRGBA Color = .White; public ColorRGBA Color = .White;
public Vector4 UvTransform = .(0, 0, 1, 1); public Vector4 UvTransform = .(0, 0, 1, 1);
@@ -63,7 +76,7 @@ namespace GlitchyEngine.World
public void Dispose() public void Dispose()
{ {
Sprite?.ReleaseRef(); _sprite?.ReleaseRef();
} }
} }
+51 -25
View File
@@ -88,7 +88,7 @@ namespace GlitchyEngine.World
{ {
Serialize.Value(writer, "Color", component.Color); Serialize.Value(writer, "Color", component.Color);
Serialize.Value(writer, "IsCircle", component.IsCircle); Serialize.Value(writer, "IsCircle", component.IsCircle);
Serialize.Value(writer, "Sprite", component.Sprite); Serialize.Value(writer, "Sprite", component.Sprite?.Identifier);
Serialize.Value(writer, "UvTransform", component.UvTransform); Serialize.Value(writer, "UvTransform", component.UvTransform);
}); });
@@ -169,6 +169,16 @@ namespace GlitchyEngine.World
Serialize.Value(writer, "Restitution", component.Restitution); Serialize.Value(writer, "Restitution", component.Restitution);
Serialize.Value(writer, "RestitutionThreshold", component.RestitutionThreshold); Serialize.Value(writer, "RestitutionThreshold", component.RestitutionThreshold);
}); });
SerializeComponent<MeshComponent>(writer, entity, "MeshComponent", scope (component) =>
{
Serialize.Value(writer, "Mesh", component.Mesh.Identifier);
});
SerializeComponent<MeshRendererComponent>(writer, entity, "MeshRendererComponent", scope (component) =>
{
Serialize.Value(writer, "Material", component.Material.Identifier);
});
} }
writer.EntryEnd(); writer.EntryEnd();
@@ -260,6 +270,21 @@ namespace GlitchyEngine.World
private Result<void> DeserializeEntity(BonReader reader) private Result<void> DeserializeEntity(BonReader reader)
{ {
mixin DeserializeAsset<T>(StringView identifier) where T : Asset
{
Asset asset = null;
Try!(Deserialize.Value(reader, identifier, out asset));
if (asset != null && !(asset is T))
{
Log.EngineLogger.Error($"Asset {asset.Identifier} is not a {nameof(T)}.");
return .Err;
}
(T)asset
}
Try!(reader.ObjectBlock()); Try!(reader.ObjectBlock());
Deserialize.Value<uint64>(reader, "Id", let uuid); Deserialize.Value<uint64>(reader, "Id", let uuid);
@@ -287,40 +312,22 @@ namespace GlitchyEngine.World
delete name; delete name;
return .Ok;
}));
case "NameComponent":
Try!(DeserializeComponent<DebugNameComponent>(reader, entity, scope (component) =>
{
String name;
Deserialize.Value(reader, "Name", out name);
component.SetName(name);
delete name;
return .Ok; return .Ok;
})); }));
case "SpriterRendererComponent": case "SpriterRendererComponent":
Try!(DeserializeComponent<SpriterRendererComponent>(reader, entity, scope (component) => Try!(DeserializeComponent<SpriterRendererComponent>(reader, entity, scope (component) =>
{ {
// TODO: Texture
Try!(Deserialize.Value(reader, "Color", out component.Color)); Try!(Deserialize.Value(reader, "Color", out component.Color));
reader.EntryEnd(); reader.EntryEnd();
Try!(Deserialize.Value(reader, "IsCircle", out component.IsCircle)); Try!(Deserialize.Value(reader, "IsCircle", out component.IsCircle));
reader.EntryEnd(); reader.EntryEnd();
String spriteName; using (Texture2D sprite = DeserializeAsset!<Texture2D>("Sprite"))
Try!(Deserialize.Value(reader, "Sprite", out spriteName)); {
component.Sprite = (Texture2D)sprite;
if (spriteName != null) }
component.Sprite = Content.LoadAsset<Texture2D>(spriteName);
delete spriteName;
reader.EntryEnd(); reader.EntryEnd();
Try!(Deserialize.Value(reader, "UvTransform", out component.UvTransform)); Try!(Deserialize.Value(reader, "UvTransform", out component.UvTransform));
return .Ok; return .Ok;
@@ -407,7 +414,7 @@ namespace GlitchyEngine.World
case "LightComponent": case "LightComponent":
Try!(DeserializeComponent<LightComponent>(reader, entity, scope (component) => Try!(DeserializeComponent<LightComponent>(reader, entity, scope (component) =>
{ {
SceneLight light = component.SceneLight; ref SceneLight light = ref component.SceneLight;
Deserialize.Value(reader, "LightType", out light.[Friend]_type); Deserialize.Value(reader, "LightType", out light.[Friend]_type);
reader.EntryEnd(); reader.EntryEnd();
@@ -464,7 +471,26 @@ namespace GlitchyEngine.World
return .Ok; return .Ok;
})); }));
case "MeshComponent":
Try!(DeserializeComponent<MeshComponent>(reader, entity, scope (component) =>
{
using (GeometryBinding mesh = DeserializeAsset!<GeometryBinding>("Mesh"))
{
component.Mesh = mesh;
}
return .Ok;
}));
case "MeshRendererComponent":
Try!(DeserializeComponent<MeshRendererComponent>(reader, entity, scope (component) =>
{
using (Material material = DeserializeAsset!<Material>("Material"))
{
component.Material = material;
}
return .Ok;
}));
default: default:
Log.EngineLogger.AssertDebug(false, "Unknown component type"); Log.EngineLogger.AssertDebug(false, "Unknown component type");
//return .Err; //return .Err;