The Integrate the 3D Engine Balder into Your Silverlight Applications Series

Part1 In this series of articles, you will learn how to integrate the famous 3D Engine - Balder into your Silverlight applications.

Part2 In this second part of the series, we are going to continue to discuss the Balder engine in the aspect of other advanced concepts and features, i.e. Light, View and Camera.

Part 3 In this final part of this series, we are going to learn other advanced concepts support in Balder, such as Sprite, Skybox, HeightMap, the MVVM pattern, and more.

Introduction

In this final part of this series, we are going to learn other advanced concepts support in Balder, such as Sprite, Skybox,
HeightMap, the MVVM pattern, and more. Note, at the time we admit the power of Balder, we are still going to point out the
insufficiencies in many aspects, all of which are still to be proved through concrete samples.

NOTE

1. The third part related samples are still located in the project named Balder_tut_Adv.

2. The
development environments and tools we'll use in these series of articles are all the same as the ones covered in the first two
parts.

Sprite Support

In Balder, a sprite is a flat image based objects that exist in 3D space - they are rendered along with other 3D content and
positioned and scaled correct according to their 3D space position.

In complex 3D games, there are often a great number of
objects interacting at the same time. This will consume a large part of time of the 3D render engine. By introducing a proper number of
2D sprites this situation can improved.

Till now, Balder 0.8.8.8 has only provided limited support for the 2D sprite. Let's
consider a related sample application. Figure 1 illustrates a sample with a sprite moving back and forth across the scene.

Figure 1: A moving sprite in action

To make comparison, we put a box at the center as the frame
of reference. Here's the related XAML code.

Listing 1: Primitive_Sprite.xaml

Currently, you only need to deal with the AssetName property of Sprite. In this case, we specify an image
file sun.png (the default position is under the subfolder \Assets).

To achieve the sprite animation, we generally resort to the
Storyboard object in Silverlight. Related behind .cs code is as follows:

Note that, in Balder 0.8.8.8 only limited support for Sprite has been provided. For example, the Interactivemode
property cannot affect Sprite. What's more, the mouse related events do not apply to Sprite. To prove this, please refer to the
following sample.

First, XAML code is as follows:

Listing 2: MoveSprite.xaml

Now, please consider the following behind .cs code:

The above case applies to built-in 3D geometries, such as Box, Ring, Cylinder, but not suitable to Sprite. You can view
another related sample called MoveBox.xaml in the source code to make detailed comparison.

Next, let's look into the skybox
support in Balder.

Skybox Support

Image that when the game's role moves in the scene, the scene at the top of the sky will change accordingly. The changes in the sky
scene can be achieved using the Skybox.

Concepts

Currently, describing the "sky" technologies main includes three types:

Flat Sky (Sky Plane), just put a flat at the head.

Sky Dome, what put at the top of the head is a curved surface.

Sky Box, what put into the scene is a cube.

Here, we only show interest in the sky box. Sky boxes are often formed by the six sides of a cube, which often changes with the
movement of the view port. A sky box is very useful to describe the far distant location of the scenery that people can not
reach.

Sky box itself is not difficult for the programmer. But really beautiful sky boxes often require the participation of art
staff.

NOTE:

In advanced applications, the texture in the sky box may also be used to generate Cube Map, and accordingly to
produce the surface reflection, cloud shadow, reflection and other special dazzling effects.

Now, let's check out the definition of Skybox in Balder.

Listing 3: The definition of Skybox in Balder

As you've seen, to define a Skybox, we only need to specify the six images associated with the six sides of the box using
the Back, Bottom, Front, Left, Right, and Top
properties. Next, let's construct a related example.

A basic example using Skybox

First, let's take a look at one of the running-time snapshots, as shown in Figure 2 below.

Figure 2: One of the running-time snapshots to use the skybox

Similarly, to gain comparison effect, we put a box at the center of the scene. And, around the box, we define a sky box used
to describe the surrounding environment and a small part of the sky. And also, we set up an animation making the camera move around the
scene.

Now, you can look at the following XAML code.

Listing 4: Define a skybox using XAML

Above, we used six .jpg files to specify the six properties Back, Bottom, Front,
Left, Right, and Top, respectively. Note, currently, Balder only provides support for the .png
and .jpg formats.

The next and most important thing is the size of each image should be two to the power of a positive integer
(in our sample, all being 2^8, i.e. 256 X 256). This is decided by the Skybox related algorithm. In fact, this rule also applies to
mapping materials.

Related behind .cs code is like the following:

Listing 5: Dynamically change the position of the camera (eyes) to animate the skybox

Here, we've utilized a general DispatcherTimer object to control the animation. If you have good solid geometry
knowledge, you can surely figure out what kind of space curve here define (x=cos(t)*30, z=sin(t)*30, y=sin(2t)*30). Obviously, this is
a tricky way to define the routine to move the camera, all related stuffs worth hard researching into.

How to create the images used in Skybox

As a supplementary, I want to simply introduce how to use 3DS MAX 2009 to create the six Skybox-required images.

1. Start up
3DS MAX 2009.

2. Open a max file (used to generate the six images), add a sphere in the scene, used to represent the position of
the viewpoint.

3. Press M to open the material editor. Then, choose one of the unused material balls, setting it to Standard
Material.

Thus, the production of the six pictures used to create the sky box is over.

Careful readers should have
noticed in the above running-time Figure 2 there are several lines between each small pictures. So, in real scenario cases, the six
images should further modified at the edges using tools, like PhotoShop or Gimp.

Further study

As seen from the above XAML, Skybox is virtually defined as a property of the Game. Hence, as you may image, when the
Game is loaded, it should automatically check out its Skybox property. If it does exist, then load it before any other
geometries or meshes. Please refer to the following code abstracted from Balder.dll using .NET Reflector.

Listing 6: Skybox is a property of Viewport

Note in the Render method of Viewport, the Skybox property is checked. And if existed, it will be rendered
onto the view port.

Listing 7: Skybox is a property of Game

Here, in the method RegisterGame of Game, the Skybox gets initialized.

Starting from next section, we
are to shift our attention to another good support in Balder - Heightmap.

Heightmap Support

In the three-dimensional virtual world of games, establishing high fidelity of virtual scenes is usually required, of which three-
dimensional terrain fidelity is one of the keys. However, terrain generation and rendering require a huge amount of computation. What'
more, real terrain generation also needs the support of the terrain database. Using very limited computing capacity in the PC,
generating a real-time realistic three-dimensional terrain has always been a problem for the industry. After years of exploration,
generation of three-dimensional terrain has formed a series of excellent algorithms.

In my research, although Balder has also
provided support for heightmap, it merely offers fundamental implementation. In another word, it has not embedded ready-to-use
algorithms to generate various kinds of heightmaps, but only supplies to you an empty frame for you to introduce your own
algorithms.

In Balder, it introduces a class called Heightmap. Listing 10 below shows the key definition stripped from .NET
Reflector.

Listing 8: Heightmap definition stripped from .NET Reflector

Except for the last three public properties (Dimension, HeightSegments, and
LengthSegments), the HeightInput event is the most important member in the Heightmap class. As for other
members, you hardly need to care about.

Sample 1 - Primitive_HeightMap.xaml

Let's first look at the running-time snapshot, as shown in Figure 4. As soon as the sample starts up, there will be a sin-form
animation appearing on the scene. When you click the button 'Pause' the animation can pause, and another click will re-invoke the
animation.

Figure 4: A simple height map is used to create a sin form of map

Next,
let's take a look at the related xaml code.

Listing 9: Basic Heightmap sample related XAML code

In fact, in this sample, there are two animations. One is controlled by the Storyboard object at the beginning. The other
will be provided in the next paragraph. Here, we defined a simple heightmap and subscribed to its HeightInput
event.

Next, let's track to see the HeightInput event related behind code and hence another animation.

Listing 10: The HeightInput event handler

To understand the above code, let's first look at the HeightmapEventArgs class definition:

Listing 11: The HeightmapEventArgs class definition

By default, the values of the GridX and GridY equal to those of LengthSegments
and HeightSegments, respectively. ActualVertex corresponds to the vertex, while the Color
represents the current vertex's color. The Height is most important, which is used to represent the actual height of the
vertex (the y coordinate).

Now, as you have seen, in the above code, we've only modified the Height value of the
HeightmapEventArgs parameter using the Sin function. As for what kind of mathematics rules to use to generate the related
Height value, this should depend on your math talent and wide computer graphics knowledge.

Sample 2 - use Heightmap to create the rippling water wave’s effect

Now, let's see a more advanced sample, which is a revised version from the online counterpart.

As usual, let's first look at
the snapshot, as shown in Figure 5 below.

Figure 5: Use heightmap to create the ripple animation effect

Then,
what's behind the scene? Let's first look at the XAML code.

Listing 12: The ripple sample related XAML code

There is nothing peculiar here, isn't there? Next, let's continue to look into the behind code.

Listing 13: Use Heightmap to create the water ripple animation

Here, I'm going to skip the discussion about the inner water ripple related algorithm. But there is still something
deserved to be pointed out. The Update event of the Game object will be triggered whenever the objects inside the scene
changes. On the other hand, the HeightInput event of the Heightmap object will be triggered whenever the content of the
Heightmap object changes.

So, we can say that we've in fact established two events (the Update event of the Game
object and the HeightInput event of the Heightmap object) related loops. The two loops trigger each other, which leads to
the water rippling animation.

Limited support for other situations

Note, for now, Balder merely provides limited support in the Heightmap class. So, if you want to create vivid terrains like those in
real games, there are still lots of work to do. A good article on this is called "Terrain Generation with a Heightmap" at
http://www.chadvernon.com/blog/resources/managed-directx-2/terrain-generation-with-a-heightmap/.

Altogether, to create an ideal
heightmap requires you to know much knowledge about heightmap related algorithms. And also, there is still much to do with Heightmap in
Balder.

Starting from next section, we will shift out attention to the MVVM support in Balder.

Model-View-ViewModel Support

Since Silverlight 2, Commands has partially existed in the form of the definition of the interface for them - ICommand. The Balder
engine provides basic support commands for some of its controls.

Commands are meant as a way of separating the UI from the logic
in a cleaner way than a code-behind event for a page or usercontrol, they represent the behavior for a specific event and each control
controls what event triggers a Command. For most controls in Balder this would be the MouseLeftButtonUp event if the
mouse was over the object at the point of click.

Commands are frequently used in the popular MVVM (Model View ViewModel) pattern
and could be placed as properties on the ViewModel and databound directly on the Control. In this way, View can be well decoupled from
state and behavior.

Before we are going to provide workable samples, something must be pointed out beforehand. One is at the
short materials at codeplex on Commands could not work as expected- it is true at least for Balder 0.8.8.8. To prove this, please
consider the following sample.

1. XAML code (MVVM_1.xaml):

Listing 14: The typical XAML code to use MVVM pattern

2. Behind C# code:

Listing 15: The typical XAML code to use MVVM pattern

I think there is no need to give further explanation with the above code. In fact, today, you can easily retrieve plenty
of MVVM pattern related stuffs. According to what is pre-designed, when we click the Box geometry its diffuse color should switch
between Blue and Red. However, it does not work. So, we have reason to say at least in Balder 0.8.8.8 the easy-to-use MVVM pattern
support is still its infancy.

However, I can also bring to you an awkward yet really workable example.

An awkward yet really workable example

In this sample, we are to achieve such a goal. When the user clicks the Box in the scene, the related Camera will be moved farther
or nearer, so as to form the effect of zooming in and out. For this, we can change the Z value of the Position property of the
Camera.

Now, let's first take a look at the MVVM related components.

1. Model definition is as follows:

2. ViewModel definition.

The ViewModel serves as the Controller of the well-known MVC pattern. In our case, the
ViewModel definition is as follows:

ICommand is normally supported in Silverlight 4, with the main aim right targeting the MVVM pattern. The
SwitchBoxSize method is the center. The related command definition is given as follows.

3. Command
definition.

In defining the class SwitchBoxSizeCommand, the key should be to implement the Execute method. Here, through the member
_vm (of the type ViewModel_2), the method SwitchCameraZ is invoked. Note the method SwitchCameraZ is right
defined in the ViewModel. So, just follow the pattern, and you can achieve most of the MVVM pattern.

Till now, let's take a short
time to retrospect what the really most part is. It's the SwitchCameraZ method defined in ViewModel. As defined in the
MVVM pattern, in this method we typically do something with the Model, letting this operation further affecting the View (the
XAML).

Please pay more attention to the bold parts in the above code. According to the MVVM design, when the Box is clicked, the
method SwitchBoxSize will be fired - if the CanExecute method returns true (for simplicity, we did no
validation in it, but return true directly).

According to my debug, when the box is clicked, the method SwitchBoxSize
indeed has been invoked. But how can we let the modification in this method affect the Camera's property in turn? In Balder
0.8.8.8, the answer is you cannot using data binding directly with most of the Balder stuffs (e.g. the in-built geometries, camera,
light, etc). To do this, at least for now, we can resort to the following trick - using a common Silverlight control acting as the
mediator.

5. The behind code for the TextBox control named Text1:

Yes, as you've seen, the really awkward thing occurs here - we subscribed to a TextChanged event handler,
inside which we changed the Z value of the property Position of the camera.

Again, let's review the
Textbox related XAML code:

Till now, everything becomes clear. By clicking the Box, the behind Model changes, which leads to the change of content
of the TextBox which in turn triggers the TextChanged event of this control. And at last, the Z value of the property
Position of the camera is modified from the behind.

Now, you can see the zooming in /out result. Figure 6 shows the
first snapshot.

If you click again the box, you will see a bigger box before you, as shown in Figure 7.

Figure 7: The second click leads to a ‘bigger’ box (zoom in)

If you continue
to click the box, it will switch between the above two states.

The last thing is: why do we set Opacity="0" of the
TextBox control? In this way, we can avoid an ugly TextBox control appears beside the box. However, you cannot set
Visibility=”Collapse” of the TextBox control because, this way, the TextChanged event of this control
cannot be triggered.

On the whole, the unsupported feature in Balder 0.8.8.8 is you cannot get the following
through.

If doing so, you are sure to catch some running-time exception thrown by the system.

An Advanced Sample

The online sample itself is developed using the MVVM pattern. However, it did not resort to ICommand (like the above sample)
directly.

It utilized another open source tool NInject, a famous Dependency Injection framework targeting .NET, to achieve the
sample's MVVM architecture. Of course, the NInject not only helps this online sample but also greatly simplifies the architecture of
the Balder engine, which introduces the popular and advanced Aspect-Oriented Programming idea.

Since to gain better understanding
with how the online sample works will involve around the NInject framework, we are not going to delve into it any more. If time
permitted, I will write another article covering the NInject framework.

NOTE:

The author of Balder modified the NInject a little, so that it can be used in the Silverlight environment.
However, do bear in mind that you cannot add reference to the assemble NInject.dll (from the Ninject website) in your Silverlight
project directly.

Summary

In this series of articles, we've discussed how to introduce Balder into Silverlight applications through pieces of samples. In
fact, till now, the real story has just begun. There are still a lot of good things, especially advanced concepts, such as matrix
algorithm, debug helper, worth carefully studying. In future articles I will still focus upon them.

In any case, as a new 3D
engine mainly targeting Silverlight, Balder has gone through its infancy, and is gradually moving towards maturity and success.

The Integrate the 3D Engine Balder into Your Silverlight Applications Series

Part1 In this series of articles, you will learn how to integrate the famous 3D Engine - Balder into your Silverlight applications.

Part2 In this second part of the series, we are going to continue to discuss the Balder engine in the aspect of other advanced concepts and features, i.e. Light, View and Camera.

Part 3 In this final part of this series, we are going to learn other advanced concepts support in Balder, such as Sprite, Skybox, HeightMap, the MVVM pattern, and more.

About Xianzhong Zhu

I'm a college teacher and also a freelance developer and writer from WeiFang China, with more than fourteen years of experience in design, and development of various kinds of products and applications on Windows platform. My expertise is in Visual C++/Basic/C#, SQL Server 2000/2005/2008, PHP+MyS...

This author has published 81 articles on DotNetSlackers. View other articles or the complete profile here.

Discussion

HI I wonder if you have a next article planned on balder discussing how to do dynamics texture. I have read many of the forum but could not figure out how to do it. An example would be helpful. Keep it up.