public static void Save(Model3DAttachment attachment, string path) { var attachmentPath = path + ".Attachment.txt"; Serialization.WriteObjectToFile(attachmentPath, CreateFromModel3DAttachment(attachment), Serialization.Format.JSON); }
private static ModelAttachmentFormat CreateFromModel3DAttachment(Model3DAttachment attachment) { var origin = new ModelAttachmentFormat(); origin.ScaleFactor = attachment.ScaleFactor; if (attachment.MeshOptions.Count > 0) { origin.MeshOptions = new Dictionary <string, MeshOptionFormat>(); } if (attachment.Animations.Count > 0) { origin.Animations = new Dictionary <string, ModelAnimationFormat>(); } if (attachment.MaterialEffects.Count > 0) { origin.MaterialEffects = new Dictionary <string, ModelMaterialEffectFormat>(); } foreach (var meshOption in attachment.MeshOptions) { var meshOptionFormat = new MeshOptionFormat { HitTestTarget = meshOption.HitTestTarget, }; switch (meshOption.CullMode) { case CullMode.None: meshOptionFormat.CullMode = "None"; break; case CullMode.CullClockwise: meshOptionFormat.CullMode = "CullClockwise"; break; case CullMode.CullCounterClockwise: meshOptionFormat.CullMode = "CullCounterClockwise"; break; } origin.MeshOptions.Add(meshOption.Id, meshOptionFormat); } foreach (var animation in attachment.Animations) { var animationFormat = new ModelAnimationFormat { Markers = new Dictionary <string, ModelMarkerFormat>(), }; foreach (var markerData in animation.Markers) { var markerFormat = new ModelMarkerFormat { Frame = markerData.Marker.Frame }; switch (markerData.Marker.Action) { case MarkerAction.Play: markerFormat.Action = "Start"; break; case MarkerAction.Stop: markerFormat.Action = "Stop"; break; case MarkerAction.Jump: markerFormat.Action = "Jump"; markerFormat.JumpTarget = markerData.Marker.JumpTo; break; } if (animation.MarkersBlendings.Count > 0) { markerFormat.SourceMarkersBlending = new Dictionary <string, int>(); foreach (var markerBlending in animation.MarkersBlendings.Where(m => m.DestMarkerId == markerData.Marker.Id)) { markerFormat.SourceMarkersBlending.Add(markerBlending.SourceMarkerId, (int)markerBlending.Blending.DurationInFrames); } } if (markerData.Blending != null) { markerFormat.Blending = (int)markerData.Blending.DurationInFrames; } animationFormat.Markers.Add(markerData.Marker.Id, markerFormat); } if (animation.Blending != null) { animationFormat.Blending = (int)animation.Blending.DurationInFrames; } if (animation.Nodes.Count > 0) { animationFormat.Nodes = animation.Nodes.Count > 0 ? animation.Nodes.Select(n => n.Id).ToList() : null; } else if (animation.IgnoredNodes.Count > 0) { animationFormat.IgnoredNodes = animation.IgnoredNodes.Select(n => n.Id).ToList(); } origin.Animations.Add(animation.Name, animationFormat); } foreach (var materialEffect in attachment.MaterialEffects) { var name = materialEffect.Path.Split('/'); var materialEffectFormat = new ModelMaterialEffectFormat { Path = name.Last(), MaterialName = materialEffect.Name, }; if (materialEffect.Blending != null) { materialEffectFormat.Blending = (int)materialEffect.Blending.Duration; } origin.MaterialEffects.Add(materialEffect.Name, materialEffectFormat); } return(origin); }
public Model3DAttachment Parse(string modelPath, bool useBundle = true) { modelPath = AssetPath.CorrectSlashes( Path.Combine(Path.GetDirectoryName(modelPath) ?? "", Path.GetFileNameWithoutExtension(AssetPath.CorrectSlashes(modelPath) ?? "") )); var attachmentPath = modelPath + Model3DAttachment.FileExtension; try { ModelAttachmentFormat modelAttachmentFormat; if (useBundle) { if (!AssetBundle.Current.FileExists(attachmentPath)) { return(null); } modelAttachmentFormat = Serialization.ReadObject <ModelAttachmentFormat>(attachmentPath); } else { if (!File.Exists(attachmentPath)) { return(null); } modelAttachmentFormat = Serialization.ReadObjectFromFile <ModelAttachmentFormat>(attachmentPath); } var attachment = new Model3DAttachment { ScaleFactor = modelAttachmentFormat.ScaleFactor }; if (modelAttachmentFormat.MeshOptions != null) { foreach (var meshOptionFormat in modelAttachmentFormat.MeshOptions) { var meshOption = new Model3DAttachment.MeshOption() { Id = meshOptionFormat.Key, HitTestTarget = meshOptionFormat.Value.HitTestTarget }; if (!string.IsNullOrEmpty(meshOptionFormat.Value.CullMode)) { switch (meshOptionFormat.Value.CullMode) { case "None": meshOption.CullMode = CullMode.None; break; case "CullClockwise": meshOption.CullMode = CullMode.CullClockwise; break; case "CullCounterClockwise": meshOption.CullMode = CullMode.CullCounterClockwise; break; } } attachment.MeshOptions.Add(meshOption); } } if (modelAttachmentFormat.Animations != null) { foreach (var animationFormat in modelAttachmentFormat.Animations) { var animation = new Model3DAttachment.Animation { Name = animationFormat.Key, }; if (animationFormat.Value.Markers != null) { foreach (var markerFormat in animationFormat.Value.Markers) { var markerData = new Model3DAttachment.MarkerData { Marker = new Marker { Id = markerFormat.Key, Frame = FixFrame(markerFormat.Value.Frame) } }; if (!string.IsNullOrEmpty(markerFormat.Value.Action)) { switch (markerFormat.Value.Action) { case "Start": markerData.Marker.Action = MarkerAction.Play; break; case "Stop": markerData.Marker.Action = MarkerAction.Stop; break; case "Jump": markerData.Marker.Action = MarkerAction.Jump; markerData.Marker.JumpTo = markerFormat.Value.JumpTarget; break; } } if (markerFormat.Value.Blending != null) { markerData.Blending = new BlendingOption((int)markerFormat.Value.Blending); } if (markerFormat.Value.SourceMarkersBlending != null) { foreach (var elem in markerFormat.Value.SourceMarkersBlending) { animation.MarkersBlendings.Add(new Model3DAttachment.MarkerBlendingData { DestMarkerId = markerFormat.Key, SourceMarkerId = elem.Key, Blending = new BlendingOption(elem.Value), }); } } animation.Markers.Add(markerData); } } if (animationFormat.Value.Blending != null) { animation.Blending = new BlendingOption((int)animationFormat.Value.Blending); } if (animationFormat.Value.Nodes != null) { animation.Nodes = new ObservableCollection <Model3DAttachment.NodeData>( animationFormat.Value.Nodes.Select(n => new Model3DAttachment.NodeData { Id = n })); } if (animationFormat.Value.IgnoredNodes != null && animationFormat.Value.IgnoredNodes.Count > 0) { if (animation.Nodes.Count > 0) { throw new Exception("Conflict between 'Nodes' and 'IgnoredNodes' in animation '{0}", animation.Name); } animation.IgnoredNodes = new ObservableCollection <Model3DAttachment.NodeData>( animationFormat.Value.IgnoredNodes.Select(n => new Model3DAttachment.NodeData { Id = n })); } attachment.Animations.Add(animation); } } if (modelAttachmentFormat.MaterialEffects != null) { foreach (var materialEffectFormat in modelAttachmentFormat.MaterialEffects) { var materialEffect = new Model3DAttachment.MaterialEffect() { Name = materialEffectFormat.Key, MaterialName = materialEffectFormat.Value.MaterialName, Path = FixPath(modelPath, materialEffectFormat.Value.Path) }; if (materialEffectFormat.Value.Blending != null) { materialEffect.Blending = new BlendingOption((int)materialEffectFormat.Value.Blending); } attachment.MaterialEffects.Add(materialEffect); } } return(attachment); } catch (System.Exception e) { throw new System.Exception(modelPath + ": " + e.Message, e); } }