static bool ListDiff <T>(ModelDiffContext context, List <T> lhs, List <T> rhs, Func <ModelDiffContext, T, T, bool> pred, Func <T, int> order = null) { var equals = true; if (lhs.Count != rhs.Count) { equals = false; context.List.Add(new ModelDiff { Context = context.Path, Message = $"{lhs.Count} != {rhs.Count}", }); } var l = order != null?lhs.OrderBy(order).GetEnumerator() : lhs.GetEnumerator(); var r = order != null?rhs.OrderBy(order).GetEnumerator() : rhs.GetEnumerator(); for (int i = 0; i < lhs.Count; ++i) { l.MoveNext(); r.MoveNext(); if (!pred(context.Enter($"{i}"), l.Current, r.Current)) { equals = false; } } return(equals); }
static bool Vector3NearlyEquals(ModelDiffContext _, Vector3 l, Vector3 r) { if (Math.Abs(l.X - r.X) > EPSILON) { return(false); } if (Math.Abs(l.Y - r.Y) > EPSILON) { return(false); } if (Math.Abs(l.Z - r.Z) > EPSILON) { return(false); } return(true); }
static bool TextureInfoEquals(ModelDiffContext context, TextureInfo lhs, TextureInfo rhs) { if (!context.RequireComapre(lhs, rhs, out bool equals)) { return(equals); } if (lhs.Offset != rhs.Offset) { return(false); } if (lhs.Scaling != rhs.Scaling) { return(false); } return(TextureEquals(context.Enter("Texture"), lhs.Texture, rhs.Texture)); }
/// <summary> /// 違うところを集める(debug用) /// </summary> public static List <ModelDiff> Diff(this Model lhs, Model rhs) { var context = ModelDiffContext.Create(); context.Enter(nameof(lhs.AssetGenerator)).Push(lhs.AssetGenerator, rhs.AssetGenerator, StringEquals); context.Enter(nameof(lhs.AssetVersion)).Push(lhs.AssetVersion, rhs.AssetVersion, StringEquals); context.Enter(nameof(lhs.AssetMinVersion)).Push(lhs.AssetMinVersion, rhs.AssetMinVersion, StringEquals); context.Enter(nameof(lhs.AssetCopyright)).Push(lhs.AssetCopyright, rhs.AssetCopyright, StringEquals); // Materialの参照で比較する ListDiff(context.Enter("Materials"), lhs.Materials, rhs.Materials, MaterialEquals); ListDiff(context.Enter("Meshes"), lhs.MeshGroups, rhs.MeshGroups, MeshGroupEquals); ListDiff(context.Enter("Nodes"), lhs.Nodes, rhs.Nodes, NodeEquals); ListDiff(context.Enter("Skins"), lhs.Skins, rhs.Skins, SkinEquals); Vrm(context.Enter("Vrm"), lhs, rhs); return(context.List); }
static bool StringEquals(ModelDiffContext _, string l, string r) { if (string.IsNullOrEmpty(l)) { return(string.IsNullOrEmpty(r)); } else { if (string.IsNullOrEmpty(r)) { return(false); } else { return(l == r); } } }
static bool ImageBytesEquals(ModelDiffContext context, Image lhs, Image rhs) { if (lhs is null) { if (rhs is null) { return(true); } else { return(false); } } if (rhs is null) { return(false); } return(lhs.Bytes.SequenceEqual(rhs.Bytes)); }
static bool QuaternionNearlyEquals(ModelDiffContext _, Quaternion l, Quaternion r) { if (Math.Abs(l.X - r.X) > EPSILON) { return(false); } if (Math.Abs(l.Y - r.Y) > EPSILON) { return(false); } if (Math.Abs(l.Z - r.Z) > EPSILON) { return(false); } if (Math.Abs(l.W - r.W) > EPSILON) { return(false); } return(true); }
static bool TextureEquals(ModelDiffContext context, Texture lhs, Texture rhs) { if (!context.RequireComapre(lhs, rhs, out bool equals)) { if (!equals) { return(false); } return(true); } equals = true; if (!context.Enter("Name").Push(lhs.Name, rhs.Name, StringEquals)) { equals = false; } if (!context.Enter("MagFilter").Push(lhs.Sampler.MagFilter, rhs.Sampler.MagFilter)) { equals = false; } if (!context.Enter("MinFilter").Push(lhs.Sampler.MinFilter, rhs.Sampler.MinFilter)) { equals = false; } if (!context.Enter("WrapS").Push(lhs.Sampler.WrapS, rhs.Sampler.WrapS)) { equals = false; } if (!context.Enter("WrapT").Push(lhs.Sampler.WrapT, rhs.Sampler.WrapT)) { equals = false; } if (lhs is ImageTexture l && rhs is ImageTexture r) { if (!ImageBytesEquals(context, l.Image, r.Image)) { equals = false; } return(equals); }
static void Image(ModelDiffContext context, Image lhs, Image rhs) { context.Enter($"{lhs.Name}:{rhs.Name}").Push(lhs, rhs, ImageBytesEquals); }
static bool ImageBytesEquals(ModelDiffContext context, Image lhs, Image rhs) { return(lhs.Bytes.Span.SequenceEqual(rhs.Bytes.Span)); }