Several people have approached me about my 'hack' way of dragging objects in Papervision, so I decided to comp up a quick demo and share the technique, and of course, the source.
The hack is to use a Plane as a "drag plane". Then, all you need to do is detect where the mouse hits that plane in 3D space, and move your object to that location. This image shows what this looks like if the drag plane is not set to fully transparent (you can toggle this in the demo with the "v" key).

For this demo, I let you toggle if you are dragging vertically or horizontally with the "a" key. Alternatively, you can set it to a "perspective" drag mode with "s" which is simply putting the plane at a 45 degree angle.
The real magic happens in this snippet:
-
if(isDragging){
-
-
var rh:RenderHitData = viewport.hitTestPoint2D(new Point viewport.containerSprite.mouseX, viewport.containerSprite.mouseY));
-
-
if(rh.hasHit){
-
sphere.x = rh.x
-
sphere.y = rh.y;
-
sphere.z = rh.z;
We check to see if there is a hit with the mouse via hitTestPoint2D - this means we are hitting the drag plane. If there IS a hit, we simply move our object (the sphere) to the 3D location specified by the RenderHitData. To make sure we don't get the hit data for the sphere, i toggle its interactivity off once it has been clicked.
You'll also notice in this demo I included a few physics related things to play with, including the ability to throw the object, as well as bouyancy and gravity. Simply press "g" to activity these abilities.
I keep the drag plane relative to the world axis by defalt, but there is no reason you need to be limited to this. We can have the drag plane ALWAYS face the direction of the camera by simply changing its Y rotation. You can turn this off/on by pressing the "l" key. All we have to do to get this permanent orientation is to find the angle of the camera from the center, and set the planes rotation to the inverse:
-
if(locked){
-
var ang:Number = Math.atan2(camera.z, camera.x)*180/Math.PI-90;
-
dragPlane.rotationY = -ang;
-
}
And thats it! You can now drag around in 3D! This method would be easy to extend to drag multiple objects (simply use a dragTarget instead of sphere for everything). I am currently working on unproject functionality that will allow you to "actually" drag in 3D, but so far the numbers aren't working right. I'm close - hopefully will have it in the next few days.
Be sure to use physics mode ("g") - I'm hoping to see some air-hockey games in the near future! Enjoy!
and

34 Comments, Comment or Ping
I dont see anything happening when I press the “l” key. The plane doesn’t seem to be facing the camera when l is pressed.
Can you please explain?
February 17th, 2008
@Jiri – It only really has an effect on the xy and perspective dragging, since xz isn’t limited in direction by camera position. You can see the difference by turning visibility on, autoRotate on, toggle drag mode to vertical (xy), and then toggle locked as it rotates around. When its locked to the world it uses a constant XY axis, otherwise it uses one relative to camera position.
February 17th, 2008
Fantastic tutorial!
However, if I compile with the latest svn great white effects branch in CS3 IDE I get an execution error: TypeError: Error #1007: Instantiation attempted on a non-constructor. at Drag3D$iinit()
February 17th, 2008
@timbon – this class is written with flex builder, so if you want to use the Flash IDE, you will need to replace new bamboo() with a bitmap from your flash library, as flash can’t embed content.
hth.
February 17th, 2008
I removed the bamboo shader and replaced it with:
var gm = new GouraudMaterial(light, 0xFF3300, 0×330A00);
but now the hotkeys don’t work…
I have flex builder 2. Do you have a link to a simple way of implementing this class in builder so that I could compile it?
Many thanks!
February 17th, 2008
it’s an amazing tutorial
i can’t wait to use it on some works !
keep good work man !
February 18th, 2008
I’m looking for a freelancer to do a small project using PaperVision – please contact me for details.
February 19th, 2008
I accessed this demo a few days ago and it was great. Since then I’ve updated to the latest Flash Player and now it doesn’t work, I get the screen telling me to get Flash Player. Anyone else having this problem?
February 23rd, 2008
hi,
tnx again for this great educational material on pv3d, but can u explain a bit more about the classes that needs to be included from the effects folder, i.e. include the effects folder in my build path as well as the main pv3d folder or totally override/delete it?
Thanks:)
February 23rd, 2008
@Am – you just need to include the effects branch folder – nothing else. it includes all classes required for pv3d and is synced with GW.
February 23rd, 2008
WHat if i wanna use a virtual mouse(with controlled position) to detetct hit test with 3d faces ?
February 26th, 2008
Any example of VirtualMouse events ?
February 28th, 2008
re: “..replace new bamboo() with a bitmap from your flash library”
like this ?
var bm:BitmapMaterial = new BitmapMaterial(“texture”);
pointing to a bitmap in library with linkage = texture?
thanks in advance.
March 2nd, 2008
included the boolean:
BitmapMaterial(”texture”, false);
produces a swf, but no interaction, nor errors.
March 2nd, 2008
Any help about virtual mouse to detect objects by custom coords? I can’t get objects react to virtualmouse event, how can I do it ?
March 4th, 2008
is that difficult people ?
March 8th, 2008
There is alot of stuff on interactivity on the list. You should look into viewport.hitTestPoint2D which will return what object is hit by a coord of your choosing.
hth
March 8th, 2008
I saw that, and thanks for reply, and i tried to figure it out but i could get only space coords and not reference to hitted object, that’s why i asked a basi example just build somethign around it
March 8th, 2008
Nice source here. I’m currently trying to understand the code and stuff, but I have a question.
Why do you need another dragPlane if the target we are clicking is the object? Whats the purpose of the dragPlane anyway?
April 25th, 2008
Great! I was looking for a similar code to create a 3d map tool. The idea is a tool to place primitives (ej: plane) in space to finally create a xml map with all the positions and rotations, so I can parse it later to get a 3d “world”.
My problem was to find an easy way to place and rotate objects in a scene and your code is what I need to place. I´ll do something similar (with keyboard keys) to rotate the 3d objects.
Thanks a lot!
May 24th, 2008
If anybody wants to check my “alpha” app here´s the temp
link
May 24th, 2008
I tried this example with flex builder 3 but i cant get the dragging working, when i set the boolean for is dragging manualy to true then dragging works. looks like there is something strange. Just did copy and paste with the code. any ideas? thanks.
May 27th, 2008
There is a chance there were some changes in the newest revisions of GW. I haven’t had a chance to test it, but thats the only reason i can think of it might not work for you. If i find out anything i’ll be sure to let you know
May 27th, 2008
@Hwang – You need a drag layer unless you want to do the math yourself. I might go ahead and write a “math” way of doing this. If you try to use hit test data of the object itself, you will notice that it detects where the faces of the object actually are, and your dragging will not be accurate (unless you are dragging a plane). Your object will move to that face’s position instead of the center point.
hope that makes a little sense…
May 27th, 2008
@andy thanks would be nice to get it working its a really great example.
May 27th, 2008
Hi
Thanks for the source, i think your work is awesome. I”ve run into a problem though. I’ve just started using AS3 and papervision so i’m probably just being a n00b, but I keep getting the error with the line: viewport.addRenderLayer(dP);
The error reads:
1061: Call to a possibly undefined method addRenderLayer through a reference with static type org.papervision3d.view:Viewport3D.
Any help please, dont know what i’ve done wrong? I’ve added the Greatwhite and the Effects classpaths.
June 23rd, 2008
i got this error
Renderlayer 1046: Type was not found or was not a compile-time constant: RenderLayer.
it seems my version of papervision dont have this class RenderLayer
how can i fix this problem?
please
July 25th, 2008
A short description how to change the source to get it running in the Flash IDE:
As stated above, you will need the “Effects” branch of PV3D
Import a texture-Bitmap into the library, link the symbol to a class, let´s say “myTexture”.
Set the document class to “Drag3D”.
In Drag3D.as uncomment lines 39 and 40:
//[Embed(source="meshes/bamboo.jpg")]
//public var bamboo:Class;
and change line 97 to
var bm:BitmapMaterial = new BitmapMaterial(new myTexture(1,1));
A last thing to do: the dragging didn´t work. So I changed line 51 in Drag3D.as to
public var isDragging = true;
September 1st, 2008
I notice that once converted to flash it runs alot slower has anyone
else noticed that
October 23rd, 2008
Thanks, for the wonderfull tutorial….
December 17th, 2009
I have got the same error like Pedro .
Renderlayer 1046: Type was not found or was not a compile-time constant: RenderLayer.
Pedro,did you fix the problem??? I just can’t find the good papervision version.
plz someone help me!!! it’s very important for me
my mail addres is : dlillalaura@yahoo.com
February 11th, 2010
Reply to “Dragging in 3D – The Easy Way”