WPF 3D Demo - Solar System
The Demo
Download Binaries and Source Code (833K zip)
SolarSystem is a WPF demo showing WPF 3D, control templates, and data binding techniques. You will need Visual Studio 2008 to compile the demo.
The proram displays the Earth rotating around the Sun (body sizes are not to scale), with a realistic texture depicting Earth oceans and continents. Sun facing side of the Earth is illuminated by a light source placed in the Sun. The program also correctly shows the Earth axis tilt, which makes possible to observe the change of seasons, and the polar day/polar night effect around the poles.
Click and drug the mouse to rotate the scene. Use controls on the right side to change the time scale, pause or reverse time, and show/hide the Earth orbit plane.
Unfortunately, current version of Silverlight does not support 3D features, so it is not possible to run the demo as a Silverlight application. You must download the code and run it locally.
Lessons Learnt While Building the Demo
3D Primitives, or Lack Thereof
WPF does not provide built-in 3D objects like spheres and cubes. All 3D bodies must be built either "by hand" as a list of triangles, by exporting meshes from third party packages like 3D Max, or by building the meshes in code. In this project we chose the latter.
Animations Are Not for Continuous Action
My attempt to base Earth rotation on an animation failed. I did not find an animation that would run a "time" property continously to infinity, and I also had difficulty animating a property on my model class, as opposed to a visual property of an object, but this apparently could be overcome, see "Animating a viewmodel property" on social.msdn.com. I found it easier to run a timer and handle the time myself.
You Do Need Expression Blend
It is possible to create XAML for simple UIs exclusively by hand, but for anything even slightly complicated you need Expression Blend. This gives you WYSIWYG. Having to switch between two editors is annoying, but then you don't have to wait for the next version of Visual Studio to get the new features. From the other hand, they could have made it a plugin or something - version independence does not necessarily has to drag with it two different UIs.
Control Templates Rock
You use control templates to customize the view of controls such as check boxes, while keeping the standard behavior: checkbox changes state when clicked, etc. This is one of the coolest feature of WPF in my opinion, since to achieve the same in Windows Forms, or Win32 API you had to write a lot of code. I am especially fond of ContentPresenter, which basically provides a way to say "user supplied content goes here".
I was a little annoyed, however, but the rules on the triggers. E.g. you can switch the checkbox image in the control template - one image for checked, another for unchecked, but you cannot control the Foreground property of the control. You need to define a style for that.
Expression Design is Fun
I created the checkbox images in Microsoft Expression Design. I don't want to brag, but for a person with very limited artistic abilities like myself, the images look quite impressive. Seasoned graphics designers will probably scoff at the lack of advanced features, but Expression Design is ideal for programmers. It is straightforward and easy to use, unlike some parts of Photoshop that still baffle me. Maybe it's a difference between an artistic brain and a programmer's brain.
Emissive Materials are Tricky
It is not recommended to create a body out of emissive material alone. You must always combine an emissive material with a diffuse material, or else weird things will happen. Also, the diffuse material must come first in the material group.
WPF Bodies Don't Have Visible Property
GeometryModel3D
does not have Visible
property.
In my Surface
class I add it on my own. When the body must
become invisible, I set its material to null, thus rendering it out of
existence.
Notes about The Source Code
The source has two projects: Surfaces and SolarSystem. Surfaces is a class library that provides primitives for sphere and circle, as well as Microsoft classes for dragging the scene around with the mouse.
SolarSystem is an executable project that (you guessed!) displays the
Solar System. The focal point is OrbitsCalculator
class
that runs the timer and determines position and rotation angle of the
Sun and the Earth based on current time. This is our ViewModel class
that has numerous bindings to MainWindow.Xaml
. The project
has minimal code in MainWindow.Xaml.cs
- all the logic is
in the OrbitsCalculator
.
ToDo List
- Create better mesh for sphere - with triangles more evenly spaced
- Come up with a better trackball implementation, so you can click on Earth and drag it, and it will remain under the cursor
- Create zoom feature
- Add the Moon? Solar eclipses maybe?