Categories
General

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 :

[kml_flashembed movie=”/wp-content/uploads/manual/2008/lineperspectivegw.swf” width=”480″ height=”350″ FVERSION=”9″ QUALITY=”high” /]

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
// //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 : sebleedelisle@gmail.com


// 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();

		}


	}
}

20 replies on “Papervision Perspective Line material”

Tres cool! But now i’m absolutely itching to know how PV3D is going to change!!!!!

Come on seb don’t tease us like this! I am guessing the PV3D team are working with adobe to integrate the Flash Player 10 native 3D functionality.

can’t get it to compile:

The class ‘LineMaterial3D’ must subclass ‘flash.display.MovieClip’ since it is linked to a library symbol of that type.

Any ideas? Thanks!!

Hey Seb, Great stuff!
I’ve also played with lines in greatwhite, starting with Andy’s code that had per segment perspective in older pv3d versions.

I also found drawing curves instead of circles to be a lot faster. You can see it in action over here.

cheers, Mark

Hey Mark!

Nice example! Yeah i’ve noticed the drawCircle function is a little slow, I’m sure i could do a better version of this that draws the whole shape in one go… I may well do this as I need it for a project so watch this space!!!

cheers

Seb

[…] MLB project was delivered in June after three solid months of work (including a new line material for PV3D which still works despite my caveat) and the project was delivered. It was a perfect project – a […]

Excuse my bad English! Thank you for this nice work! …
Now, it is one year ago, that you made this post. But in the current version of papervision, there is now LineMaterial3D. What has happened?

hey Seb,
i cnat get the above code to work with the latest Version of PV3D. Can you post an exampel of how to use it? Is there a way to update the class to work with latest PV3D?

ok, i got it working now. One question, i draw the line with addLine and i use tween max onUpdate Function do do it dynamically. Every addLine call causes somehow some sort of segment. Is it possible to remove that “end-start” shape from the line to have a seamless line?

here is the code to the updated class, i get very bad framerates(see example) but it works. Is there a way to optimize it?

//pastebin.com/m34788a7f

here an example:
i mean the round shapes, they are caused by the easing function of the tweener i think…
ttp://www.subsonance.com/testSpace/lines

Hi Malte,

Awesome! Thank you very much for this posting. Maybe Seb could tell something about the code.

Sebastian

Comments are closed.