29 April Unproject with useProjectionMatrix = true
I just updated Papervision3D to allow the CameraObject3D#unproject method to work when CameraObject3D#useProjectionMatrix = true.
Papervision3D has two methods of ‘projecting’ vectors onto the screen:
- useProjectionMatrix = false, this is the default ‘fast’ method
- useProjectionMatrix = true, this is the method where projection is done by a matrix
Note that Papervision3D switches to method #2 in ‘ortho mode’.
So what is the difference exactly between these two kinds of projection? First we need to define what projection is. Projection is what adds ‘perspective’ to a scene and makes sure your scene fits to the viewport. Its the last step in the so-called ‘render pipeline’.
We can derive the ‘fore shortening’ effect of perspective in several ways. Method #1 is simple, effective and fast. It uses the camera’s focus and zoom values. Method #2 uses a more classic way of projection : it uses a dedicated matrix. Tech buffs: very much like OpenGL’s gluPerspective.
Andy Zupko has a great post on unproject using method #1.
We will discuss unproject using method #2, which works slightly different.
The difference is that when #useProjectionMatrix is set to true, then CameraObject3D#unproject returns a point in world-space, rather then a ray. Let me explain with some code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | // we want to use a projection matrix camera.useProjectionMatrix = true; // '0' indicates we want a point on the near plane var pointOnNearPlane : Number3D = camera.unproject( screenX, screenY, 0 ); // '1' indicates we want a point on the far plane var pointOnFarPlane : Number3D = camera.unproject( screenX, screenY, 1 ); // Construct the ray's direction var dir : Number3D = Number3D.sub( pointOnFarPlane, pointOnNearPlane ); // Normalize dir.normalize(); // So, now you have a ray with its origin at 'pointOnNearPlane', // and direction 'dir' |
Optimization: could save some cycles by doing (*not* in ortho mode!, see below):
1 2 3 4 5 6 7 | var camPosition : Number3D = new Number3D( camera.x, camera.y, camera.z ); // Construct the ray's direction var dir : Number3D = Number3D.sub( pointOnFarPlane, camPosition ); // Normalize dir.normalize(); // So, now you have a ray with its origin at the camera's position // and direction 'dir' |
Why can’t we use above optimization in ortho mode?
In perspective mode all ‘rays’ originate from the camera’s position: the ‘view cone’ has shape of a pyramid. Hence we can assume ‘pointOnNearPlane’ to coincide with the camera’s position.
In ortho mode however the ‘view cone’ has the shape of a cube, all rays are parallel. Hence we need to unproject *two* points to construct our ray.
Now simply follow Andy Zupko ’s post to drag objects around.
Or perform ‘picking’, or…
Update:
Created a little demo to visualize what I’m ranting about, check it out here
3 Comments - Tags: camera, Flash, Papervision3D, unproject




The Suite75 CADviewer is an useful tool for all Groove users who work with CAD-files. The tool lets you review 2D CAD-drawings alone or realtime with other space members.