author: Krasimir Tsonev

Hi there, I'm . Senior front-end engineer with over 13 years of experience. I write, speak and occasionally code stuff. Follow me on Twitter, GitHub, Facebook or LinkedIn

Papervision3d: Finding 2D coordinates of a 3D object

Papervision3d is probably the most popular 3D flash engine. There are dozen of applications/sites that use it. These days I also decided to create a 3D effect in my portfolio site. Everything works fine, but I needed a tooltip for each of the 3D objects on my scene. To be able to animate everything I needed 2D coordinates of all my 3D elements.
Actually the solution was very easy. I used the "screen" property of my objects. Here is an example (check lines: 59,60):
package lib.document {
    import flash.display.MovieClip;
    import flash.events.Event;
    import org.papervision3d.objects.DisplayObject3D;
    import org.papervision3d.objects.primitives.Sphere;
    import org.papervision3d.view.BasicView;
    public class App extends MovieClip {
      private
      var _view: BasicView;
      private
      var _wrapper: DisplayObject3D;
      private
      var _items: Array;
      private
      var _areaWidth: Number;
      private
      var _areaHeight: Number;
  
      function App() {
        _areaWidth = 800;
        _areaHeight = 600;
        _items = [];
        _view = new BasicView(_areaWidth, _areaHeight, true);
        _wrapper = new DisplayObject3D();
        addChild(_view);
        _view.scene.addChild(_wrapper);
        addSphereAndTooltip("item 1");
        addSphereAndTooltip("item 2");
        addSphereAndTooltip("item 3");
        _view.startRendering();
        addEventListener(Event.ENTER_FRAME, setPositionOfTheTooltip);
      }
      private
  
      function setPositionOfTheTooltip(e: Event): void {
        // rotate the wrapper depending on the mouse position			
        if (_wrapper) {
          var horizontalP: Number = 0;
          var verticalP: Number = 0;
          if (mouseX > _areaWidth / 2) {
            horizontalP = Math.ceil((mouseX - (_areaWidth / 2)) / (_areaWidth / 2) * 100);
          } else {
            horizontalP = -Math.ceil(((_areaWidth / 2) - mouseX) / (_areaWidth / 2) * 100);
          }
          if (mouseY > _areaHeight / 2) {
            verticalP = -Math.ceil((mouseY - (_areaHeight / 2)) / (_areaHeight / 2) * 100);
          } else {
            verticalP = Math.ceil((_areaHeight / 2 - mouseY) / (_areaHeight / 2) * 100);
          }
          _wrapper.rotationY -= (_wrapper.rotationY - (horizontalP * 180 / 100)) * 0.05;
          _wrapper.rotationX -= (_wrapper.rotationX - (verticalP * 90 / 100)) * 0.05;
        } // set position of the tooltips	
        var numOfItems: int = _items.length;
        for (var i: int = 0; i & lt; numOfItems; i++) {
          _items[i].tooltip.x = _items[i].sphere.screen.x + (_areaWidth / 2);
          _items[i].tooltip.y = _items[i].sphere.screen.y + (_areaHeight / 2);
        }
      }
      private
      function addSphereAndTooltip(tooltipTitle: String): void {
        // create sphere	
        var sphere: Sphere = new Sphere(null, 100);
        sphere.autoCalcScreenCoords = true;
        sphere.x = getRandomNum(-500, 500);
        sphere.y = getRandomNum(-500, 500);
        sphere.z = getRandomNum(-500, 500);
        _wrapper.addChild(sphere);
        // create tooltip		
        var tooltip: MovieClip = new Tooltip();
        tooltip.field.text = tooltipTitle;
        addChild(tooltip);
        _items.push({
          sphere: sphere,
          tooltip: tooltip
        });
      }
      public
  
      function getRandomNum(min: Number, max: Number): Number {
        var num: Number = Math.floor(Math.random() * (max - min + 1)) + min;
        return num;
      }
    }
  }
Download the source files from here.Check the result here.
If you enjoy this post, share it on Twitter, Facebook or LinkedIn. Or maybe comment below: