Saturday, March 7, 2009

3D in Silverlight 2 with Kit3D

We all know how much everyone is waiting for Silverlight 3 and various forums and blogs are already flooded with Silverlight 3 wishlist and discussion about the upcoming 3D support in Silverlight. We all know right now 3D is not supported in Silverlight which is supported to extent in WPF. No wonder 3D support will add much more value to Web applications since due to Windows 7 Multitouch capability, everyone these days getting ready to make there application much more close to user.

Now I am discussing despite not having support of 3D in Silverlight 2, how we can do it with a Codeplex project dll file well known as “Kit3D.dll” aka Kit3D Project. I am writing this particular article just to make you aware about this 3D implementation dll in Silverlight 2 so that if you find it useful, you can start working on it and implement it until the real 3D supports come with Silverlight 3, I have downloaded the dll and took some sample code and made some Tweaks/Changes in it. So my code snippet below is derived from original source with modifications.

Kit3D unfortunately don’t have any specific documentation which can talk about the various classes and members in it, Neither we have any video,but now I guess we are mature enough on Silverlight so we can implement it in our way.

Step 1 : Download Kit3D.dll file from CodePlex at :

http://kit3d.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=12582#ReleaseFiles

Step 2 : Create a Silverlight Project and add reference of Kit3D.dll file.

Cube.xaml :

<Grid x:Name="LayoutRoot" Background="White">
       <Canvas Width="0" Height="0">
       </Canvas>
   </Grid>

Cube.xaml.cs :

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using Kit3D.Windows.Controls;
using Kit3D.Windows.Media;
using Kit3D.Windows.Media.Media3D;

namespace SL_Kit3D_Demo
{
    public partial class Cube : UserControl
    {
        private Viewport3D viewport;
        RotateTransform3D Rotate;

        public Cube()
        {
            InitializeComponent();
            this.Loaded += new RoutedEventHandler(Cube_Loaded);
        }

        void Cube_Loaded(object sender, RoutedEventArgs e)
        {
            ModelVisual3D Visual = new ModelVisual3D();
            GeometryModel3D MyCube = new GeometryModel3D();
            MyCube.Geometry = CreateCubeMesh();
            MyCube.Material = new DiffuseMaterial(new Kit3DBrush(new SolidColorBrush(Colors.Gray)));

            Visual.Content = MyCube;

            Transform3DGroup Transform = new Transform3DGroup();
            Transform.Children.Add(new ScaleTransform3D(3, 3, 3));

            Rotate = new RotateTransform3D();
            Rotate.Rotation = new AxisAngleRotation3D();
            Transform.Children.Add(Rotate);
            MyCube.Transform = Transform;

            viewport = new Viewport3D();

            viewport.Camera = new PerspectiveCamera(new Point3D(-5, 15, 25),
                                                    new Vector3D(5, -15, -25),
                                                    new Vector3D(0, 1, 0),
                                                    45);
            viewport.Children.Add(Visual);
            viewport.HorizontalAlignment = HorizontalAlignment.Stretch;
            viewport.VerticalAlignment = VerticalAlignment.Stretch;

            this.LayoutRoot.Children.Add(viewport);

            Kit3D.Windows.Media.CompositionTarget.Rendering += new EventHandler(CompositionTarget_Rendering);
        }

        private MeshGeometry3D CreateCubeMesh()
        {
            MeshGeometry3D mesh = new MeshGeometry3D();
            mesh.Positions = new Point3DCollection
            {
                new Point3D(-0.5,0.5,0.5),
                new Point3D(0.5,0.5,0.5),
                new Point3D(-0.5,-0.5,0.5),
                new Point3D(0.5,-0.5,0.5),
                new Point3D(0.5,0.5,-0.5),
                new Point3D(-0.5, 0.5, -0.5),
                new Point3D(0.5,-0.5,-0.5),
                new Point3D(-0.5,-0.5,-0.5),

                new Point3D(-0.5,0.5,-0.5),
                new Point3D(-0.5,0.5,0.5),
                new Point3D(-0.5,-0.5,-0.5),
                new Point3D(-0.5,-0.5,0.5),
                new Point3D(0.5,0.5,0.5),
                new Point3D(0.5,0.5,-0.5),
                new Point3D(0.5,-0.5,0.5),
                new Point3D(0.5,-0.5,-0.5),

                new Point3D(-0.5,0.5,-0.5),
                new Point3D(0.5,0.5,-0.5),
                new Point3D(-0.5,0.5,0.5),
                new Point3D(0.5,0.5,0.5),
                new Point3D(0.5,-0.5,-0.5),
                new Point3D(-0.5,-0.5,-0.5),
                new Point3D(0.5,-0.5,0.5),
                new Point3D(-0.5,-0.5,0.5)
            };

            mesh.TriangleIndices = new Int32Collection
            {
                0, 2, 1, 1, 2, 3,
                4, 6, 5, 5, 6, 7,
                8, 10, 9, 9, 10, 11,
                12, 14, 13, 13, 14, 15,
                16, 18, 17, 17, 18, 19,
                20, 22, 21, 21, 22, 23
            };

            return mesh;
        }

        void CompositionTarget_Rendering(object sender, EventArgs e)
        {
          ((AxisAngleRotation3D)Rotate.Rotation).Angle += 1;
        }
    }
}

Basically, Once you refer Kit3D.dll file, you can import namespaces Kit3D.Windows.Media and Kit3D.Windows.Media.Media3D by which you can make your silverlight application capable to render 3D. There are several classes like GeometryModel3D which talks about various properties by which you can apply shape,color etc to your geometry. CompositionTarget_Rendering is the only event which provides rendering, here in that you can see we are moving cube in circular rotation of 1 degree. Those who know WPF very well they can see common terms like ViewPort,Camera etc.

I tried out to modify some of the co-ordinates in CreateCubeMesh, then I get result like few distorted plane on different axis like this :

1

Frankly speaking, It took much of my time since I am not much use to WPF, but those of you are good at it, might you create much more good stuff than I did from above. Well, output will look like this :

 2

Well, though it might look like some cube which any dumb can create, no, its not like that, Kit3D is bit complex to program but it is very much powerful, if you not satisfied what i am saying, go ahead and visit this URL :

http://www.markdawson.org/Kit3D/

You can check full source code here :

http://kit3d.codeplex.com/SourceControl/changeset/view/14651#234928

Make a note which is mentioned on http://kit3d.codeplex.com/ that “This project is still very early on in its lifecycle”,but still its very good to start using it as a primary step towards 3D graphics in Silverlight 2.

My only wish to make you aware of Kit3D, Hope you will download it and try it out by creating wonderful 3D Silverlight applications.

Vikram.

3 comments:

Priyanka said...

Hi Im a student, for my fianl year projetc im doing a WPF application which contains 3D models in it, I have some doubts, can you please give me your mail id or skype id to contact you.

Thanx in advance

Vikram Pendse said...

Priyanka, you can mail here vikram[dot]pendse[at]puneusergroup[dot]org

Priyanka said...

Hi, I sent a mail to you vikram.pendse@puneusergroup.org

Please check it