mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-08-28 13:54:45 -05:00
update
This commit is contained in:
@@ -16,8 +16,14 @@ namespace UniVRM10
|
||||
var json = glb.Json.Bytes.ParseAsJson();
|
||||
var gltf = UniGLTF.GltfDeserializer.Deserialize(json);
|
||||
|
||||
// attach glb bin to buffer
|
||||
foreach (var buffer in gltf.buffers)
|
||||
{
|
||||
buffer.OpenStorage(new UniGLTF.SimpleStorage(glb.Binary.Bytes));
|
||||
}
|
||||
|
||||
// https://github.com/vrm-c/vrm-specification/issues/205
|
||||
SceneRotator.Rotate(gltf);
|
||||
RotateY180.Rotate(gltf);
|
||||
|
||||
var extensions = new UniGLTF.glTFExtensionExport();
|
||||
{
|
||||
|
||||
94
Assets/VRM10/Runtime/Migration/RotateY180.cs
Normal file
94
Assets/VRM10/Runtime/Migration/RotateY180.cs
Normal file
@@ -0,0 +1,94 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UniGLTF;
|
||||
|
||||
namespace UniVRM10
|
||||
{
|
||||
/// <summary>
|
||||
/// x, y, z => -x, y, -z
|
||||
/// </summary>
|
||||
public static class RotateY180
|
||||
{
|
||||
public static void Rotate(glTFNode node)
|
||||
{
|
||||
if (node.matrix != null && node.matrix.Length == 16)
|
||||
{
|
||||
throw new NotImplementedException("matrix not implemented !");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (node.translation != null && node.translation.Length == 3)
|
||||
{
|
||||
var t = node.translation;
|
||||
t[0] = -t[0];
|
||||
t[2] = -t[2];
|
||||
}
|
||||
if (node.rotation != null && node.rotation.Length == 4)
|
||||
{
|
||||
// throw new NotImplementedException("not normlaized !");
|
||||
}
|
||||
if (node.scale != null && node.rotation.Length == 3)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ReverseVector3Array(glTF gltf, int accessorIndex, HashSet<int> used)
|
||||
{
|
||||
if (!used.Add(accessorIndex))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var accessor = gltf.accessors[accessorIndex];
|
||||
var buffer = gltf.GetViewBytes(accessor.bufferView);
|
||||
var span = VrmLib.SpanLike.Wrap<UnityEngine.Vector3>(buffer);
|
||||
for (int i = 0; i < span.Length; ++i)
|
||||
{
|
||||
span[i] = span[i].RotateY180();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// シーンをY軸で180度回転する
|
||||
/// </summary>
|
||||
/// <param name="gltf"></param>
|
||||
public static void Rotate(glTF gltf)
|
||||
{
|
||||
foreach (var node in gltf.nodes)
|
||||
{
|
||||
Rotate(node);
|
||||
}
|
||||
|
||||
var used = new HashSet<int>();
|
||||
foreach (var mesh in gltf.meshes)
|
||||
{
|
||||
foreach (var prim in mesh.primitives)
|
||||
{
|
||||
ReverseVector3Array(gltf, prim.attributes.POSITION, used);
|
||||
ReverseVector3Array(gltf, prim.attributes.NORMAL, used);
|
||||
foreach (var target in prim.targets)
|
||||
{
|
||||
ReverseVector3Array(gltf, target.POSITION, used);
|
||||
ReverseVector3Array(gltf, target.NORMAL, used);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var skin in gltf.skins)
|
||||
{
|
||||
if (!used.Add(skin.inverseBindMatrices))
|
||||
{
|
||||
var accessor = gltf.accessors[skin.inverseBindMatrices];
|
||||
var buffer = gltf.GetViewBytes(accessor.bufferView);
|
||||
var span = VrmLib.SpanLike.Wrap<UnityEngine.Matrix4x4>(buffer);
|
||||
for (int i = 0; i < span.Length; ++i)
|
||||
{
|
||||
// span[i] = span[i].RotateY180();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
namespace UniVRM10
|
||||
{
|
||||
public static class SceneRotator
|
||||
{
|
||||
/// <summary>
|
||||
/// シーンをY軸で180度回転する
|
||||
/// </summary>
|
||||
/// <param name="gltf"></param>
|
||||
public static void Rotate(UniGLTF.glTF gltf)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -40,11 +40,21 @@ namespace UniVRM10
|
||||
|
||||
public static class UnityExtensions
|
||||
{
|
||||
public static Vector4 RotateY180(this Vector4 v)
|
||||
{
|
||||
return new Vector4(-v.x, v.y, -v.z, v.w);
|
||||
}
|
||||
|
||||
public static Vector4 ReverseZ(this Vector4 v)
|
||||
{
|
||||
return new Vector4(v.x, v.y, -v.z, v.w);
|
||||
}
|
||||
|
||||
public static Vector3 RotateY180(this Vector3 v)
|
||||
{
|
||||
return new Vector3(-v.x, v.y, -v.z);
|
||||
}
|
||||
|
||||
public static Vector3 ReverseZ(this Vector3 v)
|
||||
{
|
||||
return new Vector3(v.x, v.y, -v.z);
|
||||
@@ -94,6 +104,14 @@ namespace UniVRM10
|
||||
#endif
|
||||
}
|
||||
|
||||
public static Matrix4x4 RotateY180(this Matrix4x4 m)
|
||||
{
|
||||
var t = m.GetColumn(3);
|
||||
var tt = RotateY180(t);
|
||||
m.SetColumn(3, tt);
|
||||
return m;
|
||||
}
|
||||
|
||||
public static Matrix4x4 ReverseZ(this Matrix4x4 m)
|
||||
{
|
||||
m.SetTRS(m.ExtractPosition().ReverseZ(), m.ExtractRotation().ReverseZ(), m.ExtractScale());
|
||||
|
||||
@@ -3,6 +3,7 @@ using NUnit.Framework;
|
||||
using UnityEngine;
|
||||
using UniJSON;
|
||||
using System;
|
||||
using UniGLTF;
|
||||
|
||||
namespace UniVRM10
|
||||
{
|
||||
@@ -56,5 +57,44 @@ namespace UniVRM10
|
||||
MigrationVrm.Check(vrm0Json, GetExtension(gltf.extensions, UniGLTF.Extensions.VRMC_springBone.VRMC_springBone.ExtensionNameUtf8,
|
||||
UniGLTF.Extensions.VRMC_springBone.GltfDeserializer.Deserialize), gltf.nodes);
|
||||
}
|
||||
|
||||
const float EPS = 1e-4f;
|
||||
|
||||
static bool Nearly(float l, float r)
|
||||
{
|
||||
return Mathf.Abs(l - r) <= EPS;
|
||||
}
|
||||
|
||||
static bool Nearly(Vector3 l, Vector3 r)
|
||||
{
|
||||
if (!Nearly(l.x, r.x)) return false;
|
||||
if (!Nearly(l.y, r.y)) return false;
|
||||
if (!Nearly(l.z, r.z)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RotateTest()
|
||||
{
|
||||
var euler = new Vector3(0, 10, 20);
|
||||
var r = Quaternion.Euler(euler);
|
||||
var node = new glTFNode
|
||||
{
|
||||
translation = new float[] { 1, 2, 3 },
|
||||
rotation = new float[] { r.x, r.y, r.z, r.w },
|
||||
scale = new float[] { 1, 2, 3 },
|
||||
};
|
||||
RotateY180.Rotate(node);
|
||||
|
||||
Assert.AreEqual(new Vector3(-1, 2, 3), node.translation.ToVector3().ToUnityVector3());
|
||||
Assert.AreEqual(new Vector3(1, 2, 3), node.scale.ToVector3().ToUnityVector3());
|
||||
|
||||
var result = node.rotation.ToQuaternion().ToUnityQuaternion().eulerAngles;
|
||||
Debug.LogFormat($"{result}");
|
||||
|
||||
Assert.True(Nearly(0, result.x));
|
||||
Assert.True(Nearly(360 - 10, result.y));
|
||||
Assert.True(Nearly(360 - 20, result.z));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user