Monthly Archives: July 2007

Community Server module for embedding Silverlight 1.1 to posts

I figured I just jump into it; creating a Community Server 2007 module for rendering Silverlight content.

It all started up yesterday as a simple thing, but I figured that I didn’t feel comfortable with the way the plugin system worked in Community Server, so I created a small abstraction from it to make it feel more right for me. ūüôā¬†¬† It’s all based upon attributes instead of hooking up events. The reason¬†I started doing the¬†abstraction¬†was that I have a couple of modules I need in the pipeline and wanted to simplify stuff I will be¬†needing for all modules, such as filtering for¬†ApplicationType.

The module code turns out¬†as follows (I’ve attached the entire project with¬†source and binaries)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
  [Module("SilverlightModule")]
  public class SilverlightModule : BaseModule
  {
    private static readonly string SilverlightScript = "Silverlight";
    private static readonly string SilverlightApplicationScript = 
                        "SilverlightApplication";

    [Method(MethodType.PreRender)]
    [MethodType(MethodType.PreRender)]
    [ApplicationType(ApplicationType.Weblog)]
    [ApplicationType(ApplicationType.ContentManagement)]
    public string Render(string protocol,string xamlUri)
    {
      string completeUri = protocol + ":" + xamlUri;

      Page page = MethodContext.Current.Page;

      if (!page.ClientScript.
          IsClientScriptBlockRegistered(SilverlightScript))
      {
        page.ClientScript.
          RegisterClientScriptBlock(  typeof(SilverlightModule), 
                        SilverlightScript, 
                        Resources.Silverlight, true);
      }

      if (!page.ClientScript.
          IsClientScriptBlockRegistered(SilverlightApplicationScript))
      {
        page.ClientScript.
          RegisterClientScriptBlock(  typeof(SilverlightModule), 
                        SilverlightApplicationScript, 
                        Resources.SilverlightApplication, 
                        true);
      }

      Guid applicationGuid = Guid.NewGuid();

      string hostName = "SilverlightControlHost_"+applicationGuid.ToString();

      completeUri = completeUri.Trim();

      return 
      "<div id="" + hostName + "" style="background-color:Black" >" +
      "<script type="text/javascript" style="background-color:Black">" +
      "createSilverlight(""+completeUri+"",""+applicationGuid.ToString()+"");" +
      "</script>" +
      "</div>";
    }
  }

CommunityServermoduleforembeddi.1toposts_780E_image_1

Installation instructions :

Copy the binary (DoLittle.CS.Modules.dll) into the bin directory of your Community Server installation. Add the following line to your communityserver.config file :

<add name=”SilverlightModule” type=”DoLittle.CS.Modules.SilverlightModule, DoLittle.CS.Modules”/>

Then you have the SilverlightModule up and running.

To use it you simple write [SilverlightModule: protocol:uri] in your editor.

protocol : http, https
uri : The uri for the XAML to use

Sample : [SilverlightModule: http://www.dolittle.com/Silverlight/3D/Page.xaml]

Remember to use the unlink button for the Uri. Community Server editor and most other editors will automatically translate the Uri and add a href around it.

Spinning cube in Silverlight Alpha 1.1 using C#

Silverlight represents a subset of WPF and it’s features, one of the features that¬†aren’t part of the subset is 3D. When the Silverlight 1.1 Alpha with the support for managed code came out earlier this year, I couldn’t wait to get my hands dirty and try to get some 3D content on it even though it didn’t support it. I got very happy when I saw they left the Polygon visual in there, that means you have some optimized way of drawing triangles. Anywho, the purpose of this tutorial is to show how little code you can get away with if¬†you just want to have a simple spinning cube.

The sample is very basic and does not involve any heavy geometry math. If you want a sample using Matrix math and more advanced geomtry stuff, take a look at the Balder project : http://www.codeplex.com/Balder

The main loop

The first thing we need before we do anything else is a main loop. This can be achieved by using the animation system in Silverlight. By creating a storyboard and hook up the Completed event we can achieve a steady callback. In our Page.xaml we create our own Canvas for the spinning cube and add a storyboard inside it :


1
2
3
4
5
  <Canvas x:Name="spinningCubeCanvas">
    <Canvas.Resources>
      <Storyboard x:Name="spinningCubeStorybard" 
Completed="spinningCubeCanvas_Render"/>
    </Canvas.Resources>
  </Canvas>

That’s in fact all the XAML we will be needing to achieve a spinning cube. Now for the code-behind.
In the Page_Loaded event we add the following code to start our mainloop.

this.spinningCubeStorybard.Begin();
Then we need to implement the Completed event for the Storyboard : 
1
2
3
4
public void spinningCubeCanvas_Render(object sender, EventArgs e)
{
   this.spinningCubeStorybard.Begin();
}

 

Our Cube

To define our cube we need points in 3D space, these are called Vertices (one vertex, several vertices). We therefor create a simple class to represent a vertex. The class represents the original vertex before we have done any calculations on it and also contains the finished calculated vertex ready to be used on our 2D screen.

1
2
3
4
5
6
    private class Vertex
    {
      public  double X, Y, Z;
      public double RotatedX, RotatedY, RotatedZ;
      public int TranslatedX, TranslatedY;
    }

As you can see, the vertex contains an X,Y and Z representing the coordinate in 3D space. In addition it contains the rotated version and the translated 
(2D) version. Now that we have the definition of a vertex, we need the definition of a triangle that hooks  itself on 3 vertices, we call these Faces. A face 
contains 3 integers representing an index into the array of vertices for the object we are rotating.
1
2
3
4
    private class Face
    {
      public int VertexA, VertexB, VertexC;
    }

Now we need to create the array of vertices for the object :

1
2
3
4
5
6
7
8
9
10
    private Vertex[] _vertices = new Vertex[] {
                     new Vertex() { X=-150, Y=-150, Z=-150},
                     new Vertex() { X=150, Y=-150, Z=-150},
                     new Vertex() { X=-150, Y=150, Z=-150},
                     new Vertex() { X=150, Y=150, Z=-150},
                     new Vertex() { X=-150, Y=-150, Z=150},
                     new Vertex() { X=150, Y=-150, Z=150},
                     new Vertex() { X=-150, Y=150, Z=150},
                     new Vertex() { X=150, Y=150, Z=150},
                   };

And we need an array of faces that hooks up to these vertices :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
    private Face[] _faces = new Face[] {
                    new Face() { VertexA=2, VertexB=1, VertexC=0},
                    new Face() { VertexA=1, VertexB=2, VertexC=3},
                    new Face() { VertexA=4, VertexB=5, VertexC=6},
                    new Face() { VertexA=7, VertexB=6, VertexC=5},
                    new Face() { VertexA=0, VertexB=4, VertexC=6},
                    new Face() { VertexA=0, VertexB=6, VertexC=2},
                    new Face() { VertexA=7, VertexB=5, VertexC=1},
                    new Face() { VertexA=3, VertexB=7, VertexC=1},
                    new Face() { VertexA=5, VertexB=4, VertexC=0},
                    new Face() { VertexA=1, VertexB=5, VertexC=0},
                    new Face() { VertexA=2, VertexB=6, VertexC=7},
                    new Face() { VertexA=2, VertexB=7, VertexC=3},
                };


The "Magic"
Now we are good to go to implement all the rendering to make this into a spinning cube. First we need to rotate all the vertices around the 
X,Y and Z axis. We do this very simple, no matrix math involved, very very basic geometry stuff involving sin and cos.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
      // Calculate all the vertices
      foreach (Vertex vertex in this._vertices)
      {
        // Rotate the vertex around the Z axis
        tempY1 = (vertex.X * Math.Sin(this._zRotation)) + 
                 (vertex.Y * Math.Cos(this._zRotation));
        tempX1 = (vertex.X * Math.Cos(this._zRotation)) - 
                 (vertex.Y * Math.Sin(this._zRotation));

        // Rotate the vertex around the Y axis
        vertex.RotatedX = (vertex.Z * Math.Sin(this._yRotation)) + 
                          (tempX1 * Math.Cos(this._yRotation));
        tempZ1 = (vertex.Z * Math.Cos(this._yRotation)) - 
                 (tempX1 * Math.Sin(this._yRotation));

        // Rotate the vertex around the X axis
        vertex.RotatedZ = (tempY1 * Math.Sin(this._xRotation)) + 
                          (tempZ1 * Math.Cos(this._xRotation));
        vertex.RotatedY = (tempY1 * Math.Cos(this._xRotation)) - 
                          (tempZ1 * Math.Sin(this._xRotation));

        // Translate the vertex into a 2D coordinate
        vertex.TranslatedX = ((int) ((vertex.RotatedX * focalLength) / 
                                    (vertex.RotatedZ + zoom)))+xoffset;
        vertex.TranslatedY = ((int) ((vertex.RotatedY * focalLength) / 
                                    (vertex.RotatedZ + zoom)))+yoffset;
      }

This gives us all the vertices rotated and translated. Great, we can finally get our cube up and running. The next part gets the vertices based upon the 
index of the vertices in each face and creates a Polygon visual that we add to the rendering pipeline of Silverlight, in our case we add it to the Canvas 
we have created for our spinning cube. Before we add anything to it we clear it. The loop also does a hidden surface removal, we do not need to render 
polygons that aren't really visible. We want to know which polygons are facing away, this involves doing a mixed product of the 3 vertices. 
The result of the mixed product can also be used for our purpose to give the polygon a color, you'll see some strange color magic in the loop. :) 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
// Create polygons for Silverlight to work with from the newly 
// calculated vertices
this.spinningCubeCanvas.Children.Clear();
foreach (Face face in this._faces)
{
  Vertex vertexA = this._vertices[face.VertexA];
  Vertex vertexB = this._vertices[face.VertexB];
  Vertex vertexC = this._vertices[face.VertexC];

  // Do a mixedproduct of all vertices for hidden surface removal
  double mixedProduct = (vertexB.TranslatedX - vertexA.TranslatedX) *
               (vertexC.TranslatedY - vertexA.TranslatedY) -
               (vertexC.TranslatedX - vertexA.TranslatedX) *
               (vertexB.TranslatedY - vertexA.TranslatedY);
  bool visible = mixedProduct < 0;
  if (!visible)
  {
    continue;
  }


  // Use the mixed product for "shading". 
  // The larger the face, the brighter it is.
  double shade = -mixedProduct; // *512;
  shade /= 1024;

  int color = (int)shade;
  color += 128;
  if (color >= 250)
  {
    color = 250;
  }
  if (color < 30)
  {
    color = 30;
  }

  byte red = (byte)(color >> 3);
  byte green = (byte)(color >> 1);
  byte blue = (byte)(color);


  // Create the polygon and initialize the point and the color
  Polygon polygon = new Polygon();
  polygon.Points = new Point[] {
       new Point(vertexA.TranslatedX,vertexA.TranslatedY),
       new Point(vertexB.TranslatedX,vertexB.TranslatedY),
       new Point(vertexC.TranslatedX,vertexC.TranslatedY)
     };
  polygon.Fill = new SolidColorBrush(Color.FromRgb(red, green, blue));

  this.spinningCubeCanvas.Children.Add(polygon);
}

 

That's pretty much it...  Now you just need to rotate it. :) 
SpinningcubeinSilverlightAlpha1.1usingC_10CC9_image
Download the sourcecode attached to this post for a working version.

Update 12th of August 2007 : 
I've updated the attachment to work with Siliverlight 1.1 Alpha Refresh

MediaPlayer Content plugin for Windows Live Writer

I’ve just sort of finished a simple plugin for adding a MediaPlayer object to blogs from the Windows Live Writer.
In order to use the plugin you must enable the object tag, so they won’t get scrubbed during rendering.

For Community Server this is achieved by going into the communityserver.config file (residing in the Web directory of your Community Server installation) and going to the <markup> section; here you can add the object tag as a trusted tag type. Remember that you’re doing that on your own risk!!!!

Anyways..  Download the file to play around with it.  I’ve also attached the source for it.

Important :
To install it you have to copy it to the Plugins directory of Windows Live Writer, typically c:Program FilesWindows Live WriterPlugins.

 

Mini-ITX motherboard I want to have – now..

I’ve been drewling the last weeks over a brilliant motherboard from Axiomtek. It’s form factor is Mini-ITX and is built around the Socket 479 for the CPU. It supports running a Intel Core 2 Duo processor for Socket M (479) with a FSB of 667 MHz.

For HTPC  machines it is brilliant not to mention for home servers that you just want to stove away somewhere and don’t want to worry about space.. 

Anywayz.. Have a look at this beauty :

http://www.axiomtek.com.tw/Products/ViewProduct.asp?view=463

Make your local retailer import it! ūüôā    I’ve encouraged everyone I talk to, to send my favourite retailer an email to make them import it..