Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

Rotating a cube with Papervision3D

New Here ,
Dec 16, 2010 Dec 16, 2010

Hi,

I am working on an interactive flash animation, wherein I want the user to be able to rotate a cube along the y-axis by the help of mouseclicks (mening clicking the cube and moving the mouse to rotate it). I started out with a simple Papervision example, that consists of a cube with 6 faces, that rotes in both x- and y-directions according to the mouse movement  (and as you can see I have commented out these lines).

I am totally confused of how to implement the mouse behavior especially when there are 4 faces of the cube that i want to work with - remember i just want the user to look at a cube and move it accordingly to its y-axis. So, i am not sure what to do, if I should re-write the //cube.rotationY += xDist * 0.05; or how to re-construct the  function stage_mouseDownHandler.....well, what can I say, I need help, and i would appreciate it very much!

Here is the code - unfortunately it doesnt really display anything...

import org.papervision3d.scenes.*;

import org.papervision3d.cameras.*;

import org.papervision3d.objects.*;

import org.papervision3d.objects.special.*;

import org.papervision3d.objects.primitives.*;

import org.papervision3d.materials.*;

import org.papervision3d.materials.special.*;

import org.papervision3d.materials.shaders.*;

import org.papervision3d.materials.utils.*;

import org.papervision3d.lights.*;

import org.papervision3d.render.*;

import org.papervision3d.view.*;

import org.papervision3d.events.*;

import org.papervision3d.core.utils.*;

import org.papervision3d.core.utils.virtualmouse.VirtualMouse;

import org.papervision3d.core.math.Matrix3D;

import org.papervision3d.core.math.Number3D;

import org.papervision3d.lights.PointLight3D;

import org.papervision3d.materials.shadematerials.FlatShadeMaterial;

import org.papervision3d.objects.primitives.Sphere;

import org.papervision3d.view.BasicView;

import flash.events.MouseEvent;

var viewport:Viewport3D = new Viewport3D(0, 0, true, true);

addChild(viewport);

viewport.buttonMode = true;

var renderer:BasicRenderEngine = new BasicRenderEngine();                       

var scene:Scene3D = new Scene3D();                       

var camera:Camera3D = new Camera3D();

camera.zoom = 11;

camera.focus = 100;                

var isMouseDown:Boolean = false;

function moveCube() {

var mam:MovieMaterial = new MovieMaterial(face);

mam.interactive = true;

mam.smooth = true;

mam.animated = true;

var mam2:MovieMaterial = new MovieMaterial(face2);

mam2.interactive = true;

mam2.smooth = true;

mam2.animated = true;

var mam3:MovieMaterial = new MovieMaterial(face3);

mam3.interactive = true;

mam3.smooth = true;

mam3.animated = true;

var mam4:MovieMaterial = new MovieMaterial(face4);

mam4.interactive = true;

mam4.smooth = true;

mam4.animated = true;

var mam5:MovieMaterial = new MovieMaterial(face5);

mam5.interactive = true;

mam5.smooth = true;

mam5.animated = true;

var mam6:MovieMaterial = new MovieMaterial(face6);

mam6.interactive = true;

mam6.smooth = true;

mam6.animated = true;

var cube:Cube = new Cube(new MaterialsList({front:mam, back:mam2, left:mam3, right:mam4,top:mam5, bottom:mam6}), 300, 300, 300, 20, 20, 20);

scene.addChild(cube);

stage.addEventListener(MouseEvent.MOUSE_DOWN, stage_mouseDownHandler);

stage.addEventListener(MouseEvent.MOUSE_UP, stage_mouseUpHandler);

}

function stage_mouseDownHandler(event:MouseEvent):void

          {

               isMouseDown = true;

          }

function stage_mouseUpHandler(event:MouseEvent):void

          {

               isMouseDown = false;     

          }

//addEventListener(Event.ENTER_FRAME, loop);

function loop(e:Event):void

{

     

     

     

     //var xDist:Number = mouseX - stage.stageWidth * 0.5;

     //var yDist:Number = mouseY - stage.stageHeight * 0.5;

     //cube.rotationY += xDist * 0.05;

     //cube.rotationX += -yDist * 0.05;

     renderer.renderScene(scene, camera, viewport);

}

face.addEventListener(MouseEvent.CLICK, faceClick);

function faceClick(e:MouseEvent):void

{

     

     navigateToURL(new URLRequest("http://www.yahoo.com"));

// or gotoframe

}

face2.addEventListener(MouseEvent.CLICK, face2Click);

function face2Click(e:MouseEvent):void

{

     navigateToURL(new URLRequest("http://www.google.com"));

}

face3.addEventListener(MouseEvent.CLICK, face3Click);

function face3Click(e:MouseEvent):void

{

     navigateToURL(new URLRequest("http://www.flickr.com"));

}

face4.addEventListener(MouseEvent.CLICK, face4Click);

function face4Click(e:MouseEvent):void

{

     navigateToURL(new URLRequest("http://www.youtube.com"));

}

face5.addEventListener(MouseEvent.CLICK, face5Click);

function face5Click(e:MouseEvent):void

{

     navigateToURL(new URLRequest("http://www.facebook.com"));

}

face6.addEventListener(MouseEvent.CLICK, face6Click);

function face6Click(e:MouseEvent):void

{

     navigateToURL(new URLRequest("http://www.adobe.com"));

}

TOPICS
ActionScript
4.2K
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Dec 16, 2010 Dec 16, 2010

i haven't used PV much, but I've done a lot of 3D in flash.

generally, you just need to turn off any code that adjusts the X axis, and keep the Y.

so looks like keep these:

var xDist:Number = mouseX - stage.stageWidth * 0.5;

cube.rotationY += xDist * 0.05;

and don't use these:

//var yDist:Number = mouseY - stage.stageHeight * 0.5;

//cube.rotationX += -yDist * 0.05;

although, this:

var xDist:Number = mouseX - stage.stageWidth * 0.5;

cube.rotationY += xDist * 0.05;

appears to adjust the Y of the cube by the X movement of the mouse, so you'll need to adjust the method of how Y changes to mouse clicks or how ever you want to do it in the UI.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Dec 16, 2010 Dec 16, 2010

something like:

myLeftButton.addEventListener(MouseEvent.CLICK, rotateLeft);

function rotateLeft(e:MouseEvent):void

{

     cube.rotationY -= 1;

}

myRightButton.addEventListener(MouseEvent.CLICK, rotateRight);

function rotateRight(e:MouseEvent):void

{

     cube.rotationY += 1;

}

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Dec 17, 2010 Dec 17, 2010

Miquael,

Thank you so much for the reply.

Well, PV was just the first API that I wanted to try out, since it was the first to pop up on google. Do you have any suggestions to another API that is maybe easier? Or are they just all the same?

There is also the greensock/tweenlight API, but as far as I have seen it doesnt really have what I need, in regards to building 3D.

What I wanted to make is something like this site http://www.kendaperez.com/ but now I just discovered that there are more faces with textures, instead of just a cube... but i have to start somewhere 🙂

Thank you for the suggestion with the code, will try it out!

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Dec 17, 2010 Dec 17, 2010

I've done much ActionScript 3D well before PV3D or any other API came out, and so I've usually just done pretty simple stuff from the ground up.  I think PV3D is definately a good way to go (especially for the example you want to emulate with textures and such), and there are others that may be worth taking a look at also (I'm not sure how all the AS 3D APIs match up these days).  PV3D was the standard years ago, but others may have surpassed ...

http://alternativaplatform.com/en/

http://away3d.com/

http://www.flare3d.com/

Anyway, looking ahead, Adobe will be upgrading ActionScript with new and inherent 3D APIs which will make for some very big improvements for 3D in Flash in general--including low-level processing of 3D directly thru the GPU of devices!!

http://www.bytearray.org/?p=2346

http://www.bytearray.org/?p=2310

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Dec 17, 2010 Dec 17, 2010

Sounds great and thank you for the suggestions!

As far as I see it with the Flare3D its made only for 3D Max, and I wish they'd make something more crossplatform (especially thinking of OSX) for users of Blender for instance. But in any case its just a tangent growing out of the whole OpenGL techniques and framework, as far as I see it, but there is a lot of competition out there.

One last question, which might seem silly... but, why cant I declare my variables myLeftButton and myRightButton when these need to be of type Boolean, correct?

Basically like:

var myLeftButton: Boolean;

or

var myLeftButton: Boolean = true;

I dont quite understand it, i get an exception saying "Call to a possibly undefined method addEventListener through a reference with static type Boolean"

is there another way to access the mouse clicks? or what am i doing wrong? 

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Dec 17, 2010 Dec 17, 2010

var myLeftButton would not be Boolean.  as myLeftButton would be referring to a graphic object that acts as a UI button, it would probably be either a Sprite or MovieClip type declaration.  but also, depending on how you are creating your project, you may not need to declare it at all.  anyway, this understanding is fundamental to working with graphic objects in ActionScript, so I'd recommend looking at some other examples out there to see how this works.  like this:

http://www.adobe.com/devnet/actionscript/articles/event_handling_as3.html

http://www.ehow.com/how_5684576_create-button-actionscript-3_0.html

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Dec 20, 2010 Dec 20, 2010

Yes, I kind of knew that, but got confused about how to access the mouseclicks, meaning avoiding to reference instance names of graphics objects. The problem was now simple - i just had to add the the rotation to each face of the cube. Something like this:

face2.addEventListener(MouseEvent.CLICK, face2Click);


function face2Click(e:MouseEvent):void

{


cube.rotationY -= 90;

}

My problem right now, is that there is a rotation but there is no animation. Meaning for each mouse click you will just see one face/rectangle being changed to another rectangle. So now its more like a translation (a movement) - it just doest move, but more like jumping from 0 degrees to 90 degrees... if you know what i mean?

I mean the rotationY must be the rotation matrix, but what can i do to make it rotate, like in real life... ? Any thoughts?

Thanks!



Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Dec 20, 2010 Dec 20, 2010

yes, now you would want to implement TweenLite (or one of the other greensock packages) to manage fluid transitions.  TweenLite itself does not do 3D. TweenLite is a great solution for doing "tweens" of any type of value, and is flexible enough that you can apply it to just about anything.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Dec 20, 2010 Dec 20, 2010

or ... even without TweenLite, you can use a general addEventListener(Event.ENTER_FRAME, update) that will run a constant loop to an "update" function.

your mouse click functions would adjust a different variable that is used in the update function.

this.addEventListener(Event.ENTER_FRAME, update); // constant loop


face2.addEventListener(MouseEvent. MOUSE_DOWN, face2ClickDOWN);

face2.addEventListener(MouseEvent.MOUSE_UP, face2ClickUP);

function face2ClickDOWN(e:MouseEvent):void {

     Yrotation = 0.5;

}

function face2ClickUP(e:MouseEvent):void {

     Yrotation = 0;

}

function update(e:Event) {

     cube.rotationY += Yrotation;

}

as the update function would be running constantly, the Yrotation var would be 0.5 when the mouse is down, and then increment the cube rotation value by 0.5 for every cycle of the loop.  when the mouse is up, then then value of Yrotation is set to 0, so the rotation will stop.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Dec 23, 2010 Dec 23, 2010

Thank you so much for all the input. I tried different things, but first off I already did try the tweenlight library, and it looks like it somehow interferes with the papervision library (????)

i basically added the this line: TweenLite.to(cube, 1, {x:65, y:117, rotation:90}); to the Eventlistener function for just one face... and i get this error:

ReferenceError: Error #1069: Property rotation not found on org.papervision3d.objects.primitives.Cube and there is no default value.

     at com.greensock::TweenLite/init()

     at com.greensock::TweenLite/renderTime()

     at com.greensock.core::SimpleTimeline/renderTime()

     at com.greensock::TweenLite$/updateAll()

Second of all, i did try your code, and this line of code; 

   cube.rotationY += Yrotation;

removes the cube off the stage, like its displayed in the first frame and then it dissapears. I did modify the code and specify the variable the following way:

   cube.rotationY += Yrotation = 1;

now the cube moves the way I want it to (which means fluid)... but, i dont want it to move by it self, but by the mouse clicks, as mentioned before.

the following piece of code just moves the cube by clicks, but its not really updating by each frame so its a fluid transition... i dont get it.

face2.addEventListener(MouseEvent.MOUSE_DOWN, face2ClickDOWN);

face2.addEventListener(MouseEvent.MOUSE_UP, face2ClickUP);

function face2ClickDOWN(e:MouseEvent):void

{

//TweenLite.to(cube, 1, {x:65, y:117, rotation:90});

cube.rotationY += Yrotation = 10;

}

function face2ClickUP(e:MouseEvent):void

{

      cube.rotationY += Yrotation = 35;

}

function update(e:Event):void

{

    //cube.rotationY += Yrotation = 1;

   // cube.rotationY += Yrotation;

renderer.renderScene(scene, camera, viewport);

}

Any suggestions?

Thanks!

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Dec 26, 2010 Dec 26, 2010
LATEST

this should help you understand how to work with PV3D and TweenLite.
It's also a good starting point for what you are trying to achieve.

http://pv3d.org/2009/04/09/sliced-cube/

Cheers

Tiago

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines