Introduction

Yes, this is another rotating cube example in WPF. But it's also the first part of my series that will present how to make an animated walking robot in WPF using C# code. Very little XAML is used in this project because we are modeling everything in C# code. In this first part, we will introduce some basic reusable classes for building shapes in WPF and set up a simple animated scene. In future instalments, we will talk about other kinds of shapes, back materials, smooth shading and flat shading, and storyboards. The classes we use to make the cube will be combined to make our robot, a simple character with its own movements. All the source is included for each instalment of the series.

We begin by starting a new project in Visual Studio 2010. Choose WPF Application as the project type. You will have to add this XAML to the MainWindow:

We will need some code to add our points to a GeometryMesh3D so they can be used in a model. Since we are going to be combining triangles from different shape classes together to make a single model, we will pass in the mesh variable and add our triangle points to it:

We have made this a static function because we will usually want to add a triangle only as part of a larger form. Rarely would we ever construct a triangle model on its own. We will be using hundreds of triangles, so we don't want to instantiate a triangle class just to add a triangle to a mesh.

You will notice that we have included an argument called combine_vertices. This is very important because of the difference between flat shading and smooth shading in WPF. For our cube model, we want to use flat shading. If you combine vertices for your triangle mesh, it leads to smooth shading using the Gouraud method. Later on, we will show how this can apply to shapes such as a cylinder where we might want to use smooth shading. For now, we will add the capability for combing vertices to our triangle class, even though it won't be used for the cube example:

When combining points in a triangle mesh, each unique point (Position) is only listed once in the mesh, even though it may belong to several triangles. A separate list (TriangleIndices) is used to store the indices for each point that is used to make each triangle. A third list is needed to provide the normals for each triangle. This is necessary for calculating the angle of incidence between a light source and the surface of each triangle. This is how WPF does flat shading. It uses Gouraud interpolation to smooth out the shading, but only if you combine the points that are the same. If you list each point separately, flat shading will be the result. This is what we want for our cube.

Normals are calculated using a simple cross product. WPF gives you a built in Vector member function for that. Here is our member function that calculates a normal for our triangle:

This allows us to fill the Normals list while we are building our mesh.

We add another member function to construct a triangle GeometryModel3D, just in case we wanted to do that. It won't be needed for this project, but I include it anyway. It takes a color as an argument and constructs the model using a DiffuseMaterial of that solid color:

As with the triangle, we will not always want to instantiate a rectangle by itself, so we make this member function static and pass in the points each time. The order of the points when we call WpfTriangle.addTriangleToMesh will ensure that each triangle has the same winding direction. This is important because by default, shapes in WPF have only one side and are invisible from the other side. This is determined by the winding direction or order of the points in each triangle, so it is important to keep this consistent for all triangles in your model.

We add another member function for when we have an instance of a rectangle and want to add it to a mesh without specifying the points, letting it use its member points instead:

The complete code for the triangle and rectangle classes is available in the zip file for this article. Let's move on to the cube. Only 4 member variables are necessary in order to completely describe our cube:

We provide a member function for adding a cube to a mesh. For convenience, it is a static function that will construct a cube and then add it to the mesh. It does this by constructing a rectangle for each side and then adding each of those to the mesh:

We need some helper functions in our window to accomplish some of the work that we listed above. These functions create out lights and camera. They also make use of the sceneSize variable we defined earlier, so if you want to change the coordinate base, everything will still work together:

So that is our simple rotating cube. The triangle and other classes that we made will be useful in constructing our simple scene with a walking robot character. The animation concepts will also come in handy later for making the robot's arms and legs move. In the next article in the series, we will add a cylinder class and demonstrate the difference between flat shading and smooth shading.

Share

About the Author

Gary Miller is a professional software developer whose clients have included Delta Air Lines, Cingular Wireless, and the Center For Disease Control. He has developed advanced graphical user interfaces for traffic control systems and medical call centers. Some animated 3D products he has developed include Field Artist and Calder4D. He has developed a Silverlight powered social networking site for music students called Field Artist Central

Calder4D is a Windows program that allows you to model and animate 3D shapes and then produces the XAML code to include those animated shapes in your own WPF applications.