I have been playing with the awesome Away3DLite. Playing with 1000s of polygons is very liberating, but still doesn’t mean we can slack off with the optimisation. It is important to take any opportunity to lessen the number of calculations performed per frame by the player.
To this end, I was just putting together a 2D layer above my 3D scene when I found that the camera.screen function (available in the standard Away3D library) that projects 3D coordinates(x,y,z) to 2D screen positions (x,y) wasn’t present.
In Away3DLite we have to calculate this ourselves. The salient information can be gained through a model or container’s viewMatrix3D property. To get an accurate screen position the the x,y,and z positions are drawn from viewMatrix3D. Each of x and y are divided by the z value and any screen offsets are applied.
Here is the method as a function:
public function calc2DCoords(screen_element:*):Point
{var posn:Vector3D = screen_element.viewMatrix3D.position
var screenX:Number = posn.x / posn.z;
var screenY:Number = posn.y / posn.z;return new Point(screenX+screenW_offset,screenY+screeH_offset)
}
Pass through a screen element (a model, primitive or object container) and the 2D result will be returned. The screenW_offset and screenH_offset are required if the ‘view’ has been centred on the stage.
I have put together a demo here to demonstrate the function. I load a couple of models into the scene and let a 2D info panel follow each around the screen.
Demo: Translating 3D Coordinates to 2D Screen Position
Source: ZIP
Good points!
In Sandy3d, how does this apply? thanks.
Pedro,
Unfortunately I haven’t used Sandy for a VERY long time (>3yrs) I’m not sure exactly how the global rendering is applied, I’m sure the Sandy forums will be able to help though (http://www.flashsandy.org/forum/).
Sorry I can’t help further.
ok thanks
Can I use that code in Away3D, or its only for AwayLite?
Is there a way of working out the scale of the 2D object, so that it would follow in the 3D space but be displayed in 2D ? Many thanks, Liam
Hi, I tried this and got this error
Property viewMatrix3D not found on away3d.primitives.Plane
I wondered if you could elaborate.
Cheers
Steve
For away3D 4.0 I ended up using this:
var vecPos:Vector3D = ObjectContainer3D( my.nested.objectContainer3D).sceneTransform.transformVector( new Vector3D(0, 0, 0 ) ) ;
//where Vector3D(0, 0, 0 ) is the local position within the my.nested.objectContainer3D ( for example change second zero to local height of the nested object to get the top of the object )
var spr:Shape = new Shape();
spr.x = (view3D.width / 2) + (vecPos.x);
spr.y = (view3D.height / 2) – (vecPos.y);
– that’s it, now you have 2D coordinates relative to the sprite where you view3D is attached to on.
– An extra note: if you rescale your view3D by setting view3D.width/height after your initial scene setup and you don’t redraw all your objects after that resize then you have to implement the difference in scale versus the original setup of the objects in the formula:
//the view3D size on scene setup
var myInitialView3DWidth = 1000;
var myInitialView3DHeight = 1000;
//now after you resized your view
var myRelativeScaleWidth = view3D.width / myInitialView3DWidth ;
var myRelativeScaleHeight = view3D.height / myInitialView3DHeight ;
var spr:Shape = new Shape();
spr.x = (view3D.width / 2) + (vecPos.x * myRelativeScaleWidth );
spr.y = (view3D.height / 2) – (vecPos.y * myRelativeScaleHeight );
it works! thank you!