holopy3/Assets/UniGLTF/Core/Scripts/Extensions/glTFExtensions.cs
Lena Biresch 490ef558ef CleanUp
2021-01-28 13:07:52 +01:00

199 lines
6.7 KiB
C#

using System;
using System.Linq;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using UnityEngine;
namespace UniGLTF
{
[Serializable, StructLayout(LayoutKind.Sequential, Pack = 1)]
struct UShort4
{
public ushort x;
public ushort y;
public ushort z;
public ushort w;
public UShort4(ushort _x, ushort _y, ushort _z, ushort _w)
{
x = _x;
y = _y;
z = _z;
w = _w;
}
}
public static class glTFExtensions
{
struct ComponentVec
{
public glComponentType ComponentType;
public int ElementCount;
public ComponentVec(glComponentType componentType, int elementCount)
{
ComponentType = componentType;
ElementCount = elementCount;
}
}
static Dictionary<Type, ComponentVec> ComponentTypeMap = new Dictionary<Type, ComponentVec>
{
{ typeof(Vector2), new ComponentVec(glComponentType.FLOAT, 2) },
{ typeof(Vector3), new ComponentVec(glComponentType.FLOAT, 3) },
{ typeof(Vector4), new ComponentVec(glComponentType.FLOAT, 4) },
{ typeof(UShort4), new ComponentVec(glComponentType.UNSIGNED_SHORT, 4) },
{ typeof(Matrix4x4), new ComponentVec(glComponentType.FLOAT, 16) },
{ typeof(Color), new ComponentVec(glComponentType.FLOAT, 4) },
};
static glComponentType GetComponentType<T>()
{
var cv = default(ComponentVec);
if (ComponentTypeMap.TryGetValue(typeof(T), out cv))
{
return cv.ComponentType;
}
else if (typeof(T) == typeof(uint))
{
return glComponentType.UNSIGNED_INT;
}
else if (typeof(T) == typeof(float))
{
return glComponentType.FLOAT;
}
else
{
throw new NotImplementedException(typeof(T).Name);
}
}
static string GetAccessorType<T>()
{
var cv = default(ComponentVec);
if (ComponentTypeMap.TryGetValue(typeof(T), out cv))
{
switch (cv.ElementCount)
{
case 2: return "VEC2";
case 3: return "VEC3";
case 4: return "VEC4";
case 16: return "MAT4";
default: throw new Exception();
}
}
else
{
return "SCALAR";
}
}
static int GetAccessorElementCount<T>()
{
var cv = default(ComponentVec);
if (ComponentTypeMap.TryGetValue(typeof(T), out cv))
{
return cv.ElementCount;
}
else
{
return 1;
}
}
public static int ExtendBufferAndGetAccessorIndex<T>(this glTF gltf, int bufferIndex, T[] array,
glBufferTarget target = glBufferTarget.NONE) where T : struct
{
return gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, new ArraySegment<T>(array), target);
}
public static int ExtendBufferAndGetAccessorIndex<T>(this glTF gltf, int bufferIndex,
ArraySegment<T> array,
glBufferTarget target = glBufferTarget.NONE) where T : struct
{
if (array.Count == 0)
{
return -1;
}
var viewIndex = ExtendBufferAndGetViewIndex(gltf, bufferIndex, array, target);
var accessorIndex = gltf.accessors.Count;
gltf.accessors.Add(new glTFAccessor
{
bufferView = viewIndex,
byteOffset = 0,
componentType = GetComponentType<T>(),
type = GetAccessorType<T>(),
count = array.Count,
});
return accessorIndex;
}
public static int ExtendBufferAndGetViewIndex<T>(this glTF gltf, int bufferIndex,
T[] array,
glBufferTarget target = glBufferTarget.NONE) where T : struct
{
return ExtendBufferAndGetViewIndex(gltf, bufferIndex, new ArraySegment<T>(array), target);
}
public static int ExtendBufferAndGetViewIndex<T>(this glTF gltf, int bufferIndex,
ArraySegment<T> array,
glBufferTarget target = glBufferTarget.NONE) where T : struct
{
if (array.Count == 0)
{
return -1;
}
var view = gltf.buffers[bufferIndex].Append(array, target);
var viewIndex = gltf.bufferViews.Count;
gltf.bufferViews.Add(view);
return viewIndex;
}
public static int ExtendSparseBufferAndGetAccessorIndex<T>(this glTF gltf, int bufferIndex,
int accessorCount,
T[] sparseValues, int[] sparseIndices, int sparseViewIndex,
glBufferTarget target = glBufferTarget.NONE) where T : struct
{
return ExtendSparseBufferAndGetAccessorIndex(gltf, bufferIndex,
accessorCount,
new ArraySegment<T>(sparseValues), sparseIndices, sparseViewIndex,
target);
}
public static int ExtendSparseBufferAndGetAccessorIndex<T>(this glTF gltf, int bufferIndex,
int accessorCount,
ArraySegment<T> sparseValues, int[] sparseIndices, int sparseIndicesViewIndex,
glBufferTarget target = glBufferTarget.NONE) where T : struct
{
if (sparseValues.Count == 0)
{
return -1;
}
var sparseValuesViewIndex = ExtendBufferAndGetViewIndex(gltf, bufferIndex, sparseValues, target);
var accessorIndex = gltf.accessors.Count;
gltf.accessors.Add(new glTFAccessor
{
byteOffset = 0,
componentType = GetComponentType<T>(),
type = GetAccessorType<T>(),
count = accessorCount,
sparse = new glTFSparse
{
count=sparseIndices.Length,
indices = new glTFSparseIndices
{
bufferView = sparseIndicesViewIndex,
componentType = glComponentType.UNSIGNED_INT
},
values = new glTFSparseValues
{
bufferView = sparseValuesViewIndex,
}
}
});
return accessorIndex;
}
}
}