/// <summary> /// * Position, Normal の Z座標に -1 を乗算する /// * Rotation => Axis Angle に分解 => Axis の Z座標に -1 を乗算。Angle に -1 を乗算 /// * Triangle の index を 0, 1, 2 から 2, 1, 0 に反転する /// </summary> static void ReverseAxisAndFlipTriangle(this Model model, Reverser reverser, bool ignoreVrm) { foreach (var g in model.MeshGroups) { foreach (var m in g.Meshes) { foreach (var(k, v) in m.VertexBuffer) { if (k == VertexBuffer.PositionKey || k == VertexBuffer.NormalKey) { reverser.ReverseBuffer(v); } else if (k == VertexBuffer.TangentKey) { // I don't know } } switch (m.IndexBuffer.ComponentType) { case AccessorValueType.UNSIGNED_BYTE: FlipTriangle(SpanLike.Wrap <Byte>(m.IndexBuffer.Bytes)); break; case AccessorValueType.UNSIGNED_SHORT: FlipTriangle(SpanLike.Wrap <UInt16>(m.IndexBuffer.Bytes)); break; case AccessorValueType.UNSIGNED_INT: FlipTriangle(SpanLike.Wrap <UInt32>(m.IndexBuffer.Bytes)); break; default: throw new NotImplementedException(); } foreach (var mt in m.MorphTargets) { foreach (var(k, v) in mt.VertexBuffer) { if (k == VertexBuffer.PositionKey || k == VertexBuffer.NormalKey) { reverser.ReverseBuffer(v); } if (k == VertexBuffer.TangentKey) { // I don't know } } } } } // 親から順に処理する // Rootは原点決め打ちのノード(GLTFに含まれない) foreach (var n in model.Root.Traverse().Skip(1)) { n.SetMatrix(reverser.ReverseMatrix(n.Matrix), false); } // 親から順に処理したので不要 // model.Root.CalcWorldMatrix(); foreach (var s in model.Skins) { if (s.InverseMatrices != null) { reverser.ReverseBuffer(s.InverseMatrices); } } foreach (var a in model.Animations) { // TODO: } if (model.Vrm != null) { if (!ignoreVrm) { // LookAt if (model.Vrm.LookAt != null) { model.Vrm.LookAt.OffsetFromHeadBone = reverser.ReverseVector3(model.Vrm.LookAt.OffsetFromHeadBone); } // SpringBone if (model.Vrm.SpringBone != null) { foreach (var b in model.Vrm.SpringBone.Springs) { foreach (var c in b.Colliders) { for (int i = 0; i < c.Colliders.Count; ++i) { var s = c.Colliders[i]; switch (s.ColliderType) { case VrmSpringBoneColliderTypes.Sphere: c.Colliders[i] = VrmSpringBoneCollider.CreateSphere(reverser.ReverseVector3(s.Offset), s.Radius); break; case VrmSpringBoneColliderTypes.Capsule: c.Colliders[i] = VrmSpringBoneCollider.CreateCapsule(reverser.ReverseVector3(s.Offset), s.Radius, reverser.ReverseVector3(s.CapsuleTail)); break; default: throw new NotImplementedException(); } } } foreach (var j in b.Joints) { j.GravityDir = reverser.ReverseVector3(j.GravityDir); } } } } } }