mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-08-27 13:24:42 -05:00
Merge pull request #1339 from ousttrue/gltf_buffer_helper
[Maintenance] refactoring gltf buffer access
This commit is contained in:
@@ -100,8 +100,8 @@ namespace UniGLTF
|
||||
default: throw new System.Exception();
|
||||
}
|
||||
|
||||
var gltf = new glTF();
|
||||
using (var exporter = new gltfExporter(gltf, Settings))
|
||||
var data = new ExportingGltfData();
|
||||
using (var exporter = new gltfExporter(data, Settings))
|
||||
{
|
||||
exporter.Prepare(State.ExportRoot);
|
||||
exporter.Export(new EditorTextureSerializer());
|
||||
@@ -109,12 +109,12 @@ namespace UniGLTF
|
||||
|
||||
if (isGlb)
|
||||
{
|
||||
var bytes = gltf.ToGlbBytes();
|
||||
var bytes = data.ToGlbBytes();
|
||||
File.WriteAllBytes(path, bytes);
|
||||
}
|
||||
else
|
||||
{
|
||||
var (json, buffers) = gltf.ToGltf(path);
|
||||
var (json, buffers) = data.ToGltf(path);
|
||||
// without BOM
|
||||
var encoding = new System.Text.UTF8Encoding(false);
|
||||
File.WriteAllText(path, json, encoding);
|
||||
|
||||
@@ -17,7 +17,6 @@ namespace UniGLTF
|
||||
public GltfData Data => m_data;
|
||||
|
||||
public glTF GLTF => m_data.GLTF;
|
||||
public IStorage Storage => m_data.Storage;
|
||||
|
||||
public readonly Dictionary<SubAssetKey, UnityPath> Textures = new Dictionary<SubAssetKey, UnityPath>();
|
||||
private readonly IReadOnlyDictionary<SubAssetKey, Texture> m_subAssets;
|
||||
|
||||
@@ -1,46 +1,11 @@
|
||||
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)]
|
||||
public struct Byte4
|
||||
{
|
||||
public readonly byte x;
|
||||
public readonly byte y;
|
||||
public readonly byte z;
|
||||
public readonly byte w;
|
||||
public Byte4(byte _x, byte _y, byte _z, byte _w)
|
||||
{
|
||||
x = _x;
|
||||
y = _y;
|
||||
z = _z;
|
||||
w = _w;
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable, StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct UShort4
|
||||
{
|
||||
public readonly ushort x;
|
||||
public readonly ushort y;
|
||||
public readonly ushort z;
|
||||
public readonly 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
|
||||
@@ -131,367 +96,6 @@ namespace UniGLTF
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// sparseValues は間引かれた配列
|
||||
/// </summary>
|
||||
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 float[] FlatternFloatArrayFromAccessor(this glTF self, int accessorIndex)
|
||||
{
|
||||
var vertexAccessor = self.accessors[accessorIndex];
|
||||
|
||||
if (vertexAccessor.count <= 0) return new float[] { };
|
||||
|
||||
var bufferCount = vertexAccessor.count * vertexAccessor.TypeCount;
|
||||
|
||||
float[] result = null;
|
||||
if (vertexAccessor.bufferView != -1)
|
||||
{
|
||||
var attrib = new float[vertexAccessor.count * vertexAccessor.TypeCount];
|
||||
var view = self.bufferViews[vertexAccessor.bufferView];
|
||||
var segment = self.buffers[view.buffer].GetBytes();
|
||||
var bytes = new ArraySegment<Byte>(segment.Array, segment.Offset + view.byteOffset + vertexAccessor.byteOffset, vertexAccessor.count * view.byteStride);
|
||||
bytes.MarshalCopyTo(attrib);
|
||||
result = attrib;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = new float[bufferCount];
|
||||
}
|
||||
|
||||
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<float>(sparse.count * vertexAccessor.TypeCount, 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> GetImageBytesFromTextureIndex(this glTF self, IStorage storage, int textureIndex)
|
||||
{
|
||||
var imageIndex = self.textures[textureIndex].source;
|
||||
return self.GetImageBytes(storage, imageIndex);
|
||||
}
|
||||
|
||||
public static ArraySegment<Byte> GetImageBytes(this glTF self, IStorage storage, int imageIndex)
|
||||
{
|
||||
var image = self.images[imageIndex];
|
||||
if (string.IsNullOrEmpty(image.uri))
|
||||
{
|
||||
return self.GetViewBytes(image.bufferView);
|
||||
}
|
||||
else
|
||||
{
|
||||
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, JsonNode 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);
|
||||
|
||||
// remove unused extenions
|
||||
var json = f.ToString().ParseAsJson().ToString(" ");
|
||||
self.RemoveUnusedExtensions(json);
|
||||
|
||||
return Glb.Create(json, self.buffers[0].GetBytes()).ToBytes();
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
public static bool IsGeneratedUniGLTFAndOlderThan(string generatorVersion, int major, int minor)
|
||||
{
|
||||
if (string.IsNullOrEmpty(generatorVersion)) return false;
|
||||
|
||||
@@ -2,15 +2,23 @@ using System;
|
||||
|
||||
namespace UniGLTF
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents bytes access by URL in gltf
|
||||
/// </summary>
|
||||
public interface IStorage
|
||||
{
|
||||
ArraySegment<Byte> Get(string url = default);
|
||||
|
||||
/// <summary>
|
||||
/// Get original filepath if exists
|
||||
/// gltf の buffer の バイト列アクセス を実装する。
|
||||
/// 1. url による相対パス
|
||||
/// 2. url によるbase64 encoding
|
||||
/// 3. url がnullのときに bin chunk(buffers[0]) にアクセスする
|
||||
///
|
||||
/// TODO:
|
||||
/// 1. url による相対パス
|
||||
/// 以外をやめて、呼び出し側で分岐させる。
|
||||
/// </summary>
|
||||
/// <param name="url"></param>
|
||||
/// <returns></returns>
|
||||
string GetPath(string url);
|
||||
ArraySegment<Byte> Get(string url = default);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6e3316b83a7396047839d12538e5db52
|
||||
guid: f87f7ed809642e0429061fd5f6c169f3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
|
||||
@@ -40,13 +40,6 @@ namespace UniGLTF
|
||||
|
||||
[JsonSchema(MinItems = 1, ExplicitIgnorableItemLength = 0)]
|
||||
public List<glTFAccessor> accessors = new List<glTFAccessor>();
|
||||
|
||||
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);
|
||||
}
|
||||
#endregion
|
||||
|
||||
[JsonSchema(MinItems = 1, ExplicitIgnorableItemLength = 0)]
|
||||
|
||||
@@ -185,7 +185,7 @@ namespace UniGLTF
|
||||
return string.Join("/", path);
|
||||
}
|
||||
|
||||
public static AnimationClip ConvertAnimationClip(glTF gltf, glTFAnimation animation, IAxisInverter inverter, glTFNode root = null)
|
||||
public static AnimationClip ConvertAnimationClip(GltfData data, glTFAnimation animation, IAxisInverter inverter, glTFNode root = null)
|
||||
{
|
||||
var clip = new AnimationClip();
|
||||
clip.ClearCurves();
|
||||
@@ -195,14 +195,14 @@ namespace UniGLTF
|
||||
|
||||
foreach (var channel in animation.channels)
|
||||
{
|
||||
var relativePath = RelativePathFrom(gltf.nodes, root, gltf.nodes[channel.target.node]);
|
||||
var relativePath = RelativePathFrom(data.GLTF.nodes, root, data.GLTF.nodes[channel.target.node]);
|
||||
switch (channel.target.path)
|
||||
{
|
||||
case glTFAnimationTarget.PATH_TRANSLATION:
|
||||
{
|
||||
var sampler = animation.samplers[channel.sampler];
|
||||
var input = gltf.GetArrayFromAccessor<float>(sampler.input);
|
||||
var output = gltf.FlatternFloatArrayFromAccessor(sampler.output);
|
||||
var input = data.GetArrayFromAccessor<float>(sampler.input);
|
||||
var output = data.FlatternFloatArrayFromAccessor(sampler.output);
|
||||
|
||||
AnimationImporterUtil.SetAnimationCurve(
|
||||
clip,
|
||||
@@ -224,8 +224,8 @@ namespace UniGLTF
|
||||
case glTFAnimationTarget.PATH_ROTATION:
|
||||
{
|
||||
var sampler = animation.samplers[channel.sampler];
|
||||
var input = gltf.GetArrayFromAccessor<float>(sampler.input);
|
||||
var output = gltf.FlatternFloatArrayFromAccessor(sampler.output);
|
||||
var input = data.GetArrayFromAccessor<float>(sampler.input);
|
||||
var output = data.FlatternFloatArrayFromAccessor(sampler.output);
|
||||
|
||||
AnimationImporterUtil.SetAnimationCurve(
|
||||
clip,
|
||||
@@ -250,8 +250,8 @@ namespace UniGLTF
|
||||
case glTFAnimationTarget.PATH_SCALE:
|
||||
{
|
||||
var sampler = animation.samplers[channel.sampler];
|
||||
var input = gltf.GetArrayFromAccessor<float>(sampler.input);
|
||||
var output = gltf.FlatternFloatArrayFromAccessor(sampler.output);
|
||||
var input = data.GetArrayFromAccessor<float>(sampler.input);
|
||||
var output = data.FlatternFloatArrayFromAccessor(sampler.output);
|
||||
|
||||
AnimationImporterUtil.SetAnimationCurve(
|
||||
clip,
|
||||
@@ -267,8 +267,8 @@ namespace UniGLTF
|
||||
|
||||
case glTFAnimationTarget.PATH_WEIGHT:
|
||||
{
|
||||
var node = gltf.nodes[channel.target.node];
|
||||
var mesh = gltf.meshes[node.mesh];
|
||||
var node = data.GLTF.nodes[channel.target.node];
|
||||
var mesh = data.GLTF.meshes[node.mesh];
|
||||
var primitive = mesh.primitives.FirstOrDefault();
|
||||
var targets = primitive.targets;
|
||||
|
||||
@@ -283,8 +283,8 @@ namespace UniGLTF
|
||||
.ToArray();
|
||||
|
||||
var sampler = animation.samplers[channel.sampler];
|
||||
var input = gltf.GetArrayFromAccessor<float>(sampler.input);
|
||||
var output = gltf.GetArrayFromAccessor<float>(sampler.output);
|
||||
var input = data.GetArrayFromAccessor<float>(sampler.input);
|
||||
var output = data.GetArrayFromAccessor<float>(sampler.output);
|
||||
AnimationImporterUtil.SetAnimationCurve(
|
||||
clip,
|
||||
relativePath,
|
||||
|
||||
26
Assets/UniGLTF/Runtime/UniGLTF/IO/Byte4.cs
Normal file
26
Assets/UniGLTF/Runtime/UniGLTF/IO/Byte4.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace UniGLTF
|
||||
{
|
||||
[Serializable, StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public readonly struct Byte4 : IEquatable<Byte4>
|
||||
{
|
||||
public readonly byte x;
|
||||
public readonly byte y;
|
||||
public readonly byte z;
|
||||
public readonly byte w;
|
||||
public Byte4(byte _x, byte _y, byte _z, byte _w)
|
||||
{
|
||||
x = _x;
|
||||
y = _y;
|
||||
z = _z;
|
||||
w = _w;
|
||||
}
|
||||
|
||||
public bool Equals(Byte4 other)
|
||||
{
|
||||
return x == other.x && y == other.y && z == other.z && w == other.w;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/UniGLTF/Runtime/UniGLTF/IO/Byte4.cs.meta
Normal file
11
Assets/UniGLTF/Runtime/UniGLTF/IO/Byte4.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7d396586954b6d34a84d9af8638e492e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
229
Assets/UniGLTF/Runtime/UniGLTF/IO/ExportingGltfData.cs
Normal file
229
Assets/UniGLTF/Runtime/UniGLTF/IO/ExportingGltfData.cs
Normal file
@@ -0,0 +1,229 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UniJSON;
|
||||
|
||||
namespace UniGLTF
|
||||
{
|
||||
public class ExportingGltfData
|
||||
{
|
||||
readonly glTF _gltf = new glTF();
|
||||
|
||||
public glTF GLTF => _gltf;
|
||||
|
||||
public ExportingGltfData(int reserved = default)
|
||||
{
|
||||
if (reserved == 0)
|
||||
{
|
||||
reserved = 50 * 1024 * 1024;
|
||||
}
|
||||
// glb body と gltf の bin 兼用
|
||||
_gltf.buffers.Add(new glTFBuffer(new ArrayByteBuffer(new byte[reserved])));
|
||||
}
|
||||
|
||||
#region Buffer management for export
|
||||
public int ExtendBufferAndGetViewIndex<T>(
|
||||
ArraySegment<T> array,
|
||||
glBufferTarget target = glBufferTarget.NONE) where T : struct
|
||||
{
|
||||
if (array.Count == 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
var view = _gltf.buffers[0].Append(array, target);
|
||||
var viewIndex = _gltf.bufferViews.Count;
|
||||
_gltf.bufferViews.Add(view);
|
||||
return viewIndex;
|
||||
}
|
||||
|
||||
public int ExtendBufferAndGetViewIndex<T>(
|
||||
T[] array,
|
||||
glBufferTarget target = glBufferTarget.NONE) where T : struct
|
||||
{
|
||||
return ExtendBufferAndGetViewIndex(new ArraySegment<T>(array), target);
|
||||
}
|
||||
|
||||
public int ExtendBufferAndGetAccessorIndex<T>(
|
||||
ArraySegment<T> array,
|
||||
glBufferTarget target = glBufferTarget.NONE) where T : struct
|
||||
{
|
||||
if (array.Count == 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
var viewIndex = ExtendBufferAndGetViewIndex(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 = glTFExtensions.GetComponentType<T>(),
|
||||
type = glTFExtensions.GetAccessorType<T>(),
|
||||
count = array.Count,
|
||||
});
|
||||
return accessorIndex;
|
||||
}
|
||||
|
||||
public int ExtendBufferAndGetAccessorIndex<T>(T[] array,
|
||||
glBufferTarget target = glBufferTarget.NONE) where T : struct
|
||||
{
|
||||
return ExtendBufferAndGetAccessorIndex(new ArraySegment<T>(array), target);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// sparseValues は間引かれた配列
|
||||
/// </summary>
|
||||
public int ExtendSparseBufferAndGetAccessorIndex<T>(
|
||||
int accessorCount,
|
||||
T[] sparseValues, int[] sparseIndices, int sparseViewIndex,
|
||||
glBufferTarget target = glBufferTarget.NONE) where T : struct
|
||||
{
|
||||
return ExtendSparseBufferAndGetAccessorIndex(
|
||||
accessorCount,
|
||||
new ArraySegment<T>(sparseValues), sparseIndices, sparseViewIndex,
|
||||
target);
|
||||
}
|
||||
|
||||
public int ExtendSparseBufferAndGetAccessorIndex<T>(
|
||||
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(sparseValues, target);
|
||||
var accessorIndex = _gltf.accessors.Count;
|
||||
_gltf.accessors.Add(new glTFAccessor
|
||||
{
|
||||
byteOffset = 0,
|
||||
componentType = glTFExtensions.GetComponentType<T>(),
|
||||
type = glTFExtensions.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;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ToGltf & ToGlb
|
||||
static Utf8String s_extensions = Utf8String.From("extensions");
|
||||
|
||||
static bool UsedExtension(glTF self, string key)
|
||||
{
|
||||
if (self.extensionsUsed.Contains(key))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void Traverse(glTF self, JsonNode node, JsonFormatter f, Utf8String parentKey)
|
||||
{
|
||||
if (node.IsMap())
|
||||
{
|
||||
f.BeginMap();
|
||||
foreach (var kv in node.ObjectItems())
|
||||
{
|
||||
if (parentKey == s_extensions)
|
||||
{
|
||||
if (!UsedExtension(self, kv.Key.GetString()))
|
||||
{
|
||||
// skip extension not in used
|
||||
continue;
|
||||
}
|
||||
}
|
||||
f.Key(kv.Key.GetUtf8String());
|
||||
Traverse(self, kv.Value, f, kv.Key.GetUtf8String());
|
||||
}
|
||||
f.EndMap();
|
||||
}
|
||||
else if (node.IsArray())
|
||||
{
|
||||
f.BeginList();
|
||||
foreach (var x in node.ArrayItems())
|
||||
{
|
||||
Traverse(self, x, f, default(Utf8String));
|
||||
}
|
||||
f.EndList();
|
||||
}
|
||||
else
|
||||
{
|
||||
f.Value(node);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 出力前に不要な extension を削除する
|
||||
/// </summary>
|
||||
/// <param name="self"></param>
|
||||
/// <param name="json"></param>
|
||||
/// <returns></returns>
|
||||
static string RemoveUnusedExtensions(glTF self, string json)
|
||||
{
|
||||
var f = new JsonFormatter();
|
||||
Traverse(self, JsonParser.Parse(json), f, default(Utf8String));
|
||||
return f.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// GLBバイト列
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public byte[] ToGlbBytes()
|
||||
{
|
||||
var f = new JsonFormatter();
|
||||
GltfSerializer.Serialize(f, _gltf);
|
||||
|
||||
// remove unused extenions
|
||||
var json = f.ToString().ParseAsJson().ToString(" ");
|
||||
RemoveUnusedExtensions(_gltf, json);
|
||||
return Glb.Create(json, _gltf.buffers[0].GetBytes()).ToBytes();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// glTF 形式で出力する?
|
||||
/// </summary>
|
||||
/// <param name="gltfPath"></param>
|
||||
/// <returns></returns>
|
||||
public (string, List<glTFBuffer>) ToGltf(string gltfPath)
|
||||
{
|
||||
// fix buffer path
|
||||
if (_gltf.buffers.Count == 1)
|
||||
{
|
||||
var withoutExt = Path.GetFileNameWithoutExtension(gltfPath);
|
||||
_gltf.buffers[0].uri = $"{withoutExt}.bin";
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
var f = new JsonFormatter();
|
||||
GltfSerializer.Serialize(f, _gltf);
|
||||
var json = f.ToString().ParseAsJson().ToString(" ");
|
||||
RemoveUnusedExtensions(_gltf, json);
|
||||
return (json, _gltf.buffers);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
11
Assets/UniGLTF/Runtime/UniGLTF/IO/ExportingGltfData.cs.meta
Normal file
11
Assets/UniGLTF/Runtime/UniGLTF/IO/ExportingGltfData.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8c397b99fe3e0db4fa7a25dc63fff6af
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,8 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace UniGLTF
|
||||
{
|
||||
/// <summary>
|
||||
/// Implement bin chunk access
|
||||
/// </summary>
|
||||
public class SimpleStorage : IStorage
|
||||
{
|
||||
ArraySegment<Byte> m_bytes;
|
||||
@@ -20,13 +24,11 @@ namespace UniGLTF
|
||||
{
|
||||
return m_bytes;
|
||||
}
|
||||
|
||||
public string GetPath(string url)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implement url that represnet relative path
|
||||
/// </summary>
|
||||
public class FileSystemStorage : IStorage
|
||||
{
|
||||
string m_root;
|
||||
@@ -45,17 +47,23 @@ namespace UniGLTF
|
||||
;
|
||||
return new ArraySegment<byte>(bytes);
|
||||
}
|
||||
}
|
||||
|
||||
public string GetPath(string url)
|
||||
/// <summary>
|
||||
/// for UnitTest
|
||||
/// </summary>
|
||||
public sealed class GltfStorage : IStorage
|
||||
{
|
||||
glTF _gltf;
|
||||
|
||||
public GltfStorage(glTF gltf)
|
||||
{
|
||||
if (url.FastStartsWith("data:"))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Path.Combine(m_root, url).Replace("\\", "/");
|
||||
}
|
||||
_gltf = gltf;
|
||||
}
|
||||
|
||||
public ArraySegment<byte> Get(string url)
|
||||
{
|
||||
return _gltf.buffers[0].GetBytes();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace UniGLTF
|
||||
{
|
||||
/// <summary>
|
||||
/// * JSON is parsed but not validated as glTF
|
||||
/// * For glb, bin chunks are already available
|
||||
/// </summary>
|
||||
public sealed class GltfData
|
||||
{
|
||||
/// <summary>
|
||||
@@ -42,7 +47,7 @@ namespace UniGLTF
|
||||
/// <summary>
|
||||
/// URI access
|
||||
/// </summary>
|
||||
public IStorage Storage { get; }
|
||||
public IStorage _storage;
|
||||
|
||||
/// <summary>
|
||||
/// Migration Flags used by ImporterContext
|
||||
@@ -55,20 +60,216 @@ namespace UniGLTF
|
||||
Json = json;
|
||||
GLTF = gltf;
|
||||
Chunks = chunks;
|
||||
Storage = storage;
|
||||
_storage = storage;
|
||||
MigrationFlags = migrationFlags;
|
||||
}
|
||||
|
||||
public static GltfData CreateFromGltfDataForTest(glTF gltf)
|
||||
public static GltfData CreateFromGltfDataForTest(glTF gltf, ArraySegment<byte> bytes = default)
|
||||
{
|
||||
IStorage storage = null;
|
||||
if (bytes.Array != null)
|
||||
{
|
||||
storage = new SimpleStorage(bytes);
|
||||
}
|
||||
else
|
||||
{
|
||||
storage = new GltfStorage(gltf);
|
||||
}
|
||||
return new GltfData(
|
||||
string.Empty,
|
||||
string.Empty,
|
||||
gltf,
|
||||
new List<GlbChunk>(),
|
||||
new SimpleStorage(new ArraySegment<byte>()),
|
||||
storage,
|
||||
new MigrationFlags()
|
||||
);
|
||||
}
|
||||
|
||||
public ArraySegment<Byte> GetBytes(int bufferIndex)
|
||||
{
|
||||
// TODO:
|
||||
var buffer = GLTF.buffers[bufferIndex];
|
||||
return _storage.Get(buffer.uri);
|
||||
}
|
||||
|
||||
public ArraySegment<Byte> GetViewBytes(int bufferView)
|
||||
{
|
||||
var view = GLTF.bufferViews[bufferView];
|
||||
var segment = GetBytes(view.buffer);
|
||||
return new ArraySegment<byte>(segment.Array, segment.Offset + view.byteOffset, view.byteLength);
|
||||
}
|
||||
|
||||
T[] GetAttrib<T>(int count, int byteOffset, glTFBufferView view) where T : struct
|
||||
{
|
||||
var segment = GetBytes(view.buffer);
|
||||
var attrib = new T[count];
|
||||
var bytes = new ArraySegment<Byte>(segment.Array, segment.Offset + view.byteOffset + byteOffset, count * view.byteStride);
|
||||
bytes.MarshalCopyTo(attrib);
|
||||
return attrib;
|
||||
}
|
||||
|
||||
T[] GetAttrib<T>(glTFAccessor accessor, glTFBufferView view) where T : struct
|
||||
{
|
||||
return GetAttrib<T>(accessor.count, accessor.byteOffset, view);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get indices and cast to int
|
||||
/// </summary>
|
||||
/// <param name="accessor"></param>
|
||||
/// <param name="count"></param>
|
||||
/// <returns></returns>
|
||||
IEnumerable<int> _GetIndices(glTFAccessor accessor, out int count)
|
||||
{
|
||||
count = accessor.count;
|
||||
var view = GLTF.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);
|
||||
}
|
||||
|
||||
public int[] GetIndices(int accessorIndex)
|
||||
{
|
||||
int count;
|
||||
var result = _GetIndices(GLTF.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 = GLTF.accessors[accessorIndex];
|
||||
|
||||
if (vertexAccessor.count <= 0) return new T[] { };
|
||||
|
||||
var result = (vertexAccessor.bufferView != -1)
|
||||
? GetAttrib<T>(vertexAccessor, GLTF.bufferViews[vertexAccessor.bufferView])
|
||||
: new T[vertexAccessor.count]
|
||||
;
|
||||
|
||||
var sparse = vertexAccessor.sparse;
|
||||
if (sparse != null && sparse.count > 0)
|
||||
{
|
||||
// override sparse values
|
||||
var indices = _GetIndices(GLTF.bufferViews[sparse.indices.bufferView], sparse.count, sparse.indices.byteOffset, sparse.indices.componentType);
|
||||
var values = GetAttrib<T>(sparse.count, sparse.values.byteOffset, GLTF.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 float[] FlatternFloatArrayFromAccessor(int accessorIndex)
|
||||
{
|
||||
var vertexAccessor = GLTF.accessors[accessorIndex];
|
||||
|
||||
if (vertexAccessor.count <= 0) return new float[] { };
|
||||
|
||||
var bufferCount = vertexAccessor.count * vertexAccessor.TypeCount;
|
||||
|
||||
float[] result = null;
|
||||
if (vertexAccessor.bufferView != -1)
|
||||
{
|
||||
var attrib = new float[vertexAccessor.count * vertexAccessor.TypeCount];
|
||||
var view = GLTF.bufferViews[vertexAccessor.bufferView];
|
||||
var segment = GetBytes(view.buffer);
|
||||
var bytes = new ArraySegment<Byte>(segment.Array, segment.Offset + view.byteOffset + vertexAccessor.byteOffset, vertexAccessor.count * view.byteStride);
|
||||
bytes.MarshalCopyTo(attrib);
|
||||
result = attrib;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = new float[bufferCount];
|
||||
}
|
||||
|
||||
var sparse = vertexAccessor.sparse;
|
||||
if (sparse != null && sparse.count > 0)
|
||||
{
|
||||
// override sparse values
|
||||
var indices = _GetIndices(GLTF.bufferViews[sparse.indices.bufferView], sparse.count, sparse.indices.byteOffset, sparse.indices.componentType);
|
||||
var values = GetAttrib<float>(sparse.count * vertexAccessor.TypeCount, sparse.values.byteOffset, GLTF.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 ArraySegment<Byte> GetImageBytes(int imageIndex)
|
||||
{
|
||||
var image = GLTF.images[imageIndex];
|
||||
if (string.IsNullOrEmpty(image.uri))
|
||||
{
|
||||
return GetViewBytes(image.bufferView);
|
||||
}
|
||||
else
|
||||
{
|
||||
return _storage.Get(image.uri);
|
||||
}
|
||||
}
|
||||
|
||||
public ArraySegment<Byte> GetImageBytesFromTextureIndex(int textureIndex)
|
||||
{
|
||||
var imageIndex = GLTF.textures[textureIndex].source;
|
||||
return GetImageBytes(imageIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,7 +57,6 @@ namespace UniGLTF
|
||||
public GltfData Data { get; }
|
||||
public String Json => Data.Json;
|
||||
public glTF GLTF => Data.GLTF;
|
||||
public IStorage Storage => Data.Storage;
|
||||
#endregion
|
||||
|
||||
// configuration
|
||||
@@ -135,7 +134,7 @@ namespace UniGLTF
|
||||
{
|
||||
await AnimationClipFactory.LoadAnimationClipAsync(key, () =>
|
||||
{
|
||||
var clip = AnimationImporterUtil.ConvertAnimationClip(GLTF, gltfAnimation, InvertAxis.Create());
|
||||
var clip = AnimationImporterUtil.ConvertAnimationClip(Data, gltfAnimation, InvertAxis.Create());
|
||||
return Task.FromResult(clip);
|
||||
});
|
||||
}
|
||||
@@ -178,7 +177,7 @@ namespace UniGLTF
|
||||
var index = i;
|
||||
using (MeasureTime("ReadMesh"))
|
||||
{
|
||||
var x = await awaitCaller.Run(() => meshImporter.ReadMesh(GLTF, index, inverter));
|
||||
var x = await awaitCaller.Run(() => meshImporter.ReadMesh(Data, index, inverter));
|
||||
var y = await BuildMeshAsync(awaitCaller, MeasureTime, x, index);
|
||||
Meshes.Add(y);
|
||||
}
|
||||
@@ -225,7 +224,7 @@ namespace UniGLTF
|
||||
Profiler.BeginSample("NodeImporter.SetupSkinning");
|
||||
for (var i = 0; i < nodes.Count; ++i)
|
||||
{
|
||||
NodeImporter.SetupSkinning(GLTF, nodes, i, inverter);
|
||||
NodeImporter.SetupSkinning(Data, nodes, i, inverter);
|
||||
}
|
||||
Profiler.EndSample();
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace UniGLTF
|
||||
{
|
||||
public static class BlendShapeExporter
|
||||
{
|
||||
public static gltfMorphTarget Export(glTF gltf, int gltfBuffer, Vector3[] positions, Vector3[] normals, bool useSparse)
|
||||
public static gltfMorphTarget Export(ExportingGltfData data, Vector3[] positions, Vector3[] normals, bool useSparse)
|
||||
{
|
||||
var accessorCount = positions.Length;
|
||||
if (normals != null && positions.Length != normals.Length)
|
||||
@@ -44,8 +44,8 @@ namespace UniGLTF
|
||||
var positionAccessorIndex = -1;
|
||||
if (sparseIndices.Length > 0)
|
||||
{
|
||||
var sparseIndicesViewIndex = gltf.ExtendBufferAndGetViewIndex(gltfBuffer, sparseIndices);
|
||||
positionAccessorIndex = gltf.ExtendSparseBufferAndGetAccessorIndex(gltfBuffer, accessorCount,
|
||||
var sparseIndicesViewIndex = data.ExtendBufferAndGetViewIndex(sparseIndices);
|
||||
positionAccessorIndex = data.ExtendSparseBufferAndGetAccessorIndex(accessorCount,
|
||||
sparseIndices.Select(x => positions[x]).ToArray(), sparseIndices, sparseIndicesViewIndex,
|
||||
glBufferTarget.NONE);
|
||||
}
|
||||
@@ -57,8 +57,8 @@ namespace UniGLTF
|
||||
var sparseNormalIndices = Enumerable.Range(0, positions.Length).Where(x => normals[x] != Vector3.zero).ToArray();
|
||||
if (sparseNormalIndices.Length > 0)
|
||||
{
|
||||
var sparseNormalIndicesViewIndex = gltf.ExtendBufferAndGetViewIndex(gltfBuffer, sparseNormalIndices);
|
||||
normalAccessorIndex = gltf.ExtendSparseBufferAndGetAccessorIndex(gltfBuffer, accessorCount,
|
||||
var sparseNormalIndicesViewIndex = data.ExtendBufferAndGetViewIndex(sparseNormalIndices);
|
||||
normalAccessorIndex = data.ExtendSparseBufferAndGetAccessorIndex(accessorCount,
|
||||
sparseNormalIndices.Select(x => normals[x]).ToArray(), sparseNormalIndices, sparseNormalIndicesViewIndex,
|
||||
glBufferTarget.NONE);
|
||||
}
|
||||
@@ -73,15 +73,15 @@ namespace UniGLTF
|
||||
else
|
||||
{
|
||||
// position
|
||||
var positionAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(gltfBuffer, positions, glBufferTarget.ARRAY_BUFFER);
|
||||
gltf.accessors[positionAccessorIndex].min = positions.Aggregate(positions[0], (a, b) => new Vector3(Mathf.Min(a.x, b.x), Math.Min(a.y, b.y), Mathf.Min(a.z, b.z))).ToArray();
|
||||
gltf.accessors[positionAccessorIndex].max = positions.Aggregate(positions[0], (a, b) => new Vector3(Mathf.Max(a.x, b.x), Math.Max(a.y, b.y), Mathf.Max(a.z, b.z))).ToArray();
|
||||
var positionAccessorIndex = data.ExtendBufferAndGetAccessorIndex(positions, glBufferTarget.ARRAY_BUFFER);
|
||||
data.GLTF.accessors[positionAccessorIndex].min = positions.Aggregate(positions[0], (a, b) => new Vector3(Mathf.Min(a.x, b.x), Math.Min(a.y, b.y), Mathf.Min(a.z, b.z))).ToArray();
|
||||
data.GLTF.accessors[positionAccessorIndex].max = positions.Aggregate(positions[0], (a, b) => new Vector3(Mathf.Max(a.x, b.x), Math.Max(a.y, b.y), Mathf.Max(a.z, b.z))).ToArray();
|
||||
|
||||
// normal
|
||||
var normalAccessorIndex = -1;
|
||||
if (normals != null)
|
||||
{
|
||||
normalAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(gltfBuffer, normals, glBufferTarget.ARRAY_BUFFER);
|
||||
normalAccessorIndex = data.ExtendBufferAndGetAccessorIndex(normals, glBufferTarget.ARRAY_BUFFER);
|
||||
}
|
||||
|
||||
return new gltfMorphTarget
|
||||
|
||||
@@ -9,14 +9,14 @@ namespace UniGLTF
|
||||
{
|
||||
public delegate (ushort x, ushort y, ushort z, ushort w) Getter(int index);
|
||||
|
||||
public static (Getter, int) GetAccessor(glTF gltf, int accessorIndex)
|
||||
public static (Getter, int) GetAccessor(GltfData data, int accessorIndex)
|
||||
{
|
||||
var gltfAccessor = gltf.accessors[accessorIndex];
|
||||
var gltfAccessor = data.GLTF.accessors[accessorIndex];
|
||||
switch (gltfAccessor.componentType)
|
||||
{
|
||||
case glComponentType.UNSIGNED_BYTE:
|
||||
{
|
||||
var array = gltf.GetArrayFromAccessor<Byte4>(accessorIndex);
|
||||
var array = data.GetArrayFromAccessor<Byte4>(accessorIndex);
|
||||
Getter getter = (i) =>
|
||||
{
|
||||
var value = array[i];
|
||||
@@ -27,7 +27,7 @@ namespace UniGLTF
|
||||
|
||||
case glComponentType.UNSIGNED_SHORT:
|
||||
{
|
||||
var array = gltf.GetArrayFromAccessor<UShort4>(accessorIndex);
|
||||
var array = data.GetArrayFromAccessor<UShort4>(accessorIndex);
|
||||
Getter getter = (i) =>
|
||||
{
|
||||
var value = array[i];
|
||||
|
||||
@@ -30,9 +30,9 @@ namespace UniGLTF
|
||||
m_normals[index] = normal;
|
||||
}
|
||||
|
||||
public gltfMorphTarget ToGltf(glTF gltf, int gltfBuffer, bool useNormal, bool useSparse)
|
||||
public gltfMorphTarget ToGltf(ExportingGltfData data, bool useNormal, bool useSparse)
|
||||
{
|
||||
return BlendShapeExporter.Export(gltf, gltfBuffer,
|
||||
return BlendShapeExporter.Export(data,
|
||||
m_positions,
|
||||
useNormal ? m_normals : null,
|
||||
useSparse);
|
||||
@@ -103,24 +103,24 @@ namespace UniGLTF
|
||||
m_weights.Add(new Vector4(boneWeight.weight0, boneWeight.weight1, boneWeight.weight2, boneWeight.weight3));
|
||||
}
|
||||
|
||||
public glTFPrimitives ToGltfPrimitive(glTF gltf, int bufferIndex, int materialIndex, IEnumerable<int> indices)
|
||||
public glTFPrimitives ToGltfPrimitive(ExportingGltfData data, int materialIndex, IEnumerable<int> indices)
|
||||
{
|
||||
var indicesAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, indices.Select(x => (uint)m_vertexIndexMap[x]).ToArray(), glBufferTarget.ELEMENT_ARRAY_BUFFER);
|
||||
var indicesAccessorIndex = data.ExtendBufferAndGetAccessorIndex(indices.Select(x => (uint)m_vertexIndexMap[x]).ToArray(), glBufferTarget.ELEMENT_ARRAY_BUFFER);
|
||||
var positions = m_positions.ToArray();
|
||||
var positionAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, positions, glBufferTarget.ARRAY_BUFFER);
|
||||
var positionAccessorIndex = data.ExtendBufferAndGetAccessorIndex(positions, glBufferTarget.ARRAY_BUFFER);
|
||||
var normals = m_normals.ToArray();
|
||||
var normalAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, normals, glBufferTarget.ARRAY_BUFFER);
|
||||
var uvAccessorIndex0 = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, m_uv.ToArray(), glBufferTarget.ARRAY_BUFFER);
|
||||
var normalAccessorIndex = data.ExtendBufferAndGetAccessorIndex(normals, glBufferTarget.ARRAY_BUFFER);
|
||||
var uvAccessorIndex0 = data.ExtendBufferAndGetAccessorIndex(m_uv.ToArray(), glBufferTarget.ARRAY_BUFFER);
|
||||
|
||||
int? jointsAccessorIndex = default;
|
||||
if (m_joints != null)
|
||||
{
|
||||
jointsAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, m_joints.ToArray(), glBufferTarget.ARRAY_BUFFER);
|
||||
jointsAccessorIndex = data.ExtendBufferAndGetAccessorIndex(m_joints.ToArray(), glBufferTarget.ARRAY_BUFFER);
|
||||
}
|
||||
int? weightAccessorIndex = default;
|
||||
if (m_weights != null)
|
||||
{
|
||||
weightAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, m_weights.ToArray(), glBufferTarget.ARRAY_BUFFER);
|
||||
weightAccessorIndex = data.ExtendBufferAndGetAccessorIndex(m_weights.ToArray(), glBufferTarget.ARRAY_BUFFER);
|
||||
}
|
||||
|
||||
var primitive = new glTFPrimitives
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace UniGLTF
|
||||
/// <param name="axisInverter"></param>
|
||||
/// <param name="settings"></param>
|
||||
/// <returns></returns>
|
||||
public static (glTFMesh, Dictionary<int, int>) Export(glTF gltf, int gltfBuffer,
|
||||
public static (glTFMesh, Dictionary<int, int>) Export(ExportingGltfData data,
|
||||
MeshExportInfo unityMesh, List<Material> unityMaterials,
|
||||
IAxisInverter axisInverter, GltfExportSettings settings)
|
||||
{
|
||||
@@ -84,7 +84,7 @@ namespace UniGLTF
|
||||
flipped.Add(t1);
|
||||
flipped.Add(t0);
|
||||
}
|
||||
var gltfPrimitive = buffer.ToGltfPrimitive(gltf, gltfBuffer, materialIndex, flipped);
|
||||
var gltfPrimitive = buffer.ToGltfPrimitive(data, materialIndex, flipped);
|
||||
|
||||
// blendShape(morph target)
|
||||
for (int j = 0; j < mesh.blendShapeCount; ++j)
|
||||
@@ -101,7 +101,7 @@ namespace UniGLTF
|
||||
axisInverter.InvertVector3(blendShapeNormals[k]));
|
||||
}
|
||||
|
||||
gltfPrimitive.targets.Add(blendShape.ToGltf(gltf, gltfBuffer, !settings.ExportOnlyBlendShapePosition,
|
||||
gltfPrimitive.targets.Add(blendShape.ToGltf(data, !settings.ExportOnlyBlendShapePosition,
|
||||
settings.UseSparseAccessorForMorphTarget));
|
||||
}
|
||||
|
||||
|
||||
@@ -24,27 +24,27 @@ namespace UniGLTF
|
||||
/// <param name="axisInverter"></param>
|
||||
/// <param name="settings"></param>
|
||||
/// <returns></returns>
|
||||
public static (glTFMesh, Dictionary<int, int> blendShapeIndexMap) Export(glTF gltf, int bufferIndex,
|
||||
public static (glTFMesh, Dictionary<int, int> blendShapeIndexMap) Export(ExportingGltfData data,
|
||||
MeshExportInfo unityMesh, List<Material> unityMaterials,
|
||||
IAxisInverter axisInverter, GltfExportSettings settings)
|
||||
{
|
||||
var mesh = unityMesh.Mesh;
|
||||
var materials = unityMesh.Materials;
|
||||
var positions = mesh.vertices.Select(axisInverter.InvertVector3).ToArray();
|
||||
var positionAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, positions, glBufferTarget.ARRAY_BUFFER);
|
||||
gltf.accessors[positionAccessorIndex].min = positions.Aggregate(positions[0], (a, b) => new Vector3(Mathf.Min(a.x, b.x), Math.Min(a.y, b.y), Mathf.Min(a.z, b.z))).ToArray();
|
||||
gltf.accessors[positionAccessorIndex].max = positions.Aggregate(positions[0], (a, b) => new Vector3(Mathf.Max(a.x, b.x), Math.Max(a.y, b.y), Mathf.Max(a.z, b.z))).ToArray();
|
||||
var positionAccessorIndex = data.ExtendBufferAndGetAccessorIndex(positions, glBufferTarget.ARRAY_BUFFER);
|
||||
data.GLTF.accessors[positionAccessorIndex].min = positions.Aggregate(positions[0], (a, b) => new Vector3(Mathf.Min(a.x, b.x), Math.Min(a.y, b.y), Mathf.Min(a.z, b.z))).ToArray();
|
||||
data.GLTF.accessors[positionAccessorIndex].max = positions.Aggregate(positions[0], (a, b) => new Vector3(Mathf.Max(a.x, b.x), Math.Max(a.y, b.y), Mathf.Max(a.z, b.z))).ToArray();
|
||||
|
||||
var normalAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, mesh.normals.Select(y => axisInverter.InvertVector3(y.normalized)).ToArray(), glBufferTarget.ARRAY_BUFFER);
|
||||
var normalAccessorIndex = data.ExtendBufferAndGetAccessorIndex(mesh.normals.Select(y => axisInverter.InvertVector3(y.normalized)).ToArray(), glBufferTarget.ARRAY_BUFFER);
|
||||
|
||||
int? tangentAccessorIndex = default;
|
||||
if (settings.ExportTangents)
|
||||
{
|
||||
tangentAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, mesh.tangents.Select(axisInverter.InvertVector4).ToArray(), glBufferTarget.ARRAY_BUFFER);
|
||||
tangentAccessorIndex = data.ExtendBufferAndGetAccessorIndex(mesh.tangents.Select(axisInverter.InvertVector4).ToArray(), glBufferTarget.ARRAY_BUFFER);
|
||||
}
|
||||
|
||||
var uvAccessorIndex0 = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, mesh.uv.Select(y => y.ReverseUV()).ToArray(), glBufferTarget.ARRAY_BUFFER);
|
||||
var uvAccessorIndex1 = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, mesh.uv2.Select(y => y.ReverseUV()).ToArray(), glBufferTarget.ARRAY_BUFFER);
|
||||
var uvAccessorIndex0 = data.ExtendBufferAndGetAccessorIndex(mesh.uv.Select(y => y.ReverseUV()).ToArray(), glBufferTarget.ARRAY_BUFFER);
|
||||
var uvAccessorIndex1 = data.ExtendBufferAndGetAccessorIndex(mesh.uv2.Select(y => y.ReverseUV()).ToArray(), glBufferTarget.ARRAY_BUFFER);
|
||||
|
||||
var colorAccessorIndex = -1;
|
||||
|
||||
@@ -54,12 +54,12 @@ namespace UniGLTF
|
||||
)
|
||||
{
|
||||
// UniUnlit で Multiply 設定になっている
|
||||
colorAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, mesh.colors, glBufferTarget.ARRAY_BUFFER);
|
||||
colorAccessorIndex = data.ExtendBufferAndGetAccessorIndex(mesh.colors, glBufferTarget.ARRAY_BUFFER);
|
||||
}
|
||||
|
||||
var boneweights = mesh.boneWeights;
|
||||
var weightAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, boneweights.Select(y => new Vector4(y.weight0, y.weight1, y.weight2, y.weight3)).ToArray(), glBufferTarget.ARRAY_BUFFER);
|
||||
var jointsAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, boneweights.Select(y =>
|
||||
var weightAccessorIndex = data.ExtendBufferAndGetAccessorIndex(boneweights.Select(y => new Vector4(y.weight0, y.weight1, y.weight2, y.weight3)).ToArray(), glBufferTarget.ARRAY_BUFFER);
|
||||
var jointsAccessorIndex = data.ExtendBufferAndGetAccessorIndex(boneweights.Select(y =>
|
||||
new UShort4(
|
||||
(ushort)unityMesh.GetJointIndex(y.boneIndex0),
|
||||
(ushort)unityMesh.GetJointIndex(y.boneIndex1),
|
||||
@@ -127,7 +127,7 @@ namespace UniGLTF
|
||||
indices.Add((uint)i0);
|
||||
}
|
||||
|
||||
var indicesAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, indices.ToArray(), glBufferTarget.ELEMENT_ARRAY_BUFFER);
|
||||
var indicesAccessorIndex = data.ExtendBufferAndGetAccessorIndex(indices.ToArray(), glBufferTarget.ELEMENT_ARRAY_BUFFER);
|
||||
if (indicesAccessorIndex < 0)
|
||||
{
|
||||
// https://github.com/vrm-c/UniVRM/issues/664
|
||||
@@ -156,7 +156,7 @@ namespace UniGLTF
|
||||
int exportBlendShapes = 0;
|
||||
for (int j = 0; j < unityMesh.Mesh.blendShapeCount; ++j)
|
||||
{
|
||||
var morphTarget = ExportMorphTarget(gltf, bufferIndex,
|
||||
var morphTarget = ExportMorphTarget(data,
|
||||
unityMesh.Mesh, j,
|
||||
settings.UseSparseAccessorForMorphTarget,
|
||||
settings.ExportOnlyBlendShapePosition, axisInverter);
|
||||
@@ -200,7 +200,7 @@ namespace UniGLTF
|
||||
return useSparse;
|
||||
}
|
||||
|
||||
static gltfMorphTarget ExportMorphTarget(glTF gltf, int bufferIndex,
|
||||
static gltfMorphTarget ExportMorphTarget(ExportingGltfData data,
|
||||
Mesh mesh, int blendShapeIndex,
|
||||
bool useSparseAccessorForMorphTarget,
|
||||
bool exportOnlyBlendShapePosition,
|
||||
@@ -244,7 +244,7 @@ namespace UniGLTF
|
||||
normals[i] = axisInverter.InvertVector3(normals[i]);
|
||||
}
|
||||
|
||||
return BlendShapeExporter.Export(gltf, bufferIndex,
|
||||
return BlendShapeExporter.Export(data,
|
||||
blendShapeVertices,
|
||||
exportOnlyBlendShapePosition && useNormal ? null : blendShapeNormals,
|
||||
useSparseAccessorForMorphTarget);
|
||||
|
||||
@@ -139,7 +139,7 @@ namespace UniGLTF
|
||||
/// <param name="ctx"></param>
|
||||
/// <param name="gltfMesh"></param>
|
||||
/// <returns></returns>
|
||||
public void ImportMeshIndependentVertexBuffer(glTF gltf, glTFMesh gltfMesh, IAxisInverter inverter)
|
||||
public void ImportMeshIndependentVertexBuffer(GltfData data, glTFMesh gltfMesh, IAxisInverter inverter)
|
||||
{
|
||||
foreach (var prim in gltfMesh.primitives)
|
||||
{
|
||||
@@ -147,14 +147,14 @@ namespace UniGLTF
|
||||
var indexBuffer = prim.indices;
|
||||
|
||||
// position は必ずある
|
||||
var positions = gltf.GetArrayFromAccessor<Vector3>(prim.attributes.POSITION);
|
||||
var positions = data.GetArrayFromAccessor<Vector3>(prim.attributes.POSITION);
|
||||
m_positions.AddRange(positions.Select(inverter.InvertVector3));
|
||||
var fillLength = m_positions.Count;
|
||||
|
||||
// normal
|
||||
if (prim.attributes.NORMAL != -1)
|
||||
{
|
||||
var normals = gltf.GetArrayFromAccessor<Vector3>(prim.attributes.NORMAL);
|
||||
var normals = data.GetArrayFromAccessor<Vector3>(prim.attributes.NORMAL);
|
||||
if (normals.Length != positions.Length)
|
||||
{
|
||||
throw new Exception("different length");
|
||||
@@ -166,12 +166,12 @@ namespace UniGLTF
|
||||
// uv
|
||||
if (prim.attributes.TEXCOORD_0 != -1)
|
||||
{
|
||||
var uvs = gltf.GetArrayFromAccessor<Vector2>(prim.attributes.TEXCOORD_0);
|
||||
var uvs = data.GetArrayFromAccessor<Vector2>(prim.attributes.TEXCOORD_0);
|
||||
if (uvs.Length != positions.Length)
|
||||
{
|
||||
throw new Exception("different length");
|
||||
}
|
||||
if (gltf.IsGeneratedUniGLTFAndOlder(1, 16))
|
||||
if (data.GLTF.IsGeneratedUniGLTFAndOlder(1, 16))
|
||||
{
|
||||
#pragma warning disable 0612
|
||||
// backward compatibility
|
||||
@@ -189,7 +189,7 @@ namespace UniGLTF
|
||||
// uv2
|
||||
if (prim.attributes.TEXCOORD_1 != -1)
|
||||
{
|
||||
var uvs = gltf.GetArrayFromAccessor<Vector2>(prim.attributes.TEXCOORD_1);
|
||||
var uvs = data.GetArrayFromAccessor<Vector2>(prim.attributes.TEXCOORD_1);
|
||||
if (uvs.Length != positions.Length)
|
||||
{
|
||||
throw new Exception("different length");
|
||||
@@ -201,7 +201,7 @@ namespace UniGLTF
|
||||
// color
|
||||
if (prim.attributes.COLOR_0 != -1)
|
||||
{
|
||||
var colors = gltf.GetArrayFromAccessor<Color>(prim.attributes.COLOR_0);
|
||||
var colors = data.GetArrayFromAccessor<Color>(prim.attributes.COLOR_0);
|
||||
if (colors.Length != positions.Length)
|
||||
{
|
||||
throw new Exception("different length");
|
||||
@@ -213,8 +213,8 @@ namespace UniGLTF
|
||||
// skin
|
||||
if (prim.attributes.JOINTS_0 != -1 && prim.attributes.WEIGHTS_0 != -1)
|
||||
{
|
||||
var (joints0, jointsLength) = JointsAccessor.GetAccessor(gltf, prim.attributes.JOINTS_0);
|
||||
var (weights0, weightsLength) = WeightsAccessor.GetAccessor(gltf, prim.attributes.WEIGHTS_0);
|
||||
var (joints0, jointsLength) = JointsAccessor.GetAccessor(data, prim.attributes.JOINTS_0);
|
||||
var (weights0, weightsLength) = WeightsAccessor.GetAccessor(data, prim.attributes.WEIGHTS_0);
|
||||
if (jointsLength != positions.Length)
|
||||
{
|
||||
throw new Exception("different length");
|
||||
@@ -258,7 +258,7 @@ namespace UniGLTF
|
||||
var blendShape = GetOrCreateBlendShape(i);
|
||||
if (primTarget.POSITION != -1)
|
||||
{
|
||||
var array = gltf.GetArrayFromAccessor<Vector3>(primTarget.POSITION);
|
||||
var array = data.GetArrayFromAccessor<Vector3>(primTarget.POSITION);
|
||||
if (array.Length != positions.Length)
|
||||
{
|
||||
throw new Exception("different length");
|
||||
@@ -268,7 +268,7 @@ namespace UniGLTF
|
||||
}
|
||||
if (primTarget.NORMAL != -1)
|
||||
{
|
||||
var array = gltf.GetArrayFromAccessor<Vector3>(primTarget.NORMAL);
|
||||
var array = data.GetArrayFromAccessor<Vector3>(primTarget.NORMAL);
|
||||
if (array.Length != positions.Length)
|
||||
{
|
||||
throw new Exception("different length");
|
||||
@@ -278,7 +278,7 @@ namespace UniGLTF
|
||||
}
|
||||
if (primTarget.TANGENT != -1)
|
||||
{
|
||||
var array = gltf.GetArrayFromAccessor<Vector3>(primTarget.TANGENT);
|
||||
var array = data.GetArrayFromAccessor<Vector3>(primTarget.TANGENT);
|
||||
if (array.Length != positions.Length)
|
||||
{
|
||||
throw new Exception("different length");
|
||||
@@ -291,7 +291,7 @@ namespace UniGLTF
|
||||
|
||||
var indices =
|
||||
(indexBuffer >= 0)
|
||||
? gltf.GetIndices(indexBuffer)
|
||||
? data.GetIndices(indexBuffer)
|
||||
: TriangleUtil.FlipTriangle(Enumerable.Range(0, m_positions.Count)).ToArray() // without index array
|
||||
;
|
||||
for (int i = 0; i < indices.Length; ++i)
|
||||
@@ -314,17 +314,17 @@ namespace UniGLTF
|
||||
/// <param name="ctx"></param>
|
||||
/// <param name="gltfMesh"></param>
|
||||
/// <returns></returns>
|
||||
public void ImportMeshSharingVertexBuffer(glTF gltf, glTFMesh gltfMesh, IAxisInverter inverter)
|
||||
public void ImportMeshSharingVertexBuffer(GltfData data, glTFMesh gltfMesh, IAxisInverter inverter)
|
||||
{
|
||||
{
|
||||
// 同じVertexBufferを共有しているので先頭のモノを使う
|
||||
var prim = gltfMesh.primitives.First();
|
||||
m_positions.AddRange(gltf.GetArrayFromAccessor<Vector3>(prim.attributes.POSITION).SelectInplace(inverter.InvertVector3));
|
||||
m_positions.AddRange(data.GetArrayFromAccessor<Vector3>(prim.attributes.POSITION).SelectInplace(inverter.InvertVector3));
|
||||
|
||||
// normal
|
||||
if (prim.attributes.NORMAL != -1)
|
||||
{
|
||||
m_normals.AddRange(gltf.GetArrayFromAccessor<Vector3>(prim.attributes.NORMAL).SelectInplace(inverter.InvertVector3));
|
||||
m_normals.AddRange(data.GetArrayFromAccessor<Vector3>(prim.attributes.NORMAL).SelectInplace(inverter.InvertVector3));
|
||||
}
|
||||
|
||||
#if false
|
||||
@@ -338,31 +338,31 @@ namespace UniGLTF
|
||||
// uv
|
||||
if (prim.attributes.TEXCOORD_0 != -1)
|
||||
{
|
||||
if (gltf.IsGeneratedUniGLTFAndOlder(1, 16))
|
||||
if (data.GLTF.IsGeneratedUniGLTFAndOlder(1, 16))
|
||||
{
|
||||
#pragma warning disable 0612
|
||||
// backward compatibility
|
||||
m_uv.AddRange(gltf.GetArrayFromAccessor<Vector2>(prim.attributes.TEXCOORD_0).SelectInplace(x => x.ReverseY()));
|
||||
m_uv.AddRange(data.GetArrayFromAccessor<Vector2>(prim.attributes.TEXCOORD_0).SelectInplace(x => x.ReverseY()));
|
||||
#pragma warning restore 0612
|
||||
}
|
||||
else
|
||||
{
|
||||
m_uv.AddRange(gltf.GetArrayFromAccessor<Vector2>(prim.attributes.TEXCOORD_0).SelectInplace(x => x.ReverseUV()));
|
||||
m_uv.AddRange(data.GetArrayFromAccessor<Vector2>(prim.attributes.TEXCOORD_0).SelectInplace(x => x.ReverseUV()));
|
||||
}
|
||||
}
|
||||
|
||||
// uv2
|
||||
if (prim.attributes.TEXCOORD_1 != -1)
|
||||
{
|
||||
m_uv2.AddRange(gltf.GetArrayFromAccessor<Vector2>(prim.attributes.TEXCOORD_1).SelectInplace(x => x.ReverseUV()));
|
||||
m_uv2.AddRange(data.GetArrayFromAccessor<Vector2>(prim.attributes.TEXCOORD_1).SelectInplace(x => x.ReverseUV()));
|
||||
}
|
||||
|
||||
// color
|
||||
if (prim.attributes.COLOR_0 != -1)
|
||||
{
|
||||
if (gltf.accessors[prim.attributes.COLOR_0].TypeCount == 3)
|
||||
if (data.GLTF.accessors[prim.attributes.COLOR_0].TypeCount == 3)
|
||||
{
|
||||
var vec3Color = gltf.GetArrayFromAccessor<Vector3>(prim.attributes.COLOR_0);
|
||||
var vec3Color = data.GetArrayFromAccessor<Vector3>(prim.attributes.COLOR_0);
|
||||
m_colors.AddRange(new Color[vec3Color.Length]);
|
||||
|
||||
for (int i = 0; i < vec3Color.Length; i++)
|
||||
@@ -371,21 +371,21 @@ namespace UniGLTF
|
||||
m_colors[i] = new Color(color.x, color.y, color.z);
|
||||
}
|
||||
}
|
||||
else if (gltf.accessors[prim.attributes.COLOR_0].TypeCount == 4)
|
||||
else if (data.GLTF.accessors[prim.attributes.COLOR_0].TypeCount == 4)
|
||||
{
|
||||
m_colors.AddRange(gltf.GetArrayFromAccessor<Color>(prim.attributes.COLOR_0));
|
||||
m_colors.AddRange(data.GetArrayFromAccessor<Color>(prim.attributes.COLOR_0));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotImplementedException(string.Format("unknown color type {0}", gltf.accessors[prim.attributes.COLOR_0].type));
|
||||
throw new NotImplementedException(string.Format("unknown color type {0}", data.GLTF.accessors[prim.attributes.COLOR_0].type));
|
||||
}
|
||||
}
|
||||
|
||||
// skin
|
||||
if (prim.attributes.JOINTS_0 != -1 && prim.attributes.WEIGHTS_0 != -1)
|
||||
{
|
||||
var (joints0, jointsLength) = JointsAccessor.GetAccessor(gltf, prim.attributes.JOINTS_0);
|
||||
var (weights0, weightsLength) = WeightsAccessor.GetAccessor(gltf, prim.attributes.WEIGHTS_0);
|
||||
var (joints0, jointsLength) = JointsAccessor.GetAccessor(data, prim.attributes.JOINTS_0);
|
||||
var (weights0, weightsLength) = WeightsAccessor.GetAccessor(data, prim.attributes.WEIGHTS_0);
|
||||
|
||||
for (int j = 0; j < jointsLength; ++j)
|
||||
{
|
||||
@@ -425,17 +425,17 @@ namespace UniGLTF
|
||||
if (primTarget.POSITION != -1)
|
||||
{
|
||||
blendShape.Positions.Assign(
|
||||
gltf.GetArrayFromAccessor<Vector3>(primTarget.POSITION), inverter.InvertVector3);
|
||||
data.GetArrayFromAccessor<Vector3>(primTarget.POSITION), inverter.InvertVector3);
|
||||
}
|
||||
if (primTarget.NORMAL != -1)
|
||||
{
|
||||
blendShape.Normals.Assign(
|
||||
gltf.GetArrayFromAccessor<Vector3>(primTarget.NORMAL), inverter.InvertVector3);
|
||||
data.GetArrayFromAccessor<Vector3>(primTarget.NORMAL), inverter.InvertVector3);
|
||||
}
|
||||
if (primTarget.TANGENT != -1)
|
||||
{
|
||||
blendShape.Tangents.Assign(
|
||||
gltf.GetArrayFromAccessor<Vector3>(primTarget.TANGENT), inverter.InvertVector3);
|
||||
data.GetArrayFromAccessor<Vector3>(primTarget.TANGENT), inverter.InvertVector3);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -449,7 +449,7 @@ namespace UniGLTF
|
||||
}
|
||||
else
|
||||
{
|
||||
var indices = gltf.GetIndices(prim.indices);
|
||||
var indices = data.GetIndices(prim.indices);
|
||||
m_subMeshes.Add(indices);
|
||||
}
|
||||
|
||||
@@ -531,18 +531,18 @@ namespace UniGLTF
|
||||
return sharedAttributes;
|
||||
}
|
||||
|
||||
public MeshContext ReadMesh(glTF gltf, int meshIndex, IAxisInverter inverter)
|
||||
public MeshContext ReadMesh(GltfData data, int meshIndex, IAxisInverter inverter)
|
||||
{
|
||||
var gltfMesh = gltf.meshes[meshIndex];
|
||||
var gltfMesh = data.GLTF.meshes[meshIndex];
|
||||
|
||||
var meshContext = new MeshContext(gltfMesh.name, meshIndex);
|
||||
if (HasSharedVertexBuffer(gltfMesh))
|
||||
{
|
||||
meshContext.ImportMeshSharingVertexBuffer(gltf, gltfMesh, inverter);
|
||||
meshContext.ImportMeshSharingVertexBuffer(data, gltfMesh, inverter);
|
||||
}
|
||||
else
|
||||
{
|
||||
meshContext.ImportMeshIndependentVertexBuffer(gltf, gltfMesh, inverter);
|
||||
meshContext.ImportMeshIndependentVertexBuffer(data, gltfMesh, inverter);
|
||||
}
|
||||
|
||||
meshContext.RenameBlendShape(gltfMesh);
|
||||
|
||||
@@ -10,14 +10,14 @@ namespace UniGLTF
|
||||
/// </summary>
|
||||
public delegate (float x, float y, float z, float w) Getter(int index);
|
||||
|
||||
public static (Getter, int) GetAccessor(glTF gltf, int accessorIndex)
|
||||
public static (Getter, int) GetAccessor(GltfData data, int accessorIndex)
|
||||
{
|
||||
var gltfAccessor = gltf.accessors[accessorIndex];
|
||||
var gltfAccessor = data.GLTF.accessors[accessorIndex];
|
||||
switch (gltfAccessor.componentType)
|
||||
{
|
||||
case glComponentType.UNSIGNED_BYTE:
|
||||
{
|
||||
var array = gltf.GetArrayFromAccessor<Byte4>(accessorIndex);
|
||||
var array = data.GetArrayFromAccessor<Byte4>(accessorIndex);
|
||||
Getter getter = (i) =>
|
||||
{
|
||||
var value = array[i];
|
||||
@@ -29,7 +29,7 @@ namespace UniGLTF
|
||||
|
||||
case glComponentType.UNSIGNED_SHORT:
|
||||
{
|
||||
var array = gltf.GetArrayFromAccessor<UShort4>(accessorIndex);
|
||||
var array = data.GetArrayFromAccessor<UShort4>(accessorIndex);
|
||||
Getter getter = (i) =>
|
||||
{
|
||||
var value = array[i];
|
||||
@@ -41,7 +41,7 @@ namespace UniGLTF
|
||||
|
||||
case glComponentType.FLOAT:
|
||||
{
|
||||
var array = gltf.GetArrayFromAccessor<Vector4>(accessorIndex);
|
||||
var array = data.GetArrayFromAccessor<Vector4>(accessorIndex);
|
||||
Getter getter = (i) =>
|
||||
{
|
||||
var value = array[i];
|
||||
|
||||
@@ -156,7 +156,7 @@ namespace UniGLTF
|
||||
}
|
||||
}
|
||||
|
||||
public static void SetupSkinning(glTF gltf, List<TransformWithSkin> nodes, int i, IAxisInverter inverter)
|
||||
public static void SetupSkinning(GltfData data, List<TransformWithSkin> nodes, int i, IAxisInverter inverter)
|
||||
{
|
||||
var x = nodes[i];
|
||||
var skinnedMeshRenderer = x.Transform.GetComponent<SkinnedMeshRenderer>();
|
||||
@@ -168,12 +168,12 @@ namespace UniGLTF
|
||||
if (mesh == null) throw new Exception();
|
||||
if (skinnedMeshRenderer == null) throw new Exception();
|
||||
|
||||
if (x.SkinIndex.Value < gltf.skins.Count)
|
||||
if (x.SkinIndex.Value < data.GLTF.skins.Count)
|
||||
{
|
||||
// calculate internal values(boundingBox etc...) when sharedMesh assigned ?
|
||||
skinnedMeshRenderer.sharedMesh = null;
|
||||
|
||||
var skin = gltf.skins[x.SkinIndex.Value];
|
||||
var skin = data.GLTF.skins[x.SkinIndex.Value];
|
||||
var joints = skin.joints.Select(y => nodes[y].Transform).ToArray();
|
||||
if (joints.Any())
|
||||
{
|
||||
@@ -182,7 +182,7 @@ namespace UniGLTF
|
||||
|
||||
if (skin.inverseBindMatrices != -1)
|
||||
{
|
||||
var bindPoses = gltf.GetArrayFromAccessor<Matrix4x4>(skin.inverseBindMatrices)
|
||||
var bindPoses = data.GetArrayFromAccessor<Matrix4x4>(skin.inverseBindMatrices)
|
||||
.Select(inverter.InvertMat4)
|
||||
.ToArray()
|
||||
;
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace UniGLTF
|
||||
{
|
||||
private readonly string _json;
|
||||
private readonly IStorage _storage;
|
||||
|
||||
|
||||
public JsonWithStorageParser(string json, IStorage storage = null)
|
||||
{
|
||||
_json = json;
|
||||
|
||||
@@ -22,17 +22,16 @@ namespace UniGLTF
|
||||
/// <param name="bufferIndex"></param>
|
||||
/// <param name="texture"></param>
|
||||
/// <returns>gltf texture index</returns>
|
||||
public static int PushGltfTexture(this glTF gltf, int bufferIndex, Texture2D texture, ColorSpace textureColorSpace, ITextureSerializer textureSerializer)
|
||||
public static int PushGltfTexture(ExportingGltfData data, Texture2D texture, ColorSpace textureColorSpace, ITextureSerializer textureSerializer)
|
||||
{
|
||||
var bytesWithMime = textureSerializer.ExportBytesWithMime(texture, textureColorSpace);
|
||||
|
||||
// add view
|
||||
var view = gltf.buffers[bufferIndex].Append(bytesWithMime.bytes, glBufferTarget.NONE);
|
||||
var viewIndex = gltf.AddBufferView(view);
|
||||
var viewIndex = data.ExtendBufferAndGetViewIndex(bytesWithMime.bytes);
|
||||
|
||||
// add image
|
||||
var imageIndex = gltf.images.Count;
|
||||
gltf.images.Add(new glTFImage
|
||||
var imageIndex = data.GLTF.images.Count;
|
||||
data.GLTF.images.Add(new glTFImage
|
||||
{
|
||||
name = TextureImportName.RemoveSuffix(texture.name),
|
||||
bufferView = viewIndex,
|
||||
@@ -40,13 +39,13 @@ namespace UniGLTF
|
||||
});
|
||||
|
||||
// add sampler
|
||||
var samplerIndex = gltf.samplers.Count;
|
||||
var samplerIndex = data.GLTF.samplers.Count;
|
||||
var sampler = TextureSamplerUtil.Export(texture);
|
||||
gltf.samplers.Add(sampler);
|
||||
data.GLTF.samplers.Add(sampler);
|
||||
|
||||
// add texture
|
||||
var textureIndex = gltf.textures.Count;
|
||||
gltf.textures.Add(new glTFTexture
|
||||
var textureIndex = data.GLTF.textures.Count;
|
||||
data.GLTF.textures.Add(new glTFTexture
|
||||
{
|
||||
sampler = samplerIndex,
|
||||
source = imageIndex,
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace UniGLTF
|
||||
var gltfImage = data.GLTF.images[gltfTexture.source];
|
||||
var name = TextureImportName.GetUnityObjectName(TextureImportTypes.sRGB, gltfTexture.name, gltfImage.uri);
|
||||
var sampler = TextureSamplerUtil.CreateSampler(data.GLTF, textureIndex);
|
||||
GetTextureBytesAsync getTextureBytesAsync = () => Task.FromResult(ToArray(data.GLTF.GetImageBytesFromTextureIndex(data.Storage, textureIndex)));
|
||||
GetTextureBytesAsync getTextureBytesAsync = () => Task.FromResult(ToArray(data.GetImageBytesFromTextureIndex(textureIndex)));
|
||||
var param = new TextureDescriptor(name, gltfImage.GetExt(), gltfImage.uri, offset, scale, sampler, TextureImportTypes.sRGB, default, default, getTextureBytesAsync, default, default, default, default, default);
|
||||
return (param.SubAssetKey, param);
|
||||
}
|
||||
@@ -46,7 +46,7 @@ namespace UniGLTF
|
||||
var gltfImage = data.GLTF.images[gltfTexture.source];
|
||||
var name = TextureImportName.GetUnityObjectName(TextureImportTypes.Linear, gltfTexture.name, gltfImage.uri);
|
||||
var sampler = TextureSamplerUtil.CreateSampler(data.GLTF, textureIndex);
|
||||
GetTextureBytesAsync getTextureBytesAsync = () => Task.FromResult(ToArray(data.GLTF.GetImageBytesFromTextureIndex(data.Storage, textureIndex)));
|
||||
GetTextureBytesAsync getTextureBytesAsync = () => Task.FromResult(ToArray(data.GetImageBytesFromTextureIndex(textureIndex)));
|
||||
var param = new TextureDescriptor(name, gltfImage.GetExt(), gltfImage.uri, offset, scale, sampler, TextureImportTypes.Linear, default, default, getTextureBytesAsync, default, default, default, default, default);
|
||||
return (param.SubAssetKey, param);
|
||||
}
|
||||
@@ -57,7 +57,7 @@ namespace UniGLTF
|
||||
var gltfImage = data.GLTF.images[gltfTexture.source];
|
||||
var name = TextureImportName.GetUnityObjectName(TextureImportTypes.NormalMap, gltfTexture.name, gltfImage.uri);
|
||||
var sampler = TextureSamplerUtil.CreateSampler(data.GLTF, textureIndex);
|
||||
GetTextureBytesAsync getTextureBytesAsync = () => Task.FromResult(ToArray(data.GLTF.GetImageBytesFromTextureIndex(data.Storage, textureIndex)));
|
||||
GetTextureBytesAsync getTextureBytesAsync = () => Task.FromResult(ToArray(data.GetImageBytesFromTextureIndex(textureIndex)));
|
||||
var param = new TextureDescriptor(name, gltfImage.GetExt(), gltfImage.uri, offset, scale, sampler, TextureImportTypes.NormalMap, default, default, getTextureBytesAsync, default, default, default, default, default);
|
||||
return (param.SubAssetKey, param);
|
||||
}
|
||||
@@ -73,7 +73,7 @@ namespace UniGLTF
|
||||
var gltfTexture = data.GLTF.textures[metallicRoughnessTextureIndex.Value];
|
||||
name = TextureImportName.GetUnityObjectName(TextureImportTypes.StandardMap, gltfTexture.name, data.GLTF.images[gltfTexture.source].uri);
|
||||
sampler = TextureSamplerUtil.CreateSampler(data.GLTF, metallicRoughnessTextureIndex.Value);
|
||||
getMetallicRoughnessAsync = () => Task.FromResult(ToArray(data.GLTF.GetImageBytesFromTextureIndex(data.Storage, metallicRoughnessTextureIndex.Value)));
|
||||
getMetallicRoughnessAsync = () => Task.FromResult(ToArray(data.GetImageBytesFromTextureIndex(metallicRoughnessTextureIndex.Value)));
|
||||
}
|
||||
|
||||
GetTextureBytesAsync getOcclusionAsync = default;
|
||||
@@ -85,7 +85,7 @@ namespace UniGLTF
|
||||
name = TextureImportName.GetUnityObjectName(TextureImportTypes.StandardMap, gltfTexture.name, data.GLTF.images[gltfTexture.source].uri);
|
||||
}
|
||||
sampler = TextureSamplerUtil.CreateSampler(data.GLTF, occlusionTextureIndex.Value);
|
||||
getOcclusionAsync = () => Task.FromResult(ToArray(data.GLTF.GetImageBytesFromTextureIndex(data.Storage, occlusionTextureIndex.Value)));
|
||||
getOcclusionAsync = () => Task.FromResult(ToArray(data.GetImageBytesFromTextureIndex(occlusionTextureIndex.Value)));
|
||||
}
|
||||
|
||||
var texDesc = new TextureDescriptor(name, ".png", null, offset, scale, sampler, TextureImportTypes.StandardMap, metallicFactor, roughnessFactor, getMetallicRoughnessAsync, getOcclusionAsync, default, default, default, default);
|
||||
|
||||
27
Assets/UniGLTF/Runtime/UniGLTF/IO/UShort4.cs
Normal file
27
Assets/UniGLTF/Runtime/UniGLTF/IO/UShort4.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace UniGLTF
|
||||
{
|
||||
[Serializable, StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public readonly struct UShort4 : IEquatable<UShort4>
|
||||
{
|
||||
public readonly ushort x;
|
||||
public readonly ushort y;
|
||||
public readonly ushort z;
|
||||
public readonly ushort w;
|
||||
|
||||
public UShort4(ushort _x, ushort _y, ushort _z, ushort _w)
|
||||
{
|
||||
x = _x;
|
||||
y = _y;
|
||||
z = _z;
|
||||
w = _w;
|
||||
}
|
||||
|
||||
public bool Equals(UShort4 other)
|
||||
{
|
||||
return x == other.x && y == other.y && z == other.z && w == other.w;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/UniGLTF/Runtime/UniGLTF/IO/UShort4.cs.meta
Normal file
11
Assets/UniGLTF/Runtime/UniGLTF/IO/UShort4.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b1f199669bb47f747865a96bcd7bcbfb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -292,6 +292,9 @@ namespace UniGLTF.Zip
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implement url that reference zip archive
|
||||
/// </summary>
|
||||
class ZipArchiveStorage : IStorage
|
||||
{
|
||||
public override string ToString()
|
||||
@@ -378,10 +381,5 @@ namespace UniGLTF.Zip
|
||||
|
||||
throw new NotImplementedException(found.CompressionMethod.ToString());
|
||||
}
|
||||
|
||||
public string GetPath(string url)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,9 @@ namespace UniGLTF
|
||||
{
|
||||
public class gltfExporter : IDisposable
|
||||
{
|
||||
protected glTF glTF;
|
||||
protected ExportingGltfData _data;
|
||||
|
||||
protected glTF _gltf => _data.GLTF;
|
||||
|
||||
public GameObject Copy
|
||||
{
|
||||
@@ -67,13 +69,13 @@ namespace UniGLTF
|
||||
|
||||
GltfExportSettings m_settings;
|
||||
|
||||
public gltfExporter(glTF gltf, GltfExportSettings settings)
|
||||
public gltfExporter(ExportingGltfData data, GltfExportSettings settings)
|
||||
{
|
||||
glTF = gltf;
|
||||
_data = data;
|
||||
|
||||
glTF.extensionsUsed.AddRange(ExtensionUsed);
|
||||
_gltf.extensionsUsed.AddRange(ExtensionUsed);
|
||||
|
||||
glTF.asset = new glTFAssets
|
||||
_gltf.asset = new glTFAssets
|
||||
{
|
||||
generator = "UniGLTF-" + UniGLTFVersion.VERSION,
|
||||
version = "2.0",
|
||||
@@ -224,9 +226,6 @@ namespace UniGLTF
|
||||
|
||||
public virtual void Export(ITextureSerializer textureSerializer)
|
||||
{
|
||||
var bytesBuffer = new ArrayByteBuffer(new byte[50 * 1024 * 1024]);
|
||||
var bufferIndex = glTF.AddBuffer(bytesBuffer);
|
||||
|
||||
Nodes = Copy.transform.Traverse()
|
||||
.Skip(1) // exclude root object for the symmetry with the importer
|
||||
.ToList();
|
||||
@@ -240,7 +239,7 @@ namespace UniGLTF
|
||||
m_textureExporter = new TextureExporter(textureSerializer);
|
||||
|
||||
var materialExporter = CreateMaterialExporter();
|
||||
glTF.materials = Materials.Select(x => materialExporter.ExportMaterial(x, TextureExporter, m_settings)).ToList();
|
||||
_gltf.materials = Materials.Select(x => materialExporter.ExportMaterial(x, TextureExporter, m_settings)).ToList();
|
||||
#endregion
|
||||
|
||||
#region Meshes
|
||||
@@ -253,10 +252,10 @@ namespace UniGLTF
|
||||
}
|
||||
|
||||
var (gltfMesh, blendShapeIndexMap) = m_settings.DivideVertexBuffer
|
||||
? MeshExporter_DividedVertexBuffer.Export(glTF, bufferIndex, unityMesh, Materials, m_settings.InverseAxis.Create(), m_settings)
|
||||
: MeshExporter_SharedVertexBuffer.Export(glTF, bufferIndex, unityMesh, Materials, m_settings.InverseAxis.Create(), m_settings)
|
||||
? MeshExporter_DividedVertexBuffer.Export(_data, unityMesh, Materials, m_settings.InverseAxis.Create(), m_settings)
|
||||
: MeshExporter_SharedVertexBuffer.Export(_data, unityMesh, Materials, m_settings.InverseAxis.Create(), m_settings)
|
||||
;
|
||||
glTF.meshes.Add(gltfMesh);
|
||||
_gltf.meshes.Add(gltfMesh);
|
||||
Meshes.Add(unityMesh.Mesh);
|
||||
if (!MeshBlendShapeIndexMap.ContainsKey(unityMesh.Mesh))
|
||||
{
|
||||
@@ -276,9 +275,9 @@ namespace UniGLTF
|
||||
foreach (var node in Nodes)
|
||||
{
|
||||
var gltfNode = ExportNode(node, Nodes, uniqueUnityMeshes, skins);
|
||||
glTF.nodes.Add(gltfNode);
|
||||
_gltf.nodes.Add(gltfNode);
|
||||
}
|
||||
glTF.scenes = new List<gltfScene>
|
||||
_gltf.scenes = new List<gltfScene>
|
||||
{
|
||||
new gltfScene
|
||||
{
|
||||
@@ -293,20 +292,20 @@ namespace UniGLTF
|
||||
if (uniqueBones != null && renderer is SkinnedMeshRenderer smr)
|
||||
{
|
||||
var matrices = x.GetBindPoses().Select(m_settings.InverseAxis.Create().InvertMat4).ToArray();
|
||||
var accessor = glTF.ExtendBufferAndGetAccessorIndex(bufferIndex, matrices, glBufferTarget.NONE);
|
||||
var accessor = _data.ExtendBufferAndGetAccessorIndex(matrices, glBufferTarget.NONE);
|
||||
var skin = new glTFSkin
|
||||
{
|
||||
inverseBindMatrices = accessor,
|
||||
joints = uniqueBones.Select(y => Nodes.IndexOf(y)).ToArray(),
|
||||
skeleton = Nodes.IndexOf(smr.rootBone),
|
||||
};
|
||||
var skinIndex = glTF.skins.Count;
|
||||
glTF.skins.Add(skin);
|
||||
var skinIndex = _gltf.skins.Count;
|
||||
_gltf.skins.Add(skin);
|
||||
|
||||
foreach (var z in Nodes.Where(y => y.Has(renderer)))
|
||||
{
|
||||
var nodeIndex = Nodes.IndexOf(z);
|
||||
var node = glTF.nodes[nodeIndex];
|
||||
var node = _gltf.nodes[nodeIndex];
|
||||
node.skin = skinIndex;
|
||||
}
|
||||
}
|
||||
@@ -339,14 +338,14 @@ namespace UniGLTF
|
||||
{
|
||||
var sampler = animationWithCurve.Animation.samplers[kv.Key];
|
||||
|
||||
var inputAccessorIndex = glTF.ExtendBufferAndGetAccessorIndex(bufferIndex, kv.Value.Input);
|
||||
var inputAccessorIndex = _data.ExtendBufferAndGetAccessorIndex(kv.Value.Input);
|
||||
sampler.input = inputAccessorIndex;
|
||||
|
||||
var outputAccessorIndex = glTF.ExtendBufferAndGetAccessorIndex(bufferIndex, kv.Value.Output);
|
||||
var outputAccessorIndex = _data.ExtendBufferAndGetAccessorIndex(kv.Value.Output);
|
||||
sampler.output = outputAccessorIndex;
|
||||
|
||||
// modify accessors
|
||||
var outputAccessor = glTF.accessors[outputAccessorIndex];
|
||||
var outputAccessor = _gltf.accessors[outputAccessorIndex];
|
||||
var channel = animationWithCurve.Animation.channels.First(x => x.sampler == kv.Key);
|
||||
switch (glTFAnimationTarget.GetElementCount(channel.target.path))
|
||||
{
|
||||
@@ -369,8 +368,9 @@ namespace UniGLTF
|
||||
}
|
||||
}
|
||||
animationWithCurve.Animation.name = clip.name;
|
||||
glTF.animations.Add(animationWithCurve.Animation);
|
||||
_gltf.animations.Add(animationWithCurve.Animation);
|
||||
}
|
||||
|
||||
}
|
||||
#endregion
|
||||
#endif
|
||||
@@ -382,10 +382,10 @@ namespace UniGLTF
|
||||
for (var exportedTextureIdx = 0; exportedTextureIdx < exported.Count; ++exportedTextureIdx)
|
||||
{
|
||||
var (unityTexture, colorSpace) = exported[exportedTextureIdx];
|
||||
glTF.PushGltfTexture(bufferIndex, unityTexture, colorSpace, textureSerializer);
|
||||
GltfTextureExporter.PushGltfTexture(_data, unityTexture, colorSpace, textureSerializer);
|
||||
}
|
||||
|
||||
FixName(glTF);
|
||||
FixName(_gltf);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -122,8 +122,8 @@ namespace UniGLTF
|
||||
root.GetComponent<MeshRenderer>().sharedMaterial = mat;
|
||||
|
||||
// Export glTF
|
||||
var gltf = new glTF();
|
||||
using (var exporter = new gltfExporter(gltf, new GltfExportSettings
|
||||
var data = new ExportingGltfData();
|
||||
using (var exporter = new gltfExporter(data, new GltfExportSettings
|
||||
{
|
||||
InverseAxis = Axes.X,
|
||||
ExportOnlyBlendShapePosition = false,
|
||||
@@ -134,6 +134,7 @@ namespace UniGLTF
|
||||
exporter.Prepare(root);
|
||||
exporter.Export(new EditorTextureSerializer());
|
||||
}
|
||||
var gltf = data.GLTF;
|
||||
Assert.AreEqual(1, gltf.images.Count);
|
||||
var exportedImage = gltf.images[0];
|
||||
Assert.AreEqual("image/png", exportedImage.mimeType);
|
||||
@@ -142,8 +143,10 @@ namespace UniGLTF
|
||||
UnityEngine.Object.DestroyImmediate(mat);
|
||||
UnityEngine.Object.DestroyImmediate(root);
|
||||
|
||||
var parsed = GltfData.CreateFromGltfDataForTest(gltf);
|
||||
|
||||
// Extract Image to Texture2D
|
||||
var exportedBytes = gltf.GetViewBytes(exportedImage.bufferView).ToArray();
|
||||
var exportedBytes = parsed.GetViewBytes(exportedImage.bufferView).ToArray();
|
||||
var exportedTexture = new Texture2D(2, 2, TextureFormat.ARGB32, mipChain: false, linear: false);
|
||||
Assert.IsTrue(exportedTexture.LoadImage(exportedBytes)); // Always true ?
|
||||
Assert.AreEqual(srcTex.width, exportedTexture.width);
|
||||
|
||||
@@ -8,34 +8,35 @@ namespace UniGLTF
|
||||
[Test]
|
||||
public void TextureNameUniqueness()
|
||||
{
|
||||
var gltfData = new glTF();
|
||||
gltfData.asset.version = "2.0";
|
||||
gltfData.buffers.Add(new glTFBuffer(new ArrayByteBuffer(Array.Empty<byte>())));
|
||||
gltfData.textures.Add(new glTFTexture
|
||||
var data = new ExportingGltfData();
|
||||
var gltf = data.GLTF;
|
||||
gltf.asset.version = "2.0";
|
||||
gltf.buffers.Add(new glTFBuffer(new ArrayByteBuffer(Array.Empty<byte>())));
|
||||
gltf.textures.Add(new glTFTexture
|
||||
{
|
||||
name = "FooBar",
|
||||
source = 0,
|
||||
});
|
||||
gltfData.textures.Add(new glTFTexture
|
||||
gltf.textures.Add(new glTFTexture
|
||||
{
|
||||
name = "foobar",
|
||||
source = 1,
|
||||
});
|
||||
gltfData.images.Add(new glTFImage
|
||||
gltf.images.Add(new glTFImage
|
||||
{
|
||||
name = "HogeFuga",
|
||||
});
|
||||
gltfData.images.Add(new glTFImage
|
||||
gltf.images.Add(new glTFImage
|
||||
{
|
||||
name = "hogefuga",
|
||||
});
|
||||
|
||||
var parser = new GlbLowLevelParser("Test", gltfData.ToGlbBytes());
|
||||
var data = parser.Parse();
|
||||
var parser = new GlbLowLevelParser("Test", data.ToGlbBytes());
|
||||
var parsed = parser.Parse();
|
||||
|
||||
Assert.AreEqual("FooBar", data.GLTF.textures[0].name);
|
||||
Assert.AreEqual("FooBar", parsed.GLTF.textures[0].name);
|
||||
// NOTE: 大文字小文字が違うだけの名前は、同一としてみなされ、Suffix が付く。
|
||||
Assert.AreEqual("foobar__UNIGLTF__DUPLICATED__2", data.GLTF.textures[1].name);
|
||||
Assert.AreEqual("foobar__UNIGLTF__DUPLICATED__2", parsed.GLTF.textures[1].name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -57,13 +57,13 @@ namespace UniGLTF
|
||||
|
||||
static Byte[] Export(GameObject root)
|
||||
{
|
||||
var gltf = new glTF();
|
||||
using (var exporter = new gltfExporter(gltf, new GltfExportSettings()))
|
||||
var data = new ExportingGltfData();
|
||||
using (var exporter = new gltfExporter(data, new GltfExportSettings()))
|
||||
{
|
||||
exporter.Prepare(root);
|
||||
exporter.Export(new EditorTextureSerializer());
|
||||
return gltf.ToGlbBytes();
|
||||
}
|
||||
return data.ToGlbBytes();
|
||||
}
|
||||
|
||||
// Unsolved Animation Export issue
|
||||
|
||||
@@ -25,7 +25,6 @@ namespace UniGLTF
|
||||
w.Write(8.0f);
|
||||
bytes = ms.ToArray();
|
||||
}
|
||||
var storage = new SimpleStorage(new ArraySegment<byte>(bytes));
|
||||
|
||||
var gltf = new glTF
|
||||
{
|
||||
@@ -54,9 +53,9 @@ namespace UniGLTF
|
||||
}
|
||||
}
|
||||
};
|
||||
gltf.buffers[0].OpenStorage(storage);
|
||||
|
||||
var (getter, len) = WeightsAccessor.GetAccessor(gltf, 0);
|
||||
var data = GltfData.CreateFromGltfDataForTest(gltf, new ArraySegment<byte>(bytes));
|
||||
var (getter, len) = WeightsAccessor.GetAccessor(data, 0);
|
||||
Assert.AreEqual((1.0f, 2.0f, 3.0f, 4.0f), getter(0));
|
||||
Assert.AreEqual((5.0f, 6.0f, 7.0f, 8.0f), getter(1));
|
||||
}
|
||||
@@ -118,9 +117,7 @@ namespace UniGLTF
|
||||
[Test]
|
||||
public void SharedVertexBufferTest()
|
||||
{
|
||||
var glTF = new glTF();
|
||||
var bytesBuffer = new ArrayByteBuffer(new byte[50 * 1024 * 1024]);
|
||||
var bufferIndex = glTF.AddBuffer(bytesBuffer);
|
||||
var data = new ExportingGltfData(50 * 1024 * 1024);
|
||||
|
||||
var Materials = new List<Material>{
|
||||
new Material(Shader.Find("Standard")), // A
|
||||
@@ -136,12 +133,14 @@ namespace UniGLTF
|
||||
|
||||
var unityMesh = MeshExportList.Create(go);
|
||||
var (gltfMesh, blendShapeIndexMap) = meshExportSettings.DivideVertexBuffer
|
||||
? MeshExporter_DividedVertexBuffer.Export(glTF, bufferIndex, unityMesh, Materials, axisInverter, meshExportSettings)
|
||||
: MeshExporter_SharedVertexBuffer.Export(glTF, bufferIndex, unityMesh, Materials,axisInverter, meshExportSettings)
|
||||
? MeshExporter_DividedVertexBuffer.Export(data, unityMesh, Materials, axisInverter, meshExportSettings)
|
||||
: MeshExporter_SharedVertexBuffer.Export(data, unityMesh, Materials, axisInverter, meshExportSettings)
|
||||
;
|
||||
|
||||
var parsed = GltfData.CreateFromGltfDataForTest(data.GLTF);
|
||||
|
||||
{
|
||||
var indices = glTF.GetIndices(gltfMesh.primitives[0].indices);
|
||||
var indices = parsed.GetIndices(gltfMesh.primitives[0].indices);
|
||||
Assert.AreEqual(0, indices[0]);
|
||||
Assert.AreEqual(1, indices[1]);
|
||||
Assert.AreEqual(5, indices[2]);
|
||||
@@ -149,8 +148,9 @@ namespace UniGLTF
|
||||
Assert.AreEqual(1, indices[4]);
|
||||
Assert.AreEqual(4, indices[5]);
|
||||
}
|
||||
|
||||
{
|
||||
var indices = glTF.GetIndices(gltfMesh.primitives[1].indices);
|
||||
var indices = parsed.GetIndices(gltfMesh.primitives[1].indices);
|
||||
Assert.AreEqual(1, indices[0]);
|
||||
Assert.AreEqual(2, indices[1]);
|
||||
Assert.AreEqual(4, indices[2]);
|
||||
@@ -159,16 +159,14 @@ namespace UniGLTF
|
||||
Assert.AreEqual(3, indices[5]);
|
||||
}
|
||||
|
||||
var positions = glTF.GetArrayFromAccessor<Vector3>(gltfMesh.primitives[0].attributes.POSITION);
|
||||
var positions = parsed.GetArrayFromAccessor<Vector3>(gltfMesh.primitives[0].attributes.POSITION);
|
||||
Assert.AreEqual(6, positions.Length);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DividedVertexBufferTest()
|
||||
{
|
||||
var glTF = new glTF();
|
||||
var bytesBuffer = new ArrayByteBuffer(new byte[50 * 1024 * 1024]);
|
||||
var bufferIndex = glTF.AddBuffer(bytesBuffer);
|
||||
var data = new ExportingGltfData(50 * 1024 * 1024);
|
||||
|
||||
var Materials = new List<Material>{
|
||||
new Material(Shader.Find("Standard")), // A
|
||||
@@ -184,12 +182,13 @@ namespace UniGLTF
|
||||
|
||||
var unityMesh = MeshExportList.Create(go);
|
||||
var (gltfMesh, blendShapeIndexMap) = meshExportSettings.DivideVertexBuffer
|
||||
? MeshExporter_DividedVertexBuffer.Export(glTF, bufferIndex, unityMesh, Materials, axisInverter, meshExportSettings)
|
||||
: MeshExporter_SharedVertexBuffer.Export(glTF, bufferIndex, unityMesh, Materials,axisInverter, meshExportSettings)
|
||||
? MeshExporter_DividedVertexBuffer.Export(data, unityMesh, Materials, axisInverter, meshExportSettings)
|
||||
: MeshExporter_SharedVertexBuffer.Export(data, unityMesh, Materials, axisInverter, meshExportSettings)
|
||||
;
|
||||
|
||||
var parsed = GltfData.CreateFromGltfDataForTest(data.GLTF);
|
||||
{
|
||||
var indices = glTF.GetIndices(gltfMesh.primitives[0].indices);
|
||||
var indices = parsed.GetIndices(gltfMesh.primitives[0].indices);
|
||||
Assert.AreEqual(0, indices[0]);
|
||||
Assert.AreEqual(1, indices[1]);
|
||||
Assert.AreEqual(3, indices[2]);
|
||||
@@ -198,12 +197,12 @@ namespace UniGLTF
|
||||
Assert.AreEqual(2, indices[5]);
|
||||
}
|
||||
{
|
||||
var positions = glTF.GetArrayFromAccessor<Vector3>(gltfMesh.primitives[0].attributes.POSITION);
|
||||
var positions = parsed.GetArrayFromAccessor<Vector3>(gltfMesh.primitives[0].attributes.POSITION);
|
||||
Assert.AreEqual(4, positions.Length);
|
||||
}
|
||||
|
||||
{
|
||||
var indices = glTF.GetIndices(gltfMesh.primitives[1].indices);
|
||||
var indices = parsed.GetIndices(gltfMesh.primitives[1].indices);
|
||||
Assert.AreEqual(0, indices[0]);
|
||||
Assert.AreEqual(1, indices[1]);
|
||||
Assert.AreEqual(3, indices[2]);
|
||||
@@ -212,7 +211,7 @@ namespace UniGLTF
|
||||
Assert.AreEqual(2, indices[5]);
|
||||
}
|
||||
{
|
||||
var positions = glTF.GetArrayFromAccessor<Vector3>(gltfMesh.primitives[1].attributes.POSITION);
|
||||
var positions = parsed.GetArrayFromAccessor<Vector3>(gltfMesh.primitives[1].attributes.POSITION);
|
||||
Assert.AreEqual(4, positions.Length);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,25 +100,25 @@ namespace UniGLTF
|
||||
var go = CreateSimpleScene();
|
||||
|
||||
// export
|
||||
var gltf = new glTF();
|
||||
var data = new ExportingGltfData();
|
||||
|
||||
string json = null;
|
||||
using (var exporter = new gltfExporter(gltf, new GltfExportSettings()))
|
||||
using (var exporter = new gltfExporter(data, new GltfExportSettings()))
|
||||
{
|
||||
exporter.Prepare(go);
|
||||
exporter.Export(new EditorTextureSerializer());
|
||||
|
||||
// remove empty buffer
|
||||
gltf.buffers.Clear();
|
||||
data.GLTF.buffers.Clear();
|
||||
|
||||
json = gltf.ToJson();
|
||||
json = data.GLTF.ToJson();
|
||||
}
|
||||
|
||||
// parse
|
||||
var data = new JsonWithStorageParser(json).Parse();
|
||||
var parsed = new JsonWithStorageParser(json).Parse();
|
||||
|
||||
// import
|
||||
using (var context = new ImporterContext(data))
|
||||
using (var context = new ImporterContext(parsed))
|
||||
using (var loaded = context.Load())
|
||||
{
|
||||
AssertAreEqual(go.transform, loaded.transform);
|
||||
@@ -293,14 +293,14 @@ namespace UniGLTF
|
||||
[Test]
|
||||
public void GlTFToJsonTest()
|
||||
{
|
||||
var gltf = new glTF();
|
||||
using (var exporter = new gltfExporter(gltf, new GltfExportSettings()))
|
||||
var data = new ExportingGltfData();
|
||||
using (var exporter = new gltfExporter(data, new GltfExportSettings()))
|
||||
{
|
||||
exporter.Prepare(CreateSimpleScene());
|
||||
exporter.Export(new EditorTextureSerializer());
|
||||
}
|
||||
|
||||
var expected = gltf.ToJson().ParseAsJson();
|
||||
var expected = data.GLTF.ToJson().ParseAsJson();
|
||||
expected.AddKey(Utf8String.From("meshes"));
|
||||
expected.AddValue(default(ArraySegment<byte>), ValueNodeType.Array);
|
||||
expected["meshes"].AddValue(default(ArraySegment<byte>), ValueNodeType.Object);
|
||||
@@ -334,7 +334,7 @@ namespace UniGLTF
|
||||
primitive["targets"][1].AddKey(Utf8String.From("TANGENT"));
|
||||
primitive["targets"][1].AddValue(Utf8String.From("0").Bytes, ValueNodeType.Integer);
|
||||
|
||||
gltf.meshes.Add(new glTFMesh("test")
|
||||
data.GLTF.meshes.Add(new glTFMesh("test")
|
||||
{
|
||||
primitives = new List<glTFPrimitives>
|
||||
{
|
||||
@@ -362,7 +362,7 @@ namespace UniGLTF
|
||||
}
|
||||
}
|
||||
});
|
||||
var actual = gltf.ToJson().ParseAsJson();
|
||||
var actual = data.GLTF.ToJson().ParseAsJson();
|
||||
|
||||
Assert.AreEqual(expected, actual);
|
||||
}
|
||||
@@ -528,9 +528,10 @@ namespace UniGLTF
|
||||
}
|
||||
|
||||
// export
|
||||
var gltf = new glTF();
|
||||
var data = new ExportingGltfData();
|
||||
var gltf = data.GLTF;
|
||||
var json = default(string);
|
||||
using (var exporter = new gltfExporter(gltf, new GltfExportSettings()))
|
||||
using (var exporter = new gltfExporter(data, new GltfExportSettings()))
|
||||
{
|
||||
exporter.Prepare(go);
|
||||
exporter.Export(new EditorTextureSerializer());
|
||||
@@ -553,9 +554,9 @@ namespace UniGLTF
|
||||
// import
|
||||
{
|
||||
var storage = new SimpleStorage(new ArraySegment<byte>(new byte[1024 * 1024]));
|
||||
var data = new JsonWithStorageParser(json, storage).Parse();
|
||||
var parsed = new JsonWithStorageParser(json, storage).Parse();
|
||||
|
||||
using (var context = new ImporterContext(data))
|
||||
using (var context = new ImporterContext(parsed))
|
||||
using (var loaded = context.Load())
|
||||
{
|
||||
var importedRed = loaded.transform.GetChild(0);
|
||||
@@ -573,10 +574,10 @@ namespace UniGLTF
|
||||
// import new version
|
||||
{
|
||||
var storage = new SimpleStorage(new ArraySegment<byte>(new byte[1024 * 1024]));
|
||||
var data = new JsonWithStorageParser(json, storage).Parse();
|
||||
var parsed = new JsonWithStorageParser(json, storage).Parse();
|
||||
|
||||
//Debug.LogFormat("{0}", context.Json);
|
||||
using (var context = new ImporterContext(data))
|
||||
using (var context = new ImporterContext(parsed))
|
||||
using (var loaded = context.Load())
|
||||
{
|
||||
var importedRed = loaded.transform.GetChild(0);
|
||||
@@ -610,9 +611,10 @@ namespace UniGLTF
|
||||
}
|
||||
|
||||
// export
|
||||
var gltf = new glTF();
|
||||
var data = new ExportingGltfData();
|
||||
var gltf = data.GLTF;
|
||||
string json;
|
||||
using (var exporter = new gltfExporter(gltf, new GltfExportSettings()))
|
||||
using (var exporter = new gltfExporter(data, new GltfExportSettings()))
|
||||
{
|
||||
exporter.Prepare(go);
|
||||
exporter.Export(new EditorTextureSerializer());
|
||||
@@ -627,9 +629,9 @@ namespace UniGLTF
|
||||
// import
|
||||
{
|
||||
var storage = new SimpleStorage(new ArraySegment<byte>(new byte[1024 * 1024]));
|
||||
var data = new JsonWithStorageParser(json, storage).Parse();
|
||||
var parsed = new JsonWithStorageParser(json, storage).Parse();
|
||||
|
||||
using (var context = new ImporterContext(data))
|
||||
using (var context = new ImporterContext(parsed))
|
||||
using (var loaded = context.Load())
|
||||
{
|
||||
Assert.AreEqual(1, loaded.transform.GetChildren().Count());
|
||||
@@ -674,9 +676,10 @@ namespace UniGLTF
|
||||
Assert.True(vs.All(x => x.CanExport));
|
||||
|
||||
// export
|
||||
var gltf = new glTF();
|
||||
var data = new ExportingGltfData();
|
||||
var gltf = data.GLTF;
|
||||
string json;
|
||||
using (var exporter = new gltfExporter(gltf, new GltfExportSettings()))
|
||||
using (var exporter = new gltfExporter(data, new GltfExportSettings()))
|
||||
{
|
||||
exporter.Prepare(root);
|
||||
exporter.Export(new EditorTextureSerializer());
|
||||
@@ -692,9 +695,9 @@ namespace UniGLTF
|
||||
// import
|
||||
{
|
||||
var storage = new SimpleStorage(new ArraySegment<byte>(new byte[1024 * 1024]));
|
||||
var data = new JsonWithStorageParser(json, storage).Parse();
|
||||
var parsed = new JsonWithStorageParser(json, storage).Parse();
|
||||
|
||||
using (var context = new ImporterContext(data))
|
||||
using (var context = new ImporterContext(parsed))
|
||||
using (var loaded = context.Load())
|
||||
{
|
||||
Assert.AreEqual(2, loaded.transform.GetChildren().Count());
|
||||
|
||||
@@ -222,13 +222,13 @@ namespace VRM
|
||||
|
||||
// 出力
|
||||
var sw = System.Diagnostics.Stopwatch.StartNew();
|
||||
var gltf = new UniGLTF.glTF();
|
||||
using (var exporter = new VRMExporter(gltf, settings.MeshExportSettings))
|
||||
var data = new UniGLTF.ExportingGltfData();
|
||||
using (var exporter = new VRMExporter(data, settings.MeshExportSettings))
|
||||
{
|
||||
exporter.Prepare(target);
|
||||
exporter.Export(new EditorTextureSerializer());
|
||||
}
|
||||
var bytes = gltf.ToGlbBytes();
|
||||
var bytes = data.ToGlbBytes();
|
||||
Debug.LogFormat("Export elapsed {0}", sw.Elapsed);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
@@ -12,27 +12,27 @@ namespace VRM
|
||||
{
|
||||
public const Axes Vrm0xSpecificationInverseAxis = Axes.Z;
|
||||
|
||||
public static glTF Export(GltfExportSettings configuration, GameObject go, ITextureSerializer textureSerializer)
|
||||
public static ExportingGltfData Export(GltfExportSettings configuration, GameObject go, ITextureSerializer textureSerializer)
|
||||
{
|
||||
var gltf = new glTF();
|
||||
using (var exporter = new VRMExporter(gltf, configuration))
|
||||
var data = new ExportingGltfData();
|
||||
using (var exporter = new VRMExporter(data, configuration))
|
||||
{
|
||||
exporter.Prepare(go);
|
||||
exporter.Export(textureSerializer);
|
||||
}
|
||||
return gltf;
|
||||
return data;
|
||||
}
|
||||
|
||||
public readonly VRM.glTF_VRM_extensions VRM = new glTF_VRM_extensions();
|
||||
|
||||
public VRMExporter(glTF gltf, GltfExportSettings exportSettings) : base(gltf, exportSettings)
|
||||
public VRMExporter(ExportingGltfData data, GltfExportSettings exportSettings) : base(data, exportSettings)
|
||||
{
|
||||
if (exportSettings == null || exportSettings.InverseAxis != Vrm0xSpecificationInverseAxis)
|
||||
{
|
||||
throw new Exception( $"VRM specification requires InverseAxis settings as {Vrm0xSpecificationInverseAxis}");
|
||||
throw new Exception($"VRM specification requires InverseAxis settings as {Vrm0xSpecificationInverseAxis}");
|
||||
}
|
||||
|
||||
gltf.extensionsUsed.Add(glTF_VRM_extensions.ExtensionName);
|
||||
_gltf.extensionsUsed.Add(glTF_VRM_extensions.ExtensionName);
|
||||
}
|
||||
|
||||
protected override IMaterialExporter CreateMaterialExporter()
|
||||
@@ -118,7 +118,7 @@ namespace VRM
|
||||
VRM.meta.title = meta.Title;
|
||||
if (meta.Thumbnail != null)
|
||||
{
|
||||
VRM.meta.texture = glTF.PushGltfTexture(glTF.buffers.Count - 1, meta.Thumbnail, ColorSpace.sRGB, textureSerializer);
|
||||
VRM.meta.texture = GltfTextureExporter.PushGltfTexture(_data, meta.Thumbnail, ColorSpace.sRGB, textureSerializer);
|
||||
}
|
||||
|
||||
VRM.meta.licenseType = meta.LicenseType;
|
||||
@@ -213,7 +213,7 @@ namespace VRM
|
||||
var f = new JsonFormatter();
|
||||
VRMSerializer.Serialize(f, VRM);
|
||||
var bytes = f.GetStoreBytes();
|
||||
glTFExtensionExport.GetOrCreate(ref glTF.extensions).Add("VRM", bytes);
|
||||
glTFExtensionExport.GetOrCreate(ref _gltf.extensions).Add("VRM", bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -170,7 +170,7 @@ namespace VRM.Samples
|
||||
|
||||
// TODO: Check contents in JSON
|
||||
/*var exportJson = */
|
||||
JsonParser.Parse(vrm.ToJson());
|
||||
JsonParser.Parse(vrm.GLTF.ToJson());
|
||||
|
||||
// TODO: Check contents in JSON
|
||||
/*var newExportedJson = */
|
||||
|
||||
@@ -65,9 +65,9 @@ namespace UniVRM10
|
||||
/// <param name="storage"></param>
|
||||
/// <param name="gltfMesh"></param>
|
||||
/// <param name="option"></param>
|
||||
static IEnumerable<glTFPrimitives> ExportMeshDivided(this VrmLib.Mesh mesh, List<object> materials, Vrm10Storage storage, ExportArgs option)
|
||||
static IEnumerable<glTFPrimitives> ExportMeshDivided(this VrmLib.Mesh mesh, List<object> materials,
|
||||
ExportingGltfData writer, ExportArgs option)
|
||||
{
|
||||
var bufferIndex = 0;
|
||||
var usedIndices = new List<int>();
|
||||
var meshIndices = SpanLike.CopyFrom(mesh.IndexBuffer.GetAsIntArray());
|
||||
var positions = mesh.VertexBuffer.Positions.GetSpan<UnityEngine.Vector3>().ToArray();
|
||||
@@ -121,7 +121,7 @@ namespace UniVRM10
|
||||
}
|
||||
}
|
||||
var materialIndex = submesh.Material;
|
||||
var gltfPrimitive = buffer.ToGltfPrimitive(storage.Gltf, bufferIndex, materialIndex, indices);
|
||||
var gltfPrimitive = buffer.ToGltfPrimitive(writer, materialIndex, indices);
|
||||
|
||||
// blendShape
|
||||
for (int j = 0; j < mesh.MorphTargets.Count; ++j)
|
||||
@@ -145,7 +145,7 @@ namespace UniVRM10
|
||||
);
|
||||
}
|
||||
|
||||
gltfPrimitive.targets.Add(blendShape.ToGltf(storage.Gltf, bufferIndex, !option.removeMorphNormal, option.sparse));
|
||||
gltfPrimitive.targets.Add(blendShape.ToGltf(writer, !option.removeMorphNormal, option.sparse));
|
||||
}
|
||||
|
||||
yield return gltfPrimitive;
|
||||
@@ -160,7 +160,7 @@ namespace UniVRM10
|
||||
/// <param name="storage"></param>
|
||||
/// <param name="option"></param>
|
||||
/// <returns></returns>
|
||||
public static glTFMesh ExportMeshGroup(this MeshGroup src, List<object> materials, Vrm10Storage storage, ExportArgs option)
|
||||
public static glTFMesh ExportMeshGroup(this MeshGroup src, List<object> materials, ExportingGltfData writer, ExportArgs option)
|
||||
{
|
||||
var gltfMesh = new glTFMesh
|
||||
{
|
||||
@@ -172,7 +172,7 @@ namespace UniVRM10
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
foreach (var prim in src.Meshes[0].ExportMeshDivided(materials, storage, option))
|
||||
foreach (var prim in src.Meshes[0].ExportMeshDivided(materials, writer, option))
|
||||
{
|
||||
gltfMesh.primitives.Add(prim);
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ namespace UniVRM10
|
||||
|
||||
GetTextureBytesAsync getThumbnailImageBytesAsync = () =>
|
||||
{
|
||||
var bytes = data.GLTF.GetImageBytes(data.Storage, imageIndex);
|
||||
var bytes = data.GetImageBytes(imageIndex);
|
||||
return Task.FromResult(GltfTextureImporter.ToArray(bytes));
|
||||
};
|
||||
var texDesc = new TextureDescriptor(objectName, gltfImage.GetExt(), gltfImage.uri, Vector2.zero, Vector2.one, default, TextureImportTypes.sRGB, default, default,
|
||||
|
||||
@@ -37,10 +37,6 @@ namespace UniVRM10
|
||||
Storage.Gltf.extensionsUsed.Add(UniGLTF.Extensions.VRMC_materials_mtoon.VRMC_materials_mtoon.ExtensionName);
|
||||
Storage.Gltf.extensionsUsed.Add(UniGLTF.Extensions.VRMC_springBone.VRMC_springBone.ExtensionName);
|
||||
Storage.Gltf.extensionsUsed.Add(UniGLTF.Extensions.VRMC_node_constraint.VRMC_node_constraint.ExtensionName);
|
||||
Storage.Gltf.buffers.Add(new glTFBuffer
|
||||
{
|
||||
|
||||
});
|
||||
|
||||
m_textureSerializer = textureSerializer;
|
||||
m_textureExporter = new TextureExporter(m_textureSerializer);
|
||||
@@ -61,11 +57,11 @@ namespace UniVRM10
|
||||
return asset;
|
||||
}
|
||||
|
||||
public static IEnumerable<glTFMesh> ExportMeshes(List<MeshGroup> groups, List<object> materials, Vrm10Storage storage, ExportArgs option)
|
||||
public static IEnumerable<glTFMesh> ExportMeshes(List<MeshGroup> groups, List<object> materials, ExportingGltfData data, ExportArgs option)
|
||||
{
|
||||
foreach (var group in groups)
|
||||
{
|
||||
yield return group.ExportMeshGroup(materials, storage, option);
|
||||
yield return group.ExportMeshGroup(materials, data, option);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -201,7 +197,7 @@ namespace UniVRM10
|
||||
for (var exportedTextureIdx = 0; exportedTextureIdx < exportedTextures.Count; ++exportedTextureIdx)
|
||||
{
|
||||
var (unityTexture, texColorSpace) = exportedTextures[exportedTextureIdx];
|
||||
Storage.Gltf.PushGltfTexture(0, unityTexture, texColorSpace, m_textureSerializer);
|
||||
GltfTextureExporter.PushGltfTexture(Storage, unityTexture, texColorSpace, m_textureSerializer);
|
||||
}
|
||||
|
||||
if (thumbnailTextureIndex.HasValue)
|
||||
|
||||
@@ -10,7 +10,7 @@ using VrmLib;
|
||||
|
||||
namespace UniVRM10
|
||||
{
|
||||
public class Vrm10Storage
|
||||
public class Vrm10Storage : ExportingGltfData
|
||||
{
|
||||
UniGLTF.GltfData m_data;
|
||||
public UniGLTF.glTF Gltf => m_data.GLTF;
|
||||
@@ -29,10 +29,7 @@ namespace UniVRM10
|
||||
m_data = new GltfData(
|
||||
string.Empty,
|
||||
string.Empty,
|
||||
new glTF
|
||||
{
|
||||
extensionsUsed = new List<string>(),
|
||||
},
|
||||
GLTF,
|
||||
new List<GlbChunk>(),
|
||||
new SimpleStorage(new ArraySegment<byte>()),
|
||||
new MigrationFlags()
|
||||
@@ -41,8 +38,6 @@ namespace UniVRM10
|
||||
{
|
||||
new UniGLTF.ArrayByteBuffer()
|
||||
};
|
||||
|
||||
Gltf.AddBuffer(Buffers[0]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -69,7 +69,7 @@ namespace UniVRM10
|
||||
// copy images
|
||||
foreach (var image in gltf.images)
|
||||
{
|
||||
var bytes = gltf.GetViewBytes(image.bufferView);
|
||||
var bytes = _data.GetViewBytes(image.bufferView);
|
||||
image.bufferView = AddBuffer(bytes);
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace UniVRM10
|
||||
}
|
||||
}
|
||||
|
||||
static void ReverseVector3Array(glTF gltf, int accessorIndex, HashSet<int> used)
|
||||
static void ReverseVector3Array(GltfData data, int accessorIndex, HashSet<int> used)
|
||||
{
|
||||
if (accessorIndex == -1)
|
||||
{
|
||||
@@ -59,7 +59,7 @@ namespace UniVRM10
|
||||
return;
|
||||
}
|
||||
|
||||
var accessor = gltf.accessors[accessorIndex];
|
||||
var accessor = data.GLTF.accessors[accessorIndex];
|
||||
var bufferViewIndex = -1;
|
||||
if (accessor.bufferView != -1)
|
||||
{
|
||||
@@ -72,7 +72,7 @@ namespace UniVRM10
|
||||
|
||||
if (bufferViewIndex != -1)
|
||||
{
|
||||
var buffer = gltf.GetViewBytes(bufferViewIndex);
|
||||
var buffer = data.GetViewBytes(bufferViewIndex);
|
||||
var span = SpanLike.Wrap<UnityEngine.Vector3>(buffer);
|
||||
for (int i = 0; i < span.Length; ++i)
|
||||
{
|
||||
@@ -85,35 +85,35 @@ namespace UniVRM10
|
||||
/// シーンをY軸で180度回転する
|
||||
/// </summary>
|
||||
/// <param name="gltf"></param>
|
||||
public static void Rotate(glTF gltf)
|
||||
public static void Rotate(GltfData data)
|
||||
{
|
||||
foreach (var node in gltf.nodes)
|
||||
foreach (var node in data.GLTF.nodes)
|
||||
{
|
||||
Rotate(node);
|
||||
}
|
||||
|
||||
// mesh の回転のみでよい
|
||||
var used = new HashSet<int>();
|
||||
foreach (var mesh in gltf.meshes)
|
||||
foreach (var mesh in data.GLTF.meshes)
|
||||
{
|
||||
foreach (var prim in mesh.primitives)
|
||||
{
|
||||
ReverseVector3Array(gltf, prim.attributes.POSITION, used);
|
||||
ReverseVector3Array(gltf, prim.attributes.NORMAL, used);
|
||||
ReverseVector3Array(data, prim.attributes.POSITION, used);
|
||||
ReverseVector3Array(data, prim.attributes.NORMAL, used);
|
||||
foreach (var target in prim.targets)
|
||||
{
|
||||
ReverseVector3Array(gltf, target.POSITION, used);
|
||||
ReverseVector3Array(gltf, target.NORMAL, used);
|
||||
ReverseVector3Array(data, target.POSITION, used);
|
||||
ReverseVector3Array(data, target.NORMAL, used);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var skin in gltf.skins)
|
||||
foreach (var skin in data.GLTF.skins)
|
||||
{
|
||||
if (used.Add(skin.inverseBindMatrices))
|
||||
{
|
||||
var accessor = gltf.accessors[skin.inverseBindMatrices];
|
||||
var buffer = gltf.GetViewBytes(accessor.bufferView);
|
||||
var accessor = data.GLTF.accessors[skin.inverseBindMatrices];
|
||||
var buffer = data.GetViewBytes(accessor.bufferView);
|
||||
var span = SpanLike.Wrap<UnityEngine.Matrix4x4>(buffer);
|
||||
for (int i = 0; i < span.Length; ++i)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user