public TextureMetadataCollection(DestinationFolder urhoDataFolder) { var allMaterials = AssetDatabase.FindAssets("").Select(_ => AssetContext.Create(_, urhoDataFolder)) .Where(_ => _.Type == typeof(Material)); foreach (var asset in allMaterials) { var material = AssetDatabase.LoadAssetAtPath <Material>(asset.AssetPath); var description = new MaterialDescription(material); if (description.MetallicRoughness != null) { var metallicRoughness = description.MetallicRoughness; if (metallicRoughness.MetallicGloss != null) { var meta = AddTexture(metallicRoughness.MetallicGloss, new TextureReferences( TextureSemantic.PBRMetallicGlossiness, 1.0f, metallicRoughness.SmoothnessTextureChannel == SmoothnessTextureChannel.MetallicOrSpecularAlpha ? metallicRoughness.MetallicGloss : metallicRoughness.BaseColor, metallicRoughness.SmoothnessTextureChannel)); } AddTexture(metallicRoughness.BaseColor, new TextureReferences(TextureSemantic.PBRBaseColor)); AddTexture(metallicRoughness.DetailBaseColor, new TextureReferences(TextureSemantic.MainTextureDetail)); } else if (description.SpecularGlossiness != null) { var specularGlossiness = description.SpecularGlossiness; if (specularGlossiness.PBRSpecular != null) { AddTexture(specularGlossiness.PBRSpecular, new TextureReferences( TextureSemantic.PBRSpecularGlossiness, 1.0f, specularGlossiness.Diffuse, specularGlossiness.SmoothnessTextureChannel)); AddTexture(specularGlossiness.Diffuse, new TextureReferences(TextureSemantic.PBRDiffuse, 1.0f, specularGlossiness.PBRSpecular, specularGlossiness.SmoothnessTextureChannel)); } else { AddTexture(specularGlossiness.Diffuse, new TextureReferences(TextureSemantic.PBRDiffuse, 1.0f, specularGlossiness.PBRSpecular, specularGlossiness.SmoothnessTextureChannel)); } AddTexture(specularGlossiness.DetailDiffuse, new TextureReferences(TextureSemantic.MainTextureDetail)); } else { var legacy = description.Legacy; AddTexture(legacy.Diffuse, new TextureReferences(TextureSemantic.MainTexture)); AddTexture(legacy.Specular, new TextureReferences(TextureSemantic.Specular)); AddCommonTextures(legacy); } } }
private static (float min, float max, Vector2 size) WriteHeightMap(AssetContext asset, string heightmapFileName, Terrain terrain) { var w = terrain.terrainData.heightmapResolution; var h = terrain.terrainData.heightmapResolution; var max = float.MinValue; var min = float.MaxValue; var heights = terrain.terrainData.GetHeights(0, 0, w, h); foreach (var height in heights) { if (height > max) { max = height; } if (height < min) { min = height; } } if (max < min) { max = 1; min = 0; } else if (max == min) { max = min + 0.1f; } using (var imageFile = asset.DestinationFolder.Create(heightmapFileName)) { if (imageFile != null) { using (var binaryWriter = new BinaryWriter(imageFile)) { WriteTgaHeader(binaryWriter, 32, w, h); for (var y = h - 1; y >= 0; --y) { for (var x = 0; x < w; ++x) { var height = (heights[h - y - 1, x] - min) / (max - min) * 255.0f; var msb = (byte)height; var lsb = (byte)((height - msb) * 255.0f); binaryWriter.Write((byte)0); //B - none binaryWriter.Write(lsb); //G - LSB binaryWriter.Write(msb); //R - MSB binaryWriter.Write((byte)255); //A - none } } } } } return(min, max, new Vector2(w, h)); }
private static void Process3DAsset(AssetCollection assets, AssetContext assetContext) { new MeshExporter(assets).ExportAsset(assetContext); if (assetContext.Type != typeof(Mesh)) { new PrefabExporter(assets).ExportAsset(assetContext); } }
private void ExportAnimation(AssetContext asset, AnimationClip clipAnimation) { var name = GetSafeFileName(clipAnimation.name); var fileName = Path.Combine(asset.ContentFolder, name + ".ani"); //_assetCollection.AddAnimationPath(clipAnimation, fileName); if (!File.Exists(fileName)) { using (var file = Urho3DExporter.ExportAssets.CreateFile(fileName)) { using (var writer = new BinaryWriter(file)) { writer.Write(new byte[] { 0x55, 0x41, 0x4e, 0x49 }); WriteStringSZ(writer, clipAnimation.name); writer.Write(clipAnimation.length); if (clipAnimation.legacy) { WriteTracksAsIs(clipAnimation, writer); } else { var allBindings = AnimationUtility.GetCurveBindings(clipAnimation); var rootBones = new HashSet <string>(allBindings.Select(_ => GetRootBoneName(_)).Where(_ => _ != null)); if (rootBones.Count != 1) { Debug.LogWarning(asset.AssetPath + ": Multiple root bones found (" + string.Join(", ", rootBones.ToArray()) + "), falling back to curve export"); WriteTracksAsIs(clipAnimation, writer); } else { var rootBoneName = rootBones.First(); var rootGOs = _skeletons .Select(_ => (_.name == rootBoneName) ? _.transform : _.transform.Find(rootBoneName)) .Where(_ => _ != null).ToList(); if (rootGOs.Count == 1) { WriteSkelAnimation(clipAnimation, rootGOs.First().gameObject, writer); } else { Debug.LogWarning(asset.AssetPath + ": Multiple game objects found that match root bone name, falling back to curve export"); WriteTracksAsIs(clipAnimation, writer); } } } } } } }
//[MenuItem("CONTEXT/Terrain/Export Terrain To Urho3D")] //static void ExportTerrain(MenuCommand command) //{ // if (!ResolveDataPath(out var urhoDataPath)) return; //} public static void ExportToUrho(string targetPath, bool overrideFiles, bool exportSelected) { if (string.IsNullOrWhiteSpace(targetPath)) { return; } var urhoDataPath = new DestinationFolder(targetPath, overrideFiles); AssetCollection assets; if (Selection.assetGUIDs.Length == 0 || !exportSelected) { assets = new AssetCollection(urhoDataPath, AssetDatabase.FindAssets("").Select(_ => AssetContext.Create(_, urhoDataPath)) .Where(_ => _.Type != null)); } else { var selectedAssets = new HashSet <string>(); foreach (var assetGuiD in Selection.assetGUIDs) { AddSelection(assetGuiD, selectedAssets); } var enumerable = selectedAssets.Select(_ => AssetContext.Create(_, urhoDataPath)).ToList(); var assetContexts = enumerable.Where(_ => _.Type != null).ToList(); assets = new AssetCollection(urhoDataPath, assetContexts); } _id = 0; var other = Split(assets, _ => _.Is3DAsset, _ => Process3DAsset(assets, _)); var textureMetadataCollection = new TextureMetadataCollection(urhoDataPath); other = Split(other, _ => _.Type == typeof(Texture3D) || _.Type == typeof(Texture2D) || _.Type == typeof(Cubemap), _ => new TextureExporter(assets, textureMetadataCollection).ExportAsset(_)); other = Split(other, _ => _.Type == typeof(Material), _ => new MaterialExporter(assets, textureMetadataCollection).ExportAsset(_)); var activeScene = SceneManager.GetActiveScene(); other = Split(other, _ => _.Type == typeof(SceneAsset), _ => { if (_.AssetPath == activeScene.path) { ProcessSceneAsset(assets, _, activeScene); } }); foreach (var assetContext in other) { ProcessAsset(assets, assetContext); } }
private static void ProcessAsset(AssetCollection assets, AssetContext assetContext) { if (assetContext.Type == typeof(GameObject)) { new PrefabExporter(assets).ExportAsset(assetContext); } else if (assetContext.Type == typeof(SceneAsset)) { //new SceneExporter(assets).ExportAsset(assetContext); } }
private void WriteTerrainWeightsTexture(AssetContext asset, string weightsTextureName, Terrain terrain) { var layers = terrain.terrainData.terrainLayers; var w = terrain.terrainData.alphamapWidth; var h = terrain.terrainData.alphamapHeight; var alphamaps = terrain.terrainData.GetAlphamaps(0, 0, w, h); var numAlphamaps = alphamaps.GetLength(2); //Urho3D doesn't support more than 3 textures if (numAlphamaps > 3) { numAlphamaps = 3; } using (var imageFile = asset.DestinationFolder.Create(weightsTextureName)) { if (imageFile == null) { return; } using (var binaryWriter = new BinaryWriter(imageFile)) { var weights = new byte[4]; weights[3] = 255; WriteTgaHeader(binaryWriter, weights.Length * 8, w, h); for (var y = h - 1; y >= 0; --y) { for (var x = 0; x < w; ++x) { var sum = 0; for (var i = 0; i < weights.Length; ++i) { if (numAlphamaps > i && layers.Length > i) { var weight = (byte)(alphamaps[h - y - 1, x, i] * 255.0f); sum += weight; weights[i] = weight; } } if (sum == 0) { weights[0] = 255; } binaryWriter.Write(weights[2]); //B binaryWriter.Write(weights[1]); //G binaryWriter.Write(weights[0]); //R binaryWriter.Write(weights[3]); //A } } } } }
public void ExportAsset(AssetContext asset) { using (var writer = asset.CreateXml()) { if (writer == null) { return; } var go = AssetDatabase.LoadAssetAtPath <GameObject>(asset.AssetPath); WriteObject(writer, "", go, new HashSet <Renderer>(), asset); } }
private void TransformSpecularGlossiness(AssetContext asset, Texture texture, TextureReferences reference) { var specularGloss = texture as Texture2D; EnsureReadableTexture(specularGloss); var diffuse = reference.SmoothnessSource as Texture2D; EnsureReadableTexture(diffuse); var smoothnessSource = reference.SmoothnessTextureChannel == SmoothnessTextureChannel.MetallicOrSpecularAlpha ? specularGloss : diffuse; var metallicRoughMapName = GetTextureOutputName(asset.UrhoAssetName, reference); using (var fileStream = asset.DestinationFolder.Create(metallicRoughMapName)) { if (fileStream != null) { var width = Math.Max(specularGloss.width, smoothnessSource.width); var height = Math.Max(specularGloss.height, smoothnessSource.height); var tmpTexture = new Texture2D(width, height, TextureFormat.RGBA32, false); tmpTexture.hideFlags = HideFlags.HideAndDontSave; var metallicColors = specularGloss.GetPixels32(0); var diffuseColors = diffuse.GetPixels32(0); var smoothnessColors = specularGloss == smoothnessSource ? metallicColors : smoothnessSource.GetPixels32(0); var pixels = new Color32[width * height]; var index = 0; for (var y = 0; y < height; ++y) { for (var x = 0; x < width; ++x) { var r = 1.0f - Get(smoothnessColors, smoothnessSource.width, smoothnessSource.height, x, y, width, height).a; var d = GetLuminance(Get(diffuseColors, diffuse.width, diffuse.height, x, y, width, height)); var s = GetLuminance(Get(metallicColors, specularGloss.width, specularGloss.height, x, y, width, height)); var m = s / (d + s); pixels[index] = new Color(r, m, 0, 1); ++index; } } tmpTexture.SetPixels32(pixels, 0); var bytes = tmpTexture.EncodeToPNG(); fileStream.Write(bytes, 0, bytes.Length); } } }
private static void Process3DAsset(AssetCollection assets, AssetContext assetContext) { Directory.CreateDirectory(assetContext.ContentFolder); new MeshExporter(assets).ExportAsset(assetContext); if (File.Exists(assetContext.UrhoFileName)) { return; } new PrefabExporter(assets).ExportAsset(assetContext); }
public void ExportAsset(AssetContext asset) { var go = AssetDatabase.LoadAssetAtPath <SceneAsset>(asset.AssetPath); var exclusionSet = new HashSet <Renderer>(); using (XmlTextWriter writer = CreateXmlFile(asset)) { using (var scene = Element.Start(writer, "scene")) { } } }
private void TransformSpecularGlossiness(AssetContext asset, Texture texture, TextureReferences reference) { var specularGloss = texture as Texture2D; EnsureReadableTexture(specularGloss); var diffuse = reference.SmoothnessSource as Texture2D; EnsureReadableTexture(diffuse); var smoothnessSource = reference.SmoothnessTextureChannel == SmoothnessTextureChannel.MetallicOrSpecularAlpha ? specularGloss : diffuse; var metallicRoughMapName = GetTextureOutputName(asset.UrhoAssetName, reference); using (var fileStream = asset.DestinationFolder.Create(metallicRoughMapName)) { if (fileStream != null) { var tmpTexture = CreateTargetTexture(specularGloss, diffuse); var specularColors = new PixelSource(specularGloss, tmpTexture.width, tmpTexture.height, Color.black); var diffuseColors = new PixelSource(diffuse, tmpTexture.width, tmpTexture.height, Color.white); var smoothnessColors = specularGloss == smoothnessSource ? specularColors : diffuseColors; var pixels = new Color32[tmpTexture.width * tmpTexture.height]; var index = 0; for (var y = 0; y < tmpTexture.height; ++y) { for (var x = 0; x < tmpTexture.width; ++x) { var mr = PBRUtils.ConvertToMetallicRoughness(new PBRUtils.SpecularGlossiness { diffuse = diffuseColors.GetAt(x, y), specular = specularColors.GetAt(x, y), glossiness = smoothnessColors.GetAt(x, y).a, opacity = 1.0f }); pixels[index] = new Color(mr.roughness, mr.metallic, 0, 1); ++index; } } tmpTexture.SetPixels32(pixels, 0); var bytes = tmpTexture.EncodeToPNG(); fileStream.Write(bytes, 0, bytes.Length); } } }
public void ExportAsset(AssetContext asset) { if (!File.Exists(asset.FullPath)) { Debug.LogError("File " + asset.FullPath + " not found"); return; } var texture = AssetDatabase.LoadAssetAtPath <Texture>(asset.AssetPath); _assets.AddTexturePath(texture, asset.UrhoAssetName); var fullCopy = false; foreach (var reference in _textureMetadata.ResolveReferences(texture)) { switch (reference.Semantic) { case TextureSemantic.PBRMetallicGlossiness: { TransformMetallicGlossiness(asset, texture, reference); break; } case TextureSemantic.PBRSpecularGlossiness: { TransformSpecularGlossiness(asset, texture, reference); break; } case TextureSemantic.PBRDiffuse: { TransformDiffuse(asset, texture, reference); break; } default: { if (!fullCopy) { asset.DestinationFolder.CopyFile(asset.FullPath, asset.UrhoAssetName); fullCopy = true; } break; } } } }
private static void ProcessAsset(AssetCollection assets, AssetContext assetContext) { if (File.Exists(assetContext.UrhoFileName)) { return; } Directory.CreateDirectory(Path.GetDirectoryName(assetContext.UrhoFileName)); if (assetContext.Type == typeof(GameObject)) { new PrefabExporter(assets).ExportAsset(assetContext); } else if (assetContext.Type == typeof(SceneAsset)) { //new SceneExporter(assets).ExportAsset(assetContext); } }
public void ExportAsset(AssetContext asset) { var go = AssetDatabase.LoadAssetAtPath <SceneAsset>(asset.AssetPath); var exclusionSet = new HashSet <Renderer>(); using (var writer = asset.CreateXml()) { if (writer == null) { return; } using (var scene = Element.Start(writer, "scene")) { } } }
private void ExportMaterial(AssetContext asset, Material material) { var mat = new MaterialDescription(material); if (mat.SpecularGlossiness != null) { ExportSpecularGlossiness(asset, mat.SpecularGlossiness); } else if (mat.MetallicRoughness != null) { ExportMetallicRoughness(asset, mat.MetallicRoughness); } else { ExportLegacy(asset, mat.Legacy ?? new LegacyShaderArguments()); } }
private void TransformDiffuse(AssetContext asset, Texture texture, TextureReferences reference) { var diffuse = texture as Texture2D; EnsureReadableTexture(diffuse); var specularGlossiness = reference.SmoothnessSource as Texture2D; EnsureReadableTexture(specularGlossiness); var metallicRoughMapName = GetTextureOutputName(asset.UrhoAssetName, reference); using (var fileStream = asset.DestinationFolder.Create(metallicRoughMapName)) { if (fileStream != null) { var specWidth = specularGlossiness?.width ?? 1; var specHeight = specularGlossiness?.height ?? 1; var smoothnessColors = specularGlossiness?.GetPixels32(0) ?? new[] { new Color32(0, 0, 0, 255) }; var width = Math.Max(diffuse.width, specWidth); var height = Math.Max(diffuse.height, specHeight); var tmpTexture = new Texture2D(width, height, TextureFormat.RGBA32, false); tmpTexture.hideFlags = HideFlags.HideAndDontSave; var diffuseColors = diffuse.GetPixels32(0); var pixels = new Color32[width * height]; var index = 0; for (var y = 0; y < height; ++y) { for (var x = 0; x < width; ++x) { var specular = Get(smoothnessColors, specWidth, specHeight, x, y, width, height); var diffuseColor = Get(diffuseColors, diffuse.width, diffuse.height, x, y, width, height); pixels[index] = new Color(diffuseColor.r + specular.r, diffuseColor.g + specular.g, diffuseColor.b + specular.b, diffuseColor.a); ++index; } } tmpTexture.SetPixels32(pixels, 0); var bytes = tmpTexture.EncodeToPNG(); fileStream.Write(bytes, 0, bytes.Length); } } }
private void ExportMesh(AssetContext asset, GameObject go) { var skinnedMeshRenderer = go.GetComponent <SkinnedMeshRenderer>(); var meshFilter = go.GetComponent <MeshFilter>(); //Debug.Log("Game object: "+go.name+", components: "+string.Join(", ", go.GetComponents<Component>().Select(_=>_.GetType().Name).ToArray())); Mesh mesh = null; if (skinnedMeshRenderer != null) { mesh = skinnedMeshRenderer.sharedMesh; } else if (meshFilter != null) { mesh = meshFilter.sharedMesh; } if (mesh != null && _meshes.Add(mesh)) { var name = GetSafeFileName(mesh.name); var fileName = Path.Combine(asset.ContentFolder, name + ".mdl"); _assetCollection.AddMeshPath(mesh, fileName); if (!File.Exists(fileName)) { using (var file = Urho3DExporter.ExportAssets.CreateFile(fileName)) { using (var writer = new BinaryWriter(file)) { WriteMesh(writer, mesh, BuildBones(skinnedMeshRenderer)); } } } } for (var i = 0; i < go.transform.childCount; ++i) { ExportMesh(asset, go.transform.GetChild(i).gameObject); } }
public void ExportAsset(AssetContext asset, Scene scene) { var exlusion = new HashSet <Renderer>(); using (XmlTextWriter writer = CreateXmlFile(asset)) { using (var sceneElement = Element.Start(writer, "scene")) { WriteAttribute(writer, "\t", "Name", scene.name); StartCompoent(writer, "\t", "Octree"); EndElement(writer, "\t"); StartCompoent(writer, "\t", "DebugRenderer"); EndElement(writer, "\t"); foreach (var gameObject in scene.GetRootGameObjects()) { WriteObject(writer, "", gameObject, exlusion); } } } }
private void TransformMetallicGlossiness(AssetContext asset, Texture texture, TextureReferences reference) { var metallicGloss = texture as Texture2D; EnsureReadableTexture(metallicGloss); var smoothnessSource = reference.SmoothnessSource as Texture2D; EnsureReadableTexture(smoothnessSource); var metallicRoughMapName = GetTextureOutputName(asset.UrhoAssetName, reference); using (var fileStream = asset.DestinationFolder.Create(metallicRoughMapName)) { if (fileStream != null) { var tmpTexture = CreateTargetTexture(metallicGloss, reference.SmoothnessSource as Texture2D); var metallicColors = new PixelSource(metallicGloss, tmpTexture.width, tmpTexture.height, new Color(0, 0, 0, 0)); var smoothnessColors = metallicGloss == smoothnessSource ? metallicColors : new PixelSource(smoothnessSource, tmpTexture.width, tmpTexture.height, new Color(0, 0, 0, 0)); var pixels = new Color32[tmpTexture.width * tmpTexture.height]; var index = 0; for (var y = 0; y < tmpTexture.height; ++y) { for (var x = 0; x < tmpTexture.width; ++x) { var r = 1.0f - smoothnessColors.GetAt(x, y).a; var m = metallicColors.GetAt(x, y).r; pixels[index] = new Color(r, m, 0, 1); ++index; } } tmpTexture.SetPixels32(pixels, 0); var bytes = tmpTexture.EncodeToPNG(); fileStream.Write(bytes, 0, bytes.Length); } } }
public static AssetContext Create(string guid, string urhoDataFolder) { var res = new AssetContext { Guid = guid }; res.AssetPath = AssetDatabase.GUIDToAssetPath(guid); if (!string.IsNullOrEmpty(res.AssetPath)) { res.Type = AssetDatabase.GetMainAssetTypeAtPath(res.AssetPath); res.RelPath = res.AssetPath; if (res.RelPath.StartsWith("Assets/", StringComparison.InvariantCultureIgnoreCase)) { res.RelPath = res.RelPath.Substring("Assets/".Length); } res.FullPath = Path.Combine(Application.dataPath, res.RelPath); res.FileExtension = System.IO.Path.GetExtension(res.AssetPath).ToLower(); res.UrhoAssetName = res.RelPath; if (res.Type == typeof(Material)) { res.UrhoAssetName = RepaceExtension(res.UrhoAssetName, ".xml"); } else if (res.Type == typeof(GameObject)) { res.UrhoAssetName = RepaceExtension(res.UrhoAssetName, ".xml"); res.Is3DAsset = _supported3DFormats.Contains(res.FileExtension); } else if (res.Type == typeof(SceneAsset)) { res.UrhoAssetName = RepaceExtension(res.UrhoAssetName, ".xml"); } res.UrhoFileName = System.IO.Path.Combine(urhoDataFolder, res.UrhoAssetName); if (res.Is3DAsset) { res.ContentFolder = res.UrhoFileName.Substring(0, res.UrhoFileName.Length - ".xml".Length); } } return(res); }
public void ExportAsset(AssetContext asset) { var texture = AssetDatabase.LoadAssetAtPath <Texture>(asset.AssetPath); _assets.AddTexturePath(texture, asset.UrhoAssetName); if (asset.UrhoFileName == null) { return; } if (File.Exists(asset.UrhoFileName)) { return; } if (!File.Exists(asset.FullPath)) { Debug.LogError("File " + asset.FullPath + " not found"); return; } Directory.CreateDirectory(Path.GetDirectoryName(asset.UrhoFileName)); File.Copy(asset.FullPath, asset.UrhoFileName); }
private void ExportTerrain(XmlWriter writer, GameObject obj, AssetContext asset, Terrain terrain, string subPrefix, string subSubPrefix) { if (terrain == null) { return; } var terrainSize = terrain.terrainData.size; writer.WriteWhitespace(subPrefix); writer.WriteStartElement("node"); writer.WriteAttributeString("id", (++_id).ToString()); writer.WriteWhitespace("\n"); var folderAndName = asset.RelPath + "/" + Path.GetInvalidFileNameChars().Aggregate(obj.name, (_1, _2) => _1.Replace(_2, '_')); var heightmapFileName = "Textures/Terrains/" + folderAndName + ".tga"; var materialFileName = "Materials/Terrains/" + folderAndName + ".xml"; var(min, max, size) = WriteHeightMap(asset, heightmapFileName, terrain); WriteAttribute(writer, subPrefix, "Position", new Vector3(terrainSize.x * 0.5f, -min, terrainSize.z * 0.5f)); StartCompoent(writer, subPrefix, "Terrain"); WriteAttribute(writer, subSubPrefix, "Height Map", "Image;" + heightmapFileName); WriteAttribute(writer, subSubPrefix, "Material", "Material;" + materialFileName); WriteTerrainMaterial(terrain, asset, materialFileName, "Textures/Terrains/" + folderAndName + ".Weights.tga"); WriteAttribute(writer, subSubPrefix, "Vertex Spacing", new Vector3(terrainSize.x / size.x, 2.0f * (max - min), terrainSize.z / size.y)); EndElement(writer, subPrefix); EndElement(writer, subPrefix); }
private static void ProcessSceneAsset(AssetCollection assets, AssetContext assetContext, Scene scene) { new SceneExporter(assets).ExportAsset(assetContext, scene); }
private void ExportLegacy(AssetContext asset, LegacyShaderArguments arguments) { using (var writer = asset.DestinationFolder.CreateXml(asset.UrhoAssetName)) { if (writer == null) { return; } writer.WriteStartDocument(); writer.WriteWhitespace(Environment.NewLine); var flags = new LegacyTechniqueFlags(); flags.hasAlpha = arguments.Transparent; flags.hasDiffuse = arguments.Diffuse != null; flags.hasEmissive = arguments.Emission != null; flags.hasNormal = arguments.Bump != null; flags.hasSpecular = arguments.Specular != null; writer.WriteStartElement("material"); writer.WriteWhitespace(Environment.NewLine); { var bestTechnique = Techniques[0]; var bestTechniqueDistance = bestTechnique.Material - flags; foreach (var technique in Techniques) { if (technique.Material.Fits(flags)) { var d = technique.Material - flags; if (d < bestTechniqueDistance) { bestTechnique = technique; bestTechniqueDistance = d; } } } WriteTechnique(writer, "Techniques/" + bestTechnique.Name); } if (arguments.Diffuse != null) { WriteTexture(arguments.Diffuse, writer, "diffuse"); } if (arguments.Specular != null) { WriteTexture(arguments.Specular, writer, "specular"); } if (arguments.Bump != null) { WriteTexture(arguments.Bump, writer, "normal"); } if (arguments.Emission != null) { WriteTexture(arguments.Bump, writer, "emissive"); } WriteParameter(writer, "MatDiffColor", BaseNodeExporter.Format(arguments.DiffColor)); if (arguments.HasEmission) { WriteParameter(writer, "MatEmissiveColor", BaseNodeExporter.FormatRGB(arguments.EmissiveColor)); } writer.WriteEndElement(); writer.WriteEndDocument(); } }
private void ExportSpecularGlossiness(AssetContext asset, SpecularGlossinessShaderArguments arguments) { using (var writer = asset.DestinationFolder.CreateXml(asset.UrhoAssetName)) { if (writer == null) { return; } writer.WriteStartDocument(); writer.WriteWhitespace(Environment.NewLine); writer.WriteStartElement("material"); writer.WriteWhitespace(Environment.NewLine); if (arguments.Diffuse != null) { // Albedo if (arguments.PBRSpecular != null) { // Albedo, MetallicGloss if (arguments.Bump != null) { // Albedo, MetallicGloss, Normal if (arguments.Emission) { // Albedo, MetallicGloss, Normal, Emission if (arguments.Transparent) { WriteTechnique(writer, "Techniques/PBR/PBRMetallicRoughDiffNormalSpecEmissiveAlpha.xml"); } else { WriteTechnique(writer, "Techniques/PBR/PBRMetallicRoughDiffNormalSpecEmissive.xml"); } WriteTexture(arguments.Emission, writer, "emissive"); } else { // Albedo, MetallicGloss, Normal, No Emission if (arguments.Transparent) { WriteTechnique(writer, "Techniques/PBR/PBRMetallicRoughDiffNormalSpecAlpha.xml"); } else { WriteTechnique(writer, "Techniques/PBR/PBRMetallicRoughDiffNormalSpec.xml"); } } WriteTexture(arguments.Bump, writer, "normal"); } else { // Albedo, MetallicGloss, No Normal if (arguments.Transparent) { WriteTechnique(writer, "Techniques/PBR/PBRMetallicRoughDiffSpecAlpha.xml"); } else { WriteTechnique(writer, "Techniques/PBR/PBRMetallicRoughDiffSpec.xml"); } } if (_assets.TryGetTexturePath(arguments.PBRSpecular, out var baseAssetName)) { var textureReferences = new TextureReferences(TextureSemantic.PBRSpecularGlossiness, 1.0f, arguments.SmoothnessTextureChannel == SmoothnessTextureChannel.AlbedoAlpha ? arguments.Diffuse : arguments.PBRSpecular, arguments.SmoothnessTextureChannel); var textureOutputName = TextureExporter.GetTextureOutputName(baseAssetName, textureReferences); WriteTexture(textureOutputName, writer, "specular"); } } else { // Albedo, No MetallicGloss if (arguments.Bump != null) { // Albedo, No MetallicGloss, Normal if (arguments.Emission != null) { // Albedo, No MetallicGloss, Normal, Emission if (arguments.Transparent) { WriteTechnique(writer, "Techniques/PBR/PBRDiffNormalEmissiveAlpha.xml"); } else { WriteTechnique(writer, "Techniques/PBR/PBRDiffNormalEmissive.xml"); } WriteTexture(arguments.Emission, writer, "emissive"); } else { // Albedo, No MetallicGloss, Normal, No Emission if (arguments.Transparent) { WriteTechnique(writer, "Techniques/PBR/PBRDiffNormalAlpha.xml"); } else { WriteTechnique(writer, "Techniques/PBR/PBRDiffNormal.xml"); } } WriteTexture(arguments.Bump, writer, "normal"); } else { // Albedo, No MetallicGloss, No Normal if (arguments.Transparent) { WriteTechnique(writer, "Techniques/PBR/PBRDiffAlpha.xml"); } else { WriteTechnique(writer, "Techniques/PBR/PBRDiff.xml"); } } } if (_assets.TryGetTexturePath(arguments.Diffuse, out var diffuseName)) { var textureReferences = new TextureReferences(TextureSemantic.PBRDiffuse, 1.0f, arguments.PBRSpecular, arguments.SmoothnessTextureChannel); var textureOutputName = TextureExporter.GetTextureOutputName(diffuseName, textureReferences); WriteTexture(textureOutputName, writer, "diffuse"); } } else { // No albedo if (arguments.Transparent) { WriteTechnique(writer, "Techniques/PBR/PBRNoTextureAlpha.xml"); } else { WriteTechnique(writer, "Techniques/PBR/PBRNoTexture.xml"); } } WriteParameter(writer, "MatDiffColor", BaseNodeExporter.Format(arguments.DiffuseColor)); if (arguments.HasEmission) { WriteParameter(writer, "MatEmissiveColor", BaseNodeExporter.FormatRGB(arguments.EmissiveColor)); } WriteParameter(writer, "MatEnvMapColor", BaseNodeExporter.FormatRGB(Color.white)); WriteParameter(writer, "MatSpecColor", BaseNodeExporter.Format(Vector4.zero)); if (arguments.PBRSpecular != null) { WriteParameter(writer, "Roughness", BaseNodeExporter.Format(0)); WriteParameter(writer, "Metallic", BaseNodeExporter.Format(0)); } else { ////TODO: Evaluate correct parameters: WriteParameter(writer, "Roughness", BaseNodeExporter.Format(0.0f)); WriteParameter(writer, "Metallic", BaseNodeExporter.Format(0.0f)); } writer.WriteEndElement(); writer.WriteEndDocument(); } }
//private void WriteMaterialAttribute(string subSubPrefix, Material[] meshRendererMaterials) //{ // var material = new StringBuilder(); // material.Append("Material"); // for (var i = 0; i < meshRendererMaterials.Length; ++i) // { // var meshRendererMaterial = meshRendererMaterials[i]; // var relPath = GetRelAssetPath(meshRendererMaterial); // var outputMaterialName = "Materials/" + relPath + ".xml"; // material.Append(";"); // material.Append(outputMaterialName); // var materialFileName = Path.Combine(_assetsFolder, outputMaterialName); // if (!File.Exists(materialFileName)) // CreateMaterial(materialFileName, meshRendererMaterial); // } // WriteAttribute(subSubPrefix, "Material", material.ToString()); //} protected void WriteObject(XmlWriter writer, string prefix, GameObject obj, HashSet <Renderer> excludeList, AssetContext asset) { var localExcludeList = new HashSet <Renderer>(excludeList); if (!string.IsNullOrEmpty(prefix)) { writer.WriteWhitespace(prefix); } writer.WriteStartElement("node"); writer.WriteAttributeString("id", (++_id).ToString()); writer.WriteWhitespace("\n"); var subPrefix = prefix + "\t"; var subSubPrefix = subPrefix + "\t"; WriteAttribute(writer, subPrefix, "Is Enabled", obj.activeSelf); WriteAttribute(writer, subPrefix, "Name", obj.name); WriteAttribute(writer, subPrefix, "Tags", obj.tag); WriteAttribute(writer, subPrefix, "Position", obj.transform.localPosition); WriteAttribute(writer, subPrefix, "Rotation", obj.transform.localRotation); WriteAttribute(writer, subPrefix, "Scale", obj.transform.localScale); var meshFilter = obj.GetComponent <MeshFilter>(); var meshRenderer = obj.GetComponent <MeshRenderer>(); var skinnedMeshRenderer = obj.GetComponent <SkinnedMeshRenderer>(); var lodGroup = obj.GetComponent <LODGroup>(); var meshCollider = obj.GetComponent <MeshCollider>(); var terrain = obj.GetComponent <Terrain>(); var light = obj.GetComponent <Light>(); var camera = obj.GetComponent <Camera>(); var reflectionProbe = obj.GetComponent <ReflectionProbe>(); //if (reflectionProbe != null) //{ // StartCompoent(subPrefix, "Zone"); // WriteAttribute(subSubPrefix, "Bounding Box Min", -(reflectionProbe.size * 0.5f)); // WriteAttribute(subSubPrefix, "Bounding Box Max", (reflectionProbe.size * 0.5f)); // var cubemap = reflectionProbe.bakedTexture as Cubemap; // if (cubemap != null) // { // var name = SaveCubemap(cubemap); // WriteAttribute(subSubPrefix, "Zone Texture", "TextureCube;" + name); // } // EndElement(subPrefix); //} if (camera != null) { StartCompoent(writer, subPrefix, "Camera"); WriteAttribute(writer, subSubPrefix, "Near Clip", camera.nearClipPlane); WriteAttribute(writer, subSubPrefix, "Far Clip", camera.farClipPlane); EndElement(writer, subPrefix); } if (light != null && light.type != LightType.Area) { StartCompoent(writer, subPrefix, "Light"); if (light.type == LightType.Directional) { WriteAttribute(writer, subSubPrefix, "Light Type", "Directional"); } else if (light.type == LightType.Spot) { WriteAttribute(writer, subSubPrefix, "Light Type", "Spot"); } else if (light.type == LightType.Point) { WriteAttribute(writer, subSubPrefix, "Range", light.range); } WriteAttribute(writer, subSubPrefix, "Color", light.color); WriteAttribute(writer, subSubPrefix, "Brightness Multiplier", light.intensity); WriteAttribute(writer, subSubPrefix, "Cast Shadows", light.shadows != LightShadows.None); EndElement(writer, subPrefix); } ExportTerrain(writer, obj, asset, terrain, subPrefix, subSubPrefix); if (lodGroup != null) { var lods = lodGroup.GetLODs(); foreach (var lod in lods.Skip(1)) { foreach (var renderer in lod.renderers) { localExcludeList.Add(renderer); } } //lods[0].renderers } if (meshRenderer != null && !localExcludeList.Contains(meshRenderer)) { if (meshFilter != null) { StartCompoent(writer, subPrefix, "StaticModel"); var sharedMesh = meshFilter.sharedMesh; string meshPath; if (_assets.TryGetMeshPath(sharedMesh, out meshPath)) { WriteAttribute(writer, subSubPrefix, "Model", "Model;" + meshPath); } var materials = "Material"; foreach (var material in meshRenderer.sharedMaterials) { string path; _assets.TryGetMaterialPath(material, out path); materials += ";" + path; } WriteAttribute(writer, subSubPrefix, "Material", materials); WriteAttribute(writer, subSubPrefix, "Cast Shadows", meshRenderer.shadowCastingMode != ShadowCastingMode.Off); EndElement(writer, subPrefix); } } if (skinnedMeshRenderer != null && !localExcludeList.Contains(skinnedMeshRenderer)) { StartCompoent(writer, subPrefix, "AnimatedModel"); var sharedMesh = skinnedMeshRenderer.sharedMesh; string meshPath; if (_assets.TryGetMeshPath(sharedMesh, out meshPath)) { WriteAttribute(writer, subSubPrefix, "Model", "Model;" + meshPath); } var materials = "Material"; foreach (var material in skinnedMeshRenderer.sharedMaterials) { string path; _assets.TryGetMaterialPath(material, out path); materials += ";" + path; } WriteAttribute(writer, subSubPrefix, "Material", materials); WriteAttribute(writer, subSubPrefix, "Cast Shadows", skinnedMeshRenderer.shadowCastingMode != ShadowCastingMode.Off); EndElement(writer, subPrefix); } if (meshCollider != null) { } foreach (Transform childTransform in obj.transform) { if (childTransform.parent.gameObject == obj) { WriteObject(writer, subPrefix, childTransform.gameObject, localExcludeList, asset); } } if (!string.IsNullOrEmpty(prefix)) { writer.WriteWhitespace(prefix); } writer.WriteEndElement(); writer.WriteWhitespace("\n"); }
private static void ExportToUrho() { string urhoDataPath = EditorUtility.SaveFolderPanel("Save assets to Data folder", _prevFolder, ""); if (string.IsNullOrEmpty(urhoDataPath)) { return; } if (urhoDataPath.StartsWith(Path.GetDirectoryName(Application.dataPath).Replace('\\', '/'), StringComparison.InvariantCultureIgnoreCase)) { EditorUtility.DisplayDialog("Error", "Selected path is inside Unity folder. Please select a different folder.", "Ok"); return; } _prevFolder = urhoDataPath; AssetCollection assets; if (Selection.assetGUIDs.Length == 0) { assets = new AssetCollection(urhoDataPath, AssetDatabase.FindAssets("").Select(_ => AssetContext.Create(_, urhoDataPath)).Where(_ => _.Type != null)); } else { var selectedAssets = new HashSet <string>(); foreach (var assetGuiD in Selection.assetGUIDs) { AddSelection(assetGuiD, selectedAssets); } assets = new AssetCollection(urhoDataPath, selectedAssets.Select(_ => AssetContext.Create(_, urhoDataPath)).Where(_ => _.Type != null)); } _id = 0; //string urhoDataPath = @"C:\Temp\Data\"; //foreach (var type in assets.Select(_ => _.Type).Distinct()) Debug.Log(type.FullName); List <AssetContext> other = Split(assets, _ => _.Is3DAsset, _ => Process3DAsset(assets, _)); other = Split(other, _ => _.Type == typeof(Texture3D) || _.Type == typeof(Texture2D) || _.Type == typeof(Cubemap), _ => new TextureExporter(assets).ExportAsset(_)); other = Split(other, _ => _.Type == typeof(Material), _ => new MaterialExporter(assets).ExportAsset(_)); var activeScene = EditorSceneManager.GetActiveScene(); other = Split(other, _ => _.Type == typeof(SceneAsset), _ => { if (_.AssetPath == activeScene.path) { ProcessSceneAsset(assets, _, activeScene); } }); foreach (var assetContext in other) { ProcessAsset(assets, assetContext); } //foreach (var s in guids2) //{ // var path = AssetDatabase.GUIDToAssetPath(s); // if (path.StartsWith(assetsPrefix)) // { // path = path.Substring(assetsPrefix.Length); // } // if (path.StartsWith("PolygonSciFiCity")) // { // if (path.EndsWith(".prefab", true, CultureInfo.InvariantCulture)) // { // ExportPrefab(s, path, @"C:\Temp\Data\"); // } // if (path.EndsWith(".fbx", true, CultureInfo.InvariantCulture)) // { // ExportModel(s, path, @"C:\Temp\Data\"); // } // if (path.EndsWith(".mat", true, CultureInfo.InvariantCulture)) // { // ExportMaterial(s, path, @"C:\Temp\Data\"); // } // if (path.EndsWith(".png", true, CultureInfo.InvariantCulture) || // path.EndsWith(".dds", true, CultureInfo.InvariantCulture) || // path.EndsWith(".tga", true, CultureInfo.InvariantCulture)) // { // CopyFileIfNew(s, path, @"C:\Temp\Data\"); // } // } //} }
protected XmlTextWriter CreateXmlFile(AssetContext asset) { var file = ExportAssets.CreateFile(asset.UrhoFileName); return(new XmlTextWriter(file, new UTF8Encoding(false))); }
private void WriteTerrainMaterial(Terrain terrain, AssetContext asset, string materialPath, string weightsTextureName) { using (var writer = asset.DestinationFolder.CreateXml(materialPath)) { if (writer == null) { return; } var layers = terrain.terrainData.terrainLayers; if (layers.Length > 3) { layers = layers.Take(3).ToArray(); } writer.WriteStartDocument(); writer.WriteStartElement("material"); writer.WriteWhitespace(Environment.NewLine); { writer.WriteStartElement("technique"); writer.WriteAttributeString("name", "Techniques/TerrainBlend.xml"); writer.WriteEndElement(); writer.WriteWhitespace(Environment.NewLine); } { writer.WriteStartElement("texture"); writer.WriteAttributeString("unit", "0"); writer.WriteAttributeString("name", weightsTextureName); writer.WriteEndElement(); writer.WriteWhitespace(Environment.NewLine); WriteTerrainWeightsTexture(asset, weightsTextureName, terrain); } for (var layerIndex = 0; layerIndex < layers.Length; ++layerIndex) { var layer = layers[layerIndex]; writer.WriteStartElement("texture"); writer.WriteAttributeString("unit", (layerIndex + 1).ToString(CultureInfo.InvariantCulture)); if (layer.diffuseTexture != null) { string urhoAssetName; if (_assets.TryGetTexturePath(layer.diffuseTexture, out urhoAssetName)) { writer.WriteAttributeString("name", urhoAssetName); } } writer.WriteEndElement(); writer.WriteWhitespace(Environment.NewLine); } { writer.WriteStartElement("parameter"); writer.WriteAttributeString("name", "MatSpecColor"); writer.WriteAttributeString("value", "0.5 0.5 0.5 16"); writer.WriteEndElement(); writer.WriteWhitespace(Environment.NewLine); } { writer.WriteStartElement("parameter"); writer.WriteAttributeString("name", "DetailTiling"); writer.WriteAttributeString("value", "32 32"); writer.WriteEndElement(); writer.WriteWhitespace(Environment.NewLine); } writer.WriteEndElement(); writer.WriteEndDocument(); } }