In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

3Dお絵かき Ver0.3

2011-01-7
papervision3Dの習作として3Dのお絵かきツールを作ってみました。
次は奥行きも考慮して描けるのと、ピクセルではなく線で描けるようにしたいと思います。

2011-01-16
ピクセルからline3Dで描くように変更しました。
W,Sキーで3Dカーソルの奥行き方向の移動ができるようになりました。

----------------操作方法-----------------
青い点:3Dカーソル
マウス左クリック+マウス上下左右:点を描く
Shiftキー+マウス左右:カメラ回転
スペースキー:描いた絵を消す
Wキー:3Dカーソルを奥に移動
Sキー:3Dカーソルを手前に移動
-----------------------------------------
Get Adobe Flash player
by sasa 15 Jan 2011
/**
 * Copyright sasa ( http://wonderfl.net/user/sasa )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/yNek
 */

package {
    import flash.events.*;
    import flash.geom.*;
    import flash.filters.*;
    import flash.utils.*;
    import flash.display.StageQuality;
    import org.papervision3d.core.math.Number3D;
    import org.papervision3d.core.utils.*;
    import org.papervision3d.core.effects.*;
    import org.papervision3d.core.geom.*;
    import org.papervision3d.core.geom.renderables.*;
    import org.papervision3d.materials.*;
    import org.papervision3d.materials.special.LineMaterial;
    import org.papervision3d.objects.primitives.*;
    import org.papervision3d.view.layer.*;
    import org.papervision3d.view.*;
    
    [SWF(backgroundColor="0x000000")]
    
    public class Main extends BasicView {
        
        //------------------------------------
        // プライベートメンバ変数
        //------------------------------------
        private var _writeMode:Boolean = false;
        private var _dragMode:Boolean = false;
        private var _rot:Number = 0;
        private var _cursor:Sphere;
        private var _cur3Dcursor:Number3D;
        private var _old3Dcursor:Number3D;
        private var _saveOld3Dcursor:Number3D;
        private var _depth:Number = 0;
        private var _distDepth:Number = 10;
        private var _curpos:Point;
        private var _oldpos:Point;
        private var _lines3D:Lines3D;
        private var _lm:LineMaterial;
        private var _layer:BitmapEffectLayer;
        
        //------------------------------------
        // コンストラクタ
        //------------------------------------
        public function Main():void {
            stage.quality = StageQuality.LOW;
            
            //地面を作成
            var plane:Plane = new Plane(new WireframeMaterial(0x333333), 2000, 2000, 14, 14);
            plane.y = -stage.stageHeight/2;
            plane.rotationX = 90;
            scene.addChild(plane);
            
            //3Dカーソルを作成
            _cursor = new Sphere(new WireframeMaterial(0x0099FF), 4, 4, 4);
            scene.addChild(_cursor);

            //3Dカーソルの移動量を測るための、_old3Dcursor、_cur3Dcursorを作成
            _cur3Dcursor = get3DcurPos();
            _old3Dcursor = _cur3Dcursor;            
            
            //マウスカーソルの移動量を測るための、_curpos、_oldposを作成
            //ビューの回転にしか使わない。
            _curpos = new Point(mouseX, mouseY);
            _oldpos = new Point();
            _oldpos = _curpos;
                
            //カメラの初期位置設定
            _rot = mouseX / stage.stageWidth * 360;
            camera.x = 1000 * Math.cos(_rot * Math.PI / 180);
            camera.y = 200;
            camera.z = 1000 * Math.sin(_rot * Math.PI / 180);
            
            // ビットマップエフェクトレイヤーを作成
            _layer = new BitmapEffectLayer(viewport, 640, 480);
            viewport.containerSprite.addLayer(_layer);
            // ブラーエフェクトを設定
            _layer.addEffect(new BitmapLayerEffect(new BlurFilter(2, 2, 4), false));
            
            //ラインマテリアルを作成
            _lm = new LineMaterial(0xFF9900);
            
            // レンダリング
            startRendering();
            
            // エンターフレームイベントの登録
            stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
            stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
            stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
            stage.addEventListener(KeyboardEvent.KEY_UP, keyUPHandler);
            stage.addEventListener(Event.ENTER_FRAME, loop);
        }
        
        //------------------------------------
        // MouseDownの挙動
        // _writeModeをtrueにし、line3Dを描けるよう準備する
        //------------------------------------
        private function mouseDownHandler(event:MouseEvent):void
        {
            _lines3D = new Lines3D();
            scene.addChild(_lines3D);
            _layer.addDisplayObject3D(_lines3D);
            _writeMode = true;
        }
        
        //------------------------------------
        // MouseUpの挙動
        // _writeModeをfalseにし、line3Dを描かないようにする
        //------------------------------------
        private function mouseUpHandler(event:MouseEvent):void
        {
            _writeMode = false;
        }
        
        //------------------------------------
        // KeyDownの挙動
        // Shiftキーが押されたら
        // 1.マウス位置と_depthを元に、3Dカーソルの位置を求める
        // 2.現在のマウス位置を_oldposに保存する
        // 3._dragModeをtrueにし、カメラを回転させる準備をする
        // スペースキーが押されたら、line3Dをすべて消す
        // Wキーが押されたら、_depth(今のカメラ位置を元にした奥行き)を減少させる。
        // Sキーが押されたら、_depth(今のカメラ位置を元にした奥行き)を増加させる。
        //------------------------------------
        private function keyDownHandler(e:KeyboardEvent):void {
            switch(e.keyCode)
            {
                case 16://SHIFTキー
                    _old3Dcursor = get3DcurPos();
                    _oldpos = new Point(mouseX, mouseY);
                    _dragMode = true;
                    break;
                case 32://SPACEキー
                    _lines3D.removeAllLines();
                    break;
                case 83://Sキー
                    _depth -= _distDepth;
                    break;
                case 87://Wキー
                    _depth += _distDepth;
                    break;
            }
        }
        
        //------------------------------------
        // KeyUpの挙動
        // Shiftキーが離されたら
        // 1.現在の3dカーソル位置を_old3Dcursorに保存する
        // 2._dragModeをtrueにし、カメラを回転させる準備をする
        //------------------------------------
        private function keyUPHandler(e:KeyboardEvent):void {
            if(e.keyCode == 16)
            {
                _old3Dcursor = _cur3Dcursor;
                _dragMode = false;
            }
        }
        
        //------------------------------------
        // EnterFrameの挙動
        // 1.カーソルの位置更新
        // 2.マウスダウンされていたら(= _writeModeがtrueなら)、3Dカーソルの位置にline3Dを描く
        // 3.Shiftキーが押されていたら(= _dragModeがtrueなら)、マウスの位置から角度を計算しカメラを回転させる
        //------------------------------------
        private function loop(e:Event):void
        {
            //マウスカーソルの位置取得
            _oldpos = _curpos;
            _curpos = new Point(mouseX, mouseY);
            //3Dカーソルの位置更新
            _old3Dcursor = _cur3Dcursor;
            _cur3Dcursor = get3DcurPos();
            _cursor.x = _cur3Dcursor.x;
            _cursor.y = _cur3Dcursor.y;
            _cursor.z = _cur3Dcursor.z;
            
            if(_writeMode)
            {
                //過去と現在の3Dカーソル位置の差から、line3Dを描く
                var line3D:Line3D = new Line3D(_lines3D, _lm, 1,
                    new Vertex3D(_old3Dcursor.x, _old3Dcursor.y, _old3Dcursor.z), 
                        new Vertex3D(_cur3Dcursor.x, _cur3Dcursor.y, _cur3Dcursor.z));
                _lines3D.addLine(line3D);
            }
            else if(_dragMode)
            {
                //shiftキーが押させる前のマウス位置(_oldpos)と現在のマウス位置(_oldpos)の差分を回転量とし、現在の角度_rotに足す
                _rot += (_oldpos.x - _curpos.x) / stage.stageWidth * 360;
                camera.x = 1000 * Math.cos(_rot * Math.PI / 180);
                camera.z = 1000 * Math.sin(_rot * Math.PI / 180);
            }
        }
        
        private function get3DcurPos():Number3D
        {
            //3Dカーソルをカメラと垂直平面上で動かすため、まず3Dカーソルを(現在の角度+90)回転させ、
            //またdepth値を元に3Dカーソルの奥行き位置を足して計算する
            var tempX:Number = (mouseX - stage.stageWidth / 2) * 2 * Math.cos((_rot + 90) * Math.PI / 180)
                                + _depth * Math.cos((_rot + 180) * Math.PI / 180);
            var tempY:Number = -mouseY + stage.stageHeight/2;
            var tempZ:Number = (mouseX - stage.stageWidth / 2) * 2 * Math.sin((_rot + 90) * Math.PI / 180)
                                + _depth * Math.sin((_rot + 180) * Math.PI / 180);
                                
            return new Number3D(tempX, tempY, tempZ);
        }
    }
}