<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
  <channel>
    <title>TimJones.tw Blog</title>
    <description>Blog of Tim Jones, software developer in Taiwan</description>
    <link>http://timjones.tw/</link>
    <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/roastedamoeba" /><feedburner:info uri="roastedamoeba" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
      <title>NDepend 4 review</title>
      <description>&lt;p&gt;&lt;a href="http://www.ndepend.com"&gt;NDepend&lt;/a&gt; is an analysis tool for .NET code, that provides many ways of generating and viewing code metrics. Here&amp;#39;s what the homepage says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;NDepend is a Visual Studio tool to manage complex .NET code and achieve high Code Quality. With NDepend, software quality can be measured using Code Metrics, visualized using Graphs and Treemaps, and enforced using standard and custom Rules. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I&amp;#39;ll admit, when I did my first analysis session with NDepend, I was a little taken aback at the amount of detail being thrown at me. However, it didn&amp;#39;t take long before I appreciated the sheer depth of available information. And viewed in that light, the visual interface is actually well thought through. It&amp;#39;s a 4th generation product, and it shows.&lt;/p&gt;

&lt;p&gt;First things first: when you download NDepend, you won’t find an installer. Personally, I like the convenience of an .msi, but it’s not a big deal. I chose to copy NDepend to Program Files.&lt;/p&gt;

&lt;p&gt;NDepend 4 comes in two versions: standalone, and integrated with Visual Studio. Personally I prefer the standalone version – there are enough tool windows that I think it deserves its own host program.&lt;/p&gt;

&lt;p&gt;When you first open NDepend, you&amp;#39;ll be greeted by a familiar IDE-style interface.&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/blog/ndepend1.png" alt="NDepend interface"/&gt;&lt;/p&gt;

&lt;h2&gt;Analysing a Project&lt;/h2&gt;

&lt;p&gt;For the purposes of this review, I&amp;#39;ll be analysing &lt;a href="http://dotliquidmarkup.org"&gt;DotLiquid&lt;/a&gt;. It&amp;#39;s quite a small project, but probably large enough to have some issues that NDepend might uncover. You can analyse either a .csproj or a compiled DLL.&lt;/p&gt;

&lt;p&gt;After analysis, NDepend will open an HTML report in your browser:&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/blog/ndepend5.png" alt="HTML report"/&gt;&lt;/p&gt;

&lt;p&gt;You can use Visual NDepend to browse the same information as shown in the report. The rest of this review will focus on Visual NDepend.&lt;/p&gt;

&lt;h2&gt;Code Query LINQ&lt;/h2&gt;

&lt;p&gt;One of NDepend 4&amp;#39;s flagship features is Code Query LINQ (CQLinq). This, as the name suggests, lets you use LINQ to query your codebase. NDepend comes with many built-in queries, and you can write your own. &lt;/p&gt;

&lt;p&gt;The built-in queries cover many categories, including among others:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Code Quality&lt;/li&gt;
&lt;li&gt;Object Oriented Design&lt;/li&gt;
&lt;li&gt;API Breaking Changes&lt;/li&gt;
&lt;li&gt;Dead Code&lt;/li&gt;
&lt;li&gt;Naming Conventions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As an example of what CQLinq looks like, here is one of the built-in rules that suggests avoiding namespaces with few types:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span style="color:#777"&gt;// &amp;lt;Name&amp;gt;Avoid namespaces with few types&amp;lt;/Name&amp;gt;&lt;/span&gt;
warnif count &amp;gt; &lt;span style="color:#00D"&gt;0&lt;/span&gt; from n in JustMyCode.Namespaces 
let types = n.ChildTypes.Where(t =&amp;gt; !t.IsGeneratedByCompiler)
where 
  types.Count() &amp;lt; &lt;span style="color:#00D"&gt;5&lt;/span&gt; 
  orderby types.Count() ascending
select &lt;span style="color:#080;font-weight:bold"&gt;new&lt;/span&gt; { n, types } 
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Selecting a query in the &amp;quot;Queries and Rules Explorer&amp;quot; panel will highlight (in the &amp;quot;Metrics&amp;quot; panel) the methods, types, namespaces or assemblies matched by that query. After selecting the &amp;quot;Quick summary of methods to refactor&amp;quot; query, this is what the &amp;quot;Metrics&amp;quot; panel looks like for DotLiquid:&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/blog/ndepend2.png" alt="Metrics panel"/&gt;&lt;/p&gt;

&lt;h2&gt;Dependency Matrix&lt;/h2&gt;

&lt;p&gt;The Dependency Matrix panel is more useful than it first appears. It shows you whether, and how, each part (namespace, type, method) of your project depends on other parts of your project or other libraries. For example, the &lt;code&gt;Extends&lt;/code&gt; tag in DotLiquid depends on &lt;code&gt;IFileSystem&lt;/code&gt;, so there is a blue 1 in that column and row to indicate that 1 member in the &lt;code&gt;Extends&lt;/code&gt; type uses the &lt;code&gt;IFileSystem&lt;/code&gt; type.&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/blog/ndepend3.png" alt="Dependency Matrix"/&gt;&lt;/p&gt;

&lt;p&gt;The Dependency Matrix is perhaps most useful for spotting dependencies that you didn&amp;#39;t expect, or that shouldn&amp;#39;t exist.&lt;/p&gt;

&lt;h2&gt;Dependency Graph&lt;/h2&gt;

&lt;p&gt;The Dependency Graph panel is more straightforward - as far as I can see, it&amp;#39;s a graphical version of the Dependency Matrix panel, although it gives you several more display options. You can drill into each assembly, and view dependencies right down to the method level. You get a bird&amp;#39;s-eye view of the relative size of each assembly &amp;#47; type &amp;#47; method, as well as a graphic depiction of their inter-dependencies.&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/blog/ndepend4.png" alt="Dependency Graph"/&gt;&lt;/p&gt;

&lt;h2&gt;Code Diff&lt;/h2&gt;

&lt;p&gt;With the DotLiquid project, we have committed to semantic versioning. NDepend can help with this – I can compare previous versions with the trunk version, and check that I haven’t accidentally broken API compatibility in a minor version bump. Here&amp;#39;s what it looks like – note that you can filter by added code, removed code, changed code, etc. You can even edit the CQLinq query to completely customise the filter. &lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/blog/ndepend6.png" alt="Code Diff"/&gt;&lt;/p&gt;

&lt;h2&gt;Build Server Integration&lt;/h2&gt;

&lt;p&gt;NDepend can be integrated with TFS, CruiseControl, FinalBuilder and TeamCity. It can also be run from the command line.&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Almost everything in NDepend&amp;#39;s interface is clickable, or has a tooltip. There is a huge amount of depth here. The documentation is very thorough – and, for once, it’s not full of useless MSDN-style &amp;quot;This gets or sets the [property name]&amp;quot; tidbits.&lt;/p&gt;

&lt;p&gt;Overall, I am impressed with NDepend 4. The only downside I can see is its complexity (and possibly, depending on your situation, its price – but I&amp;#39;m all for software developers charging for their hard work). If you are willing to spend some time learning how it works, and if your project warrants it, then you&amp;#39;ll be rewarded with some very deep code metrics. The tagline is &amp;quot;Make your .NET code Beautiful with NDepend.&amp;quot; If its code metrics help you write code that can withstand the microscopic level of detail that NDepend exposes, then &amp;quot;beautiful&amp;quot; might just be the right word.&lt;/p&gt;

&lt;h3&gt;Disclaimer&lt;/h3&gt;

&lt;p&gt;Patrick Smacchia contacted me about reviewing NDepend. I received a free licence for NDepend 4. Patrick did not express any expectation of a positive review.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/OSSacB_0T7U" height="1" width="1"/&gt;</description>
      <pubDate>Sat, 15 Dec 2012 15:47:01 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/OSSacB_0T7U/ndepend-4-review</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2012/12/15/ndepend-4-review</feedburner:origLink></item>
    <item>
      <title>Multi-file item templates in Visual Studio 2010</title>
      <description>&lt;p&gt;Visual Studio 2010 comes with lots of item templates, but sometimes the built-in ones aren&amp;#39;t enough.  Here I&amp;#39;ll walk through creating a multi-file item template that will add a model, view, view model and  controller to an ASP.NET MVC website. It&amp;#39;s not a great example, because MVC comes with its own scaffolding system for such tasks, but it will demonstrate the general technique.&lt;/p&gt;

&lt;h2&gt;Files&lt;/h2&gt;

&lt;p&gt;First, create a new folder somewhere with the following structure.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;MyTemplate.vstemplate&lt;/li&gt;
&lt;li&gt;__TemplateIcon.ico&lt;/li&gt;
&lt;li&gt;Controllers

&lt;ul&gt;
&lt;li&gt;EntityController.cs&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Models

&lt;ul&gt;
&lt;li&gt;Entity.cs&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;ViewModels

&lt;ul&gt;
&lt;li&gt;EntityViewModel.cs&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Views

&lt;ul&gt;
&lt;li&gt;Entity

&lt;ul&gt;
&lt;li&gt;Index.cshtml&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;The .vstemplate file&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;.vstemplate&lt;/code&gt; file should look like this:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&amp;lt;?xml version=&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;1.0&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; encoding=&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;utf-8&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;?&amp;gt;
&amp;lt;VSTemplate Version=&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;3.0.0&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; Type=&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;Item&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; xmlns=&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;http://schemas.microsoft.com/developer/vstemplate/2005&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&amp;gt;
    &amp;lt;TemplateData&amp;gt;
        &amp;lt;Name&amp;gt;Example Entity Template&amp;lt;/Name&amp;gt;
        &amp;lt;Description&amp;gt;Creates a model &lt;span style="color:#080;font-weight:bold"&gt;and&lt;/span&gt; related MVC items (controller, view model &lt;span style="color:#080;font-weight:bold"&gt;and&lt;/span&gt; view)&amp;lt;/Description&amp;gt;
        &amp;lt;Icon&amp;gt;__TemplateIcon.ico&amp;lt;/Icon&amp;gt;
        &amp;lt;ProjectType&amp;gt;CSharp&amp;lt;/ProjectType&amp;gt;
        &amp;lt;SortOrder&amp;gt;&lt;span style="color:#00D"&gt;10&lt;/span&gt;&amp;lt;/SortOrder&amp;gt;
        &amp;lt;DefaultName&amp;gt;Entity&amp;lt;/DefaultName&amp;gt;
    &amp;lt;/TemplateData&amp;gt;
    &amp;lt;TemplateContent&amp;gt;
        &amp;lt;ProjectItem TargetFileName=&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;Models&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#F00;background-color:#FAA"&gt;\&lt;/span&gt;$fileinputname$.cs&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt; ReplaceParameters=&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#069"&gt;true&lt;/span&gt;&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;&amp;gt;Models&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#F00;background-color:#FAA"&gt;\&lt;/span&gt;Entity.cs&amp;lt;/ProjectItem&amp;gt;
        &amp;lt;ProjectItem TargetFileName=&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;Controllers&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#F00;background-color:#FAA"&gt;\&lt;/span&gt;$fileinputname$Controller.cs&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt; ReplaceParameters=&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#069"&gt;true&lt;/span&gt;&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;&amp;gt;Controllers&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#F00;background-color:#FAA"&gt;\&lt;/span&gt;EntityController.cs&amp;lt;/ProjectItem&amp;gt;
        &amp;lt;ProjectItem TargetFileName=&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;ViewModels&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#F00;background-color:#FAA"&gt;\&lt;/span&gt;$fileinputname$ViewModel.cs&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt; ReplaceParameters=&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#069"&gt;true&lt;/span&gt;&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;&amp;gt;ViewModels&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#F00;background-color:#FAA"&gt;\&lt;/span&gt;EntityViewModel.cs&amp;lt;/ProjectItem&amp;gt;
        &amp;lt;ProjectItem TargetFileName=&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;Views&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#F00;background-color:#FAA"&gt;\&lt;/span&gt;$fileinputname$&lt;span style="color:#F00;background-color:#FAA"&gt;\&lt;/span&gt;Index.cshtml&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt; ReplaceParameters=&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#069"&gt;true&lt;/span&gt;&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;&amp;gt;Views&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#F00;background-color:#FAA"&gt;\&lt;/span&gt;Entity&lt;span style="color:#F00;background-color:#FAA"&gt;\&lt;/span&gt;Index.cshtml&amp;lt;/ProjectItem&amp;gt;
    &amp;lt;/TemplateContent&amp;gt;
    &amp;lt;WizardExtension&amp;gt;
        &amp;lt;Assembly&amp;gt;Microsoft.VisualStudio.Web.Application, Version=&lt;span style="color:#00D"&gt;1&lt;/span&gt;&lt;span style="color:#60E"&gt;0&lt;/span&gt;&lt;span style="color:#60E"&gt;.0&lt;/span&gt;&lt;span style="color:#60E"&gt;.0&lt;/span&gt;&lt;span style="color:#60E"&gt;.0&lt;/span&gt;, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a&amp;lt;/Assembly&amp;gt;
        &amp;lt;FullClassName&amp;gt;Microsoft.VisualStudio.Web.Application.WATemplateWizard&amp;lt;/FullClassName&amp;gt;
    &amp;lt;/WizardExtension&amp;gt;
&amp;lt;/VSTemplate&amp;gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Note the &lt;code&gt;WizardExtension&lt;/code&gt; element. This is important, because it will allow you to use the &lt;code&gt;$classname$&lt;/code&gt; parameter in the template files.&lt;/p&gt;

&lt;h2&gt;Templates&lt;/h2&gt;

&lt;p&gt;I won&amp;#39;t include all the template files here, but I&amp;#39;ll include two so that you get the general idea. First, here is the model:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span style="color:#088;font-weight:bold"&gt;using&lt;/span&gt; MyCmsRulez;

&lt;span style="color:#080;font-weight:bold"&gt;namespace&lt;/span&gt; $rootnamespace$.Models
{
    &lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; &lt;span style="color:#080;font-weight:bold"&gt;class&lt;/span&gt; &lt;span style="color:#F00;background-color:#FAA"&gt;$&lt;/span&gt;safeitemname$
    {

    }
}
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;And here is the controller. Note the use of &lt;code&gt;$classname$&lt;/code&gt;: this will be replaced with the name that the user entered in the Add New Item dialog, as opposed to the name of the file currently being generated. As far as I can see, &lt;a href="http://msdn.microsoft.com/en-us/library/eehb4faa.aspx"&gt;this page&lt;/a&gt; is not accurate in that &lt;code&gt;$itemname$&lt;/code&gt; is &lt;em&gt;not&lt;/em&gt; the name the user entered in the Add New Item dialog if it&amp;#39;s a multi-item template.&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span style="color:#088;font-weight:bold"&gt;using&lt;/span&gt; System.Web.Mvc;
&lt;span style="color:#088;font-weight:bold"&gt;using&lt;/span&gt; $rootnamespace$.Models;
&lt;span style="color:#088;font-weight:bold"&gt;using&lt;/span&gt; $rootnamespace$.ViewModels;

&lt;span style="color:#080;font-weight:bold"&gt;namespace&lt;/span&gt; $rootnamespace$.Controllers
{
    &lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; &lt;span style="color:#080;font-weight:bold"&gt;class&lt;/span&gt; &lt;span style="color:#F00;background-color:#FAA"&gt;$&lt;/span&gt;classname$Controller : Controller
    {
        &lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; ActionResult Index()
        {
            &lt;span style="color:#080;font-weight:bold"&gt;return&lt;/span&gt; View(&lt;span style="color:#080;font-weight:bold"&gt;new&lt;/span&gt; $classname$ViewModel(CurrentItem));
        }
    }
}
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2&gt;Installation&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Zip up the files (making sure you don&amp;#39;t have an unnecessary root folder), and name the file something like &amp;quot;EntityTemplate.zip&amp;quot;.&lt;/li&gt;
&lt;li&gt;Copy into: &lt;code&gt;C:\Users\[username]\Documents\Visual Studio 2010\Templates\ItemTemplates\Visual C#&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A more elegant solution is to use the &lt;a href="http://www.microsoft.com/download/en/details.aspx?id=21835"&gt;Visual Studio 2010 SDK&lt;/a&gt;. The SDK comes with a &amp;quot;C# Item Template&amp;quot; project type. That allows your template files to be included in a project in your solution. When you build that project, it will create a &lt;code&gt;.vsix&lt;/code&gt; package, which can be distributed. When run, the templates in the &lt;code&gt;.vsix&lt;/code&gt; package will install themselves to the correct location.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/-uTFh8hyKX8" height="1" width="1"/&gt;</description>
      <pubDate>Tue, 20 Mar 2012 14:43:45 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/-uTFh8hyKX8/multi-item-templates-in-visual-studio-2010</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2012/03/20/multi-item-templates-in-visual-studio-2010</feedburner:origLink></item>
    <item>
      <title>Integrating DotLiquid with SharePoint 2010</title>
      <description>&lt;p&gt;&lt;a href="http://jbaurle.wordpress.com/"&gt;Jürgen Bäurle&lt;/a&gt; has written a useful article (PDF version &lt;a href="http://www.parago.de/jbaurle/articles/SP2010TemplateEngine/HowToImplementAGenericTemplateEngineForSharePoint2010UsingDotLiquid.pdf"&gt;here&lt;/a&gt;) explaining how to use DotLiquid as a templating engine for SharePoint:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://jbaurle.wordpress.com/2011/05/04/how-to-implement-a-generic-template-engine-for-sharepoint-2010-using-dotliquid/"&gt;How To Implement A Generic Template Engine For SharePoint 2010 Using DotLiquid&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;This article shows how to implement a generic template manager based on the free DotLiquid templating system with SharePoint specific extensions.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Thanks Jürgen!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/cDi8tHOpRNE" height="1" width="1"/&gt;</description>
      <pubDate>Thu, 05 May 2011 20:40:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/cDi8tHOpRNE/integrating-dotliquid-with-sharepoint</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2011/05/05/integrating-dotliquid-with-sharepoint</feedburner:origLink></item>
    <item>
      <title>Marshalling C# structures into Direct3D 11 cbuffers using SharpDX</title>
      <description>&lt;p&gt;&lt;strong&gt;UPDATE 08&amp;#47;03&amp;#47;2011&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I have incorporated Alexandre Mutel&amp;#39;s refactoring suggestion from his comment below, to avoid creating a &lt;code&gt;DataStream&lt;/code&gt; every time.&lt;/li&gt;
&lt;li&gt;He also suggests an alternative approach, which is more elegant but requires more code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It&amp;#39;s tempting, after Googling a problem, finding no solutions, then going old-school and actually trying to solve it myself, and eventually coming up with a solution, to keep running and never look back. But this particular problem gave me lots of SEO-friendly keywords to put in the page title of a blog post, so here we are.&lt;/p&gt;

&lt;h2&gt;Background&lt;/h2&gt;

&lt;p&gt;A bit of background - I&amp;#39;m working on some enhancements to &lt;a href="http://github.com/tgjones/dotwarp"&gt;DotWarp&lt;/a&gt;, which will allow an arbitrary number of directional lights, point lights, and spotlights to be applied to a scene. DotWarp uses &lt;a href="http://code.google.com/p/sharpdx/"&gt;SharpDX&lt;/a&gt; to wrap Direct3D 11. DotWarp works with a single material type, defined in a file called &lt;code&gt;BasicEffect.fx&lt;/code&gt;. I used that name because it roughly follows XNA&amp;#39;s &lt;code&gt;BasicEffect&lt;/code&gt; API (or rather it did until this most recent change to support arbitrary numbers of different light types).&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;.fx&lt;/code&gt; extension is also misleading, because I&amp;#39;m not using the Direct3D 11 Effects framework - instead I compile the vertex and pixel shaders separately. I have a &lt;code&gt;BasicEffect&lt;/code&gt; class defined in C# that tries to abstract that fact away from callers.&lt;/p&gt;

&lt;h2&gt;The problem&lt;/h2&gt;

&lt;p&gt;Direct3D 11 shader parameters are declared inside &lt;code&gt;cbuffer&lt;/code&gt; structures (parameters declared in global scope will be added to an implicit &lt;code&gt;cbuffer&lt;/code&gt;). cbuffers themselves are outside the scope of this blog post, but they&amp;#39;re pretty cool and offer some good performance improvements over the Direct3D 9 way of doing things. A typical &lt;code&gt;cbuffer&lt;/code&gt; might look like this:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;
cbuffer BasicEffectVertexConstants : &lt;span style="color:#088;font-weight:bold"&gt;register&lt;/span&gt;(b0)
{
    matrix WorldViewProjection;
    matrix World;
}
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;The difficulty comes in setting the values for &lt;code&gt;WorldViewProjection&lt;/code&gt; and &lt;code&gt;World&lt;/code&gt; from your C# code. It gets even tricker if you want to use arrays inside your structures.&lt;/p&gt;

&lt;h2&gt;A solution&lt;/h2&gt;

&lt;p&gt;What follows is fairly SharpDX-specific, although the same general principle should work for SlimDX too. First, we need to define a C# struct that matches the HLSL struct.&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;
[StructLayout(LayoutKind.Explicit, Size = &lt;span style="color:#00D"&gt;128&lt;/span&gt;)]
internal &lt;span style="color:#080;font-weight:bold"&gt;struct&lt;/span&gt; BasicEffectVertexConstants
{
    [FieldOffset(&lt;span style="color:#00D"&gt;0&lt;/span&gt;)]
    &lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; Matrix WorldViewProjection;

    [FieldOffset(&lt;span style="color:#00D"&gt;64&lt;/span&gt;)]
    &lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; Matrix World;
}
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;You will notice I&amp;#39;ve used attributes to explicitly set the size and field offsets. This is to avoid differences between .NET and HLSL in how fields are packed. MSDN has a good page on &lt;a href="http://msdn.microsoft.com/en-us/library/bb509632.aspx"&gt;Packing Rules for Constant Variables&lt;/a&gt;, which covers the HLSL side. For the struct above, it would be packed correctly for HLSL even without the attributes, but that isn&amp;#39;t always true, so I prefer to be consistent and always set the size and field offsets explicitly.&lt;/p&gt;

&lt;p&gt;Now we need a couple of helper methods. The first is going to create a Direct3D 11 constant buffer resource, for a particular struct type. The second helper method is going to update that Direct3D 11 constant buffer resource with new values. &lt;em&gt;UPDATE&lt;/em&gt; To keep things simple, we&amp;#39;ll create a new class:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;
internal &lt;span style="color:#080;font-weight:bold"&gt;class&lt;/span&gt; &lt;span style="color:#B06;font-weight:bold"&gt;ConstantBuffer&lt;/span&gt;&amp;lt;T&amp;gt; : IDisposable
    where T : &lt;span style="color:#080;font-weight:bold"&gt;struct&lt;/span&gt;
{
    &lt;span style="color:#088;font-weight:bold"&gt;private&lt;/span&gt; readonly Device _device;
    &lt;span style="color:#088;font-weight:bold"&gt;private&lt;/span&gt; readonly Buffer _buffer;
    &lt;span style="color:#088;font-weight:bold"&gt;private&lt;/span&gt; readonly DataStream _dataStream;

    &lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; Buffer Buffer
    {
        get { &lt;span style="color:#080;font-weight:bold"&gt;return&lt;/span&gt; _buffer; }
    }

    &lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; ConstantBuffer(Device device)
    {
        _device = device;

        &lt;span style="color:#777"&gt;// If no specific marshalling is needed, can use&lt;/span&gt;
        &lt;span style="color:#777"&gt;// SharpDX.Utilities.SizeOf&amp;lt;T&amp;gt;() for better performance.&lt;/span&gt;
        &lt;span style="color:#0a5;font-weight:bold"&gt;int&lt;/span&gt; size = Marshal.SizeOf(typeof (T));

        _buffer = &lt;span style="color:#080;font-weight:bold"&gt;new&lt;/span&gt; Buffer(device, &lt;span style="color:#080;font-weight:bold"&gt;new&lt;/span&gt; BufferDescription
        {
            Usage = ResourceUsage.Default,
            BindFlags = BindFlags.ConstantBuffer,
            SizeInBytes = size,
            CpuAccessFlags = CpuAccessFlags.None,
            OptionFlags = ResourceOptionFlags.None,
            StructureByteStride = &lt;span style="color:#00D"&gt;0&lt;/span&gt;
        });

        _dataStream = &lt;span style="color:#080;font-weight:bold"&gt;new&lt;/span&gt; DataStream(size, &lt;span style="color:#069"&gt;true&lt;/span&gt;, &lt;span style="color:#069"&gt;true&lt;/span&gt;);
    }

    &lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; &lt;span style="color:#088;font-weight:bold"&gt;void&lt;/span&gt; UpdateValue(T value)
    {
        &lt;span style="color:#777"&gt;// If no specific marshalling is needed, can use &lt;/span&gt;
        &lt;span style="color:#777"&gt;// dataStream.Write(value) for better performance.&lt;/span&gt;
        Marshal.StructureToPtr(value, _dataStream.DataPointer, &lt;span style="color:#069"&gt;false&lt;/span&gt;);

        var dataBox = &lt;span style="color:#080;font-weight:bold"&gt;new&lt;/span&gt; DataBox(&lt;span style="color:#00D"&gt;0&lt;/span&gt;, &lt;span style="color:#00D"&gt;0&lt;/span&gt;, _dataStream);
        _device.ImmediateContext.UpdateSubresource(dataBox, _buffer, &lt;span style="color:#00D"&gt;0&lt;/span&gt;);
    }

    &lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; &lt;span style="color:#088;font-weight:bold"&gt;void&lt;/span&gt; Dispose()
    {
        &lt;span style="color:#080;font-weight:bold"&gt;if&lt;/span&gt; (_dataStream != null)
            _dataStream.Dispose();
        &lt;span style="color:#080;font-weight:bold"&gt;if&lt;/span&gt; (_buffer != null)
            _buffer.Dispose();
    }
}
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Armed with this class, we can start to write our actual code. First, we&amp;#39;ll create the constant buffer. This should be in your initialisation code:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;
_vertexConstantBuffer = &lt;span style="color:#080;font-weight:bold"&gt;new&lt;/span&gt; ConstantBuffer&amp;lt;BasicEffectVertexConstants&amp;gt;(device);
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Don&amp;#39;t forget to &lt;code&gt;Dispose()&lt;/code&gt; of that instance in your cleanup code.&lt;/p&gt;

&lt;p&gt;Finally, we can update the values inside the &lt;code&gt;cbuffer&lt;/code&gt; using the values from our C# struct with this code. Obviously you&amp;#39;ll want to replace the structure type, and the setting of the field values, with your own parameters.&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;
var vertexConstants = &lt;span style="color:#080;font-weight:bold"&gt;new&lt;/span&gt; BasicEffectVertexConstants();

Matrix wvp = ConversionUtility.ToSharpDXMatrix(World * View * Projection);
vertexConstants.WorldViewProjection = Matrix.Transpose(wvp);
vertexConstants.World = Matrix.Transpose(ConversionUtility.ToSharpDXMatrix(World));

_vertexConstantBuffer.UpdateValue(vertexConstants);

DeviceContext.VertexShader.SetConstantBuffer(&lt;span style="color:#00D"&gt;0&lt;/span&gt;, _vertexConstantBuffer.Buffer);
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2&gt;Field offsets&lt;/h2&gt;

&lt;p&gt;If your &lt;code&gt;cbuffer&lt;/code&gt; is more complicated, then you&amp;#39;ll have some other problems. Take this example:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;
cbuffer BasicEffectPixelConstants : &lt;span style="color:#088;font-weight:bold"&gt;register&lt;/span&gt;(b0)
{
    float3 CameraPosition = float3(&lt;span style="color:#00D"&gt;0&lt;/span&gt;, &lt;span style="color:#00D"&gt;5&lt;/span&gt;, &lt;span style="color:#00D"&gt;20&lt;/span&gt;);

    &lt;span style="color:#0a5;font-weight:bold"&gt;bool&lt;/span&gt; LightingEnabled = &lt;span style="color:#069"&gt;true&lt;/span&gt;;

    float3 AmbientLightColor = float3(&lt;span style="color:#60E"&gt;0&lt;/span&gt;&lt;span style="color:#60E"&gt;.3&lt;/span&gt;, &lt;span style="color:#60E"&gt;0&lt;/span&gt;&lt;span style="color:#60E"&gt;.3&lt;/span&gt;, &lt;span style="color:#60E"&gt;0&lt;/span&gt;&lt;span style="color:#60E"&gt;.3&lt;/span&gt;);

    float3 DiffuseColor = float3(&lt;span style="color:#60E"&gt;0&lt;/span&gt;&lt;span style="color:#60E"&gt;.1&lt;/span&gt;, &lt;span style="color:#60E"&gt;0&lt;/span&gt;&lt;span style="color:#60E"&gt;.7&lt;/span&gt;, &lt;span style="color:#60E"&gt;0&lt;/span&gt;&lt;span style="color:#60E"&gt;.1&lt;/span&gt;);
    float3 SpecularColor = float3(&lt;span style="color:#00D"&gt;1&lt;/span&gt;, &lt;span style="color:#00D"&gt;1&lt;/span&gt;, &lt;span style="color:#00D"&gt;1&lt;/span&gt;);
    &lt;span style="color:#0a5;font-weight:bold"&gt;float&lt;/span&gt; SpecularPower = &lt;span style="color:#00D"&gt;16&lt;/span&gt;;

    &lt;span style="color:#0a5;font-weight:bold"&gt;bool&lt;/span&gt; TextureEnabled = &lt;span style="color:#069"&gt;false&lt;/span&gt;;

    &lt;span style="color:#0a5;font-weight:bold"&gt;float&lt;/span&gt; Alpha = &lt;span style="color:#00D"&gt;1&lt;/span&gt;;
}
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;If you tried to map that onto a C# struct without explicitly setting field offsets, it wouldn&amp;#39;t work, because HLSL has very strict &lt;a href="http://msdn.microsoft.com/en-us/library/bb509632.aspx"&gt;rules&lt;/a&gt; for packing constant variables, which are not the same as .NET. I haven&amp;#39;t found an automatic way of calculating the correct field offsets, but I have setup unit tests that allow me to check that I got it right. In this case, the corresponding C# struct looks like this:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;
[StructLayout(LayoutKind.Explicit, Size = &lt;span style="color:#00D"&gt;80&lt;/span&gt;)]
internal &lt;span style="color:#080;font-weight:bold"&gt;struct&lt;/span&gt; BasicEffectPixelConstants
{
    [FieldOffset(&lt;span style="color:#00D"&gt;0&lt;/span&gt;)]
    &lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; Vector3 CameraPosition;

    [FieldOffset(&lt;span style="color:#00D"&gt;12&lt;/span&gt;)]
    &lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; &lt;span style="color:#0a5;font-weight:bold"&gt;bool&lt;/span&gt; LightingEnabled;

    [FieldOffset(&lt;span style="color:#00D"&gt;16&lt;/span&gt;)]
    &lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; Vector3 AmbientLightColor;

    [FieldOffset(&lt;span style="color:#00D"&gt;32&lt;/span&gt;)]
    &lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; Vector3 DiffuseColor;

    [FieldOffset(&lt;span style="color:#00D"&gt;48&lt;/span&gt;)]
    &lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; Vector3 SpecularColor;

    [FieldOffset(&lt;span style="color:#00D"&gt;60&lt;/span&gt;)]
    &lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; &lt;span style="color:#0a5;font-weight:bold"&gt;float&lt;/span&gt; SpecularPower;

    [FieldOffset(&lt;span style="color:#00D"&gt;64&lt;/span&gt;)]
    &lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; &lt;span style="color:#0a5;font-weight:bold"&gt;bool&lt;/span&gt; TextureEnabled;

    [FieldOffset(&lt;span style="color:#00D"&gt;68&lt;/span&gt;)]
    &lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; &lt;span style="color:#0a5;font-weight:bold"&gt;float&lt;/span&gt; Alpha;
}
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2&gt;Arrays&lt;/h2&gt;

&lt;p&gt;Finally, I can cover the case that prompted this blog post: using arrays inside your structs. You&amp;#39;ll want to do this, for example, if you want to have a collection of lights, and loop through them in your shader code.&lt;/p&gt;

&lt;p&gt;I have a DirectionalLight structure in HLSL:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;
&lt;span style="color:#080;font-weight:bold"&gt;struct&lt;/span&gt; DirectionalLight
{
    &lt;span style="color:#0a5;font-weight:bold"&gt;bool&lt;/span&gt; Enabled;
    float3 Direction;
    float3 Color;
};
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;... for which I&amp;#39;ve defined the corresponding structure in C#:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;
[StructLayout(LayoutKind.Explicit, Size = &lt;span style="color:#00D"&gt;32&lt;/span&gt;)]
internal &lt;span style="color:#080;font-weight:bold"&gt;struct&lt;/span&gt; BasicEffectDirectionalLight
{
    [FieldOffset(&lt;span style="color:#00D"&gt;0&lt;/span&gt;)]
    &lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; &lt;span style="color:#0a5;font-weight:bold"&gt;bool&lt;/span&gt; Enabled;

    [FieldOffset(&lt;span style="color:#00D"&gt;4&lt;/span&gt;)]
    &lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; Vector3 Direction;

    [FieldOffset(&lt;span style="color:#00D"&gt;16&lt;/span&gt;)]
    &lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; Vector3 Color;
}
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;I then have this &lt;code&gt;cbuffer&lt;/code&gt;:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;
&lt;span style="color:#579"&gt;#define&lt;/span&gt; MAX_LIGHTS &lt;span style="color:#00D"&gt;16&lt;/span&gt;

cbuffer LightConstants : &lt;span style="color:#088;font-weight:bold"&gt;register&lt;/span&gt;(b1)
{
    &lt;span style="color:#0a5;font-weight:bold"&gt;int&lt;/span&gt; ActiveDirectionalLights;
    DirectionalLight DirectionalLights[MAX_LIGHTS];
}
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;... which maps to this C# structure:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;
&lt;span style="color:#088;font-weight:bold"&gt;private&lt;/span&gt; &lt;span style="color:#088;font-weight:bold"&gt;const&lt;/span&gt; &lt;span style="color:#0a5;font-weight:bold"&gt;int&lt;/span&gt; MaxLights = &lt;span style="color:#00D"&gt;16&lt;/span&gt;;

[StructLayout(LayoutKind.Explicit, Size = &lt;span style="color:#00D"&gt;4&lt;/span&gt; + (&lt;span style="color:#00D"&gt;32&lt;/span&gt; * MaxLights) + &lt;span style="color:#00D"&gt;12&lt;/span&gt; &lt;span style="color:#777"&gt;/* padding */&lt;/span&gt;)]
internal &lt;span style="color:#080;font-weight:bold"&gt;struct&lt;/span&gt; BasicEffectLightConstants
{
    [FieldOffset(&lt;span style="color:#00D"&gt;0&lt;/span&gt;)]
    &lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; &lt;span style="color:#0a5;font-weight:bold"&gt;int&lt;/span&gt; ActiveDirectionalLights;

    [FieldOffset(&lt;span style="color:#00D"&gt;16&lt;/span&gt;), MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxLights)]
    &lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; BasicEffectDirectionalLight[] DirectionalLights;
}
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;The additional &lt;code&gt;MarshalAs&lt;/code&gt; attribute on the array is the key to getting this to work. Without that, .NET won&amp;#39;t know how to map the structure into the fixed size bit of memory that Direct3D has allocated to the &lt;code&gt;cbuffer&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In summary - mapping structures from C# to HLSL cbuffers is non-trivial, but can certainly be done in entirely managed code. Have a look at the source code for &lt;a href="http://github.com/tgjones/dotwarp"&gt;DotWarp&lt;/a&gt; to see a complete working example.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/DhHmdj-Y648" height="1" width="1"/&gt;</description>
      <pubDate>Tue, 08 Mar 2011 01:18:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/DhHmdj-Y648/marshalling-c-structures-into-directd--cbuffers-using</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2011/03/08/marshalling-c-structures-into-directd--cbuffers-using</feedburner:origLink></item>
    <item>
      <title>DotWarp - Server-side 3D renderer for .NET</title>
      <description>&lt;h2&gt;Skip to the end...&lt;/h2&gt;

&lt;p&gt;You can download DotWarp binaries from two places:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/tgjones/dotwarp/downloads"&gt;GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.nuget.org/Packages/Packages/Details/DotWarp-1-1-0-0"&gt;NuGet&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;What is it?&lt;/h2&gt;

&lt;p&gt;Building on top of &lt;a href="/blog/archive/2011/02/22/nexus---vector-and-matrix-maths-library"&gt;Nexus&lt;/a&gt; and &lt;a href="/blog/archive/2011/02/22/meshellator---open-source-d-asset-import"&gt;Meshellator&lt;/a&gt;, I am pleased to announce the first version of &lt;a href="https://github.com/tgjones/dotwarp"&gt;DotWarp&lt;/a&gt;, an open source server-side 3D renderer for .NET 4.0. It can be used in a background application (i.e. one without a UI) for rendering 3D meshes into 2D bitmaps.&lt;/p&gt;

&lt;p&gt;As the name suggests, DotWarp builds on top of &lt;a href="http://msdn.microsoft.com/en-us/library/gg615082.aspx"&gt;Windows Advanced Rasterization Platform&lt;/a&gt; (or WARP). WARP is a software rasterizer, written by Microsoft, which allows Direct3D to be used in situations where it previously could not be - such as on servers without dedicated graphics hardware. WARP will work wherever the DirectX 11 runtime is installed, which at this time is Windows 7, Windows Server 2008 R2, and Windows Vista with the KB971644 update. I have personally tested it on Windows 7 and Windows Server 2008 R2.&lt;/p&gt;

&lt;p&gt;DotWarp also makes extensive use of &lt;a href="http://code.google.com/p/sharpdx/"&gt;SharpDX&lt;/a&gt;. SharpDX is a .NET managed DirectX API, directly generated from DirectX SDK headers. I could also have used SlimDX, but I like the fact that SharpDX is platform independent, so doesn&amp;#39;t require separate builds for x86 and x64. I&amp;#39;d like to give a shout out to &lt;a href="http://code4k.blogspot.com/"&gt;Alexandre Mutel&lt;/a&gt;, not just for writing SharpDX but also for being very helpful answering my (in some cases dumb) questions about it.&lt;/p&gt;

&lt;h2&gt;How can I use it?&lt;/h2&gt;

&lt;p&gt;First you&amp;#39;ll need to add a reference from your project to the DotWarp, Meshellator and Nexus assemblies. The easiest way to do this is via &lt;a href="http://www.nuget.org/"&gt;NuGet&lt;/a&gt; (just search for &lt;a href="http://www.nuget.org/Packages/Packages/Details/DotWarp-1-1-0-0"&gt;DotWarp&lt;/a&gt; - that package will bring in all required dependencies), but you can also &lt;a href="https://github.com/tgjones/dotwarp/downloads"&gt;download the binaries from GitHub&lt;/a&gt;. You&amp;#39;ll also need the latest &lt;a href="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=2DA43D38-DB71-4C1B-BC6A-9B6652CD92A3"&gt;DirectX End-User Runtime&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The only DotWarp class you need to worry about is &lt;code&gt;WarpSceneRenderer&lt;/code&gt;. This requires a &lt;code&gt;Scene&lt;/code&gt; object, a width and height, and a &lt;code&gt;Camera&lt;/code&gt;. The &lt;code&gt;Scene&lt;/code&gt; object comes from Meshellator (either loaded from a mesh file or created from a primitive shape), and the &lt;code&gt;Camera&lt;/code&gt; comes from Nexus (either created manually or automatically from the scene bounds). The &lt;code&gt;Render&lt;/code&gt; method returns a &lt;code&gt;BitmapSource&lt;/code&gt;, which is WPF&amp;#39;s bitmap type. This can then be saved to disk, or used however you like.&lt;/p&gt;

&lt;p&gt;We&amp;#39;ll start simple:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;
Scene scene = MeshellatorLoader.CreateFromTeapot(&lt;span style="color:#00D"&gt;10&lt;/span&gt;, &lt;span style="color:#00D"&gt;20&lt;/span&gt;);
&lt;span style="color:#088;font-weight:bold"&gt;using&lt;/span&gt; (WarpSceneRenderer renderer = &lt;span style="color:#080;font-weight:bold"&gt;new&lt;/span&gt; WarpSceneRenderer(scene, &lt;span style="color:#00D"&gt;550&lt;/span&gt;, &lt;span style="color:#00D"&gt;350&lt;/span&gt;))
{
    renderer.Initialize();

    Camera camera = PerspectiveCamera.CreateFromBounds(
        scene.Bounds, &lt;span style="color:#080;font-weight:bold"&gt;new&lt;/span&gt; Viewport(&lt;span style="color:#00D"&gt;0&lt;/span&gt;, &lt;span style="color:#00D"&gt;0&lt;/span&gt;, &lt;span style="color:#00D"&gt;550&lt;/span&gt;, &lt;span style="color:#00D"&gt;350&lt;/span&gt;),
        MathUtility.PI_OVER_4, &lt;span style="color:#00D"&gt;0&lt;/span&gt;, &lt;span style="color:#00D"&gt;0&lt;/span&gt;, &lt;span style="color:#00D"&gt;1&lt;/span&gt;);

    BitmapSource bitmap = renderer.Render(camera);

    JpegBitmapEncoder e = &lt;span style="color:#080;font-weight:bold"&gt;new&lt;/span&gt; JpegBitmapEncoder();
    e.Frames.Add(BitmapFrame.Create(bitmap));
    &lt;span style="color:#088;font-weight:bold"&gt;using&lt;/span&gt; (Stream stream = File.OpenWrite(&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;output.jpg&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;))
        e.Save(stream);
}
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Which results in this, which is not terribly interesting:&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/blog/dotwarp1.jpg" alt="image"/&gt;&lt;/p&gt;

&lt;p&gt;To control the camera, we can setup a &lt;code&gt;PerspectiveCamera&lt;/code&gt; or &lt;code&gt;OrthographicCamera&lt;/code&gt; with the desired parameters. But it&amp;#39;s hard to get the position and direction right, and I&amp;#39;m lazy, so I like to use the &lt;code&gt;CreateFromBounds&lt;/code&gt; method on &lt;code&gt;PerspectiveCamera&lt;/code&gt;, which lets you set yaw and pitch like this (angles are in radians):&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;
...

Camera camera = PerspectiveCamera.CreateFromBounds(
    scene.Bounds, &lt;span style="color:#080;font-weight:bold"&gt;new&lt;/span&gt; Viewport(&lt;span style="color:#00D"&gt;0&lt;/span&gt;, &lt;span style="color:#00D"&gt;0&lt;/span&gt;, &lt;span style="color:#00D"&gt;550&lt;/span&gt;, &lt;span style="color:#00D"&gt;350&lt;/span&gt;),
    MathUtility.PI_OVER_4, &lt;span style="color:#60E"&gt;0&lt;/span&gt;&lt;span style="color:#60E"&gt;.3f&lt;/span&gt;, &lt;span style="color:#60E"&gt;0&lt;/span&gt;&lt;span style="color:#60E"&gt;.3f&lt;/span&gt;, &lt;span style="color:#00D"&gt;1&lt;/span&gt;);

...
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Keeping everything else the same, results in this image, which is slightly better:&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/blog/dotwarp2.jpg" alt="image"/&gt;&lt;/p&gt;

&lt;p&gt;Of course only rendering primitives is not really very useful, so let&amp;#39;s render a mesh from a 3DS file:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;
Scene scene = MeshellatorLoader.ImportFromFile(&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;Models/3ds/85-nissan-fairlady.3ds&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;);
&lt;span style="color:#088;font-weight:bold"&gt;using&lt;/span&gt; (WarpSceneRenderer renderer = &lt;span style="color:#080;font-weight:bold"&gt;new&lt;/span&gt; WarpSceneRenderer(scene, &lt;span style="color:#00D"&gt;550&lt;/span&gt;, &lt;span style="color:#00D"&gt;250&lt;/span&gt;))
{
    renderer.Initialize();

    Camera camera = PerspectiveCamera.CreateFromBounds(
        scene.Bounds, &lt;span style="color:#080;font-weight:bold"&gt;new&lt;/span&gt; Viewport(&lt;span style="color:#00D"&gt;0&lt;/span&gt;, &lt;span style="color:#00D"&gt;0&lt;/span&gt;, &lt;span style="color:#00D"&gt;550&lt;/span&gt;, &lt;span style="color:#00D"&gt;250&lt;/span&gt;),
        MathUtility.PI_OVER_4, &lt;span style="color:#60E"&gt;2&lt;/span&gt;&lt;span style="color:#60E"&gt;.5f&lt;/span&gt;, -&lt;span style="color:#60E"&gt;0&lt;/span&gt;&lt;span style="color:#60E"&gt;.3f&lt;/span&gt;, &lt;span style="color:#00D"&gt;1&lt;/span&gt;);

    BitmapSource bitmap = renderer.Render(camera);

    JpegBitmapEncoder e = &lt;span style="color:#080;font-weight:bold"&gt;new&lt;/span&gt; JpegBitmapEncoder();
    e.Frames.Add(BitmapFrame.Create(bitmap));
    &lt;span style="color:#088;font-weight:bold"&gt;using&lt;/span&gt; (Stream stream = File.OpenWrite(&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;output.jpg&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;))
        e.Save(stream);
}
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;That&amp;#39;s a little more interesting:&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/blog/dotwarp3.jpg" alt="image"/&gt;&lt;/p&gt;

&lt;p&gt;There are a few options that can be configured (not many options in this first version):&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;
Scene scene = MeshellatorLoader.ImportFromFile(&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;Models/Obj/Tank.obj&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;);
&lt;span style="color:#088;font-weight:bold"&gt;using&lt;/span&gt; (WarpSceneRenderer renderer = &lt;span style="color:#080;font-weight:bold"&gt;new&lt;/span&gt; WarpSceneRenderer(scene, &lt;span style="color:#00D"&gt;550&lt;/span&gt;, &lt;span style="color:#00D"&gt;350&lt;/span&gt;))
{
    renderer.Initialize();

    renderer.Options.TriangleWindingOrderReversed = &lt;span style="color:#069"&gt;true&lt;/span&gt;;
    renderer.Options.BackgroundColor = Colors.Gray;
    renderer.Options.LightingEnabled = &lt;span style="color:#069"&gt;false&lt;/span&gt;;

    Camera camera = PerspectiveCamera.CreateFromBounds(
        scene.Bounds, &lt;span style="color:#080;font-weight:bold"&gt;new&lt;/span&gt; Viewport(&lt;span style="color:#00D"&gt;0&lt;/span&gt;, &lt;span style="color:#00D"&gt;0&lt;/span&gt;, &lt;span style="color:#00D"&gt;550&lt;/span&gt;, &lt;span style="color:#00D"&gt;350&lt;/span&gt;),
        MathUtility.PI_OVER_4, &lt;span style="color:#60E"&gt;0&lt;/span&gt;&lt;span style="color:#60E"&gt;.5f&lt;/span&gt;, -&lt;span style="color:#60E"&gt;0&lt;/span&gt;&lt;span style="color:#60E"&gt;.3f&lt;/span&gt;, &lt;span style="color:#00D"&gt;1&lt;/span&gt;);

    BitmapSource bitmap = renderer.Render(camera);

    JpegBitmapEncoder e = &lt;span style="color:#080;font-weight:bold"&gt;new&lt;/span&gt; JpegBitmapEncoder();
    e.Frames.Add(BitmapFrame.Create(bitmap));
    &lt;span style="color:#088;font-weight:bold"&gt;using&lt;/span&gt; (Stream stream = File.OpenWrite(&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;output.jpg&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;))
        e.Save(stream);
}
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;img src="/assets/blog/dotwarp4.jpg" alt="image"/&gt;&lt;/p&gt;

&lt;p&gt;Finally, the camera can of course be positioned manually:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;
Scene scene = MeshellatorLoader.ImportFromFile(&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;Models/3ds/85-nissan-fairlady.3ds&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;);
&lt;span style="color:#088;font-weight:bold"&gt;using&lt;/span&gt; (WarpSceneRenderer renderer = &lt;span style="color:#080;font-weight:bold"&gt;new&lt;/span&gt; WarpSceneRenderer(scene, &lt;span style="color:#00D"&gt;550&lt;/span&gt;, &lt;span style="color:#00D"&gt;350&lt;/span&gt;))
{
    renderer.Initialize();

    renderer.Options.BackgroundColor = Color.FromRgb(&lt;span style="color:#00D"&gt;200&lt;/span&gt;, &lt;span style="color:#00D"&gt;200&lt;/span&gt;, &lt;span style="color:#00D"&gt;200&lt;/span&gt;);

    Camera camera = &lt;span style="color:#080;font-weight:bold"&gt;new&lt;/span&gt; PerspectiveCamera
    {
        LookDirection = &lt;span style="color:#080;font-weight:bold"&gt;new&lt;/span&gt; Vector3D(-&lt;span style="color:#00D"&gt;1&lt;/span&gt;, -&lt;span style="color:#60E"&gt;0&lt;/span&gt;&lt;span style="color:#60E"&gt;.3f&lt;/span&gt;, &lt;span style="color:#00D"&gt;1&lt;/span&gt;),
        Position = &lt;span style="color:#080;font-weight:bold"&gt;new&lt;/span&gt; Point3D(&lt;span style="color:#00D"&gt;2100&lt;/span&gt;, &lt;span style="color:#00D"&gt;1200&lt;/span&gt;, -&lt;span style="color:#00D"&gt;700&lt;/span&gt;),
    };

    BitmapSource bitmap = renderer.Render(camera);

    JpegBitmapEncoder e = &lt;span style="color:#080;font-weight:bold"&gt;new&lt;/span&gt; JpegBitmapEncoder();
    e.Frames.Add(BitmapFrame.Create(bitmap));
    &lt;span style="color:#088;font-weight:bold"&gt;using&lt;/span&gt; (Stream stream = File.OpenWrite(&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;output.jpg&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;))
        e.Save(stream);
}
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;img src="/assets/blog/dotwarp5.jpg" alt="image"/&gt;&lt;/p&gt;

&lt;p&gt;DotWarp can also be used from the command line, but the command line tool only lets you specify an input model and an output file, and it positions the camera automatically, so it&amp;#39;s not terribly useful for anything other than testing:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;DotWarp.CommandLine.exe &amp;quot;MyModel.3ds&amp;quot; &amp;quot;output.png&amp;quot;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;And that&amp;#39;s it! I hope you find this useful - if you have any feedback or suggestions, please let me know with a comment below.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/at7dJIPIVsQ" height="1" width="1"/&gt;</description>
      <pubDate>Wed, 23 Feb 2011 20:22:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/at7dJIPIVsQ/dotwarp---server-side-d-renderer-for</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2011/02/23/dotwarp---server-side-d-renderer-for</feedburner:origLink></item>
    <item>
      <title>Meshellator - Open source 3D asset import library for .NET / Silverlight</title>
      <description>&lt;p&gt;&lt;a href="https://github.com/tgjones/meshellator"&gt;Meshellator&lt;/a&gt; is an open source 3D asset import library, available for both .NET 4.0 and Silverlight 4.0. Meshellator is the underlying library for the &lt;a href="/blog/archive/2010/11/20/ds-obj-and-nff-content-importers-for-xna"&gt;3DS, OBJ and NFF content importers for XNA&lt;/a&gt; which I have mentioned previously.&lt;/p&gt;

&lt;h2&gt;What?&lt;/h2&gt;

&lt;p&gt;Supported file formats are quite limited at the moment. If anybody wants to contribute more, please &lt;a href="https://github.com/tgjones/meshellator"&gt;feel free&lt;/a&gt;!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;3DS&lt;/li&gt;
&lt;li&gt;OBJ&lt;/li&gt;
&lt;li&gt;NFF&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As well as importing meshes from a file, Meshellator also allows you to create meshes from primitive shapes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cube&lt;/li&gt;
&lt;li&gt;Cylinder&lt;/li&gt;
&lt;li&gt;Plane&lt;/li&gt;
&lt;li&gt;Sphere&lt;/li&gt;
&lt;li&gt;Teapot&lt;/li&gt;
&lt;li&gt;Torus&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Meshellator&amp;#39;s only dependency is on &lt;a href="https://github.com/tgjones/nexus"&gt;Nexus&lt;/a&gt;, a lightweight vector and matrix library I &lt;a href="/blog/archive/2011/02/22/nexus---vector-and-matrix-maths-library"&gt;blogged about recently&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;How?&lt;/h2&gt;

&lt;p&gt;Meshellator is quite easy to use. After you&amp;#39;ve added a reference to &lt;code&gt;Meshellator.dll&lt;/code&gt; (or &lt;code&gt;Meshellator.Silverlight.dll&lt;/code&gt;), the following line is enough to load from a file into a &lt;code&gt;Scene&lt;/code&gt; object. The &lt;code&gt;Scene&lt;/code&gt; object contains collections for meshes and materials, and should be quite intuitive to navigate.&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;Scene scene = MeshellatorLoader.ImportFromFile(&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;85-nissan-fairlady.3ds&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;);
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Loading one of the built-in primitive shapes is just as easy. Each of the primitive shape methods have some parameters for size and tessellation level.&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;
Scene scene = MeshellatorLoader.CreateFromTeapot(&lt;span style="color:#00D"&gt;10&lt;/span&gt;, &lt;span style="color:#00D"&gt;20&lt;/span&gt;);
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2&gt;Why?&lt;/h2&gt;

&lt;p&gt;Given that there&amp;#39;s several open source asset import libraries already - in particular &lt;a href="http://assimp.sourceforge.net/"&gt;Open Asset Import Library (or Assimp)&lt;/a&gt; - why make another one? Good question - if you&amp;#39;re working purely on Windows, and don&amp;#39;t mind a bit of interop into native code, then Assimp is indeed the solution I&amp;#39;d recommend. It&amp;#39;s mature, well supported, and supports a whole host of formats.&lt;/p&gt;

&lt;p&gt;Meshellator, on the other hand, is new and only supports 2 or 3 file formats at the moment. However, I believe it has a useful place in the .NET ecosystem, as the first (as far as I know) fully managed open source asset import library. Because it&amp;#39;s fully managed, it also works on Silverlight.&lt;/p&gt;

&lt;h2&gt;Where?&lt;/h2&gt;

&lt;p&gt;You can browse the Meshellator source code &lt;a href="https://github.com/tgjones/meshellator"&gt;here&lt;/a&gt;, and you can download the binaries from two places:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/tgjones/meshellator/downloads"&gt;GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://nuget.org/Packages/Packages/Details/Meshellator-1-0-0-0"&gt;NuGet&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Viewer&lt;/h2&gt;

&lt;p&gt;The source code (but not the binary downloads) includes a viewer application.&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/blog/meshellatorviewer1.jpg" alt="image"/&gt;&lt;/p&gt;

&lt;p&gt;The viewer application is not developed enough to be that useful, but it may be of technical interest - it combines &lt;a href="http://avalondock.codeplex.com/"&gt;AvalonDock&lt;/a&gt;, &lt;a href="http://fluent.codeplex.com/"&gt;FluentRibbon&lt;/a&gt; and &lt;a href="http://slimdx.org/"&gt;SlimDX&lt;/a&gt; in a WPF MVVM application based on &lt;a href="http://caliburn.codeplex.com/"&gt;Caliburn&lt;/a&gt;. As a historical aside, this viewer application is what eventually became &lt;a href="/blog/archive/2010/12/09/xbuilder-v-released"&gt;XBuilder&lt;/a&gt;, after I realised that the world didn&amp;#39;t need another general-purpose model viewer, and the &amp;quot;model viewer as a Visual Studio extension&amp;quot; niche was more interesting.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/lYHMyj40-Pg" height="1" width="1"/&gt;</description>
      <pubDate>Tue, 22 Feb 2011 22:48:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/lYHMyj40-Pg/meshellator---open-source-d-asset-import</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2011/02/22/meshellator---open-source-d-asset-import</feedburner:origLink></item>
    <item>
      <title>Nexus - vector and matrix maths library for .NET / Silverlight, suitable for 3D development</title>
      <description>&lt;p&gt;&lt;a href="https://github.com/tgjones/nexus"&gt;Nexus&lt;/a&gt; is a vector and maths library I have been using for my own projects for a while now. &lt;/p&gt;

&lt;p&gt;Unlike WPF&amp;#39;s 3D structures in the &lt;code&gt;System.Windows.Media.Media3D&lt;/code&gt; namespace, such as &lt;code&gt;Point3D&lt;/code&gt;, the structures in Nexus use fields, rather than properties, so they can be used directly in the context of vertex shaders and pixel shaders, which require predicable structure layouts. &lt;/p&gt;

&lt;p&gt;I followed WPF&amp;#39;s example of having separate structures for points (positions) and vectors (directions, i.e. normals). I feel this makes for cleaner APIs.&lt;/p&gt;

&lt;p&gt;Nexus has structures for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;2D, 3D and 4D vectors and points&lt;/li&gt;
&lt;li&gt;3D lines and rays&lt;/li&gt;
&lt;li&gt;Quaternion class&lt;/li&gt;
&lt;li&gt;3x3 and 4x4 matrices&lt;/li&gt;
&lt;li&gt;Colors&lt;/li&gt;
&lt;li&gt;Bounding boxes&lt;/li&gt;
&lt;li&gt;Transforms (scale, translation, rotation)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Nexus also includes a &lt;code&gt;Camera&lt;/code&gt; class, with &lt;code&gt;PerspectiveCamera&lt;/code&gt; and &lt;code&gt;OrthographicCamera&lt;/code&gt; derived classes. &lt;code&gt;PerspectiveCamera&lt;/code&gt; includes a &lt;code&gt;CreateFromBounds()&lt;/code&gt; method that might be interesting to others, which allows the camera to be positioned based on a bounding box of an object or scene.&lt;/p&gt;

&lt;p&gt;Nexus has no dependencies apart from the .NET framework, is available for .NET 4.0 and Silverlight 4, and is open source. You can get the binaries from two locations: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/tgjones/nexus/downloads"&gt;GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.nuget.org/Packages/Packages/Details/Nexus-1-0-0-0"&gt;NuGet&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I wrote Nexus because some of my graphics projects don&amp;#39;t use XNA, and I wanted a standard (and lightweight) maths library I could fall back on in those situations. Obviously if your game or project targets XNA or another framework that comes with its own maths library, then you wouldn&amp;#39;t need something like Nexus.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/BGTEZyugvBI" height="1" width="1"/&gt;</description>
      <pubDate>Tue, 22 Feb 2011 09:51:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/BGTEZyugvBI/nexus---vector-and-matrix-maths-library</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2011/02/22/nexus---vector-and-matrix-maths-library</feedburner:origLink></item>
    <item>
      <title>StitchUp in action</title>
      <description>&lt;p&gt;After launching an &lt;a href="/blog/archive/2010/11/13/introducing-stitchup-generating-shaders-from-hlsl-shader-fragments"&gt;open source project&lt;/a&gt;, it&amp;#39;s always gratifying to see it being used by other people. So far, I know about two instances where StitchUp has been integrated into a graphics &amp;#47; game engine.&lt;/p&gt;

&lt;h2&gt;MadoxLabs Framework&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://madox.ca/mediawiki/index.php/XBox:Framework:StitchUp"&gt;MadoxLabs Xbox Framework - StitchUp&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That link is a great write-up of how StitchUp was integrated into their engine. The write-up concludes with this note on performance:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;All of the extra function calls, structure manipulating and variable copying that StitchUp does seems like a lot of work on the surface. To look into this, I compared the generated ASM file for a StitchUp shader and my original hand written shader. The result is that the StitchUp shader is smaller or equal to the original shader. In two places, the StitchUp shader avoided an if statement. In one place, it avoided an rsq call. There is also less preshader blocks in the ASM files. In all, the StitchUp shader is about 17 instructions less.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This version includes conditionals as part of the fragment syntax; this is useful, and I hope to incorporate it into the official version of StitchUp.&lt;/p&gt;

&lt;h2&gt;Engine Nine&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://nine.codeplex.com/"&gt;Engine Nine&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I hadn&amp;#39;t heard of this engine before, but it looks promising [especially now that it includes StitchUp ;-)]. I&amp;#39;ve had a browse through the source code, and the StitchUp integration looks quite slick.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/j3_E9bAPjYE" height="1" width="1"/&gt;</description>
      <pubDate>Thu, 30 Dec 2010 11:40:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/j3_E9bAPjYE/stitchup-in-action</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2010/12/30/stitchup-in-action</feedburner:origLink></item>
    <item>
      <title>Drawing an XNA Model bounding box</title>
      <description>&lt;ul&gt;
&lt;li&gt;&lt;em&gt;The source code for a working version is &lt;a href="https://github.com/tgjones/xna-tutorials/tree/master/DrawBoundingBox"&gt;here&lt;/a&gt;.&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you&amp;#39;re making a level editor, or perhaps a &lt;a href="/blog/archive/2010/12/09/xbuilder-v-released"&gt;model viewer&lt;/a&gt;, it can sometimes be useful to see a visualisation of the 3D space a model sits within. It might also be handy if you use bounding boxes for physics, and you want to check that the bounding box is really where you think it is.&lt;/p&gt;

&lt;h2&gt;Creating the bounding box&lt;/h2&gt;

&lt;p&gt;First (and hopefully not surprisingly), you&amp;#39;ll need the bounding box itself. XNA has a nice structure for this, helpfully named &lt;code&gt;BoundingBox&lt;/code&gt;. If you already have access to one of these for your model, then you can skip to the next section. If you only have a &lt;code&gt;Model&lt;/code&gt; object, and want to creating a bounding box, then you can use this code. Note that the &lt;code&gt;ModelMesh&lt;/code&gt; class has a &lt;code&gt;BoundingSphere&lt;/code&gt; property. XNA allows us to create a &lt;code&gt;BoundingBox&lt;/code&gt; from a &lt;code&gt;BoundingSphere&lt;/code&gt;, but that wouldn&amp;#39;t be a tight fit - it would be larger than necessary. So I prefer to go back to the original vertices and use them to create the bounding box. Step 1, then, is to extract the vertex positions from the &lt;code&gt;Model&lt;/code&gt;:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;
&lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; &lt;span style="color:#088;font-weight:bold"&gt;static&lt;/span&gt; &lt;span style="color:#080;font-weight:bold"&gt;class&lt;/span&gt; &lt;span style="color:#B06;font-weight:bold"&gt;VertexElementExtractor&lt;/span&gt;
{
    &lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; &lt;span style="color:#088;font-weight:bold"&gt;static&lt;/span&gt; Vector3[] GetVertexElement(ModelMeshPart meshPart, VertexElementUsage usage)
    {
        VertexDeclaration vd = meshPart.VertexBuffer.VertexDeclaration;
        VertexElement[] elements = vd.GetVertexElements();

        Func&amp;lt;VertexElement, &lt;span style="color:#0a5;font-weight:bold"&gt;bool&lt;/span&gt;&amp;gt; elementPredicate = ve =&amp;gt; ve.VertexElementUsage == usage &amp;amp;&amp;amp; ve.VertexElementFormat == VertexElementFormat.Vector3;
        &lt;span style="color:#080;font-weight:bold"&gt;if&lt;/span&gt; (!elements.Any(elementPredicate))
            &lt;span style="color:#080;font-weight:bold"&gt;return&lt;/span&gt; null;

        VertexElement element = elements.First(elementPredicate);

        Vector3[] vertexData = &lt;span style="color:#080;font-weight:bold"&gt;new&lt;/span&gt; Vector3[meshPart.NumVertices];
        meshPart.VertexBuffer.GetData((meshPart.VertexOffset * vd.VertexStride) + element.Offset,
            vertexData, &lt;span style="color:#00D"&gt;0&lt;/span&gt;, vertexData.Length, vd.VertexStride);

        &lt;span style="color:#080;font-weight:bold"&gt;return&lt;/span&gt; vertexData;
    }
}
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;We can now write the code to create a bounding box for a &lt;code&gt;ModelMeshPart&lt;/code&gt;:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;
&lt;span style="color:#088;font-weight:bold"&gt;private&lt;/span&gt; &lt;span style="color:#088;font-weight:bold"&gt;static&lt;/span&gt; BoundingBox? GetBoundingBox(ModelMeshPart meshPart, Matrix transform)
{
    &lt;span style="color:#080;font-weight:bold"&gt;if&lt;/span&gt; (meshPart.VertexBuffer == null)
        &lt;span style="color:#080;font-weight:bold"&gt;return&lt;/span&gt; null;

    Vector3[] positions = VertexElementExtractor.GetVertexElement(meshPart, VertexElementUsage.Position);
    &lt;span style="color:#080;font-weight:bold"&gt;if&lt;/span&gt; (positions == null)
        &lt;span style="color:#080;font-weight:bold"&gt;return&lt;/span&gt; null;

    Vector3[] transformedPositions = &lt;span style="color:#080;font-weight:bold"&gt;new&lt;/span&gt; Vector3[positions.Length];
    Vector3.Transform(positions, ref transform, transformedPositions);

    &lt;span style="color:#080;font-weight:bold"&gt;return&lt;/span&gt; BoundingBox.CreateFromPoints(transformedPositions);
}
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Now we can loop through each &lt;code&gt;ModelMesh&lt;/code&gt; and &lt;code&gt;ModelMeshPart&lt;/code&gt; within the &lt;code&gt;Model&lt;/code&gt;, and create the merged bounding box for the whole model (making sure to transform the positions based on the bone transforms):&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;
&lt;span style="color:#088;font-weight:bold"&gt;private&lt;/span&gt; &lt;span style="color:#088;font-weight:bold"&gt;static&lt;/span&gt; BoundingBox CreateBoundingBox(Model model)
{
    Matrix[] boneTransforms = &lt;span style="color:#080;font-weight:bold"&gt;new&lt;/span&gt; Matrix[model.Bones.Count];
    model.CopyAbsoluteBoneTransformsTo(boneTransforms);

    BoundingBox result = &lt;span style="color:#080;font-weight:bold"&gt;new&lt;/span&gt; BoundingBox();
    foreach (ModelMesh mesh in model.Meshes)
        foreach (ModelMeshPart meshPart in mesh.MeshParts)
        {
            BoundingBox? meshPartBoundingBox = GetBoundingBox(meshPart, boneTransforms[mesh.ParentBone.Index]);
            &lt;span style="color:#080;font-weight:bold"&gt;if&lt;/span&gt; (meshPartBoundingBox != null)
                result = BoundingBox.CreateMerged(result, meshPartBoundingBox.Value);
        }
    &lt;span style="color:#080;font-weight:bold"&gt;return&lt;/span&gt; result;
}
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;In XBuilder, I actually create a bounding box for each &lt;code&gt;ModelMesh&lt;/code&gt;, but the general principle is the same.&lt;/p&gt;

&lt;p&gt;We now have a &lt;code&gt;BoundingBox&lt;/code&gt; for our &lt;code&gt;Model&lt;/code&gt;, so we can get ready to draw it.&lt;/p&gt;

&lt;h2&gt;Preparing to draw the bounding box&lt;/h2&gt;

&lt;p&gt;You could draw an actual box, with solid lines. I prefer the approach taken by most 3D modelling packages of just drawing the corners. This is a bit more involved, and sorry for the long code snippet. If anybody knows a cleverer way of doing this, please let me know! First we need a class to hold the vertex and index buffers we&amp;#39;re going to create:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;
&lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; &lt;span style="color:#080;font-weight:bold"&gt;class&lt;/span&gt; &lt;span style="color:#B06;font-weight:bold"&gt;BoundingBoxBuffers&lt;/span&gt;
{
    &lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; VertexBuffer Vertices;
    &lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; &lt;span style="color:#0a5;font-weight:bold"&gt;int&lt;/span&gt; VertexCount;
    &lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; IndexBuffer Indices;
    &lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; &lt;span style="color:#0a5;font-weight:bold"&gt;int&lt;/span&gt; PrimitiveCount;
}
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Now we can build this object:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;
&lt;span style="color:#088;font-weight:bold"&gt;private&lt;/span&gt; BoundingBoxBuffers CreateBoundingBoxBuffers(BoundingBox boundingBox, GraphicsDevice graphicsDevice)
{
    BoundingBoxBuffers boundingBoxBuffers = &lt;span style="color:#080;font-weight:bold"&gt;new&lt;/span&gt; BoundingBoxBuffers();

    boundingBoxBuffers.PrimitiveCount = &lt;span style="color:#00D"&gt;24&lt;/span&gt;;
    boundingBoxBuffers.VertexCount = &lt;span style="color:#00D"&gt;48&lt;/span&gt;;

    VertexBuffer vertexBuffer = &lt;span style="color:#080;font-weight:bold"&gt;new&lt;/span&gt; VertexBuffer(graphicsDevice,
        typeof(VertexPositionColor), boundingBoxBuffers.VertexCount,
        BufferUsage.WriteOnly);
    List&amp;lt;VertexPositionColor&amp;gt; vertices = &lt;span style="color:#080;font-weight:bold"&gt;new&lt;/span&gt; List&amp;lt;VertexPositionColor&amp;gt;();

    &lt;span style="color:#088;font-weight:bold"&gt;const&lt;/span&gt; &lt;span style="color:#0a5;font-weight:bold"&gt;float&lt;/span&gt; ratio = &lt;span style="color:#60E"&gt;5&lt;/span&gt;&lt;span style="color:#60E"&gt;.0f&lt;/span&gt;;

    Vector3 xOffset = &lt;span style="color:#080;font-weight:bold"&gt;new&lt;/span&gt; Vector3((boundingBox.Max.X - boundingBox.Min.X) / ratio, &lt;span style="color:#00D"&gt;0&lt;/span&gt;, &lt;span style="color:#00D"&gt;0&lt;/span&gt;);
    Vector3 yOffset = &lt;span style="color:#080;font-weight:bold"&gt;new&lt;/span&gt; Vector3(&lt;span style="color:#00D"&gt;0&lt;/span&gt;, (boundingBox.Max.Y - boundingBox.Min.Y) / ratio, &lt;span style="color:#00D"&gt;0&lt;/span&gt;);
    Vector3 zOffset = &lt;span style="color:#080;font-weight:bold"&gt;new&lt;/span&gt; Vector3(&lt;span style="color:#00D"&gt;0&lt;/span&gt;, &lt;span style="color:#00D"&gt;0&lt;/span&gt;, (boundingBox.Max.Z - boundingBox.Min.Z) / ratio);
    Vector3[] corners = boundingBox.GetCorners();

    &lt;span style="color:#777"&gt;// Corner 1.&lt;/span&gt;
    AddVertex(vertices, corners[&lt;span style="color:#00D"&gt;0&lt;/span&gt;]);
    AddVertex(vertices, corners[&lt;span style="color:#00D"&gt;0&lt;/span&gt;] + xOffset);
    AddVertex(vertices, corners[&lt;span style="color:#00D"&gt;0&lt;/span&gt;]);
    AddVertex(vertices, corners[&lt;span style="color:#00D"&gt;0&lt;/span&gt;] - yOffset);
    AddVertex(vertices, corners[&lt;span style="color:#00D"&gt;0&lt;/span&gt;]);
    AddVertex(vertices, corners[&lt;span style="color:#00D"&gt;0&lt;/span&gt;] - zOffset);

    &lt;span style="color:#777"&gt;// Corner 2.&lt;/span&gt;
    AddVertex(vertices, corners[&lt;span style="color:#00D"&gt;1&lt;/span&gt;]);
    AddVertex(vertices, corners[&lt;span style="color:#00D"&gt;1&lt;/span&gt;] - xOffset);
    AddVertex(vertices, corners[&lt;span style="color:#00D"&gt;1&lt;/span&gt;]);
    AddVertex(vertices, corners[&lt;span style="color:#00D"&gt;1&lt;/span&gt;] - yOffset);
    AddVertex(vertices, corners[&lt;span style="color:#00D"&gt;1&lt;/span&gt;]);
    AddVertex(vertices, corners[&lt;span style="color:#00D"&gt;1&lt;/span&gt;] - zOffset);

    &lt;span style="color:#777"&gt;// Corner 3.&lt;/span&gt;
    AddVertex(vertices, corners[&lt;span style="color:#00D"&gt;2&lt;/span&gt;]);
    AddVertex(vertices, corners[&lt;span style="color:#00D"&gt;2&lt;/span&gt;] - xOffset);
    AddVertex(vertices, corners[&lt;span style="color:#00D"&gt;2&lt;/span&gt;]);
    AddVertex(vertices, corners[&lt;span style="color:#00D"&gt;2&lt;/span&gt;] + yOffset);
    AddVertex(vertices, corners[&lt;span style="color:#00D"&gt;2&lt;/span&gt;]);
    AddVertex(vertices, corners[&lt;span style="color:#00D"&gt;2&lt;/span&gt;] - zOffset);

    &lt;span style="color:#777"&gt;// Corner 4.&lt;/span&gt;
    AddVertex(vertices, corners[&lt;span style="color:#00D"&gt;3&lt;/span&gt;]);
    AddVertex(vertices, corners[&lt;span style="color:#00D"&gt;3&lt;/span&gt;] + xOffset);
    AddVertex(vertices, corners[&lt;span style="color:#00D"&gt;3&lt;/span&gt;]);
    AddVertex(vertices, corners[&lt;span style="color:#00D"&gt;3&lt;/span&gt;] + yOffset);
    AddVertex(vertices, corners[&lt;span style="color:#00D"&gt;3&lt;/span&gt;]);
    AddVertex(vertices, corners[&lt;span style="color:#00D"&gt;3&lt;/span&gt;] - zOffset);

    &lt;span style="color:#777"&gt;// Corner 5.&lt;/span&gt;
    AddVertex(vertices, corners[&lt;span style="color:#00D"&gt;4&lt;/span&gt;]);
    AddVertex(vertices, corners[&lt;span style="color:#00D"&gt;4&lt;/span&gt;] + xOffset);
    AddVertex(vertices, corners[&lt;span style="color:#00D"&gt;4&lt;/span&gt;]);
    AddVertex(vertices, corners[&lt;span style="color:#00D"&gt;4&lt;/span&gt;] - yOffset);
    AddVertex(vertices, corners[&lt;span style="color:#00D"&gt;4&lt;/span&gt;]);
    AddVertex(vertices, corners[&lt;span style="color:#00D"&gt;4&lt;/span&gt;] + zOffset);

    &lt;span style="color:#777"&gt;// Corner 6.&lt;/span&gt;
    AddVertex(vertices, corners[&lt;span style="color:#00D"&gt;5&lt;/span&gt;]);
    AddVertex(vertices, corners[&lt;span style="color:#00D"&gt;5&lt;/span&gt;] - xOffset);
    AddVertex(vertices, corners[&lt;span style="color:#00D"&gt;5&lt;/span&gt;]);
    AddVertex(vertices, corners[&lt;span style="color:#00D"&gt;5&lt;/span&gt;] - yOffset);
    AddVertex(vertices, corners[&lt;span style="color:#00D"&gt;5&lt;/span&gt;]);
    AddVertex(vertices, corners[&lt;span style="color:#00D"&gt;5&lt;/span&gt;] + zOffset);

    &lt;span style="color:#777"&gt;// Corner 7.&lt;/span&gt;
    AddVertex(vertices, corners[&lt;span style="color:#00D"&gt;6&lt;/span&gt;]);
    AddVertex(vertices, corners[&lt;span style="color:#00D"&gt;6&lt;/span&gt;] - xOffset);
    AddVertex(vertices, corners[&lt;span style="color:#00D"&gt;6&lt;/span&gt;]);
    AddVertex(vertices, corners[&lt;span style="color:#00D"&gt;6&lt;/span&gt;] + yOffset);
    AddVertex(vertices, corners[&lt;span style="color:#00D"&gt;6&lt;/span&gt;]);
    AddVertex(vertices, corners[&lt;span style="color:#00D"&gt;6&lt;/span&gt;] + zOffset);

    &lt;span style="color:#777"&gt;// Corner 8.&lt;/span&gt;
    AddVertex(vertices, corners[&lt;span style="color:#00D"&gt;7&lt;/span&gt;]);
    AddVertex(vertices, corners[&lt;span style="color:#00D"&gt;7&lt;/span&gt;] + xOffset);
    AddVertex(vertices, corners[&lt;span style="color:#00D"&gt;7&lt;/span&gt;]);
    AddVertex(vertices, corners[&lt;span style="color:#00D"&gt;7&lt;/span&gt;] + yOffset);
    AddVertex(vertices, corners[&lt;span style="color:#00D"&gt;7&lt;/span&gt;]);
    AddVertex(vertices, corners[&lt;span style="color:#00D"&gt;7&lt;/span&gt;] + zOffset);

    vertexBuffer.SetData(vertices.ToArray());
    boundingBoxBuffers.Vertices = vertexBuffer;

    IndexBuffer indexBuffer = &lt;span style="color:#080;font-weight:bold"&gt;new&lt;/span&gt; IndexBuffer(graphicsDevice, IndexElementSize.SixteenBits, boundingBoxBuffers.VertexCount,
        BufferUsage.WriteOnly);
    indexBuffer.SetData(Enumerable.Range(&lt;span style="color:#00D"&gt;0&lt;/span&gt;, boundingBoxBuffers.VertexCount).Select(i =&amp;gt; (&lt;span style="color:#0a5;font-weight:bold"&gt;short&lt;/span&gt;)i).ToArray());
    boundingBoxBuffers.Indices = indexBuffer;

    &lt;span style="color:#080;font-weight:bold"&gt;return&lt;/span&gt; boundingBoxBuffers;
}

&lt;span style="color:#088;font-weight:bold"&gt;private&lt;/span&gt; &lt;span style="color:#088;font-weight:bold"&gt;static&lt;/span&gt; &lt;span style="color:#088;font-weight:bold"&gt;void&lt;/span&gt; AddVertex(List&amp;lt;VertexPositionColor&amp;gt; vertices, Vector3 position)
{
    vertices.Add(&lt;span style="color:#080;font-weight:bold"&gt;new&lt;/span&gt; VertexPositionColor(position, Color.White));
}
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2&gt;Drawing the bounding box&lt;/h2&gt;

&lt;p&gt;By now you should have an instance of &lt;code&gt;BoundingBoxBuffers&lt;/code&gt;. To get it on to the screen, you&amp;#39;ll need an &lt;code&gt;Effect&lt;/code&gt; - I keep it simple and use &lt;code&gt;BasicEffect&lt;/code&gt;:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;
BasicEffect lineEffect = &lt;span style="color:#080;font-weight:bold"&gt;new&lt;/span&gt; BasicEffect(graphicsDevice);
lineEffect.LightingEnabled = &lt;span style="color:#069"&gt;false&lt;/span&gt;;
lineEffect.TextureEnabled = &lt;span style="color:#069"&gt;false&lt;/span&gt;;
lineEffect.VertexColorEnabled = &lt;span style="color:#069"&gt;true&lt;/span&gt;;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Finally, we&amp;#39;re ready to draw the bounding box:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;
&lt;span style="color:#088;font-weight:bold"&gt;private&lt;/span&gt; &lt;span style="color:#088;font-weight:bold"&gt;void&lt;/span&gt; DrawBoundingBox(BoundingBoxBuffers buffers, BasicEffect effect, GraphicsDevice graphicsDevice, Matrix view, Matrix projection)
{
    graphicsDevice.SetVertexBuffer(buffers.Vertices);
    graphicsDevice.Indices = buffers.Indices;

    effect.World = Matrix.Identity;
    effect.View = view;
    effect.Projection = projection;

    foreach (EffectPass pass in effect.CurrentTechnique.Passes)
    {
        pass.Apply();
        graphicsDevice.DrawIndexedPrimitives(PrimitiveType.LineList, &lt;span style="color:#00D"&gt;0&lt;/span&gt;, &lt;span style="color:#00D"&gt;0&lt;/span&gt;,
            buffers.VertexCount, &lt;span style="color:#00D"&gt;0&lt;/span&gt;, buffers.PrimitiveCount);
    }
}
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;If everything went right, you should have something that looks like this on your screen:&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/blog/boundingbox.jpg" alt="image"/&gt;&lt;/p&gt;

&lt;p&gt;If you don&amp;#39;t have that, or if I didn&amp;#39;t explain it properly, maybe looking at &lt;a href="https://github.com/tgjones/xna-tutorials/tree/master/DrawBoundingBox"&gt;my version&lt;/a&gt; will help. I hope this is useful - let me know if you have any comments or questions.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/t_wmEhom0u4" height="1" width="1"/&gt;</description>
      <pubDate>Fri, 10 Dec 2010 08:46:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/t_wmEhom0u4/drawing-an-xna-model-bounding-box</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2010/12/10/drawing-an-xna-model-bounding-box</feedburner:origLink></item>
    <item>
      <title>XBuilder v0.2 released</title>
      <description>&lt;h2&gt;Cut to the chase...&lt;/h2&gt;

&lt;p&gt;XBuilder is an extension for Visual Studio 2010 which lets you preview your XNA assets (models, effects and textures) right inside Visual Studio. I have previously blogged about XBuilder &lt;a href="/blog/archive/2010/11/26/announcing-xbuilder-a-free--open-source-content"&gt;here&lt;/a&gt;, &lt;a href="/blog/archive/2010/12/01/xbuilder-updates---grid-rotation-indicator-mouse"&gt;here&lt;/a&gt; and &lt;a href="/blog/archive/2010/12/01/xbuilder-updates---show-normals"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I&amp;#39;ve finished work on XBuilder v0.2, and it&amp;#39;s available either using Visual Studio Extension Manager, or from the &lt;a href="http://visualstudiogallery.msdn.microsoft.com/en-us/30e6bc7d-4d92-49da-ac40-adab43fd94a1"&gt;Visual Studio Gallery&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;XBuilder is open source, and the code is available in the &lt;a href="https://github.com/formosatek/xbuilder"&gt;GitHub repository&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;What&amp;#39;s new since v0.1?&lt;/h2&gt;

&lt;p&gt;Quite a lot, as it turns out... I&amp;#39;ve blogged about some of these features before, but I&amp;#39;ll include everything here anyway because, well, it pads out my blog post.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Grid&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can customise the minor and major grid line spacing, as well as minor, major and axis grid colours.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rotation indicator&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Click and drag this to rotate the camera. This is quite helpful for keeping track of what direction you&amp;#39;re looking in.&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/blog/xbuilder8.jpg" alt="image"/&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mouse wheel zoom&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Pretty self-explanatory - when the content preview window has focus, use your mouse wheel to zoom in and out.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Preview effects.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Effect preview is little more than a working prototype at the moment. You can preview effects and choose which primitive (sphere, cube, cylinder, torus, plane and of course teapot) to use to render the effect. If your effect includes parameters with semantics named &lt;code&gt;WORLDVIEWPROJECTION&lt;/code&gt;, &lt;code&gt;WORLD&lt;/code&gt;, &lt;code&gt;VIEW&lt;/code&gt; or &lt;code&gt;PROJECTION&lt;/code&gt;, XBuilder will set the matrices for you. If you use a custom &lt;code&gt;EffectProcessor&lt;/code&gt; and your runtime effect class implements &lt;code&gt;IEffectMatrices&lt;/code&gt;, XBuilder will set the matrices. But that&amp;#39;s it - I need to implement DXSAS or something similar so that other parameters, such as lighting or material related parameters, can also be set.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Uses your importer and processor settings&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In v0.1, the importer was auto-detected by the XNA Content Pipeline and the processor was hard-coded, with no processor parameters. For v0.2, I&amp;#39;ve changed this to use whatever you have setup for in your content project. This was harder than I thought.&lt;/p&gt;

&lt;p&gt;At first it looked easy - each file in the content project exposes an interface called &lt;code&gt;IVSBuildPropertyStorage&lt;/code&gt;, which lets you access arbitrary MSBuild properties, such as &lt;code&gt;Importer&lt;/code&gt; and &lt;code&gt;Processor&lt;/code&gt;. However, you need to know the property name up-front - and for processor parameters, which have names like &lt;code&gt;ProcessorParameters_Scale&lt;/code&gt;, this is a problem. &lt;code&gt;IVsBuildPropertyStorage&lt;/code&gt; doesn&amp;#39;t offer any way of getting a list of available property names.&lt;/p&gt;

&lt;p&gt;My second attempt involved using the MSBuild API to open the content project file, find the relevant &lt;code&gt;ProjectItem&lt;/code&gt; and read its properties. This worked... but only the first time you do it. MSBuild does something weird with caching opened projects in a static variable somewhere, so you can&amp;#39;t open a project twice. I also tried opening the content project file as a standard XML file, but both of these approaches have the same root problem - even if they worked, they rely on you saving the content project file. If you&amp;#39;re just tweaking processor parameter values, you don&amp;#39;t want to save the project every time you want to update the preview.&lt;/p&gt;

&lt;p&gt;My third, and successful, attempt was a bit different - I used a similar technique to what XNA uses internally. However, I didn&amp;#39;t want to rely on reflection, as that&amp;#39;s messy, so I stuck with public interfaces and types only. The end result is that XBuilder is able to pick up your processor parameter changes immediately, without you needing to save anything. You can tweak your parameter value, hit the keyboard shortcut (see below) and the preview will update.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Bounding boxes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you select this option, a bounding box will be drawn for each mesh within your model.&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/blog/xbuilder10.jpg" alt="image"/&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Solid+Wireframe shading mode&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src="/assets/blog/xbuilder11.jpg" alt="image"/&gt;&lt;/p&gt;

&lt;p&gt;Again, self-explanatory - I&amp;#39;m using something similar to &lt;a href="http://www.catalinzima.com/samples/12-months-12-samples-2008/drawing-wireframes-without-z-fighting/"&gt;Catalin Zima&amp;#39;s technique for wireframe without z-fighting&lt;/a&gt;. You can configure the wireframe colour and z-bias values. Note that this shading mode will only work with models that use &lt;code&gt;BasicEffect&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Render normals&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src="/assets/blog/xbuilder12.jpg" alt="image"/&gt;&lt;/p&gt;

&lt;p&gt;Helpful for debugging - you can customise the length of the rendered normals as a proportion of the model bounding sphere radius.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Alpha blending&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If your model uses alpha blending, you&amp;#39;ll want to enable this option. XBuilder will render opaque mesh parts first, followed by transparent mesh parts. At the moment it doesn&amp;#39;t do any depth-sorting in the second pass.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Keyboard shortcut&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ctrl+Shift+Alt+F10 will open the content preview window.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;More configurable options&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src="/assets/blog/xbuilder9.jpg" alt="image"/&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Available from Visual Studio Extension Manager&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src="/assets/blog/xbuilder13.jpg" alt="image"/&gt;&lt;/p&gt;

&lt;p&gt;You can download and install XBuilder right within Visual Studio Extension Manager. When new versions are released, I&amp;#39;ll be adding them to the gallery, so this is the route I&amp;#39;d recommend for installing XBuilder.&lt;/p&gt;

&lt;h2&gt;What&amp;#39;s next?&lt;/h2&gt;

&lt;p&gt;I&amp;#39;m going to take a bit of a break, and perhaps actually work on a game project... when I come back to XBuilder, I am going to clean up the code (which got a bit messy while working on v0.2), and then work on the &lt;a href="https://github.com/formosatek/xbuilder/issues"&gt;features I&amp;#39;ve got planned for v0.3&lt;/a&gt;. It&amp;#39;s not too late to suggest features for v0.3 though - I&amp;#39;d really like this to become a community-driven project. (I know several people have asked for animation support - this is planned for v0.3.)&lt;/p&gt;

&lt;p&gt;This is really just a hobby project for me, so it lives or dies on your feedback - please let me know what you think, if it&amp;#39;s useful for you, what would make it useful for you, etc. If you find any bugs, please let me know &lt;a href="https://github.com/formosatek/xbuilder/issues"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/aeHfw7LYAFY" height="1" width="1"/&gt;</description>
      <pubDate>Thu, 09 Dec 2010 00:27:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/aeHfw7LYAFY/xbuilder-v-released</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2010/12/09/xbuilder-v-released</feedburner:origLink></item>
    <item>
      <title>Content Aware Image Resizing for ASP.NET</title>
      <description>&lt;p&gt;Content Aware Image Resizing (also known as &lt;a href="http://en.wikipedia.org/wiki/Seam_carving"&gt;seam carving&lt;/a&gt;) is an algorithm, developed by Shai Avidan, which resizes an image by removing &lt;em&gt;seams&lt;/em&gt; (paths of least importance) to reduce image size, or inserting seams to extend it. This is nice because it allows you to crop images without missing important details.&lt;/p&gt;

&lt;p&gt;I didn&amp;#39;t know about this technique until a friend pointed me in the direction of &lt;a href="http://sites.google.com/site/brainrecall/cair"&gt;CAIR&lt;/a&gt;, an open source implementation of seam carving. Never one to turn a blind eye to unnecessary but cool software, I have added a &lt;code&gt;ContentAwareResizeFilter&lt;/code&gt; to &lt;a href="https://github.com/tgjones/dynamic-image"&gt;my fork&lt;/a&gt; of &lt;a href="https://github.com/sitdap/dynamic-image"&gt;DynamicImage&lt;/a&gt; (DynamicImage is an open source image manipulation library for ASP.NET - there&amp;#39;s some &lt;a href="https://github.com/sitdap/dynamic-image/wiki"&gt;getting started documentation here&lt;/a&gt;). &lt;code&gt;ContentAwareResizeFilter&lt;/code&gt; simply calls the CAIR executable, so the credit for all the hard work goes to &lt;a href="http://sites.google.com/site/brainrecall"&gt;Brain Recall&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;An example might make things clearer. Here is the original image:&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/blog/dynamicimagecair1.jpg" alt="image"/&gt;&lt;/p&gt;

&lt;p&gt;Here is the image reduced in width using scaling:&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/blog/dynamicimagecair2.jpg" alt="image"/&gt;&lt;/p&gt;

&lt;p&gt;And here is the image reduced in width using content aware image resizing:&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/blog/dynamicimagecair3.jpg" alt="image"/&gt;&lt;/p&gt;

&lt;p&gt;The DynamicImage markup for the final image above is:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;
&lt;span style="color:#070"&gt;&amp;lt;sitdap:DynamicImage&lt;/span&gt; &lt;span style="color:#b48"&gt;runat&lt;/span&gt;=&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;server&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#070"&gt;&amp;gt;&lt;/span&gt;
    &lt;span style="color:#070"&gt;&amp;lt;Layers&amp;gt;&lt;/span&gt;
        &lt;span style="color:#070"&gt;&amp;lt;sitdap:ImageLayer&lt;/span&gt; &lt;span style="color:#b48"&gt;SourceFileName&lt;/span&gt;=&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;~/Assets/Images/sunset.jpg&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#070"&gt;&amp;gt;&lt;/span&gt;
            &lt;span style="color:#070"&gt;&amp;lt;Filters&amp;gt;&lt;/span&gt;
                &lt;span style="color:#070"&gt;&amp;lt;sitdap:ContentAwareResizeFilter&lt;/span&gt; &lt;span style="color:#b48"&gt;Width&lt;/span&gt;=&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;350&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span style="color:#b48"&gt;ConvolutionType&lt;/span&gt;=&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;V1&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span style="color:#070"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span style="color:#070"&gt;&amp;lt;/Filters&amp;gt;&lt;/span&gt;
        &lt;span style="color:#070"&gt;&amp;lt;/sitdap:ImageLayer&amp;gt;&lt;/span&gt;
    &lt;span style="color:#070"&gt;&amp;lt;/Layers&amp;gt;&lt;/span&gt;
&lt;span style="color:#070"&gt;&amp;lt;/sitdap:DynamicImage&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;If you don&amp;#39;t use web forms, you can use the fluent interface in code:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;
&lt;span style="color:#0a5;font-weight:bold"&gt;string&lt;/span&gt; imageUrl = &lt;span style="color:#080;font-weight:bold"&gt;new&lt;/span&gt; DynamicImageBuilder()
    .WithLayer(
        LayerBuilder.Image.SourceFile(&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;~/Assets/Images/sunset.jpg&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)
        .WithFilter(FilterBuilder.ContentAwareResize.ToWidth(&lt;span style="color:#00D"&gt;350&lt;/span&gt;))
    ).Url;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Here&amp;#39;s another example (you might recognise &lt;a href="http://commons.wikimedia.org/wiki/File:Broadway_tower_edit.jpg"&gt;this one&lt;/a&gt; from the &lt;a href="http://en.wikipedia.org/wiki/Seam_carving"&gt;Wikipedia article&lt;/a&gt;, but the images below are created using DynamicImage). The original image:&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/blog/dynamicimagecair4.jpg" alt="image"/&gt;&lt;/p&gt;

&lt;p&gt;Reduced in width using scaling:&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/blog/dynamicimagecair5.jpg" alt="image"/&gt;&lt;/p&gt;

&lt;p&gt;Reduced in width using content aware image resizing:&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/blog/dynamicimagecair6.jpg" alt="image"/&gt;&lt;/p&gt;

&lt;p&gt;In some situations, I think this effect is potentially very useful.&lt;/p&gt;

&lt;p&gt;If image manipulation in ASP.NET interests you, you might be interested in my previous posts on &lt;a href="/blog/archive/2010/11/04/creating-thumbnails-of-a-pdf-in-aspnet"&gt;creating PDF thumbnails&lt;/a&gt; and &lt;a href="/blog/archive/2010/11/04/creating-website-thumbnail-images-in-aspnet"&gt;creating website thumbnails&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/HRzg3y6zwwM" height="1" width="1"/&gt;</description>
      <pubDate>Fri, 03 Dec 2010 01:25:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/HRzg3y6zwwM/content-aware-image-resizing-for-aspnet</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2010/12/03/content-aware-image-resizing-for-aspnet</feedburner:origLink></item>
    <item>
      <title>XBuilder updates - Show normals</title>
      <description>&lt;p&gt;Just a little update today - I&amp;#39;ve added the ability to show normals for debugging purposes (or a low-tech &lt;a href="http://www.sgtconker.com/2009/10/article-fur-rendering/"&gt;fur rendering&lt;/a&gt; technique?). The colour of the normals is based on their direction, and the length is configurable.&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/blog/xbuilder7.jpg" alt="image"/&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/CkURAc22CSQ" height="1" width="1"/&gt;</description>
      <pubDate>Wed, 01 Dec 2010 19:31:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/CkURAc22CSQ/xbuilder-updates---show-normals</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2010/12/01/xbuilder-updates---show-normals</feedburner:origLink></item>
    <item>
      <title>Extracting the normals from a Model at runtime</title>
      <description>&lt;p&gt;In case this is useful to somebody: the following code will extract the normals from a &lt;code&gt;ModelMeshPart&lt;/code&gt; at runtime. Usually this is best done with a custom &lt;code&gt;ModelProcessor&lt;/code&gt;, but that&amp;#39;s not always possible.&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;
&lt;span style="color:#088;font-weight:bold"&gt;private&lt;/span&gt; &lt;span style="color:#088;font-weight:bold"&gt;static&lt;/span&gt; Vector3[] GetNormals(ModelMeshPart meshPart)
{
    &lt;span style="color:#080;font-weight:bold"&gt;if&lt;/span&gt; (meshPart.VertexBuffer == null)
        &lt;span style="color:#080;font-weight:bold"&gt;return&lt;/span&gt; null;

    VertexBuffer vb = meshPart.VertexBuffer;
    &lt;span style="color:#080;font-weight:bold"&gt;if&lt;/span&gt; (meshPart.VertexBuffer.Tag != null) &lt;span style="color:#777"&gt;// Vertex buffers can be, and usually are, shared between ModelMeshPart's.&lt;/span&gt;
        &lt;span style="color:#080;font-weight:bold"&gt;return&lt;/span&gt; (Vector3[]) meshPart.VertexBuffer.Tag;

    VertexDeclaration vd = vb.VertexDeclaration;
    VertexElement[] elements = vd.GetVertexElements();

    Func&amp;lt;VertexElement,&lt;span style="color:#0a5;font-weight:bold"&gt;bool&lt;/span&gt;&amp;gt; normalElementPredicate = ve =&amp;gt; ve.VertexElementUsage == VertexElementUsage.Normal &amp;amp;&amp;amp; ve.VertexElementFormat == VertexElementFormat.Vector3;
    &lt;span style="color:#080;font-weight:bold"&gt;if&lt;/span&gt; (!elements.Any(normalElementPredicate))
        &lt;span style="color:#080;font-weight:bold"&gt;return&lt;/span&gt; null;

    VertexElement normalElement = elements.First(normalElementPredicate);

    Vector3[] normals = &lt;span style="color:#080;font-weight:bold"&gt;new&lt;/span&gt; Vector3[vb.VertexCount];
    vb.GetData(normalElement.Offset, normals, &lt;span style="color:#00D"&gt;0&lt;/span&gt;, vb.VertexCount, vd.VertexStride);

    &lt;span style="color:#080;font-weight:bold"&gt;return&lt;/span&gt; normals;
}
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;In fact, I&amp;#39;m not going to use this code, because I think I&amp;#39;ve found a way to use a custom &lt;code&gt;ModelProcessor&lt;/code&gt; for my scenario, but perhaps it will be of use to somebody else.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/h8VGYZPsUlA" height="1" width="1"/&gt;</description>
      <pubDate>Wed, 01 Dec 2010 16:59:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/h8VGYZPsUlA/extracting-the-normals-from-a-model-at-runtime</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2010/12/01/extracting-the-normals-from-a-model-at-runtime</feedburner:origLink></item>
    <item>
      <title>XBuilder updates - Grid, rotation indicator, mouse wheel zoom</title>
      <description>&lt;p&gt;I did a little more work tonight on &lt;a href="https://github.com/formosatek/xbuilder"&gt;XBuilder&lt;/a&gt;. The next release will be v0.2, which is not yet ready (&lt;a href="https://github.com/formosatek/xbuilder/issues"&gt;here&lt;/a&gt; are some of the items I&amp;#39;m working on for v0.2, although I retain the right to add &amp;#47; remove from that list). However, I thought I&amp;#39;d share a video to hopefully whet your appetite for what&amp;#39;s coming. This is all checked in to the &lt;a href="https://github.com/formosatek/xbuilder"&gt;repo&lt;/a&gt;, so if you want to live dangerously (and have the Visual Studio SDK installed), then feel free to grab the latest code and have a go.&lt;/p&gt;

&lt;p&gt;The highlights are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;The preview window now shows a grid.&lt;/em&gt; This should help you keep track of where you are. The major, minor, and axis line colours are all customisable.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;You can zoom with the mouse wheel.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;You can rotate the camera using the cube in the top-right corner.&lt;/em&gt; This is, err, inspired by a certain major 3D editing package, and I&amp;#39;m hoping it&amp;#39;s okay for me to borrow the idea. If anybody thinks differently, please let me know.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Previously you could rotate only the object, not the camera. Right now you can only rotate the camera. I hope to add object rotation back in, but I&amp;#39;ll wait till I have time to implement it properly.&lt;/p&gt;

&lt;p&gt;&lt;object width="640" height="470"&gt;&lt;param name="movie" value="http://www.youtube.com/v/9fQnh88hKsM?fs=1&amp;amp;hl=en_US"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/9fQnh88hKsM?fs=1&amp;amp;hl=en_US" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="470"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/yU5EZe6opOg" height="1" width="1"/&gt;</description>
      <pubDate>Wed, 01 Dec 2010 02:59:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/yU5EZe6opOg/xbuilder-updates---grid-rotation-indicator-mouse</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2010/12/01/xbuilder-updates---grid-rotation-indicator-mouse</feedburner:origLink></item>
    <item>
      <title>StitchUp - Support for multiple techniques</title>
      <description>&lt;p&gt;I have just &lt;a href="https://github.com/tgjones/stitchup/commit/7351c20496c6db2007ac42b178212ac9d83d0b7e"&gt;pushed some code&lt;/a&gt; and &lt;a href="https://github.com/tgjones/stitchup/downloads"&gt;added a new download&lt;/a&gt; to &lt;a href="https://github.com/tgjones/stitchup"&gt;StitchUp&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This new version adds support for multiple techniques inside &lt;code&gt;.stitchedeffect&lt;/code&gt; files. In case this is your first time reading about StitchUp, then a better place to start is &lt;a href="/blog/archive/2010/11/13/introducing-stitchup-generating-shaders-from-hlsl-shader-fragments"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This change involved quite a lot of refactoring, because it affects almost every part of the code generation process. The end result is that you can have multiple techniques that share some of the same fragments. The parameters and textures for those fragments will be declared only once, but the generated vertex and pixel shaders will be unique to each technique (or rather, to each pass, since you can have multiple passes inside each technique).&lt;/p&gt;

&lt;p&gt;Because having multiple techniques in an effect will not be used by everybody, I didn&amp;#39;t want to penalise those who don&amp;#39;t need them by complicating the &lt;code&gt;.stitchedeffect&lt;/code&gt; format. So I have left the original format intact, which means you can still declare your &lt;code&gt;.stitchedeffect&lt;/code&gt; like this:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;
Fragments&lt;span style="color:#F00;background-color:#FAA"&gt;\&lt;/span&gt;VertexTypes&lt;span style="color:#F00;background-color:#FAA"&gt;\&lt;/span&gt;PositionNormalTexture.fragment
Fragments&lt;span style="color:#F00;background-color:#FAA"&gt;\&lt;/span&gt;VertexTypes&lt;span style="color:#F00;background-color:#FAA"&gt;\&lt;/span&gt;VertexPassThru.fragment
Fragments&lt;span style="color:#F00;background-color:#FAA"&gt;\&lt;/span&gt;BasicMaterial.fragment
Fragments&lt;span style="color:#F00;background-color:#FAA"&gt;\&lt;/span&gt;Lights&lt;span style="color:#F00;background-color:#FAA"&gt;\&lt;/span&gt;DirectionalLight.fragment
Fragments&lt;span style="color:#F00;background-color:#FAA"&gt;\&lt;/span&gt;LightingModels&lt;span style="color:#F00;background-color:#FAA"&gt;\&lt;/span&gt;Phong.fragment
Fragments&lt;span style="color:#F00;background-color:#FAA"&gt;\&lt;/span&gt;PixelColorOutput.fragment
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;If however, you want to use multiple techniques, you can use the new format (with the same file extension of &lt;code&gt;.stitchedeffect&lt;/code&gt;):&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;
stitchedeffect basic_effect;

[fragments]
fragment pnt = &lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;Fragments&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#F00;background-color:#FAA"&gt;\&lt;/span&gt;VertexTypes&lt;span style="color:#F00;background-color:#FAA"&gt;\&lt;/span&gt;PositionNormalTexture.fragment&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;;
fragment vpt = &lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;Fragments&lt;span style="color:#F00;background-color:#FAA"&gt;\&lt;/span&gt;VertexTypes&lt;span style="color:#F00;background-color:#FAA"&gt;\&lt;/span&gt;VertexPassThru.fragment&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;;
fragment bm = &lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;Fragments&lt;span style="color:#F00;background-color:#FAA"&gt;\&lt;/span&gt;BasicMaterial.fragment&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;;
fragment dl = &lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;Fragments&lt;span style="color:#F00;background-color:#FAA"&gt;\&lt;/span&gt;Lights&lt;span style="color:#F00;background-color:#FAA"&gt;\&lt;/span&gt;DirectionalLight.fragment&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;;
fragment ph = &lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;Fragments&lt;span style="color:#F00;background-color:#FAA"&gt;\&lt;/span&gt;LightingModels&lt;span style="color:#F00;background-color:#FAA"&gt;\&lt;/span&gt;Phong.fragment&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;;
fragment pco = &lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;Fragments&lt;span style="color:#F00;background-color:#FAA"&gt;\&lt;/span&gt;PixelColorOutput.fragment&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;;

[techniques]
technique t1
{
    pass p1
    {
        fragments = [pnt, vpt, bm, dl, ph, pco];
    }
}

technique t2
{
    pass p1
    {
        fragments =
        [
            pnt, vpt, bm, dl, ph,
            &lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;Fragments&lt;span style="color:#F00;background-color:#FAA"&gt;\&lt;/span&gt;AlternatePixelColorOutput.fragment&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;
        ];
    }
}
&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;As you&amp;#39;ll notice, you can mix and match &amp;quot;declared&amp;quot; fragments with inline strings. But there is a difference between the two.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If you declare a fragment (in the &lt;code&gt;[fragments]&lt;/code&gt; block), then the StitchUp compiler will only generate parameter and texture declarations for that fragment once, regardless of how many times you reference that fragment in technique passes.&lt;/li&gt;
&lt;li&gt;If you use a string literal inside a &lt;code&gt;pass&lt;/code&gt;, such as in the second technique above, the StitchUp compiler will assume that fragment is unique to that pass, and generate unique parameter and texture declarations for it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I have updated the demo project to include a few examples of different &lt;code&gt;.stitchedeffect&lt;/code&gt; files.&lt;/p&gt;

&lt;p&gt;I hope some of you find this a useful addition. Let me know what you think - and as always, if you find a bug, please &lt;a href="https://github.com/tgjones/stitchup/issues"&gt;let me know&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/3X2xUKHimMA" height="1" width="1"/&gt;</description>
      <pubDate>Sun, 28 Nov 2010 01:49:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/3X2xUKHimMA/stitchup---support-for-multiple-techniques</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2010/11/28/stitchup---support-for-multiple-techniques</feedburner:origLink></item>
    <item>
      <title>Announcing XBuilder, a free &amp; open source content viewer for XNA 4.0 integrated with Visual Studio 2010</title>
      <description>&lt;p&gt;Following &lt;a href="/blog/archive/2010/11/20/xna-model-viewer-inside-visual-studio"&gt;two&lt;/a&gt; &lt;a href="/blog/archive/2010/11/23/a-sneak-preview-of-xna-inspector"&gt;changes of name&lt;/a&gt;, I am now calling this project &lt;a href="https://github.com/formosatek/xbuilder"&gt;XBuilder&lt;/a&gt;. Why the change(s) of name? Well, I remembered the XNA Magic &amp;#47; Blade3D name change, and I didn&amp;#39;t want to get into any legal trouble, especially since this is a non-money-making piece of software.&lt;/p&gt;

&lt;p&gt;It&amp;#39;s rather a grandiose name for something that boils down to a single tool window - but I have plans for a v0.2...&lt;/p&gt;

&lt;h2&gt;The &lt;a href="http://en.wikipedia.org/wiki/Wikipedia:Too_long;_didn%27t_read"&gt;TL;DR&lt;/a&gt; version&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/formosatek/xbuilder"&gt;XBuilder&lt;/a&gt; is a Visual Studio 2010 extension which helps with XNA 4.0 development.&lt;/li&gt;
&lt;li&gt;XBuilder provides a &amp;quot;Content Preview&amp;quot; window, which can render your models and textures.&lt;/li&gt;
&lt;li&gt;In the Content Preview window, you can rotate your models, and set solid &amp;#47; wireframe fill mode.&lt;/li&gt;
&lt;li&gt;XBuilder uses whatever content importers and processors you have referenced from your content project. So if it builds in your content project, it should work with XBuilder.&lt;/li&gt;
&lt;li&gt;The source code is &lt;a href="https://github.com/formosatek/xbuilder"&gt;available on github&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;I have released v0.1, which you can &lt;a href="https://github.com/formosatek/xbuilder/downloads"&gt;download here&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;To install just double-click the .vsix file, and it should install into Visual Studio.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I plan to make it available online through Extension Manager, but I&amp;#39;d rather get some feedback first and make sure it&amp;#39;s stable before I do that.&lt;/p&gt;

&lt;h2&gt;Screenshots&lt;/h2&gt;

&lt;p&gt;Everybody likes screenshots, so here&amp;#39;s a few.&lt;/p&gt;

&lt;p&gt;There are two ways to open the Content Preview window. The first is the traditional View &amp;#47; Other Windows &amp;#47; Content Preview menu item:&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/blog/xbuilder1.jpg" alt="image"/&gt;&lt;/p&gt;

&lt;p&gt;The second is a context menu item on supported file formats (more on that later):&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/blog/xbuilder2.jpg" alt="image"/&gt;&lt;/p&gt;

&lt;p&gt;After clicking Preview on a model, the model will load:&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/blog/xbuilder3.jpg" alt="image"/&gt;&lt;/p&gt;

&lt;p&gt;You can change it to wireframe:&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/blog/xbuilder4.jpg" alt="image"/&gt;&lt;/p&gt;

&lt;p&gt;You can rotate it by dragging your mouse inside the window (on second thoughts you don&amp;#39;t need a screenshot of that).&lt;/p&gt;

&lt;p&gt;If the content importer or processor throws an error for any reason, it will appear in the Output window:&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/blog/xbuilder5.jpg" alt="image"/&gt;&lt;/p&gt;

&lt;p&gt;Finally, it comes with an options page, which lets you configure the file extensions you want to activate the &amp;quot;Preview&amp;quot; context menu for. At the moment, XBuilder is not able to work out which files can be processed with the XNA Content Pipeline, so you need to tell it here. By default it will support the file types that XNA supports, but if you have your own importers you can include those file types here.&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/blog/xbuilder6.jpg" alt="image"/&gt;&lt;/p&gt;

&lt;h2&gt;System requirements&lt;/h2&gt;

&lt;p&gt;Unfortunately 3rd party Visual Studio extensions don&amp;#39;t work with Visual Studio Express editions. So you&amp;#39;ll need a full-blown edition of Visual Studio (I&amp;#39;m actually not sure if Standard will work - perhaps somebody who has Standard can let me know).&lt;/p&gt;

&lt;p&gt;You&amp;#39;ll need XNA 4.0 installed.&lt;/p&gt;

&lt;h2&gt;The future&lt;/h2&gt;

&lt;p&gt;There&amp;#39;s a lot that could be done with this - and I have specific plans for a v0.2. Whether I actually build v0.2 depends very much on the response to this first release - I&amp;#39;m quite curious whether this tool will be useful for other people. If not, at least I had fun building it!&lt;/p&gt;

&lt;p&gt;I learnt quite a bit about Visual Studio extensibility while building XBuilder, so if there&amp;#39;s any interest, I could write a blog post or two about my experiences and the stumbling blocks I hit.&lt;/p&gt;

&lt;p&gt;So, go &lt;a href="https://github.com/formosatek/xbuilder/downloads"&gt;download&lt;/a&gt; it, have a play, and let me know what you think by leaving a comment. Actual bugs would be better on the &lt;a href="https://github.com/formosatek/xbuilder/issues"&gt;issues page&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/YH66uPgiI2U" height="1" width="1"/&gt;</description>
      <pubDate>Fri, 26 Nov 2010 03:35:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/YH66uPgiI2U/announcing-xbuilder-a-free--open-source-content</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2010/11/26/announcing-xbuilder-a-free--open-source-content</feedburner:origLink></item>
    <item>
      <title>A sneak preview of "XNA Inspector"</title>
      <description>&lt;p&gt;This is the same project I &lt;a href="/blog/archive/2010/11/20/xna-model-viewer-inside-visual-studio"&gt;mentioned in my last post&lt;/a&gt;. It&amp;#39;s quite fun to work on so I&amp;#39;ve done a little bit more to it since then.&lt;/p&gt;

&lt;p&gt;I&amp;#39;m going to call it &amp;quot;XNA Inspector&amp;quot;, since it was partially inspired by the inspector panel in Unity3D. It&amp;#39;s a Visual Studio 2010 extension which allows models and textures (and shortly effects) from XNA Content Projects to be previewed in a tool window. It&amp;#39;s very much in development, but when it&amp;#39;s finished it will be open source, and available through Visual Studio Extension Manager.&lt;/p&gt;

&lt;p&gt;Here&amp;#39;s a sneak peek of it in action:&lt;/p&gt;

&lt;p&gt;&lt;object width="640" height="470"&gt;&lt;param name="movie" value="http://www.youtube.com/v/73KdeBpS57I?fs=1&amp;amp;hl=en_US"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/73KdeBpS57I?fs=1&amp;amp;hl=en_US" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="470"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/p&gt;

&lt;p&gt;I&amp;#39;m not sure when it will be finished - not for a couple of weeks at least, but I&amp;#39;ll post updates here as I go.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/gST6yERDV9c" height="1" width="1"/&gt;</description>
      <pubDate>Tue, 23 Nov 2010 03:21:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/gST6yERDV9c/a-sneak-preview-of-xna-inspector</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2010/11/23/a-sneak-preview-of-xna-inspector</feedburner:origLink></item>
    <item>
      <title>XNA Model Viewer inside Visual Studio 2010</title>
      <description>&lt;p&gt;This is a work-in-progress - I just had the idea this morning to embed an XNA model viewer in a Visual Studio tool window. I had previously been working on a standalone model viewer, but then I thought, why recreate some of Visual Studio when you can use the real thing?&lt;/p&gt;

&lt;p&gt;The current entry point is to right-click on a model file in a Content project, and click a &amp;quot;View Model&amp;quot; context menu item, but this could be changed so that if the model viewer tool window is open, it will update whenever you select a new model file.&lt;/p&gt;

&lt;p&gt;Right now it only loads the model, but I could add some more tools to change the effect, change effect parameters, etc.&lt;/p&gt;

&lt;p&gt;Click the image for a larger version.&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/blog/modelviewer1small.jpg" alt="image"/&gt;:&amp;#47;assets&amp;#47;images&amp;#47;blog&amp;#47;modelviewer1.jpg&lt;/p&gt;

&lt;p&gt;What do you think? It&amp;#39;s actually surprisingly easy to write a tool window for Visual Studio - so (armed with the Windows Forms samples from App Hub) this whole thing only took an hour. I like projects like that...&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/lNOsWlsrZ3U" height="1" width="1"/&gt;</description>
      <pubDate>Sat, 20 Nov 2010 14:47:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/lNOsWlsrZ3U/xna-model-viewer-inside-visual-studio</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2010/11/20/xna-model-viewer-inside-visual-studio</feedburner:origLink></item>
    <item>
      <title>3DS, OBJ, and NFF content importers for XNA 4.0</title>
      <description>&lt;p&gt;Continuing my recent hobby of &lt;a href="/blog/archive/2010/11/13/introducing-stitchup-generating-shaders-from-hlsl-shader-fragments"&gt;digging up old projects&lt;/a&gt; and &lt;a href="/blog/archive/2010/11/16/an-xna--content-pipeline-processor-for-terrain"&gt;releasing them&lt;/a&gt;, I want to mention a couple of content importers that I have been working on.&lt;/p&gt;

&lt;p&gt;I&amp;#39;d like to preface this by saying that I&amp;#39;ve acted as an aggregator; most of this code was ported from somebody else&amp;#39;s work, as I have acknowledged below. If there are any bugs, they are almost certainly my fault, and if you find one please &lt;a href="https://github.com/tgjones/osiris/issues"&gt;log an issue&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So the 3 content importers I&amp;#39;ve added to &lt;a href="https://github.com/tgjones/osiris"&gt;Osiris&lt;/a&gt; (my catch-all project for XNA content pipeline extensions, including the &lt;a href="/blog/archive/2010/11/16/an-xna--content-pipeline-processor-for-terrain"&gt;terrain geomipmapping processor&lt;/a&gt;) are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;3DS&lt;/em&gt; - Lots of free 3D models on the web are in this format. My code was ported from &lt;a href="http://www.pixelnerve.com/processing/libraries/mri3ds/"&gt;MRI3DS&lt;/a&gt;, a Java 3DS importer.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;OBJ&lt;/em&gt; - Again, this is a common format. My code was ported from &lt;a href="http://www.pixelnerve.com/processing/libraries/objimport/"&gt;OBJ_IMPORT&lt;/a&gt;, a Java OBJ importer. I&amp;#39;m aware that there is an &lt;a href="http://create.msdn.com/en-us/education/catalog/sample/custom_model_importer"&gt;OBJ importer on App Hub&lt;/a&gt;, that may well be better than this one - the more choice the better, right?&lt;/li&gt;
&lt;li&gt;&lt;em&gt;NFF&lt;/em&gt; - Actually, it&amp;#39;s generous to call this an &lt;a href="http://tog.acm.org/resources/SPD/NFF.TXT"&gt;NFF&lt;/a&gt; importer. All I really wanted was a simple file format to create primitives, and NFF was the closest I could find. I have implemented a tiny amount of the specification, and then bolted on my own additions. Have a look in the &lt;a href="https://github.com/tgjones/osiris/tree/master/src/ModelsDemo/ModelsDemoContent/Primitives/"&gt;ModelsDemo content project&lt;/a&gt; for some examples. Just because it will break up the monotony of this post, I&amp;#39;ll include one of the NFF files here:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;
&lt;span style="color:#579"&gt;# A&lt;/span&gt; material
f &lt;span style="color:#60E"&gt;0&lt;/span&gt;&lt;span style="color:#60E"&gt;.3&lt;/span&gt; &lt;span style="color:#60E"&gt;0&lt;/span&gt;&lt;span style="color:#60E"&gt;.3&lt;/span&gt; &lt;span style="color:#60E"&gt;0&lt;/span&gt;&lt;span style="color:#60E"&gt;.3&lt;/span&gt; &lt;span style="color:#60E"&gt;0&lt;/span&gt;&lt;span style="color:#60E"&gt;.8&lt;/span&gt; &lt;span style="color:#60E"&gt;0&lt;/span&gt;&lt;span style="color:#60E"&gt;.2&lt;/span&gt; &lt;span style="color:#00D"&gt;16&lt;/span&gt; &lt;span style="color:#00D"&gt;0&lt;/span&gt;

&lt;span style="color:#579"&gt;# A&lt;/span&gt; plane at &lt;span style="color:#00D"&gt;0&lt;/span&gt; &lt;span style="color:#00D"&gt;0&lt;/span&gt; &lt;span style="color:#00D"&gt;0&lt;/span&gt; with a &lt;span style="color:#D20"&gt;'w&lt;/span&gt;idth&lt;span style="color:#D20"&gt;' &lt;/span&gt;of &lt;span style="color:#00D"&gt;50&lt;/span&gt; &lt;span style="color:#080;font-weight:bold"&gt;and&lt;/span&gt; &lt;span style="color:#D20"&gt;'h&lt;/span&gt;eight&lt;span style="color:#D20"&gt;' &lt;/span&gt;of &lt;span style="color:#00D"&gt;40&lt;/span&gt;
x-plane &lt;span style="color:#00D"&gt;0&lt;/span&gt; &lt;span style="color:#00D"&gt;0&lt;/span&gt; &lt;span style="color:#00D"&gt;0&lt;/span&gt; &lt;span style="color:#00D"&gt;50&lt;/span&gt; &lt;span style="color:#00D"&gt;40&lt;/span&gt;

&lt;span style="color:#579"&gt;# A&lt;/span&gt; red material
f &lt;span style="color:#60E"&gt;0&lt;/span&gt;&lt;span style="color:#60E"&gt;.8&lt;/span&gt; &lt;span style="color:#60E"&gt;0&lt;/span&gt;&lt;span style="color:#60E"&gt;.1&lt;/span&gt; &lt;span style="color:#60E"&gt;0&lt;/span&gt;&lt;span style="color:#60E"&gt;.1&lt;/span&gt; &lt;span style="color:#60E"&gt;0&lt;/span&gt;&lt;span style="color:#60E"&gt;.8&lt;/span&gt; &lt;span style="color:#60E"&gt;0&lt;/span&gt;&lt;span style="color:#60E"&gt;.2&lt;/span&gt; &lt;span style="color:#00D"&gt;16&lt;/span&gt; &lt;span style="color:#00D"&gt;0&lt;/span&gt;

&lt;span style="color:#579"&gt;# A&lt;/span&gt; cube at -&lt;span style="color:#00D"&gt;50&lt;/span&gt; &lt;span style="color:#00D"&gt;0&lt;/span&gt; &lt;span style="color:#00D"&gt;0&lt;/span&gt; with a &lt;span style="color:#D20"&gt;'s&lt;/span&gt;ize&lt;span style="color:#D20"&gt;' &lt;/span&gt;of &lt;span style="color:#00D"&gt;50&lt;/span&gt;
x-cube -&lt;span style="color:#00D"&gt;50&lt;/span&gt; &lt;span style="color:#00D"&gt;0&lt;/span&gt; &lt;span style="color:#00D"&gt;0&lt;/span&gt; &lt;span style="color:#00D"&gt;50&lt;/span&gt;

&lt;span style="color:#579"&gt;# A&lt;/span&gt; green material
f &lt;span style="color:#60E"&gt;0&lt;/span&gt;&lt;span style="color:#60E"&gt;.1&lt;/span&gt; &lt;span style="color:#60E"&gt;0&lt;/span&gt;&lt;span style="color:#60E"&gt;.8&lt;/span&gt; &lt;span style="color:#60E"&gt;0&lt;/span&gt;&lt;span style="color:#60E"&gt;.1&lt;/span&gt; &lt;span style="color:#60E"&gt;0&lt;/span&gt;&lt;span style="color:#60E"&gt;.8&lt;/span&gt; &lt;span style="color:#60E"&gt;0&lt;/span&gt;&lt;span style="color:#60E"&gt;.2&lt;/span&gt; &lt;span style="color:#00D"&gt;16&lt;/span&gt; &lt;span style="color:#00D"&gt;0&lt;/span&gt;

&lt;span style="color:#579"&gt;# A&lt;/span&gt; teapot at &lt;span style="color:#00D"&gt;50&lt;/span&gt; &lt;span style="color:#00D"&gt;0&lt;/span&gt; &lt;span style="color:#00D"&gt;0&lt;/span&gt; with a &lt;span style="color:#D20"&gt;'s&lt;/span&gt;ize&lt;span style="color:#D20"&gt;' &lt;/span&gt;of &lt;span style="color:#00D"&gt;50&lt;/span&gt;, with a tessellation level of &lt;span style="color:#00D"&gt;10&lt;/span&gt;
tess &lt;span style="color:#00D"&gt;10&lt;/span&gt; x-teapot &lt;span style="color:#00D"&gt;50&lt;/span&gt; &lt;span style="color:#00D"&gt;0&lt;/span&gt; &lt;span style="color:#00D"&gt;0&lt;/span&gt; &lt;span style="color:#00D"&gt;50&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;The available primitives are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Teapot (every good primitive library needs one of these)&lt;/li&gt;
&lt;li&gt;Cube&lt;/li&gt;
&lt;li&gt;Sphere&lt;/li&gt;
&lt;li&gt;Cylinder&lt;/li&gt;
&lt;li&gt;Torus&lt;/li&gt;
&lt;li&gt;Plane&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And before you ask, yes, the code for these is adapted from the &lt;a href="http://create.msdn.com/en-US/education/catalog/sample/primitives_3d"&gt;Primitives3D sample&lt;/a&gt; on App Hub. Like I said, most of what I&amp;#39;ve done with these importers is package up other people&amp;#39;s work, in a hopefully easy to use way.&lt;/p&gt;

&lt;p&gt;As with all the software in my recent posts, this code is open source and &lt;a href="https://github.com/tgjones/osiris"&gt;hosted on GitHub&lt;/a&gt;. If you dig through the code, you might notice that it calls out to two other libraries called &lt;a href="https://github.com/tgjones/meshellator"&gt;Meshellator&lt;/a&gt; and &lt;a href="https://github.com/tgjones/nexus"&gt;Nexus&lt;/a&gt;. These are two other open source projects I&amp;#39;m working on, but I&amp;#39;m not ready to talk about them in any great detail. The reason I&amp;#39;ve abstracted the mesh importing away from XNA is that I use the same library for a nascent software rasterizer.&lt;/p&gt;

&lt;p&gt;On a tangential note, I have three reasons for releasing this software as open source:&lt;/p&gt;

&lt;h1&gt;I&amp;#39;m legally obligated to by the licenses of the original code I ported from.&lt;/h1&gt;

&lt;h1&gt;I strongly believe in doing my bit to help us all, as the XNA community, to move beyond this kind of entry-level functionality and make some &lt;a href="http://www.indiegames-uprising.com/"&gt;cool games&lt;/a&gt;. It makes me happy to know that there are &lt;a href="http://www.google.com/search"&gt;many other people&lt;/a&gt;?q=open+source+xna&amp;amp;ie=utf-8&amp;amp;oe=utf-8&amp;amp;aq=t&amp;amp;rls=org.mozilla:en-GB:official&amp;amp;client=firefox-a doing the same thing.&lt;/h1&gt;

&lt;h1&gt;In the past I have been one of the people who, when asked if they are going to release something as open source, have answered &amp;quot;yes, I want to, but I&amp;#39;m just going to polish it a little bit more&amp;quot;, and then you never hear from them again. No longer - so what I&amp;#39;m releasing may not be bug-free, but I will respond to all comments and logged issues, and hey, it&amp;#39;s open source.&lt;/h1&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/UMsVi-iAIK0" height="1" width="1"/&gt;</description>
      <pubDate>Sat, 20 Nov 2010 00:09:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/UMsVi-iAIK0/ds-obj-and-nff-content-importers-for-xna</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2010/11/20/ds-obj-and-nff-content-importers-for-xna</feedburner:origLink></item>
    <item>
      <title>Some StitchUp updates</title>
      <description>&lt;h2&gt;The short version&lt;/h2&gt;

&lt;p&gt;There is a new build of &lt;a href="/blog/archive/2010/11/13/introducing-stitchup-generating-shaders-from-hlsl-shader-fragments"&gt;StitchUp&lt;/a&gt; available &lt;a href="https://github.com/tgjones/stitchup/downloads"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It includes these new features:
* The parser supports initial values for parameters.
* The parser supports C-style single line comments.
* The build output window in Visual Studio now shows a clickable message for the generated effect &lt;/p&gt;

&lt;h2&gt;The long version&lt;/h2&gt;

&lt;p&gt;After my last post introducing &lt;a href="/blog/archive/2010/11/13/introducing-stitchup-generating-shaders-from-hlsl-shader-fragments"&gt;StitchUp&lt;/a&gt;, I received some feedback, including a very detailed comment from &amp;quot;Alejandro&amp;quot; (sorry Alejandro, I&amp;#39;m not implying I&amp;#39;m on first name terms with you, I just don&amp;#39;t know your surname). I started to reply to his comment, but it got quite big, so I thought I&amp;#39;d write a new post, which will allow me to wax more lyrical about some new features. I also think some of his questions might be interesting for a wider audience.&lt;/p&gt;

&lt;p&gt;So, here are his questions, and my responses:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In the [params] body, how can I set a starting default value? like:
[params]
float4 color : DIFFUSE_COLOR; &amp;#47;&amp;#47; = { 1,1,1,1}; ?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It wasn&amp;#39;t possible before, but it is now. I&amp;#39;ve modified the parser to include support for initial values. So the following declarations are now possible - note that this is only valid within the &lt;code&gt;[params]&lt;/code&gt; block, since they are the only variable declarations that initial values make sense on.&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;
[params]
float3 lightDir : LIGHT_DIRECTION = { &lt;span style="color:#60E"&gt;1&lt;/span&gt;&lt;span style="color:#60E"&gt;.0f&lt;/span&gt;, -&lt;span style="color:#00D"&gt;1&lt;/span&gt;, &lt;span style="color:#00D"&gt;1&lt;/span&gt; };
float3 lightDir = { &lt;span style="color:#60E"&gt;1&lt;/span&gt;&lt;span style="color:#60E"&gt;.0f&lt;/span&gt;, -&lt;span style="color:#00D"&gt;1&lt;/span&gt;, &lt;span style="color:#00D"&gt;1&lt;/span&gt; };
float3 lightDir = float3(&lt;span style="color:#60E"&gt;1&lt;/span&gt;&lt;span style="color:#60E"&gt;.0f&lt;/span&gt;, -&lt;span style="color:#00D"&gt;1&lt;/span&gt;, &lt;span style="color:#00D"&gt;1&lt;/span&gt;);
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Next question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;... the BasicMaterial fragment doesn&amp;#39;t import anything but has a [vertex] attribute and interpolator. Is there some magic wand going around behind the scenes? Like: &amp;quot;No one output-ed an uv and you need it, so I&amp;#39;ll just give to you&amp;quot;?.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Yes, that is exactly what is happening. The code generator follows these rules:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;If the fragment includes a vertex shader, then use it - don&amp;#39;t auto-generate one.&lt;/em&gt; You might have values in the &lt;code&gt;[interpolators]&lt;/code&gt; block that you want to pass to the pixel shader, but that is not going to happen automatically. You need to use the &lt;code&gt;output&lt;/code&gt; meta-function, which is used by &lt;code&gt;PositionNormalTexture.fragment&lt;/code&gt; in the demo project.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;If the fragment doesn&amp;#39;t include a vertex shader, then auto-generate one.&lt;/em&gt; The code generator creates pass-through statements for all values in the &lt;code&gt;[interpolators]&lt;/code&gt; block. For BasicMaterial, the auto-generated vertex shader looks like this:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;
&lt;span style="color:#777"&gt;// -------- vertex shader basic_material2 --------&lt;/span&gt;
&lt;span style="color:#088;font-weight:bold"&gt;void&lt;/span&gt; basic_material2_vs(basic_material2_VERTEXINPUT input, inout VERTEXOUTPUT output)
{
    output.basic_material2.uv = input.uv;
}
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Next question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Is it still possible to #include an .fxh with basic functions and methods? I tried but failed big time. Or the correct practice would be to think about &amp;quot;Helper Fragments&amp;quot; and you would be actually &amp;quot;importing the methods&amp;quot;? (for things like random, poisson things, etc).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Yes, this is supported, in two ways.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You can create a fragment with only a &lt;code&gt;[headercode]&lt;/code&gt; block. See &lt;code&gt;DirectionalLight.fragment&lt;/code&gt; in the demo project for an example. I think this is the most elegant solution.&lt;/li&gt;
&lt;li&gt;You can use &lt;code&gt;#include&lt;/code&gt; within an &lt;code&gt;__hlsl__&lt;/code&gt; block, but because of the way I&amp;#39;m calling &lt;code&gt;EffectProcessor&lt;/code&gt; with a dynamically generated effect, you&amp;#39;ll need to use absolute path names (i.e. &lt;code&gt;C:\...\MyInclude.fxh&lt;/code&gt;).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Next question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Is there a way to see the stitched .fx file (ouput somewhere in some folder). I only see it when there is an error (usually name mismatch). Visual studio keeps it in a temporal folder.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The output is always called &lt;code&gt;StitchedEffect.fx&lt;/code&gt;, and it&amp;#39;s always saved in your temp folder. You&amp;#39;re right that Visual Studio only shows you a clickable error message if there&amp;#39;s an error. I&amp;#39;ve actually &lt;a href="http://forums.create.msdn.com/forums/t/66862.aspx"&gt;asked on the App Hub forums&lt;/a&gt; how to do this for informational messages. In the meantime, I have added a message to the build output log, which you can double-click on to open the stitched effect file. The message looks like this:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;
&lt;span style="color:#970;font-weight:bold"&gt;C:&lt;/span&gt;&lt;span style="color:#F00;background-color:#FAA"&gt;\&lt;/span&gt;Users&lt;span style="color:#F00;background-color:#FAA"&gt;\&lt;/span&gt;Tim Jones&lt;span style="color:#F00;background-color:#FAA"&gt;\&lt;/span&gt;AppData&lt;span style="color:#F00;background-color:#FAA"&gt;\&lt;/span&gt;Local&lt;span style="color:#F00;background-color:#FAA"&gt;\&lt;/span&gt;Temp&lt;span style="color:#F00;background-color:#FAA"&gt;\&lt;/span&gt;StitchedEffect.fx :   Stitched effect generated (&lt;span style="color:#0a5;font-weight:bold"&gt;double&lt;/span&gt;-click &lt;span style="color:#963"&gt;this&lt;/span&gt; message to view).
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Next question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;When assigning Visual C++ as the .fragment text editor (to get a little bit of syntax highlighting) commenting a line outside of the &lt;strong&gt;hlsl&lt;/strong&gt; body (via ctrl+e, c) will always crash Visual Studio. (Is there a way to assign NShader as the syntax highlighter for the .fragment? that would be awesome)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The first little issue is that the StitchUp parser didn&amp;#39;t allow for comments. I&amp;#39;ve implemented that now, so you can use C-style single-line comments in your &lt;code&gt;.fragment&lt;/code&gt; files:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;
float3 lightDir : LIGHT_DIRECTION = { &lt;span style="color:#60E"&gt;1&lt;/span&gt;&lt;span style="color:#60E"&gt;.0f&lt;/span&gt;, -&lt;span style="color:#00D"&gt;1&lt;/span&gt;, &lt;span style="color:#00D"&gt;1&lt;/span&gt; }; &lt;span style="color:#777"&gt;// This is a comment.&lt;/span&gt;
&lt;span style="color:#777"&gt;//float3 lightDir : LIGHT_DIRECTION = { 1.0f, -1, 1 };&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;I hadn&amp;#39;t heard of &lt;a href="http://nshader.codeplex.com/"&gt;NShader&lt;/a&gt; before - that&amp;#39;s a nice project. The only way I could see to add support for &lt;code&gt;.fragment&lt;/code&gt; files was to change the original source code. Since the developers of NShader are unlikely to be interested in supporting StitchUp-specific extensions, I have &lt;a href="https://github.com/tgjones/nshader-stitchup"&gt;created a fork of NShader&lt;/a&gt;. You can &lt;a href="https://github.com/tgjones/nshader-stitchup/downloads"&gt;download the StitchUp-specific VSIX file&lt;/a&gt;. So far I have only added support for the &lt;code&gt;.fragment&lt;/code&gt; extension, but it would be nice to add support for StitchUp keywords, such as &lt;code&gt;export&lt;/code&gt;, &lt;code&gt;import&lt;/code&gt; and &lt;code&gt;output&lt;/code&gt;. Oh, and you probably don&amp;#39;t want to install it at the same time as the official NShader package - in any case, Visual Studio probably won&amp;#39;t let you, because I haven&amp;#39;t changed of the package GUIDs.&lt;/p&gt;

&lt;p&gt;After installing this custom version of NShader, your &lt;code&gt;.fragment&lt;/code&gt; files should look like this:&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/blog/stitchup5.jpg" alt="image"/&gt;&lt;/p&gt;

&lt;p&gt;Hope this helps - as always, please post thoughts, feedback, etc. below.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/4PyUE-y4MeQ" height="1" width="1"/&gt;</description>
      <pubDate>Thu, 18 Nov 2010 22:45:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/4PyUE-y4MeQ/some-stitchup-updates</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2010/11/18/some-stitchup-updates</feedburner:origLink></item>
    <item>
      <title>Terrain GeoMipMapping on Windows Phone 7</title>
      <description>&lt;p&gt;&lt;em&gt;Update - 2010-11-16 17:10&lt;/em&gt; &lt;a href="http://sharky.bluecog.co.nz/"&gt;Lawrence Hodson&lt;/a&gt; has reported that &lt;a href="http://twitter.com/#!/SharkyNZ/status/4453810541957120"&gt;this works on an HTC Trophy&lt;/a&gt; (pic included).&lt;/p&gt;

&lt;p&gt;As I &lt;a href="/blog/archive/2010/11/16/an-xna--content-pipeline-processor-for-terrain"&gt;promised in my last post&lt;/a&gt;, I have made the necessary changes (which were not many) to get my terrain geomipmapping content pipeline processor working for Windows Phone 7. It turns out this is as easy as right-clicking the project in Visual Studio and selecting &amp;quot;Create Copy of Project for Windows Phone&amp;quot;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I don&amp;#39;t actually have a Windows Phone, so I haven&amp;#39;t tested any of this on a real device. It&amp;#39;s possible (probable) that performance could be an issue, and a smaller heightmap or higher &amp;quot;tau&amp;quot; value would need to be used.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I have pushed the changes up to the &lt;a href="https://github.com/tgjones/osiris"&gt;github repository&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Some screenshots of the terrain demo running in the emulator:&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/blog/geomipmappingwp7-1.jpg" alt="image"/&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/blog/geomipmappingwp7-2.jpg" alt="image"/&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/Y6gxKaysYH8" height="1" width="1"/&gt;</description>
      <pubDate>Tue, 16 Nov 2010 08:58:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/Y6gxKaysYH8/terrain-geomipmapping-on-windows-phone</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2010/11/16/terrain-geomipmapping-on-windows-phone</feedburner:origLink></item>
    <item>
      <title>An XNA 4.0 Content Pipeline processor for Terrain GeoMipMapping</title>
      <description>&lt;h2&gt;Introduction&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://www.flipcode.com/archives/Fast_Terrain_Rendering_Using_Geometrical_MipMapping.shtml"&gt;Geomipmapping&lt;/a&gt; was introduced by W. H. de Boer in 2000. Here&amp;#39;s what Wikipedia has to &lt;a href="http://en.wikipedia.org/wiki/Geomipmapping:"&gt;say about it&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Geomipmapping or geometrical mipmapping is a real-time block-based terrain rendering algorithm developed by W.H. de Boer in 2000 that aims to reduce CPU processing time which is a common bottleneck in level of detail approaches to terrain rendering.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you want to have a medium to large terrain in your game, then you&amp;#39;ll need some kind of block-based terrain rendering algorithm, and geomipmapping is one of the easier ones to implement. I wrote an implementation several years ago. It served my purpose, but it was difficult for anybody else to integrate into their own game.&lt;/p&gt;

&lt;p&gt;In attempt to solve that, and make it extremely easy for anybody to use terrain geomipmapping for their XNA game, I have refactored my implementation into an XNA 4.0 Content Pipeline extension.&lt;/p&gt;

&lt;h2&gt;Download&lt;/h2&gt;

&lt;p&gt;The project is called Osiris; it&amp;#39;s open source; and it&amp;#39;s available here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/tgjones/osiris"&gt;Osiris repository on github&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The repository includes a demo project, which is a derivation of the GeneratedGeometry and ChaseCamera samples.&lt;/p&gt;

&lt;p&gt;This is the properties pane for the heightmap in the demo project:&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/blog/geomipmapping3.jpg" alt="image"/&gt;&lt;/p&gt;

&lt;p&gt;And here is ALL the code you need to write to add the terrain to your game. The &lt;code&gt;TerrainComponent&lt;/code&gt; will take care of adjusting level of detail and drawing itself.&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;
terrain = &lt;span style="color:#080;font-weight:bold"&gt;new&lt;/span&gt; TerrainComponent(&lt;span style="color:#963"&gt;this&lt;/span&gt;, &lt;span style="color:#F00;background-color:#FAA"&gt;`&lt;/span&gt;&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;Terrain&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#F00;background-color:#FAA"&gt;\&lt;/span&gt;HeightMap&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;);
Components.Add(terrain);
&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;OK, I lied a little. The &lt;code&gt;TerrainComponent&lt;/code&gt; expects there to be a service in the &lt;code&gt;Game.Services&lt;/code&gt; collection which implements `ICameraService@:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;
&lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; interface ICameraService
{
    Matrix Projection { get; }
    Matrix View { get; }

    &lt;span style="color:#0a5;font-weight:bold"&gt;float&lt;/span&gt; ProjectionNear { get; }
    &lt;span style="color:#0a5;font-weight:bold"&gt;float&lt;/span&gt; ProjectionTop { get; }

    Vector3 Position { get; }
}
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;
camera = &lt;span style="color:#080;font-weight:bold"&gt;new&lt;/span&gt; ChaseCamera();
Services.AddService(typeof (ICameraService), camera);
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Here are some screenshots of it in action (use B to toggle wireframe in the demo):&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/blog/geomipmapping1.jpg" alt="image"/&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/blog/geomipmapping2.jpg" alt="image"/&gt;&lt;/p&gt;

&lt;h2&gt;The future&lt;/h2&gt;

&lt;p&gt;This is a pretty basic implementation - it uses DualTextureEffect to allow a base texture and a detail texture. I have intentionally used a built-in effect so that it will work with Windows Phone 7. This is something I&amp;#39;d like to get running soon, as I want to try out WP7 development.&lt;/p&gt;

&lt;p&gt;At the moment there is no way of doing lighting calculations. You can&amp;#39;t use vertex normals, because geomipmapping changes which vertices are rendered from frame to frame, so lighting based on vertex normals would be &amp;quot;popping&amp;quot; constantly. I intend to calculate lighting at build-time. I&amp;#39;d love to get some feedback on the basic implementation first, though, before getting too far into that.&lt;/p&gt;

&lt;p&gt;Most of the structure is in place to do frustum culling on individual patches, but I haven&amp;#39;t yet written the code to actually do it.&lt;/p&gt;

&lt;h2&gt;An aside on the name&lt;/h2&gt;

&lt;p&gt;The eagle-eyed will notice that I have previously used the name &amp;quot;Osiris&amp;quot; for &lt;a href="http://www.roastedamoeba.com/blog/archive/2008/07/29/osiris-scenegraph-development-part----introduction"&gt;another game-related project&lt;/a&gt;. You may also notice a two year gap between that blog post and &lt;a href="http://www.roastedamoeba.com/blog/archive/2010/10/25/introducing-dotliquid-the-secure-open-source-template-engine"&gt;the next one&lt;/a&gt;. That attempt at writing an all-encompassing scene graph pretty much wiped me out for 2 years as far as hobby development went. I got overwhelmed with the size of it and wasn&amp;#39;t having fun. I am now older and not much wiser, but I do know that smaller projects are more enjoyable. I&amp;#39;m also much more likely to finish them, given that I do this stuff in my free time, and have less and less of that. So this new appropriation of the name Osiris is the direction I&amp;#39;ll be going with game development - small bits of functionality that are usable by themselves, and hopefully useful to others. And hopefully the odd game...&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/OM9jDEwq56U" height="1" width="1"/&gt;</description>
      <pubDate>Tue, 16 Nov 2010 01:58:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/OM9jDEwq56U/an-xna--content-pipeline-processor-for-terrain</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2010/11/16/an-xna--content-pipeline-processor-for-terrain</feedburner:origLink></item>
    <item>
      <title>Introducing StitchUp: "Generating Shaders from HLSL Shader Fragments" implemented in XNA 4.0</title>
      <description>&lt;p&gt;&lt;em&gt;or &amp;quot;A stitch in time saves lots of mucking about with shader permutation explosion...&amp;quot;&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Want to skip to the end?&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The project is open source and hosted in a &lt;a href="https://github.com/tgjones/stitchup"&gt;github repository&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;You can download the latest release &lt;a href="https://github.com/tgjones/stitchup/downloads"&gt;from here&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;There&amp;#39;s a &lt;a href="https://github.com/tgjones/stitchup/tree/master/src/StitchUp.Demo/"&gt;demo project&lt;/a&gt; in the repo to get you started.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;A bit of background&lt;/h2&gt;

&lt;p&gt;HLSL shaders have been around for a while now. There are a multitude of different effects that you can create with shaders. They are very powerful, and taken on their own, fairly easy to work with. However, problems start to creep in when you&amp;#39;re writing a game with several different shaders (what I&amp;#39;m really talking about are &lt;em&gt;effects&lt;/em&gt;, which combine vertex and pixel shaders into a single compilable unit). As soon as you start working with multiple effects, you hit the usual problems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I want something like this shader, but with an additional detail texture instead of one.&lt;/li&gt;
&lt;li&gt;I want to add a new light, but I don&amp;#39;t want to code it for each of my effects.&lt;/li&gt;
&lt;li&gt;I want to add a new &lt;em&gt;type&lt;/em&gt; of light, but I don&amp;#39;t want to code it for each of my effects.&lt;/li&gt;
&lt;li&gt;etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This boils down to &amp;quot;how do I handle shader permutations?&amp;quot; Of course, there are &lt;em&gt;many&lt;/em&gt; ways of solving this problem, ranging from hard-coded &lt;code&gt;#if&lt;/code&gt; statements, through to fully-fledged node-based shader graphs.&lt;/p&gt;

&lt;h2&gt;What does it do?&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/tgjones/stitchup"&gt;StitchUp&lt;/a&gt; is one possible solution of the problem of shader permutation explosion. It is an implementation, using an XNA 4.0 Content Pipeline extension, of Shawn Hargreaves&amp;#39; article &lt;a href="http://www.talula.demon.co.uk/hlsl_fragments/hlsl_fragments.html"&gt;Generating Shaders From HLSL Fragments&lt;/a&gt;. I see StitchUp as sitting somewhere in the middle between hard-coded &lt;code&gt;#if&lt;/code&gt; statements and node-based shader graphs. It&amp;#39;s far more flexible than preprocessor defines or includes, but it&amp;#39;s less powerful (and also simpler to work with as a developer) than a shader node graph.&lt;/p&gt;

&lt;p&gt;For much more detail and background on HLSL fragments, go &lt;a href="http://www.talula.demon.co.uk/hlsl_fragments/hlsl_fragments.html"&gt;have a read of the article this project is based on&lt;/a&gt;. I have implemented everything in the article except for the last section on &amp;quot;Adaptive Fragments&amp;quot;. I have also changed the syntax used to define fragments, as you&amp;#39;ll see below.&lt;/p&gt;

&lt;p&gt;StitchUp allows you to create effects by defining individual shader fragments. These fragments are stitched together to form the complete effect. Fragments can include a vertex shader part, a pixel shader part, or both. They can specify that they require effect parameters, vertex attributes, interpolated attributes, and textures. Fragments can communicate with each other by exporting and importing named values.&lt;/p&gt;

&lt;h2&gt;What does it look like?&lt;/h2&gt;

&lt;p&gt;Here&amp;#39;s an example fragment:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;
fragment base_texture;

[textures]
texture2D color_map;

[vertexattributes]
float2 uv;

[interpolators]
float2 uv;

[ps &lt;span style="color:#00D"&gt;2&lt;/span&gt;_0]
__hlsl__
&lt;span style="color:#088;font-weight:bold"&gt;void&lt;/span&gt; main(INPUT input, inout OUTPUT output)
{
    output.color = tex2D(color_map, input.uv);
}
__hlsl__
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Here&amp;#39;s a simple vertex fragment. This fragment shows a bit more of the fragment definition syntax - it&amp;#39;s pretty close to HLSL, including semantics.&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;
fragment vertex_transform;

[parameters]
matrix wvp : WORLDVIEWPROJECTION;

[vertexattributes]
float3 position : POSITION;
float3 normal : NORMAL;

[interpolators]
float3 normal;

[vs &lt;span style="color:#00D"&gt;2&lt;/span&gt;_0]
__hlsl__
&lt;span style="color:#088;font-weight:bold"&gt;void&lt;/span&gt; main(INPUT input, inout OUTPUT output)
{
    output.position = mul(float4(input.position, &lt;span style="color:#00D"&gt;1&lt;/span&gt;), wvp);
    output(normal, input.normal);
}
__hlsl__
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;All variable names will get mangled in the final effect file, to ensure they are unique across all fragments. This happens behind the scenes, and you shouldn&amp;#39;t need to worry about it (until something goes wrong and then you can &lt;a href="https://github.com/tgjones/stitchup/issues"&gt;log an issue&lt;/a&gt;).&lt;/p&gt;

&lt;h2&gt;How does it work?&lt;/h2&gt;

&lt;p&gt;StitchUp is implemented as an XNA 4.0 Content Pipeline extension. In your Content project, you have many &lt;code&gt;.fragment&lt;/code&gt; files, and one or more &lt;code&gt;.stitchedeffect&lt;/code&gt; files. These files are associated with StitchUp-specific importers and processors. At compile-time, StitchUp will take the fragments and compile them into an effect. From here on it&amp;#39;s as though the effect came from the standard Effect Importer &amp;#47; Processor, and you can load it into your XNA game as you would any other effect.&lt;/p&gt;

&lt;p&gt;StitchUp also comes with a custom Model Importer. This importer lets you specify which effect to use to render the model, and will build and load that effect instead of the standard BasicEffect.&lt;/p&gt;

&lt;h2&gt;Can I see a demo?&lt;/h2&gt;

&lt;p&gt;Sure! There&amp;#39;s a demo project in the &lt;a href="https://github.com/tgjones/stitchup"&gt;repository&lt;/a&gt;. This project is based on the &lt;a href="http://create.msdn.com/en-US/education/catalog/sample/chasecamera"&gt;Chase Camera sample&lt;/a&gt; from &lt;a href="http://create.msdn.com/"&gt;App Hub&lt;/a&gt;. The fragments here combine to form a simplified version of BasicEffect (please forgive the nonsensical logic of this sentence).&lt;/p&gt;

&lt;p&gt;The fragments are included in the demo content project like this:&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/blog/stitchup1.jpg" alt="image"/&gt;&lt;/p&gt;

&lt;p&gt;The file properties for a &lt;code&gt;.fragment&lt;/code&gt; file look like this:&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/blog/stitchup2.jpg" alt="image"/&gt;&lt;/p&gt;

&lt;p&gt;The file properties for a &lt;code&gt;.stitchedeffect&lt;/code&gt; file look like this:&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/blog/stitchup3.jpg" alt="image"/&gt;&lt;/p&gt;

&lt;p&gt;The file properties for one of the models file look like this:&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/blog/stitchup4.jpg" alt="image"/&gt;&lt;/p&gt;

&lt;p&gt;At runtime, the effect parameter values are set in the &lt;code&gt;DrawModel&lt;/code&gt; method in &lt;code&gt;ChaseCameraGame.cs&lt;/code&gt;. Because the parameter names for each fragment will get mangled to ensure they are unique, it&amp;#39;s slightly awkward to refer to parameters by name (this is an area I&amp;#39;d like to improve in the future). So I generally use semantics, if I know I&amp;#39;ll only use a fragment once per effect.&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;
Matrix wvp = transforms[mesh.ParentBone.Index] * world * camera.View * camera.Projection;
effect.Parameters.GetParameterBySemantic(&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;WORLD&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;).SetValue(transforms[mesh.ParentBone.Index] * world);
effect.Parameters.GetParameterBySemantic(&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;WORLDVIEWPROJECTION&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;).SetValue(wvp);  
effect.Parameters.GetParameterBySemantic(&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;CAMERA_POSITION&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;).SetValue(camera.Position);

effect.Parameters.GetParameterBySemantic(&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;AMBIENT_LIGHT_DIFFUSE_COLOR&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;).SetValue(&lt;span style="color:#080;font-weight:bold"&gt;new&lt;/span&gt; Vector4(&lt;span style="color:#60E"&gt;0&lt;/span&gt;&lt;span style="color:#60E"&gt;.1f&lt;/span&gt;, &lt;span style="color:#60E"&gt;0&lt;/span&gt;&lt;span style="color:#60E"&gt;.1f&lt;/span&gt;, &lt;span style="color:#60E"&gt;0&lt;/span&gt;&lt;span style="color:#60E"&gt;.1f&lt;/span&gt;, &lt;span style="color:#60E"&gt;1&lt;/span&gt;&lt;span style="color:#60E"&gt;.0f&lt;/span&gt;));
effect.Parameters.GetParameterBySemantic(&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;LIGHT_DIRECTION&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;).SetValue(Vector3.Normalize(&lt;span style="color:#080;font-weight:bold"&gt;new&lt;/span&gt; Vector3(&lt;span style="color:#60E"&gt;0&lt;/span&gt;&lt;span style="color:#60E"&gt;.2f&lt;/span&gt;, -&lt;span style="color:#60E"&gt;0&lt;/span&gt;&lt;span style="color:#60E"&gt;.9f&lt;/span&gt;, &lt;span style="color:#60E"&gt;0&lt;/span&gt;&lt;span style="color:#60E"&gt;.2f&lt;/span&gt;)));
effect.Parameters.GetParameterBySemantic(&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;LIGHT_DIFFUSE_COLOR&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;).SetValue(&lt;span style="color:#080;font-weight:bold"&gt;new&lt;/span&gt; Vector4(&lt;span style="color:#60E"&gt;0&lt;/span&gt;&lt;span style="color:#60E"&gt;.5f&lt;/span&gt;, &lt;span style="color:#60E"&gt;0&lt;/span&gt;&lt;span style="color:#60E"&gt;.6f&lt;/span&gt;, &lt;span style="color:#60E"&gt;0&lt;/span&gt;&lt;span style="color:#60E"&gt;.4f&lt;/span&gt;, &lt;span style="color:#60E"&gt;1&lt;/span&gt;&lt;span style="color:#60E"&gt;.0f&lt;/span&gt;));

effect.Parameters.GetParameterBySemantic(&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;DIFFUSE_TEXTURE_ENABLED&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;).SetValue(&lt;span style="color:#069"&gt;true&lt;/span&gt;);
effect.Parameters.GetParameterBySemantic(&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;SPECULAR_COLOR&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;).SetValue(Vector3.One);
effect.Parameters.GetParameterBySemantic(&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;SPECULAR_POWER&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;).SetValue(&lt;span style="color:#00D"&gt;16&lt;/span&gt;);
effect.Parameters.GetParameterBySemantic(&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;SPECULAR_INTENSITY&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;).SetValue(&lt;span style="color:#00D"&gt;1&lt;/span&gt;);
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2&gt;Over to you...&lt;/h2&gt;

&lt;p&gt;If you do decide to give StitchUp a try, I&amp;#39;d appreciate any feedback you might have, positive or otherwise. Either leave a comment here or log an issue in the github repository. I&amp;#39;ll gladly accept push requests for bug fixes.&lt;/p&gt;

&lt;h2&gt;The future?&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;There are some unit tests, but not enough. I&amp;#39;d like to expand on these.&lt;/li&gt;
&lt;li&gt;Documentation! The wiki is a bit empty at the moment...&lt;/li&gt;
&lt;li&gt;Adaptive fragments? This is the only part of the original article that I haven&amp;#39;t implemented.&lt;/li&gt;
&lt;li&gt;Runtime classes to act as a wrapper for the compile-time fragments. They could keep track of the fragment names and make it a bit easier to set parameter values.&lt;/li&gt;
&lt;li&gt;Right now you need to have a fragment with a vertex shader to do the vertex transformation. StitchUp could generate this automatically.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Acknowledgements&lt;/h1852531521&gt;

&lt;p&gt;If it wasn&amp;#39;t obvious already, this whole project owes its existence to Shawn Hargreaves&amp;#39; article &lt;a href="http://www.talula.demon.co.uk/hlsl_fragments/hlsl_fragments.html"&gt;Generating Shaders From HLSL Fragments&lt;/a&gt;, which first appeared in ShaderX3 and is now available from &lt;a href="http://www.talula.demon.co.uk/"&gt;his website&lt;/a&gt;. Shawn also helped with some technical questions I had.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/CCkGY9QM6yU" height="1" width="1"/&gt;</description>
      <pubDate>Sat, 13 Nov 2010 14:01:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/CCkGY9QM6yU/introducing-stitchup-generating-shaders-from-hlsl-shader-fragments</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2010/11/13/introducing-stitchup-generating-shaders-from-hlsl-shader-fragments</feedburner:origLink></item>
    <item>
      <title>NuGet package now available for DotLiquid</title>
      <description>&lt;p&gt;To make it a bit easier to get started with &lt;a href="http://dotliquidmarkup.org/"&gt;DotLiquid&lt;/a&gt;, I have &lt;a href="http://nupackpackages.codeplex.com/"&gt;created&lt;/a&gt; a &lt;a href="http://nuget.codeplex.com/"&gt;NuGet&lt;/a&gt; package for it. This is now in the official NuGet package repository. Just search for DotLiquid, click &amp;quot;Install&amp;quot;, and you should be good to go.&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/blog/dotliquidnugetpackage.jpg" alt="image"/&gt;&lt;/p&gt;

&lt;p&gt;While this initial version should be fairly stable, we are still actively developing DotLiquid, and I&amp;#39;ll be updating the NuGet package as we go.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/8UBJ6cZRG4g" height="1" width="1"/&gt;</description>
      <pubDate>Mon, 08 Nov 2010 08:43:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/8UBJ6cZRG4g/nuget-package-now-available-for-dotliquid</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2010/11/08/nuget-package-now-available-for-dotliquid</feedburner:origLink></item>
    <item>
      <title>My default stack</title>
      <description>&lt;p&gt;Before you write this off as one of those ego posts that... no, it&amp;#39;s pretty much an ego post. I offer it in the chance that may be useful to somebody somewhere.&lt;/p&gt;

&lt;p&gt;This is a list of the software &amp;#47; libraries I use for new projects.&lt;/p&gt;

&lt;h2&gt;The basics&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Visual Studio 2010&lt;/li&gt;
&lt;li&gt;ReSharper 5.1&lt;/li&gt;
&lt;li&gt;.NET 4.0&lt;/li&gt;
&lt;li&gt;ASP.NET MVC 2.0 - I use a number of open source libraries which haven&amp;#39;t yet updated to MVC 3.0 Beta&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.red-gate.com/products/reflector/"&gt;Reflector&lt;/a&gt; - is it possible to survive without this?&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Database&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.mongodb.org/"&gt;MongoDB&lt;/a&gt; - I&amp;#39;m a recent convert from SQL Server. The so-called NoSQL debate goes on, but for most web projects MongoDB makes a lot of sense.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://normproject.org/"&gt;NoRM&lt;/a&gt; - .NET driver for MongoDB&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;ASP.NET&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;As mentioned above, ASP.NET MVC 2.0&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.sparkviewengine.com"&gt;Spark&lt;/a&gt; view engine&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dotless/dotless"&gt;dotless&lt;/a&gt; - I&amp;#39;ll generally use this if I&amp;#39;m writing the CSS myself&lt;/li&gt;
&lt;li&gt;&lt;a href="http://ajaxmin.codeplex.com"&gt;Microsoft Ajax Minifier&lt;/a&gt; - I use the MSBuild task at compile time (by the way, was there ever a worse name? It minifies JS and CSS, and really has nothing to do with AJAX)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Code&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Dependency injection: Managed Extensibility Framework (MEF). I used to use &lt;a href="http://ninject.org"&gt;Ninject&lt;/a&gt;, and still love it, but in most cases MEF is enough, and it&amp;#39;s built-in to .NET 4.0.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/sitdap/dynamic-image"&gt;DynamicImage&lt;/a&gt; - A not-well-known (so far) but excellent library from &lt;a href="http://www.sitdap.com"&gt;Sound in Theory&lt;/a&gt; which takes care of all image manipulation.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Testing&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.nunit.org/"&gt;NUnit&lt;/a&gt; - Don&amp;#39;t really need to say much about this one.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.jetbrains.com/profiler/index.html"&gt;dotTrace&lt;/a&gt;?topDT&lt;/li&gt;
&lt;li&gt;I don&amp;#39;t use a coverage tool yet, but I&amp;#39;m a big fan of JetBrains, so I&amp;#39;ll probably check out &lt;a href="http://www.jetbrains.com/dotcover/"&gt;dotCover&lt;/a&gt; soon.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Deployment&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;MSBuild script to build solution, run NUnit tests, and call msdeploy to sync with live (or staging, depending on the project) IIS website&lt;/li&gt;
&lt;li&gt;TeamCity running on build server to detect changes in source code repository and run MSBuild script&lt;/li&gt;
&lt;/ul&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/EcjSOZv0vNE" height="1" width="1"/&gt;</description>
      <pubDate>Fri, 05 Nov 2010 08:10:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/EcjSOZv0vNE/my-default-stack</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2010/11/05/my-default-stack</feedburner:origLink></item>
    <item>
      <title>Creating website thumbnail images in ASP.NET</title>
      <description>&lt;p&gt;Following on from my post about &lt;a href="/blog/archive/2010/11/04/creating-thumbnails-of-a-pdf-in-aspnet"&gt;generating PDF thumbnails in ASP.NET&lt;/a&gt;, here is another one about generating website thumbnail images using &lt;a href="https://github.com/sitdap/dynamic-image"&gt;DynamicImage&lt;/a&gt;.&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;
&lt;span style="color:#070"&gt;&amp;lt;sitdap:DynamicImage&lt;/span&gt; &lt;span style="color:#b48"&gt;runat&lt;/span&gt;=&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;server&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span style="color:#b48"&gt;ImageFormat&lt;/span&gt;=&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;Jpeg&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#070"&gt;&amp;gt;&lt;/span&gt;
    &lt;span style="color:#070"&gt;&amp;lt;Layers&amp;gt;&lt;/span&gt;
        &lt;span style="color:#070"&gt;&amp;lt;sitdap:WebsiteScreenshotLayer&lt;/span&gt; &lt;span style="color:#b48"&gt;WebsiteUrl&lt;/span&gt;=&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;http://www.microsoft.com&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#070"&gt;&amp;gt;&lt;/span&gt;
            &lt;span style="color:#070"&gt;&amp;lt;Filters&amp;gt;&lt;/span&gt;
                &lt;span style="color:#070"&gt;&amp;lt;sitdap:ResizeFilter&lt;/span&gt; &lt;span style="color:#b48"&gt;Width&lt;/span&gt;=&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;500&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span style="color:#b48"&gt;Mode&lt;/span&gt;=&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;UseWidth&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span style="color:#070"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span style="color:#070"&gt;&amp;lt;/Filters&amp;gt;&lt;/span&gt;
        &lt;span style="color:#070"&gt;&amp;lt;/sitdap:WebsiteScreenshotLayer&amp;gt;&lt;/span&gt;
    &lt;span style="color:#070"&gt;&amp;lt;/Layers&amp;gt;&lt;/span&gt;
&lt;span style="color:#070"&gt;&amp;lt;/sitdap:DynamicImage&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;You can also use the fluent interface:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;
&lt;span style="color:#0a5;font-weight:bold"&gt;string&lt;/span&gt; imageUrl = &lt;span style="color:#080;font-weight:bold"&gt;new&lt;/span&gt; DynamicImageBuilder()
    .WithLayer(
        &lt;span style="color:#080;font-weight:bold"&gt;new&lt;/span&gt; WebsiteScreenshotLayerBuilder().WebsiteUrl(&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;http://www.microsoft.com&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)
        .WithFilter(FilterBuilder.Resize.ToWidth(&lt;span style="color:#00D"&gt;500&lt;/span&gt;))
    ).Url;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;The preceding code will result in this image:&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/blog/websitethumbnaillayer1.jpg" alt="image"/&gt;&lt;/p&gt;

&lt;p&gt;As you can see, the image is of the whole web page, not just the cropped window you&amp;#39;d normally see. If you want that, you can use the &lt;code&gt;Crop&lt;/code&gt; filter:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;
&lt;span style="color:#070"&gt;&amp;lt;sitdap:DynamicImage&lt;/span&gt; &lt;span style="color:#b48"&gt;runat&lt;/span&gt;=&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;server&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span style="color:#b48"&gt;ImageFormat&lt;/span&gt;=&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;Jpeg&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#070"&gt;&amp;gt;&lt;/span&gt;
    &lt;span style="color:#070"&gt;&amp;lt;Layers&amp;gt;&lt;/span&gt;
        &lt;span style="color:#070"&gt;&amp;lt;sitdap:WebsiteScreenshotLayer&lt;/span&gt; &lt;span style="color:#b48"&gt;WebsiteUrl&lt;/span&gt;=&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;http://www.microsoft.com&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#070"&gt;&amp;gt;&lt;/span&gt;
            &lt;span style="color:#070"&gt;&amp;lt;Filters&amp;gt;&lt;/span&gt;
                &lt;span style="color:#070"&gt;&amp;lt;sitdap:ResizeFilter&lt;/span&gt; &lt;span style="color:#b48"&gt;Width&lt;/span&gt;=&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;500&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span style="color:#b48"&gt;Mode&lt;/span&gt;=&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;UseWidth&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span style="color:#070"&gt;/&amp;gt;&lt;/span&gt;
                &lt;span style="color:#070"&gt;&amp;lt;sitdap:CropFilter&lt;/span&gt; &lt;span style="color:#b48"&gt;Width&lt;/span&gt;=&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;500&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span style="color:#b48"&gt;Height&lt;/span&gt;=&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;500&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span style="color:#070"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span style="color:#070"&gt;&amp;lt;/Filters&amp;gt;&lt;/span&gt;
        &lt;span style="color:#070"&gt;&amp;lt;/sitdap:WebsiteScreenshotLayer&amp;gt;&lt;/span&gt;
    &lt;span style="color:#070"&gt;&amp;lt;/Layers&amp;gt;&lt;/span&gt;
&lt;span style="color:#070"&gt;&amp;lt;/sitdap:DynamicImage&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Now you should have:&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/blog/websitethumbnaillayer2.jpg" alt="image"/&gt;&lt;/p&gt;

&lt;p&gt;You can optionally specify a timeout, after which if the screenshot capture process hasn&amp;#39;t finished, it will terminate and not produce an image. &lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;
&lt;span style="color:#070"&gt;&amp;lt;sitdap:WebsiteScreenshotLayer&lt;/span&gt; &lt;span style="color:#b48"&gt;WebsiteUrl&lt;/span&gt;=&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;http://www.microsoft.com&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span style="color:#b48"&gt;Timeout&lt;/span&gt;=&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;3000&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span style="color:#070"&gt;/&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;
&lt;span style="color:#080;font-weight:bold"&gt;new&lt;/span&gt; WebsiteScreenshotLayerBuilder()
    .WebsiteUrl(&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;http://www.microsoft.com&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)
    .Timeout(&lt;span style="color:#00D"&gt;3000&lt;/span&gt;)
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Since these images will take a while to produce, you&amp;#39;ll probably want to &lt;a href="https://github.com/sitdap/dynamic-image/wiki/Getting-Started"&gt;enable caching&lt;/a&gt; in DynamicImage.&lt;/p&gt;

&lt;p&gt;Thanks are due to to &lt;a href="http://nolovelust.com/post/C-Website-Screenshot-Generator-AKA-Get-Screenshot-of-Webpage-With-Aspnet-C.aspx"&gt;&amp;#39;NoLoveLust&amp;#39;s work on wrapping CutyCapt.exe&lt;/a&gt;, which provided a starting point for this code.&lt;/p&gt;

&lt;p&gt;To get it working, you&amp;#39;ll need to copy &lt;code&gt;CutyCapt.exe&lt;/code&gt; from the &lt;a href="https://github.com/tgjones/dynamic-image/tree/master/Tools/"&gt;Tools folder&lt;/a&gt; in the repo to &lt;code&gt;App_Data&amp;#47;DynamicImage&lt;/code&gt;.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/rX7umFgBFrE" height="1" width="1"/&gt;</description>
      <pubDate>Thu, 04 Nov 2010 08:55:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/rX7umFgBFrE/creating-website-thumbnail-images-in-aspnet</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2010/11/04/creating-website-thumbnail-images-in-aspnet</feedburner:origLink></item>
    <item>
      <title>Creating thumbnails of a PDF in ASP.NET</title>
      <description>&lt;p&gt;Recently I pushed a new feature to &lt;a href="https://github.com/tgjones/dynamic-image"&gt;my fork&lt;/a&gt; of &lt;a href="https://github.com/sitdap/dynamic-image"&gt;DynamicImage&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;DynamicImage&lt;/h2&gt;

&lt;p&gt;Since you might not have heard of DynamicImage before, here&amp;#39;s a brief introduction: DynamicImage is an open source image manipulation library for ASP.NET from &lt;a href="http://www.sitdap.com"&gt;Sound in Theory&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Have a look at the &lt;a href="https://github.com/sitdap/dynamic-image/wiki"&gt;wiki page&lt;/a&gt; for information on getting started with DynamicImage.&lt;/p&gt;

&lt;p&gt;DynamicImage composes images using two key concepts:&lt;/p&gt;

&lt;h1&gt;&lt;em&gt;Layers&lt;/em&gt;. An image can be composed of several layers. There are several layer types built-in: TextLayer, ImageLayer, RectangleShapeLayer and PolygonShapeLayer.&lt;/h1&gt;

&lt;h1&gt;&lt;em&gt;Filters&lt;/em&gt;. Each layer can have zero or more filters applied to it. There are more than 15 filters built-in, including basic ones such as resize, crop, and border, and more advanced ones such as gaussian blur, distort corners, feather, shiny floor and curves.&lt;/h1&gt;

&lt;p&gt;It&amp;#39;s easy to add both new layer types and new filter types.&lt;/p&gt;

&lt;h2&gt;PDF Thumbnails&lt;/h2&gt;

&lt;p&gt;Getting back to the topic of this post, I added a new layer type, &lt;code&gt;PdfLayer&lt;/code&gt;. Here it is in action:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;
&lt;span style="color:#070"&gt;&amp;lt;sitdap:DynamicImage&lt;/span&gt; &lt;span style="color:#b48"&gt;runat&lt;/span&gt;=&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;server&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span style="color:#b48"&gt;ImageFormat&lt;/span&gt;=&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;Jpeg&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#070"&gt;&amp;gt;&lt;/span&gt;
    &lt;span style="color:#070"&gt;&amp;lt;Layers&amp;gt;&lt;/span&gt;
        &lt;span style="color:#070"&gt;&amp;lt;sitdap:PdfLayer&lt;/span&gt; &lt;span style="color:#b48"&gt;SourceFileName&lt;/span&gt;=&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;~/Assets/PDFs/pdf-test.pdf&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span style="color:#b48"&gt;PageNumber&lt;/span&gt;=&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;1&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#070"&gt;&amp;gt;&lt;/span&gt;
            &lt;span style="color:#070"&gt;&amp;lt;Filters&amp;gt;&lt;/span&gt;
                &lt;span style="color:#070"&gt;&amp;lt;sitdap:ResizeFilter&lt;/span&gt; &lt;span style="color:#b48"&gt;Width&lt;/span&gt;=&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;500&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span style="color:#b48"&gt;Mode&lt;/span&gt;=&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;UseWidth&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span style="color:#070"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span style="color:#070"&gt;&amp;lt;/Filters&amp;gt;&lt;/span&gt;
        &lt;span style="color:#070"&gt;&amp;lt;/sitdap:PdfLayer&amp;gt;&lt;/span&gt;
    &lt;span style="color:#070"&gt;&amp;lt;/Layers&amp;gt;&lt;/span&gt;
&lt;span style="color:#070"&gt;&amp;lt;/sitdap:DynamicImage&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;You could also use the fluent interface if you&amp;#39;re not using WebForms, or you prefer to build images in code:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;
&lt;span style="color:#0a5;font-weight:bold"&gt;string&lt;/span&gt; imageUrl = &lt;span style="color:#080;font-weight:bold"&gt;new&lt;/span&gt; DynamicImageBuilder()
    .WithLayer(
        &lt;span style="color:#080;font-weight:bold"&gt;new&lt;/span&gt; PdfLayerBuilder().SourceFileName(&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;~/Assets/PDFs/pdf-test.pdf&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;).PageNumber(&lt;span style="color:#00D"&gt;1&lt;/span&gt;)
        .WithFilter(FilterBuilder.Resize.ToWidth(&lt;span style="color:#00D"&gt;500&lt;/span&gt;))
    ).Url;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Under the covers, this is using the excellent &lt;a href="https://github.com/mephraim/ghostscriptsharp"&gt;GhostscriptSharp&lt;/a&gt; library from &lt;a href="http://www.mattephraim.com/"&gt;Matthew Ephraim&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/38nxYaLvt3c" height="1" width="1"/&gt;</description>
      <pubDate>Thu, 04 Nov 2010 08:50:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/38nxYaLvt3c/creating-thumbnails-of-a-pdf-in-aspnet</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2010/11/04/creating-thumbnails-of-a-pdf-in-aspnet</feedburner:origLink></item>
    <item>
      <title>Farewell, 0x1D</title>
      <description>&lt;p&gt;This Saturday, I will turn 30. When I was 20, 30 seemed like a big deal. As I&amp;#39;ve got closer to it, I&amp;#39;ve become more of the opinion that life is a series of rolling events rather than age-related milestones. I&amp;#39;m also pretty sure that&amp;#39;s what people tell themselves when they get older.&lt;/p&gt;

&lt;p&gt;In no particular order, my 20s have included:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Meeting and marrying a wonderful girl, and moving to Taiwan with her.&lt;/li&gt;
&lt;li&gt;Getting a BSc in Computer Science (only took me 5 years).&lt;/li&gt;
&lt;li&gt;Working for a Web 1.0 startup in London, which didn&amp;#39;t make it.&lt;/li&gt;
&lt;li&gt;Working for another startup in London, which did.&lt;/li&gt;
&lt;li&gt;Working as Technical Director with a web design agency in Exeter.&lt;/li&gt;
&lt;li&gt;Freelancing while trying to get something of our own off the ground.&lt;/li&gt;
&lt;li&gt;Travelling to &lt;a href="http://www.whereivebeen.com/map.php"&gt;various places&lt;/a&gt;?uID=2098712&amp;amp;iID=112c309eea05613f283a4f89870c3f5b.&lt;/li&gt;
&lt;li&gt;Running a few 10ks and half marathons.&lt;/li&gt;
&lt;li&gt;Programming in ASP, then Javascript, then VB6, toying with C++, then learning everything again with .NET and C#. Not forgetting putting my time in with SQL, and paying the angle bracket tax of XML.&lt;/li&gt;
&lt;li&gt;Working on an &lt;a href="http://www.roastedamoeba.com/blog/archive/2010/10/25/introducing-dotliquid-the-secure-open-source-template-engine"&gt;open source project&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Overall, it&amp;#39;s been a great decade, and I&amp;#39;m excited to start the next one. I&amp;#39;m curious what I&amp;#39;ll be writing about in 10 years time... (waiting for future Tim to come back in time to tell me)... nope, I guess time travel hasn&amp;#39;t been invented yet.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/1J-3IeNjR4U" height="1" width="1"/&gt;</description>
      <pubDate>Tue, 26 Oct 2010 15:31:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/1J-3IeNjR4U/farewell-xd</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2010/10/26/farewell-xd</feedburner:origLink></item>
    <item>
      <title>Introducing DotLiquid: the secure, open-source template engine for .NET</title>
      <description>&lt;p&gt;Want to skip straight to the goods?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://dotliquidmarkup.org/try-online"&gt;Try DotLiquid online&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://github.com/formosatek/dotliquid/downloads"&gt;Download DotLiquid&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;The Problem&lt;/h2&gt;

&lt;p&gt;One of the questions that comes up fairly often for the average developer is: &amp;quot;How can I transfer &lt;em&gt;this&lt;/em&gt; data into &lt;em&gt;that&lt;/em&gt; output?&amp;quot; The data often takes the form of an object, and the output is often HTML or plain text. There are, of course, &lt;a href="http://whereslou.com/2009/01/27/late-bound-eval-email-templates-revisited"&gt;many&lt;/a&gt; &lt;a href="http://code.google.com/p/csharptemplates/"&gt;ways&lt;/a&gt; &lt;a href="http://www.stringtemplate.org/"&gt;of&lt;/a&gt; &lt;a href="http://csharp-source.net/open-source/template-engines"&gt;skinning&lt;/a&gt; &lt;a href="http://visualstudiomagazine.com/articles/2009/05/01/visual-studios-t4-code-generation.aspx"&gt;the cat[1]&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;These existing .NET template engines are very suitable for one specific use-case: when the developer, or another trusted party, is responsible for authoring the templates. However, to the best of my knowledge, there have not been any full-featured[2] template engines available for .NET which are suitable for the other use-case: when &lt;em&gt;you want customers to edit their own templates&lt;/em&gt;. You may want this because you host the customer&amp;#39;s website on your server, or simply because .NET is too complex to give to a non-techie.&lt;/p&gt;

&lt;h2&gt;Enter DotLiquid&lt;/h2&gt;

&lt;p&gt;This is the thinking behind why I wrote &lt;a href="http://dotliquidmarkup.org/"&gt;DotLiquid&lt;/a&gt;, a C# port of the &lt;a href="http://www.liquidmarkup.org"&gt;Liquid&lt;/a&gt; template engine from Ruby. DotLiquid offers the following benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It is &lt;em&gt;secure&lt;/em&gt;. It only allows access to the data and operations you explicitly allow.&lt;/li&gt;
&lt;li&gt;It is &lt;em&gt;proven&lt;/em&gt;. The &lt;a href="http://www.liquidmarkup.org/"&gt;Liquid&lt;/a&gt; template language has been used in major web applications such as &lt;a href="http://www.shopify.com/"&gt;Shopify&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;It can be &lt;em&gt;extended easily&lt;/em&gt;, in part because it is open source, in part because it&amp;#39;s &lt;a href="http://github.com/formosatek/dotliquid/wiki/DotLiquid-for-Developers"&gt;designed that way&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;It is completely &lt;em&gt;standalone&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Where can I find it?&lt;/h2&gt;

&lt;p&gt;The website is &lt;a href="http://dotliquidmarkup.org/"&gt;here&lt;/a&gt;. You can &lt;a href="http://dotliquidmarkup.org/try-online"&gt;try it online&lt;/a&gt;. The source code for DotLiquid is hosted on GitHub, and can be found &lt;a href="http://github.com/formosatek/dotliquid"&gt;here&lt;/a&gt;. This is also the place to &lt;a href="http://github.com/formosatek/dotliquid/issues"&gt;log issues&lt;/a&gt;. There is some &lt;a href="http://github.com/formosatek/dotliquid/wiki"&gt;documentation&lt;/a&gt;, although (as ever) I hope to expand on what is there. The current version of DotLiquid can be downloaded &lt;a href="http://github.com/formosatek/dotliquid/downloads"&gt;here&lt;/a&gt; (we&amp;#39;re on Beta 2 at the moment, and we&amp;#39;re just letting that brew for a while before pushing out the final release of 1.0). Once &amp;quot;&lt;a href="http://nupack.codeplex.com/"&gt;the package manager formerly known as NuPack&lt;/a&gt;&amp;quot; has settled down a bit, I&amp;#39;ll be creating a package so that you can easily include DotLiquid in your projects.&lt;/p&gt;

&lt;p&gt;If you&amp;#39;ve made it this far, chances are you might be looking for this sort of library. If you do use it in your project, I hope you find it helpful, and if you would like your project to be mentioned on the &lt;a href="http://dotliquidmarkup.org/"&gt;DotLiquid website&lt;/a&gt;, just &lt;a href="http://formosatek.com/"&gt;drop me a line&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Acknowledgements&lt;/h2&gt;

&lt;p&gt;DotLiquid wouldn&amp;#39;t exist without Liquid, and Liquid wouldn&amp;#39;t exist without &lt;a href="http://blog.leetsoft.com/"&gt;Tobias Lütke&lt;/a&gt;. Thank you Tobias.&lt;/p&gt;

&lt;p&gt;I&amp;#39;d also like to thank &lt;a href="http://www.alessandropetrelli.com/"&gt;Alessandro Petrelli&lt;/a&gt; for his many useful contributions to DotLiquid.&lt;/p&gt;

&lt;p&gt;fn1. I actually like cats.
fn2. I say &amp;quot;full-featured&amp;quot; because I could find at least one &lt;a href="http://code.google.com/p/csharptemplates/"&gt;template engine which uses Django-style syntax&lt;/a&gt;, but I don&amp;#39;t think it offers important constructs such as loops and conditionals.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/zKoQ_OdvlnE" height="1" width="1"/&gt;</description>
      <pubDate>Mon, 25 Oct 2010 23:11:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/zKoQ_OdvlnE/introducing-dotliquid-the-secure-open-source-template-engine</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2010/10/25/introducing-dotliquid-the-secure-open-source-template-engine</feedburner:origLink></item>
    <item>
      <title>Osiris SceneGraph Development Part 1 - Introduction</title>
      <description>&lt;p&gt;This series will describe the development of a scene graph toolkit. This is a non-work project so I can&amp;#39;t promise regular updates, but I will do my best.&lt;/p&gt;

&lt;p&gt;&amp;lt;##Motivation&amp;lt;&amp;#47;##
I wondered about calling this YASG (Yet Another Scene Graph). &lt;a href="http://www.openscenegraph.org/"&gt;There&amp;#39;s&lt;/a&gt; &lt;a href="http://www.opensg.org/"&gt;quite&lt;/a&gt; &lt;a href="http://developer.nvidia.com/object/nvsg_home.html"&gt;a&lt;/a&gt; &lt;a href="http://www.ogre3d.org/"&gt;few&lt;/a&gt; of them out there. However, nothing quite suited.&lt;/p&gt;

&lt;p&gt;My primary goal in writing a scene graph is to use it as the basis of an XNA game. However, I&amp;#39;ve got some other projects on the go. One is a &lt;a href="http://www.roastedamoeba.com/blog/archive/2008/05/15/xna--hybrid-ray-tracer"&gt;ray tracer&lt;/a&gt;, and the other is a software renderer. The software renderer will be used in an ASP.NET control that I am developing for my company.&lt;/p&gt;

&lt;p&gt;I realised that I was writing very similar code for each of these three projects: specifically, code to manage the scene data. All three required code for some sort of tree involving transforms; all three required code for camera transformations; all three required code for storing triangular meshes.&lt;/p&gt;

&lt;p&gt;It seemed to me that it would be highly desirable to completely separate the scene data from the rendering. If this was possible, I could write one scene graph system, and three renderers (ray tracer, hardware rasterizer, software rasterizer).&lt;/p&gt;

&lt;p&gt;If at this point you&amp;#39;re thinking &amp;quot;uh oh - I see where this is going - it&amp;#39;s going to be a nightmare to abstract away the differences between those renderers&amp;quot;, then you&amp;#39;d be completely right. And if this was a commercial project, it would almost certainly be dead in the water, in terms of reward for time spent. But this is a hobby project, and I love abstraction.&lt;/p&gt;

&lt;p&gt;&amp;lt;##Problems&amp;lt;&amp;#47;##
Immediately I began to hit problems. Possibly the most basic requirement of any graphics library is a good set of maths classes - i.e. vector, matrix, etc. Since the primary usage of the scene graph is going to be for an XNA game, it would make sense to use the maths classes available in XNA (Vector3, Matrix, etc.) right? Sadly not. I am exposing the other two renderers (software rasterizer, ray tracer) through an ASP.NET web control. I don&amp;#39;t want to have Microsoft.Xna.Framework as a dependency for an ASP.NET control. The same goes for the maths classes in WPF (Vector3D, Point3D, etc.).&lt;/p&gt;

&lt;p&gt;&amp;lt;##Core classes&amp;lt;&amp;#47;##
So I decided to write my own maths classes. Having now done this, I can say it&amp;#39;s not fun, when it feels so much like re-inventing the wheel. But I wanted a scene graph which could be used by multiple renderers. So I don&amp;#39;t have much choice. I used both WPF (the Media3D namespace) and XNA as a model for my maths classes. I like how WPF separates out Vector3D and Point3D. I know you can accomplish everything you need to with just a Vector3D, but it seems more rigorous to provide separate types. I have implemented the following types:&lt;/p&gt;

&lt;p&gt;&lt;ul&gt;
    &lt;li&gt;Color&lt;/li&gt;&lt;li&gt;Matrix3 (used for some physics calculations)&lt;/li&gt;&lt;li&gt;Matrix4&lt;/li?&lt;li&gt;Plane&lt;/li&gt;&lt;li&gt;Point (for texture coordinates)&lt;/li&gt;&lt;li&gt;Point3D&lt;/li&gt;&lt;li&gt;Ray3D&lt;/li&gt;&lt;li&gt;Vector3D&lt;/li&gt;
&lt;/ul&gt;
&amp;lt;##Scene graph&amp;lt;&amp;#47;##
Whew! I haven&amp;#39;t even started describing the design of the scene graph but I&amp;#39;m going to finish soon. In summary: in this series of blog posts I will be describing the development of a scene graph, starting from scratch. I will try to describe the major problems I face along the way. Later on I will talk about how I&amp;#39;ve implemented &amp;#47; am implementing each of the three renderers (ray tracer, software rasterizer, hardware rasterizer).&lt;/p&gt;

&lt;p&gt;I did quite a lot of research of existing scene graphs (including OpenSceneGraph and Nvidia Scene Graph), and tried to distil what I liked from them, together with my own ideas. I also had the restriction of needing the scene graph to work with a ray tracer, which is a limitation not faced by most existing scene graphs (which are optimised for a particular renderer, such as OpenGL). At the same time, the scene graph needed to cope with a hardware renderer, which (for example) requires vertices to be stored in a vertex buffer in graphics memory. I will describe the solutions I came up with in Part 2.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/UeJdcET1tU8" height="1" width="1"/&gt;</description>
      <pubDate>Tue, 29 Jul 2008 21:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/UeJdcET1tU8/osiris-scenegraph-development-part----introduction</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2008/07/29/osiris-scenegraph-development-part----introduction</feedburner:origLink></item>
    <item>
      <title>Setting the default button for a nested control in ASP.NET</title>
      <description>&lt;p&gt;In ASP.NET 2.0, you can declaratively set which button which be &amp;quot;clicked&amp;quot; when the user presses the Enter key. This can be done on either the &lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt; or &lt;code&gt;&amp;lt;asp:Panel&amp;gt;&lt;/code&gt; tag, as follows:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;
&lt;span style="color:#070"&gt;&amp;lt;asp:Panel&lt;/span&gt; &lt;span style="color:#b48"&gt;runat&lt;/span&gt;=&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;server&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span style="color:#b48"&gt;DefaultButton&lt;/span&gt;=&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;btnSubmit&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#070"&gt;&amp;gt;&lt;/span&gt;
    &lt;span style="color:#070"&gt;&amp;lt;asp:TextBox&lt;/span&gt; &lt;span style="color:#b48"&gt;runat&lt;/span&gt;=&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;server&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span style="color:#b48"&gt;ID&lt;/span&gt;=&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;txtFirstName&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span style="color:#070"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span style="color:#070"&gt;&amp;lt;asp:Button&lt;/span&gt; &lt;span style="color:#b48"&gt;runat&lt;/span&gt;=&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;server&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span style="color:#b48"&gt;ID&lt;/span&gt;=&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;btnSubmit&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span style="color:#b48"&gt;Text&lt;/span&gt;=&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;Submit&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span style="color:#070"&gt;/&amp;gt;&lt;/span&gt;
&lt;span style="color:#070"&gt;&amp;lt;/asp:Panel&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;This works fine as long as the button control is directly contained within the Panel or form. However, if the button control is nested within a user control or any other control that implements INamingContainer, it will no longer work.&lt;/p&gt;

&lt;p&gt;I discovered that you can still do this declaratively - but you need to use the &lt;em&gt;relative&lt;/em&gt; ID. For the sake of argument, let&amp;#39;s say that the button is contained within a CreateUserWizard control (this could be any control or user control though).&lt;/p&gt;

&lt;p&gt;For this scenario, you&amp;#39;d need to set the DefaultButton property to the path &lt;em&gt;relative to the Panel on which you&amp;#39;re setting the DefaultButton&lt;/em&gt;. For example (note that &amp;quot;__CustomNav0&amp;quot; might need to be replaced - I get this ID because of a custom adapter I use on the CreateUserWizard control):&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;
&lt;span style="color:#070"&gt;&amp;lt;asp:Panel&lt;/span&gt; &lt;span style="color:#b48"&gt;runat&lt;/span&gt;=&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;server&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span style="color:#b48"&gt;DefaultButton&lt;/span&gt;=&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;cuwRegister$__CustomNav0$btnSubmit&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#070"&gt;&amp;gt;&lt;/span&gt;
    &lt;span style="color:#070"&gt;&amp;lt;asp:CreateUserWizard&lt;/span&gt; &lt;span style="color:#b48"&gt;runat&lt;/span&gt;=&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;server&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span style="color:#b48"&gt;ID&lt;/span&gt;=&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;cuwRegister&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#070"&gt;&amp;gt;&lt;/span&gt;
        &lt;span style="color:#070"&gt;&amp;lt;WizardSteps&amp;gt;&lt;/span&gt;
            &lt;span style="color:#070"&gt;&amp;lt;asp:CompleteWizardStep&lt;/span&gt; &lt;span style="color:#b48"&gt;runat&lt;/span&gt;=&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;server&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#070"&gt;&amp;gt;&lt;/span&gt;
                &lt;span style="color:#070"&gt;&amp;lt;CustomNavigationTemplate&amp;gt;&lt;/span&gt;
                    &lt;span style="color:#070"&gt;&amp;lt;asp:Button&lt;/span&gt; &lt;span style="color:#b48"&gt;runat&lt;/span&gt;=&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;server&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span style="color:#b48"&gt;ID&lt;/span&gt;=&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;btnSubmit&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span style="color:#b48"&gt;Text&lt;/span&gt;=&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;Submit&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span style="color:#070"&gt;/&amp;gt;&lt;/span&gt;
                &lt;span style="color:#070"&gt;&amp;lt;/CustomNavigationTemplate&amp;gt;&lt;/span&gt;
            &lt;span style="color:#070"&gt;&amp;lt;/asp:CompleteWizardStep&amp;gt;&lt;/span&gt;
        &lt;span style="color:#070"&gt;&amp;lt;/WizardSteps&amp;gt;&lt;/span&gt;
    &lt;span style="color:#070"&gt;&amp;lt;/asp:CreateUserWizard&amp;gt;&lt;/span&gt;
&lt;span style="color:#070"&gt;&amp;lt;/asp:Panel&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;I hope this helps somebody.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/SRA6fLsIuJY" height="1" width="1"/&gt;</description>
      <pubDate>Tue, 24 Jun 2008 11:55:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/SRA6fLsIuJY/setting-the-default-button-for-a-nested-control</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2008/06/24/setting-the-default-button-for-a-nested-control</feedburner:origLink></item>
    <item>
      <title>XNA 3.0 Hybrid Ray Tracer</title>
      <description>&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;a href="http://www.roastedamoeba.com/assets/software/raytracing.zip"&gt;Download XNA 3.0 Hybrid Tracer&lt;/a&gt; (source code, requires Visual Studio 2008 and XNA 3.0 CTP)

Last week while going through my personal software graveyard, I "dug up" a ray tracer I started a few years ago. I had written it using C#, and it was rendered using GDI+. I decided to bring it up to date - and you can't get newer than the XNA 3.0 CTP, released last week. At this stage there's hardly any new features related to Windows development, apart from audio, but I like being able to use Visual Studio 2008 and LINQ.

Anyway, one thing that annoyed me about my previous implementation was how difficult it was to move the camera around. So, I decided to write a hybrid ray tracer:
&lt;ul&gt;&lt;li&gt;When the camera is static, ray tracing is used.&lt;/li&gt;&lt;li&gt;When the camera is moving, XNA hardware rasterization is used.&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;Features
&lt;/span&gt;&lt;ul&gt;&lt;li&gt;Automatically switches from ray tracing to hardware rasterization when camera is moving&lt;/li&gt;&lt;li&gt;Loads scenes from an XML file using the XNA Content Pipeline&lt;/li&gt;&lt;li&gt;Supports sphere and plane primitives, with other primitives coming soon (including triangles, and hence meshes)&lt;/li&gt;&lt;li&gt;Point lights, with other light types coming soon
&lt;/li&gt;&lt;/ul&gt;The current version is fairly basic, both in terms of ray tracing and rasterization. The two render methods are also not very similar - about the only thing they are the same at is object position. However, I know it's usually better for me to upload &lt;span style="font-weight: bold;"&gt;something&lt;/span&gt;, however basic, just to get the ball rolling. So here it is. Feel free to use the code in any way you like. Hopefully you'll find it logically structured.

The camera has two modes:
&lt;ul&gt;&lt;li&gt;Pan: This took me a while to get right. I eventually realised that software like 3D Studio Max converts mouse coordinates from screen space to world space, and then pans in world space. So I did the same.&lt;/li&gt;&lt;li&gt;Arc ball: I'm not happy with my implementation of this. It sort of works though - I set it to rotate around a point 5 world units in front of the camera.&lt;/li&gt;&lt;li&gt;In either mode, you can use the mouse scroll wheel to zoom (although this doesn't work very well yet).
&lt;/li&gt;&lt;/ul&gt;
My todo list:
&lt;ul&gt;&lt;li&gt;Ray tracer&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Refraction&lt;/li&gt;&lt;li&gt;Photon mapping&lt;/li&gt;&lt;li&gt;Textures&lt;/li&gt;&lt;li&gt;kd-tree for spatial sorting&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;XNA rasterization&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Specular lighting&lt;/li&gt;&lt;li&gt;Environment mapping&lt;/li&gt;&lt;li&gt;Planar reflections and refractions&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Both renderers&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Fresnel effect&lt;/li&gt;&lt;li&gt;Textures&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;Screenshots&lt;/span&gt;
&lt;p&gt;&lt;img src="/assets/blog/raytrace1.png" /&gt;&lt;/p&gt;&lt;p&gt;&lt;img src="/assets/blog/xna1.png" /&gt;&lt;/p&gt;&lt;img src="/assets/blog/raytrace2.png" /&gt;
&lt;p&gt;&lt;img src="/assets/blog/xna2.png" /&gt;&lt;/p&gt;&lt;div style="clear:both; padding-bottom:0.25em"&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/HTSr_bP2fJI" height="1" width="1"/&gt;</description>
      <pubDate>Thu, 15 May 2008 23:49:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/HTSr_bP2fJI/xna--hybrid-ray-tracer</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2008/05/15/xna--hybrid-ray-tracer</feedburner:origLink></item>
    <item>
      <title>ASP.NET HTML Control Mapping</title>
      <description>&lt;p&gt;Ever wondered how ASP.NET takes an HTML tag, such as &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt;, and maps it to an &lt;code&gt;System.Web.UI.HtmlControls.HtmlHead&lt;/code&gt; object? Well, me neither, till today. But if you ever want to know, Reflector comes in handy. In the &lt;code&gt;System.Web.UI&lt;/code&gt; namespace, there&amp;#39;s an internal class called &lt;code&gt;HtmlTagNameToTypeMapper&lt;/code&gt;. In here, there&amp;#39;s a method called &lt;code&gt;GetControlType&lt;/code&gt;, which looks like this:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;
Type ITagNameToTypeMapper.GetControlType(&lt;span style="color:#0a5;font-weight:bold"&gt;string&lt;/span&gt; tagName, IDictionary attributeBag)
{
  Type type;
  &lt;span style="color:#080;font-weight:bold"&gt;if&lt;/span&gt; (tagMap == null)
  {
      Hashtable hashtable = &lt;span style="color:#080;font-weight:bold"&gt;new&lt;/span&gt; Hashtable(&lt;span style="color:#00D"&gt;10&lt;/span&gt;, StringComparer.OrdinalIgnoreCase);
      hashtable.Add(&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;a&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, typeof(HtmlAnchor));
      hashtable.Add(&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;button&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, typeof(HtmlButton));
      hashtable.Add(&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;form&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, typeof(HtmlForm));
      hashtable.Add(&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;head&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, typeof(HtmlHead));
      hashtable.Add(&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;img&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, typeof(HtmlImage));
      hashtable.Add(&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;textarea&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, typeof(HtmlTextArea));
      hashtable.Add(&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;select&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, typeof(HtmlSelect));
      hashtable.Add(&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;table&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, typeof(HtmlTable));
      hashtable.Add(&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;tr&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, typeof(HtmlTableRow));
      hashtable.Add(&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;td&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, typeof(HtmlTableCell));
      hashtable.Add(&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;th&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, typeof(HtmlTableCell));
      tagMap = hashtable;
  }
  &lt;span style="color:#080;font-weight:bold"&gt;if&lt;/span&gt; (inputTypes == null)
  {
      Hashtable hashtable2 = &lt;span style="color:#080;font-weight:bold"&gt;new&lt;/span&gt; Hashtable(&lt;span style="color:#00D"&gt;10&lt;/span&gt;, StringComparer.OrdinalIgnoreCase);
      hashtable2.Add(&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;text&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, typeof(HtmlInputText));
      hashtable2.Add(&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;password&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, typeof(HtmlInputPassword));
      hashtable2.Add(&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;button&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, typeof(HtmlInputButton));
      hashtable2.Add(&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;submit&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, typeof(HtmlInputSubmit));
      hashtable2.Add(&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;reset&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, typeof(HtmlInputReset));
      hashtable2.Add(&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;image&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, typeof(HtmlInputImage));
      hashtable2.Add(&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;checkbox&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, typeof(HtmlInputCheckBox));
      hashtable2.Add(&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;radio&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, typeof(HtmlInputRadioButton));
      hashtable2.Add(&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;hidden&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, typeof(HtmlInputHidden));
      hashtable2.Add(&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;file&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, typeof(HtmlInputFile));
      inputTypes = hashtable2;
  }
  &lt;span style="color:#080;font-weight:bold"&gt;if&lt;/span&gt; (StringUtil.EqualsIgnoreCase(&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;input&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, tagName))
  {
      &lt;span style="color:#0a5;font-weight:bold"&gt;string&lt;/span&gt; str = (&lt;span style="color:#0a5;font-weight:bold"&gt;string&lt;/span&gt;) attributeBag[&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;type&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;];
      &lt;span style="color:#080;font-weight:bold"&gt;if&lt;/span&gt; (str == null)
      {
          str = &lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;text&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;;
      }
      type = (Type) inputTypes[str];
      &lt;span style="color:#080;font-weight:bold"&gt;if&lt;/span&gt; (type == null)
      {
          &lt;span style="color:#080;font-weight:bold"&gt;throw&lt;/span&gt; &lt;span style="color:#080;font-weight:bold"&gt;new&lt;/span&gt; HttpException(SR.GetString(&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;Invalidtypeforinputtag&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span style="color:#080;font-weight:bold"&gt;new&lt;/span&gt; object[] { str }));
      }
      &lt;span style="color:#080;font-weight:bold"&gt;return&lt;/span&gt; type;
  }
  type = (Type) tagMap[tagName];
  &lt;span style="color:#080;font-weight:bold"&gt;if&lt;/span&gt; (type == null)
  {
      type = typeof(HtmlGenericControl);
  }
  &lt;span style="color:#080;font-weight:bold"&gt;return&lt;/span&gt; type;
}
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Unfortunately, there&amp;#39;s no way I can see of overriding this behaviour - for example, if you wanted to map the &lt;code&gt;&amp;lt;li&amp;gt;&lt;/code&gt; element to a custom &lt;code&gt;HtmlListItemControl&lt;/code&gt;, it&amp;#39;s impossible.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/TjLYr6QSk2Q" height="1" width="1"/&gt;</description>
      <pubDate>Wed, 02 Jan 2008 16:47:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/TjLYr6QSk2Q/aspnet-html-control-mapping</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2008/01/02/aspnet-html-control-mapping</feedburner:origLink></item>
    <item>
      <title>A few things I wonder about</title>
      <description>&lt;div style="clear:both;"&gt;&lt;/div&gt;Continuing the line of thought from a previous blog post, here's some more things I wonder about, complete with answers that I have helpfully researched for you:

&lt;span style="font-weight: bold;"&gt;How many ants live in an ants' nest?
&lt;/span&gt;An ant colony &lt;a href="http://www.amonline.net.au/factSheets/ant_colonies.htm"&gt;can range in size&lt;/a&gt; from a few 10s of individuals to over a million, depending on species and age of the colony.

&lt;span style="font-weight: bold;"&gt;Can a swan really break your arm?&lt;/span&gt;
Yes, but only in &lt;a href="http://www.swanuk.org.uk/faq.htm"&gt;exceptional cases&lt;/a&gt;.

&lt;span style="font-weight: bold;"&gt;How do the screens at London bus stops calculate when buses are due?
&lt;/span&gt;Currently, they use a tag and beacon system, which records the location of the bus when it passes roadside beacons along the route. However, Transport for London has been trialling a GPS system where a GPS device on each bus would update a central computer every 30 seconds. They plan eventually to be able to &lt;a href="http://www.computing.co.uk/computing/news/2149572/real-system-trial-boards-london"&gt;send SMS updates to passengers' mobile phones&lt;/a&gt;, which would be pretty cool.

&lt;span style="font-weight: bold;"&gt;[What is RFID and] when will it appear in supermarkets?
&lt;/span&gt;Radio Frequency Identification (RFID) is an automatic identification method; tiny electronic tags are attached to an item, and these tags can be read remotely, within a range of a few metres. In Japan, the government wanted consumers to be able to track food right back to the producer, so tags are applied to the packaging of fruit and vegetables right after they have been picked and packed. RFID readers attached to mobile phones allow consumers to view information about the produce. Bring it on! Although I suspect the British government will cripple the technology in some way; I'm not particularly cynical about our government, but there's simply too many &lt;span style="font-style: italic;"&gt;Sun&lt;/span&gt; and &lt;span style="font-style: italic;"&gt;Daily Mail&lt;/span&gt; readers to let any technology that exciting into the country.&lt;span style="font-weight: bold;"&gt;

&lt;span style="font-weight: bold;"&gt;How many countries are there in the world?&lt;/span&gt;&lt;/span&gt;
According to &lt;a href="http://en.wikipedia.org/wiki/List_of_countries"&gt;a Wikipedia entry&lt;/a&gt;, there are 245 entities that are considered countries. Of the countries eligible to be members of the United Nations (i.e. sovereign states), all but one or two are. I say one or two, because it depends on how you define Taiwan's status as a country (in 1971 it was replaced in the United Nations by the People's Republic of China, but since 1991 has been actively trying to rejoin) . The other one is Vatican City which has chosen not to join.&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;
&lt;/span&gt;&lt;div style="clear:both; padding-bottom:0.25em"&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/iK2F872cmzE" height="1" width="1"/&gt;</description>
      <pubDate>Sat, 19 May 2007 22:40:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/iK2F872cmzE/a-few-things-i-wonder-about</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2007/05/19/a-few-things-i-wonder-about</feedburner:origLink></item>
    <item>
      <title>Milky Way + Andromedia = Milkomeda</title>
      <description>&lt;p&gt;Astronomers have calculated that, in five billion years, the Milky Way and our closest neighbouring galaxy, Andromeda, will violently collide, creating a new merged galaxy, which has been dubbed Milkomeda. The two galaxies will (apparently) swing past each other in less than 2 billion years, then again 1.5 billion years after that, before merging 5 million years from now. Scientists have calculated that there is a 3% chance that the sun will defect to Andromeda during the second close pass, in which case viewers on Earth (assuming there&amp;#39;s any left by that point) would see the Milky Way as a spiral in the night sky.&lt;/p&gt;

&lt;p&gt;If you&amp;#39;d like to see what the &amp;quot;merger&amp;quot; might look like, watch this video. I find it oddly beautiful, given how cataclysmically destructive the whole thing is. It&amp;#39;s funny to think that each of the two spirals of white contains hundreds of billions of stars.&lt;/p&gt;

&lt;p&gt;&lt;object classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" codebase="http://www.apple.com/qtactivex/qtplugin.cab" height="260" width="320"&gt; &lt;param name="src" value="http://www.cita.utoronto.ca/%7Edubinski/Gravitas/mov320/6_SpiralMetamorphosis.mov" /&gt;&lt;param name="autoplay" value="false" /&gt;&lt;param name="controller" value="true" /&gt;&lt;param name="loop" value="false" /&gt;&lt;embed src="http://www.cita.utoronto.ca/%7Edubinski/Gravitas/mov320/6_SpiralMetamorphosis.mov" autoplay="false" controller="true" loop="false" pluginspage="http://www.apple.com/quicktime/download/" height="260" width="320"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/mSyWZHd4hqk" height="1" width="1"/&gt;</description>
      <pubDate>Sat, 19 May 2007 00:01:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/mSyWZHd4hqk/milky-way--andromedia--milkomeda</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2007/05/19/milky-way--andromedia--milkomeda</feedburner:origLink></item>
    <item>
      <title>Depressible buttons on drink carton lids</title>
      <description>&lt;p&gt;&lt;img src="/assets/blog/dsc00658.jpg" alt="drink carton"/&gt;&lt;/p&gt;

&lt;p&gt;If you&amp;#39;re anything like me (and God help you if you are), you&amp;#39;ll have wondered why those little buttons on the plastic lids of soft drink cartons, such as you get from McDonalds, are never actually pressed by the fast food operative. I don&amp;#39;t remember ever seeing them used.&lt;/p&gt;

&lt;p&gt;However, while enjoying a nutritional* dinner at a Burger King &amp;quot;restaurant&amp;quot;, I noticed that the &amp;quot;diet&amp;quot; button on one of my friend&amp;#39;s drinks had, in fact, been pressed. After recovering from the initial feeling of jealousy that my button had never been pressed, so to speak, I realised it might have something to do with never ordering diet drinks. That said, some fast food chains have a more advanced drink lid configuration which allows for the flavour to be selected as well, and I&amp;#39;ve also never seen that used.&lt;/p&gt;

&lt;p&gt;But apparently I&amp;#39;ve been living in the dark, and it&amp;#39;s quite common in some countries, such as the United States, to have these buttons used on a regular basis. I can only dream.&lt;/p&gt;

&lt;p&gt;If you think depressible buttons on plastic lids are boring, then &lt;a href="http://technabob.com/blog/2006/10/06/new-soda-bottle-tech-lets-you-mix-your-own-flavors/"&gt;check this out&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;*Burger King helpfully provide a colour-coded table listing all the Good Things contained in each burger, so it must be nutritional.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/CCQrvLe3zLI" height="1" width="1"/&gt;</description>
      <pubDate>Thu, 10 May 2007 23:22:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/CCQrvLe3zLI/depressible-buttons-on-drink-carton-lids</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2007/05/10/depressible-buttons-on-drink-carton-lids</feedburner:origLink></item>
    <item>
      <title>Reversible quotations</title>
      <description>&lt;p&gt;Walking around the Imperial War Museum today, I saw this quote:
&lt;blockquote&gt;&amp;quot;Mankind must put an end to war, or war will put an end to mankind.&amp;quot;
-- John F. Kennedy&lt;/blockquote&gt;I realised that this kind of quote, which I&amp;#39;ll call a &amp;quot;reversible quote&amp;quot;, is pretty popular. But all you really need to do is sit down and think of two concepts (i.e. &amp;quot;mankind&amp;quot; and &amp;quot;war&amp;quot;), join them with a verb (i.e. &amp;quot;end&amp;quot;), and then reverse it. Or, for another form, think of a verb (i.e. &amp;quot;fail&amp;quot;) and a noun that can also be a verb (i.e. &amp;quot;plan&amp;quot;). Here&amp;#39;s a few other quotes I found. I&amp;#39;m sure there&amp;#39;s lots of others, feel free to suggest them and we can create a master list of reversible quotations.
&lt;blockquote&gt;&amp;quot;And so, my fellow Americans, ask not what your country can do for you; ask what you can do for your country.&amp;quot;
-- John F. Kennedy&lt;/blockquote&gt;&lt;blockquote&gt;&amp;quot;Let us never negotiate out of fear. But let us never fear to negotiate.&amp;quot;
-- John F. Kennedy&lt;/blockquote&gt;&lt;blockquote&gt;&amp;quot;A pessimist is one who makes difficulties of his opportunities and an optimist is one who makes opportunities of his difficulties.&amp;quot;
-- Harry S. Truman&lt;/blockquote&gt;&lt;blockquote&gt;&amp;quot;And in the end it&amp;#39;s not the years in your life that count. It&amp;#39;s the life in your years.&amp;quot;
-- Abraham Lincoln&lt;/blockquote&gt;&lt;blockquote&gt;&amp;quot;For those who like this sort of thing, this is the sort of thing they like.&amp;quot; [eh?!]
-- Abraham Lincoln&lt;/blockquote&gt;&lt;blockquote&gt;&amp;quot;Peace is not absence of conflict, it is the ability to handle conflict by peaceful means.&amp;quot;
-- Ronald Reagan&lt;/blockquote&gt;&lt;blockquote&gt;&amp;quot;He who fails to plan, plans to fail.&amp;quot;
-- Unknown&lt;/blockquote&gt;It&amp;#39;s not exactly a reversible quotation, but I couldn&amp;#39;t resist:
&lt;blockquote&gt;&amp;quot;I just want you to know that, when we talk about war, we&amp;#39;re really talking about peace.&amp;quot;
-- George W. Bush&lt;/blockquote&gt;
This all looks pretty easy to me, so I&amp;#39;m inspired to try some of my own:
&lt;blockquote&gt;&amp;quot;A photographer may think he is taking a photograph of a place, but really the photograph is taking the photographer... places.&amp;quot;
-- Tim G. Jones
&lt;/blockquote&gt;Okay, so it&amp;#39;s not that easy. Let&amp;#39;s try again using the second form.
&amp;gt;
He who prizes the win, wins the prize.
-- Tim G. Jones&lt;/p&gt;

&lt;p&gt;See? Instant eloquence guaranteed. It doesn&amp;#39;t even need to be true.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/GzKzf3iOeNk" height="1" width="1"/&gt;</description>
      <pubDate>Mon, 09 Apr 2007 22:20:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/GzKzf3iOeNk/reversible-quotations</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2007/04/09/reversible-quotations</feedburner:origLink></item>
    <item>
      <title>Overriding the meaning of ~ in ASP.NET</title>
      <description>&lt;p&gt;Random techie discovery... You can override the meaning of the tilde (~) in paths in ASP.NET.&lt;/p&gt;

&lt;p&gt;I often use the &lt;code&gt;~&lt;/code&gt; so that it doesn&amp;#39;t matter whether my web application is sitting at the root level or in a virtual directory. For example, I could include this as the href of a link tag to make ASP.NET write out the correct path of a stylesheet:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;~/App_Assets/Css/Screen.css&lt;span style="color:#F00;background-color:#FAA"&gt;`&lt;/span&gt;&lt;span style="color:#F00;background-color:#FAA"&gt;`&lt;/span&gt;&lt;span style="color:#F00;background-color:#FAA"&gt;`&lt;/span&gt;

I discovered today that you can override the meaning of that &lt;span style="color:#F00;background-color:#FAA"&gt;`&lt;/span&gt;~&lt;span style="color:#F00;background-color:#FAA"&gt;`&lt;/span&gt;, to potentially point anywhere you like, such as a subfolder. [See here](http:&lt;span style="color:#777"&gt;//blogs.msdn.com/davidebb/archive/2005/11/27/497339.aspx) for details.&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/A_E5SIVse0g" height="1" width="1"/&gt;</description>
      <pubDate>Thu, 05 Apr 2007 17:35:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/A_E5SIVse0g/overriding-the-meaning-of--in-aspnet</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2007/04/05/overriding-the-meaning-of--in-aspnet</feedburner:origLink></item>
    <item>
      <title>Clever shit</title>
      <description>&lt;div style="clear:both;"&gt;&lt;/div&gt;Coming back home on the tube tonight, I met a man who tried to do the human race a favour by removing himself from the gene pool, using alcohol as his tool of choice.

I first noticed him when, on a nearly empty train, he lurched over to my area of the carriage and sort of hung over me. I glanced up at him, with a look calculated to convey a message along the lines of "my personal space ends about a metre beyond where you are now", which seemed to work because he backed off.

A few seconds later he decided to sit down - I say "decided", actually it had more to do with a sudden change in the train's velocity which caught him off balance. I had cunningly placed my man-bag on the seat next to me so he careered into the seat beyond that.

He then did his best to engage me in conversation. Conversation, that is, in the form of Antipodean grunts. I believe he used the word "brethren" a lot although I couldn't be sure. Again, cunningly, I had my iPod(tm) headphones in, so I could pretend I didn't hear anything.

At Earl's Court, the train filled with people, and a girl sat down on the previously empty seat between the hero of the story, and me. I instantly felt guilty, mainly because of the pungent odour he was emitting, and thought about offering to switch places with her, but it was too late. He had already started making his "moves", which consisted of the following conversation:

Him: "Hello gorgeous."
Her: "You stink."
Him: "Oh."

She got off at the next stop.

The rest of the journey was spent with him trying to come up with increasingly desperate insults, I assume directed at me, although because the motion of the train had a direct effect on his ability to stay in his seat, the insults could have been directed at the floor, it was difficult to tell.

He went through the basics: "you're bald" (true), "you're wearing a checked shirt" (also true), "Mr. iPod" (clutching at straws). My personal favourite, and the one that I feel summarises his ability to stay in the gene pool, was his critique on the copy of &lt;span style="font-style: italic;"&gt;New Scientist &lt;/span&gt;that was I was reading:

"Clever shit."&lt;div style="clear:both; padding-bottom:0.25em"&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/1SvHHZnJUE8" height="1" width="1"/&gt;</description>
      <pubDate>Sun, 25 Mar 2007 23:26:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/1SvHHZnJUE8/clever-shit</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2007/03/25/clever-shit</feedburner:origLink></item>
    <item>
      <title>Climate science</title>
      <description>&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;a href="http://environment.newscientist.com/article.ns?id=dn11417&amp;amp;feedId=online-news_rss20"&gt;This New Scientist article&lt;/a&gt; indicates that some "fudging" of climate science may have been systematically occurring over the last 10 years. The guy who seems to have been responsible, Phil Cooney, used to be a lobbyist for the American Petroleum Institute, and he has since gone on to ExxonMobil. In other words, exactly the kind of person we want influencing the policy of the global hegemon on climate change.

While I'm complaining about other people / entities doing their best to destroy the world, allow me to mention Shell - this year's sponsor of the Wildlife Photographer of the Year competition. &lt;a href="http://www.foe.co.uk/index.html"&gt;Friends of the Earth&lt;/a&gt; has an interesting set of photos highlighting their more accurate role as &lt;a href="http://www.foe.co.uk/campaigns/corporates/news/shell_wildlife_gallery.html"&gt;Shell: Wildlife Destroyer of the Year&lt;/a&gt;.

Okay, enough green politics. I don't know what I'm talking about anyway.&lt;div style="clear:both; padding-bottom:0.25em"&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/PS18ISn3Od4" height="1" width="1"/&gt;</description>
      <pubDate>Tue, 20 Mar 2007 22:31:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/PS18ISn3Od4/climate-science</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2007/03/20/climate-science</feedburner:origLink></item>
    <item>
      <title>Toilet paper folder and dispenser</title>
      <description>&lt;div style="clear:both;"&gt;&lt;/div&gt;Eventually, this had to be invented by somebody: an "automatic", although by the looks of it not-quite-working, &lt;a href="http://www.youtube.com/watch?v=QTsXlTKaFq0"&gt;toilet paper folder and dispenser&lt;/a&gt;.

Edit: While we're on the subject of toilet paper, have a look at this discussion on &lt;a href="http://www.youtube.com/watch?v=oFUupaCm7fE"&gt;crumple vs. fold&lt;/a&gt;...&lt;div style="clear:both; padding-bottom:0.25em"&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/ZM1zZKvZxYo" height="1" width="1"/&gt;</description>
      <pubDate>Sun, 18 Mar 2007 23:52:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/ZM1zZKvZxYo/toilet-paper-folder-and-dispenser</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2007/03/18/toilet-paper-folder-and-dispenser</feedburner:origLink></item>
    <item>
      <title>Increasing the maximum connections to a server in IE and Firefox</title>
      <description>&lt;div style="clear:both;"&gt;&lt;/div&gt;Although the HTTP 1.1 specification says that only two connections to a single server should be allowed through a browser, it's often necessary (well, preferable) to open more connections. For example, when downloading multiple files, or simply to increase rendering speed.

In Internet Explorer, you just need to add the following value to your registry:

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings]
"MaxConnectionsPerServer"=dword:00000010

In Firefox, type about:config in the address bar, and then change this value, for example to 16:

network.http.max-persistent-connections-per-server

Hope this helps!&lt;div style="clear:both; padding-bottom:0.25em"&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/Y5uS78J-i3g" height="1" width="1"/&gt;</description>
      <pubDate>Thu, 15 Mar 2007 16:12:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/Y5uS78J-i3g/increasing-the-maximum-connections-to-a-server-in</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2007/03/15/increasing-the-maximum-connections-to-a-server-in</feedburner:origLink></item>
    <item>
      <title>Urinal etiquette</title>
      <description>&lt;div style="clear:both;"&gt;&lt;/div&gt;Relatively speaking, there has been very little written on the subject of urinals. This is strange, as urinals are very much a part of the life of the modern day man. I have decided to redress this shortcoming, and provide a detailed explanation of the usage of said conveniences.

&lt;span style="font-weight: bold;"&gt;Introduction&lt;/span&gt;
There are many, many different factors to be taken into account during the use of urinals. It is not, as some people uneducated in the field may think, a simple matter of walking into the men's toilets, doing one's business, washing one's hands, and leaving. Oh no. Using a urinal correctly has as much etiquette and as many rules as eating at a high-class restaurant. Not that those two things are in any way related.

&lt;span style="font-weight: bold;"&gt;Urinal Etiquette&lt;/span&gt;
Now we get down to the actual rules themselves:

&lt;span style="font-style: italic;"&gt;Finding a Urinal&lt;/span&gt;
&lt;ul&gt;&lt;li&gt;If there is a cubicle available, you should always use it in preference to a urinal, unless:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;none of the urinals are currently being used, or&lt;/li&gt;&lt;li&gt;there are several free (and contiguous) urinals, or&lt;/li&gt;&lt;li&gt;you would have to walk past the urinals to get to the vacant cubicle.&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;If you must use a urinal, it is necessary to carefully pick the appropriate urinal. Failure to do so will result in strange looks and a feeling of embarassment. This will also make you less of a man. Use the following rules to pick a urinal:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;If there are 3 vacant urinals in a row, choose the middle one of the three.&lt;/li&gt;&lt;li&gt;If all the urinals but one are free, and if the one being used is at one end of the set of urinals, do not under any circumstances choose the urinal at the other end of the line, unless there are less than four urinals in total. Doing so would be homophobic and bad. In general terms, when faced with this situation, you should pick a urinal that is halfway between the centre point of the line of urinals, and the vacant end.&lt;/li&gt;&lt;li&gt;If there are only 2 vacant urinals in a row, then which one of the 2 you pick is pretty much up to you, but if possible pick the urinal that is nearest the end of the line, or nearest the door.&lt;/li&gt;&lt;li&gt;If each free urinal is separate (i.e. there is a maximum of 1 free in a row) then only use a urinal if the spacing between urinals is greater than 70cm. Any less than this, and you risk brushing against one of the other urinal users. This is bad. If the spacing is less than 70cm, you must wait until 2 or more urinals in a row become available.&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;
&lt;span style="font-style: italic;"&gt;Using a Urinal&lt;/span&gt;
We now assume that you have successfully found a urinal, and are ready to start using it. The process becomes a little more complicated at this point, and there are several things you must think about:
&lt;ul&gt;&lt;li&gt;Unzipping - this must be done completely nonchalantly. No signs of self-consciousness or uncomfortableness should be shown. It is preferable to keep looking straight ahead, but if necessary then a quick glance downwards is acceptable.&lt;/li&gt;&lt;li&gt;While doing your business, eye position is extremely important. In fact the importance of this point cannot be overstated. Always look straight ahead or up at the ceiling. Do not look down, and under no circumstances should you look at other urinal users.&lt;/li&gt;&lt;li&gt;Some people find it helpful to whistle as a way of informing others that they are comfortable with the situation. Remember not to whistle too loudly, as this indicates a slightly forced comfortableness, suggesting that in fact the urinal user is ill at ease in the situation. A sound recording of the suggested whistling volume will be uploaded to this site soon.
&lt;/li&gt;&lt;/ul&gt;&lt;div style="clear:both; padding-bottom:0.25em"&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/L8rlFTHiA3g" height="1" width="1"/&gt;</description>
      <pubDate>Wed, 14 Mar 2007 08:42:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/L8rlFTHiA3g/urinal-etiquette</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2007/03/14/urinal-etiquette</feedburner:origLink></item>
    <item>
      <title>The not-so-beautiful game</title>
      <description>&lt;div style="clear:both;"&gt;&lt;/div&gt;This is from a leaflet I was handed by one of those people on the street who you desperately try to avoid - in this case, I tried the "buffer person" and "ground scanning" tactics - but somehow they outwit you and you end up holding a piece of paper with some odd words written on it.

For example:
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_Wywrr60_Hxc/ReM05-y0yoI/AAAAAAAAABE/PWPXDCmccmc/s1600-h/Image.jpg"&gt;&lt;img style="cursor: pointer;" src="http://bp0.blogger.com/_Wywrr60_Hxc/ReM05-y0yoI/AAAAAAAAABE/PWPXDCmccmc/s400/Image.jpg" alt="" id="BLOGGER_PHOTO_ID_5035926979043707522" border="0" /&gt;&lt;/a&gt;

What I'm wondering is, if Jesus is the referee, and the world is the pitch... can I be the streaker? And what does Jesus think of dives and reckless tackling?

On second thoughts... I don't wish to be red-carded so I'll stop now.&lt;div style="clear:both; padding-bottom:0.25em"&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/7HM2_Es8b2Q" height="1" width="1"/&gt;</description>
      <pubDate>Mon, 26 Feb 2007 19:27:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/7HM2_Es8b2Q/the-not-so-beautiful-game</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2007/02/26/the-not-so-beautiful-game</feedburner:origLink></item>
    <item>
      <title>Is your second cousin once removed the child of your first cousin twice removed?</title>
      <description>&lt;p&gt;Are you confused by the phrase &amp;quot;second cousin once removed&amp;quot;, and wonder how its different from &amp;quot;first cousin twice removed&amp;quot;? I&amp;#39;ve always wondered how the cousin system works but it&amp;#39;s another one of those things I haven&amp;#39;t got round to. Enter the wonderful world of the web.&lt;/p&gt;

&lt;p&gt;Actually, it&amp;#39;s quite simple. As my complicated chart below shows. If you wish to determine what type of cousin another family member is to you, find the closest common ancestor. Count the number of generations that you and your cousin are from your ancestor. If you are the same number of generations away from your ancestor as your cousin, then you are first, second etc. cousins, where the number is one less than the number of generations that you and your cousin are from the ancestor.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://bp0.blogger.com/_Wywrr60_Hxc/RdESOfKg39I/AAAAAAAAAAw/o8G-NW4meVE/s1600-h/Cousins.jpg"&gt;&lt;img src="http://bp0.blogger.com/_Wywrr60_Hxc/RdESOfKg39I/AAAAAAAAAAw/o8G-NW4meVE/s400/Cousins.jpg" alt="" id="BLOGGER_PHOTO_ID_5030822298842619858" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As an example, if your nearest common ancestor is your great great grandfather, four generations away, then you are third cousins.&lt;/p&gt;

&lt;p&gt;It gets a bit more complicated when your cousin is a different number of generations from the ancestor. Then, the relation is based on the nearer of you and your cousin from the ancestor. Additionally, your cousin is said to be &amp;quot;removed&amp;quot; by the number of generations he &amp;#47; she is away from your own generation.&lt;/p&gt;

&lt;p&gt;For example, your second cousin&amp;#39;s father is your first cousin once removed, because he is only two generations away from your common ancestors, your great grandparents, but he is &amp;quot;removed&amp;quot; by one from your generation.&lt;/p&gt;

&lt;p&gt;You&amp;#39;ll notice in the chart that each relational name is used twice. Your father&amp;#39;s cousin is your first cousin once removed; but so is your cousin&amp;#39;s child. There are ways of disambiguating these relationships if you really want to.&lt;/p&gt;

&lt;p&gt;So now you know.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/ejVeYb0-qqM" height="1" width="1"/&gt;</description>
      <pubDate>Mon, 12 Feb 2007 23:49:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/ejVeYb0-qqM/is-your-second-cousin-once-removed-the-child</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2007/02/12/is-your-second-cousin-once-removed-the-child</feedburner:origLink></item>
    <item>
      <title>Solved: The Great Religion Debate</title>
      <description>&lt;div style="clear:both;"&gt;&lt;/div&gt;WHSmith weighs in with its take on the veracity of atheism...

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp2.blogger.com/_Wywrr60_Hxc/Rcev_kmz-QI/AAAAAAAAAAk/dpyavpW0-98/s1600-h/DSC00626.JPG"&gt;&lt;img style="cursor: pointer;" src="http://bp2.blogger.com/_Wywrr60_Hxc/Rcev_kmz-QI/AAAAAAAAAAk/dpyavpW0-98/s400/DSC00626.JPG" alt="" id="BLOGGER_PHOTO_ID_5028181015675533570" border="0" /&gt;&lt;/a&gt;

Oh, the irony.&lt;div style="clear:both; padding-bottom:0.25em"&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/2G6wf0XSv_0" height="1" width="1"/&gt;</description>
      <pubDate>Mon, 05 Feb 2007 22:24:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/2G6wf0XSv_0/solved-the-great-religion-debate</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2007/02/05/solved-the-great-religion-debate</feedburner:origLink></item>
    <item>
      <title>Sacrificial chips</title>
      <description>&lt;div style="clear:both;"&gt;&lt;/div&gt;When eating a bowl of chips at a pub, or a packet of fries at a fast-food outlet, I like to empty 2 or 3 ketchup sachets onto a limited area of chippage. Normally most of the ketchup falls onto one chip, but there is always a fallout area covering 3 or 4 chips. The central chip in the catchment area will normally become so soggy that when I do eat it, after consuming all other available non-dead chips*, it's difficult to taste anything other than ketchup.

Anyway, I like to refer to this as the "sacrificial chip". Please help me to push this phrase into common use. Personally, I like the sacrificial chip, indeed consider it the pinnacle of the bowl-of-chips eating experience, but I have at least one friend who dislikes sacrificing chips so much that she will "ketchup" (that's a verb) each chip individually, directly from the sachet.

*Dead chips are the chips that are either too crispy to chew, or chips that simply look odd, presumably due to inconsistencies in the McKentuckyBurger "french fry" manufacturing process.&lt;div style="clear:both; padding-bottom:0.25em"&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/HGrXzH3kz3Q" height="1" width="1"/&gt;</description>
      <pubDate>Mon, 29 Jan 2007 19:15:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/HGrXzH3kz3Q/sacrificial-chips</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2007/01/29/sacrificial-chips</feedburner:origLink></item>
    <item>
      <title>Free will</title>
      <description>&lt;div style="clear:both;"&gt;&lt;/div&gt;There is a lot of discussion going on at the moment about free will; so I feel compelled (geddit?) to post on the subject myself. Some interesting reading, if you haven't seen this stuff before:

&lt;a href="http://www.economist.com/opinion/displaystory.cfm?story_id=8453850"&gt;http://www.economist.com/opinion/displaystory.cfm?story_id=8453850&lt;/a&gt;
&lt;a href="http://www.newscientist.com/channel/fundamentals/mg19025504.000"&gt;http://www.newscientist.com/channel/fundamentals/mg19025504.000&lt;/a&gt;

I can't offer much in the way of philosphical or experimental arguments for or against free will, so I'd like to approach it in a different way.

When I was a teenager I was, it's fair to say, a very different person. I was, as teenagers invariably are, the product of a combination of influences: family, school, friends, church. From these influences I had built up a certain world view. I happened upon some essays and stores that I wrote at school, reproduced here for your amusement (the fact that I now cringe when reading this stuff perfectly illustrates the point I'm about to make):
&lt;blockquote&gt;"In the book of Genesis, inspired by God, and written by Moses, we find the beginnings of man"&lt;/blockquote&gt;&lt;blockquote&gt;"In 1984, a stamp was issued in Britain that commemorated the 2nd Election of the European Parliament. This shows a woman riding on a beast which is on seven waves, or mounds. This symbolism bears a striking similarity to the passage in Revelation 17, which states: 'I will tell you the mystery of the woman and of the beast that carries her, which has the seven heads and the ten horns ... Here is the mind which has wisdom: The seven heads are seven mountains on which the woman sits...'" [I like this one; in my opinion, Christians rule the roost at conspiracy theories]&lt;/blockquote&gt;&lt;blockquote&gt;"[Jesus] has given us clear instructions about how to be a servant. These have priority over our own desires for success ... Let us strive to humble ourselves to Him. Only by doing that will we find true fulfillment and satisfaction."&lt;/blockquote&gt;&lt;blockquote&gt;"State schools ...  are feeding children evolution, atheism, and every other ‘ism’ that is opposed to God." [I think was actually right on this point, but my stance on it now may be somewhat different]&lt;/blockquote&gt;Ouch. I feel quite uncomfortable even reading those quotes myself, let alone sharing them. But I want to make a point: I'm different from who I was then. I'm very different. But why?

As I see it, there are three possible ways in which I might have changed:
&lt;ul&gt;&lt;li&gt;I realised that my views were "wrong", and pro-actively decided to change my views to fit better with what I perceived to be more right. For me, there was certainly an element of dissatisfaction with how my world view, but I didn't plan to throw out the baby &lt;span style="font-style: italic;"&gt;and&lt;/span&gt; the bathwater.
&lt;/li&gt;&lt;li&gt;I made no conscious choice to change, but instead a complicated sequence of events and people in my life led to where I am now. The more I think about it, the more likely it seems to me. Some people have been quite influential in my life, and without them I may well have followed a different path. In turn, the lives of those people have been shaped by others, in infinitely complex and different ways.&lt;/li&gt;&lt;li&gt;Some combination of the above
&lt;/li&gt;&lt;/ul&gt;The part that is not straightforward about the 2nd option is that, on the face of it, there's an implication that nobody is responsible for the person they in fact are. I disagree: I view myself as a standalone entity, and am responsible for both my opinions and my actions. Maybe this is the where the "veto" mechanism mentioned in one of the articles I linked to above comes in, such that each time my brain was about to allow a change to its view of the world, my conscious mind had the opportunity to veto it, and my &lt;span style="font-style: italic;"&gt;not&lt;/span&gt; vetoing a change is the only way I can express free will and "uniqueness".

Since this whole subject is damn near unprovable, I look at it as an interesting diversion, with no real purpose. That said, like most pointless discussions, I find it fascinating. What do you think - do we choose to develop our personalities and characters, or are those traits merely effects of complex causes?&lt;div style="clear:both; padding-bottom:0.25em"&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/CsZckyCzvyk" height="1" width="1"/&gt;</description>
      <pubDate>Tue, 16 Jan 2007 17:45:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/CsZckyCzvyk/free-will</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2007/01/16/free-will</feedburner:origLink></item>
    <item>
      <title>Happiness</title>
      <description>&lt;div style="clear:both;"&gt;&lt;/div&gt;After a discussion I had tonight with a friend, over [quite a few] drinks, regarding happiness, I got to thinking, how do you really define a concept as vague as happiness?

The dictionary.com definition is:
&lt;ol&gt;&lt;li&gt;the quality or state of being happy&lt;/li&gt;&lt;li&gt;good fortune; pleasure; contentment; joy&lt;/li&gt;&lt;/ol&gt;It seems to me that of the second definition, both good fortune and pleasure are externally derived, and probably an unstable basis for happiness. Contentment is a passive feeling, of having achieved what you want to or acquired the possessions you desire, etc.

This leaves joy, which I again looked up on dictionary.com, only to find that most of the definitions relate again to external influences. The same with happy.

Is our species really so dependent on others? I like to think that if I was stuck on the dark side of the moon, with only an antique Apollo moon buggy for company [yes, this was a scenario that was discussed tonight] it would still be possible for me to be happy. Maybe not happy in the dictionary sense.

Here's a question, and I wouldn't say I know the answer: Is it possible to be happy with other people if you are not happy on your own?&lt;div style="clear:both; padding-bottom:0.25em"&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/r81XAEiIZn4" height="1" width="1"/&gt;</description>
      <pubDate>Fri, 12 Jan 2007 01:35:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/r81XAEiIZn4/happiness</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2007/01/12/happiness</feedburner:origLink></item>
    <item>
      <title>Thief Steals Urinal</title>
      <description>&lt;div style="clear:both;"&gt;&lt;/div&gt;Just when you thought all the innovative thiefs were moving into the high-tech worlds of identity and digital theft, somebody comes along to remind you that there's still some old-skool crooks out there.

The BBC is &lt;a href="http://news.bbc.co.uk/1/hi/england/hampshire/6234445.stm"&gt;reporting that a man has stolen a urinal from a pub in Southampton&lt;/a&gt;. Apparently he went into the pub at about 5pm and ordered a half-pint of Fosters. He then went into the toilet several times, each time removing part of the white urinal bowl from the wall. It seems the guy did a highly professional job, turning off the stopcock and capping the pipe, and wiping his fingerprints from the door as he left (one wonders if he also wiped his fingerprints from his half-pint glass).

He left the pub with a bulging rucksack, and was caught on CCTV.

I like to imagine the conversation that may have happened between this man and a friend the night before:

Thief: "I have a nice house, but I'm worried it's missing something. The pièce de la resistance, so to speak."

Friend: "You mean like a banqueting hall, or a built-in cinema?"

Thief: "Actually I was thinking smaller-scale. Maybe a urinal in my bathroom."

Friend: "Why would you want a urinal in your bathroom?"

Thief: "For one thing, I wouldn't need to lift the seat back up after my girlfriend has used the bathroom. Also, I wouldn't need to remember to flush."

Friend: "Okay, so where do you buy urinals from?"

Thief: "Well, there weren't any on the Ikea website, but I did spot a nice one at the Royal Oak..."

Maybe.&lt;div style="clear:both; padding-bottom:0.25em"&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/50sfWdTQXec" height="1" width="1"/&gt;</description>
      <pubDate>Sat, 06 Jan 2007 11:57:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/50sfWdTQXec/thief-steals-urinal</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2007/01/06/thief-steals-urinal</feedburner:origLink></item>
    <item>
      <title>New Year's Resolutions</title>
      <description>&lt;div style="clear:both;"&gt;&lt;/div&gt;My new year's resolution: 1280 x 1024.

Sorry.

Although I agree with those who say that making resolutions at the beginning of a new year is a pointless activity - because if something's worth doing at the beginning of a year then it's worth doing all the time - I find it's a useful crutch.

Here's some of mine:
&lt;ul&gt;&lt;li&gt;Learn to play the oboe. I have a dream of sitting at the top of a mountain, guru-like, playing comforting melodies on the oboe to weary travellers. I shall call myself Sage Tim The Cold And Not That Wise.
&lt;/li&gt;&lt;li&gt;Expand my repertoire of recipes. There's thousands of different ingredients available in the average supermarket, and a number several orders of magnitude higher ways of combining those ingredients. And I know how to cook, oh, about 6 different dinners.
&lt;/li&gt;&lt;li&gt;Cycle to work. I've been promising this one to myself and others for a year now, but this time I'm, uhmm, slightly more serious.
&lt;/li&gt;&lt;li&gt;Enter some local 5k and 10k runs. I loved running these distances when preparing for the Nike 10k run in October, and I'd like to do some more competitive running, especially at the 5k distance, primarily because it's over nice and quickly.
&lt;/li&gt;&lt;/ul&gt;&lt;div style="clear:both; padding-bottom:0.25em"&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/83cqu93bwic" height="1" width="1"/&gt;</description>
      <pubDate>Wed, 03 Jan 2007 17:54:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/83cqu93bwic/new-years-resolutions</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2007/01/03/new-years-resolutions</feedburner:origLink></item>
    <item>
      <title>Our car game now has a car...</title>
      <description>&lt;div style="clear:both;"&gt;&lt;/div&gt;Thanks to Jason's work, we now have a vehicle in Torq2. It may turn out to just be a placeholder until we can find something better, but whichever way you look at it it's nicer than the cube I was using previously...

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp3.blogger.com/_Wywrr60_Hxc/RZbeHxDEjBI/AAAAAAAAAAY/yJZ251JhO5c/s1600-h/Screen0015.jpg"&gt;&lt;img style="cursor: pointer;" src="http://bp3.blogger.com/_Wywrr60_Hxc/RZbeHxDEjBI/AAAAAAAAAAY/yJZ251JhO5c/s400/Screen0015.jpg" alt="" id="BLOGGER_PHOTO_ID_5014439460130294802" border="0" /&gt;&lt;/a&gt;&lt;div style="clear:both; padding-bottom:0.25em"&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/22UPiS4hNdY" height="1" width="1"/&gt;</description>
      <pubDate>Sat, 30 Dec 2006 21:45:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/22UPiS4hNdY/our-car-game-now-has-a-car</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2006/12/30/our-car-game-now-has-a-car</feedburner:origLink></item>
    <item>
      <title>Vista - Failed to install ISKernel files</title>
      <description>&lt;div style="clear:both;"&gt;&lt;/div&gt;I've hit my first real snag with Vista - while trying to install Macromedia Contribute 3, I got this error: "1: Failed to install ISkernel files. Make sure you have appropriate privileges on this machine."

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp1.blogger.com/_Wywrr60_Hxc/RZRxExDEjAI/AAAAAAAAAAM/uiJx_JNnDEg/s1600-h/Screenshot.jpg"&gt;&lt;img style="cursor: pointer;" src="http://bp1.blogger.com/_Wywrr60_Hxc/RZRxExDEjAI/AAAAAAAAAAM/uiJx_JNnDEg/s400/Screenshot.jpg" alt="" id="BLOGGER_PHOTO_ID_5013756611869838338" border="0" /&gt;&lt;/a&gt;

Apparently you can get that if you try to run a .msi directly, which I was. If you use a setup.exe bootstrapper, there's no problems, but I didn't have one.

The simple answer, I discovered, is to build yourself one. All you need to do is create an app, I did mine in VB (because I accidentally clicked that project type instead of C#, I hasten to point out) but you could use anything, that simply starts the .msi process. Then build your app, and right-click on your exe in Explorer and choose "Run this program as an administrator" on the Compatibility tab. Hey presto!&lt;div style="clear:both; padding-bottom:0.25em"&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/rJWABoCoODA" height="1" width="1"/&gt;</description>
      <pubDate>Fri, 29 Dec 2006 01:29:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/rJWABoCoODA/vista---failed-to-install-iskernel-files</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2006/12/29/vista---failed-to-install-iskernel-files</feedburner:origLink></item>
    <item>
      <title>Things I wonder about</title>
      <description>&lt;div style="clear:both;"&gt;&lt;/div&gt;Some things I'm thinking about today:
&lt;ul&gt;&lt;li&gt;What would it be like to "hear" colour instead of see it? I read something recently that suggested that bats may be able to recognise specific textures on objects, through their super-sensitive hearing; so this could be thought of as "hearing colour". Thinking about this reminds me of when I tried to get my head around non-base-10 number systems at school.&lt;/li&gt;&lt;li&gt;Nobody who has ever watched The Shawshank Redemption has gone on to become a suicide bomber. Prove me wrong!&lt;/li&gt;&lt;li&gt;Why is it that so often arguments end up being two-sided? Why is it so common that there are only two sides to an argument? I would have thought it's far more likely, for anything complex, that there would be more than two points of view. I suspect this is something to do with the attention span of the average TV viewer. Take a few examples: evolution / creation, Republican / Democrat, PC / Mac. The English political system is an example of where the public have managed to cope with&lt;span style="font-weight: bold;"&gt; &lt;/span&gt;&lt;span style="font-style: italic;"&gt;three&lt;/span&gt; major political parties: Labour, Tory and LibDem. But even there, politician's views (and, correspondingly, the views of the people they represent) are probably more of a continuous, not discrete spectrum. My point is this: given any argument, why can't we as individual people have our own individual opinions, without feeling the need to give ourselves a label, such as "I'm an atheist". Labels aren't that interesting - complex individual opinion, on the other hand, is.
&lt;/li&gt;&lt;/ul&gt;&lt;div style="clear:both; padding-bottom:0.25em"&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/zESGEaNFYxQ" height="1" width="1"/&gt;</description>
      <pubDate>Wed, 27 Dec 2006 15:57:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/zESGEaNFYxQ/things-i-wonder-about</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2006/12/27/things-i-wonder-about</feedburner:origLink></item>
    <item>
      <title>Vista: Clear, Connected, Clumsy</title>
      <description>&lt;p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;I&amp;#39;ve bitten the bullet and installed Windows Vista. I wasn&amp;#39;t expecting much, after the fiasco of its lengthy development cycle, but I&amp;#39;ve been pleasantly surprised, amongst the irritations.&lt;/p&gt;

&lt;p&gt;It feels much more responsive than XP; although User Account Control goes some way to offsetting this with its constant requests for permission. I&amp;#39;m hoping UAC will be less necessary once I&amp;#39;ve got everything setup.&lt;/p&gt;

&lt;p&gt;The startup time of Vista is quicker on my machine than XP; applications start faster, and redraw quicker. The 3D-hardware-accelerated compositing engine appears to be working well. I&amp;#39;m not yet convinced about the Sidebar but I suppose it just needs its killer app.&lt;/p&gt;

&lt;p&gt;I like that the self-obsessed plethora of &amp;quot;My ...&amp;quot; has been removed, and rationalised into a much nicer directory structure of &amp;quot;Pictures&amp;quot;, &amp;quot;Music&amp;quot;, &amp;quot;Documents&amp;quot;, etc. However, I&amp;#39;ve unsuccessfully tried to access the &amp;quot;SendTo&amp;quot; folder under my user profile, because I like to add a shortcut to Notepad in there; this kind of thing reminds me that Vista is, in fact, a genuinely new version of Windows.&lt;/p&gt;

&lt;p&gt;I&amp;#39;ve also installed Office 2007 and as you&amp;#39;d expect this works smoothly with Vista. For some odd reason it doesn&amp;#39;t use the Vista theme though! Then again, Microsoft rarely follow their own UI guidelines.&lt;/p&gt;

&lt;p&gt;I find Vista slightly clumsy and unpolished, which I would say is unusual for a Microsoft product. I can&amp;#39;t put my finger on any one feature that I don&amp;#39;t like, but as a whole it seems like it may have been rushed out a little too soon. Maybe it&amp;#39;s just the little things like icon heights and padding in Windows Explorer.&lt;/p&gt;

&lt;p&gt;Or maybe I&amp;#39;m just a dork.&lt;div style="clear:both; padding-bottom:0.25em"&gt;&lt;/div&gt;&lt;p class="blogger-labels"&gt;Labels: &lt;a rel='tag' href="http://www.roastedamoeba.com/blog/labels/Windows Vista.xml"&gt;Windows Vista&lt;/a&gt;&lt;/p&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/Pn4-9k29XdM" height="1" width="1"/&gt;</description>
      <pubDate>Wed, 27 Dec 2006 10:11:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/Pn4-9k29XdM/vista-clear-connected-clumsy</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2006/12/27/vista-clear-connected-clumsy</feedburner:origLink></item>
    <item>
      <title>12 Days of Christmas</title>
      <description>&lt;p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;Lest I be accused of not sharing some Christmas cheer, I thought I&amp;#39;d make up for my previous grumpy posts by singing &amp;quot;The 12 Days of Christmas&amp;quot; to all you lovely folks. Because I try not to stick with tradition, I&amp;#39;m going to sing it in the key of C#:
&lt;pre&gt;List&lt;string&gt; pGiftsReceived = new List&lt;string&gt;();
for (int nDay = 1; nDay &amp;lt;= 12; nDay++)
{
  Console.WriteLine(&amp;quot;On the &amp;quot; + ToOrdinal(nDay) + &amp;quot; day of Christmas,&amp;quot;);
  Console.WriteLine(&amp;quot;my true love sent to me&amp;quot;);&lt;/p&gt;

&lt;p&gt;switch (nDay)
  {
    case 1 : pGiftsReceived.Add(&amp;quot;And a partridge in a pair tree.&amp;quot;); break;
    case 2 : pGiftsReceived.Add(&amp;quot;Two turtle doves,&amp;quot;); break;
    case 3 : pGiftsReceived.Add(&amp;quot;Three French hens,&amp;quot;); break;
    case 4 : pGiftsReceived.Add(&amp;quot;Four calling birds,&amp;quot;); break;
    case 5 : pGiftsReceived.Add(&amp;quot;Five golden rings,&amp;quot;); break;
    case 6 : pGiftsReceived.Add(&amp;quot;Six geese a-laying,&amp;quot;); break;
    case 7 : pGiftsReceived.Add(&amp;quot;Seven swans a-swimming,&amp;quot;); break;
    case 8 : pGiftsReceived.Add(&amp;quot;Eight maids a-milking,&amp;quot;); break;
    case 9 : pGiftsReceived.Add(&amp;quot;Nine ladies dancing,&amp;quot;); break;
    case 10 : pGiftsReceived.Add(&amp;quot;Ten lords a-leaping,&amp;quot;); break;
    case 11 : pGiftsReceived.Add(&amp;quot;Eleven pipers piping,&amp;quot;); break;
    case 12 : pGiftsReceived.Add(&amp;quot;Twelve drummers drumming,&amp;quot;); break;
  }&lt;/p&gt;

&lt;p&gt;for (int j = pGiftsReceived.Count - 1; j &amp;gt;= 0; j--)
  {
    string sGift = pGiftsReceived[j];
    if (nDay == 1 &amp;amp;&amp;amp; j == 0) sGift = sGift.Substring(4);
    Console.WriteLine(sGift);
  }&lt;/p&gt;

&lt;p&gt;Console.WriteLine();
}```
[Although I&amp;#39;m slightly embarassed to admit it (and I run a serious risk of receiving accusations of being a &amp;quot;dork&amp;quot; from certain quarters&amp;quot;) I have actually compiled and run this code.]&lt;div style="clear:both; padding-bottom:0.25em"&gt;&lt;/div&gt;&lt;p class="blogger-labels"&gt;Labels: &lt;a rel='tag' href="http://www.roastedamoeba.com/blog/labels/dork.xml"&gt;dork&lt;/a&gt;&lt;/p&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/F7CVWONtIXY" height="1" width="1"/&gt;</description>
      <pubDate>Fri, 22 Dec 2006 00:15:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/F7CVWONtIXY/-days-of-christmas</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2006/12/22/-days-of-christmas</feedburner:origLink></item>
    <item>
      <title>Why I Am Not A Christian</title>
      <description>&lt;div style="clear:both;"&gt;&lt;/div&gt;I'm finally getting round to reading the text of a lecture by Bertrand Russell, titled "Why I Am Not A Christian." I was sent the link a while ago by a friend, but I guess now that it's Christmas, and the shops are filled with brussel sprouts and the sound of Cliff Richards' voice (&lt;a href="http://eclectech.co.uk/notcliff.php"&gt;look here&lt;/a&gt; for a song that's &lt;span style="font-weight: bold;"&gt;not&lt;/span&gt; by Cliff Richards), I feel compelled to find some sanity.

To summarise very briefly, here are his main points. First, he covers some arguments often used for the existence of God:
&lt;ul&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;The First-cause Argument&lt;/span&gt;. Everything we see in this world has a cause, and if you go back in the chain of causes, eventually you must come to a First Cause, and we call that First Cause "God". Russell points out that this is circular; the question "Who made me?" cannot be answered , since it immediately suggests the next question "Who made God?" If everything has a cause, then God must have a cause. So this argument doesn't really help.&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;The Natural-law Argument&lt;/span&gt;. I don't think this argument is used very much anymore, but it used to be held that because there is a natural order to everything in the universe, it must have been God that made it that way. In other words God, the Lawgiver, laid down natural laws for His universe. This is a confusion of the difference between human and natural laws. Human laws are created to control the behaviour of humans; natural laws simply describe the behaviour how things work. Most of those so-called natural laws have since been shown to be chance.&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;The Argument from Design&lt;/span&gt;. Russell was speaking in 1927, and so didn't have all the latest arguments that we have today, but his gist is that the world merely *looks* designed because that is the natural result of Darwinian evolution. He also remarks that, if this world really is the best that an omnipotent, omniscient Creator can come up with, then it's astonishing.&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;The Moral Arguments for Deity.&lt;/span&gt; Immanuel Kant's moral argument for the existence of God, at least in one of its forms, is this: There would be no right or wrong unless God existed. Russell says he is not concerned with whether there is a difference between right and wrong, but rather, if you are quite sure that there is a difference, is that due to God's decree? If it is, then for God Himself there is no difference, and it doesn't mean anything to say that God is good. In order to say that, you would need an independent means of deciding goodness, outside of God, which again takes you on a circular path. I would add that it's doubtful whether morality came from religion at all, given the often violent history of religion, and the fact that all across the world there is a general consensus on morality that spans religions, and many other reasons too.
&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;The Argument for the Remedying of Injustice&lt;/span&gt;. Since there is great injustice in the world, and the good suffer and wicked prosper, if you are going to have justice in the universe as a whole you have to suppose a future life to redress the balance of life here on earth (so the argument goes). Therefore there must be a God, and a Heaven and Hell. But if you take this world as a statistical sample, and that's pretty much all we humans can do, then you'd have to suppose that the universe as a whole is unjust.&lt;/li&gt;&lt;/ul&gt;So far, these arguments have been intellectual, and of course most people are not moved by intellect. Some believe because they have been taught from infancy to do so, and some believe because they need to feel that they have a sort of big brother looking out for them.

Then Russell discusses the character of Christ. Christ said
&lt;blockquote&gt;"Resist not evil, but whosoever shall smite thee on thy right cheek, turn to him the other also."
&lt;/blockquote&gt;Lao-tse and Budda said the same thing some 500 or 600 years before Christ. In Russell's opinion, Christians today do not actually follow this, for the most part. My own opinion, as the son of believing parents, is that some Christians really do follow this, although certainly not all. Either way, Christ was certainly not alone in these kind of moral exhortations.

Another of Christ's sayings does not appear to be popular in the law courts of &lt;span style="font-style: italic;"&gt;any&lt;/span&gt; country:
&lt;blockquote&gt;"Judge not lest ye be judged."&lt;/blockquote&gt;Russell says he is not so concerned with the historical question - Christ may or may not have existed; if He did we don't know anything about Him. So, taking the Gospel narrative on its own merit, there are some things that do not seem very wise. For example, Jesus clearly believed that His second coming would occur within the lifetimes of those living at that time:
&lt;blockquote&gt;"Ye shall not have gone over the cities of Israel till the Son of Man be come."

"There are some standing here which shall not taste death till the Son of Man comes into His kingdom."
&lt;/blockquote&gt;These do not seem superlatively wise things to say, given that as near as we can tell, we're still here.

Then Russell covers the vindictive nature of Christ's response to those who did not like to His preaching:
&lt;blockquote&gt;"Ye serpents, ye generation of vipers, how can ye escape the damnation of Hell."
&lt;/blockquote&gt;It's perhaps not the best tone, and some of Christ's other remarks ("Whosoever speaketh against the Holy Ghost it shall not be forgiven him neither in this World nor in the world to come") have caused untold misery to people who believed they commited that sin and would never be forgiven.

Jesus repeats again and again that hell-fire is a punishment for sin: this sounds like a doctrine of cruelty. In fact, some of the actual quotations have been taken and (mis-)used to cause literal cruel torture.

Now we come to the emotional argument: people would not be virtuous without religion; we would all be wicked if we did not hold to the Christian faith. As Russell points out, the people who have held to it have been for the most part extremely wicked. In the so-called ages of faith, when men really did believe 100% of the Christian faith, there was the Inquisition; millions of women were burned as witches; every kind of cruelty was practiced upon all sorts of people in the name of religion.

Here Russell makes a strong statement and I'd like to reproduce it here verbatim:
&lt;blockquote&gt;"Every single bit of progress in humane feeling, every improvement in the criminal law, every step toward the diminution of war, every step toward better treatment of the coloured races, or every mitigation of slavery, every moral progress that there has been in the world, has been consistently opposed by the organised churches of the world. I say quite deliberately that the Christian religion, as organised in its churches, has been and still is the principal enemy of moral progress in the world."
&lt;/blockquote&gt;I have little choice but to offer a hearty "Amen brother!" Since Russell's time the churches of the world have perhaps mellowed, and do not offer the obstruction to progress that they once did. But between their arguments about whether women should be "allowed" (how patronising!) to be priests, or whether gay men can get above a certain rank in the clergy, it doesn't seem to me that they have helped much, either.

I'll finish with a wonderful quote from, of course, Bertrand Russell:
&lt;blockquote&gt;"A good world needs knowledge, kindliness, and courage; it does not need a regretful hankering after the past or a fettering of the free intelligence by the words uttered long ago by ignorant men. It needs a fearless outlook and a free intelligence. It needs hope for the future, not looking back all the time toward a past that is dead, which we trust will be far surpassed by the future that our intelligence can create." &lt;/blockquote&gt;
You can &lt;a href="http://users.drew.edu/%7Ejlenz/whynot.html"&gt;read the lecture text yourself here&lt;/a&gt;.

Sorry for the lengthy post!&lt;div style="clear:both; padding-bottom:0.25em"&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/JTkSLSvLWAU" height="1" width="1"/&gt;</description>
      <pubDate>Thu, 21 Dec 2006 22:31:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/JTkSLSvLWAU/why-i-am-not-a-christian</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2006/12/21/why-i-am-not-a-christian</feedburner:origLink></item>
    <item>
      <title>Zooomr</title>
      <description>&lt;div style="clear:both;"&gt;&lt;/div&gt;This is a slightly pointless post, but apparently it's going to allow me to sign up for a free Zooomr Pro account.

&lt;div style="width: 240px; text-align: right;"&gt;&lt;a href="http://beta.zooomr.com/photos/28636@Z01/551833/" title="Zooomr Photo Sharing :: Photo Sharing"&gt;&lt;img src="http://static.zooomr.com/images/551833_0272c0a708_m.jpg" alt="DSC_3039" style="border: 1px solid rgb(0, 0, 0);" border="0" height="159" width="240" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="clear:both; padding-bottom:0.25em"&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/jHPxzKb04Yc" height="1" width="1"/&gt;</description>
      <pubDate>Thu, 21 Dec 2006 13:22:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/jHPxzKb04Yc/zooomr</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2006/12/21/zooomr</feedburner:origLink></item>
    <item>
      <title>Packing</title>
      <description>&lt;p&gt;This is a little like those painful moments when a relative gets back from a long holiday, and you know you&amp;#39;re in for a spell of sitting on the sofa listening to them droning on and on while showing you their endless rolls of film, or more unfortunately these days, endless memory cards of photos.&lt;/p&gt;

&lt;p&gt;Well, welcome to Tim&amp;#39;s equivalent: snippets of holiday video carefully timed such that you think I&amp;#39;ve forgotten about it, but then here comes another one!&lt;/p&gt;

&lt;p&gt;&lt;video src="/assets/videos/packing.mp4" type="video/mp4" width="400" height="226"&gt;&lt;/video&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/zGexqGYnPtA" height="1" width="1"/&gt;</description>
      <pubDate>Sat, 16 Dec 2006 00:39:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/zGexqGYnPtA/packing</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2006/12/16/packing</feedburner:origLink></item>
    <item>
      <title>XMLSpy irritations</title>
      <description>&lt;div style="clear:both;"&gt;&lt;/div&gt;For a project at work, I need to automate Altova XMLSpy using its API. I want to "flatten" an XSD, which includes other XSDs, into a single XSD that includes all the element definitions inline, without any duplications.

It looked like a simple job - Altova have documented their API pretty well, and it's quite clean and easy to use. However, I spent 3 hours yesterday wondering why, when I added or removed nodes, nothing happened.

It turns out - as helpfully documented in a rather hidden place - that you must switch to the Grid view before you can use XMLData objects to programmatically alter the document tree. So when you open a document, you must do this (assuming you're writing in C#):
&lt;blockquote style="font-family: courier new;"&gt;&lt;span style="font-size:85%;"&gt;Document lMyNewXsd = lApp.Documents.NewFile("test.xsd", "xsd");
lMyNewXsd.SwitchViewMode(SPYViewModes.spyViewGrid);&lt;/span&gt;&lt;/blockquote&gt;Grr - I do wish gotcha's like this were documented more clearly!&lt;div style="clear:both; padding-bottom:0.25em"&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/xNQ4Kjga-1Q" height="1" width="1"/&gt;</description>
      <pubDate>Wed, 13 Dec 2006 12:47:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/xNQ4Kjga-1Q/xmlspy-irritations</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2006/12/13/xmlspy-irritations</feedburner:origLink></item>
    <item>
      <title>Progress on the coloured squares</title>
      <description>&lt;div style="clear:both;"&gt;&lt;/div&gt;After repetitively banging my head against a wall (and then having a frustrating time with game programming), I'm finally starting to make some progress with my coloured squares. Or Torq2, as I like to call it.

Soon I'll be saying "we" are making progress, because a friend has just joined me on the project - which makes it, I hope, marginally more likely that the game will be finished one day. We've previously worked together on the little known driving game known affectionately, to about 3 people, as "MouldCar", and not known at all by anybody else.

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/x/blogger2/2786/1628/1600/18119/Screen0010.jpg"&gt;&lt;img style="cursor: pointer;" src="http://photos1.blogger.com/x/blogger2/2786/1628/400/333934/Screen0010.jpg" alt="" border="0" /&gt;&lt;/a&gt;

Anyway, here's a screenshot of the current status of Torq2. It really doesn't look like much - but that actually represents the bulk of the work for getting the terrain engine up and running. It's quite scalable and will be able to support huge landscapes through an elegant LOD scheme.&lt;div style="clear:both; padding-bottom:0.25em"&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/qxaGqF8WZ5Y" height="1" width="1"/&gt;</description>
      <pubDate>Thu, 30 Nov 2006 01:14:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/qxaGqF8WZ5Y/progress-on-the-coloured-squares</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2006/11/30/progress-on-the-coloured-squares</feedburner:origLink></item>
    <item>
      <title>Christmas cheer</title>
      <description>&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;span style="font-size:100%;"&gt;Is it just me who finds &lt;a href="http://news.bbc.co.uk/1/hi/uk/6184722.stm"&gt;this story&lt;/a&gt; amusing? 10,000 Asda Christmas trees are being recalled due to a potentially lethal electrical problem. The spokesman said:&lt;/span&gt;&lt;span style="font-size:100%;"&gt;
&lt;blockquote&gt;"I think the important thing is just to illustrate the three products that this has affected - no other products or Christmas trees or fairy lights are affected in any shape or form."&lt;/blockquote&gt;Yes, I agree, Mr. Asda, that is indeed the important thing here. The important thing is certainly not, for example, that in 25 years, children will have forgotten that Christmas trees actually used to be made of pine needles and bark, and required soil. Or that, as a symbol, the Christmas tree has its origin in pagan cultures that pre-date Christianity by quite some time. Then again, that last one is more directed at Christmas itself - an odd mish-mash of a holiday that pretends to be Christian but was heavily influenced by earlier festivals.

Incidentally, indulging in a small amount of research has indicated to me that there are several reasons for actually wanting a fake, sorry, artificial, Christmas tree:
&lt;/span&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;They are necessary in some rented homes due to the potential fire danger from a dried-out real tree, leading to some landlords banning them&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;They may be necessary for people who have conifer allergy&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;span style="font-size:100%;"&gt;I suppose, grudgingly, I should allow these special cases, but that kind of thing does set me off on the usual "modern world" grumble session.

I enjoyed reading about the first "designer" Christmas trees that were sold in the 1950s and 60s. They were made with aluminium-coated paper attached to metal rods; it doesn't take a leap of imagination to realise that if you put a light too close to the paper it was rather flammable. Fortunately for us all, Christmas technology has moved on a lot since then.

Before anybody says that my hankering for the old days of real Christmas trees is not environmentally friendly, I would like to point out that artificial trees are often made out of PVC, a toxic material that is often combined with lead. They are non-recyclable. Real trees, on the other hand, are completely recyclable, reduce the amount of carbon dioxide in the atmosphere during growth, and the crops are generally replanted after cutting.&lt;/span&gt;&lt;div style="clear:both; padding-bottom:0.25em"&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/wdw9Q7-G-MA" height="1" width="1"/&gt;</description>
      <pubDate>Sun, 26 Nov 2006 03:40:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/wdw9Q7-G-MA/christmas-cheer</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2006/11/26/christmas-cheer</feedburner:origLink></item>
    <item>
      <title>When is a choice not a choice?</title>
      <description>&lt;p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;In talking to a good friend of mine last night, who was raised in a similar environment to me, we reached the (fairly obvious) conclusion that you can&amp;#39;t make a choice unless you have two paths open before you.&lt;/p&gt;

&lt;p&gt;To put it more specifically: if you parents subscribe to a particular religion, such as Christianity, and raise you as a Christian, with the expectation that you will &amp;quot;become&amp;quot; a Christian at some point (hopefully early on) in your life, without really giving you another option, then can you really be a Christian? Because in those circumstances, &amp;quot;becoming&amp;quot; a Christian is not a real choice - it&amp;#39;s more of an inevitability. And yet most Christians would agree that choice is something that God grants to humans.&lt;/p&gt;

&lt;p&gt;It seems to me a paradox - if you are raised by Christian parents to be Christian, can you truly be a Christian? I would genuinely like to hear an argument against this conclusion, if there is one.&lt;div style="clear:both; padding-bottom:0.25em"&gt;&lt;/div&gt;&lt;p class="blogger-labels"&gt;Labels: &lt;a rel='tag' href="http://www.roastedamoeba.com/blog/labels/religion.xml"&gt;religion&lt;/a&gt;&lt;/p&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/hVakAsyQaYs" height="1" width="1"/&gt;</description>
      <pubDate>Fri, 24 Nov 2006 09:40:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/hVakAsyQaYs/when-is-a-choice-not-a-choice</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2006/11/24/when-is-a-choice-not-a-choice</feedburner:origLink></item>
    <item>
      <title>They don't call me Tim "Michael Schumacher" Jones for nothing... actually they don't call me that at all</title>
      <description>&lt;div style="clear:both;"&gt;&lt;/div&gt;Anyway, I didn't win, so I didn't live up to my middle name. I came a close second, which simply isn't good enough! Next time, perhaps. I've just got back from my company's annual go-karting outing (otherwise known as "ram as many managers as you can into the tyres before you get your P45").

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger2/2786/1628/1600/DSC00591.jpg"&gt;&lt;img style="cursor: pointer;" src="http://photos1.blogger.com/blogger2/2786/1628/400/DSC00591.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;div style="clear:both; padding-bottom:0.25em"&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/JZKTJz7VAFI" height="1" width="1"/&gt;</description>
      <pubDate>Thu, 16 Nov 2006 00:52:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/JZKTJz7VAFI/they-dont-call-me-tim-michael-schumacher-jones</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2006/11/16/they-dont-call-me-tim-michael-schumacher-jones</feedburner:origLink></item>
    <item>
      <title>Flaming Lips</title>
      <description>&lt;p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger2/2786/1628/1600/DSC00585.jpg"&gt;&lt;img style="cursor: pointer;" src="http://photos1.blogger.com/blogger2/2786/1628/400/DSC00585.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Another post, another gig! This time it was the Flaming Lips - and they seemingly spared no expense to put on a great show. Psychedelic lighting, thousands of balloons, and shirt-vibrating volume were the main ingredients, which worked well with their slightly oddball music. I thoroughly enjoyed it, if only because I got to play with exceedingly large balloons.&lt;/p&gt;

&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger2/2786/1628/1600/DSC00569.jpg"&gt;&lt;img style="cursor: pointer;" src="http://photos1.blogger.com/blogger2/2786/1628/400/DSC00569.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger2/2786/1628/1600/DSC00567.jpg"&gt;&lt;img style="cursor: pointer;" src="http://photos1.blogger.com/blogger2/2786/1628/400/DSC00567.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger2/2786/1628/1600/DSC00581.jpg"&gt;&lt;img style="cursor: pointer;" src="http://photos1.blogger.com/blogger2/2786/1628/400/DSC00581.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;div style="clear:both; padding-bottom:0.25em"&gt;&lt;/div&gt;&lt;p class="blogger-labels"&gt;Labels: &lt;a rel='tag' href="http://www.roastedamoeba.com/blog/labels/Flaming Lips.xml"&gt;Flaming Lips&lt;/a&gt;, &lt;a rel='tag' href="http://www.roastedamoeba.com/blog/labels/gig.xml"&gt;gig&lt;/a&gt;&lt;/p&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/tAZ95h78gQ8" height="1" width="1"/&gt;</description>
      <pubDate>Wed, 15 Nov 2006 00:28:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/tAZ95h78gQ8/flaming-lips</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2006/11/15/flaming-lips</feedburner:origLink></item>
    <item>
      <title>Coloured squares</title>
      <description>&lt;div style="clear:both;"&gt;&lt;/div&gt;Woo, coloured squares! I'm changing direction slightly for Torq2. I'm starting from scratch, which if you know me, you'll know is something I like to do quite frequently. I did have a terrain implemented using geomipmapping, but I'm changing to the new and shiny geometry clipmapping algorithm. I've been working on it for 2 hours so far and all I've got to show for it is coloured squares:

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/3747/1168/1600/GeoClipMapping%20001.jpg"&gt;&lt;img style="cursor: pointer;" src="http://photos1.blogger.com/blogger/3747/1168/400/GeoClipMapping%20001.jpg" alt="" border="0" /&gt;&lt;/a&gt;

I'm implementing geometry clipmapping (hereafter geoclipmapping) from the &lt;a href="http://research.microsoft.com/%7Ehoppe/geomclipmap.pdf"&gt;Asirvatham / Hoppe&lt;/a&gt; paper, and I'm planning to blog about any obstacles I come across and hopefully overcome.&lt;div style="clear:both; padding-bottom:0.25em"&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/EmVAkX78jdk" height="1" width="1"/&gt;</description>
      <pubDate>Fri, 20 Oct 2006 00:24:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/EmVAkX78jdk/coloured-squares</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2006/10/20/coloured-squares</feedburner:origLink></item>
    <item>
      <title>Goo Goo Dolls</title>
      <description>&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/3747/1168/1600/DSC00541.0.jpg"&gt;&lt;img style="cursor: pointer;" src="http://photos1.blogger.com/blogger/3747/1168/400/DSC00541.0.jpg" alt="" border="0" /&gt;&lt;/a&gt;

Just come back from the Goo Goo Dolls gig at the Shepherd's Bush Empire. Man do they rock! I've been to some good gigs before by some great bands, but I think this has to be my favourite gig so far.

They played a lot of the old favourites - Slide, Broadway, Name; and some of the newer songs: Tucked Away, Smash, Stay With You (the opener), Let Love In. However, when they strummed the first few chords of Iris the crowd went absolutely wild - great stuff.

The encore was Become, a beautiful song that ends their most recent album, and then Give a Little Bit - probably my favourite song on Let Love In.

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/3747/1168/1600/DSC00539.0.jpg"&gt;&lt;img style="cursor: pointer;" src="http://photos1.blogger.com/blogger/3747/1168/400/DSC00539.0.jpg" alt="" border="0" /&gt;&lt;/a&gt;

Altogether a fun evening - I really should go to gigs more often.&lt;div style="clear:both; padding-bottom:0.25em"&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/DbjGCQseEeA" height="1" width="1"/&gt;</description>
      <pubDate>Mon, 16 Oct 2006 00:04:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/DbjGCQseEeA/goo-goo-dolls</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2006/10/16/goo-goo-dolls</feedburner:origLink></item>
    <item>
      <title>Little preview of my coast to coast video</title>
      <description>&lt;p&gt;This is mainly here for my own benefit - it&amp;#39;s not from the actual edit, this is more a proof of concept of the slow motion. What do you think? The version here isn&amp;#39;t very high quality so it will look better on DVD, I hope.&lt;/p&gt;

&lt;p&gt;&lt;video src="/assets/videos/coast-to-coast-2006-preview.mp4" type="video/mp4" width="400" height="240"&gt;&lt;/video&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/phKPnAdPcJw" height="1" width="1"/&gt;</description>
      <pubDate>Tue, 10 Oct 2006 21:01:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/phKPnAdPcJw/little-preview-of-my-coast-to-coast-video</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2006/10/10/little-preview-of-my-coast-to-coast-video</feedburner:origLink></item>
    <item>
      <title>Spiders</title>
      <description>&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/3747/1168/1600/DSC_2491.jpg"&gt;&lt;img style="cursor: pointer;" src="http://photos1.blogger.com/blogger/3747/1168/400/DSC_2491.jpg" alt="" border="0" /&gt;&lt;/a&gt;

I noticed a spider on my bathroom wall last night (not a particularly pretty one, I think you'll agree). It didn't move at all, and I realised I don't actually know how spiders sleep, if indeed they do. So I decided to find out, and since I'm sure that you're all just as interested as I am in this, I decided to share my findings with you. (Just for accuracy, the spider was in fact on a wall, but I've rotated the pictures through 90 degrees just for the convenience of a landscape format.)

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/3747/1168/1600/DSC_2491%202.jpg"&gt;&lt;img style="cursor: pointer;" src="http://photos1.blogger.com/blogger/3747/1168/400/DSC_2491%202.jpg" alt="" border="0" /&gt;&lt;/a&gt;

The simple answer to the question "do spiders sleep" is, apparently, that nobody really knows. All animals have some sort of circadian rhythm - a daily activity/inactivity cycle. However, nobody's ever done any studies to measure how long spiders spend in each state, and at what times different species do it.

Scientists do know that in cold climates, spiders are able to go into a form of hibernation, where they bring their legs into their body and remain huddled in a shelter for the winter.

It is thought that if they can shut their bodies down for long periods, they may be able to do the same for shorter periods in their daily cycle, which could be thought of as sleep.

So now you know.

Oh, and for the record, it seems that &lt;a href="http://www.straightdope.com/mailbag/mspidereat.html"&gt;you're not going to swallow any spiders in your sleep&lt;/a&gt;, despite the urband legend telling you otherwise.&lt;div style="clear:both; padding-bottom:0.25em"&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/-PjGxEHz2HU" height="1" width="1"/&gt;</description>
      <pubDate>Sun, 01 Oct 2006 11:07:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/-PjGxEHz2HU/spiders</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2006/10/01/spiders</feedburner:origLink></item>
    <item>
      <title>100000 miles - woo!</title>
      <description>&lt;div style="clear:both;"&gt;&lt;/div&gt;My little Peugeot 106 has now travelled 100000 miles since it was manufactured (or since the odometer got reset by a dodgy dealer, but I don't like to be accusatory on my blog). I believe this is the traditional point at which it requires a new cylinder head gasket, or a new engine, or something like that. Anyway, I caught the whole exciting event on my mobile phone's camera - I'm not completely sure of the legality of using a camera while heading down the A3 at 50mph, so if there's any police reading this, my real name is definitely not Tim Jones.

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/3747/1168/1600/DSC00534.jpg"&gt;&lt;img style="cursor: pointer;" src="http://photos1.blogger.com/blogger/3747/1168/400/DSC00534.jpg" alt="" border="0" /&gt;&lt;/a&gt;

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/3747/1168/1600/DSC00535.jpg"&gt;&lt;img style="cursor: pointer;" src="http://photos1.blogger.com/blogger/3747/1168/400/DSC00535.jpg" alt="" border="0" /&gt;&lt;/a&gt;

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/3747/1168/1600/DSC00536.jpg"&gt;&lt;img style="cursor: pointer;" src="http://photos1.blogger.com/blogger/3747/1168/400/DSC00536.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;div style="clear:both; padding-bottom:0.25em"&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/vEzePKyGJ-o" height="1" width="1"/&gt;</description>
      <pubDate>Sun, 01 Oct 2006 01:14:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/vEzePKyGJ-o/-miles---woo</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2006/10/01/-miles---woo</feedburner:origLink></item>
    <item>
      <title>Changing the LCD screen on a Sony Ericsson K750i</title>
      <description>&lt;div style="clear:both;"&gt;&lt;/div&gt;It seems that when you have your mobile phone in a carrier bag, and that carrier bag is being used as a base marker in a game of rounders, and one of the players (mentioning no names, Dene) descends with some speed onto the carrier bag, your mobile phone may not survive intact.

I thought at first the whole phone was broken, but it turned out that it was fully functioning except for the rather unhealthy looking screen. So without further ado, I bought a replacement LCD screen from a Hong Kong seller on eBay for £7.49 (plus a rather hefty delivery charge of £10). Impressively, it arrived today, only 4 days after I ordered it.

The only thing that wasn't included in the package was a set of instructions. So I've just spent the last hour pulling my phone apart, fitting the new screen, and then doing a lot of hoping that it would work when I reassembled everything.

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/3747/1168/1600/DSC_2472.jpg"&gt;&lt;img style="cursor: pointer;" src="http://photos1.blogger.com/blogger/3747/1168/400/DSC_2472.jpg" alt="" border="0" /&gt;&lt;/a&gt;

For future reference, this page has a great set of pictures that helped me:
&lt;a href="http://forums.se-nse.net/index.php?showtopic=1195"&gt;http://forums.se-nse.net/index.php?showtopic=1195&lt;/a&gt;

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/3747/1168/1600/DSC_2477.jpg"&gt;&lt;img style="cursor: pointer;" src="http://photos1.blogger.com/blogger/3747/1168/400/DSC_2477.jpg" alt="" border="0" /&gt;&lt;/a&gt;

After putting it back together, I'm happy to say it works!&lt;div style="clear:both; padding-bottom:0.25em"&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/FQ5J_jlIui0" height="1" width="1"/&gt;</description>
      <pubDate>Sat, 30 Sep 2006 00:10:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/FQ5J_jlIui0/changing-the-lcd-screen-on-a-sony-ericsson</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2006/09/30/changing-the-lcd-screen-on-a-sony-ericsson</feedburner:origLink></item>
    <item>
      <title>Writing your own OS with Visual Studio 2005</title>
      <description>&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;a href="http://www.managed-world.com/default.aspx"&gt;Jason Olson&lt;/a&gt; has just posted an interesting article about &lt;a href="http://www.managed-world.com/WritingYourOwnOSWithVisualStudio2005.aspx"&gt;writing your own OS with Visual Studio 2005&lt;/a&gt;. When I have a spare year or two, I might have a try!&lt;div style="clear:both; padding-bottom:0.25em"&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/D3knOijoQqA" height="1" width="1"/&gt;</description>
      <pubDate>Mon, 11 Sep 2006 13:01:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/D3knOijoQqA/writing-your-own-os-with-visual-studio</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2006/09/11/writing-your-own-os-with-visual-studio</feedburner:origLink></item>
    <item>
      <title>DVD Taxonomy</title>
      <description>&lt;div style="clear:both;"&gt;&lt;/div&gt;So I've just united the DVDs I previously had in boxes, with the DVDs I had out on shelves, to make my collection whole again. This always results in me re-thinking the taxonomic principles of classification that I'm using. Prior to this particular re-ordering, I have used genre, director, actor, and even year of release to order my DVDs on the shelf. This time I went for the simple alphabetic approach. A cop out, you say? That may be true, but it's not as trivial as it seems.

For example, in what order would you place "Bad Boys 2" and "Badlands"? For this you'd need to decide on the particular lexicographical ordering you want to use. There are three options:
&lt;ol&gt;   &lt;li&gt;Remove spaces between words for the purposes of ordering. This would give us "BadBoys2" and "Badlands", and assuming we're not using case-sensitive ordering, "BadBoys2" would come first on the shelf.&lt;/li&gt;   &lt;li&gt;Consider a space as a character that is ordered before numbers and letters.&lt;/li&gt;   &lt;li&gt;Consider a space as a character that is ordered after numbers and letters.&lt;/li&gt; &lt;/ol&gt; In the end I went with option 2, and if the film title contained a hyphen, I treated that as a character that came after a space, but before numbers and letters.

I also discount "a", "an" and "the" for the purposes of ordering.

For completeness, I should say that I order numbers before letters. But there are exceptions - for example, I own both "The Fast and the Furious", and its sequel "2 Fast 2 Furious". This raises a problem - if I ordered it properly, the sequel would appear very near the start of my DVD collection, but logically, I would prefer it to be right after "The Fast and the Furious". Therefore, I have allowed sequels to follow their predecessor films, regardless of any change in title.

If you made it to the end of this entry - congratulations, you're probably about as pedantic as I am.&lt;div style="clear:both; padding-bottom:0.25em"&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/af6P1OG0n5k" height="1" width="1"/&gt;</description>
      <pubDate>Fri, 01 Sep 2006 22:16:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/af6P1OG0n5k/dvd-taxonomy</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2006/09/01/dvd-taxonomy</feedburner:origLink></item>
    <item>
      <title>Desert Island Discs</title>
      <description>&lt;p&gt;Apparently &lt;a href="http://www.bbc.co.uk/radio4/factual/desertislanddiscs.shtml"&gt;Desert Island Discs&lt;/a&gt; is the longest running music programme in the history of radio, having been running since 1942. Despite not yet being a celebrity, I thought I&amp;#39;d jot down my choice of music, not forgetting my book and luxury item.
&lt;ol&gt;&lt;li&gt;Tonight Is The Night I Fell Asleep At The Wheel
Performer: Barenaked Ladies
CD Title: Maroon&lt;/li&gt;&lt;li&gt;Mr Jones
Performer: Counting Crows
CD Title: August and Everything After&lt;/li&gt;&lt;li&gt;The One I Love
Performer: David Gray
CD Title: Life in Slow Motion&lt;/li&gt;&lt;li&gt;Iris
Performer: Goo Goo Dolls
CD Title: Dizzy up the Girl&lt;/li&gt;&lt;li&gt;Nightswimming
Performer: R.E.M.
CD Title: Automatic for the People&lt;/li&gt;&lt;li&gt;I Hope That I Don&amp;#39;t Fall In Love With You
Performer: Tom Waits
CD Title: Closing Time&lt;/li&gt;&lt;li&gt;Who&amp;#39;s Gonna Ride Your Wild Horses
Performer: U2
CD Title: Achtung Baby&lt;/li&gt;&lt;li&gt;Meditation (from Thaïs)
Performer: Herbert von Karajan
Composer: Jules Massenet
CD Title: Meditation&lt;/li&gt;&lt;/ol&gt;&lt;/p&gt;

&lt;p&gt;Record: Achtung Baby
Book: &lt;em&gt;Hearts in Atlantis&lt;/em&gt; by Stephen King
Luxury: An unlimited supply of Skittles (the sweets), and a set of false teeth&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/rrxD1fSXfw8" height="1" width="1"/&gt;</description>
      <pubDate>Wed, 23 Aug 2006 21:58:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/rrxD1fSXfw8/desert-island-discs</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2006/08/23/desert-island-discs</feedburner:origLink></item>
    <item>
      <title>The size of space</title>
      <description>&lt;p&gt;I&amp;#39;m reading Bill Bryson&amp;#39;s &lt;a href="http://www.amazon.co.uk/gp/product/0552997048/026-3065692-6381214?v=glance&amp;n=266239&amp;amp;s=gateway&amp;v=glance"&gt;A Short History of Nearly Everything&lt;/a&gt;. It&amp;#39;s been on my bookshelf for a while but I&amp;#39;ve finally gotten around to it. I&amp;#39;ve just read the chapter on the solar system, and quite frankly, it&amp;#39;s mind-blowing. I am pretty ignorant regarding astronomy, but it seems to me that I &lt;span style="font-weight: bold;"&gt;should&lt;/span&gt; know a lot more than I do about our little planet and its place in the universe. Anyway, this little section on relative scale was pretty interesting:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;On a diagram of the solar system to scale, with the Earth reduced to about the diameter of a pea, Jupiter would be over 300 metres away and Pluto would be two and a half kilometres distant (and about the size of a bacterium, so you wouldn&amp;#39;t be able to see it anyway). On the same scale, Proxima Centauri, our nearest star, would be 16,000 kilometres away. Even if you shrank down everything so that Jupiter was as small as the full stop at the end of this sentence, and Pluto was no bigger than a molecule, Pluto would still be over 10 metres away.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Kind of makes you appreciate how inaccurate those solar system diagrams you saw at school really were, doesn&amp;#39;t it?&lt;/p&gt;

&lt;p&gt;It got me thinking - instead of reducing Earth to the size of a pea, how about you expand a pea to the size of Earth - how big would the elements of the solar system be in that scale?&lt;/p&gt;

&lt;p&gt;Well... fear not because I&amp;#39;ve done the maths for you. If a pea were the size of Earth, then in that scale, Mercury could be represented by a Grape Nut™ - if you don&amp;#39;t know what &lt;a href="http://www.kraft.com/100/innovations/grapenuts.html"&gt;Grape Nuts&lt;/a&gt; are, you need to investigate the cereal aisle at your local supermarket; a cricket ball would be about the size of Jupiter; and one of those weird exercise balls you see at gyms would be the same size as the sun.&lt;/p&gt;

&lt;p&gt;But get this - and remember our scale of a pea representing Earth - the Milky Way would be 1&amp;#47;10th the diameter of our solar system*. I have to use a distance in space as the equivalent because there&amp;#39;s simply nothing else big enough. So that makes our galaxy... quite big.&lt;/p&gt;

&lt;p&gt;*This is using the distance of Pluto from the sun as the diameter - actually the solar system is even bigger than this if you go out as far as the &lt;a href="http://en.wikipedia.org/wiki/Oort_Cloud"&gt;Oort cloud&lt;/a&gt; or beyond.&lt;div style="clear:both; padding-bottom:0.25em"&gt;&lt;/div&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/C_ShPQX-pA8" height="1" width="1"/&gt;</description>
      <pubDate>Sat, 19 Aug 2006 00:18:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/C_ShPQX-pA8/the-size-of-space</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2006/08/19/the-size-of-space</feedburner:origLink></item>
    <item>
      <title>Customising the AxWebBrowser</title>
      <description>&lt;p&gt;I recently needed to use AxWebBrowser component to do some automation of web page form filling. I wanted to capture Javascript alert boxes, grab the text from the alert box, and return it as an error to the user of my application.&lt;/p&gt;

&lt;p&gt;I also wanted to disable the loading of images and Flash animations. The code for this is below, in the &lt;code&gt;IDispatch_Invoke_Handler&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;It took me a long time to track down the method of doing this, so I thought I&amp;#39;d put it here in case anybody else needs the same info.&lt;/p&gt;

&lt;p&gt;First, some links I found useful:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://starkravingfinkle.org/blog/2004/09/"&gt;Mark Finkle&amp;#39;s blog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.codeproject.com/csharp/ExtendedWebBrowser.asp"&gt;Extended WebBrowser Control&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://support.microsoft.com/?kbid=279535"&gt;How to suppress run-time script errors as a WebBrowser control host&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://support.microsoft.com/kb/261003/"&gt;How to handle script errors as a WebBrowser control host&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://msdn.microsoft.com/workshop/browser/mshtml/overview/overview.asp"&gt;About MSHTML&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The following code shows how to setup the web browser such that you are alerted when Javascript popups are shown.&lt;/p&gt;

&lt;p&gt;First, you need to define some constants and interfaces.&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; &lt;span style="color:#080;font-weight:bold"&gt;enum&lt;/span&gt; ComConstants : uint
{
 DLCTL_DLIMAGES                          = &lt;span style="color:#02b"&gt;0x00000010&lt;/span&gt;,
 DLCTL_VIDEOS                            = &lt;span style="color:#02b"&gt;0x00000020&lt;/span&gt;,
 DLCTL_BGSOUNDS                          = &lt;span style="color:#02b"&gt;0x00000040&lt;/span&gt;,
 DLCTL_NO_SCRIPTS                        = &lt;span style="color:#02b"&gt;0x00000080&lt;/span&gt;,
 DLCTL_NO_JAVA                           = &lt;span style="color:#02b"&gt;0x00000100&lt;/span&gt;,
 DLCTL_NO_RUNACTIVEXCTLS                 = &lt;span style="color:#02b"&gt;0x00000200&lt;/span&gt;,
 DLCTL_NO_DLACTIVEXCTLS                  = &lt;span style="color:#02b"&gt;0x00000400&lt;/span&gt;,
 DLCTL_DOWNLOADONLY                      = &lt;span style="color:#02b"&gt;0x00000800&lt;/span&gt;,
 DLCTL_NO_FRAMEDOWNLOAD                  = &lt;span style="color:#02b"&gt;0x00001000&lt;/span&gt;,
 DLCTL_RESYNCHRONIZE                     = &lt;span style="color:#02b"&gt;0x00002000&lt;/span&gt;,
 DLCTL_PRAGMA_NO_CACHE                   = &lt;span style="color:#02b"&gt;0x00004000&lt;/span&gt;,
 DLCTL_NO_BEHAVIORS                      = &lt;span style="color:#02b"&gt;0x00008000&lt;/span&gt;,
 DLCTL_NO_METACHARSET                    = &lt;span style="color:#02b"&gt;0x00010000&lt;/span&gt;,
 DLCTL_URL_ENCODING_DISABLE_UTF8         = &lt;span style="color:#02b"&gt;0x00020000&lt;/span&gt;,
 DLCTL_URL_ENCODING_ENABLE_UTF8          = &lt;span style="color:#02b"&gt;0x00040000&lt;/span&gt;,
 DLCTL_NOFRAMES                          = &lt;span style="color:#02b"&gt;0x00080000&lt;/span&gt;,
 DLCTL_FORCEOFFLINE                      = &lt;span style="color:#02b"&gt;0x10000000&lt;/span&gt;,
 DLCTL_NO_CLIENTPULL                     = &lt;span style="color:#02b"&gt;0x20000000&lt;/span&gt;,
 DLCTL_SILENT                            = &lt;span style="color:#02b"&gt;0x40000000&lt;/span&gt;,
 DLCTL_OFFLINEIFNOTCONNECTED             = &lt;span style="color:#02b"&gt;0x80000000&lt;/span&gt;,
 DLCTL_OFFLINE                           = &lt;span style="color:#02b"&gt;0x80000000&lt;/span&gt;
}
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; &lt;span style="color:#080;font-weight:bold"&gt;enum&lt;/span&gt; DialogBoxCommandId
{
 Ok = &lt;span style="color:#00D"&gt;1&lt;/span&gt;,
 Cancel = &lt;span style="color:#00D"&gt;2&lt;/span&gt;,
 Abort = &lt;span style="color:#00D"&gt;3&lt;/span&gt;,
 Retry = &lt;span style="color:#00D"&gt;4&lt;/span&gt;,
 Ignore = &lt;span style="color:#00D"&gt;5&lt;/span&gt;,
 Yes = &lt;span style="color:#00D"&gt;6&lt;/span&gt;,
 No = &lt;span style="color:#00D"&gt;7&lt;/span&gt;,
 TryAgain = &lt;span style="color:#00D"&gt;10&lt;/span&gt;,
 Continue = &lt;span style="color:#00D"&gt;11&lt;/span&gt;
}
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span style="color:#088;font-weight:bold"&gt;using&lt;/span&gt; System.Runtime.InteropServices;
&lt;span style="color:#088;font-weight:bold"&gt;using&lt;/span&gt; mshtml;

[ComImport,
Guid(&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;C4D244B0-D43E-11CF-893B-00AA00BDCE1A&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
&lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; interface IDocHostShowUI
{
 [PreserveSig]
 uint ShowMessage(IntPtr hwnd, 
  [MarshalAs(UnmanagedType.LPWStr)] &lt;span style="color:#0a5;font-weight:bold"&gt;string&lt;/span&gt; lpstrText, 
  [MarshalAs(UnmanagedType.LPWStr)] &lt;span style="color:#0a5;font-weight:bold"&gt;string&lt;/span&gt; lpstrCaption, 
  uint dwType, 
  [MarshalAs(UnmanagedType.LPWStr)] &lt;span style="color:#0a5;font-weight:bold"&gt;string&lt;/span&gt; lpstrHelpFile, 
  uint dwHelpContext,
  out &lt;span style="color:#0a5;font-weight:bold"&gt;int&lt;/span&gt; lpResult);

 [PreserveSig]
 uint ShowHelp(IntPtr hwnd, [MarshalAs(UnmanagedType.LPWStr)] &lt;span style="color:#0a5;font-weight:bold"&gt;string&lt;/span&gt; pszHelpFile, 
  uint uCommand, uint dwData, 
  tagPOINT ptMouse, 
  [MarshalAs(UnmanagedType.IDispatch)] object pDispatchObjectHit);                       
}
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span style="color:#088;font-weight:bold"&gt;using&lt;/span&gt; System.Runtime.InteropServices;
&lt;span style="color:#088;font-weight:bold"&gt;using&lt;/span&gt; System.Windows.Forms;
&lt;span style="color:#088;font-weight:bold"&gt;using&lt;/span&gt; mshtml;

&lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; &lt;span style="color:#080;font-weight:bold"&gt;enum&lt;/span&gt; DOCHOSTUITYPE
{
 DOCHOSTUITYPE_BROWSE = &lt;span style="color:#00D"&gt;0&lt;/span&gt;,
 DOCHOSTUITYPE_AUTHOR = &lt;span style="color:#00D"&gt;1&lt;/span&gt;
}

&lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; &lt;span style="color:#080;font-weight:bold"&gt;enum&lt;/span&gt; DOCHOSTUIDBLCLK
{
 DOCHOSTUIDBLCLK_DEFAULT = &lt;span style="color:#00D"&gt;0&lt;/span&gt;,
 DOCHOSTUIDBLCLK_SHOWPROPERTIES = &lt;span style="color:#00D"&gt;1&lt;/span&gt;,
 DOCHOSTUIDBLCLK_SHOWCODE = &lt;span style="color:#00D"&gt;2&lt;/span&gt;
}

&lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; &lt;span style="color:#080;font-weight:bold"&gt;enum&lt;/span&gt; DOCHOSTUIFLAG
{
 DOCHOSTUIFLAG_DIALOG = &lt;span style="color:#02b"&gt;0x00000001&lt;/span&gt;,
 DOCHOSTUIFLAG_DISABLE_HELP_MENU = &lt;span style="color:#02b"&gt;0x00000002&lt;/span&gt;,
 DOCHOSTUIFLAG_NO3DBORDER = &lt;span style="color:#02b"&gt;0x00000004&lt;/span&gt;,
 DOCHOSTUIFLAG_SCROLL_NO = &lt;span style="color:#02b"&gt;0x00000008&lt;/span&gt;,
 DOCHOSTUIFLAG_DISABLE_SCRIPT_INACTIVE = &lt;span style="color:#02b"&gt;0x00000010&lt;/span&gt;,
 DOCHOSTUIFLAG_OPENNEWWIN = &lt;span style="color:#02b"&gt;0x00000020&lt;/span&gt;,
 DOCHOSTUIFLAG_DISABLE_OFFSCREEN = &lt;span style="color:#02b"&gt;0x00000040&lt;/span&gt;,
 DOCHOSTUIFLAG_FLAT_SCROLLBAR = &lt;span style="color:#02b"&gt;0x00000080&lt;/span&gt;,
 DOCHOSTUIFLAG_DIV_BLOCKDEFAULT = &lt;span style="color:#02b"&gt;0x00000100&lt;/span&gt;,
 DOCHOSTUIFLAG_ACTIVATE_CLIENTHIT_ONLY = &lt;span style="color:#02b"&gt;0x00000200&lt;/span&gt;,
 DOCHOSTUIFLAG_OVERRIDEBEHAVIORFACTORY = &lt;span style="color:#02b"&gt;0x00000400&lt;/span&gt;,
 DOCHOSTUIFLAG_CODEPAGELINKEDFONTS = &lt;span style="color:#02b"&gt;0x00000800&lt;/span&gt;,
 DOCHOSTUIFLAG_URL_ENCODING_DISABLE_UTF8 = &lt;span style="color:#02b"&gt;0x00001000&lt;/span&gt;,
 DOCHOSTUIFLAG_URL_ENCODING_ENABLE_UTF8 = &lt;span style="color:#02b"&gt;0x00002000&lt;/span&gt;,
 DOCHOSTUIFLAG_ENABLE_FORMS_AUTOCOMPLETE = &lt;span style="color:#02b"&gt;0x00004000&lt;/span&gt;,
 DOCHOSTUIFLAG_ENABLE_INPLACE_NAVIGATION = &lt;span style="color:#02b"&gt;0x00010000&lt;/span&gt;,
 DOCHOSTUIFLAG_IME_ENABLE_RECONVERSION = &lt;span style="color:#02b"&gt;0x00020000&lt;/span&gt;,
 DOCHOSTUIFLAG_THEME = &lt;span style="color:#02b"&gt;0x00040000&lt;/span&gt;,
 DOCHOSTUIFLAG_NOTHEME = &lt;span style="color:#02b"&gt;0x00080000&lt;/span&gt;,
 DOCHOSTUIFLAG_NOPICS = &lt;span style="color:#02b"&gt;0x00100000&lt;/span&gt;,
 DOCHOSTUIFLAG_NO3DOUTERBORDER = &lt;span style="color:#02b"&gt;0x00200000&lt;/span&gt;,
 DOCHOSTUIFLAG_DELEGATESIDOFDISPATCH = &lt;span style="color:#02b"&gt;0x00400000&lt;/span&gt;
}

[StructLayout(LayoutKind.Sequential)]
&lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; &lt;span style="color:#080;font-weight:bold"&gt;struct&lt;/span&gt; DOCHOSTUIINFO
{
 &lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; uint cbSize;
 &lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; uint dwFlags;
 &lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; uint dwDoubleClick;
 [MarshalAs(UnmanagedType.BStr)] &lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; &lt;span style="color:#0a5;font-weight:bold"&gt;string&lt;/span&gt; pchHostCss;
 [MarshalAs(UnmanagedType.BStr)] &lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; &lt;span style="color:#0a5;font-weight:bold"&gt;string&lt;/span&gt; pchHostNS;
}

[StructLayout(LayoutKind.Sequential)]
&lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; &lt;span style="color:#080;font-weight:bold"&gt;struct&lt;/span&gt; tagMSG
{
 &lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; IntPtr hwnd;
 &lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; uint message;
 &lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; uint wParam;
 &lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; &lt;span style="color:#0a5;font-weight:bold"&gt;int&lt;/span&gt; lParam;
 &lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; uint time;
 &lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; tagPOINT pt;
}

[ComImport(),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
GuidAttribute(&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;bd3f23c0-d43e-11cf-893b-00aa00bdce1a&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)]
&lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; interface IDocHostUIHandler
{
 [PreserveSig]
 uint ShowContextMenu(uint dwID, ref tagPOINT ppt,
  [MarshalAs(UnmanagedType.IUnknown)]  object pcmdtReserved,
  [MarshalAs(UnmanagedType.IDispatch)] object pdispReserved);

 &lt;span style="color:#088;font-weight:bold"&gt;void&lt;/span&gt; GetHostInfo(ref DOCHOSTUIINFO pInfo);
 &lt;span style="color:#088;font-weight:bold"&gt;void&lt;/span&gt; ShowUI(uint dwID, ref object pActiveObject, ref object pCommandTarget, ref object pFrame, ref object pDoc);
 &lt;span style="color:#088;font-weight:bold"&gt;void&lt;/span&gt; HideUI();
 &lt;span style="color:#088;font-weight:bold"&gt;void&lt;/span&gt; UpdateUI();
 &lt;span style="color:#088;font-weight:bold"&gt;void&lt;/span&gt; EnableModeless(&lt;span style="color:#0a5;font-weight:bold"&gt;int&lt;/span&gt; fEnable);
 &lt;span style="color:#088;font-weight:bold"&gt;void&lt;/span&gt; OnDocWindowActivate(&lt;span style="color:#0a5;font-weight:bold"&gt;int&lt;/span&gt; fActivate);
 &lt;span style="color:#088;font-weight:bold"&gt;void&lt;/span&gt; OnFrameWindowActivate(&lt;span style="color:#0a5;font-weight:bold"&gt;int&lt;/span&gt; fActivate);
 &lt;span style="color:#088;font-weight:bold"&gt;void&lt;/span&gt; ResizeBorder(ref tagRECT prcBorder, &lt;span style="color:#0a5;font-weight:bold"&gt;int&lt;/span&gt; pUIWindow, &lt;span style="color:#0a5;font-weight:bold"&gt;int&lt;/span&gt; fRameWindow);

 [PreserveSig]
 uint TranslateAccelerator(ref tagMSG lpMsg, ref Guid pguidCmdGroup, uint nCmdID);

 &lt;span style="color:#088;font-weight:bold"&gt;void&lt;/span&gt; GetOptionKeyPath([MarshalAs(UnmanagedType.BStr)] ref &lt;span style="color:#0a5;font-weight:bold"&gt;string&lt;/span&gt; pchKey, uint dw);
 object GetDropTarget(ref object pDropTarget);
 object GetExternal();

 [PreserveSig]
 uint TranslateUrl(uint dwTranslate, 
  [MarshalAs(UnmanagedType.BStr)] &lt;span style="color:#0a5;font-weight:bold"&gt;string&lt;/span&gt; pchURLIn,
  [MarshalAs(UnmanagedType.BStr)] ref &lt;span style="color:#0a5;font-weight:bold"&gt;string&lt;/span&gt; ppchURLOut);

 IDataObject FilterDataObject(IDataObject pDO);
}

[ComImport(),
GuidAttribute(&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;3050f6d0-98b5-11cf-bb82-00aa00bdce0b&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)]
&lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; interface IDocHostUIHandler2: IDocHostUIHandler
{
 &lt;span style="color:#088;font-weight:bold"&gt;void&lt;/span&gt; GetOverrideKeyPath([MarshalAs(UnmanagedType.BStr)] ref &lt;span style="color:#0a5;font-weight:bold"&gt;string&lt;/span&gt; pchKey, uint dw);
}
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span style="color:#088;font-weight:bold"&gt;using&lt;/span&gt; System.Runtime.InteropServices;

[ComImport,
Guid(&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;00000118-0000-0000-C000-000000000046&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
&lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; interface IOleClientSite
{
 &lt;span style="color:#088;font-weight:bold"&gt;void&lt;/span&gt; SaveObject();
 &lt;span style="color:#088;font-weight:bold"&gt;void&lt;/span&gt; GetMoniker(uint dwAssign, uint dwWhichMoniker, ref object ppmk);
 &lt;span style="color:#088;font-weight:bold"&gt;void&lt;/span&gt; GetContainer(ref object ppContainer);
 &lt;span style="color:#088;font-weight:bold"&gt;void&lt;/span&gt; ShowObject();
 &lt;span style="color:#088;font-weight:bold"&gt;void&lt;/span&gt; OnShowWindow(&lt;span style="color:#0a5;font-weight:bold"&gt;bool&lt;/span&gt; fShow);
 &lt;span style="color:#088;font-weight:bold"&gt;void&lt;/span&gt; RequestNewObjectLayout();
}
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span style="color:#088;font-weight:bold"&gt;using&lt;/span&gt; System.Runtime.InteropServices;

[ComImport,
Guid(&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;b722bcc7-4e68-101b-a2bc-00aa00404770&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
&lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; interface IOleDocumentSite
{
 &lt;span style="color:#088;font-weight:bold"&gt;void&lt;/span&gt; ActivateMe(ref object pViewToActivate);
}
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span style="color:#088;font-weight:bold"&gt;using&lt;/span&gt; System.Runtime.InteropServices;
&lt;span style="color:#088;font-weight:bold"&gt;using&lt;/span&gt; System.Windows.Forms;

[ComImport,
Guid(&lt;span style="background-color:hsla(0,100%,50%,0.05)"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D20"&gt;00000112-0000-0000-C000-000000000046&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
&lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; interface IOleObject
{
 &lt;span style="color:#088;font-weight:bold"&gt;void&lt;/span&gt; SetClientSite(IOleClientSite pClientSite);
 &lt;span style="color:#088;font-weight:bold"&gt;void&lt;/span&gt; GetClientSite(ref IOleClientSite ppClientSite);
 &lt;span style="color:#088;font-weight:bold"&gt;void&lt;/span&gt; SetHostNames(object szContainerApp, object szContainerObj);
 &lt;span style="color:#088;font-weight:bold"&gt;void&lt;/span&gt; Close(uint dwSaveOption);
 &lt;span style="color:#088;font-weight:bold"&gt;void&lt;/span&gt; SetMoniker(uint dwWhichMoniker, object pmk);
 &lt;span style="color:#088;font-weight:bold"&gt;void&lt;/span&gt; GetMoniker(uint dwAssign, uint dwWhichMoniker, object ppmk);
 &lt;span style="color:#088;font-weight:bold"&gt;void&lt;/span&gt; InitFromData(IDataObject pDataObject, &lt;span style="color:#0a5;font-weight:bold"&gt;bool&lt;/span&gt; fCreation, uint dwReserved);
 &lt;span style="color:#088;font-weight:bold"&gt;void&lt;/span&gt; GetClipboardData(uint dwReserved, ref IDataObject ppDataObject);
 &lt;span style="color:#088;font-weight:bold"&gt;void&lt;/span&gt; DoVerb(uint iVerb, uint lpmsg, object pActiveSite, uint lindex, uint hwndParent, uint lprcPosRect);
 &lt;span style="color:#088;font-weight:bold"&gt;void&lt;/span&gt; EnumVerbs(ref object ppEnumOleVerb);
 &lt;span style="color:#088;font-weight:bold"&gt;void&lt;/span&gt; Update();
 &lt;span style="color:#088;font-weight:bold"&gt;void&lt;/span&gt; IsUpToDate();
 &lt;span style="color:#088;font-weight:bold"&gt;void&lt;/span&gt; GetUserClassID(uint pClsid);
 &lt;span style="color:#088;font-weight:bold"&gt;void&lt;/span&gt; GetUserType(uint dwFormOfType, uint pszUserType);
 &lt;span style="color:#088;font-weight:bold"&gt;void&lt;/span&gt; SetExtent(uint dwDrawAspect, uint psizel);
 &lt;span style="color:#088;font-weight:bold"&gt;void&lt;/span&gt; GetExtent(uint dwDrawAspect, uint psizel);
 &lt;span style="color:#088;font-weight:bold"&gt;void&lt;/span&gt; Advise(object pAdvSink, uint pdwConnection);
 &lt;span style="color:#088;font-weight:bold"&gt;void&lt;/span&gt; Unadvise(uint dwConnection);
 &lt;span style="color:#088;font-weight:bold"&gt;void&lt;/span&gt; EnumAdvise(ref object ppenumAdvise);
 &lt;span style="color:#088;font-weight:bold"&gt;void&lt;/span&gt; GetMiscStatus(uint dwAspect,uint pdwStatus);
 &lt;span style="color:#088;font-weight:bold"&gt;void&lt;/span&gt; SetColorScheme(object pLogpal);
}
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Now, you can define the object that will host the web browser, using the interfaces you have just declared.&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span style="color:#088;font-weight:bold"&gt;using&lt;/span&gt; System.Runtime.InteropServices;
&lt;span style="color:#088;font-weight:bold"&gt;using&lt;/span&gt; System.Windows.Forms;
&lt;span style="color:#088;font-weight:bold"&gt;using&lt;/span&gt; mshtml;

&lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; &lt;span style="color:#080;font-weight:bold"&gt;class&lt;/span&gt; &lt;span style="color:#B06;font-weight:bold"&gt;WebBrowser&lt;/span&gt;:
 IOleClientSite,    &lt;span style="color:#777"&gt;// so MsHtml uses IDocHostUIHandler&lt;/span&gt;
 IDocHostUIHandler,
 IOleDocumentSite,  &lt;span style="color:#777"&gt;// so MsHtml uses IDocHostShowUI&lt;/span&gt;
 IDocHostShowUI
{
 &lt;span style="color:#579"&gt;#region&lt;/span&gt; IOleClientSite methods

 &lt;span style="color:#088;font-weight:bold"&gt;void&lt;/span&gt; IOleClientSite.SaveObject() {}
 &lt;span style="color:#088;font-weight:bold"&gt;void&lt;/span&gt; IOleClientSite.GetMoniker(uint dwAssign, uint dwWhichMoniker, ref object ppmk) {}
 &lt;span style="color:#088;font-weight:bold"&gt;void&lt;/span&gt; IOleClientSite.GetContainer(ref object ppContainer) {ppContainer = &lt;span style="color:#963"&gt;this&lt;/span&gt;;}
 &lt;span style="color:#088;font-weight:bold"&gt;void&lt;/span&gt; IOleClientSite.ShowObject() {}
 &lt;span style="color:#088;font-weight:bold"&gt;void&lt;/span&gt; IOleClientSite.OnShowWindow(&lt;span style="color:#0a5;font-weight:bold"&gt;bool&lt;/span&gt; fShow) {}
 &lt;span style="color:#088;font-weight:bold"&gt;void&lt;/span&gt; IOleClientSite.RequestNewObjectLayout() {}

 &lt;span style="color:#579"&gt;#endregion&lt;/span&gt;

 &lt;span style="color:#579"&gt;#region&lt;/span&gt; IDocHostUIHandler methods

 &lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; uint ShowContextMenu(uint dwID, ref tagPOINT ppt, object pcmdtReserved, object pdispReserved)
 {
  &lt;span style="color:#777"&gt;//const int MenuHandled = 0; // uncomment this line, and comment the next one, to show the context menu&lt;/span&gt;
  &lt;span style="color:#088;font-weight:bold"&gt;const&lt;/span&gt; &lt;span style="color:#0a5;font-weight:bold"&gt;int&lt;/span&gt; MenuNotHandled = &lt;span style="color:#00D"&gt;1&lt;/span&gt;;
  &lt;span style="color:#080;font-weight:bold"&gt;return&lt;/span&gt; MenuNotHandled;
 }

 &lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; uint TranslateAccelerator(ref tagMSG lpMsg, ref Guid pguidCmdGroup, uint nCmdID)
 {
  &lt;span style="color:#777"&gt;//const int KillAccelerator = 0;&lt;/span&gt;
  &lt;span style="color:#088;font-weight:bold"&gt;const&lt;/span&gt; &lt;span style="color:#0a5;font-weight:bold"&gt;int&lt;/span&gt; AllowAccelerator = &lt;span style="color:#00D"&gt;1&lt;/span&gt;;
  &lt;span style="color:#080;font-weight:bold"&gt;return&lt;/span&gt; AllowAccelerator;
 }

 &lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; object GetDropTarget(ref object pDropTarget) 
 {
  &lt;span style="color:#080;font-weight:bold"&gt;return&lt;/span&gt; pDropTarget;
 }

 &lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; object GetExternal()
 {
  &lt;span style="color:#080;font-weight:bold"&gt;return&lt;/span&gt; null;
 }

 &lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; uint TranslateUrl(uint dwTranslate, &lt;span style="color:#0a5;font-weight:bold"&gt;string&lt;/span&gt; URLIn, ref &lt;span style="color:#0a5;font-weight:bold"&gt;string&lt;/span&gt; URLOut)
 {
  &lt;span style="color:#777"&gt;//const int Translated = 0;&lt;/span&gt;
  &lt;span style="color:#088;font-weight:bold"&gt;const&lt;/span&gt; &lt;span style="color:#0a5;font-weight:bold"&gt;int&lt;/span&gt; NotTranslated = &lt;span style="color:#00D"&gt;1&lt;/span&gt;;
  &lt;span style="color:#080;font-weight:bold"&gt;return&lt;/span&gt; NotTranslated;
 }

 &lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; IDataObject FilterDataObject(IDataObject pDO) 
 {
  &lt;span style="color:#080;font-weight:bold"&gt;return&lt;/span&gt; null;
 }

 &lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; &lt;span style="color:#088;font-weight:bold"&gt;void&lt;/span&gt; GetHostInfo(ref DOCHOSTUIINFO theHostUIInfo) {}
 &lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; &lt;span style="color:#088;font-weight:bold"&gt;void&lt;/span&gt; ShowUI(uint dwID, ref object pActiveObject, ref object pCommandTarget, ref object pFrame, ref object pDoc) {}
 &lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; &lt;span style="color:#088;font-weight:bold"&gt;void&lt;/span&gt; HideUI() {}
 &lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; &lt;span style="color:#088;font-weight:bold"&gt;void&lt;/span&gt; UpdateUI() {}
 &lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; &lt;span style="color:#088;font-weight:bold"&gt;void&lt;/span&gt; EnableModeless(&lt;span style="color:#0a5;font-weight:bold"&gt;int&lt;/span&gt; fEnable) {}
 &lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; &lt;span style="color:#088;font-weight:bold"&gt;void&lt;/span&gt; OnDocWindowActivate(&lt;span style="color:#0a5;font-weight:bold"&gt;int&lt;/span&gt; fActivate) {}
 &lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; &lt;span style="color:#088;font-weight:bold"&gt;void&lt;/span&gt; OnFrameWindowActivate(&lt;span style="color:#0a5;font-weight:bold"&gt;int&lt;/span&gt; fActivate) {}
 &lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; &lt;span style="color:#088;font-weight:bold"&gt;void&lt;/span&gt; ResizeBorder(ref tagRECT prcBorder, &lt;span style="color:#0a5;font-weight:bold"&gt;int&lt;/span&gt; pUIWindow, &lt;span style="color:#0a5;font-weight:bold"&gt;int&lt;/span&gt; fRameWindow) {}
 &lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; &lt;span style="color:#088;font-weight:bold"&gt;void&lt;/span&gt; GetOptionKeyPath(ref &lt;span style="color:#0a5;font-weight:bold"&gt;string&lt;/span&gt; pchKey, uint dw) {}

 &lt;span style="color:#579"&gt;#endregion&lt;/span&gt;

 &lt;span style="color:#579"&gt;#region&lt;/span&gt; IOleDocumentSite methods

 &lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; &lt;span style="color:#088;font-weight:bold"&gt;void&lt;/span&gt; ActivateMe(ref object pViewToActivate) {}

 &lt;span style="color:#579"&gt;#endregion&lt;/span&gt;

 &lt;span style="color:#579"&gt;#region&lt;/span&gt; IDocHostShowUI methods

 &lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; uint ShowMessage(IntPtr hwnd, &lt;span style="color:#0a5;font-weight:bold"&gt;string&lt;/span&gt; msgText, &lt;span style="color:#0a5;font-weight:bold"&gt;string&lt;/span&gt; msgCaption,
  uint dwType, &lt;span style="color:#0a5;font-weight:bold"&gt;string&lt;/span&gt; lpstrHelpFile, uint dwHelpContext,
  out &lt;span style="color:#0a5;font-weight:bold"&gt;int&lt;/span&gt; lpResult)
 {
  &lt;span style="color:#777"&gt;// msgText is the contents of the MessageBox&lt;/span&gt;
  &lt;span style="color:#777"&gt;// msgCaption is the text on the MessageBox caption bar&lt;/span&gt;

  &lt;span style="color:#777"&gt;// this is where you can deal with javascript popup boxes and simulate clicking different buttons&lt;/span&gt;
  lpResult = (&lt;span style="color:#0a5;font-weight:bold"&gt;int&lt;/span&gt;) DialogBoxCommandId.Ok;

  &lt;span style="color:#777"&gt;// return one of these values&lt;/span&gt;
  &lt;span style="color:#088;font-weight:bold"&gt;const&lt;/span&gt; &lt;span style="color:#0a5;font-weight:bold"&gt;int&lt;/span&gt; MessageHandled = &lt;span style="color:#00D"&gt;0&lt;/span&gt;;    &lt;span style="color:#777"&gt;// MsHtml won't display its MessageBox&lt;/span&gt;
  &lt;span style="color:#777"&gt;//const int MessageNotHandled = 1; // MsHtml will display its MessageBox&lt;/span&gt;
  &lt;span style="color:#080;font-weight:bold"&gt;return&lt;/span&gt; MessageHandled;
 }

 &lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; uint ShowHelp(IntPtr hwnd, &lt;span style="color:#0a5;font-weight:bold"&gt;string&lt;/span&gt; pszHelpFile, uint uCommand, uint dwData, 
  tagPOINT ptMouse, object pDispatchObjectHit)
 {
  &lt;span style="color:#777"&gt;// pDispatchObject will reference an object of&lt;/span&gt;
  &lt;span style="color:#777"&gt;// type mshtml.HTMLDocumentClass, or other class&lt;/span&gt;
  &lt;span style="color:#777"&gt;// representing something on the HTML page.&lt;/span&gt;

  &lt;span style="color:#777"&gt;// return one of these values&lt;/span&gt;
  &lt;span style="color:#777"&gt;//const int HelpHandled = 0;    // MsHtml won't display its Help window&lt;/span&gt;
  &lt;span style="color:#088;font-weight:bold"&gt;const&lt;/span&gt; &lt;span style="color:#0a5;font-weight:bold"&gt;int&lt;/span&gt; HelpNotHandled = &lt;span style="color:#00D"&gt;1&lt;/span&gt;; &lt;span style="color:#777"&gt;// MsHtml will display its Help window&lt;/span&gt;

  &lt;span style="color:#080;font-weight:bold"&gt;return&lt;/span&gt; HelpNotHandled;
 }

 &lt;span style="color:#579"&gt;#endregion&lt;/span&gt;

 &lt;span style="color:#579"&gt;#region&lt;/span&gt; IDispatch methods

 [DispId(-&lt;span style="color:#00D"&gt;5512&lt;/span&gt;)] &lt;span style="color:#777"&gt;// DISPID_AMBIENT_DLCONTROL = -5512&lt;/span&gt;
 &lt;span style="color:#088;font-weight:bold"&gt;public&lt;/span&gt; &lt;span style="color:#0a5;font-weight:bold"&gt;int&lt;/span&gt; IDispatch_Invoke_Handler()
 {
  &lt;span style="color:#777"&gt;// I have found that DLCTL_NO_CLIENTPULL means that things like meta refreshes are not executed&lt;/span&gt;
  &lt;span style="color:#0a5;font-weight:bold"&gt;int&lt;/span&gt; lReturn = (&lt;span style="color:#0a5;font-weight:bold"&gt;int&lt;/span&gt;) (ComConstants.DLCTL_PRAGMA_NO_CACHE | ComConstants.DLCTL_SILENT | ComConstants.DLCTL_NO_BEHAVIORS | ComConstants.DLCTL_NO_JAVA | ComConstants.DLCTL_NO_FRAMEDOWNLOAD);
  &lt;span style="color:#080;font-weight:bold"&gt;if&lt;/span&gt; (!Configuration.LoadActiveXControls)
  {
   lReturn |= (&lt;span style="color:#0a5;font-weight:bold"&gt;int&lt;/span&gt;) (ComConstants.DLCTL_NO_DLACTIVEXCTLS | ComConstants.DLCTL_NO_RUNACTIVEXCTLS);
  }
  &lt;span style="color:#080;font-weight:bold"&gt;if&lt;/span&gt; (Configuration.LoadImages)
  {
   lReturn |= (&lt;span style="color:#0a5;font-weight:bold"&gt;int&lt;/span&gt;) ComConstants.DLCTL_DLIMAGES;
  }
  &lt;span style="color:#080;font-weight:bold"&gt;return&lt;/span&gt; lReturn;
 }

 &lt;span style="color:#579"&gt;#endregion&lt;/span&gt;
}
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;In my code, I have a member variable mWebBrowser, of type AxWebBrowser, inside my WebBrowser class. After I&amp;#39;ve created it, the following lines are necessary to &amp;quot;register&amp;quot; the WebBrowser class as the host:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;IOleObject lOleObject = (IOleObject) mWebBrowser.GetOcx();
lOleObject.SetClientSite(&lt;span style="color:#963"&gt;this&lt;/span&gt;);
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/W5cbX0Sv_CE" height="1" width="1"/&gt;</description>
      <pubDate>Tue, 15 Aug 2006 15:22:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/W5cbX0Sv_CE/customising-the-axwebbrowser</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2006/08/15/customising-the-axwebbrowser</feedburner:origLink></item>
    <item>
      <title>iLyrics</title>
      <description>&lt;div style="clear:both;"&gt;&lt;/div&gt;So, it turns out the iTunes COM API is incredibly simple to use - even with C#. It's only taken me half an hour to write a little app that grabs the selected track from iTunes, searches a lyrics website to grab the lyrics, and adds the lyrics to the track info in iTunes.

Here's a screenie:
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/3747/1168/1600/iLyrics.0.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://photos1.blogger.com/blogger/3747/1168/400/iLyrics.0.jpg" alt="" border="0" /&gt;&lt;/a&gt;

At the moment it's really basic - it will only work for one track. But it will be easy enough to make it work for any number of selected tracks.

Let me know if you're interested - I'm quite willing to publish the source and binaries.&lt;div style="clear:both; padding-bottom:0.25em"&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/xHn7aqtklaU" height="1" width="1"/&gt;</description>
      <pubDate>Mon, 14 Aug 2006 23:49:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/xHn7aqtklaU/ilyrics</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2006/08/14/ilyrics</feedburner:origLink></item>
    <item>
      <title>Getting setup with iTunes</title>
      <description>&lt;p&gt;I&amp;#39;m on the verge of buying a 60gb iPod Video. This immediately raises a problem, since I have all my music (around 400 CDs) in WMA format, as I&amp;#39;ve always been strongly in the Microsoft camp. I could use iTunes to convert WMA to MP3 or AAC, but since I&amp;#39;ve got it in 64kbps WMA, it won&amp;#39;t sound that great if it&amp;#39;s converted to another lossy format.&lt;/p&gt;

&lt;p&gt;So I&amp;#39;m going to take the opportunity to re-rip all my CDs into a new format. Given that I want to play the music on iPod, I obviously can&amp;#39;t use WMA, but I&amp;#39;ve still got to choose between AAC or MP3 (yes, okay, I could use Apple Lossless, but I want to fit more than 3 songs on my iPod).&lt;/p&gt;

&lt;p&gt;I have considered ripping to a Lossless format, which would mean I&amp;#39;d never (in theory) need to rip from my CDs again. Then I could down-convert to AAC for putting on the iPod. However, I don&amp;#39;t currently have enough money for a new hard disk, which I&amp;#39;d need in order to store all my music in a lossless format. So at the moment, although this is definitely a good idea, I&amp;#39;m going to have to stay with a lossy format.&lt;/p&gt;

&lt;p&gt;I found &lt;a href="http://members.chello.nl/%7Em.heijligers/ipod/Compression/compression.html"&gt;this page&lt;/a&gt; which contains a helpful discussion on compression formats and which sounds better.&lt;/p&gt;

&lt;p&gt;I am going to go with Marc&amp;#39;s conclusion, and use AAC 224kbps as my format of choice. Hopefully this will sound good through both headphones and hi-fi when played on the iPod.&lt;/p&gt;

&lt;p&gt;While I&amp;#39;m at it, and as much for my own reference as anything else, here&amp;#39;s the tools I&amp;#39;m finding useful to help with this whole iTunes &amp;#47; iPod transition:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Lyrics&lt;/strong&gt;
I&amp;#39;m aware there&amp;#39;s plenty of programs that claim to be able to download lyrics into iTunes automatically. I&amp;#39;ve tried several of these, but none of them seem to do the job I want. What I want is to select a track in iTunes, click &amp;quot;search&amp;quot; in the lyrics program, get a list of possible matches, select the right one, and click OK. So I&amp;#39;m going to write a little utility app that does this - if you think you might find it useful, let me know and I&amp;#39;ll develop it into a proper application that I can distribute.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.yvg.com/itunesartimporter.shtml"&gt;&lt;strong&gt;iTunes Art Importer&lt;/strong&gt;&lt;/a&gt; (free)
Uses iTunes COM and Amazon Web Services to automatically find album art&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.thelittleappfactory.com/application.php?app=iPodRip"&gt;&lt;span style="font-weight: bold;"&gt;iPodRip&lt;/span&gt;
&lt;/a&gt;I haven&amp;#39;t used this yet, but it would be incredibly useful should my desktop PC ever crash, and I needed to copy music from the iPod to PC&lt;/li&gt;
&lt;/ul&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/w8REaCBP2JQ" height="1" width="1"/&gt;</description>
      <pubDate>Mon, 14 Aug 2006 21:01:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/w8REaCBP2JQ/getting-setup-with-itunes</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2006/08/14/getting-setup-with-itunes</feedburner:origLink></item>
    <item>
      <title>Christianity - a new religion?</title>
      <description>&lt;p&gt;First some facts about Christianity:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;There are roughly 33,830 Christian denominations&lt;/li&gt;
&lt;li&gt;There are an estimated 2.1 billion adherents in the world, making Christianity the world&amp;#39;s largest religion&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Anyway, the reason for this post is that I had a sudden realisation when I was mulling over religions - Christianity as I know it (i.e. the type I was raised with, Protestantism) has only existed since the 16th century! Protestants consider their separation from the Catholic church to have taken place in the 16th century, at the time of the Reformation. I always used to think that before that, there was still a &amp;quot;real&amp;quot; Christianity, it just wasn&amp;#39;t very popular. But I&amp;#39;ve been doing some research, and my findings have challenged that point of view.&lt;/p&gt;

&lt;p&gt;Before the Reformation, the Church used to sell indulgences. An indulgence (apparently) allows a person to skip the wages of sin, that would usually be paid for in purgatory. The Church was probably making a tidy profit on this business, but then along came a man named Martin Luther who put together a paper now known as the &amp;quot;95 Theses&amp;quot;, in which he said the sale of indulgences was basically A Bad Thing. The reigning Pope, Pope Leo X, wished for Martin Luther to recant 41 of the Theses. He refused (he publicly burned the papers containing the request from the Pope), and was ex-communicated by the Catholic Church. When I initially did some research for this post, I thought I would find that those 41 theses that the Pope wished for Martin Luther to recant contained beliefs that modern Christianity would find abhorrent. However, this was not the case - in fact, many of Luther&amp;#39;s own theses contain statements that modern Protestantism would probably have a hard time agreeing with. Here&amp;#39;s a few of Luther&amp;#39;s theses:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Salvation can be sought for through the Church as it has been granted this by Christ&lt;/li&gt;
&lt;li&gt;It is clear that the power of the Church is adequate, by itself, for the forgiveness of sins&lt;/li&gt;
&lt;li&gt;The pope should rebuild St Peter&amp;#39;s with his own money&lt;/li&gt;
&lt;li&gt;You should feel guilt after being pardoned&lt;/li&gt;
&lt;li&gt;Souls in purgatory need to find love - the more love the less their sin [interestingly, the Pope in his response pointed out that Purgatory can&amp;#39;t actually be proved from Scripture]&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It&amp;#39;s easy enough to pick holes in Luther&amp;#39;s theses, and also the response from the Pope (known as Exurge Domine). But my point in all this rambling is that these events make up some of the foundation stones of modern Christianity (at least, the Protestant variety of it) - and if I was a Christian, I&amp;#39;d be looking pretty seriously at where my religion came from. It seems to me that &amp;quot;Christianity&amp;quot;, as we known it, has only been around for a few hundred years - and before that, it contained so many conflicting doctrines that one has to question whether it was really &amp;quot;Christianity&amp;quot; at all - at least by modern standards - how much can a religion change before it&amp;#39;s not the same religion?&lt;/p&gt;

&lt;p&gt;(It&amp;#39;s not particularly related to this topic, but let&amp;#39;s not forget that Martin Luther also wrote about the Jews, proposing that their homes be destroyed, synagogues and schools burned, money confiscated, and rights and liberties be curtailed.)&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/tNg1CxsERVc" height="1" width="1"/&gt;</description>
      <pubDate>Sun, 13 Aug 2006 13:30:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/tNg1CxsERVc/christianity---a-new-religion</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2006/08/13/christianity---a-new-religion</feedburner:origLink></item>
    <item>
      <title>French holiday</title>
      <description>&lt;p&gt;I have just spent a week with my flatmate, Zoe, and her family in France. Zoe&amp;#39;s parents own a farm in Alsace, which they are gradually renovating. One of the things I helped with was removing an old floor. This was a lot of fun - my appetite for destroying things was temporarily appeased. Here&amp;#39;s a somewhat sped-up version of how we did it (press play to start, has sound):&lt;/p&gt;

&lt;iframe width="560" height="315" src="http://www.youtube.com/embed/Xd-NzGmvB3c" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/OKrGs2m_8BE" height="1" width="1"/&gt;</description>
      <pubDate>Sat, 12 Aug 2006 23:27:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/OKrGs2m_8BE/french-holiday</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2006/08/12/french-holiday</feedburner:origLink></item>
    <item>
      <title>This ungodly blog</title>
      <description>&lt;p&gt;Have you ever heard the word ungodly used as an adjective for anything other than &amp;quot;hour&amp;quot;? According to &lt;a href="http://dictionary.reference.com/browse/ungodly"&gt;dictionary.com&lt;/a&gt;, the definition of ungodly is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Not revering God; impious.&lt;/li&gt;
&lt;li&gt;Sinful; wicked.&lt;/li&gt;
&lt;li&gt;Outrageous: &lt;em&gt;had to leave for work at an ungodly hour&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Personally, I&amp;#39;ve only ever heard it used in the third way.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/edeu8UuyFv0" height="1" width="1"/&gt;</description>
      <pubDate>Thu, 03 Aug 2006 10:57:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/edeu8UuyFv0/this-ungodly-blog</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2006/08/03/this-ungodly-blog</feedburner:origLink></item>
    <item>
      <title>Renamed brands</title>
      <description>&lt;p&gt;I got to thinking today, if I still had an original, wrapped Marathon bar, from the days before the &lt;a href="http://www.ciao.co.uk/Reviews/Snickers__5308867"&gt;Snickers&lt;/a&gt; fiasco, would I buy be able to sell it on Ebay for millions of pounds? Well, okay, maybe not millions. But there&amp;#39;s got to be somebody out there who collects such things.&lt;/p&gt;

&lt;p&gt;While I&amp;#39;m on the topic, maybe I should have kept hold of some Opal Fruits and &lt;a href="http://www.ciao.co.uk/Cesar__74765"&gt;Mr Dog&lt;/a&gt; as well.&lt;/p&gt;

&lt;p&gt;Work continues on the C2C video (still editing the footage from day 1 out of 12)...&lt;/p&gt;

&lt;p&gt;&lt;img src="http://photos1.blogger.com/blogger/3747/1168/400/02_07_2006%2015_38_0001.jpg" /&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/0Ajqg1huz5Y" height="1" width="1"/&gt;</description>
      <pubDate>Sun, 30 Jul 2006 22:49:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/0Ajqg1huz5Y/renamed-brands</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2006/07/30/renamed-brands</feedburner:origLink></item>
    <item>
      <title>Starting from scratch</title>
      <description>&lt;p&gt;As I was leaving my flat the other morning to go to work, I thought I smelt burning from the flat below mine. This got me thinking, what if the burning smell was, for example, coming from an iron that the owner of the flat had accidentally left on. And what if it started a fire, which burnt down both his flat and the flats above it. The question boils down to, what if my flat burnt down and I lost everything in it?&lt;/p&gt;

&lt;p&gt;Assuming I got the money from contents insurance (and I&amp;#39;m going out on a limb here and assuming that my insurance company would pay up due to loss caused by another flat owner leaving his iron on), the question I asked myself was, what would I miss? And what would I buy again? And just how materialistic am I?&lt;/p&gt;

&lt;p&gt;Things I own that I would definitely buy again: a laptop, (electronic) piano, camera, a limited selection of DVDs, a limited selection of books, walking equipment (rucksack, tent, etc.). Possibly some clothes.&lt;/p&gt;

&lt;p&gt;Things I own that I would probably not buy again: most of my DVD and CD collection, desktop computer, printer, most of my books.&lt;/p&gt;

&lt;p&gt;All in all I&amp;#39;d like to be a lot more minimalist than I am now. I love the idea of being able to pack all my worldly possessions in the boot of my car.&lt;/p&gt;

&lt;p&gt;How about you? Would you buy all your belongings again, or would you, like me, take the opportunity to shift your view on material possessions?&lt;/p&gt;

&lt;p&gt;On an unrelated note - this is a still, of the beach at St Bees, taken from my very-much-in-progress Coast to Coast documentary:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://photos1.blogger.com/blogger/3747/1168/400/01_07_2006%2020_21_0001.jpg" /&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/5k87-5DOoW0" height="1" width="1"/&gt;</description>
      <pubDate>Sat, 29 Jul 2006 13:20:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/5k87-5DOoW0/starting-from-scratch</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2006/07/29/starting-from-scratch</feedburner:origLink></item>
    <item>
      <title>Primitive Professions</title>
      <description>&lt;p&gt;Seeing as we seem to be rapidly destroying our world through removing our ozone layer and causing global warming, it got me thinking - if a scenario such as the film &amp;quot;The Day After Tomorrow&amp;quot; envisages &lt;strong&gt;did&lt;/strong&gt; in fact happen, what would be the most useful skills to have afterwards?&lt;/p&gt;

&lt;p&gt;I&amp;#39;m pretty sure that software engineers would not be high on the list. Doctors would probably come top - then, for a society to last longer than a few days (after we&amp;#39;d looted everything from the local Asda), we&amp;#39;d need farmers. Eventually, there&amp;#39;d be traders, etc. In fact it may not be too different from the original rise of civilisation.&lt;/p&gt;

&lt;p&gt;Or would it? Have we learnt anything in the last X thousand years that would help us become &amp;quot;civilised&amp;quot; more quickly the next time around? Could we use pure knowledge to rebuild, or are we now so dependent on our infrastructure that without it we&amp;#39;d be crippled?&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/jnt4N-Evug4" height="1" width="1"/&gt;</description>
      <pubDate>Fri, 28 Jul 2006 10:12:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/jnt4N-Evug4/primitive-professions</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2006/07/28/primitive-professions</feedburner:origLink></item>
    <item>
      <title>Coast to Coast</title>
      <description>&lt;p&gt;A couple of weeks ago, I spent two weeks walking from the west coast of England to the east coast. This was the most exhilerating, most beautiful, most challenging walk I&amp;#39;ve yet done. The scenery was truly superlative and I met some of the friendliest people I&amp;#39;ve ever come into contact with.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://photos1.blogger.com/blogger/3747/1168/400/09_07_2006%2012_57_0001.jpg" /&gt;&lt;/p&gt;

&lt;p&gt;I took 9 hours of video footage, which I&amp;#39;m now trying to edit down to a more reasonable 45 minutes, in a documentary style. Has anybody else tries this? I&amp;#39;ve spent a week so far, and I&amp;#39;ve got 3 minutes of edited video out of it - at this rate, expect to see the film in 2024.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/LBj2PfY4z-Q" height="1" width="1"/&gt;</description>
      <pubDate>Thu, 27 Jul 2006 21:57:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/LBj2PfY4z-Q/coast-to-coast</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2006/07/27/coast-to-coast</feedburner:origLink></item>
    <item>
      <title>Batman has Begun</title>
      <description>&lt;p&gt;I went to see Batman Begins last night.&lt;/p&gt;

&lt;p&gt;What can I say - but &lt;strong&gt;wow&lt;/strong&gt;! It&amp;#39;s as pure a piece of entertainment as I&amp;#39;ve ever seen. Come to think of it, I&amp;#39;m not sure how it could have been more entertaining.&lt;/p&gt;

&lt;p&gt;It&amp;#39;s also the first film I&amp;#39;ve seen at the cinema where the audience spontaneously applauded at the end.&lt;/p&gt;

&lt;p&gt;Moral of the story: see the film!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/vdoR_yW8A7M" height="1" width="1"/&gt;</description>
      <pubDate>Fri, 17 Jun 2005 15:48:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/vdoR_yW8A7M/batman-has-begun</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2005/06/17/batman-has-begun</feedburner:origLink></item>
    <item>
      <title>Solving cracks in geomipmapping - the wrong way...</title>
      <description>&lt;p&gt;&lt;a href="http://www.flickr.com/photos/80497340@N00/17293699/"&gt;&lt;img src="http://photos13.flickr.com/17293699_2b84c3862f_m.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is my first attempt at solving the &amp;quot;cracks&amp;quot; problem of geomipmapping. Please bear in mind that I&amp;#39;ve just been coding for the whole evening without actually running it...&lt;/p&gt;

&lt;p&gt;I&amp;#39;ll be putting up a dedicated website for Torq2 soon, with pages explaining how it all works, including a description of how I&amp;#39;m implementing geomipmapping, in case it&amp;#39;s useful for anybody.&lt;/p&gt;

&lt;p&gt;I know there&amp;#39;s a lot of tutorials out there about it, but I&amp;#39;ve found that very few of them actually get down to the nitty gritty - such as how to work out the indices for patches when joining them to neighbouring patches of different LOD...&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/l0m0-nompVQ" height="1" width="1"/&gt;</description>
      <pubDate>Fri, 03 Jun 2005 23:47:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/l0m0-nompVQ/solving-cracks-in-geomipmapping---the-wrong</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2005/06/03/solving-cracks-in-geomipmapping---the-wrong</feedburner:origLink></item>
    <item>
      <title>Torq2</title>
      <description>&lt;p&gt;&lt;a href="http://www.flickr.com/photos/80497340@N00/16916284/"&gt;&lt;img src="http://photos12.flickr.com/16916284_d48f1b4505_m.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;My final year project for my computer science degree was writing a 3D car simulatar in both C# and C++, in order to compare the performance.&lt;/p&gt;

&lt;p&gt;While I was reasonably happy with the marks I got for it, I wasn&amp;#39;t that happy with the actual simulator, so I&amp;#39;ve decided to rewrite it from scratch.&lt;/p&gt;

&lt;p&gt;Hence, this is the inaugural post for Torq2. It will feature a free-roaming landscape, and a fairly advanced physics system, once it&amp;#39;s finished.&lt;/p&gt;

&lt;p&gt;As you can see from this screenshot, it&amp;#39;s at a fairly primitive stage at the moment - I only started writing it a week ago.&lt;/p&gt;

&lt;p&gt;So far, I have a basic implementation of geomipmapping up and running, although I still have to fix the problems with cracks.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/02Z10hmHDk0" height="1" width="1"/&gt;</description>
      <pubDate>Wed, 01 Jun 2005 19:31:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/02Z10hmHDk0/torq</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2005/06/01/torq</feedburner:origLink></item>
    <item>
      <title>And we begin...</title>
      <description>&lt;p&gt;After previous abortive attempts at getting a regular blog going (including a protracted design and build of my own personal blogging software, which I didn&amp;#39;t quite finish) I have decided the best way to get started is to do it the easy way - use somebody else&amp;#39;s blogging site.&lt;/p&gt;

&lt;p&gt;So here we are. Hello! I plan to use this blog to tell the world about my interests, my job, my snippets of wisdom (yeah right), and my various projects.&lt;/p&gt;

&lt;p&gt;My current project is writing a 3D car simulator, so I&amp;#39;ll be blogging more about that in the next few weeks.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/roastedamoeba/~4/ypzP97TY-B4" height="1" width="1"/&gt;</description>
      <pubDate>Wed, 01 Jun 2005 19:09:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/roastedamoeba/~3/ypzP97TY-B4/and-we-begin</link>
    <feedburner:origLink>http://timjones.tw/blog/archive/2005/06/01/and-we-begin</feedburner:origLink></item>
  </channel>
</rss>
