Hi:
A while back, a friend of mine was working on a project in which he needed to have several trapezoid like objects floating in space which he would then later manipulate their positions to form a larger shape. We figured that the best way to go about it was to create our own trapezoid primitive in papervision using the available core classes. Needless to say, the project deadline was too close to even try it out so we ended up using trapezoid like movieclips as materials. Of course using a natively drawn mesh would have done wonders to the processor but I guess it is what is its. The thought of creating my own custom primitive (or better said, custom mesh) in papervision still lingered though. Finally, I got time to dig in and give it a shot and the results are not to shabby if I do say so myself!
Start of by creating an instance of the Trianglemesh3D class and some variables we will need in a bit:
var mesh:TriangleMesh3D = new TriangleMesh3D();
var width:Number = 500;
var height:Number = 500;
var difference:Number = .25
A mesh is basically 2 or more triangles used to form a shape. Each triangle in turn is made up of 3 vertices. The trapezoid class we’ll be examining will only use two triangles to create the shape. The first thing we need to do is plot out the vertices. A trapezoid has four corners hence we need 4 vertices:
var tl:Vertex3D = new Vertex3D(-width*0.5, height*0.5, 0); // top left
var tr:Vertex3D = new Vertex3D(width*0.5, height*0.5, 0); // top right
var br:Vertex3D = new Vertex3D(width*0.5 - (width * difference), -height*0.5, 0); // bottom right
var bl:Vertex3D = new Vertex3D(-width*0.5 + (width * difference), -height*0.5, 0); // bottom left
In the code above, “width” and “height” are self explanatory, “difference” is a number (0 – .5) indicating the length of the shorter side of the trapezoid in relation to the longest side.
Don’t forget to add the vertices to the geometry of our mesh:
mesh.geometry.vertices.push(tl, tr, bl, br);
Now that we have our vertices plotted, we need to “connect the dots” to create our triangles. In order to create our triangles we need to use the Triangle3D class which accepts as arguments the mesh which will hold the triangle, an array of vertices to draw the triangle on, a material, and an array containing 3 NumberUV objects which I will explain later in this post.
Let’s set up our vertex arrays, one for each triangle:
var triangle_1_vertices:Array = [bl, tl, tr];
var triangle_2_vertices:Array = [br, bl, tr];
Now let’s set up our corresponding NumberUV arrays. Again, one for each triangle:
var textureMap_1:Array = [new NumberUV(0, 0), new NumberUV(0, 1), new NumberUV(1, 1)];
var textureMap_2:Array = [new NumberUV(1, 0), new NumberUV(0, 0), new NumberUV(1, 1)];;
The UVs basically tell the Triangle3D instance how to map the texture. (0, 0) would be bottom-left, (0, 1) is top-left, top-right is (1, 1) and bottom-right is (1, 0).
Let’s quickly throw together the material we will be using for our mesh:
var material:ColorMaterial = new ColorMaterial(0x00CC00);
var wireMaterial:WireframeMaterial = new WireframeMaterial(0x000000);
var composite:CompositeMaterial = new CompositeMaterial();
composite.addMaterial(material);
composite.addMaterial(wireMaterial);
Now to set up our triangles:
var triangle_1_face:Triangle3D = new Triangle3D(mesh, triangle_1_vertices, composite, textureMap_1);
var triangle_2_face:Triangle3D = new Triangle3D(mesh, triangle_2_vertices, composite, textureMap_2);
Now we add our triangles (or faces) to the geometry of our mesh and finally tell the mesh that its geometry is set to be rendered:
mesh.geometry.faces.push(triangle_1_face, triangle_2_face);
mesh.geometry.ready = true;
We’re done! You can now add your mesh to the 3d scene and manipulate as you would any DisplayObject3D!
Here is the Trapezoid class I made using the code we just used above:
package
{
import org.papervision3d.core.geom.TriangleMesh3D;
import org.papervision3d.core.geom.renderables.Triangle3D;
import org.papervision3d.core.geom.renderables.Vertex3D;
import org.papervision3d.core.math.NumberUV;
import org.papervision3d.core.proto.MaterialObject3D;
public class Trapezoid extends TriangleMesh3D
{
private var height:Number;
private var width:Number;
private var difference:Number;
public function Trapezoid($material:MaterialObject3D = null, $width:Number = 500, $height:Number = 500, $difference:Number = 0.5)
{
super($material, new Array(), new Array());
width = $width;
height = $height;
difference = $difference * 0.5;
buildTrapazoid();
}
private function buildTrapazoid():void
{
var materialInstance:MaterialObject3D = material;
var arrVertices:Array = geometry.vertices;
var arrFaces:Array = geometry.faces;
// create vertices
var tl:Vertex3D = new Vertex3D(-width*0.5, height*0.5, 0); // top left
var tr:Vertex3D = new Vertex3D(width*0.5, height*0.5, 0); // top right
var br:Vertex3D = new Vertex3D(width*0.5 - (width * difference), -height*0.5, 0); // bottom right
var bl:Vertex3D = new Vertex3D(-width*0.5 + (width * difference), -height*0.5, 0); // bottom left
//add vertices
arrVertices.push(tl, tr, bl, br);
// create faces
var triangle_1_vertices:Array = [bl, tl, tr];
var triangle_2_vertices:Array = [br, bl, tr];
var textureMap_1:Array = [new NumberUV(0, 0), new NumberUV(0, 1), new NumberUV(1, 1)];
var textureMap_2:Array = [new NumberUV(1, 0), new NumberUV(0, 0), new NumberUV(1, 1)];
var triangle_1_face:Triangle3D = new Triangle3D(this, triangle_1_vertices, materialInstance, textureMap_1);
var triangle_2_face:Triangle3D = new Triangle3D(this, triangle_2_vertices, materialInstance, textureMap_2);
// add faces
arrFaces.push(triangle_1_face, triangle_2_face);
geometry.ready = true;
}
}
}
And here is a document class which shows you how to use it:
package
{
import flash.events.Event;
import org.papervision3d.materials.*;
import org.papervision3d.materials.special.CompositeMaterial;
import org.papervision3d.view.BasicView;
public class CustomMesh extends BasicView
{
private var trapazoid:Trapazoid;
public function CustomMesh()
{
camera.focus = 11;
camera.zoom = 100;
var material:ColorMaterial = new ColorMaterial(0x00CC00);
var wireMaterial:WireframeMaterial = new WireframeMaterial(0x000000);
var composite:CompositeMaterial = new CompositeMaterial();
composite.addMaterial(material);
composite.addMaterial(wireMaterial);
composite.doubleSided = true;
/*var movieMat:MovieAssetMaterial = new MovieAssetMaterial("Badge", true);
movieMat.doubleSided = true;*/
trapazoid = new Trapazoid(composite, 181, 246, .5);
scene.addChild(trapazoid);
startRendering();
}
override protected function onRenderTick(event:Event = null):void
{
trapazoid.yaw(2);
super.onRenderTick(event);
}
}
}
These are the very basic first steps in creating your very own primitives in papervision. If you get build more complex, feature rich implementations please do let me know!!
Lab, papervision3d mesh, papervision3d
Recent Comments