private static void ConvertAssimpMetadataToProperties(Ai.Metadata metadata, Node node) { foreach (var metadataEntry in metadata) { UserProperty property = null; // Skip some garbage entries if (metadataEntry.Key == "IsNull" || metadataEntry.Key == "InheritType" || metadataEntry.Key == "DefaultAttributeIndex" || metadataEntry.Key == "UserProperties" || // dupe of UDP3DSMAX metadataEntry.Key == "MaxHandle") { continue; } if (metadataEntry.Key == "UDP3DSMAX") { var properties = (( string )metadataEntry.Value.Data) .Split(new[] { "&cr;&lf;", "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries); if (properties.Length == 0) { continue; } foreach (var propertyString in properties) { // Parse property string KeyValuePair <string, string> kvp; if (propertyString.Contains('=')) { var split = propertyString.Split('='); kvp = new KeyValuePair <string, string>(split[0].TrimEnd(), split[1].TrimStart()); } else { var split = propertyString.Split(' '); kvp = new KeyValuePair <string, string>(split[0], split.Length > 1 ? split[1] : null); } // Parse value if (kvp.Value == null) { // Assume flag bool property = new UserBoolProperty(kvp.Key, true); } else if (kvp.Value.StartsWith("[") && kvp.Value.EndsWith("]")) { // Array/Vector var arrayContents = kvp.Value.Substring(1, kvp.Value.Length - 2); var arrayValues = arrayContents.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); var arrayFloatValues = new List <float>(); foreach (var arrayValue in arrayValues) { if (!float.TryParse(arrayValue, out var arrayFloatValue)) { throw new Exception($"Failed to parse array user property value as float: {arrayValue}"); } arrayFloatValues.Add(arrayFloatValue); } if (arrayFloatValues.Count == 3) { property = new UserVector3Property(kvp.Key, new Vector3(arrayFloatValues[0], arrayFloatValues[1], arrayFloatValues[2])); } else if (arrayFloatValues.Count == 4) { property = new UserVector4Property(kvp.Key, new Vector4(arrayFloatValues[0], arrayFloatValues[1], arrayFloatValues[2], arrayFloatValues[3])); } else { var arrayByteValues = arrayFloatValues.Cast <byte>(); property = new UserByteArrayProperty(kvp.Key, arrayByteValues.ToArray()); } } else if (int.TryParse(kvp.Value, out int intValue)) { property = new UserIntProperty(kvp.Key, intValue); } else if (float.TryParse(kvp.Value, out float floatValue)) { property = new UserFloatProperty(kvp.Key, floatValue); } else if (bool.TryParse(kvp.Value, out bool boolValue)) { property = new UserBoolProperty(kvp.Key, boolValue); } else { property = new UserStringProperty(kvp.Key, kvp.Value); } } } else { switch (metadataEntry.Value.DataType) { case Ai.MetaDataType.Bool: property = new UserBoolProperty(metadataEntry.Key, metadataEntry.Value.DataAs <bool>().Value); break; case Ai.MetaDataType.Int32: property = new UserIntProperty(metadataEntry.Key, metadataEntry.Value.DataAs <int>().Value); break; case Ai.MetaDataType.UInt64: property = new UserByteArrayProperty(metadataEntry.Key, BitConverter.GetBytes(metadataEntry.Value.DataAs <ulong>().Value)); break; case Ai.MetaDataType.Float: property = new UserFloatProperty(metadataEntry.Key, metadataEntry.Value.DataAs <float>().Value); break; case Ai.MetaDataType.String: property = new UserStringProperty(metadataEntry.Key, ( string )metadataEntry.Value.Data); break; case Ai.MetaDataType.Vector3D: var data = metadataEntry.Value.DataAs <Ai.Vector3D>().Value; property = new UserVector3Property(metadataEntry.Key, new Vector3(data.X, data.Y, data.Z)); break; default: throw new ArgumentOutOfRangeException(); } } if (property == null) { throw new Exception("Property shouldn't be null"); } node.Properties.Add(property.Name, property); } }