Published: 17 Sep 2010
By: Xianzhong Zhu
Download Sample Code

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.

Contents [hide]

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

    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

    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.

    4. Click the right-sided button Diffuse Color to select map type Reflect / Refract.

    5. In the Reflect/Refract settings window shown below to set other parameters. Please refer to the following figure.

    Figure 3: Use material editor to create the 6 skybox required mapping images

    Use material editor to create the 6 skybox required mapping images

    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

    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

    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).

    Next, let's continue to check out the XAML code -the View component in MVVM.

    4. View definition (in file AwkwardMVVM.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.

    Figure 6: The first snapshot of the Box zoom in/out sample (here zoom out)

    The first snapshot of the Box zoom in/out sample (here zoom out)

    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)

    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.
  • <<  Previous Article Continue reading and see our next or previous articles Next Article >>

    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.

    Other articles in this category


    Code First Approach using Entity Framework 4.1, Inversion of Control, Unity Framework, Repository and Unit of Work Patterns, and MVC3 Razor View
    A detailed introduction about the code first approach using Entity Framework 4.1, Inversion of Contr...
    jQuery Mobile ListView
    In this article, we're going to look at what JQuery Mobile uses to represent lists, and how capable ...
    Exception Handling and .Net (A practical approach)
    Error Handling has always been crucial for an application in a number of ways. It may affect the exe...
    JQuery Mobile Widgets Overview
    An overview of widgets in jQuery Mobile.
    Book Review: SignalR: Real-time Application Development
    A book review of SignalR by Simone.

    You might also be interested in the following related blog posts


    Visual Studio Add-In vs. Integration Package Part 3 read more
    Why Embedded Silverlight Makes Sense read more
    Telerik Announces Support for Microsoft Silverlight 3 read more
    What is .NET RIA Services? read more
    Moonlight 1.0 Released, Silverlight script updated – and a Chrome hack read more
    Rendering A Single View Using Multiple ViewEngines read more
    URL Rewrite for IIS - SEO Friendly URLs love it ! read more
    Some Silverlight ecosystem updates read more
    Search for Rich Internet Applications read more
    The Social API we really need. read more
    Top
     
     
     

    Discussion


    Subject Author Date
    placeholder Dynamic texture Dave Thomas 10/8/2010 5:14 AM

    Please login to rate or to leave a comment.