private void exportToAssimp(object sender, EventArgs e) { Debug.WriteLine("Exporting to assimp"); if (RenderState.rootObject != null) { Assimp.AssimpContext ctx = new Assimp.AssimpContext(); Dictionary <int, int> meshImportStatus = new Dictionary <int, int>(); Assimp.Scene aScene = new Assimp.Scene(); Assimp.Node rootNode = RenderState.rootObject.assimpExport(ref aScene, ref meshImportStatus); aScene.RootNode = rootNode; //add a single material for now Assimp.Material aMat = new Assimp.Material(); aMat.Name = "testMaterial"; aScene.Materials.Add(aMat); Assimp.ExportFormatDescription[] supported_formats = ctx.GetSupportedExportFormats(); //Assimp.Scene blenderScene = ctx.ImportFile("SimpleSkin.gltf"); //ctx.ExportFile(blenderScene, "SimpleSkin.glb", "glb2"); try { ctx.ExportFile(aScene, "test.glb", "glb2"); //ctx.ExportFile(aScene, "test.fbx", "fbx"); } catch (Exception ex) { Console.WriteLine(ex.Message); } } }
public override ModelContent Process(Assimp.Scene scene, string filename, ContentProcessorContext context) { try { Assimp.AssimpContext c = new Assimp.AssimpContext(); Assimp.ExportFormatDescription des = c.GetSupportedExportFormats()[0]; //c.ExportFile(scene,Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop),"test.dae"),des.FormatId); ModelContent content = new ModelContent(); content.Meshes = new MeshContent[scene.MeshCount]; for (int meshIndex = 0; meshIndex < scene.MeshCount; meshIndex++) { var sceneMesh = scene.Meshes[meshIndex]; var meshContent = new MeshContent(); meshContent.PrimitiveCount = sceneMesh.FaceCount; meshContent.Vertices = new VertexPositionNormalTexture[meshContent.PrimitiveCount * 3]; int vertex = 0; //TODO: indexing foreach (var f in sceneMesh.Faces) { foreach (var i in f.Indices) { var pos = sceneMesh.Vertices[i]; var norm = sceneMesh.Normals[i]; Assimp.Vector3D tex = new Assimp.Vector3D(); if (sceneMesh.TextureCoordinateChannels.Length > 0 && sceneMesh.TextureCoordinateChannels[0].Count > i) { tex = sceneMesh.TextureCoordinateChannels[0][i]; } var translated = new Vector3(pos.X, pos.Y, pos.Z) + settings.Translate; meshContent.Vertices[vertex++] = new VertexPositionNormalTexture( new Vector3(translated.X * settings.Scale.X, translated.Y * settings.Scale.Y, translated.Z * settings.Scale.Z), new Vector3(norm.X, norm.Y, norm.Z), new Vector2(tex.X, -tex.Y)); } } /*for (int i = 0; i < sceneMesh.VertexCount; i++) * { * * }*/ content.Meshes[meshIndex] = meshContent; } content.Nodes = new List <NodeContent>(); content.RootNode = ParseNode(content, scene.RootNode); foreach (var animation in scene.Animations) { var anim = new AnimationContent(); anim.Channels = new List <AnimationNodeContent>(); foreach (var channel in animation.NodeAnimationChannels) { AnimationNodeContent node = new AnimationNodeContent(); var curNode = content.Nodes.First(n => n.Name == channel.NodeName); node.Node = curNode; node.Frames = new List <AnimationFrame>(); int frameCount = Math.Max(Math.Max(channel.PositionKeyCount, channel.RotationKeyCount), channel.ScalingKeyCount); float diff = 0.0f, maxTime = 0;; for (int i = 0; i < frameCount; i++) { AnimationFrame frame = new AnimationFrame(); if (i < channel.PositionKeyCount) { frame.Frame = (float)channel.PositionKeys[i].Time; } else if (i < channel.RotationKeyCount) { frame.Frame = (float)channel.RotationKeys[i].Time; } else if (i < channel.ScalingKeyCount) { frame.Frame = (float)channel.ScalingKeys[i].Time; } if (i == 0) { diff = frame.Frame; } frame.Frame -= diff; frame.Frame = (float)(frame.Frame / animation.TicksPerSecond); maxTime = Math.Max(frame.Frame, maxTime); //TODO: interpolation var rot = channel.RotationKeyCount == 0 ? new Assimp.Quaternion(1, 0, 0, 0) : i >= channel.RotationKeyCount ? channel.RotationKeys.Last().Value : channel.RotationKeys[i].Value; var loc = channel.PositionKeyCount == 0 ? new Assimp.Vector3D() : i >= channel.PositionKeyCount ? channel.PositionKeys.Last().Value : channel.PositionKeys[i].Value; var sca = channel.ScalingKeyCount == 0 ? new Assimp.Vector3D(1, 1, 1) : i >= channel.ScalingKeyCount ? channel.ScalingKeys.Last().Value : channel.ScalingKeys[i].Value; rot.Normalize(); frame.Transform = new AnimationTransform(node.Node.Name, new Vector3((loc.X + settings.Translate.X), (loc.Y + settings.Translate.Y), (loc.Z + settings.Translate.Z)), new Vector3(sca.X * settings.Scale.X, sca.Y * settings.Scale.Y, sca.Z * settings.Scale.Z), new Quaternion(rot.X, rot.Y, rot.Z, rot.W)); node.Frames.Add(frame); } anim.MaxTime = maxTime; anim.Channels.Add(node); } content.Animations.Add(anim); } PostProcess(content, content.RootNode); return(content); } catch (Exception ex) { context.RaiseBuildMessage(filename, ex.Message, BuildMessageEventArgs.BuildMessageType.Error); } return(null); }
/// <summary> /// Converts a given .GR2 file to a .dae file for rendering and further conversion. /// </summary> /// <param name="filename">The file name.</param> /// <returns>The .dae converted model file.</returns> private static HelixToolkitScene LoadFile(string filename) { var dae = $"{filename}.dae"; if (!File.Exists(dae)) { GeneralHelper.WriteToConsole($"Converting model to .dae for rendering...\n"); var divine = $" -g \"bg3\" --action \"convert-model\" --output-format \"dae\" --source \"\\\\?\\{filename}.GR2\" --destination \"\\\\?\\{dae}\" -l \"all\""; var process = new Process(); var startInfo = new ProcessStartInfo { FileName = Properties.Settings.Default.divineExe, Arguments = divine, WindowStyle = ProcessWindowStyle.Hidden, CreateNoWindow = true, UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = true }; process.StartInfo = startInfo; process.Start(); process.WaitForExit(); GeneralHelper.WriteToConsole(process.StandardOutput.ReadToEnd()); GeneralHelper.WriteToConsole(process.StandardError.ReadToEnd()); } try { var importer = new Importer(); // Update material here? var file = importer.Load(dae); if (file == null && File.Exists(dae)) { GeneralHelper.WriteToConsole("Fixing vertices...\n"); try { var xml = XDocument.Load(dae); var geometryList = xml.Descendants().Where(x => x.Name.LocalName == "geometry").ToList(); foreach (var lod in geometryList) { var vertexId = lod.Descendants().Where(x => x.Name.LocalName == "vertices").Select(x => x.Attribute("id").Value).First(); var vertex = lod.Descendants().Single(x => x.Name.LocalName == "input" && x.Attribute("semantic").Value == "VERTEX"); vertex.Attribute("source").Value = $"#{vertexId}"; } xml.Save(dae); GeneralHelper.WriteToConsole("Model conversion complete!\n"); file = importer.Load(dae); } catch (Exception ex) { // in use by another process GeneralHelper.WriteToConsole($"Error : {ex.Message}\n"); } } if (!File.Exists($"{filename}.fbx")) { var converter = new Assimp.AssimpContext(); var exportFormats = converter.GetSupportedExportFormats().Select(e => e.FormatId); var importFormats = converter.GetSupportedImportFormats(); var imported = converter.ImportFile(dae); converter.ExportFile(imported, $"{filename}.fbx", "fbx"); } importer.Dispose(); return(file); } catch (Exception ex) { GeneralHelper.WriteToConsole($"Error loading .dae: {ex.Message}. Inner exception: {ex.InnerException?.Message}\n"); } return(null); }