Files
2025-10-12 14:33:16 +03:00

186 lines
6.2 KiB
C#
Executable File

using System;
using System.Collections.Generic;
using System.Text.Json;
namespace ReFuel.Gltf
{
public class GltfAccessor : GltfIdObject
{
public override GltfObjectKind Kind => GltfObjectKind.Accessor;
private GltfSmartId<GltfBufferView> bufferView;
public GltfBufferView? BufferView
{
get => bufferView.IsSet ? bufferView.Value : null;
set
{
if (value is null)
bufferView.Reset();
else
bufferView.Value = value;
}
}
public long ByteOffset { get; set; } = 0;
public GltfComponentType ComponentType { get; set; } = GltfComponentType.Float;
public bool Normalized { get; set; } = false;
public int Count { get; set; } = 0;
public GltfAccessorType Type { get; set; } = GltfAccessorType.Scalar;
public float[]? Max { get; set; } = null;
public float[]? Min { get; set; } = null;
public object? Sparse { get; set; } = null;
public string? Name { get; set; } = null;
public GltfAccessor(GltfDocument document) : base(document)
{
bufferView = new GltfSmartId<GltfBufferView>(document.BufferViews);
}
internal override void Deserialize(JsonElement element)
{
AssertObject(element);
if (element.TryGetProperty("bufferView", out JsonElement viewElement))
{
if (!viewElement.TryGetInt32(out int viewId))
{
PropertyFormatFail("bufferView", "expected an integer.");
}
else
{
bufferView.Id = viewId;
}
}
if (element.TryGetProperty("byteOffset", out JsonElement offsetElement))
{
if (!offsetElement.TryGetInt64(out long offset))
{
PropertyFormatFail("byteOffset", "expected an integer.");
}
else
{
ByteOffset = offset;
}
}
if (!element.TryGetProperty("componentType", out JsonElement componentElement))
{
RequiredProperty("componentType");
}
else if (!componentElement.TryGetInt32(out int i))
{
PropertyFormatFail("componentType", "expected an integer.");
}
else
{
ComponentType = (GltfComponentType)i;
}
if (element.TryGetProperty("normalized", out JsonElement normalizedElement))
{
switch (normalizedElement.ValueKind)
{
case JsonValueKind.True:
Normalized = true;
break;
case JsonValueKind.False:
Normalized = false;
break;
default:
PropertyFormatFail("normalized", "expected a boolean.");
break;
}
}
if (!element.TryGetProperty("count", out JsonElement countElement))
RequiredProperty("count");
else if (!countElement.TryGetInt32(out int i))
PropertyFormatFail("count", "expected an integer.");
else
Count = i;
if (!element.TryGetProperty("type", out JsonElement typeElement) )
RequiredProperty("type");
else
{
switch (typeElement.GetString())
{
case "SCALAR":
Type = GltfAccessorType.Scalar;
break;
case "VEC2":
Type = GltfAccessorType.Vec2;
break;
case "VEC3":
Type = GltfAccessorType.Vec3;
break;
case "VEC4":
Type = GltfAccessorType.Vec4;
break;
case "MAT2":
Type = GltfAccessorType.Mat2;
break;
case "MAT3":
Type = GltfAccessorType.Mat3;
break;
case "MAT4":
Type = GltfAccessorType.Mat4;
break;
default:
RequiredProperty("type");
break;
}
}
if (element.TryGetProperty("min", out JsonElement minElement))
{
if (minElement.ValueKind != JsonValueKind.Array)
PropertyFormatFail("min", "expected an array.");
List<float> floats = new List<float>();
foreach (JsonElement child in minElement.EnumerateArray())
{
if (!child.TryGetSingle(out float f))
PropertyFormatFail("min", "expected numeric array members.");
floats.Add(f);
}
Min = floats.ToArray();
}
if (element.TryGetProperty("max", out JsonElement maxElement))
{
if (minElement.ValueKind != JsonValueKind.Array)
PropertyFormatFail("max", "expected an array.");
List<float> floats = new List<float>();
foreach (JsonElement child in minElement.EnumerateArray())
{
if (!child.TryGetSingle(out float f))
PropertyFormatFail("max", "expected numeric array members.");
floats.Add(f);
}
Max = floats.ToArray();
}
// TODO: I'm skipping sparse for now.
if (element.TryGetProperty("name", out JsonElement nameElement))
{
Name = nameElement.GetString();
}
}
internal override void Serialize(Utf8JsonWriter writer)
{
throw new NotImplementedException();
}
}
}