UniGLTF/Runtime/UniGLTF/Format の UnityEngine 依存を除去

This commit is contained in:
ousttrue
2020-12-01 18:33:25 +09:00
parent f7f6730fec
commit f309225320
36 changed files with 545 additions and 17589 deletions

View File

@@ -0,0 +1,431 @@
using System;
using System.Linq;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using UnityEngine;
using System.IO;
using UniJSON;
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);
// index buffer's byteStride is unnecessary
gltf.bufferViews[viewIndex].byteStride = 0;
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;
}
public static int AddBuffer(this glTF self, IBytesBuffer bytesBuffer)
{
var index = self.buffers.Count;
self.buffers.Add(new glTFBuffer(bytesBuffer));
return index;
}
static T[] GetAttrib<T>(this glTF self, int count, int byteOffset, glTFBufferView view) where T : struct
{
var attrib = new T[count];
var segment = self.buffers[view.buffer].GetBytes();
var bytes = new ArraySegment<Byte>(segment.Array, segment.Offset + view.byteOffset + byteOffset, count * view.byteStride);
bytes.MarshalCopyTo(attrib);
return attrib;
}
static T[] GetAttrib<T>(this glTF self, glTFAccessor accessor, glTFBufferView view) where T : struct
{
return self.GetAttrib<T>(accessor.count, accessor.byteOffset, view);
}
static IEnumerable<int> _GetIndices(this glTF self, glTFAccessor accessor, out int count)
{
count = accessor.count;
var view = self.bufferViews[accessor.bufferView];
switch ((glComponentType)accessor.componentType)
{
case glComponentType.UNSIGNED_BYTE:
{
return self.GetAttrib<Byte>(accessor, view).Select(x => (int)(x));
}
case glComponentType.UNSIGNED_SHORT:
{
return self.GetAttrib<UInt16>(accessor, view).Select(x => (int)(x));
}
case glComponentType.UNSIGNED_INT:
{
return self.GetAttrib<UInt32>(accessor, view).Select(x => (int)(x));
}
}
throw new NotImplementedException("GetIndices: unknown componenttype: " + accessor.componentType);
}
static IEnumerable<int> _GetIndices(this glTF self, glTFBufferView view, int count, int byteOffset, glComponentType componentType)
{
switch (componentType)
{
case glComponentType.UNSIGNED_BYTE:
{
return self.GetAttrib<Byte>(count, byteOffset, view).Select(x => (int)(x));
}
case glComponentType.UNSIGNED_SHORT:
{
return self.GetAttrib<UInt16>(count, byteOffset, view).Select(x => (int)(x));
}
case glComponentType.UNSIGNED_INT:
{
return self.GetAttrib<UInt32>(count, byteOffset, view).Select(x => (int)(x));
}
}
throw new NotImplementedException("GetIndices: unknown componenttype: " + componentType);
}
public static int[] GetIndices(this glTF self, int accessorIndex)
{
int count;
var result = self._GetIndices(self.accessors[accessorIndex], out count);
var indices = new int[count];
// flip triangles
var it = result.GetEnumerator();
{
for (int i = 0; i < count; i += 3)
{
it.MoveNext(); indices[i + 2] = it.Current;
it.MoveNext(); indices[i + 1] = it.Current;
it.MoveNext(); indices[i] = it.Current;
}
}
return indices;
}
public static T[] GetArrayFromAccessor<T>(this glTF self, int accessorIndex) where T : struct
{
var vertexAccessor = self.accessors[accessorIndex];
if (vertexAccessor.count <= 0) return new T[] { };
var result = (vertexAccessor.bufferView != -1)
? self.GetAttrib<T>(vertexAccessor, self.bufferViews[vertexAccessor.bufferView])
: new T[vertexAccessor.count]
;
var sparse = vertexAccessor.sparse;
if (sparse != null && sparse.count > 0)
{
// override sparse values
var indices = self._GetIndices(self.bufferViews[sparse.indices.bufferView], sparse.count, sparse.indices.byteOffset, sparse.indices.componentType);
var values = self.GetAttrib<T>(sparse.count, sparse.values.byteOffset, self.bufferViews[sparse.values.bufferView]);
var it = indices.GetEnumerator();
for (int i = 0; i < sparse.count; ++i)
{
it.MoveNext();
result[it.Current] = values[i];
}
}
return result;
}
public static ArraySegment<Byte> GetImageBytes(this glTF self, IStorage storage, int imageIndex, out string textureName)
{
var image = self.images[imageIndex];
if (string.IsNullOrEmpty(image.uri))
{
//
// use buffer view (GLB)
//
//m_imageBytes = ToArray(byteSegment);
textureName = !string.IsNullOrEmpty(image.name) ? image.name : string.Format("{0:00}#GLB", imageIndex);
return self.GetViewBytes(image.bufferView);
}
else
{
if (image.uri.StartsWith("data:"))
{
textureName = !string.IsNullOrEmpty(image.name) ? image.name : string.Format("{0:00}#Base64Embedded", imageIndex);
}
else
{
textureName = !string.IsNullOrEmpty(image.name) ? image.name : Path.GetFileNameWithoutExtension(image.uri);
}
return storage.Get(image.uri);
}
}
static Utf8String s_extensions = Utf8String.From("extensions");
static bool UsedExtension(this glTF self, string key)
{
if (self.extensionsUsed.Contains(key))
{
return true;
}
return false;
}
static void Traverse(this glTF self, ListTreeNode<JsonValue> node, JsonFormatter f, Utf8String parentKey)
{
if (node.IsMap())
{
f.BeginMap();
foreach (var kv in node.ObjectItems())
{
if (parentKey == s_extensions)
{
if (!self.UsedExtension(kv.Key.GetString()))
{
continue;
}
}
f.Key(kv.Key.GetUtf8String());
self.Traverse(kv.Value, f, kv.Key.GetUtf8String());
}
f.EndMap();
}
else if (node.IsArray())
{
f.BeginList();
foreach (var x in node.ArrayItems())
{
self.Traverse(x, f, default(Utf8String));
}
f.EndList();
}
else
{
f.Value(node);
}
}
static string RemoveUnusedExtensions(this glTF self, string json)
{
var f = new JsonFormatter();
self.Traverse(JsonParser.Parse(json), f, default(Utf8String));
return f.ToString();
}
public static byte[] ToGlbBytes(this glTF self)
{
var f = new JsonFormatter();
GltfSerializer.Serialize(f, self);
var json = f.ToString().ParseAsJson().ToString(" ");
self.RemoveUnusedExtensions(json);
return Glb.ToBytes(json, self.buffers[0].GetBytes());
}
public static (string, List<glTFBuffer>) ToGltf(this glTF self, string gltfPath)
{
var f = new JsonFormatter();
// fix buffer path
if (self.buffers.Count == 1)
{
var withoutExt = Path.GetFileNameWithoutExtension(gltfPath);
self.buffers[0].uri = $"{withoutExt}.bin";
}
else
{
throw new NotImplementedException();
}
GltfSerializer.Serialize(f, self);
var json = f.ToString().ParseAsJson().ToString(" ");
self.RemoveUnusedExtensions(json);
return (json, self.buffers);
}
}
}

View File

@@ -1,203 +0,0 @@
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);
// index buffer's byteStride is unnecessary
gltf.bufferViews[viewIndex].byteStride = 0;
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;
}
}
}

View File

@@ -0,0 +1,35 @@
using System;
using System.IO;
namespace UniGLTF
{
/// <summary>
/// for glb chunk buffer read
/// </summary>
public class ArraySegmentByteBuffer : IBytesBuffer
{
ArraySegment<Byte> m_bytes;
public ArraySegmentByteBuffer(ArraySegment<Byte> bytes)
{
m_bytes = bytes;
}
public string Uri
{
get;
private set;
}
public glTFBufferView Extend<T>(ArraySegment<T> array, glBufferTarget target) where T : struct
{
throw new NotImplementedException();
}
public ArraySegment<byte> GetBytes()
{
return m_bytes;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f857b8b7ca45b1746af90c7fb86b2398
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.Linq;
using UniJSON;
using UnityEngine;
namespace UniGLTF
{
@@ -90,21 +89,21 @@ namespace UniGLTF
return false;
}
public static void Serialize(glTFTextureInfo info, Vector2 offset, Vector2 scale)
public static void Serialize(glTFTextureInfo info, (float, float) offset, (float, float) scale)
{
var f = new JsonFormatter();
f.BeginMap();
f.Key("offset");
f.BeginList();
f.Value(offset.x);
f.Value(offset.y);
f.Value(offset.Item1);
f.Value(offset.Item2);
f.EndList();
f.Key("scale");
f.BeginList();
f.Value(scale.x);
f.Value(scale.y);
f.Value(scale.Item1);
f.Value(scale.Item2);
f.EndList();
f.EndMap();

View File

@@ -0,0 +1,11 @@
using System;
namespace UniGLTF
{
public interface IBytesBuffer
{
string Uri { get; }
ArraySegment<Byte> GetBytes();
glTFBufferView Extend<T>(ArraySegment<T> array, glBufferTarget target) where T : struct;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2ce69a95857efe041a1e3dd9d2e6c98b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,16 @@
using System;
namespace UniGLTF
{
public interface IStorage
{
ArraySegment<Byte> Get(string url);
/// <summary>
/// Get original filepath if exists
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
string GetPath(string url);
}
}

View File

@@ -1,8 +1,7 @@
fileFormatVersion: 2
guid: 9cb8b6f878e36a74f90d172daee60bed
timeCreated: 1529327531
licenseType: Free
guid: 6e3316b83a7396047839d12538e5db52
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0

View File

@@ -28,12 +28,6 @@ namespace UniGLTF
#region Buffer
[JsonSchema(MinItems = 1, ExplicitIgnorableItemLength = 0)]
public List<glTFBuffer> buffers = new List<glTFBuffer>();
public int AddBuffer(IBytesBuffer bytesBuffer)
{
var index = buffers.Count;
buffers.Add(new glTFBuffer(bytesBuffer));
return index;
}
[JsonSchema(MinItems = 1, ExplicitIgnorableItemLength = 0)]
public List<glTFBufferView> bufferViews = new List<glTFBufferView>();
@@ -47,119 +41,12 @@ namespace UniGLTF
[JsonSchema(MinItems = 1, ExplicitIgnorableItemLength = 0)]
public List<glTFAccessor> accessors = new List<glTFAccessor>();
T[] GetAttrib<T>(glTFAccessor accessor, glTFBufferView view) where T : struct
{
return GetAttrib<T>(accessor.count, accessor.byteOffset, view);
}
T[] GetAttrib<T>(int count, int byteOffset, glTFBufferView view) where T : struct
{
var attrib = new T[count];
var segment = buffers[view.buffer].GetBytes();
var bytes = new ArraySegment<Byte>(segment.Array, segment.Offset + view.byteOffset + byteOffset, count * view.byteStride);
bytes.MarshalCopyTo(attrib);
return attrib;
}
public ArraySegment<Byte> GetViewBytes(int bufferView)
{
var view = bufferViews[bufferView];
var segment = buffers[view.buffer].GetBytes();
return new ArraySegment<byte>(segment.Array, segment.Offset + view.byteOffset, view.byteLength);
}
IEnumerable<int> _GetIndices(glTFAccessor accessor, out int count)
{
count = accessor.count;
var view = bufferViews[accessor.bufferView];
switch ((glComponentType)accessor.componentType)
{
case glComponentType.UNSIGNED_BYTE:
{
return GetAttrib<Byte>(accessor, view).Select(x => (int)(x));
}
case glComponentType.UNSIGNED_SHORT:
{
return GetAttrib<UInt16>(accessor, view).Select(x => (int)(x));
}
case glComponentType.UNSIGNED_INT:
{
return GetAttrib<UInt32>(accessor, view).Select(x => (int)(x));
}
}
throw new NotImplementedException("GetIndices: unknown componenttype: " + accessor.componentType);
}
IEnumerable<int> _GetIndices(glTFBufferView view, int count, int byteOffset, glComponentType componentType)
{
switch (componentType)
{
case glComponentType.UNSIGNED_BYTE:
{
return GetAttrib<Byte>(count, byteOffset, view).Select(x => (int)(x));
}
case glComponentType.UNSIGNED_SHORT:
{
return GetAttrib<UInt16>(count, byteOffset, view).Select(x => (int)(x));
}
case glComponentType.UNSIGNED_INT:
{
return GetAttrib<UInt32>(count, byteOffset, view).Select(x => (int)(x));
}
}
throw new NotImplementedException("GetIndices: unknown componenttype: " + componentType);
}
public int[] GetIndices(int accessorIndex)
{
int count;
var result = _GetIndices(accessors[accessorIndex], out count);
var indices = new int[count];
// flip triangles
var it = result.GetEnumerator();
{
for (int i = 0; i < count; i += 3)
{
it.MoveNext(); indices[i + 2] = it.Current;
it.MoveNext(); indices[i + 1] = it.Current;
it.MoveNext(); indices[i] = it.Current;
}
}
return indices;
}
public T[] GetArrayFromAccessor<T>(int accessorIndex) where T : struct
{
var vertexAccessor = accessors[accessorIndex];
if (vertexAccessor.count <= 0) return new T[] { };
var result = (vertexAccessor.bufferView != -1)
? GetAttrib<T>(vertexAccessor, bufferViews[vertexAccessor.bufferView])
: new T[vertexAccessor.count]
;
var sparse = vertexAccessor.sparse;
if (sparse != null && sparse.count > 0)
{
// override sparse values
var indices = _GetIndices(bufferViews[sparse.indices.bufferView], sparse.count, sparse.indices.byteOffset, sparse.indices.componentType);
var values = GetAttrib<T>(sparse.count, sparse.values.byteOffset, bufferViews[sparse.values.bufferView]);
var it = indices.GetEnumerator();
for (int i = 0; i < sparse.count; ++i)
{
it.MoveNext();
result[it.Current] = values[i];
}
}
return result;
}
#endregion
[JsonSchema(MinItems = 1, ExplicitIgnorableItemLength = 0)]
@@ -196,32 +83,6 @@ namespace UniGLTF
return GetSampler(samplerIndex);
}
public ArraySegment<Byte> GetImageBytes(IStorage storage, int imageIndex, out string textureName)
{
var image = images[imageIndex];
if (string.IsNullOrEmpty(image.uri))
{
//
// use buffer view (GLB)
//
//m_imageBytes = ToArray(byteSegment);
textureName = !string.IsNullOrEmpty(image.name) ? image.name : string.Format("{0:00}#GLB", imageIndex);
return GetViewBytes(image.bufferView);
}
else
{
if (image.uri.StartsWith("data:"))
{
textureName = !string.IsNullOrEmpty(image.name) ? image.name : string.Format("{0:00}#Base64Embedded", imageIndex);
}
else
{
textureName = !string.IsNullOrEmpty(image.name) ? image.name : Path.GetFileNameWithoutExtension(image.uri);
}
return storage.Get(image.uri);
}
}
[JsonSchema(MinItems = 1, ExplicitIgnorableItemLength = 0)]
public List<glTFMaterial> materials = new List<glTFMaterial>();
public string GetUniqueMaterialName(int index)
@@ -321,94 +182,5 @@ namespace UniGLTF
&& animations.SequenceEqual(other.animations)
;
}
bool UsedExtension(string key)
{
if (extensionsUsed.Contains(key))
{
return true;
}
return false;
}
static Utf8String s_extensions = Utf8String.From("extensions");
void Traverse(ListTreeNode<JsonValue> node, JsonFormatter f, Utf8String parentKey)
{
if (node.IsMap())
{
f.BeginMap();
foreach (var kv in node.ObjectItems())
{
if (parentKey == s_extensions)
{
if (!UsedExtension(kv.Key.GetString()))
{
continue;
}
}
f.Key(kv.Key.GetUtf8String());
Traverse(kv.Value, f, kv.Key.GetUtf8String());
}
f.EndMap();
}
else if (node.IsArray())
{
f.BeginList();
foreach (var x in node.ArrayItems())
{
Traverse(x, f, default(Utf8String));
}
f.EndList();
}
else
{
f.Value(node);
}
}
string RemoveUnusedExtensions(string json)
{
var f = new JsonFormatter();
Traverse(JsonParser.Parse(json), f, default(Utf8String));
return f.ToString();
}
public byte[] ToGlbBytes()
{
var f = new JsonFormatter();
GltfSerializer.Serialize(f, this);
var json = f.ToString().ParseAsJson().ToString(" ");
RemoveUnusedExtensions(json);
return Glb.ToBytes(json, buffers[0].GetBytes());
}
public (string, List<glTFBuffer>) ToGltf(string gltfPath)
{
var f = new JsonFormatter();
// fix buffer path
if (buffers.Count == 1)
{
var withoutExt = Path.GetFileNameWithoutExtension(gltfPath);
buffers[0].uri = $"{withoutExt}.bin";
}
else
{
throw new NotImplementedException();
}
GltfSerializer.Serialize(f, this);
var json = f.ToString().ParseAsJson().ToString(" ");
RemoveUnusedExtensions(json);
return (json, buffers);
}
}
}

View File

@@ -5,13 +5,6 @@ using System.Runtime.InteropServices;
namespace UniGLTF
{
public interface IBytesBuffer
{
string Uri { get; }
ArraySegment<Byte> GetBytes();
glTFBufferView Extend<T>(ArraySegment<T> array, glBufferTarget target) where T : struct;
}
public static class IBytesBufferExtensions
{
public static glTFBufferView Extend<T>(this IBytesBuffer buffer, T[] array, glBufferTarget target) where T : struct
@@ -88,34 +81,6 @@ namespace UniGLTF
}
}
/// <summary>
/// for glb chunk buffer read
/// </summary>
public class ArraySegmentByteBuffer : IBytesBuffer
{
ArraySegment<Byte> m_bytes;
public ArraySegmentByteBuffer(ArraySegment<Byte> bytes)
{
m_bytes = bytes;
}
public string Uri
{
get;
private set;
}
public glTFBufferView Extend<T>(ArraySegment<T> array, glBufferTarget target) where T : struct
{
throw new NotImplementedException();
}
public ArraySegment<byte> GetBytes()
{
return m_bytes;
}
}
/// <summary>
/// for exporter

View File

@@ -1,7 +1,5 @@
fileFormatVersion: 2
guid: 33b0000c5446b7547bcad1da1e9768ed
timeCreated: 1516730619
licenseType: Free
guid: 1e9c9201942704b4f9dd050115073032
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -1,26 +1,13 @@
using System;
using System;
using System.IO;
namespace UniGLTF
{
public interface IStorage
{
ArraySegment<Byte> Get(string url);
/// <summary>
/// Get original filepath if exists
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
string GetPath(string url);
}
public class SimpleStorage : IStorage
{
ArraySegment<Byte> m_bytes;
public SimpleStorage():this(new ArraySegment<byte>())
public SimpleStorage() : this(new ArraySegment<byte>())
{
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ca59fdd271a96dd409ea98e128fbebca
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -190,7 +190,7 @@ namespace UniGLTF
var scale = m.GetTextureScale(propertyName);
offset.y = (offset.y + scale.y - 1) * -1.0f;
glTF_KHR_texture_transform.Serialize(textureInfo, offset, scale);
glTF_KHR_texture_transform.Serialize(textureInfo, (offset.x, offset.y), (scale.x, scale.y));
}
}

View File

@@ -1,9 +1,9 @@
using System;
using System.IO;
using System.Text;
using UnityEngine;
using System.Reflection;
#if UNITY_EDITOR
using UnityEngine;
using UnityEditor;
#endif

View File

@@ -29,6 +29,7 @@ namespace UniJSON
f.Value(new ArraySegment<Byte>(bytes));
}
#if UNITY_5_6_OR_NEWER
public static void Value(this IFormatter f, UnityEngine.Vector2 v)
{
//CommaCheck();
@@ -58,6 +59,7 @@ namespace UniJSON
f.Key("w"); f.Value(v.w);
f.EndMap();
}
#endif
static MethodInfo GetMethod<T>(Expression<Func<T>> expression)
{

View File

@@ -1,7 +1,7 @@
using System;
using System.Reflection;
using UnityEngine;
#if UNITY_EDITOR && VRM_DEVELOP
using UnityEngine;
using System.IO;
using System.Linq;
using System.Text;

View File

@@ -1,5 +1,4 @@
using UnityEngine;
using NUnit.Framework;
using NUnit.Framework;
using System.Collections;
using System;

View File

@@ -1,5 +1,4 @@
using NUnit.Framework;
using UnityEngine;
using System.Linq;
using System.Text;

View File

@@ -142,8 +142,8 @@ namespace VRM.Samples
var parsed = f.ToString().ParseAsJson();
var newJson = parsed.ToString(" ");
File.WriteAllText("old.json", oldJson);
File.WriteAllText("new.json", newJson);
// File.WriteAllText("old.json", oldJson);
// File.WriteAllText("new.json", newJson);
// 比較
Assert.AreEqual(oldJson.ParseAsJson().ToString(), newJson.ParseAsJson().ToString());

View File

@@ -1,4 +1,5 @@
using System.IO;
using UniGLTF;
using UnityEngine;
using UnityEngine.UI;
using VRM;

8544
new.json

File diff suppressed because it is too large Load Diff

8544
old.json

File diff suppressed because it is too large Load Diff