We add a MouseDown handler method to our Viewport3D :
private void OnViewportMouseDown(object sender, MouseButtonEventArgs e)This method uses the VisualTreeHelper to find which mesh was hitten by the mouse click. If there is a match, we update the index like we did before. Matches are found with this new Cover method :
var rayMeshResult = (RayMeshGeometry3DHitTestResult)VisualTreeHelper.HitTest(viewPort, e.GetPosition(viewPort));
if (rayMeshResult != null)
for (int i = 0; i < coverList.Count; i++)
public bool Matches(MeshGeometry3D mesh)We also modify the TestWindow constructor to load all the pictures from a sample folder :
foreach (GeometryModel3D part in modelGroup.Children)
if (part.Geometry == mesh)
public TestWindow()Mouse click may increment or decrement the index by more than one cover. That's wy we need to fix the UpdateIndex method :
var imageDir = new DirectoryInfo(@"c:\_covers");
int doneImages = 0;
foreach (FileInfo image in imageDir.GetFiles("*.jpg"))
var cover = new Cover(image.FullName, doneImages++);
private void UpdateIndex(int newIndex)It is now time to play with more covers. Let's try the current application with a sample folder containing 500+ covers. These covers are usually between 400x400 and 500x500 pixels. The next Process Explorer capture shows that the application needs a lot of cpu and memory resources :
if (index != newIndex)
int oldIndex = index;
index = newIndex;
if (index > oldIndex)
for (int i = oldIndex; i <= index; i++)
for (int i = oldIndex; i >= index; i--)
camera.Position = new Point3D(.2 * index, camera.Position.Y, camera.Position.Z);
- Loading all covers brings the cpu to 100%.
- Browing all covers with the Right key pressed also needs a lot of cpu. Moreover, this rises the cache size from 300 MB to more than 1 GB.
private ImageSource LoadImageSource(string imagePath)Thumbnails improve performance while browsing, but it is still slow at startup. We will try to improve this later.
var imageFile = new FileInfo(imagePath);
var thumbnailDir = new DirectoryInfo(Path.Combine(imageFile.Directory.FullName, "tn"));
var thumbnail = new FileInfo(Path.Combine(thumbnailDir.FullName, imageFile.Name));
Image source = Image.FromFile(imageFile.FullName);
int height = source.Height;
int width = source.Width;
int factor = (height - 1) / 250 + 1;
int smallHeight = height / factor;
int smallWidth = width / factor;
Image thumb = source.GetThumbnailImage(smallWidth, smallHeight, null, IntPtr.Zero);
return new BitmapImage(new Uri(thumbnail.FullName, UriKind.RelativeOrAbsolute));
Continue with Part 5.
Edit 2014-02-23 : Code has moved to github.