mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-04-21 22:47:19 -05:00
VrmLib.Coordinates.Vrm1
https://github.com/vrm-c/vrm-specification/issues/205
This commit is contained in:
parent
96c01397ce
commit
5f86ffe842
|
|
@ -313,7 +313,7 @@ namespace UniVRM10
|
|||
|
||||
// 右手系に変換
|
||||
m_logLabel += $"convert to right handed coordinate...\n";
|
||||
model.ConvertCoordinate(VrmLib.Coordinates.Gltf, ignoreVrm: false);
|
||||
model.ConvertCoordinate(VrmLib.Coordinates.Vrm1, ignoreVrm: false);
|
||||
|
||||
var exportedBytes = GetGlb(model);
|
||||
m_logLabel += $"write to {path}...\n";
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ public class Sample : MonoBehaviour
|
|||
var exporter = new UniVRM10.RuntimeVrmConverter();
|
||||
var model = exporter.ToModelFrom10(vrm0x.Root);
|
||||
// 右手系に変換
|
||||
model.ConvertCoordinate(VrmLib.Coordinates.Gltf);
|
||||
model.ConvertCoordinate(VrmLib.Coordinates.Vrm1);
|
||||
var exportedBytes = model.ToGlb();
|
||||
|
||||
// Import 1.0
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ namespace UniVRM10.Test
|
|||
var exporter = new UniVRM10.RuntimeVrmConverter();
|
||||
var model = exporter.ToModelFrom10(root, root.GetComponent<VRM10Controller>().Meta);
|
||||
|
||||
model.ConvertCoordinate(VrmLib.Coordinates.Gltf, ignoreVrm: false);
|
||||
model.ConvertCoordinate(VrmLib.Coordinates.Vrm1, ignoreVrm: false);
|
||||
return model;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ namespace UniVRM10.Test
|
|||
byte[] ToVrm10(VrmLib.Model model)
|
||||
{
|
||||
// 右手系に変換
|
||||
VrmLib.ModelExtensionsForCoordinates.ConvertCoordinate(model, VrmLib.Coordinates.Gltf);
|
||||
VrmLib.ModelExtensionsForCoordinates.ConvertCoordinate(model, VrmLib.Coordinates.Vrm1);
|
||||
var bytes = UniVRM10.ModelExtensions.ToGlb(model);
|
||||
return bytes;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,9 +4,12 @@ namespace VrmLib
|
|||
{
|
||||
Unknown,
|
||||
|
||||
/// OpenGL standard
|
||||
/// VRM-0
|
||||
XYZ_RightUpBack_RH,
|
||||
|
||||
/// VRM-1
|
||||
XYZ_RightUpForward_RH,
|
||||
|
||||
/// D3D standard(Unity)
|
||||
XYZ_RightUpForward_LH,
|
||||
}
|
||||
|
|
@ -27,13 +30,19 @@ namespace VrmLib
|
|||
public GeometryCoordinates Geometry;
|
||||
public TextureOrigin Texture;
|
||||
|
||||
public static Coordinates Gltf => new Coordinates
|
||||
public static Coordinates Vrm0 => new Coordinates
|
||||
{
|
||||
Geometry = GeometryCoordinates.XYZ_RightUpBack_RH,
|
||||
Texture = TextureOrigin.LeftTop,
|
||||
};
|
||||
public bool IsVrm0 => this.Equals(Vrm0);
|
||||
|
||||
public bool IsGltf => this.Equals(Gltf);
|
||||
public static Coordinates Vrm1 => new Coordinates
|
||||
{
|
||||
Geometry = GeometryCoordinates.XYZ_RightUpForward_RH,
|
||||
Texture = TextureOrigin.LeftTop,
|
||||
};
|
||||
public bool IsVrm1 => this.Equals(Vrm1);
|
||||
|
||||
public static Coordinates Unity => new Coordinates
|
||||
{
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ namespace VrmLib
|
|||
return null;
|
||||
}
|
||||
|
||||
var model = new Model(Coordinates.Gltf)
|
||||
var model = new Model(Coordinates.Vrm1)
|
||||
{
|
||||
AssetVersion = storage.AssetVersion,
|
||||
AssetGenerator = storage.AssetGenerator,
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ namespace VrmLib
|
|||
public static Model CreateFromBvh(BvhNode node)
|
||||
{
|
||||
// add nodes
|
||||
var model = new Model(Coordinates.Gltf);
|
||||
var model = new Model(Coordinates.Vrm1);
|
||||
model.Root.Name = "__bvh_root__";
|
||||
|
||||
AddBvhNodeRecursive(model, model.Root, node);
|
||||
|
|
|
|||
|
|
@ -6,6 +6,83 @@ namespace VrmLib
|
|||
{
|
||||
public static class ModelExtensionsForCoordinates
|
||||
{
|
||||
static void ReverseX(BufferAccessor ba)
|
||||
{
|
||||
if (ba.ComponentType != AccessorValueType.FLOAT)
|
||||
{
|
||||
throw new Exception();
|
||||
}
|
||||
if (ba.AccessorType == AccessorVectorType.VEC3)
|
||||
{
|
||||
var span = SpanLike.Wrap<Vector3>(ba.Bytes);
|
||||
for (int i = 0; i < span.Length; ++i)
|
||||
{
|
||||
span[i] = span[i].ReverseX();
|
||||
}
|
||||
}
|
||||
else if (ba.AccessorType == AccessorVectorType.MAT4)
|
||||
{
|
||||
var span = SpanLike.Wrap<Matrix4x4>(ba.Bytes);
|
||||
for (int i = 0; i < span.Length; ++i)
|
||||
{
|
||||
span[i] = span[i].ReverseX();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
static void ReverseZ(BufferAccessor ba)
|
||||
{
|
||||
if (ba.ComponentType != AccessorValueType.FLOAT)
|
||||
{
|
||||
throw new Exception();
|
||||
}
|
||||
if (ba.AccessorType == AccessorVectorType.VEC3)
|
||||
{
|
||||
var span = SpanLike.Wrap<Vector3>(ba.Bytes);
|
||||
for (int i = 0; i < span.Length; ++i)
|
||||
{
|
||||
span[i] = span[i].ReverseZ();
|
||||
}
|
||||
}
|
||||
else if (ba.AccessorType == AccessorVectorType.MAT4)
|
||||
{
|
||||
var span = SpanLike.Wrap<Matrix4x4>(ba.Bytes);
|
||||
for (int i = 0; i < span.Length; ++i)
|
||||
{
|
||||
span[i] = span[i].ReverseZ();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
struct Reverser
|
||||
{
|
||||
public Action<BufferAccessor> ReverseBuffer;
|
||||
public Func<Vector3, Vector3> ReverseVector3;
|
||||
public Func<Matrix4x4, Matrix4x4> ReverseMatrix;
|
||||
}
|
||||
|
||||
static Reverser ZReverser => new Reverser
|
||||
{
|
||||
ReverseBuffer = ReverseZ,
|
||||
ReverseVector3 = v => v.ReverseZ(),
|
||||
ReverseMatrix = m => m.ReverseZ(),
|
||||
};
|
||||
|
||||
static Reverser XReverser => new Reverser
|
||||
{
|
||||
ReverseBuffer = ReverseX,
|
||||
ReverseVector3 = v => v.ReverseX(),
|
||||
ReverseMatrix = m => m.ReverseX(),
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// ignoreVrm: VRM-0.XX では無変換で入出力してた。VRM-1.0 では変換する。
|
||||
/// </summary>
|
||||
|
|
@ -16,14 +93,24 @@ namespace VrmLib
|
|||
return;
|
||||
}
|
||||
|
||||
if (model.Coordinates.IsGltf && coordinates.IsUnity)
|
||||
if (model.Coordinates.IsVrm0 && coordinates.IsUnity)
|
||||
{
|
||||
model.ReverseZAndFlipTriangle(ignoreVrm);
|
||||
model.ReverseAxisAndFlipTriangle(ZReverser, ignoreVrm);
|
||||
model.UVVerticalFlip();
|
||||
}
|
||||
else if (model.Coordinates.IsUnity && coordinates.IsGltf)
|
||||
else if (model.Coordinates.IsUnity && coordinates.IsVrm0)
|
||||
{
|
||||
model.ReverseZAndFlipTriangle(ignoreVrm);
|
||||
model.ReverseAxisAndFlipTriangle(ZReverser, ignoreVrm);
|
||||
model.UVVerticalFlip();
|
||||
}
|
||||
if (model.Coordinates.IsVrm1 && coordinates.IsUnity)
|
||||
{
|
||||
model.ReverseAxisAndFlipTriangle(XReverser, ignoreVrm);
|
||||
model.UVVerticalFlip();
|
||||
}
|
||||
else if (model.Coordinates.IsUnity && coordinates.IsVrm1)
|
||||
{
|
||||
model.ReverseAxisAndFlipTriangle(XReverser, ignoreVrm);
|
||||
model.UVVerticalFlip();
|
||||
}
|
||||
else
|
||||
|
|
@ -59,7 +146,7 @@ namespace VrmLib
|
|||
/// * Rotation => Axis Angle に分解 => Axis の Z座標に -1 を乗算。Angle に -1 を乗算
|
||||
/// * Triangle の index を 0, 1, 2 から 2, 1, 0 に反転する
|
||||
/// </summary>
|
||||
static void ReverseZAndFlipTriangle(this Model model, bool ignoreVrm)
|
||||
static void ReverseAxisAndFlipTriangle(this Model model, Reverser reverser, bool ignoreVrm)
|
||||
{
|
||||
foreach (var g in model.MeshGroups)
|
||||
{
|
||||
|
|
@ -69,7 +156,7 @@ namespace VrmLib
|
|||
{
|
||||
if (k == VertexBuffer.PositionKey || k == VertexBuffer.NormalKey)
|
||||
{
|
||||
ReverseZ(v);
|
||||
reverser.ReverseBuffer(v);
|
||||
}
|
||||
if (k == VertexBuffer.TangentKey)
|
||||
{
|
||||
|
|
@ -98,7 +185,7 @@ namespace VrmLib
|
|||
{
|
||||
if (k == VertexBuffer.PositionKey || k == VertexBuffer.NormalKey)
|
||||
{
|
||||
ReverseZ(v);
|
||||
reverser.ReverseBuffer(v);
|
||||
}
|
||||
if (k == VertexBuffer.TangentKey)
|
||||
{
|
||||
|
|
@ -113,7 +200,7 @@ namespace VrmLib
|
|||
// Rootは原点決め打ちのノード(GLTFに含まれない)
|
||||
foreach (var n in model.Root.Traverse().Skip(1))
|
||||
{
|
||||
n.SetMatrix(n.Matrix.ReverseZ(), false);
|
||||
n.SetMatrix(reverser.ReverseMatrix(n.Matrix), false);
|
||||
}
|
||||
// 親から順に処理したので不要
|
||||
// model.Root.CalcWorldMatrix();
|
||||
|
|
@ -122,7 +209,7 @@ namespace VrmLib
|
|||
{
|
||||
if (s.InverseMatrices != null)
|
||||
{
|
||||
ReverseZ(s.InverseMatrices);
|
||||
reverser.ReverseBuffer(s.InverseMatrices);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -138,7 +225,7 @@ namespace VrmLib
|
|||
// LookAt
|
||||
if (model.Vrm.LookAt != null)
|
||||
{
|
||||
model.Vrm.LookAt.OffsetFromHeadBone = model.Vrm.LookAt.OffsetFromHeadBone.ReverseZ();
|
||||
model.Vrm.LookAt.OffsetFromHeadBone = reverser.ReverseVector3(model.Vrm.LookAt.OffsetFromHeadBone);
|
||||
}
|
||||
|
||||
// SpringBone
|
||||
|
|
@ -154,11 +241,11 @@ namespace VrmLib
|
|||
switch (s.ColliderType)
|
||||
{
|
||||
case VrmSpringBoneColliderTypes.Sphere:
|
||||
c.Colliders[i] = VrmSpringBoneCollider.CreateSphere(s.Offset.ReverseZ(), s.Radius);
|
||||
c.Colliders[i] = VrmSpringBoneCollider.CreateSphere(reverser.ReverseVector3(s.Offset), s.Radius);
|
||||
break;
|
||||
|
||||
case VrmSpringBoneColliderTypes.Capsule:
|
||||
c.Colliders[i] = VrmSpringBoneCollider.CreateCapsule(s.Offset.ReverseZ(), s.Radius, s.CapsuleTail.ReverseZ());
|
||||
c.Colliders[i] = VrmSpringBoneCollider.CreateCapsule(reverser.ReverseVector3(s.Offset), s.Radius, reverser.ReverseVector3(s.CapsuleTail));
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
@ -169,7 +256,7 @@ namespace VrmLib
|
|||
|
||||
foreach (var j in b.Joints)
|
||||
{
|
||||
j.GravityDir = j.GravityDir.ReverseZ();
|
||||
j.GravityDir = reverser.ReverseVector3(j.GravityDir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -177,34 +264,6 @@ namespace VrmLib
|
|||
}
|
||||
}
|
||||
|
||||
static void ReverseZ(BufferAccessor ba)
|
||||
{
|
||||
if (ba.ComponentType != AccessorValueType.FLOAT)
|
||||
{
|
||||
throw new Exception();
|
||||
}
|
||||
if (ba.AccessorType == AccessorVectorType.VEC3)
|
||||
{
|
||||
var span = SpanLike.Wrap<Vector3>(ba.Bytes);
|
||||
for (int i = 0; i < span.Length; ++i)
|
||||
{
|
||||
span[i] = span[i].ReverseZ();
|
||||
}
|
||||
}
|
||||
else if (ba.AccessorType == AccessorVectorType.MAT4)
|
||||
{
|
||||
var span = SpanLike.Wrap<Matrix4x4>(ba.Bytes);
|
||||
for (int i = 0; i < span.Length; ++i)
|
||||
{
|
||||
span[i] = span[i].ReverseZ();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
static void FlipTriangle(SpanLike<byte> indices)
|
||||
{
|
||||
for (int i = 0; i < indices.Length; i += 3)
|
||||
|
|
|
|||
|
|
@ -36,6 +36,11 @@ namespace VrmLib
|
|||
return new Vector2(src.X, 1.0f - src.Y);
|
||||
}
|
||||
|
||||
public static Vector3 ReverseX(this Vector3 src)
|
||||
{
|
||||
return new Vector3(-src.X, src.Y, src.Z);
|
||||
}
|
||||
|
||||
public static Vector3 ReverseZ(this Vector3 src)
|
||||
{
|
||||
return new Vector3(src.X, src.Y, -src.Z);
|
||||
|
|
@ -51,6 +56,12 @@ namespace VrmLib
|
|||
return (new Vector3((float)x, (float)y, (float)z), (float)angle);
|
||||
}
|
||||
|
||||
public static Quaternion ReverseX(this Quaternion src)
|
||||
{
|
||||
var (axis, angle) = src.GetAxisAngle();
|
||||
return Quaternion.CreateFromAxisAngle(axis.ReverseX(), -angle);
|
||||
}
|
||||
|
||||
public static Quaternion ReverseZ(this Quaternion src)
|
||||
{
|
||||
var (axis, angle) = src.GetAxisAngle();
|
||||
|
|
@ -131,5 +142,21 @@ namespace VrmLib
|
|||
return FromTRS(t.ReverseZ(), r.ReverseZ(), s);
|
||||
}
|
||||
}
|
||||
|
||||
public static Matrix4x4 ReverseX(this Matrix4x4 m)
|
||||
{
|
||||
if (m.IsOnlyTranslation())
|
||||
{
|
||||
var ret = m;
|
||||
ret.M43 = -ret.M43;
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
var (t, r, s) = m.Decompose();
|
||||
return FromTRS(t.ReverseX(), r.ReverseX(), s);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ namespace VrmLibTests
|
|||
[Test]
|
||||
public void ModifierTest()
|
||||
{
|
||||
var model = new Model(Coordinates.Gltf);
|
||||
var model = new Model(Coordinates.Vrm1);
|
||||
var modifier = new ModelModifier(model);
|
||||
|
||||
var node0 = new Node("node0");
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ PlayerSettings:
|
|||
defaultScreenWidthWeb: 960
|
||||
defaultScreenHeightWeb: 600
|
||||
m_StereoRenderingPath: 0
|
||||
m_ActiveColorSpace: 0
|
||||
m_ActiveColorSpace: 1
|
||||
m_MTRendering: 1
|
||||
m_StackTraceTypes: 010000000100000001000000010000000100000001000000
|
||||
iosShowActivityIndicatorOnLoading: -1
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user