Seb Lee-Delisle

Menu

Papervision Perspective Line material

Good news! I’ve integrated my new 3D line drawing algorithm into a Papervision LineMaterial class!

Bad news! It probably won’t work for very long… the reason? Well Papervision is going through an exciting transformation that I’m not sure I can talk about right now… but suffice it to say, it’ll be pretty cool.

But in the meantime, you can play with this new perspective line material :

It doesn't quite look right in this example - the lines are transparent so you can see how the circles and fills are drawn - I could work out how to draw it in a single fill but it'd require a little more maths. But I actually really like the effect anyway. The lines are designed to be solid so then you wouldn't see the separate elements.

Here's the code, but PLEASE BEAR IN MIND THAT THIS WON'T WORK FOR LONG! I will try to implement this in new versions of PV3D but I can't promise anything! OH and also - this won't work with Frustum camera.

// Perspective Line material for PV3D
// Author : Seb Lee-Delisle
// Blog : www.sebleedelisle.com
// Company : www.pluginmedia.net
// Date : 25th March 2008
//
// This work is licensed under a Creative Commons  2.0 License.
 
// Full details at
// http://creativecommons.org/licenses/by/2.0/uk/
 
// You may re-use this code as you wish, but a credit would be
// appreciated. And I'd love to see what you do with it!
// mail me : [email protected]
 
 
// NB!!! THIS CODE WILL ONLY WORK WITH THE CURRENT BUILDS OF GW AND
// EFFECTS BRANCHES IN PV3D AND WILL VERY LIKELY BREAK VERY SOON!
 
package net.pluginmedia.pv3d.materials.special
{
	import org.papervision3d.materials.special.LineMaterial;
	import org.papervision3d.core.geom.renderables.Vertex3DInstance;
	import org.papervision3d.core.math.Number3D;
	import org.papervision3d.core.math.Number2D;
 
	import flash.display.Graphics;
 
	import org.papervision3d.core.geom.renderables.Line3D;
	import org.papervision3d.core.proto.MaterialObject3D;
	import org.papervision3d.core.render.data.RenderSessionData;
	import org.papervision3d.core.render.draw.ILineDrawer;
 
	public class LineMaterial3D extends LineMaterial implements ILineDrawer
	{
		private var vertex1 : Number2D = new Number2D();
		private var vertex2 : Number2D = new Number2D();
		private var p1 : Number2D = new Number2D();
		private var p2 : Number2D = new Number2D();
		private var p3 : Number2D = new Number2D();
		private var p4 : Number2D = new Number2D();
		private var lineVector : Number2D = new Number2D();
		private var spur : Number2D = new Number2D();
 
		public function LineMaterial3D(color:Number = 0xFF0000, alpha:Number = 1)
		{
			super(color, alpha);
		}
 
		override public function drawLine(line:Line3D, graphics:Graphics, renderSessionData:RenderSessionData):void
		{
			var fz:Number = (renderSessionData.camera.focus*renderSessionData.camera.zoom);
 
			var radius1:Number = fz / (renderSessionData.camera.focus + line.v0.vertex3DInstance.z) * line.size;
			var radius2:Number = fz / (renderSessionData.camera.focus + line.v1.vertex3DInstance.z) * line.size;
 
			graphics.lineStyle();
 
 
			drawLine3D(graphics, line.v0.vertex3DInstance, line.v1.vertex3DInstance, radius1, radius2);
			graphics.moveTo(0,0);
		}
 
		function drawLine3D(graphics : Graphics, v1:Vertex3DInstance, v2:Vertex3DInstance, radius1:Number, radius2:Number) : void
		{
 
 
			vertex1.reset(v1.x, v1.y);
			vertex2.reset(v2.x, v2.y);
 
			// the vector from vertex2 to vertex1
			lineVector.copyFrom(vertex1);
			lineVector.minusEq(vertex2);
 
			// the distance between points
			var d : Number = lineVector.modulo;
 
			// the angle of the spur from v1
			var spurangle:Number = Math.acos( (radius2-radius1) / d) * Number3D.toDEGREES;
			if(isNaN(spurangle)) spurangle = 0;
			spur.copyFrom(lineVector);
			spur.divideEq(d);
			spur.rotate(spurangle);
 
			// the first point in the polygon to draw
			p1.copyFrom(vertex1);
			spur.multiplyEq(radius1);
			p1.plusEq(spur);
 
			// now change the spur's length to that of radius2 and add to vertex2 to get the second polygon point
			p2.copyFrom(vertex2);
			spur.multiplyEq(radius2/radius1);
			p2.plusEq(spur);
 
			// now rotate the spur round to get the 3rd point
			spur.rotate(spurangle*-2);
			p3.copyFrom(vertex2);
			p3.plusEq(spur);
 
			// and now change the length back to radius1
			spur.multiplyEq(radius1/radius2);
			p4.copyFrom(vertex1);
			p4.plusEq(spur);
 
			graphics.lineStyle();
			graphics.beginFill(lineColor, lineAlpha);
			graphics.moveTo(vertex1.x, vertex1.y);
			graphics.lineTo(p1.x, p1.y);
			graphics.lineTo(p2.x, p2.y);
 
			graphics.lineTo(vertex2.x, vertex2.y);
 
			graphics.lineTo(p3.x, p3.y);
			graphics.lineTo(p4.x, p4.y);
 
			graphics.lineTo(vertex1.x, vertex1.y);
 
			graphics.endFill();
 
			graphics.beginFill(lineColor, lineAlpha);
			graphics.drawCircle(vertex1.x, vertex1.y, radius1);
			graphics.endFill();
 
 
			graphics.beginFill(lineColor, lineAlpha);
			graphics.drawCircle(vertex2.x, vertex2.y, radius2);
			graphics.endFill();
 
		}
 
 
	}
}
This entry was posted in Actionscript, Flash, Flash 3D, Obsolete, Papervision3D. Bookmark the permalink.

20 Responses to Papervision Perspective Line material