プログラミング工房
TOP
Flex基本
開発環境 JavaScript連携 PHP連携1 PHP連携2(AMFPHP) ウィンドウ ボタンスキン 矩形スキン ローカルファイル(テキスト) F5等の対策 ローカルファイル(イメージ) ダウンロード、アップロード 1枚の画像のカラーを変更 時間のかかる計算処理 外部SWFの読込み
Flexで3D
Flexだけで3D Papervision3Dを使ってみる 3Dオブジェクト カメラ、前後判定の工夫しました 自由な形状を作成
Flexでクラス
Class1(白黒ゲームの盤) Class2(白黒ゲームのプレイヤー) Class3(プレイヤーを外部SWF)
PHP
共通関数1
Flexの作品
お問合せの説明 サンプルのソース表示の説明 分子構造の表示(PDBファイル) マンデルブロ集合の画像作成 swf参加型白黒ゲーム(Reversi) ストップウォッチ WEB素材
AIR
AIRを使ってみる ソースファイルのHTML変換を作る
etc.
マンデルブロ集合のギャラリー ジュリア集合のギャラリー wonderflを使ってみました お問合せ

Flexで3D-カメラ、前後判定の工夫しました

■2011.03.24:作成
サンプル サンプルのソース

カメラ、前後判定の工夫しました

Flexで3D-3Dオブジェクト で前後判定が問題があったので、すこし工夫しました。
また、今回は表示物を回転(rotationX等)させるのでなく、視点(カメラ)の位置を変えるようにしてみます。

まず、前後判定の工夫ですが、地面用と建物用の配置領域(BasicView)を分けてみました。
これにより、地面全体が建物の表示の下に来るようにないります。
//初期化
private function initDataSet():void {
    //3D形状の配置領域作成
    bvG = new BasicView();  //地面用
    bvB = new BasicView();  //建物用
    base.addChild( bvG );
    base.addChild( bvB );
    rootNodeG = new DisplayObject3D();
    rootNodeB = new DisplayObject3D();
    bvG.scene.addChild(rootNodeG);
    bvB.scene.addChild(rootNodeB);
    //光源
    light = new PointLight3D();
    light.x = -1000;
    light.y = 1000;
    light.z = 1000;
    //3D形状の配置
    rootNodeG.addChild(mkGround(0xaaffaa, 0x668866));
    rootNodeB.addChild(mkBldg(300, 370, 120, 150, 200, 0, 0xffffff, 0x888888));
    rootNodeB.addChild(mkBldg(420, 370, 80, 150, 240, 0, 0xffffff, 0x888888));
            :
}

視点(カメラ)の位置を原点・カメラ間の距離(カメラは初期値で原点を向きます)、
高さ方向角度、水平方向角度で指定します。
 位置計算にはMath.sin、Math.cosを使用しますので内部計算の角度はラジアンを使用します。

また、視点位置が原点より低いときは地面用と建物用の配置領域(BasicView)の順番を
逆にして前後判定に対応しています。
//Sliderの値変更:カメラの位置セット、形状表示
private function onSlChmg():void {
    //カメラ位置
    var kyori:Number = sldKyori.value;  //原点・カメラの距離
    //高さ方向の角度(ラジアン)
    var ang1:Number = sldAng1.value * Math.PI / 180.0;  
    //方向(ラジアン)
    var ang2:Number = (sldAng2.value-180) * Math.PI / 180.0;
    var x:Number=kyori*Math.cos(ang1)*Math.sin(ang2);
    var y:Number=kyori*Math.cos(ang1)*Math.cos(ang2);
    var z:Number = kyori*Math.sin(ang1);
    bvG.camera.x = x;
    bvG.camera.z = y;
    bvG.camera.y = z;
    bvB.camera.x = x;
    bvB.camera.z = y;
    bvB.camera.y = z;
    
    //地面・建物の深度の交換
    if (z > 0) {
        //カメラの位置が地面より高いとき地面・建物の順
        if (gblSwap == true) {
            gblSwap = false;
            base.removeChild( bvB );
            base.addChild( bvB );
        }
    } else {
        //カメラの位置が地面より高いとき建物・地面の順
        if (gblSwap == false) {
            gblSwap = true;
            base.removeChild( bvG );
            base.addChild( bvG );
        }
    }
    //描画処理
    bvG.renderer.renderScene( bvG.scene , bvG.camera , bvG.viewport );
    bvB.renderer.renderScene( bvB.scene , bvB.camera , bvB.viewport );
}

プログラミング工房