Wednesday, January 30, 2008

PolyGraph3D: Making 3D happen with Silverlight 1.0!

Yes, you read that right. Silverlight 1.0 - as in unmanaged JavaScript - and 3D.

Last week I was reminded of the FarSeer Physics engine for XNA and Silverlight 2.0. I have a strange fascination for 3D software - stemming back from the years when I was a beta tester and plugin developer for Caligari trueSpace 3D - so I decided to poke around in the source code from CodePlex to see what they were doing. Turns out it was just mostly linear algebra and some simple mechanics - things I remembered working with many years ago before the age of managed runtimes and rich visual APIs. Back then we had to do all the heavy lifting with highly optimized C++ routines and drawing directly to an HWND. But things are different now, and what seemed incredibly hard in years past really didn't seem all that hard anymore.

So I was inspired I guess.

I know I could have started with the FarSeer code, and built upon that using C# and targeting the managed runtime. But oh no - that was too easy! I figured that if it can be done using simple trig and a solid model design, I bet I could make it work in JavaScript. After all, JavaScript's Math intrinsic object supports Sin() and Cos(), extensible objects, and arrays - and at the end of the day, that's all one really needs in order to create a 3D runtime. Sure, it involves a fair amount of matrix operations and dot-products and cross-products, but all those things can be learned by reading up on Wikipedia these days (or mathreference.com).

So with that, I set out to create an unmanaged 3D visualization engine for Silverlight...

I am making the code freely available and have already published out to CodePlex here: http://www.codeplex.com/polygraph3d

My efforts so far are looking pretty good (I think). Over the course of about 8 hours of coding and testing, I have the basics working. I can create a 3-dimensional polyhedron (a mesh if you will), and I can display the object in a Silverlight Canvas. I can apply scaling, rotations, and positioning of the polyhedra, and I can also build complex objects using polyhedron groups, each of which has its own local scaling/rotation/position transforms. It also supports a movable camera and performs rudimentary perspective correction as well as small optimizations for backface-culling. It currently only supports simple brushes for the object faces - I would like to implement a real texture mapping system, but that will require some very creative use of image skewing to pull it off.

I have a test page up that demos a simple 3D cube that you can move around the virtual viewport space...

image

For sure, it is a very simple demo. Clicking the red, green, and blue axis bars will move the cube around. The "spin" button introduces a gradual rotation around the Y axis... but since my rotation transform code is currently broken, the effect isn't quite what I had in mind. Hopefully I will figure that particular bug out soon.

One major hurdle I encountered was the fact that Silverlight does not let you draw directly on a Canvas, nor does it let you create your own controls. This posed a problem since I wanted to display things that simply could not be expressed using 2D XAML. I "solved" this problem by performing all of the mathematics needed to project the 3D scene into a 2D viewport, and then I use the vertex data from the projected mesh to build a series of 2D Path elements. It was indeed a dirty trick - but hey, sometimes you just have to make do with the capabilities of the platform.

Comments are closed.
View Keith Rome's profile on LinkedIn

On this page....

Archives

Navigation

Categories

Microsoft Weblogs

Web 2.0 / AJAX

Local Atlanta Bloggers

SharePoint / MOSS

WPF

Other Weblogs

MSDN Monitoring

My Blogmap

About

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

Sign In

Certification Logo Certification Logo Certification Logo Certification Logo Certification Logo

Powered by: newtelligence dasBlog 2.0.7226.0