スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

--.--.-- | | スポンサー広告

DisplacementMapFilterでパースをつけてみる

DisplacementMapFilterを使ってムービークリップ等にパースをつけるサンプル作ろうとしたんですが、あまりうまくいかなかったデス。




傾きに適当な数字(0~90)を入れて「実行」ボタンを押すと、画像がビミョウにそれっぽく変換されマス。
左側のは上辺を固定して奥に向かって傾けたカンジ、右側のは下辺を固定して奥に向かって傾けたカンジです。
マウスを画像の上にもっていくと、置き換えに使用したマップ画像が表示されます。

ソースですが、DisplacementMapFilterを使って変形する部分はPerspectiveUtil.asという名前にしてこんな風にしました。

package {
import flash.display.*;
import flash.filters.*;
import flash.geom.*;
/**
* 遠近処理加工をするクラス。
*/
public class PerspectiveUtil {
/** 上辺をスクリーンに接して傾けることを示す定数 */
public static const CONTACT_TOP = "top";
/** 下辺をスクリーンに接して傾けることを示す定数 */
public static const CONTACT_BOTTOM = "bottom";
/**
* 指定したオブジェクトに遠近処理を加えます。
* @param src 処理対象の表示オブジェクト
* @param angle 傾き角
* @param screenDepth スクリーンまでの距離
* @param contact どの辺をスクリーンに接して傾けるか?
*/
public static function lean(src:DisplayObject,
angle:Number,
screenDepth:Number,
contact:String = "top")
:BitmapData {
// 傾きが0ならなにもしない
if (angle == 0) {
return null;
}
var d:Number = screenDepth;
var rad:Number = angle * Math.PI / 180;
var cos:Number = Math.cos(rad);
var sin:Number = Math.sin(rad);
var tan:Number = Math.tan(rad);
// 最終的なサイズ
var w:Number = Math.ceil(src.width);
var h:Number = Math.ceil(src.height * cos);
src.width = w;
src.height = h;
// 仮想スクリーン上での座標
var vX:Function;
var vY:Function;
if (contact == CONTACT_TOP) {
vX = function(x:Number):Number {
return x - w / 2;
};
vY = function(y:Number):Number {
return y;
};
} else {
vX = function(x:Number):Number {
return x - w / 2;
}
vY = function(y:Number):Number {
return h - y;
};
}
// 置き換えビットマップ生成
var bitmap:BitmapData = new BitmapData(w, h);
// 変化量の最大値を求める
var y:int = 0;
var x:int = 0;
var s:Number;
var tY:Number;
var tX:Number;
var maxY:Number = 0;
var maxX:Number = 0;
for (y = 0; y < h; y++) {
tY = vY(y);
s = d / (d + tan * tY);
maxY = Math.max(maxY, Math.abs((1 - s) * tY));
for (x = 0; x < w; x++) {
tX = vX(x);
maxX = Math.max(maxX, Math.abs((1 - s) * tX));
}
}
// 調整値
var yAdj:Number = maxY == 0 ? 1 : (127 / maxY);
var xAdj:Number = maxX == 0 ? 1 : (127 / maxX);
// 色を求める
for (y = 0; y < h; y++) {
tY = vY(y);
s = d / (d + tan * tY);
var yC:int
= Math.round((contact == CONTACT_TOP ? 1 : -1)
* (1 - s) * tY * yAdj);
for (x = 0; x < w; x++) {
tX = vX(x);
var xC:int = Math.round((1 - s) * tX * xAdj);
var c:Number = 0xFF000000
+ (0x80 + yC) * 0x100
+ xC + 0x80;
bitmap.setPixel(x, y, c);
}
}
// フィルタを作成
var filter:DisplacementMapFilter
= new DisplacementMapFilter(bitmap,
new Point(),
BitmapDataChannel.BLUE,
BitmapDataChannel.GREEN,
256 / xAdj,
256 / yAdj,
"color",
0,
0);
src.filters = [filter];
return bitmap;
}
}
}
やってることは、まず透視変換抜きで変形(高さを変更)して、その後透視変換を行うDisplacementMapFilterを生成してマス。
戻り値はフィルタに使用した置き換えマップ画像デス。

そんでコレを使うフレームアクションのほーは、こんなカンジです。
import flash.display.*;
// 置き換えビットマップ
var topBitmap:Bitmap;
var bottomBitmap:Bitmap;
// 元のサイズ
var topHeight:Number = test_top_mc.height;
var bottomHeight:Number = test_bottom_mc.height;
// 実行ボタン
btn_mc.addEventListener(MouseEvent.CLICK, onBtnClick);
function onBtnClick(evt:Event) {
// 対象の状態をリセットする
test_top_mc.filters = null;
test_top_mc.height = topHeight;
test_bottom_mc.filters = null;
test_bottom_mc.height = bottomHeight;
// 角度
var angle:Number = Number(angle_txt.text);
// 上辺がスクリーンに接した傾き
if (topBitmap) {
removeChild(topBitmap);
topBitmap = null;
}
topBitmap = new Bitmap(PerspectiveUtil.lean(test_top_mc,
angle,
1000));
addChild(topBitmap);
topBitmap.x = test_top_mc.x;
topBitmap.y = test_top_mc.y;
topBitmap.visible = false;
test_top_mc.addEventListener(MouseEvent.ROLL_OVER,
function (e:Event) {
topBitmap.visible = true;
});
test_top_mc.addEventListener(MouseEvent.ROLL_OUT,
function (e:Event) {
topBitmap.visible = false;
});
// 下辺がスクリーンに接した傾き
if (bottomBitmap) {
removeChild(bottomBitmap);
bottomBitmap = null;
}
bottomBitmap
= new Bitmap(PerspectiveUtil.lean(test_bottom_mc,
angle,
1000,
PerspectiveUtil.CONTACT_BOTTOM));
addChild(bottomBitmap);
bottomBitmap.x = test_bottom_mc.x;
bottomBitmap.y = test_bottom_mc.y;
bottomBitmap.visible = false;
test_bottom_mc.addEventListener(MouseEvent.ROLL_OVER,
function (e:Event) {
bottomBitmap.visible = true;
});
test_bottom_mc.addEventListener(MouseEvent.ROLL_OUT,
function (e:Event) {
bottomBitmap.visible = false;
});
}
test_top_mcというのが左側の画像、test_bottom_mcというのが右側の画像デス。
topBitmap、bottomBitmapはそれぞれのPerspecriveUtil.leanメソッドの戻り値を保持する変数デス。画像にロールオーバーしたときに表示するようにしてます。
スポンサーサイト

テーマ:Flash - ジャンル:コンピュータ

2007.07.01 | | Comments(0) | Trackback(0) | Flash CS3

コメント

コメントの投稿


秘密にする

«  | HOME |  »

プロフィール

HundredthMonkey

Author:HundredthMonkey
プログラマ。

ブロとも申請フォーム

この人とブロともになる

メールフォーム

名前:
メール:
件名:
本文:

ブログ内検索


上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。