Last active
May 5, 2020 01:37
-
-
Save cdiggins/7ff0db8ead17ca3df5c6ff59bb50b686 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.IO; | |
using System.Linq; | |
using UnityEngine; | |
public static class VimApi | |
{ | |
/// <summary> | |
/// Represents a node in a VIM scene and provides access to useful information about the object associated with that node. | |
/// </summary> | |
public class VimNode | |
{ | |
public VimDocument Document { get; } | |
public string CategoryName { get; } | |
public string FamilyName { get; } | |
public string ElementName { get; } | |
public string SourceFileName { get; } | |
public string Room { get; } | |
public string Level { get; } | |
public List<string> MaterialNames { get; } | |
} | |
/// <summary> | |
/// Represents a collection of VIM nodes, and provides a wrapper around the VIM document. | |
/// </summary> | |
public class VimDocument | |
{ | |
public IReadOnlyList<VimNode> Nodes { get; } | |
public string RootSourceFileName { get; } | |
} | |
/// <summary> | |
/// A simple progress reporting interface with supporting utility functions and default implementations. | |
/// The numerical value may be in the 0..1 range to represent percentage, or some other custom range (e.g number of bytes). | |
/// The progress implementation may be connected to a progress bar, or logging mechanism. | |
/// </summary> | |
public interface IProgress | |
{ | |
void Report(decimal x); | |
} | |
/// <summary> | |
/// The different types of log messages | |
/// </summary> | |
public enum LogEnum | |
{ | |
Error = 0, | |
Assert = 1, | |
Warning = 2, | |
Log = 3, | |
Exception = 4 | |
} | |
/// <summary> | |
/// A simple logging interface with supporting utility functions and default implementations. | |
/// </summary> | |
public interface ILogger | |
{ | |
void Log(string msg, LogEnum type = LogEnum.Log); | |
} | |
/// <summary> | |
/// Combines a Cancelation event obersver (CancellationToken) and a cancelation requester (CancelTokenSource). | |
/// Intentionally merging two very closely related concerns that rarely have advantage in being separated. | |
/// https://stackoverflow.com/questions/14215784/why-cancellationtoken-is-separate-from-cancellationtokensource | |
/// https://docs.microsoft.com/en-us/dotnet/api/system.threading.cancellationtoken?view=netstandard-2.1 | |
/// https://docs.microsoft.com/en-us/dotnet/api/system.threading.cancellationtokensource?view=netstandard-2.1 | |
/// </summary> | |
public interface ICancelable | |
{ | |
bool IsCancelRequested(); | |
void Cancel(); | |
} | |
/// <summary> | |
/// For convenience this combines the chores of allowing long taks to be cancelled, to report progress, | |
/// and to log status. See the Helper class for a function that will generate a default logger. | |
/// </summary> | |
public interface ICancelableProgressLogger : ICancelable, ILogger, IProgress | |
{ } | |
/// <summary> | |
/// A class containing the different configuration options for driving the VIM loader | |
/// </summary> | |
public class LoadVimOptions | |
{ | |
public bool LoadTextures = false; | |
} | |
/// <summary> | |
/// Loads a VIM document into memory from a string file path or URI. | |
/// </summary> | |
public static async VimDocument LoadVim( | |
string filePathOrUri, | |
LoadVimOptions options = null, | |
ICancelableProgressLogger logger = null) | |
{ | |
throw new NotImplementedException(); | |
} | |
/// <summary> | |
/// Loads a VIM document into memory from a stream. The stream must support reading of the `Position` | |
/// property, which means that it does not work with NetworkStream. In this case you can copy to | |
/// a MemoryStream https://stackoverflow.com/a/11749081/184528 or save it to file first. | |
/// </summary> | |
public static async VimDocument LoadVim( | |
Stream stream, | |
LoadVimOptions options = null, | |
ICancelableProgressLogger logger = null) | |
{ | |
throw new NotImplementedException(); | |
} | |
/// <summary> | |
/// A group of settings for creating game objects | |
/// </summary> | |
public class CreateGameObjectOptions | |
{ | |
public bool CreateColliders = false; | |
public bool CreateCameras = false; | |
} | |
/// <summary> | |
/// Creates or more Unity game objects from a VIM scene. | |
/// The behavior is configured via functions, that can be omitted, in which reasonable defaults are provided. | |
/// Game objects may be created from a custom mapping of VIM nodes to object (e.g. all to one, many to one, one to one). | |
/// The groupKeySelector is used to select a string from the VimNode that will be used for grouping purposes. | |
/// This is similar in design to `Enumerable.GroupBy`. | |
/// This function will yield GameObjects as they are created to be consumed by the client. | |
/// Each GameObject will have a MeshFilter, a MeshRenderer, and add an initialized VimComponent | |
/// to each object. The parent will be the first class returned. | |
/// See the Helpers class for functions which make it easier to create a groupKeySlector. | |
/// In the future this will support mesh splitting options. | |
/// </summary> | |
public static async IEnumerable<GameObject> CreateGameObjects( | |
this VimDocument vim, | |
CreateGameObjectOptions options = null, | |
GameObject parent = null, | |
Func<VimNode, string> groupKeySelector = null, | |
Func<VimNode, IReadOnlyList<Material>> materialSelector = null, | |
ICancelableProgressLogger logger = null) | |
{ | |
throw new NotImplementedException(); | |
} | |
/// <summary> | |
/// By default this class is added to every game object and it provides acces to the Vim nodes | |
/// Basically it is a collection of nodes, all from the same document. | |
/// It will eventually provide a number of utility functions | |
/// </summary> | |
public class VimNodeComponent : MonoBehaviour | |
{ | |
public IReadOnlyList<VimNode> Nodes { get; set; } | |
public VimDocumentComponent DocumentComponent { get; set; } | |
} | |
/// <summary> | |
/// This class is added to the root node of the Vim hierarchy and provides access to the document. | |
/// </summary> | |
public class VimDocumentComponent : MonoBehaviour | |
{ | |
public VimDocument Document { get; set; } | |
public IEnumerable<VimNodeComponent> NodeComponents | |
=> FindObjectsOfType<VimNodeComponent>().Where(x => x.DocumentComponent == this); | |
} | |
/// <summary> | |
/// This class is returned after a hit test is performed on a VIM document | |
/// </summary> | |
public class HitTestInfo | |
{ | |
public VimNode Node; | |
public int FaceId; | |
public float Distance; | |
public Vector2 UV; | |
public Vector3 NormalAtHit; | |
public Vector3 LocationInWorldSpace; | |
} | |
/// <summary> | |
/// Given X, Y screen coordinates and an optional camera, computes a hit test on the VIM document. | |
/// Returning null if failing. | |
/// </summary> | |
public static HitTestInfo HitTest(VimDocument doc, int x, int y, Camera camera = null) | |
{ | |
throw new NotImplementedException(); | |
} | |
/// <summary> | |
/// Given a ray in world space and an optional camera, computes a hit test on the VIM document. | |
/// Returning null if failing. | |
/// </summary> | |
public static HitTestInfo HitTest(VimDocument doc, Ray ray, Camera camera = null) | |
{ | |
throw new NotImplementedException(); | |
} | |
/// <summary> | |
/// These are helper functions provided with the API that facilitate using it. | |
/// </summary> | |
public static class Helpers | |
{ | |
/// <summary> | |
/// Default implementation of a cancelable progress logger. This will | |
/// return a version appropriate for use in the editor and the run-time | |
/// with slightly different characteristics. | |
/// </summary> | |
public static ICancelableProgressLogger CreateCancelableProgressLogger() | |
{ | |
throw new NotImplementedException(); | |
} | |
#region Helper functions for creating key grouping functions | |
public static Func<VimNode, string> GroupByCategorySelector() | |
=> x => x?.CategoryName ?? "no category"; | |
public static Func<VimNode, string> GroupAllSelector() | |
=> x => ""; | |
public static Func<VimNode, string> GroupByElementSelector() | |
=> x => x?.ElementName; | |
public static Func<VimNode, string> GroupByFamilySelector() | |
=> x => x?.FamilyName ?? "no family"; | |
public static Func<VimNode, string> GroupByFirstMaterialSelector() | |
=> x => (x?.MaterialNames?.Count ?? 0) > 0 ? x.MaterialNames[0] : "no material"; | |
public static Func<VimNode, string> GroupNoneSelector() | |
=> null; | |
#endregion | |
/// <summary> | |
/// This will return a simple object factory that may or may not create mesh colliders, | |
/// </summary> | |
public static Func<VimNode, IReadOnlyList<Material>> DefaultMaterialSelector(IDictionary<string, Material> createdMaterials) | |
{ | |
throw new NotImplementedException(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment