forked from: 波打つ平面

by smallflowergame forked from 波打つ平面 (diff: 180)
波打つ平面

- 参考 -
nanlow - 【AS3】DispalyObject3Dの頂点データを取得
http://www.nanlow.com/blog/archives/2009/07/270409.php

...
@author tkinjo
♥0 | Line 104 | Modified 2010-08-11 18:01:35 | MIT License
play

ActionScript3 source code

/**
 * Copyright smallflowergame ( http://wonderfl.net/user/smallflowergame )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/hYYz
 */

// forked from tkinjo's 波打つ平面
package 
{
    /**
     * 波打つ平面
     * 
     * - 参考 -
     * nanlow - 【AS3】DispalyObject3Dの頂点データを取得
     * http://www.nanlow.com/blog/archives/2009/07/270409.php
     */
    
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import org.papervision3d.core.geom.renderables.Vertex3D;
    import org.papervision3d.core.proto.CameraObject3D;
    import org.papervision3d.materials.BitmapMaterial;
    import org.papervision3d.materials.WireframeMaterial;
    import org.papervision3d.objects.primitives.Plane;
    import org.papervision3d.scenes.Scene3D;
    import org.papervision3d.view.AbstractView;
    import org.papervision3d.view.BasicView;
    
    [SWF(width = "465", height = "465", frameRate = "60", backgroundColor = "#ffffff")]
    /**
     * ...
     * @author tkinjo
     */
    public class Main extends Sprite 
    {
        private const PLANE_WIDTH:Number = 200;
        private const PLANE_HEIGHT:Number = 200;
        private const PLANE_SEGMENTS_W:uint = 10;
        private const PLANE_SEGMENTS_H:uint = 10;
        
        private const FREQUENCY:Number = 1;
        private const WAVELENGTH:Number = 20;
        private const AMPLITUDE:Number = 20;
        private const SPEED:uint = 1;
        
        private var plane:Plane;
        
        private var outputtingSignal:Vector.<Number>;
        private var nonOutputSignal:Vector.<Number>;
        
        public function Main():void 
        {
            if (stage) init();
            else addEventListener(Event.ADDED_TO_STAGE, init);
        }
        
        private function init(e:Event = null):void 
        {
            removeEventListener(Event.ADDED_TO_STAGE, init);
            // entry point
            
            outputtingSignal = new Vector.<Number>;
            nonOutputSignal = new Vector.<Number>;
            for ( var i:uint = 0; i < stage.stageWidth; i++ ) {
                
                outputtingSignal.push( 0 );
            }
            
            var noiseBitmapData:BitmapData = createNoiseBitmapData( PLANE_WIDTH, PLANE_HEIGHT );
            
            setupNoiseBitmap( noiseBitmapData );
            
            setupPV3D( noiseBitmapData );
            
            addEventListener( Event.ENTER_FRAME, enterFrameHandler );
            stage.addEventListener( MouseEvent.MOUSE_DOWN, mouseDownHandler );
        }
        
        /**
         * 
         * @param    event
         */
        private function enterFrameHandler( event:Event ):void {
            
            var planeVertices:Array = plane.geometry.vertices;
            
            for ( var i:uint = 0; i < PLANE_SEGMENTS_W + 1; i++ ) {
                
                for ( var j:uint = 0; j < PLANE_SEGMENTS_H + 1; j++ ) {
                    
                    var vertex:Vertex3D = planeVertices[ j + ( ( PLANE_SEGMENTS_W + 1 ) * i ) ] as Vertex3D;
                    vertex.z = outputtingSignal[ i + j ];
                }
            }
            
            // シフト処理
            for ( i = 0; i < SPEED; i++ ) {
                
                outputtingSignal.pop();
                
                if ( nonOutputSignal.length ) {
                    
                    outputtingSignal.unshift( nonOutputSignal[ 0 ] );
                    nonOutputSignal.shift();
                    
                } else {
                    
                    outputtingSignal.unshift( 0 );
                }
            }
            
            /**
             * オブジェクト回転
             */
            plane.rotationY = 360 * ( mouseX - ( stage.stageWidth / 2 ) ) / stage.stageWidth;
            plane.rotationX = 360 * ( mouseY - ( stage.stageHeight / 2 ) ) / stage.stageHeight;
        }
        
        /**
         * PV3D の設定をします。
         */
        private function setupPV3D( noiseBitmapData:BitmapData ):void {
            
            var view:AbstractView = new BasicView( stage.stageWidth, stage.stageHeight / 2 );
            addChild( view );
            
            var scene:Scene3D = view.scene;
            
            var material:BitmapMaterial = new BitmapMaterial( noiseBitmapData );
            //var material:WireframeMaterial = new WireframeMaterial();
            material.doubleSided = true;
            
            plane = new Plane( material, PLANE_WIDTH, PLANE_HEIGHT, PLANE_SEGMENTS_W, PLANE_SEGMENTS_H );

            scene.addChild( plane );
            
            var camera:CameraObject3D = view.camera;
            camera.z = -( camera.focus * camera.zoom );
            
            view.startRendering();
        }
        
        /**
         * ノイズビットマップデータを生成します。
         */
        private function createNoiseBitmapData( width:int, height:int ):BitmapData {
            
            var noiseBitmapData:BitmapData = new BitmapData( width, height );
            noiseBitmapData.noise( 0 );
            
            return noiseBitmapData;
        }
        
        /**
         * ノイズビットマップを配置します。
         */
        private function setupNoiseBitmap( noiseBitmapData:BitmapData ):void {
            
            var noiseBitmap:Bitmap = new Bitmap( noiseBitmapData );
            noiseBitmap.x = stage.stageWidth - noiseBitmap.width;
            noiseBitmap.y = stage.stageHeight - noiseBitmap.height;
            addChild( noiseBitmap );
        }
        
        /**
         * 波形生成
         * 
         * @param    event
         */
        private function mouseDownHandler( event:MouseEvent ):void {
            
            for ( var i:uint = 0; i < WAVELENGTH; i++ ) {
                
                var degrees:Number = i * ( 360 / WAVELENGTH );
                var radian:Number = degrees * ( Math.PI / 180 ) * FREQUENCY;
                var signal:Number = ( Math.sin( radian ) * AMPLITUDE );
                
                if ( i < nonOutputSignal.length )
                    nonOutputSignal[ i ] += signal;
                    
                else
                    nonOutputSignal.push( signal );
            }
        }
    }
    
}