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;
}
}
}