This has been a problem for ages:
http://pixelfumes.blogspot.com/2006/01/flash-why-do-you-mock-me-bitmap.htmlAs a solution to this, some smart developer came up with a quick fix, and people seem to stick to it.
http://pixelfumes.blogspot.com/2006/01/perspective-distort-example.htmlThis solution maps a lot of triangles to a quad and uses bitmapFill to project the image onto the surface. As you can see it has some limitations, the borders become teared and the final results look so so.
I'm currently working on a wallpaper application for a company that sells.. well guess.
Since there's always version-limitations as to what you can expect from the visitors, we decided that flashplayer 9 was the target version for this application, but this version suffers from the aforementioned problems so we had to fix it somehow.
After looking at the results of the 'perspective distort script' I concluded that there was something awkwardly wrong with this way of drawing images. The code places the triangles in a linearly interpolated fashion which screws up any chance of actually drawing something close to a correct perspective.
(If you're into this kind of stuff, You've probably seen this bit of code before)
public function setTransform( x0:Number , y0:Number , x1:Number , y1:Number , x2:Number , y2:Number , x3:Number , y3:Number ):void
{
var w:Number = texture.width;
var h:Number = texture.height;
var dx30:Number = x3 - x0;
var dy30:Number = y3 - y0;
var dx21:Number = x2 - x1;
var dy21:Number = y2 - y1;
var l:Number = poly.length;
while( --l > -1 )
{
var point:Object = poly[ l ];
var gx:Number = (( point.x - _xMin ) / w);
var gy:Number = ( point.y - _yMin ) / h;
var bx:Number = x0 + gy * ( dx30 );
var by:Number = y0 + gy * ( dy30 );
point.sx = bx + gx * ( ( x1 + gy * ( dx21 ) ) - bx );
point.sy = by + gx * ( ( y1 + gy * ( dy21 ) ) - by );
}
render();
}
After some thinking I came up with a somewhat simple quick-fix to a wall specific problem. With a bit of tinkering you'll easily be able to add vertical correction too, if that floats your boat. Anyway... enjoy.
public function setTransform( x0:Number , y0:Number , x1:Number , y1:Number , x2:Number , y2:Number , x3:Number , y3:Number ):void
{
var w:Number = texture.width;
var h:Number = texture.height;
var dx30:Number = x3 - x0;
var dy30:Number = y3 - y0;
var dx21:Number = x2 - x1;
var dy21:Number = y2 - y1;
var l:Number = poly.length;
// Calculate the facing angle of the quad.
var dangle:Number = ((Math.atan2(dy30 - dy21, x2 - x0) * (180/Math.PI)) / 90);
while( --l > -1 )
{
var point:Object = poly[ l ];
var gx:Number = (( point.x - _xMin ) / w);
var gy:Number = ( point.y - _yMin ) / h;
// Quadraticly shift the triangles x-ward into the perspective depending on the facing angle
var gxshift:Number = (gx * (1 - Math.abs(dangle))) + (Math.pow(gx, 2) * Math.abs(dangle));
if (dangle > 0) gxb = 1 - gxb;
var bx:Number = x0 + gy * ( dx30 );
var by:Number = y0 + gy * ( dy30 );
// Apply the new coordinates
point.sx = bx + gxshift * ( ( x1 + gy * ( dx21 ) ) - bx );
point.sy = by + gxshift * ( ( y1 + gy * ( dy21 ) ) - by );
}
render();
}
During this project I also came across some creative ways to apply subtle sharpening to images in flash. Post a comment or something if you're interested.