|
|
Browse by Tags
All Tags » 3D Book (RSS)
Sorry, but there are no more tags available to filter with.
-
I received an email from a reader of 3D-Programmierung für Windows (the German translation of 3D Programming for Windows ) about printing scenes composed in WPF 3D. Some backbround: In the last chapter of my book (entitled "Applications and Curiosa") I discuss two ways of printing WPF 3D scenes. Both involve the handy PrintVisual method of PrintDialog . Because PrintVisual accepts any object created from a class that derives from Visual , you can print elements such as Viewport3D . However, you generally have more control over the size and placement of the printed image if you instead print objects of type Viewport3DVisual , a class that derives directly from Visual . Regardless which way you do it, you get jaggies. Apparently WPF 3D scenes always print at 96 DPI. I don't know why this is, but I suppose there's a good reason for it. My reader in Germany wasn't happy about that and wondered if there's a solution. More background: When writing 3D Programming for Windows I created many of Read More...
|
-
Of course I couldn't mention a technique of possible real-time cell-shading yesterday without actually trying it out. No, I didn't attempt to derive from BitmapEffect . (I'd love to take a crack at BitmapEffect but I simply cannot justify the expenditure of time.) Instead, I tried the RenderTargetBitmap approach. Here's a rough outline: Lay out your Page or Window normally but instead of defining a Viewport3D element, use a Border instead. The Border is perhaps the simplest FrameworkElement derivative that has a Background property. Give the Background property an object of type ImageBrush . Whatever you would have put into your Viewport3D put into a Viewport3DVisual instead. Set the Viewport property of the Viewport3DVisual to the actual size of the Border element. You'll need a handler for the SizeChanged event of the Border to keep this Viewport property updated when the Border size changes. In that same SizeChanged event handler for the Border , create an object of type RenderTargetBitmap Read More...
|
-
I received a recent query about cell-shading in WPF. Cell-shading is the technique of using just a few solid colors to imitate hand-drawn animation. The first idea that occurred to me was fiddling around with the Normals collection of a MeshGeometry3D by restricting it to just a few values. I derived from my TeapotMesh class (described here ) and reset all the items in the Normals collection to the closest vector among the group (1, 0, 0) , (–1, 0, 0) , (0, 0, 1) , and (0, 0, –1) . Then I aimed some directional light at (1, 0, –1) , and I rotated the teapot a bit relative to the light, and here's what it looked like: That result, although interesting in its own way, is only a very distant relative to this example shown in the Wikipedia article on cell shading : The problem, of course, is that the normals are vertex normals, and the surface of each pixel in each triangle in the mesh is shaded based on the averaqe of the shading at the triangle's vertices. (See Chapter Read More...
|
-
As Eric Sink pointed out recently, "WPF 3D doesn't know how to draw lines." . Fortunately, the WPF 3D team at Microsoft has made available the 3DTools library that includes the ScreenSpaceLines3D class that derives from ModelVisual3D and draws lines in a 3D scene. The "screen space" in the name of this class indicates that you specify the thickness of the lines in terms of device-independent units, which are 1/96th inch and hence often pixels. What's really nice is that the source code to ScreenSpaceLines3D is also available so you can see the clever techniques at work to make this happen: Basically, each line is a pair of triangles arranged in a long thin rectangle. While you specify the begin point and end point of this "line" in 3D coordinates, the ScreenSpaceLines3D class must determine the thickness of this "line" at each end so that after the various transforms have been applied to it (including the camera transforms — see Chapter 7 of my book 3D Programming for Windows ) it Read More...
|
-
With two-dimensional graphics, it's usually fairly easy to specify the coordinates that govern the location and size of a graphical figure. With 3D graphics, you might not have this convenience: Often you're working with primitives that have a fixed location and size, and you must use transforms to move and resize the figures. In Chapter 2 of my new book 3D Programming for Windows I show how to use TranslateTransform3D and ScaleTransform3D to assemble simple figures from unit cubes. (A unit cube has a width, height, and depth of 1 unit and is centered on the origin of the 3D coordinate system.) In Chapter 3 I continue those demonstrations with rotation, and Chapter 7 has some more advanced math behind deriving complex rotations in 3D space. I'd like to show another demonstration here using unit cubes to construct a fairly simple figure (a 7-pointed star) in 3D space. Fortunately all the trigonometry involved will be in two dimensions on the XY plane. Here's a seven-pointed star with a radius Read More...
|
-
A recent query on the MSDN Forum for WPF asked if it's possible to apply a non-affine transform to two-dimensional graphics. The simple answer is No . The 3×3 Matrix structure in the System.Windows.Media namespace does not allow setting the third column of the matrix required for non-affine transforms. However, non-affine transforms are allowed in WPF 3D and, indeed, you might be able to get the effect you want without getting involved with transforms at all. The two programs presented here both display a photo of myself in a square. Using the mouse, you can grab any one of the corners and drag it. You must click within the image! The nearest corner will jump to the mouse position and then you can drag the corner somewhere else. As you drag a corner, the other corners remain fixed. Here's the first version: NonAffineImageTransform1.xbap This is the simple approach: It uses WPF 3D to display a square on the XY plane. The 3D coordinates defined in the Positions collection of the MeshGeometry3D Read More...
|
-
It's annoying when you can write an entire application in XAML but you just need a little bit of code. Regardless how little it is, it means you'll need to make it an XBAP or an EXE when you'd really just prefer to distribute some XAML. If the only code your XAML file needs is a static MeshGeometry3D from the Petzold.Media3D library (available here ) you have a solution: The sample code from Chapter 6 of 3D Programming in Windows includes a program named MeshGeometry3DExtractor. The program finds all the classes in the Petzold.Media3D library that have public properties of type MeshGeometry3D and lists them in a ListBox . After you select one, it then lists all the settable public properites with TextBox controls so you can type in the values. (Unfortunately, it's not as fancy as the WinForms PropertyGrid ; you have to type in something acceptable to the property type's Parse method.) Then, through the magic of XamlWriter.Save , it dumps the class's generated MeshGeometry3D object into Read More...
|
-
In the section "Using Type Visibility and Member Accessibility Intelligently" of the modern classic CLR via C# (pages 169-172), Jeffrey Richter discusses why he believes that most classes should be defined as sealed. The Microsoft developers behind the System.Windows.Media.Media3D namespace seem to agree: In this namespace, every class is either abstract or sealed with just one exception: ModelVisual3D . This architecture creates challenges for the programmer wishing to write classes that generate triangle meshes algorithmically. The most straightforward approach would be deriving from MeshGeometry3D but you just can't do it. As I discuss in Chapter 6 of my new book 3D Programming for Windows , you have two good alternatives that let you reference your mesh-generation classes in XAML: Write a class that has a public property of type MeshGeometry3D . Instantiate this class as a resource in a XAML file. Define a binding between the property of this resource and the Geometry property of a Read More...
|
-
In WPF 3D, it's great to have high-level classes such as TranslateTransform3D , ScaleTransform3D , and RotateTransform3D for performing common types of transforms. It's also great to have MatrixTransform3D that encompasses all those transforms, and also performs skewing. As an extra bonus MatrixTransform3D allows non-affine transforms as well, so you can easily implement 3D taper transforms, as I demonstrated here and here . However, there are times you'd like to apply transforms to 3D figures that can't be represented with simple matrices. These I call "algorithmic transforms" because they must be expressed an algorithm applied to a collection of 3D points. In the Petzold.Media3D library (available here ), the ModelVisualBase class (described here ) has a facility to apply algorithmic transforms to 3D primitives. ModelVisualBase defines a property named AlgorithmicTransforms of type AlgorithmicTransformCollection . This is a freezable collection created simply by deriving from FreezableCollection<AlgorithmicTransform> Read More...
|
-
In some recent blog entries, I've shown some XAML files that reference the Petzold.Media3D library. You can also find a bunch of these "non-loose" XAML files in the Figures directory along with the downloadable code for my new book 3D Programming for Windows . I created these files in XamlCruncher 2.0. If you'd like to run these XAML files outside of XamlCruncher 2.0, they must be converted to EXEs or XBAPs. Converting to an XBAP is the easier option. Here's how: Suppose you have a XAML file named MyMasterpiece.xaml that references a DLL named MyLibrary.dll. In Visual Studio, create a new project of type XAML Browser Application named MyMasterpiece. Delete the files Readme.txt, Page1.xaml, Page1.xaml.cs, and App.xaml.cs. From the Project menu, select Add Existing Item (or right-click the Project name in the Solution Explorer and select Add and Existing Item). Add MyMasterpiece.xaml to the project. You can either copy the file to the project directory or just add a link to it. From the Project Read More...
|
-
In WPF 3D programming, it's often desirable to write a class that algorithmically generates triangle meshes for a particular figure, and then to reference that class in XAML. There are basically two ways of doing this, as I describe in Chapter 6 of my new book 3D Programming for Windows . The first way I described a few days ago . The second approach is to derive from ModelVisual3D . This approach is somewhat harder because your class has to define its own Material and BackMaterial properties. The Petzold.Media3D library (available here ) includes an abstract class that derives from ModelVisual3D and provides the necessary overhead, and also several classes that derive from this abstract class. The source code for these classes can be found in the Visuals directory of the Visual Studio project for the library: Object DispatcherObject DependencyObject Visual3D Read More...
|
-
Back in February, I wrote a little hack that extracted the vertices, indices, and normals from the DirectX 3D static method Mesh.Teapot (an implementation of the famous Utah Teapot ) and converted them into XAML. This XAML teapot then found its way into a couple XAML animations in the following blog entries: 3D Teapot Tragedy Asexual Reproduction of Teapots The Petzold.Media3D library (available here ) includes a TeapotMesh class that lets you use the teapot in your WPF 3D programs. If you're running XamlCruncher 2.0 with Petzold.Media3D.dll loaded, you can download and run the following XAML file: PlainTeapot.xaml Or you can just run the following XBAP to see what it looks like: PlainTeapot.xbap Notice that an instance of the TeapotMesh class is defined as a resource, and it's later referenced in a GeometryModel3D element through a binding. The exterior is colored Cyan; the interior is Red. You can use the scrollbars at the bottom and right of the page to view it from different angles. Read More...
|
-
Suppose you wanted to use WPF 3D to create a dodecahedron. A regular dodecahedron has 12 faces, each of which is a pentagon. A handy source of the three-dimensional coordinates is this Wikipedia article . One easy approach is to break each pentagonal face into five triangles that meet at the center. Implementing it, you might come up with something like this XAML file from Chapter 3 of my new book 3D Programming for Windows : RotatingDodecahedron.xaml There's nothing really wrong about doing it this way. In fact, you can even define a TextureCoordinates collection and apply a non-solid brush, as in this XAML file from Chapter 5: RotatingDodecahedronWithRadialBrush.xaml However, if you wanted to shine a PointLight or a SpotLight on this figure, you're in bad shape. The illumination of a triangle from a PointLight or SpotLight is based on an interpolation over the surface of the triangle governed by the illumination at the vertices. To get it to work right, those triangles defining the surface Read More...
|
-
Yes, I'm afraid so. I was playing around with it (see next blog entry) and had to fix a little problem in the calculation of Normals collection in the PolyhedronMeshBase class. The source code for my book 3D Programming for Windows is normally downloadable here and includes 0.9.0.0 or the Petzold.Media3D library. However, version 0.9.1.0 (and all future updates) of Petzold.Media3D is available here . Read More...
|
-
If you want to write classes that create 3D primitives for use in WPF 3D, and you also want to reference those classes in XAML files, there are basically two ways to do it, as I discuss in Chapter 6 of my book 3D Programming for Windows , "Algorithmic Mesh Geometries." The first way is this: You write a class that exposes a public property named Geometry (for example) of type MeshGeometry3D . You define an instance of this class as a resource in a XAML file. Later on in the markup, you bind the Geometry property of a GeometryModel3D element with the Geometry property of the resource. Such resources can be shared among multiple GeometryModel3D elements. That's the concept behind the classes defined in the Meshes directory of the Visual Studio project for the Petzold.Media3D library included with the source code for the book. The hierarchy for these classes begins with MeshGeneratorBase : Object DispatcherObject DependencyObject Read More...
|
|
|
|