Goal of this tutorial
In this tutorial you will learn some functions of the MehsBuilder. It can be used to create meshes in an easy way.
Creating a box by using PADrend’s MeshBuilder
A box is made of six quads which are arranged together. It contains of eight vertices, which are the corners of the box. Before building a box we need first to instantiate a MeshBuilder object.
var meshBuilder = new Rendering.MeshBuilder();
The mesh builder is than feed with the eight corners of the box. Note that the method addVertex takes eight parameters. The first parameter is the position of the vertex. It takes a Geoemetry.Vec3. The second parameter also takes a Geoemetry.Vec3 and defines the normal of the vertex. The following four parameters are responsible for color of the vertex. It needs to be given in RGBA format. The last two parameters define the texture coordinates. When a vertex is added to the meshBuilder, it is placed at the end of a list. The addVertex method returns the index of the vertex within the list. Initially the list is empty, so that the first vertex gains index 0.
//Adding the vertices
meshBuilder.addVertex(new Geometry.Vec3(0,0,0), new Geometry.Vec3(0,0,1), r, g, b, 1, 0, 0);//0
meshBuilder.addVertex(new Geometry.Vec3(0,1,0), new Geometry.Vec3(0,0,1), r, g, b, 1, 0, 0);//1
meshBuilder.addVertex(new Geometry.Vec3(1,1,0), new Geometry.Vec3(0,0,1), r, g, b, 1, 0, 0);//2
meshBuilder.addVertex(new Geometry.Vec3(1,0,0), new Geometry.Vec3(0,0,1), r, g, b, 1, 0, 0);//3
meshBuilder.addVertex(new Geometry.Vec3(0,0,-1), new Geometry.Vec3(0,0,-1), r, g, b, 1, 0, 0);//4
meshBuilder.addVertex(new Geometry.Vec3(0,1,-1), new Geometry.Vec3(0,0,-1), r, g, b, 1, 0, 0);//5
meshBuilder.addVertex(new Geometry.Vec3(1,1,-1), new Geometry.Vec3(0,0,-1), r, g, b, 1, 0, 0);//6
meshBuilder.addVertex(new Geometry.Vec3(1,0,-1), new Geometry.Vec3(0,0,-1), r, g, b, 1, 0, 0);//7
Now it is time to create the six squares based on the vertices. Each is build from two triangles (since triangles are the smallest unit when it comes to computer graphics) and contains four vertices. To build a quad we need to tell PADrend which vertices should result in a quad, based on the vertices indices. It is important to notice that the indices have to be added in counter clockwise order. This is needed by back-face culling to decide whether the back-face or front-face of a polygon is visible to the viewer. If the indices are added in clockwise order, the culling algorithm would cull the polygon, since it assumes that back-face is visible to the viewer. The MeshBuilder offers three method to add indices, which will be introduced in the following.
Adding indices one by one
The first way of arranging four vertices to a quad, is to add its indices one by one. For a quad we need two triangles. Since each triangle contains of three vertices, we need to add six indices in total. In order to add an index we have to call addIndex and pass it a vertices index. Here the method is used to create the front side of the box. Note that the indices for the two triangles are added in counter clockwise order for the reasons described above.
//Front side
//First triangle
meshBuilder.addIndex(0);
meshBuilder.addIndex(3);
meshBuilder.addIndex(2);
//Second triangle
meshBuilder.addIndex(0);
meshBuilder.addIndex(2);
meshBuilder.addIndex(1);
Adding triangles directly
In addition of adding the indices one by one, the MeshBuilder also allows for adding a triangle with a single method call. Therefore we need to call addTriangle and pass it the three indices of the triangle in counter clockwise order.
//Top side
meshBuilder.addTriangle(2,6,5);
meshBuilder.addTriangle(1,2,5);
Adding quads directly.
Last but not least it is also possible to add quads directly. The methods takes four indices and creates automatically two triangles in order to build a triangle.
//Back side
meshBuilder.addQuad(4,5,6,7);
Finalizing the mesh
After we are done adding all our vertices and triangles to the mesh builder, we can build the actual mesh. This can be simply done by calling buildMesh.
//Build the mesh
var mesh = meshBuilder.buildMesh();
Displaying mesh
To display the mesh we first need to register a scene. Therefore we need a scene graph. In PADrend the scene graph is called MinSG, which stands for minimal scene graph. It contains of different kinds of nodes and will be described in a following tutorial in more detail. First of all we need a ListNode which represents the root of the graph. A ListNode can be used to held other nodes, but does not contain any geoemetry. So we need another node to store our mesh. For this purpose we use a GeometryNode. It can be added to the scene node by the += operator. After the scene graph was build, we register the root node at the PADrend instance and select it to be the active scene, so that it is displayed.
//Create a list node holding the scene
var sceneNode = new MinSG.ListNode();
//Create a geometry node holding the mesh
var node = new MinSG.GeometryNode(mesh);
//Adding the geometry node to the scene node
sceneNode += node;
//Register the scene
PADrend.registerScene(sceneNode);
//Selecting the scene to make it active
PADrend.selectScene(sceneNode);
Creating predefined meshes
Beside building meshes from a list of vertices, the MeshBuilder also offers the creation predefined meshes. Therefore there is a number of class methods for the different meshes.
- createArrow creates an arrow. Takes the radius of the arrows cone as first parameter. The second parameter defines the arrows length.
- createCone creates a cone by three parameters. The first parameter sets the radius, the second the height of the cone. The third parameter defines the number of segments the cone is made of. The more segments the rounder and smoother the cone appears. As a downside the number of triangles increases.
- createConicalFrustum creates a cone, having its tip cut off by four parameters. The first and second parameter sets the radius of the bottom and top. The third parameter defines the height and the fourth one defines the number of segments.
- createDiscSector creates a disc-sector by an angle. The first parameter defines the discs radius. The second parameter sets the number of segments used to create the disc. The third parameter sets the opening angle of the sector.
- createDome
- createRectangle creates a rectangle. The first (optional) parameter takes a vertex description. The second and third parameter define the width and height of the rectangle.
- createRingSector creates a sector of a ring. The first and second parameter set the inner and outer radius of the ring. The third parameter sets the number of segments used to create the ring section. The fourth parameter defines the opening angle of the sector.
- createSphere creates a sphere, having a fixed radius. The first and second parameter set the number of segments in horizontal and vertical direction.
- createBox creates a box. Takes a Geometry.Box, defining the size, as parameter.
Draw modes
PADrend offers you to render meshes in four different draw modes. Function createThreeConesWithDifferentDrawState shows their effect and how they are used. Therefore four spheres are instantiated by using the predefined meshes described above. For each mesh a different draw mode is set by calling one of the following methods:
- setDrawTriangles draws a solid mesh. This mode is set by default.
- setDrawLines draws lines connecting the vertices in a rectangular shape.
- setDrawLineStrip displays the meshes triangles as lines.
- setDrawPoints draws only the meshes vertices as dots.
var numSegments = 20; //number of segments in horizontal and vertical direction
var mesh1 = Rendering.MeshBuilder.createSphere(numSegments, numSegments);
var mesh2 = Rendering.MeshBuilder.createSphere(numSegments, numSegments);
var mesh3 = Rendering.MeshBuilder.createSphere(numSegments, numSegments);
var mesh4 = Rendering.MeshBuilder.createSphere(numSegments, numSegments);
//Setting draw modes
mesh1.setDrawTriangles(); //inital setting
mesh2.setDrawLines(); //draw lines only, rectangular shaped
mesh3.setDrawLineStrip(); //draw lines only, triangular shaped
mesh4.setDrawPoints(); //draw only points (positions of vertices)
var node1 = new MinSG.GeometryNode(mesh1);
var node2 = new MinSG.GeometryNode(mesh2);
var node3 = new MinSG.GeometryNode(mesh3);
var node4 = new MinSG.GeometryNode(mesh4);
The four spheres are positioned next to each other, so that you can observe the effect of the different modes.
//Setting positions
node1.setRelPosition(new Geometry.Vec3(-2, 0, 0));
node2.setRelPosition(new Geometry.Vec3( 2, 0, 0));
node3.setRelPosition(new Geometry.Vec3(-8, 0, 0));
node4.setRelPosition(new Geometry.Vec3( 8, 0, 0));
From left to right you can see setDrawLineStrip, setDrawTriangles, setDrawLines and setDrawPoints.
Cutting mesh
In some scenarios it might be useful to cut a mesh by a plane (e.g. to show the inside of a machine). In PADRend this can be done by using the function _ Rendering.eliminateTrianglesBehindPlane_. An example usage is shown ins clipSphere. The function takes three parameters. First of all the mesh, that should be cut, is passed to it. The second and third parameter define a plane by a position and direction vector. The function clips all triangles lying on the opposite of the direction vector.
var numSegments = 20; //number of segments in horizontal and vertical direction
var mesh = Rendering.MeshBuilder.createSphere(numSegments, numSegments);
//Cutting the mesh
Rendering.eliminateTrianglesBehindPlane(mesh, new Geometry.Vec3(0.0, 0.0, 0.0), new Geometry.Vec3(-1.0, 0.0, 0.0));