/// <summary> /// Returns the string representation of an object. /// </summary> /// <param name="obj"></param> /// <returns></returns> static string ToString(object obj) { if (obj == null) { return("null"); } Type type = obj.GetType(); if (obj is float f) { return(ScenePropertyConverter.ToSceneProperty(f)); } if (obj is bool b) { return(ScenePropertyConverter.ToSceneProperty(b)); } if (obj is Vector2 vec2) { return(ScenePropertyConverter.ToSceneProperty(vec2)); } if (obj is Vector3 vec3) { return(ScenePropertyConverter.ToSceneProperty(vec3)); } if (obj is Vector4 vec4) { return(ScenePropertyConverter.ToSceneProperty(vec4)); } if (obj is Quaternion quaternion) { return(ScenePropertyConverter.ToSceneProperty(quaternion)); } if (obj is Matrix4 matrix) { return(ScenePropertyConverter.ToSceneProperty(matrix)); } if (obj is ISceneObject sceneObject) { return("o" + sceneObject.Id); } if (obj is ISceneResource sceneResource) { return("r" + sceneResource.Id); } return(obj.ToString()); }
/// <summary> /// Loads a scene file. /// </summary> /// <param name="path"></param> public static void Load(string path) { sceneResources = new List <ISceneResource>(); sceneObjects = new List <ISceneObject>(); string[] raw = File.ReadAllLines(path); string[] res = raw.Where(line => line[0] == 'r').ToArray(); string[] objs = raw.Where(line => line[0] == 'o').ToArray(); for (int i = 0; i < res.Length; i++) { string[] tokens = res[i].Split(' '); Type resType = Type.GetType(tokens[2]); if (resType == typeof(Mesh)) { Mesh mesh = Mesh.Load(tokens[3]); sceneResources.Add(mesh); } else if (resType == typeof(Texture)) { Texture texture = Texture.LoadFromFile(tokens[3], (TextureFilteringMode)Enum.Parse(typeof(TextureFilteringMode), tokens[4])); sceneResources.Add(texture); } else if (resType == typeof(Shader)) { Shader shader = new Shader(tokens[3], (ShaderType)Enum.Parse(typeof(ShaderType), tokens[4])); sceneResources.Add(shader); } } for (int i = 0; i < objs.Length; i++) { string[] tokens = objs[i].Split(' '); Type objType = Type.GetType(tokens[2]); object obj = Activator.CreateInstance(objType); sceneObjects.Add((ISceneObject)obj); } //Interpret file ISceneObject currentSceneObject = null; for (int i = 0; i < raw.Length; i++) { string[] tokens = raw[i].Split(' '); switch (tokens[0]) { default: break; //Set object case "o": { int id = int.Parse(tokens[1]); currentSceneObject = sceneObjects[id]; } break; //Set field case "f": { if (tokens[1] != "e") { FieldInfo field = currentSceneObject.GetType().GetField(tokens[1], BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); object value = GetFieldOrPropertyValue(tokens); field.SetValue(currentSceneObject, value); } else { FieldInfo field = currentSceneObject.GetType().GetField(tokens[2], BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); IList list = (IList)field.GetValue(currentSceneObject); object value = GetFieldOrPropertyValue(tokens, true); list.Add(value); field.SetValue(currentSceneObject, list); } } break; //Set property case "p": { if (tokens[1] != "e") { PropertyInfo property = currentSceneObject.GetType().GetProperty(tokens[1], BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); object value = GetFieldOrPropertyValue(tokens); property.SetValue(currentSceneObject, value); } else { PropertyInfo property = currentSceneObject.GetType().GetProperty(tokens[2], BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); IList list = (IList)property.GetValue(currentSceneObject); object value = GetFieldOrPropertyValue(tokens, true); list.Add(value); property.SetValue(currentSceneObject, list); } } break; } } //Finalize foreach (ISceneObject obj in sceneObjects) { if (obj is GameObject gameObject) { foreach (Component component in gameObject.components) { component.Start(); } GameObject.Add(gameObject); } if (obj is Drawable drawable) { foreach (Shader shader in drawable.usedShaders) { drawable.AddShaderAfterLoad(shader); } drawable.Finish(); } } object GetFieldOrPropertyValue(string[] tokens, bool element = false) { object value = null; int idAdd = 0; if (element) { idAdd = 1; } switch (tokens[2 + idAdd][0]) { default: { value = ScenePropertyConverter.FromSceneProperty(tokens[2 + idAdd]); } break; case 'o': { int id = int.Parse(tokens[2 + idAdd].Substring(1)); value = sceneObjects[id]; } break; case 'r': { int id = int.Parse(tokens[2 + idAdd].Substring(1)); value = sceneResources[id]; } break; } return(value); } }