<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Daniel Lehenbauer's Blog</title><link>http://blogs.msdn.com/b/danlehen/</link><description>Exploring 3D graphics with the Windows Presentation Foundation, and other topics occasionally of interest to .NET developers.</description><dc:language>en-US</dc:language><generator>Telligent Evolution Platform Developer Build (Build: 5.6.50428.7875)</generator><item><title>My not-so new opportunity...</title><link>http://blogs.msdn.com/b/danlehen/archive/2009/05/13/my-not-so-new-opportunity.aspx</link><pubDate>Wed, 13 May 2009 16:13:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9609334</guid><dc:creator>Daniel Lehenbauer</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/danlehen/rsscomments.aspx?WeblogPostID=9609334</wfw:commentRss><comments>http://blogs.msdn.com/b/danlehen/archive/2009/05/13/my-not-so-new-opportunity.aspx#comments</comments><description>&lt;P style="MARGIN: 0in 0in 10pt" class=MsoNormal&gt;&lt;FONT size=3 face=Calibri&gt;It is perhaps an understatement to say it's been a while since I blogged.&lt;/FONT&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0in 0in 10pt" class=MsoNormal&gt;&lt;FONT size=3 face=Calibri&gt;As is commonly the case with Microsoft blogs, the reason for going dark is that I left the WPF team almost two years ago for an opportunity I couldn't&amp;nbsp;pass by&amp;nbsp;to join&amp;nbsp;a systems incubation startup.&lt;/FONT&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0in 0in 10pt" class=MsoNormal&gt;&lt;FONT size=3 face=Calibri&gt;We're a small team with big ambitions, and as you might expect, my role involves the&amp;nbsp;exploration&amp;nbsp;of a radically different approach to the&amp;nbsp;UI/Graphics&amp;nbsp;platform which guarantees security, responsiveness, and leverages modern GPUs and manycore.&amp;nbsp; To deliver on this vision, we are revisiting every layer of the stack from device drivers, through rendering engines, up to application frameworks and programming/computation models.&lt;/FONT&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0in 0in 10pt" class=MsoNormal&gt;&lt;FONT size=3 face=Calibri&gt;While we’re not specifically seeking to fill headcount on our team, we are always on the lookout for luminaries with insight, experience, and who love to write code.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;If you are interested in joining a deep systems incubation that believes in small, hand-picked teams of truly outstanding developers, please do &lt;/FONT&gt;&lt;A href="http://blogs.msdn.com/danlehen/contact.aspx"&gt;&lt;FONT color=#0000ff size=3 face=Calibri&gt;contact me&lt;/FONT&gt;&lt;/A&gt;&lt;FONT size=3 face=Calibri&gt;.&lt;/FONT&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0in 0in 10pt" class=MsoNormal&gt;&lt;FONT size=3 face=Calibri&gt;While much is demanded of everyone in this group, we also get to participate in what I personally believe is the most exciting and revolutionary work to happen in the industry since PARC.&lt;/FONT&gt;&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9609334" width="1" height="1"&gt;</description></item><item><title>New Blender Exporter Features: Double Sided &amp; Solid (Flat) Shading</title><link>http://blogs.msdn.com/b/danlehen/archive/2006/06/22/new-blender-exporter-features-double-sided-solid-flat-shading.aspx</link><pubDate>Fri, 23 Jun 2006 07:33:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:643677</guid><dc:creator>Daniel Lehenbauer</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/danlehen/rsscomments.aspx?WeblogPostID=643677</wfw:commentRss><comments>http://blogs.msdn.com/b/danlehen/archive/2006/06/22/new-blender-exporter-features-double-sided-solid-flat-shading.aspx#comments</comments><description>&lt;P&gt;[&lt;STRONG&gt;UPDATE:&lt;/STRONG&gt; The Xaml Exporter now is hosted on CodePlex (&lt;A class="" href="http://codeplex.com/xamlexporter" mce_href="http://codeplex.com/xamlexporter"&gt;here&lt;/A&gt;)]&amp;nbsp;&lt;/P&gt;
&lt;P&gt;I checked in an updated&amp;nbsp;Blender&amp;nbsp;exporter&amp;nbsp;to&amp;nbsp;&lt;A href="http://workspaces.gotdotnet.com/3dtools" mce_href="http://workspaces.gotdotnet.com/3dtools"&gt;3D Tools for Windows Presentation Foundation&lt;/A&gt;&amp;nbsp;which adds support for double sided materials and flat shaded geometry.&amp;nbsp; I have not yet package a new release, so for the moment you’ll need to grab xaml_export.py from &lt;A href="http://www.gotdotnet.com/workspaces/messageboard/thread.aspx?id=2ce2a6b8-2085-4839-a001-1c539525f5fa&amp;amp;threadid=251954b2-5f3e-4ea2-8aa4-f4202bc588a3" mce_href="http://www.gotdotnet.com/workspaces/messageboard/thread.aspx?id=2ce2a6b8-2085-4839-a001-1c539525f5fa&amp;amp;threadid=251954b2-5f3e-4ea2-8aa4-f4202bc588a3"&gt;source control&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;&lt;IMG src="http://viewport3d.com/Blog_files/Blender_Smooth_2Sided.PNG" border=0 mce_src="http://viewport3d.com/Blog_files/Blender_Smooth_2Sided.PNG"&gt;&lt;/P&gt;
&lt;P&gt;These features are accessible via the circled buttons on the material and mesh panels during editing.&amp;nbsp; Thanks to SEISENBERG for reporting this in the &lt;A href="http://www.gotdotnet.com/workspaces/messageboard/thread.aspx?id=2ce2a6b8-2085-4839-a001-1c539525f5fa&amp;amp;threadid=251954b2-5f3e-4ea2-8aa4-f4202bc588a3" mce_href="http://www.gotdotnet.com/workspaces/messageboard/thread.aspx?id=2ce2a6b8-2085-4839-a001-1c539525f5fa&amp;amp;threadid=251954b2-5f3e-4ea2-8aa4-f4202bc588a3"&gt;message board&lt;/A&gt;.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=643677" width="1" height="1"&gt;</description></item><item><title> Looking for ScreenSpaceLines3D? -- 3D Tools v0.4 released</title><link>http://blogs.msdn.com/b/danlehen/archive/2006/05/29/610310.aspx</link><pubDate>Tue, 30 May 2006 01:08:13 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:610310</guid><dc:creator>Daniel Lehenbauer</dc:creator><slash:comments>10</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/danlehen/rsscomments.aspx?WeblogPostID=610310</wfw:commentRss><comments>http://blogs.msdn.com/b/danlehen/archive/2006/05/29/610310.aspx#comments</comments><description>&lt;p&gt;I have posted a &lt;a href="http://www.gotdotnet.com/workspaces/releases/viewuploads.aspx?id=2ce2a6b8-2085-4839-a001-1c539525f5fa"&gt;new release&lt;/a&gt; of the &lt;a href="http://workspaces.gotdotnet.com/3dtools"&gt;3D Tools for the Windows Presentation Foundation&lt;/a&gt; targeting &lt;a href="http://msdn.microsoft.com/windowsvista/downloads/products/getthebeta/default.aspx#developWinFXApps"&gt;the Beta 2 release of the WinFX runtime&lt;/a&gt;.&amp;nbsp; The big addition in this release is a community owned implementation of the ScreenSpaceLines3D class.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;ScreenSpaceLines3D&amp;nbsp;is&amp;nbsp;a 3D line primitive whose thickness&amp;nbsp;is constant in 2D space post projection.*&amp;nbsp; This means that the lines do not become &amp;ldquo;skinnier&amp;rdquo; as they receded from&amp;nbsp;a perspective&amp;nbsp;camera.&amp;nbsp; ScreenSpaceLines3D are most frequently used to implement bounding boxes, wireframe mode, or visualization of normals for editors.&amp;nbsp; Occasionally they are used in 3D scenes to represent telephone wires and similar objects that are too thin to be rendered reliably under a perspective projection.&lt;/p&gt;
&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;img src="http://viewport3d.com/Blog_files/Wireframe1p.PNG" /&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="http://viewport3d.com/Blog_files/Wireframe2p.PNG" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;I also started a MathUtils class which contains some generally useful utility methods, such as getting the View/Projection matrices from any camera and a method which returns the 3D -&amp;gt; 2D transform (useful for positioning 2D content, like text labels,&amp;nbsp;relative to&amp;nbsp;3D content.)&amp;nbsp; I&amp;rsquo;ve also added a wireframe mode to the ModelViewer sample to test ScreenSpaceLines3D.&lt;/p&gt;
&lt;p&gt;The project has been refactored into just two assemblies: 3DTools.dll which contains the reusable runtime components and the ModelViewer.exe sample.&amp;nbsp; Enjoy!&lt;/p&gt;
&lt;p&gt;* The name ScreenSpaceLines3D was a bit of a misnomer.&amp;nbsp; The lines were actually of constant thickness in the post-projective space of the Viewport3DVisual, not &amp;ldquo;device space&amp;rdquo; or &amp;ldquo;screen space&amp;rdquo; as the name implied.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=610310" width="1" height="1"&gt;</description></item><item><title>Sphere, Cone, and Cylinder Sample Updated</title><link>http://blogs.msdn.com/b/danlehen/archive/2006/02/11/530361.aspx</link><pubDate>Sun, 12 Feb 2006 07:23:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:530361</guid><dc:creator>Daniel Lehenbauer</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/danlehen/rsscomments.aspx?WeblogPostID=530361</wfw:commentRss><comments>http://blogs.msdn.com/b/danlehen/archive/2006/02/11/530361.aspx#comments</comments><description>&lt;P&gt;&lt;STRONG&gt;Minor update:&lt;/STRONG&gt; The "&lt;A HREF="/danlehen/archive/2005/10/16/481597.aspx"&gt;Extending Visual3D - Sphere, Cone, and Cylinder&lt;/A&gt;" sample has been updated to the &lt;A HREF="/danlehen/archive/2005/12/19/505647.aspx"&gt;December&lt;/A&gt;&amp;nbsp;and &lt;A HREF="/danlehen/archive/2006/01/18/514574.aspx"&gt;January CTP&lt;/A&gt; (either will work).&amp;nbsp; Thanks to Barry Briggs for doing this and sending me the updated source.&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=530361" width="1" height="1"&gt;</description></item><item><title>Xaml Export Script for Blender</title><link>http://blogs.msdn.com/b/danlehen/archive/2006/01/14/xaml-export-script-for-blender.aspx</link><pubDate>Sun, 15 Jan 2006 07:13:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:513012</guid><dc:creator>Daniel Lehenbauer</dc:creator><slash:comments>7</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/danlehen/rsscomments.aspx?WeblogPostID=513012</wfw:commentRss><comments>http://blogs.msdn.com/b/danlehen/archive/2006/01/14/xaml-export-script-for-blender.aspx#comments</comments><description>&lt;P&gt;&lt;STRONG&gt;[UPDATE:&lt;/STRONG&gt; The Xaml Exporter now is hosted on CodePlex (&lt;A class="" href="http://codeplex.com/xamlexporter" mce_href="http://codeplex.com/xamlexporter"&gt;here&lt;/A&gt;)&lt;STRONG&gt;]&lt;/STRONG&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;The 3D features in the Windows Presentation Foundation make it easier than ever&amp;nbsp;to&amp;nbsp;integrate 3D content into your applications.&amp;nbsp; However, unless you are satisfied with &lt;A href="http://blogs.msdn.com/danlehen/archive/2005/10/16/481597.aspx" mce_href="http://blogs.msdn.com/danlehen/archive/2005/10/16/481597.aspx"&gt;basic solid geometry&lt;/A&gt; you are going to need more than just the WPF.&amp;nbsp; You’re going to need 3D authoring tools to create interesting content.&lt;/P&gt;
&lt;P&gt;Unfortunately 3D tools tend to use their own proprietary file formats with limited import/export support for other formats.&amp;nbsp; Xaml, being new to the scene (no pun intended), is not yet supported by most tools.&amp;nbsp; However, some modeling programs&amp;nbsp;feature an add-in architecture that allows custom exporters to be written by 3rd parties.&amp;nbsp; The free 3D software package &lt;A href="http://en.wikipedia.org/wiki/Blender_%28software%29" mce_href="http://en.wikipedia.org/wiki/Blender_%28software%29"&gt;Blender&lt;/A&gt; is such a tool.&lt;/P&gt;
&lt;P&gt;All very interesting you say, but where is this going?&lt;/P&gt;
&lt;P&gt;I&amp;nbsp;have posted a&amp;nbsp;new release&amp;nbsp;of the &lt;A href="http://workspaces.gotdotnet.com/3dtools" mce_href="http://workspaces.gotdotnet.com/3dtools"&gt;3D Tools for the WPF&lt;/A&gt;&amp;nbsp;which&amp;nbsp;includes a Python script to export Blender scenes as Xaml.&amp;nbsp; The Xaml can then be dynamically loaded or compiled into your WPF applications.&amp;nbsp; Figure 1a shows a 3D model being edited with Blender.&amp;nbsp; Figure 1b shows the final exported Xaml as viewed with the &lt;A href="http://blogs.msdn.com/danlehen/archive/2005/12/20/506058.aspx" mce_href="http://blogs.msdn.com/danlehen/archive/2005/12/20/506058.aspx"&gt;WPF Model Viewer&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;
&lt;TABLE class="" id=table1 cellSpacing=1 width="59%" border=0&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD class="" width=301&gt;&lt;A href="http://viewport3d.com/XamlExporter/ReadMe_files/ReadMe1.jpg" mce_href="http://viewport3d.com/XamlExporter/ReadMe_files/ReadMe1.jpg"&gt;&lt;IMG height=223 src="http://viewport3d.com/XamlExporter/ReadMe_files/ReadMe1.jpg" width=300 border=0 mce_src="http://viewport3d.com/XamlExporter/ReadMe_files/ReadMe1.jpg"&gt;&lt;/A&gt;&lt;/TD&gt;
&lt;TD class=""&gt;&lt;A href="http://viewport3d.com/XamlExporter/ReadMe_files/ReadMe2.jpg" mce_href="http://viewport3d.com/XamlExporter/ReadMe_files/ReadMe2.jpg"&gt;&lt;IMG height=222 src="http://viewport3d.com/XamlExporter/ReadMe_files/ReadMe2.jpg" width=300 border=0 mce_src="http://viewport3d.com/XamlExporter/ReadMe_files/ReadMe2.jpg"&gt;&lt;/A&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class="" vAlign=top align=left width=301&gt;&lt;B&gt;Figure 1a&lt;BR&gt;&lt;/B&gt;&lt;I&gt;The&amp;nbsp;Steve Ballmer model*&amp;nbsp;is authored in Blender and then exported to Xaml.&lt;/I&gt;&lt;/TD&gt;
&lt;TD class="" vAlign=top align=left&gt;&lt;B&gt;Figure 1b&lt;BR&gt;&lt;/B&gt;&lt;I&gt;The final model as it appears in the WPF Model Viewer.&lt;/I&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class="" vAlign=top align=left colSpan=2&gt;
&lt;P align=center&gt;&lt;BR&gt;(Click for full sized images)&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;
&lt;P&gt;Because the WPF and Blender have different goals for their rendering engines&amp;nbsp;their feature sets do not match precisely.&amp;nbsp; Specifically, the WPF uses the hardware accelerated real-time rendering capabilities of your GPU.&amp;nbsp; Blender is a software based rendering engine not targeted at real-time applications.&amp;nbsp; However, the results of the export are frequently quite good.&amp;nbsp; Figure 2a is the same 3D model as rendered by Blender.&amp;nbsp; Figure 2b is the exported model viewed from a similar angle with the same lighting configuration in the WPF Model Viewer.&lt;/P&gt;
&lt;P&gt;
&lt;TABLE class="" id=table1 cellSpacing=1 width="59%" border=0&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD class="" width=301&gt;&lt;A href="http://viewport3d.com/XamlExporter/XamlExporter_Blender.jpg" mce_href="http://viewport3d.com/XamlExporter/XamlExporter_Blender.jpg"&gt;&lt;IMG height=223 src="http://viewport3d.com/XamlExporter/XamlExporter_Blender.jpg" width=300 border=0 mce_src="http://viewport3d.com/XamlExporter/XamlExporter_Blender.jpg"&gt;&lt;/A&gt;&lt;/TD&gt;
&lt;TD class=""&gt;&lt;A href="http://viewport3d.com/XamlExporter/XamlExporter_WPF.jpg" mce_href="http://viewport3d.com/XamlExporter/XamlExporter_WPF.jpg"&gt;&lt;IMG height=222 src="http://viewport3d.com/XamlExporter/XamlExporter_WPF.jpg" width=300 border=0 mce_src="http://viewport3d.com/XamlExporter/XamlExporter_WPF.jpg"&gt;&lt;/A&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class="" vAlign=top align=left width=301&gt;&lt;B&gt;Figure 2a&lt;BR&gt;&lt;/B&gt;&lt;I&gt;Steve Ballmer model* rendered using Blender’s internal&amp;nbsp;software engine.&lt;/I&gt;&lt;/TD&gt;
&lt;TD class="" vAlign=top align=left&gt;&lt;B&gt;Figure 2b&lt;BR&gt;&lt;/B&gt;&lt;I&gt;Exported model rendered using the WPF.&amp;nbsp; The blue background is not part of the scene.&lt;/I&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class="" vAlign=top align=left colSpan=2&gt;
&lt;P align=center&gt;&lt;BR&gt;(Click for full sized images)&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;/P&gt;
&lt;P&gt;To get the Xaml Export Script for Blender and the WPF Model Viewer download the latest version of the 3D Tools for WPF (&lt;A href="http://www.gotdotnet.com/workspaces/releases/viewuploads.aspx?id=2ce2a6b8-2085-4839-a001-1c539525f5fa" mce_href="http://www.gotdotnet.com/workspaces/releases/viewuploads.aspx?id=2ce2a6b8-2085-4839-a001-1c539525f5fa"&gt;available here&lt;/A&gt;).&amp;nbsp; Copy the xaml_export.py script to your Blender scripts directory.&amp;nbsp; Blender will automatically add the script to the ~File~Export menu the next time it is started.&amp;nbsp; More detailed instructions and a list of known issues are included in &lt;A href="http://viewport3d.com/XamlExporter/ReadMe.htm" mce_href="http://viewport3d.com/XamlExporter/ReadMe.htm"&gt;the Read-Me&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;* Steve Ballmer model courtesy of Bonnie Lehenbauer&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=513012" width="1" height="1"&gt;</description></item><item><title>Why did we change LookAtPoint to LookDirection?</title><link>http://blogs.msdn.com/b/danlehen/archive/2006/01/03/509092.aspx</link><pubDate>Wed, 04 Jan 2006 09:43:44 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:509092</guid><dc:creator>Daniel Lehenbauer</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/danlehen/rsscomments.aspx?WeblogPostID=509092</wfw:commentRss><comments>http://blogs.msdn.com/b/danlehen/archive/2006/01/03/509092.aspx#comments</comments><description>&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;Ernie &lt;a href="http://blogs.msdn.com/ebooth/archive/2005/12/07/500796.aspx"&gt;posted&lt;/a&gt; about the differences between the old LookAtPoint property and the new LookDirection property on ProjectionCamera (via &lt;a href="http://blogs.msdn.com/karstenj/archive/2005/12/08/501828.aspx"&gt;KarstenJ&lt;/a&gt;.)&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;The quick summary is that LookAtPoint caused the camera to look at a fixed point in space (Figure 1a).&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;The new LookDirection property causes the camera to look in a fixed direction (Figure 1b).&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;?xml:namespace prefix ="" o ns ="" "urn:schemas-microsoft-com:office:office" /&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/p&gt;
&lt;table class="MsoTableGrid" style="BORDER-COLLAPSE: collapse; mso-yfti-tbllook: 480; mso-padding-alt: 0in 5.4pt 0in 5.4pt" cellspacing="0" cellpadding="0" border="0"&gt;
&lt;tbody&gt;
&lt;tr style="mso-yfti-irow: 0; mso-yfti-firstrow: yes"&gt;
&lt;td style="BORDER-RIGHT: #ece9d8; PADDING-RIGHT: 5.4pt; BORDER-TOP: #ece9d8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0in; BORDER-LEFT: #ece9d8; WIDTH: 221.4pt; PADDING-TOP: 0in; BORDER-BOTTOM: #ece9d8; BACKGROUND-COLOR: transparent" valign="top" width="295"&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; TEXT-ALIGN: center" align="center"&gt;&lt;?xml:namespace prefix ="" v ns ="" "urn:schemas-microsoft-com:vml" /&gt;&lt;v:shapetype id="_x0000_t75" stroked="f" filled="f" path="m@4@5l@4@11@9@11@9@5xe" o:preferrelative="t" o:spt="75" coordsize="21600,21600"&gt;&lt;v:stroke joinstyle="miter"&gt;&lt;/v:stroke&gt;&lt;v:formulas&gt;&lt;v:f eqn="if lineDrawn pixelLineWidth 0"&gt;&lt;/v:f&gt;&lt;v:f eqn="sum @0 1 0"&gt;&lt;/v:f&gt;&lt;v:f eqn="sum 0 0 @1"&gt;&lt;/v:f&gt;&lt;v:f eqn="prod @2 1 2"&gt;&lt;/v:f&gt;&lt;v:f eqn="prod @3 21600 pixelWidth"&gt;&lt;/v:f&gt;&lt;v:f eqn="prod @3 21600 pixelHeight"&gt;&lt;/v:f&gt;&lt;v:f eqn="sum @0 0 1"&gt;&lt;/v:f&gt;&lt;v:f eqn="prod @6 1 2"&gt;&lt;/v:f&gt;&lt;v:f eqn="prod @7 21600 pixelWidth"&gt;&lt;/v:f&gt;&lt;v:f eqn="sum @8 21600 0"&gt;&lt;/v:f&gt;&lt;v:f eqn="prod @7 21600 pixelHeight"&gt;&lt;/v:f&gt;&lt;v:f eqn="sum @10 21600 0"&gt;&lt;/v:f&gt;&lt;/v:formulas&gt;&lt;v:path o:connecttype="rect" gradientshapeok="t" o:extrusionok="f"&gt;&lt;/v:path&gt;&lt;o:lock aspectratio="t" v:ext="edit"&gt;&lt;img height="190" alt="LookDirection-1" src="http://viewport3d.com/Blog_files/LookDirection_2D1.png" width="190" border="0" /&gt;&lt;/o:lock&gt;&lt;/v:shapetype&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style="BORDER-RIGHT: #ece9d8; PADDING-RIGHT: 5.4pt; BORDER-TOP: #ece9d8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0in; BORDER-LEFT: #ece9d8; WIDTH: 221.4pt; PADDING-TOP: 0in; BORDER-BOTTOM: #ece9d8; BACKGROUND-COLOR: transparent" valign="top" width="295"&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; TEXT-ALIGN: center" align="center"&gt;&lt;img height="190" alt="LookDirection-2" src="http://viewport3d.com/Blog_files/LookDirection_2D2.png" width="190" border="0" /&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr style="mso-yfti-irow: 1; mso-yfti-lastrow: yes"&gt;
&lt;td style="BORDER-RIGHT: #ece9d8; PADDING-RIGHT: 5.4pt; BORDER-TOP: #ece9d8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0in; BORDER-LEFT: #ece9d8; WIDTH: 221.4pt; PADDING-TOP: 0in; BORDER-BOTTOM: #ece9d8; BACKGROUND-COLOR: transparent" valign="top" width="295"&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;b style="mso-bidi-font-weight: normal"&gt;Figure 1a&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;i style="mso-bidi-font-style: normal"&gt;When the camera&amp;rsquo;s position moves from point A to point B it is automatically re-orientated so that the LookAtPoint remains centered in its view.&lt;o:p&gt;&lt;/o:p&gt;&lt;/i&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style="BORDER-RIGHT: #ece9d8; PADDING-RIGHT: 5.4pt; BORDER-TOP: #ece9d8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0in; BORDER-LEFT: #ece9d8; WIDTH: 221.4pt; PADDING-TOP: 0in; BORDER-BOTTOM: #ece9d8; BACKGROUND-COLOR: transparent" valign="top" width="295"&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;b style="mso-bidi-font-weight: normal"&gt;Figure 1b&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;i style="mso-bidi-font-style: normal"&gt;When the camera&amp;rsquo;s position moves from point A to point B it continues to face in the direction specified by the LookDirection.&lt;o:p&gt;&lt;/o:p&gt;&lt;/i&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;In terms of the camera configurations that can be represented the two properties are equally expressive.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;It is easy to convert between the two using the following equation:&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; TEXT-ALIGN: center; mso-outline-level: 1" align="center"&gt;&lt;i style="mso-bidi-font-style: normal"&gt;LookDirection = LookAtPoint - Position&lt;o:p&gt;&lt;/o:p&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; TEXT-ALIGN: center" align="center"&gt;&lt;i style="mso-bidi-font-style: normal"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;However, there are some pragmatic advantages to choosing LookDirection.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;One is that LookDirection is similar to other properties in the system (e.g., SpotLight.Direction.)&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;Another is that LookAtPoint leads to a common misunderstanding that the camera can be rotated by simply updating the camera&amp;rsquo;s position.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;Unless you also transform the UpDirection this will lead to (usually) unexpected flipping behavior at the poles.&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;It was the addition of Camera.Transform, however, that&amp;nbsp;was the largest motivation to&amp;nbsp;switch to LookDirection.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;Being able to apply Transform3Ds to Cameras simplifies a lot of animation scenarios.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;In fact, it&amp;rsquo;s currently the only way to animate a MatrixCamera.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;Also, the ability to share Transform3Ds between Cameras and nodes in the Visual tree enables scenarios where the Camera follows an object in the scene.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;(Incidentally, this is how the headlight feature of the &lt;a href="http://blogs.msdn.com/danlehen/archive/2005/12/20/506058.aspx"&gt;ModelViewer sample&lt;/a&gt; works.)&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;The addition of Camera.Transform raised questions about LookAtPoint.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;Should LookAtPoint be affected by the transform or should it continue to be defined in world space?&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;If LookAtPoint is in world space, as most people initially suppose, it breaks the illusion that the camera is a physical object in the scene because rotating the camera 180 degrees does not necessarily mean that the camera is looking in the opposite direction since it will continue to look in the direction of the same fixed point in world space.&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;On the other hand, if the camera&amp;rsquo;s transform LookAtPoint is affected by the transform then users need to convert into the camera&amp;rsquo;s coordinate system to specify the LookAtPoint.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;This is no less difficult than calculating the LookDirection and more error prone.&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;When all these things were considered: the difficulty in reconciling LookAtPoint with Camera.Transform, the fact that the perceived simplicity of LookAtPoint is negated by the need to handle the UpDirection, and that elsewhere in the system we have consistently specified orientation with direction vectors, we decided that in the long term our customers will be happier with LookDirection.&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=509092" width="1" height="1"&gt;</description></item><item><title>3D Tools Workspace updated to December CTP bits</title><link>http://blogs.msdn.com/b/danlehen/archive/2005/12/20/506058.aspx</link><pubDate>Tue, 20 Dec 2005 22:58:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:506058</guid><dc:creator>Daniel Lehenbauer</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/danlehen/rsscomments.aspx?WeblogPostID=506058</wfw:commentRss><comments>http://blogs.msdn.com/b/danlehen/archive/2005/12/20/506058.aspx#comments</comments><description>&lt;P&gt;I've packaged &lt;A href="http://www.gotdotnet.com/workspaces/releases/viewuploads.aspx?id=2ce2a6b8-2085-4839-a001-1c539525f5fa"&gt;a new release&lt;/A&gt; of the &lt;A href="http://workspaces.gotdotnet.com/3dtools"&gt;3D Tools workspace&lt;/A&gt; targeting the December CTP WinFX bits.&amp;nbsp; This release&amp;nbsp;adds&amp;nbsp;two&amp;nbsp;requested features&amp;nbsp;to the ModelViewer sample.&amp;nbsp;&amp;nbsp;The first is the ability to light the scene.&amp;nbsp; This is&amp;nbsp;convenient&amp;nbsp;if you are viewing a model which does not contain lights.&amp;nbsp; There are two options for lighting:&lt;/P&gt;
&lt;P&gt;1.&amp;nbsp; Headlight&amp;nbsp;– This will add a white directional light which follows the viewing direction of the camera (imagine a flashlight duct-taped to the front of your camera.)&amp;nbsp; The headlight is now on by default.&lt;/P&gt;
&lt;P&gt;2.&amp;nbsp; Ambient Light – This will add a white ambient light which will fully illuminate the scene.&amp;nbsp; The lack of depth cues this causes will make the scene appear “flat”, but this mode can be useful for examining a model for correctness.&amp;nbsp; The ambient light is off by default.&lt;/P&gt;
&lt;TABLE&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD&gt;&lt;IMG height=114 alt=MV-None src="http://viewport3d.com/Blog_files/MV_2DNone_small.jpg" width=200 border=0&gt; 
&lt;TD&gt;&lt;IMG height=114 alt=MV-Headlight src="http://viewport3d.com/Blog_files/MV_2DHeadlight_small.jpg" width=200 border=0&gt; 
&lt;TD&gt;&lt;IMG height=114 alt=MV-Ambient src="http://viewport3d.com/Blog_files/MV_2DAmbient_small.jpg" width=200 border=0&gt; &lt;/TD&gt;
&lt;TR&gt;
&lt;TD&gt;&lt;EM&gt;No lights&lt;/EM&gt; 
&lt;TD&gt;&lt;EM&gt;Headlight&lt;/EM&gt; 
&lt;TD&gt;&lt;EM&gt;Ambient Light&lt;/EM&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;
&lt;P&gt;Changing the lighting options in the ModelViewer does not change the model (i.e., it is non-destructive.)&lt;/P&gt;
&lt;P&gt;The other new feature is the ability to reload the currently open file to view any changes since the file was last opened.&amp;nbsp; Both new features are available via the View menu.&lt;/P&gt;
&lt;P&gt;The release contains both binary and sources.&amp;nbsp; To run the ModelViewer, you need &lt;A href="http://msdn.microsoft.com/netframework/downloads/updates/default.aspx"&gt;.NET Framework 2.0 Redist&lt;/A&gt; and the &lt;A href="http://www.microsoft.com/downloads/details.aspx?familyid=BD3BA2D5-6ADB-4FB2-A3AA-E16A9EA5603F&amp;amp;displaylang=en"&gt;December CTP WinFX Runtime&lt;/A&gt;.&amp;nbsp; To build the solution you also need the &lt;a href="http://blogs.msdn.com/danlehen/archive/2005/12/19/505647.aspx"&gt;Windows SDK and optionally VS 2005 and the VS Extensions for WinFX&lt;/A&gt;.&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=506058" width="1" height="1"&gt;</description></item><item><title>Rotating the Camera with the Mouse</title><link>http://blogs.msdn.com/b/danlehen/archive/2005/12/15/rotating-the-camera-with-the-mouse.aspx</link><pubDate>Fri, 16 Dec 2005 05:29:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:504548</guid><dc:creator>Daniel Lehenbauer</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/danlehen/rsscomments.aspx?WeblogPostID=504548</wfw:commentRss><comments>http://blogs.msdn.com/b/danlehen/archive/2005/12/15/rotating-the-camera-with-the-mouse.aspx#comments</comments><description>&lt;P&gt;Possibly the most common 3D UI paradigm is to rotate an object with the mouse in order to view it from all angles.&amp;nbsp; This is illustrated by the images of the tiger model below:&amp;nbsp; &lt;/P&gt;
&lt;P&gt;
&lt;TABLE style="BORDER-COLLAPSE: collapse" class=MsoTableGrid border=0 cellSpacing=0 cellPadding=0 class="MsoTableGrid"&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD style="BORDER-BOTTOM: #ece9d8; BORDER-LEFT: #ece9d8; PADDING-BOTTOM: 0in; BACKGROUND-COLOR: transparent; PADDING-LEFT: 5.4pt; WIDTH: 221.4pt; PADDING-RIGHT: 5.4pt; BORDER-TOP: #ece9d8; BORDER-RIGHT: #ece9d8; PADDING-TOP: 0in" width=295&gt;
&lt;P style="TEXT-ALIGN: center; MARGIN: 0in 0in 0pt" class=MsoNormal align=center&gt;&lt;IMG src="http://viewport3d.com/Trackball_files/image001.gif" width=289 height=216 mce_src="http://viewport3d.com/Trackball_files/image001.gif"&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM: #ece9d8; BORDER-LEFT: #ece9d8; PADDING-BOTTOM: 0in; BACKGROUND-COLOR: transparent; PADDING-LEFT: 5.4pt; WIDTH: 221.4pt; PADDING-RIGHT: 5.4pt; BORDER-TOP: #ece9d8; BORDER-RIGHT: #ece9d8; PADDING-TOP: 0in" width=295&gt;
&lt;P style="TEXT-ALIGN: center; MARGIN: 0in 0in 0pt" class=MsoNormal align=center&gt;&lt;IMG src="http://viewport3d.com/Trackball_files/image002.gif" width=287 height=214 mce_src="http://viewport3d.com/Trackball_files/image002.gif"&gt;&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD style="BORDER-BOTTOM: #ece9d8; BORDER-LEFT: #ece9d8; PADDING-BOTTOM: 0in; BACKGROUND-COLOR: transparent; PADDING-LEFT: 5.4pt; WIDTH: 221.4pt; PADDING-RIGHT: 5.4pt; BORDER-TOP: #ece9d8; BORDER-RIGHT: #ece9d8; PADDING-TOP: 0in" vAlign=top width=295&gt;
&lt;P style="MARGIN: 0in 0in 0pt" class=MsoNormal&gt;&lt;B&gt;Figure 1a&lt;/B&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0in 0in 0pt" class=MsoNormal&gt;&lt;I&gt;Tiger model in its original configuration&lt;/I&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM: #ece9d8; BORDER-LEFT: #ece9d8; PADDING-BOTTOM: 0in; BACKGROUND-COLOR: transparent; PADDING-LEFT: 5.4pt; WIDTH: 221.4pt; PADDING-RIGHT: 5.4pt; BORDER-TOP: #ece9d8; BORDER-RIGHT: #ece9d8; PADDING-TOP: 0in" vAlign=top width=295&gt;
&lt;P style="MARGIN: 0in 0in 0pt" class=MsoNormal&gt;&lt;B&gt;Figure 1b&lt;/B&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0in 0in 0pt" class=MsoNormal&gt;&lt;I&gt;Tiger model after the mouse has been dragged to the left and slightly down.&lt;/I&gt;&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;/P&gt;
&lt;P&gt;This UI technique is known as a "virtual trackball" and it has been a staple of interactive computer graphics since the 80s.&amp;nbsp; It has applications ranging from CAD to department store kiosks to gaming.&lt;/P&gt;
&lt;P&gt;To help developers working with the Windows Presentation Foundation get a jump-start using 3D in their&amp;nbsp;applications I have added a sample trackball implementation to the &lt;A href="http://3dtools.codeplex.com/sourcecontrol/changeset/view/19131?projectName=3DTools#113857" mce_href="http://3dtools.codeplex.com/sourcecontrol/changeset/view/19131?projectName=3DTools#113857"&gt;3DTools workspace&lt;/A&gt; with an &lt;A href="http://viewport3d.com/trackball.htm" mce_href="http://viewport3d.com/trackball.htm"&gt;accompanying article&lt;/A&gt; which discusses the mechanics of how a trackball works.&lt;/P&gt;
&lt;P&gt;Reading&amp;nbsp;the full article is not required to successfully use the sample code in your own applications, but skimming it might be useful.&amp;nbsp; You do not&amp;nbsp;need to be a member of the workspace in order to download releases which include both binaries and source (&lt;A href="http://www.gotdotnet.com/workspaces/releases/viewuploads.aspx?id=2ce2a6b8-2085-4839-a001-1c539525f5fa" mce_href="http://www.gotdotnet.com/workspaces/releases/viewuploads.aspx?id=2ce2a6b8-2085-4839-a001-1c539525f5fa"&gt;here&lt;/A&gt;).&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=504548" width="1" height="1"&gt;</description></item><item><title>WinFX November CTP Released!</title><link>http://blogs.msdn.com/b/danlehen/archive/2005/11/30/498505.aspx</link><pubDate>Wed, 30 Nov 2005 21:54:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:498505</guid><dc:creator>Daniel Lehenbauer</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/danlehen/rsscomments.aspx?WeblogPostID=498505</wfw:commentRss><comments>http://blogs.msdn.com/b/danlehen/archive/2005/11/30/498505.aspx#comments</comments><description>&lt;P&gt;If you are like me and have been &lt;a href="http://blogs.msdn.com/danlehen/archive/2005/11/10/491407.aspx"&gt;holding off&lt;/A&gt; on installing the final version of the .NET Framework 2.0 and Visual Studio 2005 until you had Windows Presentation Foundation (formerly code-named Avalon) bits to work with then the wait is over.&amp;nbsp; The November CTP of the WPF works with the final .NET/VS bits.&lt;/P&gt;
&lt;P&gt;&lt;a href="http://blogs.msdn.com/tims/default.aspx"&gt;Tim Sneath&lt;/A&gt; posted &lt;a href="http://blogs.msdn.com/tims/archive/2005/11/18/494526.aspx"&gt;links to the downloads&lt;/A&gt;.&lt;BR&gt;&lt;a href="http://blogs.msdn.com/karstenj"&gt;Karsten Januszewski&lt;/A&gt; has&amp;nbsp;&lt;a href="http://blogs.msdn.com/karstenj/archive/2005/11/18/494551.aspx"&gt;a summary changes&lt;/A&gt;&amp;nbsp;in this release.&lt;/P&gt;
&lt;P&gt;Not having to reinstall VS for each WinFX release&amp;nbsp;should make it a&amp;nbsp;lot easier to keep up with future CTPs.&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=498505" width="1" height="1"&gt;</description></item><item><title>3D for the Rest of Us: Texture Coordinates</title><link>http://blogs.msdn.com/b/danlehen/archive/2005/11/06/489627.aspx</link><pubDate>Mon, 07 Nov 2005 02:05:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:489627</guid><dc:creator>Daniel Lehenbauer</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/danlehen/rsscomments.aspx?WeblogPostID=489627</wfw:commentRss><comments>http://blogs.msdn.com/b/danlehen/archive/2005/11/06/489627.aspx#comments</comments><description>&lt;P&gt;&lt;STRONG&gt;Introduction&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;People new to 3D are frequently confused by the extra level of indirection introduced by texture coordinates.&amp;nbsp; 3D veterans familiar with texture coordinates from other platforms are sometimes surprised&amp;nbsp;that the default behavior in the Windows Presentation Foundation (formerly code-named Avalon) is a bit different than what they are accustomed to in other 3D APIs.&amp;nbsp; Below is a quick overview of what texture coordinates are and how they are specified.&amp;nbsp; The last section talks about the default behavior in the WPF and how the tradition behavior can be attained by tweaking Brush properties.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;What are Texture Coordinates?&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Texture coordinates specify which part of the Material shows up&amp;nbsp;an which part of the&amp;nbsp;&lt;A href="http://winfx.msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/T_System_Windows_Media_Media3D_MeshGeometry3D.asp"&gt;MeshGeometry3D&lt;/A&gt;.&amp;nbsp; Developers from a 2D background are&amp;nbsp;usually surprised that this is necessary.&amp;nbsp; Most 2D graphics APIs give the users drawing primitives like Ellipses, Rectangles,&amp;nbsp;Paths, etc.&amp;nbsp;with a predefined fill behavior that stretches the brush to the bounds of the given geometry.&amp;nbsp; This is the default in WPF as well.&amp;nbsp; Consider the&amp;nbsp;following diagonal GradientBrush which is white in the upper left corner, red in the middle, and black in the lower right corner:&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&amp;lt;&lt;FONT color=#800000 size=2&gt;LinearGradientBrush&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;x:Key&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;MyGrad&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;StartPoint&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;0,0&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;EndPoint&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;1,1&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;LinearGradientBrush.GradientStops&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;GradientStopCollection&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;GradientStop&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Color&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;#FFFFFF&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Offset&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;0&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;GradientStop&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Color&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;#FF0000&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Offset&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;0.5&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;GradientStop&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Color&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;#000000&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Offset&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;1&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;GradientStopCollection&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;nbsp; &amp;lt;/&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;LinearGradientBrush.GradientStops&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;lt;/&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;LinearGradientBrush&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;By default when a brush is used to fill a 2D geometry the brush is applied relative to the bounding box of the shape.&amp;nbsp; If applied to a Rectangle like the 100x100 square below the entire brush will be visible.&amp;nbsp; If the geometry does not entirely fill it’s bounding box parts of the brush will not be visible.&amp;nbsp; For example, the non-rectangular parallelogram below does not show the extreme white and black corners of the brush.&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&lt;IMG height=204 alt=TextureCoord hspace=0 src="http://blargh.com/~danlehen/TextureCoord.jpg" width=607 border=0&gt;&amp;nbsp;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;People working with 3D for the first time often expect that materials will be similarly stretched to fit the shape of their geometry.&amp;nbsp; Indeed, in my &lt;a href="http://blogs.msdn.com/danlehen/archive/2005/10/16/481597.aspx"&gt;last post&lt;/A&gt; my sample 3D primitives have default texture coordinates which mimic this behavior:&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&lt;IMG alt="" src="http://blargh.com/~danlehen/Visual3DSample.jpg" border=0&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;However, there is no single mapping which provides a reasonable default for all 3D geometry.&amp;nbsp; Even with simple geometry like the 3 quadrics depicted above the method for generating the texture coordinates of the sphere differ from that of the cone and cylinder.&amp;nbsp; In order to make the material wrap sensibly around each primitive I had to&amp;nbsp;explicitly specify&amp;nbsp;a 2D texture coordinate for each 3D position.&amp;nbsp; For example, the cone primitive generates a mesh similar to the one depicted below.&amp;nbsp;&amp;nbsp;Each 3D position in the mesh has a corresponding 2D texture coordinate which&amp;nbsp;maps that 3D position to a 2D coordinate in the material.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&lt;IMG height=306 alt=TextureCoord-2 hspace=0 src="http://blargh.com/~danlehen/TextureCoord-2.jpg" width=756 border=0&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Specifying Texture Coordinates&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;You specify texture coordinates by adding 2D Points to the MeshGeometry3D.TextureCoordinates collection.&amp;nbsp; For example, the following MeshGeometry3D maps the lower right half portion of the material to a triangle:&lt;/P&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;MeshGeometry3D&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Positions&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;-1,1,0 -1,-1,0 1,-1,0&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;TextureCoordinates&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;0,0 0,1 1,1&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;TriangleIndices&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;0,1,2&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; /&amp;gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;&lt;/FONT&gt;
&lt;P&gt;The &lt;EM&gt;i&lt;/EM&gt;th entry in the TextureCoordinates list corresponds to the &lt;EM&gt;i&lt;/EM&gt;th entry in the Positions list, so texture coordinate 0,0 is associated with the vertex at position -1,1,0.&amp;nbsp; The mapping between texture coordinates and positions is depicted below:&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Texture Coordinates&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Rendered Triangle&lt;BR&gt;&lt;/STRONG&gt;&lt;IMG height=274 alt=TextureCoord-3 hspace=0 src="http://blargh.com/~danlehen/TextureCoord-3.jpg" width=596 border=0&gt;&lt;/P&gt;
&lt;P&gt;Of course, this is not the only possibly mapping.&amp;nbsp; If we change the 2nd texture coordinate from 0,1 to 0,0.5 we produce the following image:&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Texture Coordinates&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Rendered Triangle&lt;BR&gt;&lt;/STRONG&gt;&lt;IMG height=271 alt=TextureCoord-4 hspace=0 src="http://blargh.com/~danlehen/TextureCoord-4.jpg" width=600 border=0&gt;&lt;/P&gt;
&lt;P&gt;Notice that the area of the triangle specified by the texture coordinates on the left is stretched to fit the render triangle.&lt;/P&gt;
&lt;P&gt;Texture coordinates are required when using a material with an ImageBrush, DrawingBrush, VisualBrush, LinearGradientBrush,&amp;nbsp;or RadialGradientBrush (i.e., any Brush other than a SolidColorBrush in which case every position in the mesh maps to the same color.)&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Texture Coordinates in the Windows Presentation Foundation&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;There are a couple of behavior differences that 3D veterans should be aware of when working with texture coordinates in the Windows Presentation Foundation.&amp;nbsp; These differences arise from the fact that 3D Materials leverage 2D Brushes as the source of their textures.&amp;nbsp; The wins from being able to take any arbitrary 2D brush and use it to paint a 3D mesh are enormous.&amp;nbsp; However brushes default to behavior which, while traditional for 2D, is sometimes surprising for 3D developers.&amp;nbsp; Fortunately brushes are highly configurable and it is easy to get the typical&amp;nbsp;3D behavior.&lt;/P&gt;
&lt;P&gt;The first difference is that the +Y axis in brush space (and consequently texture coordinate space)&amp;nbsp;points down by default.&amp;nbsp; This is consistent with 2D but different from the traditional 3D coordinate system where the +Y axis points up.&amp;nbsp; In order to get the +Y axis pointing up apply a Y scale of -1 and Y translation of +1:&lt;/P&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;ImageBrush&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Transform&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;scale(1,-1) translate(0,1)&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;ImageSource&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;…&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; /&amp;gt;&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;The second difference is that the brushes default to relative units.&amp;nbsp; At the beginning of this article I discussed how by default the brush maps to the relative bounding box of the 2D geometry it is being used to fill.&amp;nbsp; The same thing happens by default with the bounding box of your texture coordinates.&amp;nbsp; In the above samples I happened to use texture coordinates in the range of 0..1, but texture coordinates&amp;nbsp;of “-20,-20 -20,10 10,10” would have also filled the triangle with the same part of the image.&amp;nbsp; TileBrush’s Viewport property defaults to the rect (0,0)-(1,1) so to get the standard behavior where the bounds of the texture source maps to 0..1 you just need to&amp;nbsp;specify you are using&amp;nbsp;absolute units:&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&amp;lt;&lt;FONT color=#800000 size=2&gt;ImageBrush&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;FONT color=#ff0000 size=2&gt;ViewportUnits&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT color=#000000 size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Absolute&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT color=#000000&gt;" &lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Transform&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;scale(1,-1) translate(0,1)&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;ImageSource&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;…&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; /&amp;gt;&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P dir=ltr&gt;These 2 settings should configure brush / texture space to be identical to what you are probably used to from other APIs.&amp;nbsp; (Incidently, all of these Brush settings have the same&amp;nbsp;affect in 2D as well.)&amp;nbsp; Finally, if you need tiling&amp;nbsp;you turn it on with&amp;nbsp;TileMode=”Tile”.&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=489627" width="1" height="1"&gt;</description></item><item><title>Extending Visual3D - Sphere, Cone, and Cylinder</title><link>http://blogs.msdn.com/b/danlehen/archive/2005/10/16/481597.aspx</link><pubDate>Sun, 16 Oct 2005 20:38:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:481597</guid><dc:creator>Daniel Lehenbauer</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/danlehen/rsscomments.aspx?WeblogPostID=481597</wfw:commentRss><comments>http://blogs.msdn.com/b/danlehen/archive/2005/10/16/481597.aspx#comments</comments><description>&lt;P&gt;&lt;STRONG&gt;Update: &lt;/STRONG&gt;The source has been updated for the &lt;A HREF="/danlehen/archive/2005/12/19/505647.aspx"&gt;December&lt;/A&gt; or &lt;A HREF="/danlehen/archive/2006/01/18/514574.aspx"&gt;January CTP&lt;/A&gt; (either will work).&lt;/P&gt;
&lt;P&gt;In my&amp;nbsp;&lt;A HREF="/danlehen/archive/2005/10/09/478923.aspx"&gt;previous post&lt;/A&gt; I mentioned that one of the motivations for Visual3D was sub-classing.&amp;nbsp; Prior to the September CTP of the Windows Presentation Foundation (formerly code-named Avalon) there was no extensibility point for creating your own 3D scene nodes.&amp;nbsp; One of the many possible uses for this new extensibility point is to build a library of 3D primitives.&amp;nbsp; I put together a short sample which derives a Sphere, a Cone, and a Cylinder primitive from ModelVisual3D.&amp;nbsp; (Source available &lt;A href="http://viewport3d.com/blog_files/Visual3DSample.zip"&gt;here&lt;/A&gt;.)&lt;/P&gt;
&lt;P&gt;&lt;IMG src="http://blargh.com/~danlehen/Visual3DSample.jpg"&gt;&lt;/P&gt;
&lt;P&gt;You will notice that these primitives are directly usable from Xaml:&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;&amp;lt;&lt;FONT color=#800000&gt;Viewport3D Camera=”{Camera}” &lt;/FONT&gt;&lt;FONT color=#0000ff&gt;&amp;gt;&lt;BR&gt;&lt;/FONT&gt;&amp;nbsp; &amp;lt;&lt;FONT color=#800000&gt;my:Sphere3D Transform=”{XForm1}” Material=”{Azul}” /&lt;/FONT&gt;&lt;FONT color=#0000ff&gt;&amp;gt;&lt;BR&gt;&lt;FONT color=#000000&gt;&amp;nbsp; &amp;lt;&lt;/FONT&gt;&lt;FONT color=#800000&gt;my:Cone3D Transform=”{XForm2}” Material=”{Tulips}” /&lt;/FONT&gt;&lt;FONT color=#0000ff&gt;&amp;gt;&lt;BR&gt;&lt;FONT color=#000000&gt;&amp;nbsp; &amp;lt;&lt;/FONT&gt;&lt;FONT color=#800000&gt;my:Cylinder3D Transform=”{XForm3}” Material=”{Autumn}” /&lt;/FONT&gt;&lt;FONT color=#0000ff&gt;&amp;gt;&lt;BR&gt;&lt;FONT color=#000000&gt;&amp;lt;/&lt;/FONT&gt;&lt;FONT color=#800000&gt;Viewport3D&lt;/FONT&gt;&lt;FONT color=#0000ff&gt;&amp;gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;The&amp;nbsp;primitives are centered at the origin and have a natural size of Radius=1 and Height=2 (i.e., they&amp;nbsp;are bounded by&amp;nbsp;(-1,-1,-1) – (1,1,1)).&lt;/P&gt;
&lt;P&gt;This sample does not constitute a terribly complete or expressive library of 3D primitives, but it does illustrate how one could be built.&amp;nbsp; More compelling examples&amp;nbsp;include deriving from Visual3Ds to add new events and behavior (like collision detection) or surfacing properties like databindable properties which dynamically generate 3D charts and graphs.&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=481597" width="1" height="1"&gt;</description></item><item><title>ModelVisual3D vs. Model3DGroup -- When to use which?</title><link>http://blogs.msdn.com/b/danlehen/archive/2005/10/09/478923.aspx</link><pubDate>Mon, 10 Oct 2005 01:44:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:478923</guid><dc:creator>Daniel Lehenbauer</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/danlehen/rsscomments.aspx?WeblogPostID=478923</wfw:commentRss><comments>http://blogs.msdn.com/b/danlehen/archive/2005/10/09/478923.aspx#comments</comments><description>&lt;P&gt;(&lt;STRONG&gt;NOTE:&lt;/STRONG&gt; You might find &lt;a href="http://blogs.msdn.com/karstenj/archive/2005/10/11/479924.aspx"&gt;Karsten's pragmatic perspective&lt;/A&gt;&amp;nbsp;a useful prelude&amp;nbsp;before we dive into the artictural underpinnings.)&lt;/P&gt;
&lt;P&gt;In the&amp;nbsp;September CTP release of the Windows Presentation Foundation (formerly code-named Avalon) we made 3D a first class citizen in the Visual tree with the introducion of&amp;nbsp;Visual3D.&amp;nbsp; Up until this point 3D existed solely as content attached to a 2D Visual .&amp;nbsp; 3D users migrating to the September CTP&amp;nbsp;will encounter the Visual/Content split for the first time.&amp;nbsp; This has lead to some confusion about when&amp;nbsp;nested ModelVisual3Ds should be used to group models together vs. a Model3DGroup.&amp;nbsp; Below is a short description of Visuals and Content and how they fit together.&amp;nbsp; At the end is a concrete example&amp;nbsp;with guidelines on&amp;nbsp;when to use a ModelVisual3D vs. a Model3DGroup.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;What is a Visual?&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;A &lt;A href="http://winfx.msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/T_System_Windows_Media_Visual.asp?frame=true"&gt;Visual&lt;/A&gt; (or Visual3D) is a low-level node in the composition tree.&amp;nbsp; For people coming from a Win32 background a Visual is frequently compared to an HWND:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;A Visual has a graphical representation. 
&lt;LI&gt;A Visual keeps track of its dirty regions. 
&lt;LI&gt;If dirty, a Visual automatically re-renders each frame. 
&lt;LI&gt;Visuals can be composed into trees. 
&lt;LI&gt;A Visual can only be parented once.&amp;nbsp; (i.e., you can not share/reuse Visuals) 
&lt;LI&gt;Visuals can be positioned relative to their parent via a Transform. 
&lt;LI&gt;You can hit test a Visual.&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;There are however some notable differences between Visuals and HWNDs.&amp;nbsp; Probably the most notable is that WPF is a retained graphics architecture.&amp;nbsp; Visuals do not call back to user code to repaint when invalidated.&amp;nbsp; Instead you specify a Visual’s content (i.e., a description of what it should render).&amp;nbsp; If the Visual is dirtied for any reason it automatically repaints the dirty portion from the content specification on the next frame.&amp;nbsp; A sample Visual tree is pictured below:&lt;/P&gt;
&lt;P&gt;&lt;IMG alt=VisualTree[1] src="http://blargh.com/~danlehen/VisualTree.png" border=0&gt;&lt;/P&gt;
&lt;P&gt;Most anything that renders in the WPF derives from&amp;nbsp;Visual.&amp;nbsp; For example,&amp;nbsp;&lt;A href="http://winfx.msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/T_System_Windows_Controls_Control.asp"&gt;Control&lt;/A&gt;s derive from &lt;A href="http://winfx.msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/T_System_Windows_FrameworkElement.asp"&gt;FrameworkElement&lt;/A&gt; which derives from &lt;A href="http://winfx.msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/T_System_Windows_UIElement.asp"&gt;UIElement&lt;/A&gt; which derives from Visual.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;What is Content?&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Content is a description of what a Visual should render.&amp;nbsp; There are a few different APIs for specifying 2D content.&amp;nbsp; Currently in 3D the only way to specify content is via a graph of Model3Ds attached to a ModelVisual3D.&amp;nbsp; Like Visuals, you can build graphs of content using DrawingGroup (2D) or Model3DGroup (3D).&amp;nbsp; You can also position content via a Transform.&amp;nbsp; However, despite these superficial similarities there are important differences between Visuals and content:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Visuals are optimized to be scene nodes.&amp;nbsp; Content are serialized rendering instructions for scene nodes. 
&lt;LI&gt;Visuals are the base class for Shapes and Controls.&amp;nbsp; Content classes are sealed. 
&lt;LI&gt;Visuals are single-use.&amp;nbsp; Content can be shared/reused between Visuals. 
&lt;LI&gt;Visuals support services like hit testing.&amp;nbsp; Content are serialized rendering instructions and&amp;nbsp;nothing else.&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;&lt;STRONG&gt;Where Do Visuals End and Content Begin?&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;The distinction between Visuals and content is usually clear.&amp;nbsp; The one area which&amp;nbsp;can be a bit subjective&amp;nbsp;is whether a set of drawing primitives should be grouped together in content or by a tree of Visuals.&amp;nbsp; To give a concrete example, lets say you have a spaceship mesh that you need to appear three places on screen.&amp;nbsp; Should you use a single Visual that renders 3 spaceships?&lt;/P&gt;
&lt;P&gt;&lt;IMG src="http://blargh.com/~danlehen/Content1.png"&gt; &lt;/P&gt;
&lt;P&gt;Or 3 Visuals which render one spaceship each?&lt;/P&gt;
&lt;P&gt;&lt;IMG src="http://blargh.com/~danlehen/Content2.png"&gt;&lt;/P&gt;
&lt;P&gt;The answer depends.&amp;nbsp; If&amp;nbsp;a cluster of&amp;nbsp;3 spaceships are&amp;nbsp;flying together in tight formation&amp;nbsp;then treating them as a single&amp;nbsp;model may be reasonable, especially if you want several of these clusters cruising around the screen.&amp;nbsp; Or if you have a piece of clip-art featuring three tiny animated spaceships dog fighting around the 3D logo of your&amp;nbsp;BSG fan site you might want to treat the clip-art, spaceships and all, as a single piece of content.&lt;/P&gt;
&lt;P&gt;More typically you will want to each spaceship to be a separate node in the Visual tree.&amp;nbsp; Although you could use DrawingGroup and Model3DGroup to compose everything in your scene (assuming you do not need any Visual services like hit testing), this was not really&amp;nbsp;the intent of DrawingGroup and Model3DGroup.&amp;nbsp; The purpose of DrawingGroup and Model3DGroup is to group together the pieces of a single shareable/reusable drawing or model.&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=478923" width="1" height="1"&gt;</description></item><item><title>Mantis 3D Space Shooter</title><link>http://blogs.msdn.com/b/danlehen/archive/2005/10/03/476733.aspx</link><pubDate>Tue, 04 Oct 2005 08:36:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:476733</guid><dc:creator>Daniel Lehenbauer</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/danlehen/rsscomments.aspx?WeblogPostID=476733</wfw:commentRss><comments>http://blogs.msdn.com/b/danlehen/archive/2005/10/03/476733.aspx#comments</comments><description>&lt;P&gt;
&lt;DIV class=Section1&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Times New Roman" size=3&gt;&lt;SPAN style="FONT-SIZE: 12pt"&gt;When we decided to integrate 3D into the Windows Presentation Foundation (Avalon) the scenarios we were targeting for v1 were:&lt;?xml:namespace prefix = o /&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Times New Roman" size=3&gt;&lt;SPAN style="FONT-SIZE: 12pt"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;UL style="MARGIN-TOP: 0in" type=disc&gt;
&lt;LI class=MsoNormal style="mso-list: l0 level1 lfo1"&gt;&lt;FONT face="Times New Roman" size=3&gt;&lt;SPAN style="FONT-SIZE: 12pt"&gt;3D effects, like a “Next Page” transition that looks like the turning of a page in a book&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt; 
&lt;LI class=MsoNormal style="mso-list: l0 level1 lfo1"&gt;&lt;FONT face="Times New Roman" size=3&gt;&lt;SPAN style="FONT-SIZE: 12pt"&gt;Data visualization (charts, graphs, etc.)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt; 
&lt;LI class=MsoNormal style="mso-list: l0 level1 lfo1"&gt;&lt;FONT face="Times New Roman" size=3&gt;&lt;SPAN style="FONT-SIZE: 12pt"&gt;Catalogs where you can rotate items in 3D&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt; 
&lt;LI class=MsoNormal style="mso-list: l0 level1 lfo1"&gt;&lt;FONT face="Times New Roman" size=3&gt;&lt;SPAN style="FONT-SIZE: 12pt"&gt;3D icons and vector graphics styled on to 2D controls (Buttons, ListViewItems, etc.)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt; 
&lt;LI class=MsoNormal style="mso-list: l0 level1 lfo1"&gt;&lt;FONT face="Times New Roman" size=3&gt;&lt;SPAN style="FONT-SIZE: 12pt"&gt;A mall kiosk which shows an interactive floor plan in 3D&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt; &lt;/LI&gt;&lt;/UL&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Times New Roman" size=3&gt;&lt;SPAN style="FONT-SIZE: 12pt"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Times New Roman" size=3&gt;&lt;SPAN style="FONT-SIZE: 12pt"&gt;…and related scenarios which add a bit of sizzle to traditional applications excluding games.&amp;nbsp; However, while gaming was not a targeted scenario for v1 there is some coincidental overlap which makes WPF a decent option for certain types of games.&amp;nbsp; (Mostly games where you are clicking with the mouse instead of madly staffing. :)&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Times New Roman" size=3&gt;&lt;SPAN style="FONT-SIZE: 12pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Times New Roman" size=3&gt;&lt;SPAN style="FONT-SIZE: 12pt"&gt;One example is &lt;a href="http://blogs.msdn.com/mitchw/archive/2005/09/13/465200.aspx"&gt;Mantis&lt;/A&gt;, a polished looking 3D space shooter that &lt;a href="http://blogs.msdn.com/mitchw"&gt;Mitch Walker&lt;/A&gt; has been building using the Windows Presentation Foundation (Avalon) and Windows Communication Foundation (Indigo).&amp;nbsp; Follow the links to his blog for a description of the project, future directions, and a video snippet of actual game play.&amp;nbsp; Here are a couple of screenshots from Mitch’s blog to entice you:&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Times New Roman" size=3&gt;&lt;SPAN style="FONT-SIZE: 12pt"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;TABLE class=MsoTableGrid style="BORDER-COLLAPSE: collapse" cellSpacing=0 cellPadding=0 border=0&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD style="PADDING-RIGHT: 5.4pt; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0in; WIDTH: 221.4pt; PADDING-TOP: 0in" vAlign=top width=295&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Times New Roman" size=3&gt;&lt;SPAN style="FONT-SIZE: 12pt"&gt;&lt;A href="http://www.mitchw.net/mantis/menu_large.png"&gt;&lt;SPAN style="TEXT-DECORATION: none"&gt;&lt;IMG id=_x0000_i1028 height=180 src="http://www.mitchw.net/mantis/menu_thumb.png" width=240 border=0&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="PADDING-RIGHT: 5.4pt; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0in; WIDTH: 221.4pt; PADDING-TOP: 0in" vAlign=top width=295&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Times New Roman" size=3&gt;&lt;SPAN style="FONT-SIZE: 12pt"&gt;&lt;A href="http://www.mitchw.net/mantis/game_large.png"&gt;&lt;SPAN style="TEXT-DECORATION: none"&gt;&lt;IMG id=_x0000_i1030 height=180 src="http://www.mitchw.net/mantis/game_thumb.png" width=240 border=0&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face=Arial size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;
&lt;P class=MsoNormal&gt;&amp;nbsp;&lt;/P&gt;&lt;/DIV&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=476733" width="1" height="1"&gt;</description></item><item><title>Minor Boing Update for Channel 9 Interview...</title><link>http://blogs.msdn.com/b/danlehen/archive/2005/01/04/346731.aspx</link><pubDate>Wed, 05 Jan 2005 06:10:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:346731</guid><dc:creator>Daniel Lehenbauer</dc:creator><slash:comments>9</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/danlehen/rsscomments.aspx?WeblogPostID=346731</wfw:commentRss><comments>http://blogs.msdn.com/b/danlehen/archive/2005/01/04/346731.aspx#comments</comments><description>&lt;p&gt;I have discovered&amp;nbsp;an effective way to make sure you follow up on your promises: arrange to have them &lt;a href="http://channel9.msdn.com/ShowPost.aspx?PostID=34528#34528"&gt;captured on video&lt;/a&gt;.&amp;nbsp; I&amp;nbsp;had not&amp;nbsp;been&amp;nbsp;able to find the&amp;nbsp;15 minutes to try&amp;nbsp;&lt;a href="http://www.longhornblogs.com/rrelyea/"&gt;Rob&amp;rsquo;s&lt;/a&gt; suggestion for inserting a&amp;nbsp;resource into a collection&amp;nbsp;&lt;a href="http://blogs.msdn.com/danlehen/archive/2004/11/23/268252.aspx"&gt;since November&lt;/a&gt;, but somehow tonight was different.&amp;nbsp; I actually heard from the community before I received the internal email notifying me that the segment had been posted.&amp;nbsp; :)&lt;/p&gt;&lt;p&gt;Here is the &lt;a href="http://blargh.com/~danlehen/Boing-NoCode.zip"&gt;updated source&lt;/a&gt; which no longer uses the WindowsLoaded event.&amp;nbsp; It&amp;rsquo;s now 100% Xaml.&amp;nbsp; The trick I was missing was the &lt;font color="#0000ff" size="2"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#800000" size="2"&gt;x:Include&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt; &lt;/font&gt;&lt;font color="#ff0000" size="2"&gt;x:Content&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;=&lt;/font&gt;&lt;font size="2"&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;{ball}&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt; /&amp;gt;&lt;/font&gt;&amp;nbsp;which is a Xaml element that evaluates to a reference to the resource named &amp;ldquo;ball&amp;rdquo;.&amp;nbsp; This allows me to take the same&amp;nbsp;animated bouncing ball model and insert it into two Viewport3Ds to efficiently create the mirroring effect in Xaml which I was previously falling back to C# in the code-behind to do.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=346731" width="1" height="1"&gt;</description></item><item><title>Bouncing Back...</title><link>http://blogs.msdn.com/b/danlehen/archive/2004/11/23/268252.aspx</link><pubDate>Tue, 23 Nov 2004 08:39:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:268252</guid><dc:creator>Daniel Lehenbauer</dc:creator><slash:comments>19</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/danlehen/rsscomments.aspx?WeblogPostID=268252</wfw:commentRss><comments>http://blogs.msdn.com/b/danlehen/archive/2004/11/23/268252.aspx#comments</comments><description>&lt;div class="Section1"&gt; &lt;p&gt;&lt;font face="Times New Roman" size="3"&gt;&lt;span style="FONT-SIZE: 12pt"&gt;Trying to ease back into the community after a short hiatus, I ported the &lt;span class="SpellE"&gt;Boing&lt;/span&gt; demo that &lt;A href="http://blogs.msdn.com/danlehen/archive/2004/06/01/146259.aspx"&gt;I &lt;span class="SpellE"&gt;blogged&lt;/span&gt; about back in June&lt;/a&gt;&amp;nbsp;to the &lt;A href="http://blogs.msdn.com/danlehen/archive/2004/11/21/267581.aspx"&gt;Avalon CTP build&lt;/a&gt;.&amp;nbsp; &lt;/span&gt;&lt;/font&gt;&lt;font face="Times New Roman" size="3"&gt;&lt;span style="FONT-SIZE: 12pt"&gt;You can get the updated &lt;a href="http://blargh.com/~danlehen/Boing-CTP.zip"&gt;source here&lt;/a&gt;.&amp;nbsp; Just load the solution in to the VS.NET Whidbey Beta and press F5.&amp;nbsp; If you are using &lt;a href="http://lab.msdn.microsoft.com/express/vcsharp/default.aspx"&gt;Visual C# Express&lt;/a&gt;, see RRelyea's notes (&lt;a href="http://www.simplegeek.com/PermaLink.aspx/99113e3e-6d68-4595-ba1a-2b89206a15a9"&gt;via ChrisAn&lt;/a&gt;).&lt;/span&gt;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Times New Roman" size="3"&gt;&lt;span style="FONT-SIZE: 12pt"&gt;You will probably notice that the demo hasn't changed much since WinHEC:&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;/div&gt; &lt;table&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td&gt;&lt;img src="http://blargh.com/~danlehen/Boing.PNG" width="320" /&gt;&lt;/td&gt; &lt;td&gt;&lt;img src="http://blargh.com/~danlehen/Boing-CTP.PNG" width="320" /&gt; &lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;But there &lt;em&gt;are&lt;/em&gt; some&amp;nbsp;differences (mostly in the code):&lt;/p&gt; &lt;ul&gt; &lt;li&gt;It's running on Windows XP (note the Luna theme with blue color scheme - &lt;a href="http://www.msdn.net/Longhorn/understanding/pillars/avalon/avnov04ctp/default.aspx#intro_avalon_ctp_topic5"&gt;blue is very important&lt;/a&gt;!) &lt;li&gt;The source comes in the form of a VS.NET solution. &lt;li&gt;Window1.xaml's code behind is almost empty: &lt;ul&gt; &lt;li&gt;The ball is now animated entirely using the platform animation features instead of a Timer. &lt;li&gt;The ball's geometry is shared via &amp;lt;Application.Resources&amp;gt; in MyApp.xaml instead of being parsed from a string at runtime.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;If you want to have some fun with the animation, try moving the animated RotateTransform3D to the end of the Transform3DCollection to get an effect that looks less like physics and more like poltergeist activity:&lt;/p&gt; &lt;p&gt;&lt;img src="http://blargh.com/~danlehen/Poltergeist.PNG" /&gt;&lt;/p&gt; &lt;p&gt;(If you're not sure what is going on, &lt;A href="http://blogs.msdn.com/danlehen/archive/2004/08/08/210961.aspx"&gt;this might help&lt;/a&gt;.)&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=268252" width="1" height="1"&gt;</description></item><item><title>Avalon CTP released -- Yes it runs on XP!</title><link>http://blogs.msdn.com/b/danlehen/archive/2004/11/21/267581.aspx</link><pubDate>Mon, 22 Nov 2004 01:54:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:267581</guid><dc:creator>Daniel Lehenbauer</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/danlehen/rsscomments.aspx?WeblogPostID=267581</wfw:commentRss><comments>http://blogs.msdn.com/b/danlehen/archive/2004/11/21/267581.aspx#comments</comments><description>&lt;p class="Section1"&gt;&lt;font face="Times New Roman" size="3"&gt;&lt;span style="FONT-SIZE: 12pt"&gt;Like &lt;a href="http://www.simplegeek.com/PermaLink.aspx/45454998-e17a-40b3-8ba5-06da16892e4d"&gt;many&lt;/a&gt;&amp;nbsp;&lt;A href="http://blogs.msdn.com/tims/archive/2004/11/18/265965.aspx"&gt;many&lt;/a&gt; &lt;a href="http://www.sellsbrothers.com/news/showTopic.aspx?ixTopic=1588"&gt;others&lt;/a&gt; I am also excited about the Avalon CTP release for a number of reasons:&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;font face="Times New Roman" size="3"&gt;&lt;span style="FONT-SIZE: 12pt"&gt;&lt;/span&gt;&lt;/font&gt; &lt;div class="Section1"&gt; &lt;ul&gt; &lt;li&gt;It runs on Windows XP!&amp;nbsp; (I no longer need to boot into a separate partition to write samples for my (recently neglected) blog ;) &lt;li&gt;We have the beginnings of tool support!&amp;nbsp; The WinFX SDK installs templates for VS.NET for Avalon projects. &lt;li&gt;The have been numerous advancements across Avalon since WinHEC.&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt; &lt;p&gt;Up until this point only the very brave, installing Longhorn on a spare box and working entirely from the command line, have been able to provide us with feedback.&amp;nbsp; I am hopeful that the CTP release, while still a bit unpolished and clearly not final, will be accessible enough that we will begin to hear more from the community.&lt;/p&gt; &lt;p&gt;How do you get it?&amp;nbsp; It's available for download for &lt;a href="http://msdn.microsoft.com/subscriptions/"&gt;MSDN subscribers&lt;/a&gt; (including Academic Alliance).&lt;br style="mso-special-character: line-break" /&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=267581" width="1" height="1"&gt;</description></item><item><title>The Donut Primitive, V2</title><link>http://blogs.msdn.com/b/danlehen/archive/2004/09/05/225749.aspx</link><pubDate>Sun, 05 Sep 2004 09:05:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:225749</guid><dc:creator>Daniel Lehenbauer</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/danlehen/rsscomments.aspx?WeblogPostID=225749</wfw:commentRss><comments>http://blogs.msdn.com/b/danlehen/archive/2004/09/05/225749.aspx#comments</comments><description>&lt;div class="Section1"&gt; &lt;p&gt;&lt;font face="Times New Roman" size="3"&gt;&lt;span style="FONT-SIZE: 12pt"&gt;I had mentioned previously that I was dissatisfied with the &lt;A href="http://blogs.msdn.com/danlehen/archive/2004/07/19/188075.aspx"&gt;1&lt;sup&gt;st&lt;/sup&gt; post&lt;/a&gt; in the &lt;i style="mso-bidi-font-style: normal"&gt;&lt;span style="FONT-STYLE: italic; mso-bidi-font-style: normal"&gt;3D for the Rest of Us&lt;/span&gt;&lt;/i&gt; series because I felt that the post did not leave the reader with anything they could immediately go out and try.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/span&gt; I was much happier with the 2&lt;sup&gt;nd&lt;/sup&gt; post, even more so now that I have seen &lt;A href="http://blogs.msdn.com/karstenj/archive/0001/01/01/213776.aspx"&gt;The Donut Primitive, V2&lt;/a&gt;.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/span&gt; &lt;span class="GramE"&gt;Apologies for the delay of the 3&lt;sup&gt;rd&lt;/sup&gt; post.&lt;/span&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/span&gt; I was in and out of the office sporadically over August.&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=225749" width="1" height="1"&gt;</description></item><item><title>3D for the Rest of Us, Part 2: Transforms</title><link>http://blogs.msdn.com/b/danlehen/archive/2004/08/08/210961.aspx</link><pubDate>Sun, 08 Aug 2004 22:44:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:210961</guid><dc:creator>Daniel Lehenbauer</dc:creator><slash:comments>16</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/danlehen/rsscomments.aspx?WeblogPostID=210961</wfw:commentRss><comments>http://blogs.msdn.com/b/danlehen/archive/2004/08/08/210961.aspx#comments</comments><description>&lt;p&gt;&lt;b&gt;Introduction&lt;/b&gt; &lt;/p&gt;&lt;p&gt;This is the second in a series of posts intended to fill in the missing pieces for a developer familiar with a 2D graphics API who wants to dabble in 3D with the Avalon platform To be honest, I really was not particularily happy with the &lt;a href="http://blogs.msdn.com/danlehen/archive/2004/07/19/188075.aspx"&gt;first article&lt;/a&gt;. I wanted this series to be a very pragmatic introduction to 3D graphics and my last article quickly veered into into the abstract with its discussion about model space vs. world space. I aim to correct that this time around. This time we will be exploring transforms and using them to construct the 3D axis model we saw in the &lt;a href="http://blogs.msdn.com/danlehen/archive/2004/07/19/188075.aspx"&gt;previous article&lt;/a&gt;.&amp;nbsp; Along the way we will need to acquaint ourselves with several classes in the System.Windows.Media3D namespace.&lt;/p&gt;&lt;p&gt;&lt;a href="http://longhorn.msdn.microsoft.com/?//longhorn.msdn.microsoft.com/lhsdk/ref/ns/system.windows.media3d/c/model3d/model3d.aspx"&gt;&lt;strong&gt;Model3D&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Model3D is the abstract base class for any object which participates as a node in the 3D scene graph. From 2D you are probably familiar with building UI by creating a tree of&amp;nbsp;UIElements (or controls, or HWNDs, etc. depending on the terminology used by your favorite platform). Each&amp;nbsp;element probably surfaced properties like Top, Left, Width, and Height, etc. to position and size the child control relative to its parent. Model3D is similar to the&amp;nbsp;element base class from your favorite 2D platform. You create a 3D scene by building a graph of objects which all derive from Model3D. Model3D has a &lt;a href="http://longhorn.msdn.microsoft.com/?//longhorn.msdn.microsoft.com/lhsdk/ref/ns/system.windows.media3d/c/model3d/p/transform.aspx"&gt;Transform property&lt;/a&gt; which can be used to position, size, and orient the Model3D relative to its parent.&lt;/p&gt;&lt;p&gt;The comparison with&amp;nbsp;UIElement is not entirely accurate, however. UIElements are heavier weight objects which support layout, events, are extensible, etc. Model3Ds are light weight sealed graphics primitives. &lt;/p&gt;&lt;p&gt;&lt;a href="http://longhorn.msdn.microsoft.com/?//longhorn.msdn.microsoft.com/lhsdk/ref/ns/system.windows.media3d/c/model3dcollection/model3dcollection.aspx"&gt;&lt;strong&gt;Model3DCollection&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;p&gt;The Model3DCollection is a concrete subclass of Model3D. The purpose of a Model3DCollection is to group a set of Model3Ds together so they can be transform (moved, rotated, scaled, etc.) together. Continuing the&amp;nbsp;UIElement analogy, a Model3DCollection would be like a container&amp;nbsp;element (or panel, canvas, etc.) You add Model3Ds to a Model3DCollection via the &lt;a href="http://longhorn.msdn.microsoft.com/?//longhorn.msdn.microsoft.com/lhsdk/ref/ns/system.windows.media3d/c/model3dcollection/p/children.aspx"&gt;Children property&lt;/a&gt;. &lt;/p&gt;&lt;p&gt;&lt;b&gt;Example:&lt;/b&gt; &lt;/p&gt;&lt;pre&gt;Model3DCollection group = new Model3DCollection();&lt;br /&gt;group.Children.Add(myModel1);&lt;br /&gt;group.Children.Add(myModel2);&lt;br /&gt;group.Transform = new TranslateTransform3D(...); // Move entire group&lt;/pre&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://longhorn.msdn.microsoft.com/?//longhorn.msdn.microsoft.com/lhsdk/ref/ns/system.windows.media3d/c/transform3d/transform3d.aspx"&gt;&lt;strong&gt;Transform3D&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;We talked about transforms at a high level in the &lt;a href="http://blogs.msdn.com/danlehen/archive/2004/07/19/188075.aspx"&gt;first article&lt;/a&gt;. Transform3D is the abstract base class for our 3D transform classes. &lt;/p&gt;&lt;p&gt;&lt;a href="http://longhorn.msdn.microsoft.com/?//longhorn.msdn.microsoft.com/lhsdk/ref/ns/system.windows.media3d/c/translatetransform3d/translatetransform3d.aspx"&gt;&lt;strong&gt;TranslateTransform3D&lt;/strong&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;&lt;p&gt;Applying a TranslateTransform3D to a Model3D effectively moves all of the points in the Model3D in the direction of the supplied &lt;a href="http://longhorn.msdn.microsoft.com/?//longhorn.msdn.microsoft.com/lhsdk/ref/ns/system.windows.media3d/c/translatetransform3d/p/offset.aspx"&gt;offset vector&lt;/a&gt;. For example, an offset vector of &amp;lt;0,1.6,1&amp;gt; would move the point (4,4,4) to (4,5.6,5). (I say effectively because as we discussed &lt;a href="http://blogs.msdn.com/danlehen/archive/2004/07/19/188075.aspx"&gt;last time&lt;/a&gt; we are not modifying the value of our point. The point is still (4,4,4) in model space. What we have done is change our local frame of reference so that (4,4,4) in model space is (4,5.6,5) in world space.)&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;img src="http://blargh.com/~danlehen/Transforms-Translate.png" border="0"&gt; &lt;/p&gt;&lt;p&gt;&lt;b&gt;Example:&lt;/b&gt; &lt;/p&gt;&lt;pre&gt;myModel.Transform = new TranslateTransform3D(new Vector3D(0, 1.6, 1));&lt;/pre&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://longhorn.msdn.microsoft.com/?//longhorn.msdn.microsoft.com/lhsdk/ref/ns/system.windows.media3d/c/scaletransform3d/scaletransform3d.aspx"&gt;&lt;strong&gt;ScaleTransform3D&lt;/strong&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;&lt;p&gt;ScaleTransform3D effectively scales the model by the given &lt;a href="http://longhorn.msdn.microsoft.com/?//longhorn.msdn.microsoft.com/lhsdk/ref/ns/system.windows.media3d/c/scaletransform3d/p/scalevector.aspx"&gt;scale vector&lt;/a&gt; about the given &lt;a href="http://longhorn.msdn.microsoft.com/?//longhorn.msdn.microsoft.com/lhsdk/ref/ns/system.windows.media3d/c/scaletransform3d/p/scalecenter.aspx"&gt;center point&lt;/a&gt;. Applying a uniform scale (a scale where the scale vector has the same value for X, Y, and Z) proportionally changes the size of the object. For example, a scale of &amp;lt;0.5,0.5,0.5&amp;gt; would make the object 1/2 of its original size while a scale of &amp;lt;2,2,2&amp;gt; would double the model's size. (A scale of &amp;lt;1,1,1&amp;gt; leaves the object the same size). Applying a non-uniform scale (one where the values of X, Y, Z differ) "stretches" or "squishes" the model. For example, &amp;lt;1,2,1&amp;gt; would leave the model the same width and thickness, but make it twice as tall.&lt;/p&gt;&lt;p&gt;By default, scaling causes vertices to expand or contract about the origin (0,0,0) which may not always be the desired behavior. Consider a line segment with points at (2,2,2) and (4,4,4). Applying a uniform scale of &amp;lt;0.1, 0.1, 0.1&amp;gt; you quite possibly want to resize the line segment "in place". That is, since the original center of the segment was at (3,3,3) you expect the new segment to be (2.9,2.9,2,9) - (3.1,3.1,3.1). In actuality what happens is that each component of the end points is multiplied by 0.1 and you get the segment (0.2, 0.2, 0.2) - (0.4, 0.4, 0.4) which is of the expected length, but the position has translated towards the origin. It is common practice to author models with the center about the origin and translate them into place to avoid this issue, but in cases where this is not convenient the ScaleTransform3D offers a &lt;a href="http://longhorn.msdn.microsoft.com/?//longhorn.msdn.microsoft.com/lhsdk/ref/ns/system.windows.media3d/c/scaletransform3d/p/scalecenter.aspx"&gt;ScaleCenter property&lt;/a&gt; which allows you to specify the point in 3-space you would like the scale to expand/contract about. If you choose this point to be the perceived center of your model your model will scale "in place". (In actuality what is happening when you define the ScaleCenter is that model space is scaled and then translated to put the center point back in it's original position in world space.)&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;img src="http://blargh.com/~danlehen/Transforms-Scale.png" border="0"&gt; &lt;/p&gt;&lt;p&gt;&lt;b&gt;Example:&lt;/b&gt; &lt;/p&gt;&lt;pre&gt;myModel.Transform = new ScaleTransform3D(new Vector3D(2, 2, 2));&lt;/pre&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://longhorn.msdn.microsoft.com/?//longhorn.msdn.microsoft.com/lhsdk/ref/ns/system.windows.media3d/c/rotatetransform3d/rotatetransform3d.aspx"&gt;&lt;strong&gt;RotateTransform3D&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt; &lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;p&gt;RotateTransform3D effectively rotates a model the &lt;a href="http://longhorn.msdn.microsoft.com/?//longhorn.msdn.microsoft.com/lhsdk/ref/ns/system.windows.media3d/c/rotatetransform3d/p/angle.aspx"&gt;specified number of degrees&lt;/a&gt; about the &lt;a href="http://longhorn.msdn.microsoft.com/?//longhorn.msdn.microsoft.com/lhsdk/ref/ns/system.windows.media3d/c/rotatetransform3d/p/axis.aspx"&gt;specified axis&lt;/a&gt;. The figures below illustrate rotation about the three cardinal axes.&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;img src="http://blargh.com/~danlehen/Transforms-Rotate.png" border="0"&gt; &lt;/p&gt;&lt;p&gt;As we mentioned previously, Avalon 3D is a &lt;a href="http://msdn.microsoft.com/archive/default.asp?url=/archive/en-us/directx9_m/directx/direct3d/gettingstarted/3dcoordinatesystems/coordinatesystems.asp"&gt;right handed&lt;/a&gt; platform which means that if curl your fingers and point the thumb of your right hand in the direction of the axis your are rotating about the direction of the curl of your fingers is the direction of rotation with a positive value for angle (counter-clockwise). Similar to ScaleTransform3D, RotateTransform3D exposes a &lt;a href="http://longhorn.msdn.microsoft.com/?//longhorn.msdn.microsoft.com/lhsdk/ref/ns/system.windows.media3d/c/rotatetransform3d/p/center.aspx"&gt;Center property&lt;/a&gt; which allows you to control the center of rotation:&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;img src="http://blargh.com/~danlehen/Transforms-Rotate2.png" border="0"&gt; &lt;/p&gt;&lt;p&gt;Unlike translation and positive scale transforms which move the origin and change the scale of the coordinate system but leave the cardinal axes pointing in the original direction, rotation changes the direction of the axes in model space. (Aside: a negative scalar will invert the axis which effectively mirrors the model.) &lt;/p&gt;&lt;p&gt;&lt;img src="http://blargh.com/~danlehen/Transforms-Rotate3.png" border="0"&gt; &lt;/p&gt;&lt;p&gt;&lt;b&gt;Example:&lt;/b&gt; &lt;/p&gt;&lt;pre&gt;myModel.Transform = new RotateTransform3D(new Vector3D(0, 1, 0), 45);&lt;/pre&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://longhorn.msdn.microsoft.com/?//longhorn.msdn.microsoft.com/lhsdk/ref/ns/system.windows.media3d/c/transform3dcollection/transform3dcollection.aspx"&gt;&lt;strong&gt;Transform3DCollection&lt;/strong&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;&lt;p&gt;Frequently you want to apply more than one transform to a model (e.g. rotate it and then translate it). A Transform3DCollection allows you to do this. Transforms added to the Transform3DCollection's &lt;a href="http://longhorn.msdn.microsoft.com/?//longhorn.msdn.microsoft.com/lhsdk/ref/ns/system.windows.media3d/c/transform3dcollection/p/children.aspx"&gt;Children property&lt;/a&gt; are applied to the model in first to last order. Ordering is important because translating and then rotating does not yield the same result as rotating and then translating: &lt;/p&gt;&lt;p&gt;&lt;img src="http://blargh.com/~danlehen/Transforms-Order.png" border="0"&gt; &lt;/p&gt;&lt;p&gt;This assumes rotation about the origin. Remember that using the Center property you could have rotated about the point (1,0,0) in figure 5b which would have then rotated the square "in place" and yielded the same end result as Figure 5a. Because geometry is typically modeled about the origin, first sizing the model (scale), then orientating it (rotate), and then moving it to the desired location (translate) commonly results in the desired outcome. There are scenarios where you do want different orderings (e.g., you want to pivot the translated model as shown in 5b). In my experience I find that it usually&amp;nbsp;is more natural to add more hierarchy to your scene (in this case meaning a parent Model3DCollection which rotates the translated child), but there are exceptions of course. &lt;/p&gt;&lt;p&gt;&lt;b&gt;Example:&lt;/b&gt; &lt;/p&gt;&lt;pre&gt;Transform3DCollection xforms = new Transform3DCollection();&lt;br /&gt;xforms.Children.Add(new ScaleTransform3D(...));&lt;br /&gt;xforms.Children.Add(new RotateTransform3D(...));&lt;br /&gt;xforms.Children.Add(new TranslateTransform3D(...));&lt;br /&gt;myModel.Transform = xforms;&lt;/pre&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Building the Axes Model&lt;/b&gt; &lt;/p&gt;&lt;p&gt;We are now to the "hands-on" portion of this article. In &lt;a href="http://blogs.msdn.com/danlehen/archive/2004/07/19/188075.aspx"&gt;part 1&lt;/a&gt; I used a model of the three cardinal axes in my illustrations for which I &lt;a href="http://simplegeek.com/PermaLink.aspx/610f9420-321c-4d75-94a5-03005cb0f67d"&gt;conspicuously did not provide source&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;img src="http://blargh.com/~danlehen/Axii-0-0-5.PNG" border="0"&gt; &lt;/p&gt;&lt;p&gt;This time you get the source, at least most of it. Building the scene graph for the axes model has been removed and left as an exercise for the reader. You will find a comment in the OnLoaded handler in Window1.xaml.cs indicating where this should be done. The code contains a cylinder and cone models as well as models of the letters used to label the axes. (All converted with &lt;a href="http://blogs.msdn.com/danlehen/archive/2004/06/11/154028.aspx"&gt;IanG's x-to-xaml converter&lt;/a&gt;). Your task is to use Model3DCollections with the various Transform3Ds we have been discussing to construct the scene graph for the axes shown above. (Download the &lt;a href="http://blargh.com/~danlehen/Transforms-src.zip"&gt;source here&lt;/a&gt;.) &lt;/p&gt;&lt;p&gt;&lt;b&gt;Step 1: Building a reusable arrow&lt;/b&gt; &lt;/p&gt;&lt;p&gt;The first step will be to build a reusable arrow model from the provided Cone and Cylinder models: &lt;/p&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;img src="http://blargh.com/~danlehen/Transform-Cone.PNG" border="0"&gt;&lt;/td&gt;&lt;td&gt;&lt;img src="http://blargh.com/~danlehen/Transform-Cylinder.PNG" border="0"&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;Both models fit approximately into the unit cube (a cube 1.0 units tall, wide, and deep) and are centered about the origin. What you will want to do is apply a non-uniform scale to the cylinder to keep it 1.0 unit tall, but make it "skinnier". You will then want to perform a uniform scale to the cone to make it smaller and translate it to above the cylinder. Finally, you will want to group both of these primitives together into a Model3DCollection to create an arrow Model3D that you can re-use in your scene. This part of the scene graph will look roughly like this:&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;img src="http://blargh.com/~danlehen/Transforms-Arrow.png" border="0"&gt; &lt;/p&gt;&lt;p&gt;With some experimentation you should be able to create an arrow which looks approximately like this:&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;img src="http://blargh.com/~danlehen/Transforms-Arrow2.PNG" border="0"&gt; &lt;/p&gt;&lt;p&gt;&lt;b&gt;Step 2: Composing arrows into the axes&lt;/b&gt;&lt;/p&gt;&lt;p&gt;The next step is to take our newly created arrow model, orientate and translate it into position, and then draw it for each of the cardinal axes. This raises the question how do we get our arrow to draw 3 times. One solution would be to use the Copy() method to clone the arrow so we have three copies which can then be grouped under a single Model3DCollection:&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;img src="http://blargh.com/~danlehen/Transform-Axes.png" border="0"&gt; &lt;/p&gt;&lt;p&gt;This works, however each of those arrows models contains an identical copy of the same 3D geometry. A lighter weight solution is to take advantage of multiparenting of Model3Ds to draw the same arrow three times, but adding new transforms each time to position it differently. &lt;/p&gt;&lt;p&gt;&lt;img src="http://blargh.com/~danlehen/Transform-Axes2.png" border="0"&gt; &lt;/p&gt;&lt;p&gt;Using multiparenting when possible conserves memory and is considered a best practice, but either approach is fine for a small model like our axes. Whichever method you choose, the result you are looking for at the end of step 2 is:&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;img src="http://blargh.com/~danlehen/Transform-Axes3.PNG" border="0"&gt; &lt;/p&gt;&lt;p&gt;&lt;b&gt;Step 3: Adding the axis labels&lt;/b&gt; &lt;/p&gt;&lt;p&gt;The finishing touch is to reapply the same techniques to add the letter models to the scene to label the axes. As an added challenge my 3D modeler exported these models such that by default the infinitly thin edge is facing the camera. The models pictured below have been rotated 90 degrees about the Y-axis to make them visible: &lt;/p&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;img src="http://blargh.com/~danlehen/Transform-X.PNG" border="0"&gt;&lt;/td&gt;&lt;td&gt;&lt;img src="http://blargh.com/~danlehen/Transform-Y.PNG" border="0"&gt;&lt;/td&gt;&lt;td&gt;&lt;img src="http://blargh.com/~danlehen/Transform-Z.PNG" border="0"&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;You may want to add a rotation to your top Model3DCollection to view the finished result from a few angles to verify that your Z-axis is as expected: &lt;/p&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;img alt="" hspace="0" src="http://blargh.com/~danlehen/Axii-0-0-5.PNG" align="baseline" border="0"&gt; &lt;td&gt;&lt;img alt="" hspace="0" src="http://blargh.com/~danlehen/Axii-3-3--3.PNG" align="baseline" border="0"&gt; &lt;td&gt;&lt;img alt="" hspace="0" src="http://blargh.com/~danlehen/Axii-3-3--3_inverted.PNG" align="baseline" border="0"&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;b&gt;Conclusion&lt;/b&gt; &lt;/p&gt;&lt;p&gt;At this point you have now built your first scene graph. Along the way he have learned about grouping Model3Ds with a Model3DCollection and we have covered the 3 basic Transform3Ds and learned about combining them with a Transform3DCollection. Next time we will look at the ViewPort3D and Camera classes which will get you well on your way to building your first 3D application "from scratch".&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=210961" width="1" height="1"&gt;</description></item><item><title>Interpreted Python and WindowsForms experiment</title><link>http://blogs.msdn.com/b/danlehen/archive/2004/07/31/203250.aspx</link><pubDate>Sun, 01 Aug 2004 03:47:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:203250</guid><dc:creator>Daniel Lehenbauer</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/danlehen/rsscomments.aspx?WeblogPostID=203250</wfw:commentRss><comments>http://blogs.msdn.com/b/danlehen/archive/2004/07/31/203250.aspx#comments</comments><description>&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;I have been shopping around for a while now for a dynamic language to use when prototyping pet projects at home.&amp;nbsp; Everything I read about &lt;a href="http://www.python.org/"&gt;Python&lt;/a&gt; seemed perfect except, of course, &amp;nbsp;the lack of a .NET compiler.&amp;nbsp; This week &lt;a href="http://hugunin.net/"&gt;Jim Hugunin&lt;/a&gt;&amp;nbsp;of Jython fame&amp;nbsp;finally dropped the first binary build of &lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;&lt;a href="http://ironpython.com/"&gt;IronPython&lt;/a&gt; (Python for .NET).&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;According to the readme.htm you can build regular IL assemblies (.exes and .dlls) with IronPython, but what I have been playing with is the interpreted python console.&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;Something I&amp;nbsp;was pleasantly surprised to find was&amp;nbsp;how well the design goals of&amp;nbsp;&lt;a href="http://windowsforms.net/"&gt;WindowsForms&lt;/a&gt;&amp;nbsp;mesh with the needs of&amp;nbsp;interpreted languages.&amp;nbsp; I think there are two reasons for this:&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt 39pt; TEXT-INDENT: -0.25in; mso-list: l0 level1 lfo1; tab-stops: list 39.0pt"&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Symbol; mso-fareast-font-family: Symbol; mso-bidi-font-family: Symbol"&gt;&lt;span style="mso-list: Ignore"&gt;·&lt;span style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;We have tried to avoid invalid states (e.g., for the most part you can set properties in any order, you can call methods at any time, etc.)&amp;nbsp; This is part of the &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpgenref/html/cpconnetframeworkdesignguidelines.asp"&gt;Managed API Guidelines&lt;/a&gt;&amp;nbsp;and is just common sense when building a predictable platform.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt 39pt; TEXT-INDENT: -0.25in; mso-list: l0 level1 lfo1; tab-stops: list 39.0pt"&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Symbol; mso-fareast-font-family: Symbol; mso-bidi-font-family: Symbol"&gt;&lt;span style="mso-list: Ignore"&gt;·&lt;span style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font face="Arial" size="2"&gt;The second is that WindowsForms supports imperative style programming&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;.&amp;nbsp;&amp;nbsp;When working in a compiled&amp;nbsp;language I tend to follow a pattern of subclassing Form and having all of my child controls encapsulated.&amp;nbsp; When working with the&amp;nbsp;python interpreter I found it easier to write in an imperative style where I instantiate a vanilla Form (i.e., not a MyDialog subclass) and start adding controls to it as follows:&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt 0.5in"&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-bidi-font-family: Arial"&gt;&amp;gt;&amp;gt;&amp;gt; from System.Windows.Forms import *&lt;?xml:namespace prefix ="" o /&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt 0.5in"&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-bidi-font-family: Arial"&gt;&amp;gt;&amp;gt;&amp;gt; f = Form()&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt 0.5in"&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-bidi-font-family: Arial"&gt;&amp;gt;&amp;gt;&amp;gt; b = Button()&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt 0.5in"&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-bidi-font-family: Arial"&gt;&amp;gt;&amp;gt;&amp;gt; def OnClick(sender, args):&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt 0.5in"&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-bidi-font-family: Arial"&gt;...&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;MessageBox.Show("Clicked");&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt 0.5in"&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-bidi-font-family: Arial"&gt;...&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt 0.5in"&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-bidi-font-family: Arial"&gt;&amp;gt;&amp;gt;&amp;gt; b.Click += OnClick&lt;br /&gt;&amp;gt;&amp;gt;&amp;gt; f.Controls.Add(b)&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt 0.5in"&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-bidi-font-family: Arial"&gt;&amp;gt;&amp;gt;&amp;gt; Application.Run(f)&lt;br /&gt;&lt;br /&gt;&lt;font face="Arial"&gt;Which as it turns out, WindowsForms was intentionally engineered to support.&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;Why was WindowsForms engineer to support this you ask?&amp;nbsp; It&amp;nbsp;is because&amp;nbsp;WindowsForms had an interpreter as a customer since day 1: the Visual Studio designer.&amp;nbsp; When you are designing a dialog the designer does not create an instance of your derived class.&amp;nbsp; It creates an instance of the base class (which is essentially a new Form() unless you are designing an inherited Form) and then interprets the code statements in the InitializeComponents() method to populate the form with buttons, checkboxes, etc.&amp;nbsp; (BrianPe goes into the details&amp;nbsp;&lt;a href="http://www.urbanpotato.net/Default.aspx/document/1772"&gt;here&lt;/a&gt;).&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;I have run into a snag, however, while experimenting with WindowsForms.&amp;nbsp;&amp;nbsp;When the&amp;nbsp;Form is closed it is automatically disposed which means you can not tweak it and then Application.Run(f) a second time because WindowsForms does not allow resurrection of a Disposed() class.&amp;nbsp; This kills iterative development which is pretty much the whole goal of an interpreted language.&amp;nbsp; I haven't played with it long enough to know if there is a work around (I suspect with some foresight one could sink the Closing event to Hide() rather than Close() because I seem to recall that the&amp;nbsp;Closing event was cancelable).&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;&lt;o:p&gt;When I get a chance I would like to recompile IronPython with the CLR build from Longhorn 4074 and see how Avalon fairs in the same scenario.&amp;nbsp; We have an intrinsic advantage in that so far we have avoided needing the Dispose() pattern for our controls.&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;&lt;o:p&gt;Oh, and if you miss &lt;a href="http://weblogs.asp.net/jasonz/archive/2004/07/28/200404.aspx"&gt;the news&lt;/a&gt;, Jim Hugunin is starting his first day as a Microsoft employee on Monday.&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=203250" width="1" height="1"&gt;</description></item><item><title>3D for the Rest of Us, Part 1: 3D Coordinate System</title><link>http://blogs.msdn.com/b/danlehen/archive/2004/07/19/188075.aspx</link><pubDate>Tue, 20 Jul 2004 02:05:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:188075</guid><dc:creator>Daniel Lehenbauer</dc:creator><slash:comments>28</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/danlehen/rsscomments.aspx?WeblogPostID=188075</wfw:commentRss><comments>http://blogs.msdn.com/b/danlehen/archive/2004/07/19/188075.aspx#comments</comments><description>&lt;P&gt;&lt;STRONG&gt;Introduction&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;A &lt;A href="http://www.simplegeek.com/PermaLink.aspx/db66cde8-90a0-4a9e-a856-400cf6e11da8"&gt;hallway conversation&lt;/A&gt; which &lt;A href="http://www.simplegeek.com/"&gt;Chris Anderson&lt;/A&gt;&amp;nbsp;made me realize that when people ask me about 3D support in Avalon I have a bad habit of telling them &lt;A href="http://blogs.msdn.com/danlehen/archive/2004/06/27/167463.aspx"&gt;everything they do not need to know&lt;/A&gt;.&amp;nbsp; After all, it is all the details you do not have to worry about that consume the waking hours of our 3D team (and it is what gives the Avalon 3D platform its value.)&amp;nbsp; However, despite our efforts to abstract the hardware, to encapsulate the mathematics, and to keep the 2D and 3D APIs symmetrical, there are some concepts which are inherently unique to 3D such as cameras and lighting.&lt;/P&gt;
&lt;P&gt;This is the first in&amp;nbsp;a series of posts intended to fill in the missing pieces for a developer familiar with a 2D graphics API who wants to dabble in 3D with the Avalon platform.&amp;nbsp; The topics I initially intend to cover are:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;The 3D coordinate system 
&lt;LI&gt;Transforms - (&lt;A href="http://blogs.msdn.com/danlehen/archive/2004/08/08/210961.aspx"&gt;Part 2 now online&lt;/A&gt;) 
&lt;LI&gt;The Camera 
&lt;LI&gt;Defining 3D Geometry 
&lt;LI&gt;Lighting 
&lt;LI&gt;Materials&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;...but I am happy to adjust according to feedback.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;The 3D Coordinate System&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Most people are aware that 3D adds an extra dimension, Z,&amp;nbsp;perpendicular to the X and Y they are familiar with from 2D.&amp;nbsp; The 3D coordinate system is frequently explained to 2D developers as follows:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;The origin is now in the center of the screen instead of the upper left. 
&lt;LI&gt;The positive X axis still points right, but Y now points up instead of down. 
&lt;LI&gt;There is a new axis, Z, that points out of the screen (assuming a &lt;A href="http://msdn.microsoft.com/archive/default.asp?url=/archive/en-us/directx9_m/directx/direct3d/gettingstarted/3dcoordinatesystems/coordinatesystems.asp"&gt;right handed&lt;/A&gt; coordinate system like Avalon).&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;This is expressed pictorially in figures 1 and 2 below:&lt;/P&gt;
&lt;P&gt;&lt;IMG alt="" hspace=0 src="http://blargh.com/~danlehen/CoordSystem-1.png" align=baseline border=0&gt;&lt;/P&gt;
&lt;P&gt;The issue with this description is that while we &lt;EM&gt;can&lt;/EM&gt; choose a camera orientation consistent with the above criteria (Figure 3) we can also choose vantage points like Figures 4&amp;nbsp;or even turn the camera upside down like Figure 5.&lt;/P&gt;
&lt;P&gt;
&lt;TABLE&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD&gt;&lt;IMG alt="" hspace=0 src="http://blargh.com/~danlehen/Axii-0-0-5.PNG" align=baseline border=0&gt; 
&lt;TD&gt;&lt;IMG alt="" hspace=0 src="http://blargh.com/~danlehen/Axii-3-3--3.PNG" align=baseline border=0&gt; 
&lt;TD&gt;&lt;IMG alt="" hspace=0 src="http://blargh.com/~danlehen/Axii-3-3--3_inverted.PNG" align=baseline border=0&gt; &lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;&lt;PRE&gt;LookAtPoint=(0,0,0)&lt;BR&gt;Position=(0,0,5)&lt;BR&gt;Up=(0,1,0)&lt;/PRE&gt;
&lt;CENTER&gt;Figure 3&lt;/CENTER&gt;
&lt;TD&gt;&lt;PRE&gt;LookAtPoint=(0,0,0)&lt;BR&gt;Position=(3,3,-3)&lt;BR&gt;Up=(0,1,0)&lt;/PRE&gt;
&lt;CENTER&gt;Figure 4&lt;/CENTER&gt;
&lt;TD&gt;&lt;PRE&gt;LookAtPoint=(1,1,0)&lt;BR&gt;Position=(3,3,-3)&lt;BR&gt;Up=(0,-1,0)&lt;/PRE&gt;
&lt;CENTER&gt;Figure 5&lt;/CENTER&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;The global frame of reference (aka World Space)&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;From Figures 3-5 hopefully the reader begins to get a sense that there exists a space created by the 3 perpendicular axes.&amp;nbsp; This space is commonly referred to as world space.&amp;nbsp; World space extends infinitely in both the positive and negative directions for all three axes.&amp;nbsp; In the above screenshots (Figures 3-5), the three axes always meet at (0,0,0) in world space (even&amp;nbsp;though the location on the screen changes).&amp;nbsp; In world space, the model of the arrow labeled X extends along the positive X-axis &amp;lt;1,0,0&amp;gt;, the Y arrow along &amp;lt;0,1,0&amp;gt;, and the Z along &amp;lt;0,0,1&amp;gt;.&amp;nbsp; Again this is true in all three screenshots (Figures 3-5) even though the directions appear to change based on the camera orientation.&lt;/P&gt;
&lt;P&gt;The point is, we can position our camera anywhere in&amp;nbsp;world space and point it in any direction to generate images, but moving the camera does not change where things exist in world space.&amp;nbsp; World space is the stationary global frame of reference.&amp;nbsp; Since we are not focusing on positioning the camera this time around we will choose to adopt an orientation like Figure&amp;nbsp;6 (which was used to make the screenshot in Figure 3)&amp;nbsp;for the remainder of this post.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;&lt;IMG alt="" hspace=0 src="http://blargh.com/~danlehen/CoordSystem-6.png" align=baseline border=0&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Local Frames of Reference (aka Model space)&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;The fact that I stated that world space is the global frame of&amp;nbsp;reference&amp;nbsp;implies that there are other frames of reference.&amp;nbsp; Each&amp;nbsp;model object&amp;nbsp;has a Transform property which we can use to move, size, orientate, etc. the model.&amp;nbsp;&amp;nbsp;When we do this, we create a local frame of reference.&amp;nbsp; These local frames of references are commonly referred to as model spaces.&amp;nbsp; The concept of model spaces also exists in 2D, although we do not call them that.&amp;nbsp; Consider a canvas which contains a red rectangle&amp;nbsp;defined&amp;nbsp;to&amp;nbsp;as&amp;nbsp;(0,0)-(100,100) relative to the canvas:&lt;/P&gt;
&lt;P&gt;&lt;IMG alt="" hspace=0 src="http://blargh.com/~danlehen/CoordSystem-7.png" align=baseline border=0&gt; 
&lt;TABLE&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;Now consider Figure 8 which shows the canvas in relation to the screen.&amp;nbsp; Here we can see that while the rectangle exists in (0,0) - (100,100) relative to the canvas' local frame of reference, it may actually occupy (50,50)-(150,150) on the screen. 
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;In 3D,&amp;nbsp;it is&amp;nbsp;common practice&amp;nbsp;to author your geometry centered about the origin&amp;nbsp;like the teapot shown in Figure 9.&lt;BR&gt;&amp;nbsp;&lt;/P&gt;
&lt;TBODY&gt;&lt;/TBODY&gt;&lt;/P&gt;&lt;/TABLE&gt;
&lt;TABLE&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD&gt;&lt;IMG alt="" hspace=0 src="http://blargh.com/~danlehen/Teapot-Origin.PNG" align=baseline border=0&gt;&lt;/TD&gt;
&lt;TR&gt;
&lt;TD&gt;
&lt;CENTER&gt;Figure 9&lt;/CENTER&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;BR&gt;And then use the three basic transforms (translate, scale, and rotate) to position, size and orientate the model to where you want it in world space.&amp;nbsp; The Avalon 3D object model exposes these transforms as the TranslateTransform3D, ScaleTransform3D and RotateTransform3D classes.&amp;nbsp; Like the camera, we will touch on how to configure these transform classes in a future post.&amp;nbsp; The point we want to make this time is that just like in Figure 8 where when the canvas is moved the rectangle is still defined as (0,0)-(100,100), when you apply a transform to a model 3D you are transforming the space in which the model is defined rather than the positions of the points in the geometry.&amp;nbsp; This local frame of reference is called model space.&lt;/P&gt;
&lt;TABLE&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD&gt;&lt;IMG alt="" hspace=0 src="http://blargh.com/~danlehen/Teapot-T.PNG" align=baseline border=0&gt; 
&lt;TD&gt;&lt;IMG alt="" hspace=0 src="http://blargh.com/~danlehen/Teapot-TS.PNG" align=baseline border=0&gt; 
&lt;TD&gt;&lt;IMG alt="" hspace=0 src="http://blargh.com/~danlehen/Teapot-TSR.PNG" align=baseline border=0&gt; &lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;
&lt;CENTER&gt;&lt;SMALL&gt;translate&lt;/SMALL&gt;&lt;BR&gt;Figure 10&lt;/CENTER&gt;
&lt;TD&gt;
&lt;CENTER&gt;&lt;SMALL&gt;translate &amp;amp; scale&lt;/SMALL&gt;&lt;BR&gt;Figure 11&lt;/CENTER&gt;
&lt;TD&gt;
&lt;CENTER&gt;&lt;SMALL&gt;translate, scale, and rotate&lt;/SMALL&gt;&lt;BR&gt;Figure 12&lt;/CENTER&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;
&lt;P&gt;Figures 10 through 12 show the effects of the basic transforms when applied to our teapot model.&amp;nbsp; A second axis has been added to show the effect this has on the model space of the teapot.&amp;nbsp; In Figure 10 we can see that when we add a translation of &amp;lt;0.5, 0,5, 0.5&amp;gt; this moved the teapot up, right, and towards the viewer.&amp;nbsp; This also created a model space where (0,0,0) in the model space is equal to (0.5, 0.5, 0.5) in the global world space.&lt;/P&gt;
&lt;P&gt;Similarly, Figure 11 illustrates that adding a uniform scale of 0.5 not only scales the teapot, but also scales the local model space in which the teapot resides.&amp;nbsp; Moving 1 unit in this model space moves 0.5 units in global space.&amp;nbsp; Finally Figure 12 shows that applying a rotation changes the orientation of the teapot and at the same time changes the orientation of model space.&amp;nbsp; Moving along the Z axis in figure 12, for example, causes a change in all of X, Y, and Z in world space.&lt;/P&gt;
&lt;P&gt;The importance of model space will became more clear next time when we investigate the transforms and the Model3DCollection class which allows us to build hierarchies of model spaces that allow us to do things like take the cone and cylinder which make one of the arrows in the axes we have been seeing in the screenshots and treat them as one "arrow" model even though they are separate primitives.&lt;/P&gt;
&lt;P&gt;Continue: &lt;A href="http://blogs.msdn.com/danlehen/archive/2004/08/08/210961.aspx"&gt;Part 2 now online&lt;/A&gt;&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=188075" width="1" height="1"&gt;</description></item><item><title>3D Graph Demo Posted</title><link>http://blogs.msdn.com/b/danlehen/archive/2004/07/01/171434.aspx</link><pubDate>Fri, 02 Jul 2004 01:36:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:171434</guid><dc:creator>Daniel Lehenbauer</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/danlehen/rsscomments.aspx?WeblogPostID=171434</wfw:commentRss><comments>http://blogs.msdn.com/b/danlehen/archive/2004/07/01/171434.aspx#comments</comments><description>Coincidently, the same day that &lt;A href="http://blogs.msdn.com/danlehen/archive/2004/06/30/170496.aspx"&gt;Kerry Hammil's talk&lt;/A&gt;&amp;nbsp;which featured the 3D Blood Sugar Tracker demo aired &lt;A href="http://www.eightypercent.net/Archive/2004/06/30.html#a193"&gt;Joe Beda&lt;/A&gt; managed to get the &lt;A href="http://www.microsoft.com/downloads/details.aspx?familyid=9C1724D1-B63E-4D7D-835A-FF94A1FAD311&amp;amp;displaylang=en"&gt;source hosted at MSDN&lt;/A&gt;.&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=171434" width="1" height="1"&gt;</description></item><item><title>Avalon 3D Video Segment</title><link>http://blogs.msdn.com/b/danlehen/archive/2004/06/30/170496.aspx</link><pubDate>Thu, 01 Jul 2004 04:07:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:170496</guid><dc:creator>Daniel Lehenbauer</dc:creator><slash:comments>8</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/danlehen/rsscomments.aspx?WeblogPostID=170496</wfw:commentRss><comments>http://blogs.msdn.com/b/danlehen/archive/2004/06/30/170496.aspx#comments</comments><description>Kerry Hammil, a program manager with the Avalon team, discusses the goals and features of 3D support in Avalon and walks through writing your first Avalon 3D application in this 30 minute video segment (&lt;A href="http://msdn.microsoft.com/seminar/shared/asp/view.asp?url=/longhorn/media/en/2004-06-07%20avalon%203d/manifest.xml&amp;amp;rate=0"&gt;56K&lt;/A&gt;, &lt;A href="http://msdn.microsoft.com/seminar/shared/asp/view.asp?url=/longhorn/media/en/2004-06-07%20avalon%203d/manifest.xml&amp;amp;rate=1"&gt;150K&lt;/A&gt; or &lt;A href="http://msdn.microsoft.com/seminar/shared/asp/view.asp?url=/longhorn/media/en/2004-06-07%20avalon%203d/manifest.xml&amp;amp;rate=2"&gt;300K&lt;/A&gt;).&amp;nbsp; You will want to be sure to stay until the end for the look at future Avalon 3D features and the &lt;FONT color=#000000&gt;3D demos&lt;/FONT&gt; that &lt;A href="http://longhornblogs.com/ndunlap/"&gt;Nathan Dunlap&lt;/A&gt; and others members of our demo team have put together.&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=170496" width="1" height="1"&gt;</description></item><item><title>Avalon 3D Hit Testing Demo</title><link>http://blogs.msdn.com/b/danlehen/archive/2004/06/27/167463.aspx</link><pubDate>Mon, 28 Jun 2004 01:29:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:167463</guid><dc:creator>Daniel Lehenbauer</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/danlehen/rsscomments.aspx?WeblogPostID=167463</wfw:commentRss><comments>http://blogs.msdn.com/b/danlehen/archive/2004/06/27/167463.aspx#comments</comments><description>&lt;P&gt;One area where the Avalon platform blurs the line between 2D and 3D is&amp;nbsp;with our hit testing services.&amp;nbsp; It's easy to discover that we support traditional ray/mesh hit testing via the Model3D.HitTest(...) API, but rarely does the user want to initiate hit testing in world 3-space (this is especially true for the 3D scenarios targeted by Avalon).&amp;nbsp; Consider this simple demo (&lt;A href="http://blargh.com/~danlehen/HitTestDemo-bin.zip"&gt;binary&lt;/A&gt;, &lt;A href="http://blargh.com/~danlehen/HitTestDemo-src.zip"&gt;source&lt;/A&gt;) which displays a rotating teapot which changes color when the user clicks on it.&amp;nbsp; (Demo works on Longhorn build 4074).&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;&lt;IMG alt="" hspace=0 src="http://blargh.com/~danlehen/Teapots.PNG" width=640 align=baseline border=0&gt;&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;Mouse input arrives to us a MouseButtonEventArgs.&amp;nbsp; Using e.GetPosition(myViewPort) we get a 2D point relative to the bounds of our ViewPort3D.&amp;nbsp; How does one go from a 2D point like (327, 216) to knowing which part of the teapot is under the mouse pointer?&amp;nbsp; Further more, we do not just want to know&amp;nbsp;&lt;EM&gt;if&lt;/EM&gt; the teapot was hit, we want to know exactly &lt;EM&gt;where&lt;/EM&gt; (in model space) the teapot was hit and in the case of multiple intersections we want distance information so we can sort our results.&amp;nbsp; (And just to be clear, this is is not bounding box testing.&amp;nbsp; Clicking in the "hole" of the teapot's handle should not register as a hit.)&lt;/P&gt;
&lt;P&gt;&lt;IMG alt="" hspace=0 src="http://blargh.com/~danlehen/Teapot.PNG" align=baseline border=0&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Don't Do This&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;It turns out that this is a platform feature of Avalon so what I am about to&amp;nbsp;describe is exactly what you do &lt;EM&gt;not&lt;/EM&gt; need to know, but ignoring this for the moment the first step would be to use the bounds of the ViewPort3D to normalize the 2D point to the projection plane in post-projective homogeneous space (figure 1).&lt;/P&gt;
&lt;P align=left&gt;&lt;IMG alt="" hspace=0 src="http://blargh.com/~danlehen/HitTest-1.png" align=baseline border=0&gt;&lt;/P&gt;
&lt;P&gt;Of course, in 3-space we are not interested in hit testing a single point.&amp;nbsp; We want to know everything that is under the mouse pointer so we need to project a ray through the point in the&amp;nbsp;viewing direction (figure 2).&amp;nbsp; In&amp;nbsp;post-projective homogeneous space this is along the Z axis.&amp;nbsp; Next we need to&amp;nbsp;transform our ray back into world space.&amp;nbsp; The implementation varies by camera, but is&amp;nbsp;equivalent to&amp;nbsp;transforming by&amp;nbsp;the inverse of the &lt;A href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/programmingguide/fixedfunction/transforms/projectiontransformation/whatisprojectiontransformation.asp"&gt;projection transform&lt;/A&gt; and &lt;A href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/programmingguide/fixedfunction/transforms/projectiontransformation/whatisprojectiontransformation.asp"&gt;view transform&lt;/A&gt;s.&lt;/P&gt;
&lt;P&gt;This gives us a ray in world space which is exactly the ray you need to provide&amp;nbsp;to Model3D.HitTest(...) at the root of your model hierarchy which will then walk the Model3D hierachy and report which Model3Ds were intersected by the ray.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;What You Want To Do&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;As I mentioned earlier, integrated 2D/3D is a platform feature of Avalon.&amp;nbsp; If you call the 2D hit testing service on IVisual:&lt;/P&gt;&lt;PRE&gt;PointHitTestResult result2D = visual.HitTest(point);&lt;/PRE&gt;
&lt;P&gt;and if a ViewPort3D is hit during the&amp;nbsp;visual tree walk the point is automatically projected into the ray for the ViewPort3D's bounds and camera and hit testing continues seamlessly into 3D (figure 3).&lt;/P&gt;
&lt;P&gt;&lt;IMG alt="" hspace=0 src="http://blargh.com/~danlehen/HitTest-2.png" align=baseline border=0&gt;&lt;/P&gt;
&lt;P&gt;If a Model3D is hit during the 3D portion of the hit test the PointHitTestResult object returned by IVisual.HitTest(...) can be cast into a Model3DHitTestResult from which you can find out which Model3D was hit and the details of the intersection.&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=167463" width="1" height="1"&gt;</description></item><item><title>IanG's First Look at 3-D Support in Avalon</title><link>http://blogs.msdn.com/b/danlehen/archive/2004/06/19/160217.aspx</link><pubDate>Sun, 20 Jun 2004 01:17:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:160217</guid><dc:creator>Daniel Lehenbauer</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/danlehen/rsscomments.aspx?WeblogPostID=160217</wfw:commentRss><comments>http://blogs.msdn.com/b/danlehen/archive/2004/06/19/160217.aspx#comments</comments><description>MSDN just published an &lt;A href="http://msdn.microsoft.com/longhorn/?pull=/library/en-us/dnlong/html/avalon3d.asp"&gt;introductory article on 3D support in Avalon&lt;/A&gt; by fellow blogger &lt;A href="http://www.interact-sw.co.uk/iangblog/"&gt;Ian Griffiths&lt;/A&gt; of DevelopMentor.&amp;nbsp; The article is liberal with screenshots and provides a good mapping between the high level concepts and the Avalon object model.&amp;nbsp; It's a great way to get yourself oriented to the platfrom and includes a link to&amp;nbsp;Ian's .x file to xaml convesion tool I &lt;A href="http://blogs.msdn.com/danlehen/archive/2004/06/11/154028.aspx"&gt;mentioned earlier&lt;/A&gt;.&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=160217" width="1" height="1"&gt;</description></item><item><title>Longhorn on Virtual PC</title><link>http://blogs.msdn.com/b/danlehen/archive/2004/06/14/155698.aspx</link><pubDate>Tue, 15 Jun 2004 01:54:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:155698</guid><dc:creator>Daniel Lehenbauer</dc:creator><slash:comments>7</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/danlehen/rsscomments.aspx?WeblogPostID=155698</wfw:commentRss><comments>http://blogs.msdn.com/b/danlehen/archive/2004/06/14/155698.aspx#comments</comments><description>I was asked if Longhorn runs on Virtual PC.&amp;nbsp; I haven't tried build 4074 first hand, but according to &lt;A href="http://217.45.146.189/archive/2004/06/10/226.aspx"&gt;Stephen McGibbons&lt;/A&gt; it is &amp;#8220;a breeze&amp;#8221; to setup, performance is acceptable, and he even shows it running 3D in his &lt;A href="http://217.45.146.189/mob_img/Longhorn_VPC.jpg"&gt;screenshot&lt;/A&gt;.&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=155698" width="1" height="1"&gt;</description></item></channel></rss>
