[kml_flashembed movie="wp-content/070828/DisplayObject2DSequenceTest.swf" height="384" width="512" base="wp-content/070828/" /] Press your mouse button and arrows keys to rotate and move the camera in the enrironment.
What would you do if you needed to put a movieclip into papervision and have it facing the camera at all times? You would probably create a MovieMaterial and plane and make it look at the camera everytime the camera moves right? Well there’s another way.
Miguel Angel posted a Sprite2D class on the pv3d email list last winter but it kinda passed under the radar and was never implemented in Papervision. So we took his class, optimized it and came up with a new class called DisplayObject2D.
The class must be used with a MovieScene3D. It will add the real movieclip in the DisplayObject3D’s container, scale it and change its position. No need to render any material so its pretty fast and you can add events to the DisplayObject very easily. You can also include an image sequence inside the movieclip to mimic the rotation around the object. This could be very useful if you had a model with very complex geometries and textures which papervision couldn’t handle. Here’s a second example with basics movieclips.
Note : You’ll have to change two small things to the papervision API.
In MovieScene3D , change line 103
child.container = new Sprite();
for
child.createContainer();
In DisplayObject3D add this after line 324 :
public function createContainer():void{
container = new Sprite();
}
{ 38 comments… read them below or add one }
As we can get the DisplayObject3D.screen.x and y,we can draw 2d things freely just in a Sprite,not in pv3d sence.
Positioning the camera above the scene and rotating produces some amusing results
I assume adding full spherical rotation would be impractical?
Isn’t modulo better for convertAngleTo360() method?
private function convertAngleTo360(value:Number):Number{
return value%360;
}
Or even inline:
var rotationX:Number = (camera.rotationX – this.rotationX)%360;
Cool stuff! Although I’m having problems adding the DisplayObject2Ds to a parental DisplayObject3D object.
In the createChildren function I’ve added on top:
rootNode = new DisplayObject3D(”rootNode”);
scene.addChild(rootNode);
and below;
var do2D:DisplayObject2D = new DisplayObject2D(circle as DisplayObject,10);
rootNode.addChild(do2D);
Now.. this compiles. But during run-time. It gives the following error:
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at com.blitzagency.papervision3d::DisplayObject2D/com.blitzagency.papervision3d:DisplayObject2D::projectDisplayObject()
at com.blitzagency.papervision3d::DisplayObject2D/project()
at org.papervision3d.objects::DisplayObject3D/project()
at org.papervision3d.core.proto::SceneObject3D/renderCamera()
at com.blitzagency.papervision3d::PapervisionMovieScene/com.blitzagency.papervision3d:PapervisionMovieScene::render()
And yea.. i have declared rootNode as a DisplayObject3D variable.. any suggestions?
Rutger, MovieScene3d creates a sprite only for the children that are added straight to the scene so you can’t use a rootnode. Using a rootnode with a MovieScene3D would result in the same as using a scene3D.
maliboo, yes i’ll change that for %, thanks for the tip.
Tom, you could add images for the full spherical rotation althought you would end up with a huge file !
Hey Chuyue, you’re right but when using this class with a MovieScene3D, all the movieclips will get z sorted automatically.
I uploaded an update to the zip file with Chuyue’s and maliboo’s optimizations.
Hi Patrick, thanks for this code its great.
Not sure if you’re aware of this but with at least the 2nd demo DisplayObjectSequenceTest I’m getting memory leaks. The total memory used by the flash runtime is forever increasing.
I’ve only been using Flash for a few weeks so I’m not sure how far I’ll get with this but I’m trying to get to the bottom of it as I need to for a project I’m working on. If I get anywhere then I’ll post back. Any pointers would be greatly appreciated – I’m starting from the point of http://osflash.org/pipermail/papervision3d_osflash.org/2007-June/007486.html – as being the potential cause. It says this only in the Flash IDE – but it looks as though its affecting the browser too, so I’ll have to find a fix.
ok. For anyone interested if your using the fps camera and would like things to loop you need to do this in the 4th line of the render function, not in updateTargetObject:
if(z <= (camera.fl-100)){
spaceObject.z += (5000+camera.z);
}
This says as the camera moves ‘forward’ take any item thats ‘behind’ the camera’s focal point plus a little extra and push it way back into space. The -100 and 5000 in the function are arbitrary, you can play with yourself.
Thanks again to Patrick for the helpful classes and responses on this post.
hi,i try to addEventListener like this code
var do2D:DisplayObject2D = new DisplayObject2D(circle as DisplayObject,10);
do2D.createContainer();
var _sprite:Sprite = do2D.container;
_sprite.addEventListener(MouseEvent.CLICK,onClick);
,but nothing happened
what’s wrong?
i can’t get this working with layerscene3d. with moviescene3d it’s fine. am i being stupid, or does it just not support layerscene3d?
sean, i’ve never used layerscene3d so i can’t really help you with that. But this object was meant to use with a MovieScene3D.
milkmidi, look at the sample code, you’re not doing it right. You should never call createContainer on the do2d. The MovieScene3D does that when you add the do2d to it.
thanks,I successed to addEventListener ,Thanks
hi patrick,
i dont know how to add mouse events to plane ,,,,,, thanks in advance..
//code starts
ictionary = new Dictionary();
import caurina.transitions.Tweener;
// import the necessary files..
import org.papervision3d.scenes.*;
import org.papervision3d.cameras.*;
import org.papervision3d.objects.*;
import org.papervision3d.materials.*;
//
//import reflect.*;
//dictionary object to hold planes
var planeByContainer
var container:MovieClip=new MovieClip();
container.x=stage.stageWidth*0.5;
container.y=stage.stageHeight*0.5;
addChild(container);
this.frameRate=40;
//creating scene basic for papervision; among multiple scenes Scene3D is basic one
var scene:Scene3D=new Scene3D(container);
//camera to see objects
var camera:Camera3D=new Camera3D();
//initial camera zoom is (0,0,0);
//to zoom object into scene..
camera.zoom=10;
//star making planes…
//create material-by attaching bitmap using BitmapAssetMaterial
var bam:BitmapAssetMaterial=new BitmapAssetMaterial(”FlashIcon”);
//by default material applied to one side of object(here plane);
bam.oneSide=false;
bam.smooth=true;
for (var i:int=0; i
good stuff – thanks! On my machine I needed to change the example FLA classpaths for them to compile. Changed it from ‘classes’ to ‘./classes’
would it be possible to add the rotational capabilities to the movieclip ?
I’m not the greatest coder in the world but could it be done ?
I mean to be able to have the rotation be able to use movieclips and still retain all the great DisplayObject capabilities would top it off …
I’m not sure what you mean mszomola. But right now i’m using the rotationY of the DisplayObject3D to play the image sequence.
If you mean the rotation of the DisplayObject that contain the image sequence, i guess it could be used for rotationZ.
The problem is that if you want to display the rotationX and rotationY properly, you
I’ll try to find some time to check it out.
Yeah like basically have all the ability as you would with “plane”.
for instance , insted of the movieclip facing camera at all times and rather then mimic rotationx and y by playing the movieclip with fake angles ( which mind you if done correctly still looks and works well )
just so say so we can omit using plane and mapping the movieclip material , we can just use a movieclip , allow it to have angles and rotation just as the “plane”.
I think based on your last post you did hit on what i ment …
Hi there guys! I´m doing my first steps with papervision doing a videogame but I have a problem, after adding my display object 2d to the scene I start to add new clips to this child with a timer event. Well…after launching.. each onComplete function I tried to remove the movieclip inside the displayobject2d but…even when the movieclip dissapear with removeChild(name) it gaves me a increasing numChildren Number inside the object 2d!
that makes the game run slower..
Does someone how to remove at all child from a displayobject2d? this is the code with comments…
private function creaEffects(event:TimerEvent) {
var _particula:particula = new particula(); //the movieclip I´m adding
var Particula = new DisplayObject2D(_particula,5);
scene.addChild(Particula);
var intervalId:uint = setTimeout(Removo, 500, Particula)
}
private function Removo():void{
scene.removeChild(arguments[0])
trace(scene.numChildren); // even when the clip dissapear it gave me a increasing number
}
thx in advance!
So I tried to get this working with PV3d RC1 in Flex and it didn’t work at all, I got into the code and it looks like there is a “screen” (grabbing screen.x, screen.y, screen.z) object that is not being inherited anymore from DisplayObject3d. I tried looking for replacements but I didn’t get it to work right. Do you plan on updating the packages so that the DisplayObejct2d can work with the RC1? Or does anyone know how to get this working?
thanks! Y’all rock like diamonds! Keep up the good work!
Romke
RC1, is that the AS2 version ? If so, I think you can get the screen x,y,z from the vertex.
Something like this…
displayObject.x = vertex.screen.x;
displayObject.y = vertex.screen.y;
displayObject.visible = vertex.screen.z >= 0;
screenZ = vertex.screen.z;
Hi, can someone help me with the code to add a mouse eventlistener to a Do2D object which is inside a InteractiveScene3D scene? Thanx
Apostle
var do2D:DisplayObject2D = new DisplayObject2D(circle as DisplayObject,10);
scene.addChild(do2D);
do2D.addEventListener( “eventName”,eventHandler );
actually i made a mistake there, this is what you should do :
var circle:Circle = new Circle();
var do2D:DisplayObject2D = new DisplayObject2D(circle,10);
scene.addChild(do2D);
circle.addEventListener( “eventName”,eventHandler );
hi, got a question.
i am busy with some papervision3d project in which i do have a problem:some camera floats above a bunch of primitives and flies above them, however objects distort and i cannot properly render them, i think i do have some problem with containers, but since i am also new to the PV3D, i cannot figure it out. the relevant thing to the post made here is it that whenever you push the up arrow in the examples above, you can basically move through (or above) objects without the distortion, so i thought some might help.
this is the as3 code i am talking about:
//for 3D app.
import org.papervision3d.scenes.*;
import org.papervision3d.cameras.*;
import org.papervision3d.objects.*;
import org.papervision3d.materials.*;
//container for the 3d scene
var container:Sprite = new Sprite();
container.x = stage.stageWidth*0.5;
container.y = stage.stageHeight;
addChild(container);
//basic camera
var scene:Scene3D = new Scene3D(container);
var cameraview:Camera3D =new Camera3D;
cameraview.x = 0;
cameraview.y = 500;
cameraview.focus = 200;
var cameraX:Number=0;
addEventListener(Event.ENTER_FRAME, tilt);
addEventListener(Event.ENTER_FRAME, progress);
// preparation of standard material list for buildings
var facebuild:WireframeMaterial = new WireframeMaterial(0×999999);
var materiallist:MaterialsList = new MaterialsList();
materiallist.addMaterial(facebuild,”top”);
materiallist.addMaterial(facebuild,”bottom”);
materiallist.addMaterial(facebuild,”front”);
materiallist.addMaterial(facebuild,”back”);
materiallist.addMaterial(facebuild,”left”);
materiallist.addMaterial(facebuild,”right”);
//create array for buildings, push them into array for removing from scene.
var buildinglist:Array = new Array();
//create cube and set coordinates
for (var i:Number = 0; i<5; i++) {
var cube:Cube = new Cube(materiallist, 300, 300, 500, 1,1,1);
cube.x = -850 + (4000*Math.random());
cube.y = 0;
cube.z = 1000*Math.random();
scene.addChild(cube);
buildinglist.push(cube);
}
/*
//motion: forward
function progress(event:Event):void {
for (var k:Number =0; k<5; k++) {
//trace(buildinglist.length);
buildinglist[k].z -= Math.cos(radiansproject)*10;
buildinglist[k].x += Math.sin(radiansproject)*10;
scene.renderCamera( cameraview );
}
}
*/
//motion: left/right
function tilt(event:Event):void {
//cameraview.x +=(-cameraX); //cameraX external variable causing turning left and right.
cameraview.z +=10;
scene.renderCamera (cameraview);
}
at the examples provided the forward motion is accomplished though keyboard, but lets assume for the sample code i have provided, that my objects move towards the camera (decreasing z coordinates) constantly.
there are some excess stuff there , i have experimented a bit. you can basically ignore the commented pieces..
its a long post, and i am rather fresh to the PV3D enviroment, and if somehow would somehow help me, i will be grateful.
cheers.
has anyone revised this for papervision 2.0 (great white) it no-longer works the same way… I’m just starting to learn pv3d and the project I’m working on it would be really handy to use real movie clips form the library..
cheers
This is not possible for pv3d 2.0 because there’s is no MovieScene3D. But i know there is a new Billboard class that does something like this.
Patrick,
Where can I find that Billboard class?
Thanks!
There’s a download link in the above article. But you should know that this was written for Papervision3D 1.5, and it won’t work with 2.0.
Hey Patrick,
Very nice done!!
I am working on improving this for navigation purpose. There are two questions that I have at this point:
1. Is it possible to place an object with defined x,y,z instead of random placing?
2.Does it require redefine spaceobject in order to do Q1?
Greatly appreciative for any comments =)
Best,
Hart
Great stuff, this is perfect for a project I’m working on right now! I hope the people developing Papervision 2 are intending to have this class in their core package, because it’s a super useful way of integrating the way designers are used to working with Flash into a 3D workflow.
Incidentally, note that you have to adjust the classpath for DisplayObject2DTest to get it to work. Unless I’m the one with an older version of Flash (entirely possible,) I’m guessing your project was created before a slight change was made to how classpaths are defined. In your Publish Settings you list the classpath as “classes”, but it should be “.\classes”
Oh, and for anyone trying to use this class and realizing it doesn’t work with the latest alpha of Papervision, note that 1.7 beta is included in the download.
great tip! thank’s
Excellent!
Can we use the codes under com.blitzagency.papervision3d.* freely or for commercial?
Hi All,
we’ve just released our version of the DisplayObject2D class that solves the Z-ordering issues reported when using DisplayObject2D with Papervision3D 2.0:
http://www.tweetpond.com/blog/billboarding-in-papervision3d-20-displayobject2d/
Big thanks to Blitz Agency for originally releasing this class as open source!
Cheers, Jussi
I needed object 2d and the simplest way to do it is the screen.x and screen.y properties of the DisplayObject3D. In PV3D 2 in order to use this in every frame you must explicitly call calculateScreenCoords(camera) method.