/// <summary> /// Checks if a default scene exists for this game package. /// </summary> /// <param name="log">The log to output the result of the validation.</param> public override void Run(ILogger log) { if (log == null) { throw new ArgumentNullException(nameof(log)); } foreach (var package in Session.Packages) { // Make sure package has its assets loaded if (package.State < PackageState.AssetsReady) { continue; } var hasGameExecutable = package.Profiles.SelectMany(profile => profile.ProjectReferences).Any(projectRef => projectRef.Type == ProjectType.Executable); if (!hasGameExecutable) { continue; } // Find game settings var gameSettingsAssetItem = package.Assets.Find(GameSettingsAsset.GameSettingsLocation); AssetItem defaultScene = null; // If game settings is found, try to find default scene inside var defaultSceneRuntime = ((GameSettingsAsset)gameSettingsAssetItem?.Asset)?.DefaultScene; var defaultSceneReference = AttachedReferenceManager.GetAttachedReference(defaultSceneRuntime); if (defaultSceneReference != null) { // Find it either by Url or Id defaultScene = package.Assets.Find(defaultSceneReference.Id) ?? package.Assets.Find(defaultSceneReference.Url); // Check it is actually a scene asset if (defaultScene != null && !(defaultScene.Asset is SceneAsset)) { defaultScene = null; } } // Find or create default scene if (defaultScene == null) { defaultScene = package.Assets.Find(GameSettingsAsset.DefaultSceneLocation); if (defaultScene != null && !(defaultScene.Asset is SceneAsset)) { defaultScene = null; } } // Otherwise, try to find any scene if (defaultScene == null) { defaultScene = package.Assets.FirstOrDefault(x => x.Asset is SceneAsset); } // Nothing found, let's create an empty one if (defaultScene == null) { log.Error(package, null, AssetMessageCode.DefaultSceneNotFound, null); var defaultSceneName = NamingHelper.ComputeNewName(GameSettingsAsset.DefaultSceneLocation, package.Assets, a => a.Location); var defaultSceneAsset = DefaultAssetFactory <SceneAsset> .Create(); defaultScene = new AssetItem(defaultSceneName, defaultSceneAsset); package.Assets.Add(defaultScene); defaultScene.IsDirty = true; } // Create game settings if not done yet if (gameSettingsAssetItem == null) { log.Error(package, null, AssetMessageCode.AssetForPackageNotFound, GameSettingsAsset.GameSettingsLocation, package.FullPath.GetFileName()); var gameSettingsAsset = GameSettingsFactory.Create(); gameSettingsAsset.DefaultScene = AttachedReferenceManager.CreateProxyObject <Scene>(defaultScene.Id, defaultScene.Location); gameSettingsAssetItem = new AssetItem(GameSettingsAsset.GameSettingsLocation, gameSettingsAsset); package.Assets.Add(gameSettingsAssetItem); gameSettingsAssetItem.IsDirty = true; } } }
static void ImportFile(string path, string relativePath, string output) { string[] arr = relativePath.Split('.'); string name = Path.GetFileNameWithoutExtension(relativePath); switch (arr[arr.Length - 1]) { case "jpg": case "jpeg": case "dds": case "tiff": case "tif": case "psd": case "tga": case "bmp": case "gif": case "png": break; if ((name.ToLower().EndsWith("bump") && !name.ToLower().StartsWith("bump")) || (name.ToLower().EndsWith("normal") && !name.ToLower().StartsWith("normal"))) { TextureAsset tex = NormalMapTextureFactory.Create(); tex.Source = new UFile(relativePath); if (!overwrite && File.Exists($"{output}/{name}{TextureAsset.FileExtension}")) { Console.WriteLine($"{output}/{name}{TextureAsset.FileExtension} exists - not writing."); break; } else { AssetFileSerializer.Save($"{output}/{name}{TextureAsset.FileExtension}", tex, null); } } else { TextureAsset tex = ColorTextureFactory.Create(); tex.Source = new UFile(relativePath); if (!overwrite && File.Exists($"{output}/{name}{TextureAsset.FileExtension}")) { Console.WriteLine($"{output}/{name}{TextureAsset.FileExtension} exists - not writing."); break; } AssetFileSerializer.Save($"{output}/{name}{TextureAsset.FileExtension}", tex, null); MaterialAsset mat = DiffuseMaterialFactory.Create(); ((ComputeTextureColor)((MaterialDiffuseMapFeature)mat.Attributes.Diffuse).DiffuseMap).Texture = GetTexture(tex); AssetFileSerializer.Save($"{output}/{name}{MaterialAsset.FileExtension}", mat, null); } break; case "dae": case "3ds": case "obj": case "blend": case "x": case "md2": case "md3": case "dxf": case "fbx": if (!overwrite && File.Exists($"{output}/{name}{ModelAsset.FileExtension.Split(';')[0]}")) { Console.WriteLine($"{output}/{name}{ModelAsset.FileExtension.Split(';')[0]} exists - not writing."); break; } ModelAsset model = DefaultAssetFactory <ModelAsset> .Create(); model.Source = new UFile(relativePath); Scene scene = ctx.ImportFile(path, PostProcessSteps.None); Dictionary <string, Stride.Rendering.Material> materials = new Dictionary <string, Stride.Rendering.Material>(); for (int i = 0; i < scene.MaterialCount; i++) { if (materials.ContainsKey(scene.Materials[i].Name)) { model.Materials.Add(new ModelMaterial() { Name = scene.Materials[i].Name, MaterialInstance = new MaterialInstance(materials[scene.Materials[i].Name]) }); continue; } if (!overwrite && File.Exists($"{output}/{scene.Materials[i].Name}{MaterialAsset.FileExtension}")) { Console.WriteLine($"{output}/{scene.Materials[i].Name}{MaterialAsset.FileExtension} exists - not writing parent mesh."); break; } MaterialAsset materialAsset = DiffuseMaterialFactory.Create(); // set diffuse (if possible) if (scene.Materials[i].HasTextureDiffuse) { string diffPath = Path.GetRelativePath(output, Path.Combine(Path.GetDirectoryName(path), scene.Materials[i].TextureDiffuse.FilePath)); TextureAsset asset = ImportTexture(diffPath, TextureType.Diffuse); if (!overwrite && File.Exists($"{output}/{asset.Source.GetFileNameWithoutExtension()}{TextureAsset.FileExtension}")) { Console.WriteLine($"{output}/{asset.Source.GetFileNameWithoutExtension()}{TextureAsset.FileExtension} exists - not writing parent mesh."); break; } AssetFileSerializer.Save($"{output}/{asset.Source.GetFileNameWithoutExtension()}{TextureAsset.FileExtension}", asset, null); Texture tex = GetTexture(asset); SetTexture(materialAsset, tex, TextureType.Diffuse); } // normals if (scene.Materials[i].HasTextureNormal) { string normPath = Path.GetRelativePath(output, Path.Combine(Path.GetDirectoryName(path), scene.Materials[i].TextureNormal.FilePath)); TextureAsset asset = ImportTexture(normPath, TextureType.Normals); if (!overwrite && File.Exists($"{output}/{asset.Source.GetFileNameWithoutExtension()}{TextureAsset.FileExtension}")) { Console.WriteLine($"{output}/{asset.Source.GetFileNameWithoutExtension()}{TextureAsset.FileExtension} exists - not writing parent mesh."); break; } AssetFileSerializer.Save($"{output}/{asset.Source.GetFileNameWithoutExtension()}{TextureAsset.FileExtension}", asset, null); Texture tex = GetTexture(asset); SetTexture(materialAsset, tex, TextureType.Normals); } AssetFileSerializer.Save($"{output}/{scene.Materials[i].Name}{MaterialAsset.FileExtension}", materialAsset, null); Stride.Rendering.Material material = GetMaterial(materialAsset, scene.Materials[i].Name); model.Materials.Add(new ModelMaterial() { Name = scene.Materials[i].Name, MaterialInstance = new MaterialInstance(material) }); materials.Add(scene.Materials[i].Name, material); } AssetFileSerializer.Save($"{output}/{name}{ModelAsset.FileExtension.Split(';')[0]}", model, null); break; default: Console.WriteLine($"The file extension \".{arr[arr.Length - 1]}\" is not supported. ({path})"); break; } }