波打つ平面
波打つ平面
- 参考 -
nanlow - 【AS3】DispalyObject3Dの頂点データを取得
http://www.nanlow.com/blog/archives/2009/07/270409.php
...
@author tkinjo
/**
* Copyright tkinjo ( http://wonderfl.net/user/tkinjo )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/nDfQ
*/
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 );
}
}
}
}