Page 2 of 5
Making a mesh of it
Enough theory – its time to start coding. WPF has only a single 3D primitive – the mesh.
A mesh is a collection of 3D points or vertices organised into triangles. Each triangle defines a portion of the surface. If the points making up the triangle are anticlockwise in a view then this is the front of the triangle and it is rendered. If the points are clockwise then it’s the back face and it isn’t rendered.
This simple scheme allows the system to avoid rendering the inside surfaces of objects. In 3D graphics there are no circles, ellipses or curves, just collections of triangles which approximate a surface.
In most cases meshes are created using a graphics editing tool and then read in. However it is worth creating at least one mesh by hand – if only to discover why you need a graphics tool to do the job!
Start a new WPF Application called Cube1 and add:
using System.Windows.Media.Media3D;
The Media3D namespace is where most of the 3D classes can be found.
To get started we need a 3D mesh that can be rendered. The simplest useful mesh you can create is a cube positioned at the origin of the coordinate system.
When you first discover how a mesh is defined it seems overcomplex. First you need to define an array of all of the points making up the mesh. Then you define triangles by specifying the indices in the point array of the three points that make up each triangle. This allows the same points to be used in different triangles. It is worth keeping in mind that y is updown, x is leftright and z positive out of the screen, negative into the screen.
A function that returns a cubic mesh starts:
MeshGeometry3D MCube() { MeshGeometry3D cube = new MeshGeometry3D();
First we need to create an array of points. In this case we need eight points corresponding to the eight corners of the cube:
Point3DCollection corners = new Point3DCollection(); corners.Add(new Point3D(0.5, 0.5, 0.5)); corners.Add(new Point3D(0.5, 0.5, 0.5)); corners.Add(new Point3D(0.5, 0.5, 0.5)); corners.Add(new Point3D(0.5, 0.5, 0.5)); corners.Add(new Point3D(0.5, 0.5, 0.5)); corners.Add(new Point3D(0.5, 0.5, 0.5)); corners.Add(new Point3D(0.5, 0.5, 0.5)); corners.Add(new Point3D(0.5, 0.5, 0.5));
Every mesh stores the array of points it uses in its Positions collection:
cube.Positions = corners;
The cube and the coordinate system
The points are stored in the Positions property of the MeshGeometry3D object.
Next we need to define the 12 triangles (two for each of the six faces of the cube) by listing their points in order. It is easier to first initialise an array with the required values:
Int32[] indices ={ //front 0,1,2, 0,2,3, //back 4,7,6, 4,6,5, //Right 4,0,3, 4,3,7, //Left 1,5,6, 1,6,2, //Top 1,0,4, 1,4,5, //Bottom 2,6,7, 2,7,3 };
and then transfer this using a loop to the triangle collection:
Int32Collection Triangles = new Int32Collection(); foreach (Int32 index in indices) { Triangles.Add(index); }
This method of defining an array and transferring it is just to shorten the amount of typing needed. You could add the index values directly to the Triangles collection.
Finally we set the cube’s TriangleIndices and return it as the result:
cube.TriangleIndices = Triangles; return cube; }
A mesh also has a normals collection and a texture coordinate collection which can be used for more realistic effects but this is the simplest mesh and only requires points and triangles
<ASIN:3866454236@DE>
<ASIN:1590599551>
<ASIN:0735623945>
<ASIN:1430210842>
