public static DsonDocument LoadFromFile(DsonObjectLocator locator, string contentPath, string documentPath) { using (StreamReader reader = File.OpenText(contentPath)) { using (JsonReader jsonReader = new JsonTextReader(reader)) { DsonDocument document = new DsonDocument(locator, documentPath); var serializer = JsonSerializer.CreateDefault(); serializer.Converters.Add(new DsonObjectReferenceConverter(document)); DsonRoot root = serializer.Deserialize <DsonRoot>(jsonReader); document.root = root; return(document); } } }
public void IncludeDuf(DsonTypes.DsonRoot root) { foreach (DsonTypes.Image image in Utils.SafeEnumerable(root.image_library)) { string imagePath = image.map[0].url; if (image.map.Length != 1) { throw new InvalidOperationException("expected only one image per map"); } if (!imagesByUrl.ContainsKey(imagePath)) { imagesByUrl[imagePath] = image; } } foreach (var instance in (root.scene.materials ?? new DsonTypes.MaterialInstance[0])) { DsonTypes.Material material = instance.url.LocateReferencedObject(false); if (material == null) { continue; } if (instance.groups.Length != 1) { throw new Exception("expected exactly 1 group"); } string surfaceName = instance.groups[0]; var bag = MakeBag(surfaceName); bag.SetValue("uv_set", material.uv_set); bag.SetValue("uv_set", instance.uv_set); IncludeMaterialChannel(bag, "", material.diffuse?.channel); IncludeMaterialChannel(bag, "", instance.diffuse?.channel); foreach (var extra in Utils.SafeEnumerable(material.extra)) { string type = extra.type; bag.AddExtraType(type); foreach (var channel in Utils.SafeArray(extra.channels)) { IncludeMaterialChannel(bag, $"extra/{type}/channels/", channel.channel); } } foreach (var extra in Utils.SafeEnumerable(instance.extra)) { string type = extra.type; bag.AddExtraType(type); foreach (var channel in Utils.SafeArray(extra.channels)) { IncludeMaterialChannel(bag, $"extra/{type}/channels/", channel.channel); } } } foreach (DsonTypes.ChannelAnimation animation in (root.scene.animations ?? new DsonTypes.ChannelAnimation[0])) { string url = animation.url; url = url.Substring(url.IndexOf('#') + 1); string expectedPrefix = "materials/"; if (!url.StartsWith(expectedPrefix)) { continue; } url = url.Substring(expectedPrefix.Length); string materialNameSeparator = ":?"; int materialNameSeparatorIdx = url.IndexOf(materialNameSeparator); if (materialNameSeparatorIdx == -1) { continue; } string materialName = Uri.UnescapeDataString(url.Substring(0, materialNameSeparatorIdx)); url = url.Substring(materialNameSeparatorIdx + materialNameSeparator.Length); var bag = MakeBag(materialName); object value = animation.keys[0][1]; if (url.EndsWith("/image") && value == null) { // Setting ".../image" to null causes all image-related settings to be cleared // This comes up with Sorbet Swimsuit Style 4, which has no image (just a solid color) for the bra bag.RemoveByUrl(url + "_file"); } else { bag.SetByUrl(url, value); } } }