private void LoadFile() { var importer = new Importer(); importer.Configuration.CreateSkeletonForBoneSkinningMesh = true; importer.Configuration.SkeletonSizeScale = 0.04f; importer.Configuration.GlobalScale = 0.1f; scene = importer.Load("Solus_The_Knight.fbx"); ModelGroup.AddNode(scene.Root); Animations = scene.Animations.Select(x => x.Name).ToArray(); foreach (var node in scene.Root.Items.Traverse(false)) { if (node is BoneSkinMeshNode m) { if (!m.IsSkeletonNode) { m.IsThrowingShadow = true; m.WireframeColor = new SharpDX.Color4(0, 0, 1, 1); boneSkinNodes.Add(m); m.MouseDown += M_MouseDown; } else { skeletonNodes.Add(m); m.Visible = false; } } } }
private static void LoadModel(GroupNode node, bool renderEnvironmentMap) { OpenFileDialog dialog = new OpenFileDialog(); dialog.Filter = HelixToolkit.SharpDX.Core.Assimp.Importer.SupportedFormatsString; if (dialog.ShowDialog() == DialogResult.OK) { var path = dialog.FileName; exception = ""; currentTime = Stopwatch.GetTimestamp(); loading = true; modelName = Path.GetFileName(path); Task.Run(() => { var importer = new Importer(); return(importer.Load(path)); }).ContinueWith((x) => { loading = false; if (x.IsCompleted && x.Result != null) { node.Clear(); foreach (var model in x.Result.Root.Traverse()) { if (model is MeshNode mesh) { if (mesh.Material is PBRMaterialCore pbr) { pbr.RenderEnvironmentMap = renderEnvironmentMap; } else if (mesh.Material is PhongMaterialCore phong) { phong.RenderEnvironmentMap = renderEnvironmentMap; } } } node.AddChildNode(x.Result.Root); scene = x.Result; if (scene.Animations != null && scene.Animations.Count > 0) { animationUpdaters = scene.Animations.CreateAnimationUpdaters().Values.ToArray(); animationSelection = new bool[animationUpdaters.Count]; animationNames = animationUpdaters.Select((ani) => ani.Name).ToArray(); currentSelectedAnimation = -1; } } else if (x.Exception != null) { exception = x.Exception.Message; } }, TaskScheduler.FromCurrentSynchronizationContext()); } }
/// <summary> /// Exports to file. /// </summary> /// <param name="filePath">The file path.</param> /// <param name="scene">The scene.</param> /// <param name="formatId">The format identifier. <see cref="SupportedFormats"/></param> /// <returns></returns> public ErrorCode ExportToFile(string filePath, HelixToolkitScene scene, string formatId) { if (scene == null) { return(ErrorCode.Failed); } animations = scene.Animations; var code = ExportToFile(filePath, scene.Root, formatId); animations = null; return(code); }
private ErrorCode BuildScene(Scene assimpScene, out HelixToolkitScene scene) { scene = null; if (assimpScene == null) { ErrorCode |= ErrorCode.Failed; return(ErrorCode); } if (!assimpScene.HasMeshes) { scene = new HelixToolkitScene(new HxScene.GroupNode()); ErrorCode = ErrorCode.Succeed; return(ErrorCode.Succeed); } var internalScene = ToHelixScene(assimpScene, Configuration.EnableParallelProcessing); scene = new HelixToolkitScene(ConstructHelixScene(assimpScene.RootNode, internalScene)); ErrorCode |= ProcessSceneNodes(scene.Root); if (ErrorCode.HasFlag(ErrorCode.Failed)) { return(ErrorCode); } if (Configuration.ImportAnimations) { LoadAnimations(internalScene); scene.Animations = Animations.ToArray(); if (Configuration.CreateSkeletonForBoneSkinningMesh && Configuration.AddsPostEffectForSkeleton) { (scene.Root as HxScene.GroupNode).AddChildNode(new HxScene.NodePostEffectXRayGrid() { EffectName = Configuration.SkeletonEffects }); } } if (!ErrorCode.HasFlag(ErrorCode.Failed)) { ErrorCode |= ErrorCode.Succeed; } return(ErrorCode); }
public MainViewModel() { EffectsManager = new DefaultEffectsManager(); ModelGroup = new SceneNodeGroupModel3D(); compositeHelper.Rendering += Render; //Test importing Importer importer = new Importer(); importer.Configuration.CreateSkeletonForBoneSkinningMesh = true; importer.Configuration.SkeletonSizeScale = 0.01f; importer.Configuration.GlobalScale = 0.1f; scn = importer.Load("Gunan_animated.fbx"); //Add to model group for rendering ModelGroup.AddNode(scn.Root); //Setup each animation, this will actively play all (not always desired) animationUpdaters = new List <IAnimationUpdater>(scn.Animations.CreateAnimationUpdaters().Values); }
public void LoadModel(string fileName) { var dialogViewModel = new DialogViewModel(); HelixToolkitScene scene = null; dialogViewModel.AddTask ( (taskContext) => { taskContext.UpdateMessage($"Loading model {Path.GetFileNameWithoutExtension(fileName)}"); var loader = new Importer(); scene = loader.Load(fileName); taskContext.UpdateProgress(100); } ); this.windowManager.ShowDialog(dialogViewModel); GroupModel.Clear(); if (scene != null) { this.sceneNode = scene.Root; GroupModel.AddNode(this.sceneNode); this.SetSceneMaterials(); } }
//--------------------------------------------------------------------------------------------------------- /// <summary> /// Открытие файла /// </summary> //--------------------------------------------------------------------------------------------------------- public void OpenFile(TreeView model_tree_view) { if (mIsLoading) { return; } String path = XFileDialog.OpenUseExtension("Открыть 3D файл", OpenFileFilter); if (path == null) { return; } StopAnimation(); // Create the FBX SDK manager FbxManager lSdkManager = FbxManager.Create(); // Create an IOSettings object. FbxIOSettings ios = FbxIOSettings.Create(lSdkManager, Globals.IOSROOT); lSdkManager.SetIOSettings(ios); // ... Configure the FbxIOSettings object ... // Create an importer. FbxImporter lImporter = FbxImporter.Create(lSdkManager, ""); // Initialize the importer. bool lImportStatus = lImporter.Initialize(path, -1, lSdkManager.GetIOSettings()); mIsLoading = true; Task.Run(() => { var loader = new Importer(); //loader.Configuration.AssimpPostProcessSteps = //loader.Configuration.AssimpPostProcessSteps | //Assimp.PostProcessSteps.OptimizeGraph; return(loader.Load(path)); }).ContinueWith((result) => { mIsLoading = false; if (result.IsCompleted) { HelixToolkitScene helix_toolkit_scene = result.Result; if (helix_toolkit_scene == null) { return; } mSceneRoot = helix_toolkit_scene.Root; mSceneAnimations = helix_toolkit_scene.Animations; Animations.Clear(); GroupModel.Clear(); if (helix_toolkit_scene != null) { if (helix_toolkit_scene.Root != null) { foreach (var node in helix_toolkit_scene.Root.Traverse()) { if (node is MaterialGeometryNode m) { if (m.Material is PBRMaterialCore pbr) { pbr.RenderEnvironmentMap = RenderEnvironmentMap; } else if (m.Material is PhongMaterialCore phong) { phong.RenderEnvironmentMap = RenderEnvironmentMap; } } } } GroupModel.AddNode(helix_toolkit_scene.Root); if (helix_toolkit_scene.HasAnimation) { var dict = helix_toolkit_scene.Animations.CreateAnimationUpdaters(); foreach (var animation in dict.Values) { Animations.Add(animation); } } foreach (var node in helix_toolkit_scene.Root.Traverse()) { //node.Tag = new AttachedNodeViewModel(node); } } Boolean is_y_up = threeViewer.IsModelUpDirectionY(); checkBoxYUpModel.IsChecked = is_y_up; if (is_y_up) { } model_tree_view.ItemsSource = mSceneRoot.Items; //Scene = new CScene3D() } else if (result.IsFaulted && result.Exception != null) { MessageBox.Show(result.Exception.Message); } }, TaskScheduler.FromCurrentSynchronizationContext()); }
/// <summary> /// Convert the assimp scene to Helix Scene. /// </summary> /// <param name="assimpScene">The assimp scene.</param> /// <param name="filePath">The filePath of the model. It is used for texture loading</param> /// <param name="texturePathResolver">Custom texture path resolver</param> /// <param name="scene">The scene.</param> /// <returns></returns> public ErrorCode Load(Scene assimpScene, string filePath, out HelixToolkitScene scene, ITexturePathResolver texturePathResolver = null) { path = filePath; Configuration.TexturePathResolver = texturePathResolver; return(BuildScene(assimpScene, out scene)); }
/// <summary> /// Loads the specified file stream. User must provider custom texture loader to load texture files. /// </summary> /// <param name="fileStream">The file stream.</param> /// <param name="filePath">The filePath. Used to load texture.</param> /// <param name="formatHint">The format hint.</param> /// <param name="texturePathResolver">The custom texture path resolver</param> /// <param name="scene">The scene.</param> /// <returns></returns> public ErrorCode Load(Stream fileStream, string filePath, string formatHint, out HelixToolkitScene scene, ITexturePathResolver texturePathResolver = null) { path = filePath; ErrorCode = ErrorCode.None; AssimpContext importer = null; var useExtern = false; if (Configuration.ExternalContext != null) { importer = Configuration.ExternalContext; useExtern = true; } else { importer = new AssimpContext(); } configuration.TexturePathResolver = texturePathResolver; Clear(); scene = null; try { if (!importer.IsImportFormatSupported(formatHint)) { return(ErrorCode.FileTypeNotSupported | ErrorCode.Failed); } if (!useExtern && Configuration.AssimpPropertyConfig != null) { foreach (var config in Configuration.AssimpPropertyConfig) { importer.SetConfig(config); } } importer.Scale = configuration.GlobalScale; var postProcess = configuration.AssimpPostProcessSteps; if (configuration.FlipWindingOrder) { postProcess |= PostProcessSteps.FlipWindingOrder; } var assimpScene = importer.ImportFileFromStream(fileStream, postProcess, formatHint); return(BuildScene(assimpScene, out scene)); } catch (Exception ex) { logger.LogError(ex.Message); ErrorCode = ErrorCode.Failed; AssimpExceptionOccurred?.Invoke(this, ex); return(ErrorCode); } finally { if (!useExtern) { importer.Dispose(); } } }
/// <summary> /// Converts HelixToolkit Scene directly from assimp scene. User is responsible for providing the assimp scene. /// </summary> /// <param name="assimpScene">The assimp scene.</param> /// <param name="helixScene">The helix scene.</param> /// <returns></returns> public ErrorCode ToHelixToolkitScene(Scene assimpScene, out HelixToolkitScene helixScene) { return(BuildScene(assimpScene, out helixScene)); }
private void button1_Click(object sender, EventArgs e) { //Clear the variables for second use objReady = ""; Diffuse = new Dictionary <string, string>(); Specular = new Dictionary <string, string>(); Normal = new Dictionary <string, string>(); MaterialList = new Dictionary <string, string>(); imageType = 0; scene2 = null; //Clear the variables for second use OpenFileDialog ofd = new OpenFileDialog(); ofd.Filter = "Blender Files | *.blend"; if (ofd.ShowDialog() == DialogResult.Cancel) { return; } List <int> VertexCounts = new List <int>(); progressBar1.Value = 10; Importer importer = new Importer(); scene2 = importer.Load(ofd.FileName); HelixToolkit.Wpf.SharpDX.Assimp.Exporter exporter = new HelixToolkit.Wpf.SharpDX.Assimp.Exporter(); exporter.ExportToFile("Temp.dae", scene2.Root, "collada"); string file = File.ReadAllText("Temp.dae"); int LastLine = 0; foreach (SceneNode node in scene2.Root.Items) { string Node = ""; string subbedString = file.Substring(LastLine); if (subbedString.Contains("<node id=")) { Node = subbedString.Substring(subbedString.IndexOf("<node id="), subbedString.IndexOf("</node>") + "</node>".Length - subbedString.IndexOf("<node id=")); if (!Node.Contains("<instance_geometry")) { file = file.Replace(Node, ""); } } else { break; } LastLine = subbedString.IndexOf("</node>") + "</node>".Length + LastLine - Node.Length; } Texture texture = new Texture(); File.WriteAllText("Temp.dae", file); scene2 = importer.Load("Temp.dae"); var lines = File.ReadLines("Temp.dae"); progressBar1.Value = 20; string MaterialName = "EmptyName"; string ItemName = "EmptyItem"; MaterialList.Clear(); foreach (string line in lines) { if (line.Contains("-positions-array\" count=\"")) { VertexCounts.Add(Convert.ToInt32(Regex.Match(line.Substring(line.IndexOf("-positions-array\" count=\"") + "-positions-array\" count=\"".Length, line.IndexOf("\">") - 59), @"\d+").Value) / 3); } else if (line.Contains("<init_from>")) { if (line.Contains(@":\")) { if (imageType == 0) { Diffuse.Add(MaterialName, line.Substring(line.LastIndexOf(@"\") + 1, line.IndexOf(".") - line.LastIndexOf(@"\") - 1)); } if (imageType == 1) { Specular.Add(MaterialName, line.Substring(line.LastIndexOf(@"\") + 1, line.IndexOf(".") - line.LastIndexOf(@"\") - 1)); } if (imageType == 2) { Normal.Add(MaterialName, line.Substring(line.LastIndexOf(@"\") + 1, line.IndexOf(".") - line.LastIndexOf(@"\") - 1)); } } } else if (line.Contains("<image id=\"")) { if (line.Contains("-diffuse")) { imageType = 0; MaterialName = line.Substring(line.IndexOf("<image id=\"") + "<image id=\"".Length, line.IndexOf("-diffuse") - 3 - line.IndexOf("<image id=\"") - "-diffuse".Length); } else if (line.Contains("-normal")) { imageType = 2; MaterialName = line.Substring(line.IndexOf("<image id=\"") + "<image id=\"".Length, line.IndexOf("-specular") - 3 - line.IndexOf("<image id=\"") - "-specular".Length); } else if (line.Contains("-specular")) { imageType = 1; MaterialName = line.Substring(line.IndexOf("<image id=\"") + "<image id=\"".Length, line.IndexOf("-normal") - 3 - line.IndexOf("<image id=\"") - "-normal".Length); } } else if (line.Contains("<node id=\"")) { ItemName = line.Substring(line.IndexOf("<node id=\"") + "<node id=\"".Length, line.IndexOf("\" name=\"") - (line.IndexOf("<node id=\"") + "<node id=\"".Length)); } else if (line.Contains("target=\"")) { MaterialList.Add(ItemName, line.Substring(line.IndexOf("target=\"#") + "target=\"#".Length, line.IndexOf("\">") - (line.IndexOf("target=\"#") + "target=\"#".Length))); } } string EmptyDae = Resources.Empty; string Obj = File.ReadAllText("Temp.dae"); string Geometries = "<library_geometries>" + @" "; progressBar1.Value = 30; string librarygeometries = Obj.Substring(Obj.IndexOf("<library_geometries>"), Obj.LastIndexOf("</library_geometries>") - Obj.IndexOf("<library_geometries>") + "</library_geometries>".Length); int id = 0; foreach (SceneNode item in scene2.Root.Traverse()) { if (item is MeshNode) { if (librarygeometries.Contains("<geometry id=")) { string Geo; if (id == 0) { Geo = librarygeometries.Substring(librarygeometries.IndexOf("<geometry id="), librarygeometries.IndexOf("</geometry>") - 13); } else { Geo = librarygeometries.Substring(librarygeometries.IndexOf("<geometry id="), librarygeometries.IndexOf("</geometry>") - librarygeometries.IndexOf("<geometry id=")); } if (!Geo.Contains(@"-color0"" name=""meshId""")) { string colorReference = Geo.Substring(0, Geo.LastIndexOf("/>") + 2) + @" <input offset=""0"" semantic=""COLOR"" source=""#meshId" + id + @"-color0"" set=""0"" />" + Geo.Substring(Geo.LastIndexOf("/>") + 2); Geo = colorReference.Substring(0, colorReference.LastIndexOf("</source>") + "</source>".Length) + @" <source id=""meshId" + id + @"-color0"" name=""meshId" + id + @"-color0""> <float_array id=""meshId" + id + @"-color0-array"" count=""" + VertexCounts[id] * 3 + @"""> " + String.Concat(Enumerable.Repeat("1 ", VertexCounts[id] * 3)) + @" </float_array> <technique_common> <accessor count=""" + VertexCounts[id] * 3 + @""" offset=""0"" source=""#meshId" + id + @"-color0-array"" stride=""3""> <param name=""R"" type=""float"" /> <param name=""G"" type=""float"" /> <param name=""B"" type=""float"" /> </accessor> </technique_common> </source>" + colorReference.Substring(colorReference.LastIndexOf("</source>") + "</source>".Length); } if (id == 0) { Geometries = Geometries + Geo; } else { Geometries = Geometries + Geo + @"</geometry> "; } if (id == 0) { librarygeometries = librarygeometries.Remove(librarygeometries.IndexOf("<geometry id="), librarygeometries.IndexOf("</geometry>") + "</geometry>".Length - librarygeometries.IndexOf("<geometry id=")); } else { librarygeometries = librarygeometries.Remove(librarygeometries.IndexOf("<geometry id="), librarygeometries.IndexOf("</geometry>") + "</geometry>".Length - librarygeometries.IndexOf("<geometry id=")); } } id++; } } progressBar1.Value = 50; Geometries = Geometries + "</library_geometries>" + @" "; string objWithGeo = EmptyDae.Substring(0, 5957) + @" " + Geometries + @" " + EmptyDae.Substring(EmptyDae.IndexOf("<library_controllers>")); int loopnumber = 0; string objWithSkin = objWithGeo.Substring(0, objWithGeo.LastIndexOf("</library_controllers>")); progressBar1.Value = 60; foreach (SceneNode Item in scene2.Root.Items) { if (id > VertexCounts.Count) { id--; } string controller = @"<controller id=""meshId0-skin"" name=""skinCluster0""> <skin source=""#meshId0""> <bind_shape_matrix> 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 </bind_shape_matrix> <source id=""meshId0-skin-joints"" name=""meshId0-skin-joints""> <Name_array id=""meshId0-skin-joints-array"" count=""1"">EnterCatMarioStepB </Name_array> <technique_common> <accessor source=""#meshId0-skin-joints-array"" count=""1"" stride=""1""> <param name=""JOINT"" type=""Name""></param> </accessor> </technique_common> </source> <source id=""meshId0-skin-bind_poses"" name=""meshId0-skin-bind_poses""> <float_array id=""meshId0-skin-bind_poses-array"" count=""16""> 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 </float_array> <technique_common> <accessor count=""1"" offset=""0"" source=""#meshId0-skin-bind_poses-array"" stride=""16""> <param name=""TRANSFORM"" type=""float4x4"" /> </accessor> </technique_common> </source> <source id=""meshId0-skin-weights"" name=""meshId0-skin-weights""> <float_array id=""meshId0-skin-weights-array"" count=""1654"">" + String.Concat(Enumerable.Repeat("1 ", VertexCounts[loopnumber])) + @" </float_array> <technique_common> <accessor count=" + "\"" + VertexCounts[loopnumber] + "\"" + @" offset =""0"" source=""#meshId0-skin-weights-array"" stride=""1""> <param name=""WEIGHT"" type=""float"" /> </accessor> </technique_common> </source> <joints> <input semantic=""JOINT"" source=""#meshId0-skin-joints""></input> <input semantic=""INV_BIND_MATRIX"" source=""#meshId0-skin-bind_poses""></input> </joints> <vertex_weights count=" + "\"" + VertexCounts[loopnumber] + "\"" + @"> <input semantic=""JOINT"" source=""#meshId0-skin-joints"" offset=""0""></input> <input semantic=""WEIGHT"" source=""#meshId0-skin-weights"" offset=""1""></input> <vcount>" + String.Concat(Enumerable.Repeat("1 ", VertexCounts[loopnumber])) + " </vcount>"; string ControllerFixed = controller.Replace("skinCluster0", "skinCluster" + loopnumber); string vertexWeights = MakeZeroVertexWeights(VertexCounts[loopnumber]); objWithSkin = objWithSkin + @" " + ControllerFixed.Replace("meshId0", "meshId" + loopnumber) + @" " + vertexWeights; loopnumber++; } progressBar1.Value = 80; objWithSkin = objWithSkin + objWithGeo.Substring(objWithGeo.LastIndexOf("</library_controllers>")); string Object = objWithSkin.Substring(0, objWithSkin.LastIndexOf(@"<visual_scene id=""Bfres"" name=""Bfres"">")); Object = Object + Obj.Substring(Obj.IndexOf("<visual_scene id="), Obj.IndexOf("</visual_scene>") - Obj.IndexOf("<visual_scene id=")).Replace("<BlenderRoot>", "Bfres"); Object = Object.Substring(0, Object.IndexOf(@"<visual_scene id=""Bfres"" name=""Bfres"">") + @"<visual_scene id=""Bfres"" name=""Bfres"">".Length) + @" " + @"<node id=""EmptyBoneName"" sid=""EmptyBoneName"" name=""EmptyBoneName"" type=""JOINT""> <matrix sid=""matrix"">1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1</matrix> </node>" + Object.Substring(Object.IndexOf(@"<visual_scene id=""Bfres"" name=""Bfres"">") + @"<visual_scene id=""Bfres"" name=""Bfres"">".Length); int loopingNumber = 0; foreach (SceneNode node in scene2.Root.Items) { Object = Object.Replace(@"<instance_geometry url=""#meshId" + loopingNumber + @""">", @"<instance_controller url=""#meshId" + loopingNumber + @"-skin""> <skeleton>#EmptyBoneName</skeleton>"); Object = Object.Replace("</instance_geometry>", "</instance_controller>"); loopingNumber++; } Debug.WriteLine(Object); progressBar1.Value = 90; progressBar1.Value = 100; objReady = Object + objWithSkin.Substring(objWithSkin.LastIndexOf("</visual_scene>")); if (textBox1.Text != "") { objReady = objReady.Replace("EmptyBoneName", textBox1.Text); objReady = objReady.Replace("Bfres", textBox1.Text); } File.Delete("Temp.dae"); MessageBox.Show("Successfuly imported from " + ofd.FileName + "!"); progressBar1.Value = 0; }