You can see a full working sample of the component here.
Introduction
3D in Silverlight is an issue that has been discussed since the first release of Microsoft's newest platform. Unfortunately, it seems that Microsoft has no intention to include a 3D engine on the Silverlight framework. As we all believe that 3D is cool and has a lot of implementations, especially on the Internet, I've decided to make this project and share it with the community. This project intends to implement a custom user control for Silverlight that will allow to create a cube / box in any desired size and put image textures on its faces. It also allows to make rotations to any angle. In order to run this component, you will need Silverlight 2 installed (not the Beta version).
If you don't have SilverLight 2 installed, you can download it from here.
Background
Due to the lack of a 3D engine in Silverlight, we need to create all 3D systems from the beginning, and it's not an easy task. If you only want to paint the faces of the cube with solid colors, the task becomes much easier as all you need to do is to implement a vertices system (points in 3D environments) and a translation system into 2D coordinates. Then, you'll use Silverlight's polygon elements to draw lines between the points, and you'll be able to paint them in any solid color. Of course, each time, you will only need to show the faces that can be shown in a 2D system. Things gets much more complicated when you want to have images wrapped over the faces. If you'll try to paint the polygons from the previous section with an image brush, you will find out that when you set the polygons into different perspectives (as required when you simulate 3D rotations), the images that are used to paint them are just wrapped wrong (and no matter how you set the Stretch
field of the image brush). This problem occurs because of the inability of the Silverlight framework to deal with perspective and distort manipulation of images. And, as you probably have understood by now, these manipulations are "must have" functions in order to implement a 3D image cube. In this project, I use a dedicated algorithm that can correct the distortion of an image and I use it to wrap the image polygon faces, that together create a 3D rotating cube. This algorithm uses Quads division of images (an algorithm originally posted by Macromedia for the Flash environment), also known, in a very similar version, as the "Image Triangles Algorithm". If you experience a hard time trying to understand this algorithm, don't feel too bad with yourself, I've had a hard time too. :)
Using the Component
There are three different ways to use the 3D Cube component:
-
Adding the component to the toolbox:
You will have to right click with the mouse somewhere over the toolbox panel (where there's an empty space) and click on the "Choose Items" button. In the new window that will open, you will click on the "Browse" button and select the Element.dll file that is located in the Bin directory inside the project. You will get two new components in the toolbox panel:
The CubeSurface
component is a rotating 3D cube shape without the option to apply images to the cube faces.
The Cube
component is the full version that allows you to apply images to the faces of the cube.
After you add it to your toolbox, you can use it like a regular control and drag it into the XAML editor.
-
Adding the component to the XAML editor:
You will have to add a reference to the Elements.dll file into the project references. After that, you will be able to add it to the XAML editor as follows:
<my:Cube x:Name="My_Cube_Name" ></my:Cube>
Of course you will be able to set most of the properties of the component directly from the XAML editor.
-
Using the component in the code:
You will have to add a reference to the Elements.dll file into the project and add the using Elements
statement in the top of the page. Then, you'll be able to use it as a regular object:
Cube myCube = new Cube();
You'll be able to set the cube with its properties and methods. When you finish, don't forget to add it to the relevant canvas / grid.
A full reference guide to the component can be downloaded from here.
Known Issues
- You will notice that in some angles, annoying crossing lines appear inside the image textures on the faces. This happens because Microsoft is using Anti-Aliasing in the Silverlight framework, and there's no way to turn it off. I tried to perform overlapping in the Quads algorithm (putting the pieces a bit over each other), but results are still not good enough. The way I've solved it for now is by setting a background color to each of the faces. For now, you will have to set the colors manually according to the main colors in each image. I hope that in the next version, these colors will be found automatically.
- One strict demand of the Quads algorithm is that the input image will be in a square shape (otherwise, you lose some parts of the image). I couldn't find a way to go around this. It means that if you have a face in non-square dimensions, you will have to stretch the image that is used as the texture to that face into a square shape or you will lose some of the image in the wrapping. Unfortunately, Microsoft chose not to include an image processing tool in the Silverlight framework. I tried couple of methods to solve this issue but none of them work.
Roadmap
In the last minute, this version of the component was already updated into SilverLight 2.0 final version. Comparing to the Beta version of the component that was previously published, some bugs were fixed, performance was improved and you can now use the component directly from the toolbox. In future versions, I do intend to add some abilities:
- A zoom function that will allow you zoom in / zoom out the cube in real time.
- I hope to find a way to process the input images automatically from the code so the user won't have to process them manually.
- An option to set the border in each of the faces to any thickness and any color.
- An option to add different controls than images to the faces of the cube.
If you have more suggestions / requests for future versions, don't hesitate to send them to me.
About this Project
This component was created as a final project at the MTA College under the guidance of my instructor, Amir Kirsh (and you should thank him for the code, he's the one who made me publish it as open source:)).