Skip to content

Commit

Permalink
Merge pull request #679 from ousttrue/feature10/spring_exclude
Browse files Browse the repository at this point in the history
Feature10/spring exclude
  • Loading branch information
ousttrue authored Jan 22, 2021
2 parents 3aeaa6d + 9b45fb9 commit 01d8101
Show file tree
Hide file tree
Showing 67 changed files with 1,886 additions and 1,246 deletions.
25 changes: 25 additions & 0 deletions Assets/UniGLTF/Runtime/Extensions/ArrayExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -132,4 +132,29 @@ public static void Assign<T>(this List<T> dst, T[] src, Func<T, T> pred)
dst.AddRange(src.Select(pred));
}
}

public static class ArraySegmentExtensions
{
public static ArraySegment<T> Slice<T>(this ArraySegment<T> self, int start, int length)
{
if (start + length > self.Count)
{
throw new ArgumentOutOfRangeException();
}
return new ArraySegment<T>(
self.Array,
self.Offset + start,
length
);
}

public static ArraySegment<T> Slice<T>(this ArraySegment<T> self, int start)
{
if (start > self.Count)
{
throw new ArgumentOutOfRangeException();
}
return self.Slice(start, self.Count - start);
}
}
}
6 changes: 3 additions & 3 deletions Assets/UniGLTF/Runtime/Extensions/glTFExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -438,11 +438,11 @@ 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.ToBytes(json, self.buffers[0].GetBytes());
return Glb.Create(json, self.buffers[0].GetBytes()).ToBytes();
}

public static (string, List<glTFBuffer>) ToGltf(this glTF self, string gltfPath)
Expand Down
176 changes: 163 additions & 13 deletions Assets/UniGLTF/Runtime/UniGLTF/Format/glbTypes.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace UniGLTF
Expand All @@ -12,14 +14,39 @@ public enum GlbChunkType : uint

public struct GlbHeader
{

public static readonly byte[] GLB_MAGIC = new byte[] { 0x67, 0x6C, 0x54, 0x46 }; // "glTF"
public static readonly byte[] GLB_VERSION = new byte[] { 2, 0, 0, 0 };

public static void WriteTo(Stream s)
{
s.WriteByte((Byte)'g');
s.WriteByte((Byte)'l');
s.WriteByte((Byte)'T');
s.WriteByte((Byte)'F');
var bytes = BitConverter.GetBytes((UInt32)2);
s.Write(bytes, 0, bytes.Length);
s.Write(GLB_MAGIC, 0, GLB_MAGIC.Length);
s.Write(GLB_VERSION, 0, GLB_VERSION.Length);
}

public static int TryParse(ArraySegment<Byte> bytes, out int pos, out Exception message)
{
pos = 0;

if (!bytes.Slice(0, 4).SequenceEqual(GLB_MAGIC))
{
message = new FormatException("invalid magic");
return 0;
}
pos += 4;

if (!bytes.Slice(pos, 4).SequenceEqual(GLB_VERSION))
{
message = new FormatException("invalid magic");
return 0;
}
pos += 4;

var totalLength = BitConverter.ToInt32(bytes.Array, bytes.Offset + pos);
pos += 4;

message = null;
return totalLength;
}
}

Expand Down Expand Up @@ -48,6 +75,21 @@ public GlbChunk(GlbChunkType type, ArraySegment<Byte> bytes)
Bytes = bytes;
}

public static GlbChunk CreateJson(string json)
{
return CreateJson(new ArraySegment<byte>(Encoding.UTF8.GetBytes(json)));
}

public static GlbChunk CreateJson(ArraySegment<byte> bytes)
{
return new GlbChunk(GlbChunkType.JSON, bytes);
}

public static GlbChunk CreateBin(ArraySegment<Byte> bytes)
{
return new GlbChunk(GlbChunkType.BIN, bytes);
}

byte GetPaddingByte()
{
// chunk type
Expand Down Expand Up @@ -100,7 +142,7 @@ public int WriteTo(Stream s)

// 4byte align
var pad = GetPaddingByte();
for(int i=0; i<padding; ++i)
for (int i = 0; i < padding; ++i)
{
s.WriteByte(pad);
}
Expand All @@ -109,9 +151,33 @@ public int WriteTo(Stream s)
}
}

public static class Glb
/// <summary>
/// https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#glb-file-format-specification
/// </summary>
public struct Glb
{
public static byte[] ToBytes(string json, ArraySegment<byte> body)
public readonly GlbChunk Json;
public readonly GlbChunk Binary;

public Glb(GlbChunk json, GlbChunk binary)
{
if (json.ChunkType != GlbChunkType.JSON) throw new ArgumentException();
Json = json;
if (binary.ChunkType != GlbChunkType.BIN) throw new ArgumentException();
Binary = binary;
}

public static Glb Create(ArraySegment<byte> json, ArraySegment<byte> bin)
{
return new Glb(GlbChunk.CreateJson(json), GlbChunk.CreateBin(bin));
}

public static Glb Create(string json, ArraySegment<byte> bin)
{
return new Glb(GlbChunk.CreateJson(json), GlbChunk.CreateBin(bin));
}

public byte[] ToBytes()
{
using (var s = new MemoryStream())
{
Expand All @@ -123,12 +189,10 @@ public static byte[] ToBytes(string json, ArraySegment<byte> body)
int size = 12;

{
var chunk = new GlbChunk(json);
size += chunk.WriteTo(s);
size += Json.WriteTo(s);
}
{
var chunk = new GlbChunk(body);
size += chunk.WriteTo(s);
size += Binary.WriteTo(s);
}

s.Position = pos;
Expand All @@ -138,5 +202,91 @@ public static byte[] ToBytes(string json, ArraySegment<byte> body)
return s.ToArray();
}
}

public static GlbChunkType ToChunkType(string src)
{
switch (src)
{
case "BIN":
return GlbChunkType.BIN;

case "JSON":
return GlbChunkType.JSON;

default:
throw new FormatException("unknown chunk type: " + src);
}
}

public static Glb Parse(Byte[] bytes)
{
return Parse(new ArraySegment<byte>(bytes));
}

public static Glb Parse(ArraySegment<Byte> bytes)
{
if (TryParse(bytes, out Glb glb, out Exception ex))
{
return glb;
}
else
{
throw ex;
}
}

public static bool TryParse(Byte[] bytes, out Glb glb, out Exception ex)
{
return TryParse(new ArraySegment<byte>(bytes), out glb, out ex);
}

public static bool TryParse(ArraySegment<Byte> bytes, out Glb glb, out Exception ex)
{
glb = default(Glb);
if (bytes.Count == 0)
{
ex = new Exception("empty bytes");
return false;
}

var length = GlbHeader.TryParse(bytes, out int pos, out ex);
if (length == 0)
{
return false;
}
bytes = bytes.Slice(0, length);

try
{
var chunks = new List<GlbChunk>();
while (pos < bytes.Count)
{
var chunkDataSize = BitConverter.ToInt32(bytes.Array, bytes.Offset + pos);
pos += 4;

//var type = (GlbChunkType)BitConverter.ToUInt32(bytes, pos);
var chunkTypeBytes = bytes.Slice(pos, 4).Where(x => x != 0).ToArray();
var chunkTypeStr = Encoding.ASCII.GetString(chunkTypeBytes);
var type = ToChunkType(chunkTypeStr);
pos += 4;

chunks.Add(new GlbChunk
{
ChunkType = type,
Bytes = bytes.Slice(pos, chunkDataSize)
});

pos += chunkDataSize;
}

glb = new Glb(chunks[0], chunks[1]);
return true;
}
catch (Exception _ex)
{
ex = _ex;
return false;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@

namespace UniVRM10
{
[CustomEditor(typeof(VRMSpringBoneColliderGroup))]
public class VRMSpringBoneColliderGroupEditor : Editor
[CustomEditor(typeof(VRM10SpringBoneColliderGroup))]
public class VRM10SpringBoneColliderGroupEditor : Editor
{
VRMSpringBoneColliderGroup m_target;
VRM10SpringBoneColliderGroup m_target;

private void OnEnable()
{
m_target = (VRMSpringBoneColliderGroup)target;
m_target = (VRM10SpringBoneColliderGroup)target;
}

private void OnSceneGUI()
Expand All @@ -39,43 +39,43 @@ private void OnSceneGUI()
EditorUtility.SetDirty(m_target);
}
}

[MenuItem("CONTEXT/VRM10SpringBoneColliderGroup/X Mirror")]
private static void InvertOffsetX(MenuCommand command)
{
var target = command.context as VRMSpringBoneColliderGroup;
var target = command.context as VRM10SpringBoneColliderGroup;
if (target == null) return;

Undo.RecordObject(target, "X Mirror");

foreach (var sphereCollider in target.Colliders)
{
var offset = sphereCollider.Offset;
offset.x *= -1f;
sphereCollider.Offset = offset;
}
}

[MenuItem("CONTEXT/VRM10SpringBoneColliderGroup/Sort Colliders by Radius")]
private static void SortByRadius(MenuCommand command)
{
var target = command.context as VRMSpringBoneColliderGroup;
var target = command.context as VRM10SpringBoneColliderGroup;
if (target == null) return;

Undo.RecordObject(target, "Sort Colliders by Radius");

target.Colliders = target.Colliders.OrderBy(x => -x.Radius).ToArray();
target.Colliders = target.Colliders.OrderBy(x => -x.Radius).ToList();
}

[MenuItem("CONTEXT/VRM10SpringBoneColliderGroup/Sort Colliders by Offset Y")]
private static void SortByOffsetY(MenuCommand command)
{
var target = command.context as VRMSpringBoneColliderGroup;
var target = command.context as VRM10SpringBoneColliderGroup;
if (target == null) return;

Undo.RecordObject(target, "Sort Colliders by Offset Y");

target.Colliders = target.Colliders.OrderBy(x => -x.Offset.y).ToArray();
target.Colliders = target.Colliders.OrderBy(x => -x.Offset.y).ToList();
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

This file was deleted.

Loading

0 comments on commit 01d8101

Please sign in to comment.