Reputation: 1
For some reason I can't see any of the models I'm importing into this Helix viewport I've set up. I've tried a thousand code combinations, drawing from the examples in the HelixToolkit git as well. Nothing. No errors, no exceptions, no crashes, nothing at all. The models simply aren't visible, even though I know for a fact the program is parsing them because it used to throw exceptions at me. Maybe it's just, you know, something really dumb I'm overlooking, but right now I'm drawing a blank.
(Slightly modified) code from model importer demo with some really simple console outputs for debugging purposes:
// MainViewModel.cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using HelixToolkit.Wpf.SharpDX;
using HelixToolkit.Wpf.SharpDX.Animations;
using HelixToolkit.Wpf.SharpDX.Assimp;
using HelixToolkit.Wpf.SharpDX.Controls;
using HelixToolkit.Wpf.SharpDX.Model;
using HelixToolkit.Wpf.SharpDX.Model.Scene;
using Microsoft.Win32;
using MvvmHelpers;
using Point3D = System.Windows.Media.Media3D.Point3D;
using Vector3D = System.Windows.Media.Media3D.Vector3D;
using Color = System.Windows.Media.Color;
using Colors = System.Windows.Media.Colors;
using SharpDX;
using JulMar.Windows.Mvvm;
using System.Linq;
namespace FileLoadDemo
{
public class MainViewModel : BaseViewModel
{
private string OpenFileFilter = $"{HelixToolkit.Wpf.SharpDX.Assimp.Importer.SupportedFormatsString}";
private string ExportFileFilter = $"{HelixToolkit.Wpf.SharpDX.Assimp.Exporter.SupportedFormatsString}";
private bool showWireframe = false;
public bool ShowWireframe
{
set
{
if (SetProperty(ref showWireframe, value))
{
ShowWireframeFunct(value);
}
}
get
{
return showWireframe;
}
}
private bool renderFlat = false;
public bool RenderFlat
{
set
{
if (SetProperty(ref renderFlat, value))
{
RenderFlatFunct(value);
}
}
get
{
return renderFlat;
}
}
private bool renderEnvironmentMap = true;
public bool RenderEnvironmentMap
{
set
{
if (SetProperty(ref renderEnvironmentMap, value) && scene != null && scene.Root != null)
{
foreach (var node in scene.Root.Traverse())
{
if (node is MaterialGeometryNode m && m.Material is PBRMaterialCore material)
{
material.RenderEnvironmentMap = value;
}
}
}
}
get => renderEnvironmentMap;
}
public ICommand OpenFileCommand { get; set; }
public DefaultEffectsManager EffectsManager { get; }
public OrthographicCamera Camera { get; }
public ICommand ResetCameraCommand { get; set; }
public ICommand ExportCommand { private set; get; }
public ICommand CopyAsBitmapCommand { private set; get; }
public ICommand CopyAsHiresBitmapCommand { private set; get; }
private bool isLoading = false;
public bool IsLoading
{
private set => SetProperty(ref isLoading, value);
get => isLoading;
}
private bool isPlaying = false;
public bool IsPlaying
{
private set => SetProperty(ref isPlaying, value);
get => isPlaying;
}
private float startTime;
public float StartTime
{
private set => SetProperty(ref startTime, value);
get => startTime;
}
private float endTime;
public float EndTime
{
private set => SetProperty(ref endTime, value);
get => endTime;
}
private float currAnimationTime = 0;
public float CurrAnimationTime
{
set
{
if (EndTime == 0)
{ return; }
if (SetProperty(ref currAnimationTime, value % EndTime + StartTime))
{
animationUpdater?.Update(value, 1);
}
}
get => currAnimationTime;
}
public ObservableCollection<IAnimationUpdater> Animations { get; } = new ObservableCollection<IAnimationUpdater>();
public SceneNodeGroupModel3D GroupModel { get; } = new SceneNodeGroupModel3D();
private IAnimationUpdater selectedAnimation = null;
public IAnimationUpdater SelectedAnimation
{
set
{
if (SetProperty(ref selectedAnimation, value))
{
StopAnimation();
CurrAnimationTime = 0;
if (value != null)
{
animationUpdater = value;
animationUpdater.Reset();
animationUpdater.RepeatMode = AnimationRepeatMode.Loop;
StartTime = value.StartTime;
EndTime = value.EndTime;
}
else
{
animationUpdater = null;
StartTime = EndTime = 0;
}
}
}
get
{
return selectedAnimation;
}
}
private float speed = 1.0f;
public float Speed
{
set
{
SetProperty(ref speed, value);
}
get => speed;
}
private Point3D modelCentroid = default;
public Point3D ModelCentroid
{
private set => SetProperty(ref modelCentroid, value);
get => modelCentroid;
}
private BoundingBox modelBound = new BoundingBox();
public BoundingBox ModelBound
{
private set => SetProperty(ref modelBound, value);
get => modelBound;
}
public TextureModel EnvironmentMap { get; }
public ICommand PlayCommand { get; }
private SynchronizationContext context = SynchronizationContext.Current;
private HelixToolkitScene scene;
private IAnimationUpdater animationUpdater;
private List<BoneSkinMeshNode> boneSkinNodes = new List<BoneSkinMeshNode>();
private List<BoneSkinMeshNode> skeletonNodes = new List<BoneSkinMeshNode>();
private CompositionTargetEx compositeHelper = new CompositionTargetEx();
private long initTimeStamp = 0;
public MainViewModel(DefaultEffectsManager effectsManager)
{
EffectsManager = effectsManager;
this.OpenFileCommand = new DelegateCommand(this.OpenFile);
Camera = new OrthographicCamera()
{
LookDirection = new System.Windows.Media.Media3D.Vector3D(0, -10, -10),
Position = new System.Windows.Media.Media3D.Point3D(0, 10, 10),
UpDirection = new System.Windows.Media.Media3D.Vector3D(0, 1, 0),
FarPlaneDistance = 5000,
NearPlaneDistance = 0.1f
};
ResetCameraCommand = new DelegateCommand(() =>
{
(Camera as OrthographicCamera).Reset();
(Camera as OrthographicCamera).FarPlaneDistance = 5000;
(Camera as OrthographicCamera).NearPlaneDistance = 0.1f;
});
ExportCommand = new DelegateCommand(() => { ExportFile(); });
CopyAsBitmapCommand = new DelegateCommand(() => { CopyAsBitmapToClipBoard(); });
CopyAsHiresBitmapCommand = new DelegateCommand(() => { CopyAsHiResBitmapToClipBoard(); });
EnvironmentMap = TextureModel.Create("Cubemap_Grandcanyon.dds");
PlayCommand = new DelegateCommand(() =>
{
if (!IsPlaying && SelectedAnimation != null)
{
StartAnimation();
}
else
{
StopAnimation();
}
});
}
private void CopyAsBitmapToClipBoard()
{
var bitmap = ViewportExtensions.RenderBitmap((Viewport3DX)Application.Current.MainWindow.FindName("view"));
try
{
Clipboard.Clear();
Clipboard.SetImage(bitmap);
}
catch (Exception e)
{
Debug.WriteLine(e);
}
}
private void CopyAsHiResBitmapToClipBoard()
{
var stopwatch = new Stopwatch();
stopwatch.Start();
var bitmap = ViewportExtensions.RenderBitmap((Viewport3DX)Application.Current.MainWindow.FindName("view"), 1920, 1080);
try
{
Clipboard.Clear();
Clipboard.SetImage(bitmap);
stopwatch.Stop();
Debug.WriteLine($"creating bitmap needs {stopwatch.ElapsedMilliseconds} ms");
}
catch (Exception e)
{
Debug.WriteLine(e);
}
}
private void OpenFile()
{
if (isLoading)
{
Console.WriteLine("Loading");
return;
}
string path = OpenFileDialog(OpenFileFilter);
if (path == null)
{
Console.WriteLine("Null path");
return;
}
StopAnimation();
var syncContext = SynchronizationContext.Current;
IsLoading = true;
Task.Run(() =>
{
var loader = new Importer();
var scene = loader.Load(path);
scene.Root.Attach(EffectsManager); // Pre attach scene graph
Console.WriteLine("Attached scene graph");
scene.Root.UpdateAllTransformMatrix();
Console.WriteLine("Transform matrix updated");
if (scene.Root.TryGetBound(out var bound))
{
/// Must use UI thread to set value back.
syncContext.Post((o) => { ModelBound = bound; }, null);
}
if (scene.Root.TryGetCentroid(out var centroid))
{
/// Must use UI thread to set value back.
syncContext.Post((o) => { ModelCentroid = centroid.ToPoint3D(); }, null);
}
return scene;
}).ContinueWith((result) =>
{
IsLoading = false;
Console.WriteLine("Completed");
if (result.IsCompleted)
{
scene = result.Result;
Animations.Clear();
var oldNode = GroupModel.SceneNode.Items.ToArray();
GroupModel.Clear(false);
Task.Run(() =>
{
foreach (var node in oldNode)
{ node.Dispose(); }
});
if (scene != null)
{
if (scene.Root != null)
{
foreach (var node in scene.Root.Traverse())
{
if (node is MaterialGeometryNode m)
{
//m.Geometry.SetAsTransient();
if (m.Material is PBRMaterialCore pbr)
{
pbr.RenderEnvironmentMap = RenderEnvironmentMap;
Console.WriteLine("pbr");
}
else if (m.Material is PhongMaterialCore phong)
{
phong.RenderEnvironmentMap = RenderEnvironmentMap;
Console.WriteLine("phong");
}
}
}
}
GroupModel.AddNode(scene.Root);
if (scene.HasAnimation)
{
var dict = scene.Animations.CreateAnimationUpdaters();
foreach (var ani in dict.Values)
{
Animations.Add(ani);
}
}
FocusCameraToScene();
}
}
else if (result.IsFaulted && result.Exception != null)
{
MessageBox.Show(result.Exception.Message);
}
}, TaskScheduler.FromCurrentSynchronizationContext());
}
public void StartAnimation()
{
initTimeStamp = Stopwatch.GetTimestamp();
compositeHelper.Rendering += CompositeHelper_Rendering;
IsPlaying = true;
}
public void StopAnimation()
{
IsPlaying = false;
compositeHelper.Rendering -= CompositeHelper_Rendering;
}
private void CompositeHelper_Rendering(object sender, System.Windows.Media.RenderingEventArgs e)
{
if (animationUpdater != null)
{
var elapsed = (Stopwatch.GetTimestamp() - initTimeStamp) * speed;
CurrAnimationTime = elapsed / Stopwatch.Frequency;
}
}
private void FocusCameraToScene()
{
var maxWidth = Math.Max(Math.Max(modelBound.Width, modelBound.Height), modelBound.Depth);
var pos = modelBound.Center + new Vector3(0, 0, maxWidth);
Camera.Position = pos.ToPoint3D();
Camera.LookDirection = (modelBound.Center - pos).ToVector3D();
Camera.UpDirection = Vector3.UnitY.ToVector3D();
if (Camera is OrthographicCamera orthCam)
{
orthCam.Width = maxWidth;
}
}
private void ExportFile()
{
var index = SaveFileDialog(ExportFileFilter, out var path);
if (!string.IsNullOrEmpty(path) && index >= 0)
{
var id = HelixToolkit.Wpf.SharpDX.Assimp.Exporter.SupportedFormats[index].FormatId;
var exporter = new HelixToolkit.Wpf.SharpDX.Assimp.Exporter();
exporter.ExportToFile(path, scene, id);
return;
}
}
private string OpenFileDialog(string filter)
{
var d = new OpenFileDialog();
d.CustomPlaces.Clear();
d.Filter = filter;
if (!d.ShowDialog().Value)
{
return null;
}
return d.FileName;
}
private int SaveFileDialog(string filter, out string path)
{
var d = new SaveFileDialog();
d.Filter = filter;
if (d.ShowDialog() == true)
{
path = d.FileName;
return d.FilterIndex - 1; // This is starting from 1. So must minus 1
}
else
{
path = "";
return -1;
}
}
private void ShowWireframeFunct(bool show)
{
foreach (var node in GroupModel.GroupNode.Items.PreorderDFT((node) => node.IsRenderable))
{
if (node is MeshNode m)
{
m.RenderWireframe = show;
}
}
}
private void RenderFlatFunct(bool show)
{
foreach (var node in GroupModel.GroupNode.Items.PreorderDFT((node) => node.IsRenderable))
{
if (node is MeshNode m)
{
if (m.Material is PhongMaterialCore phong)
{
phong.EnableFlatShading = show;
}
else if (m.Material is PBRMaterialCore pbr)
{
pbr.EnableFlatShading = show;
}
}
}
}
}
}
The code I'm attempting to call previous code from:
using System;
using System.Windows.Forms;
using System.Windows.Forms.Integration;
using HelixToolkit.Wpf.SharpDX.Controls;
using FileLoadDemo;
using HelixToolkit.Wpf.SharpDX;
namespace Intelligencecasinos_Animation_Maker
{
public partial class Form3 : Form
{
private Viewport3DX viewport;
private MainViewModel viewModel;
private DefaultEffectsManager effectsManager;
public Form3()
{
InitializeComponent();
this.Load += Form3_Load;
}
private void Form3_Load(object sender, EventArgs e)
{
InitializeEffectsManager();
InitializeHelixViewport();
InitializeViewModel();
}
private void CreateGrid()
{
var grid = new AxisPlaneGridModel3D();
viewport.Items.Add(grid);
}
private void InitializeEffectsManager()
{
effectsManager = new DefaultEffectsManager();
}
private void InitializeHelixViewport()
{
viewport = new Viewport3DX
{
Name = "view",
EffectsManager = effectsManager,
Camera = new PerspectiveCamera
{
LookDirection = new System.Windows.Media.Media3D.Vector3D(0, -10, -10),
Position = new System.Windows.Media.Media3D.Point3D(0, 10, 10),
UpDirection = new System.Windows.Media.Media3D.Vector3D(0, 1, 0),
FarPlaneDistance = 5000,
NearPlaneDistance = 0.1f
},
BackgroundColor = System.Windows.Media.Color.FromRgb(30, 30, 30) // Dark background
};
// Create a WindowsFormsHost to host the WPF control
var host = new ElementHost
{
Dock = DockStyle.Fill,
Child = viewport
};
// Add the WindowsFormsHost to the existing viewportPanel
CreateGrid();
viewportPanel.Controls.Add(host);
}
private void InitializeViewModel()
{
viewModel = new MainViewModel(effectsManager);
viewport.DataContext = viewModel;
viewport.Items.Add(viewModel.GroupModel);
Console.WriteLine("Viewmodel initialized");
}
private void openToolStripMenuItem_Click(object sender, EventArgs e)
{
viewModel.OpenFileCommand.Execute(null);
}
}
}
Upvotes: 0
Views: 171