forked from: 3D演習その5 +Matrix3DとScaleとRotate
ActionScript3.0Animation読みながら、とりあえず3D投影してみる。
Z軸で動かしてみる
Camera を導入してみる
Camera を回転させてみた
Zsortをつけてみた
Camera.rotationY がおかしいのを直した。
ぐるぐる回してみる。
Matrix3Dにしてみた
せっかくなのでObject3Dに抽象化&ScaleとRotate実装
// forked from yd_niku's 3D演習その5 +Matrix3DとScaleとRotate
// forked from yd_niku's 3D演習その4 +Camera3Dの回転2
// forked from yd_niku's 3D演習その3 +Camera3Dの回転
// forked from yd_niku's forked from: 3D演習その1
// forked from yd_niku's 3D演習その1
package {
// ActionScript3.0Animation読みながら、とりあえず3D投影してみる。
// Z軸で動かしてみる
// Camera を導入してみる
// Camera を回転させてみた
// Zsortをつけてみた
// Camera.rotationY がおかしいのを直した。
// ぐるぐる回してみる。
// Matrix3Dにしてみた
// せっかくなのでObject3Dに抽象化&ScaleとRotate実装
import flash.display.Sprite;
import flash.display.DisplayObject;
import flash.display.StageQuality;
import flash.events.Event;
import flash.utils.setInterval;
import caurina.transitions.Tweener;
[SWF (backgroundColor='#000A22',frameRate=60)]
public class FlashTest extends Sprite {
private var _scene:Scene3D;
private var _camera:Camera3D;
private var _easeCamera:EaseObject;
private var screenX:Number;
private var screenY:Number;
public function FlashTest() {
stage.quality = StageQuality.MEDIUM;
setup();
putThemFar();
setInterval( changeScale, 2500 );
_easeCamera= new EaseObject( _camera );
addEventListener( Event.ENTER_FRAME, enterframeHandler );
}
private function setup():void {
Object3D.screenX = stage.stageWidth/2;
Object3D.screenY = stage.stageHeight/2;
_camera = new Camera3D();
_scene = new Scene3D( this, _camera );
var xNum:uint = 8, yNum:uint =8, zNum:uint = 8;
var xInterval:uint = 15, yInterval:uint = 15, zInterval:uint =15;
for( var i:int=0; i<xNum; ++i )
for( var j:int=0; j<yNum; ++j )
for( var k:int=0; k<zNum; ++k )
createBall( (i-xNum*0.5)*xInterval, (j-yNum*0.5)*yInterval, (k-zNum*0.2)*zInterval );
}
private function createBall( sx:Number, sy:Number, sz:Number ):void {
var obj3D:DisplayObject3D = new DisplayObject3D(new Ball());
obj3D.x = sx;
obj3D.y = sy;
obj3D.z = sz;
_scene.addChild( obj3D );
}
private function putThemFar():void {
var l:uint = _scene.renderList.length;
for( var i:uint=0; i<l; ++i ) {
var obj:DisplayObject3D = _scene.renderList[i];
var tz:Number= obj.z;
obj.z = 0;
obj.scaleX = obj.scaleY= obj.scaleZ = 0.5;
Tweener.addTween( obj, { z: tz, time:2, delay:1, transition:"easeInOutQuart" } );
}
}
private function changeScale():void {
var l:uint = _scene.renderList.length;
var scale :Number = 2*Math.random()+0.4;
var rotation:Number = 360*Math.random();
for( var i:uint=0; i<l; ++i ) {
var obj:DisplayObject3D = _scene.renderList[i];
Tweener.addTween( obj, { rotateX:rotation, rotateY:rotation, rotateX:rotation, scaleX:scale , scaleY:scale , scaleZ:scale, time:2, transition:"easeInOutQuart" } );
}
}
private function enterframeHandler (e:Event):void{
_easeCamera.vRotateX = 1;
_easeCamera.vRotateY = 1;
_easeCamera.vRotateZ = 1;
_easeCamera.calcuration();
}
}
}
class EaseObject {
public var vx :Number = 0;
public var vy :Number = 0;
public var vz :Number = 0;
public var vRotateX:Number = 0;
public var vRotateY:Number = 0;
public var vRotateZ:Number = 0;
private var friction:Number = 0.95;
private var _target:Object;
public function EaseObject ( target:Object ) {
_target = target;
}
public function calcuration():void {
vx *= friction;
vy *= friction;
vz *= friction;
vRotateX *= friction;
vRotateY *= friction;
vRotateZ *= friction;
_target.x += vx;
_target.y += vy;
_target.z += vz;
_target.rotateX+= vRotateX;
_target.rotateY+= vRotateY;
_target.rotateZ+= vRotateZ;
}
}
import flash.display.*;
import flash.events.*;
import flash.geom.*;
class Scene3D {
private var _stage:DisplayObjectContainer;
private var _camera :Camera3D;
private var _renderList:Array = [];
private var _ZsortList:Array = [];
public function Scene3D( stage:DisplayObjectContainer, camera:Camera3D ){
_stage = stage;
_camera = camera;
_stage.addEventListener( Event.ENTER_FRAME, enterfameHandler );
}
private function enterfameHandler(e:Event):void {
render();
}
public function addChild( obj3D :DisplayObject3D ) :DisplayObject3D {
_renderList.push( obj3D );
_stage.addChild( obj3D.view );
return obj3D;
}
private const PI:Number = Math.PI;
public function render():void {
_ZsortList = [];
var matrixCamera:Matrix3D = _camera.getMatrix3D();
var l:uint = _renderList.length;
for( var i:uint=0; i<l; ++i ) {
var obj:DisplayObject3D= _renderList[i];
var matrixObj :Matrix3D = obj.getMatrix3D();
var p:Vector3D = new Vector3D(obj.x,obj.y,obj.z);
p = matrixObj.transformVector( p );
p = matrixCamera.transformVector( p );
if( _camera.isInFocus( p.z) ) {
var persepective:Number= _camera.getPersepective(p.z);
var tx:Number = p.x*persepective;
var ty:Number = p.y*persepective;
obj.render( tx, ty, persepective);
obj.visible = true;
_ZsortList.push( { z:p.z, view:obj.view } );
}
else {
obj.visible = false;
}
}
// Zsort
_ZsortList.sortOn( "z", Array.DESCENDING|Array.NUMERIC );
l = _ZsortList.length;
for( i=0; i<l; ++i ) {
var zobj:Object = _ZsortList[i] as Object;
_stage.setChildIndex( zobj.view, i );
}
}
public function get renderList():Array{ return _renderList; }
}
class Object3D {
public static var screenX:Number = 0;
public static var screenY:Number = 0;
public var x:Number = 0;
public var y:Number = 0;
public var z:Number = 0;
public var scaleX:Number = 1.0;
public var scaleY:Number = 1.0;
public var scaleZ:Number = 1.0;
public var rotateX:Number = 0.0;
public var rotateY:Number = 0.0;
public var rotateZ:Number = 0.0;
public function getMatrix3D():Matrix3D {
var matrix:Matrix3D = new Matrix3D();
matrix.appendTranslation(x, y, z);
matrix.appendScale( scaleX, scaleY, scaleY );
matrix.appendRotation(rotateX, Vector3D.X_AXIS);
matrix.appendRotation(rotateY, Vector3D.Y_AXIS);
matrix.appendRotation(rotateZ, Vector3D.Z_AXIS);
return matrix;
}
}
class DisplayObject3D extends Object3D {
public var view:DisplayObject;
public function DisplayObject3D( view:DisplayObject=null ) {
this.view = view;
}
public function render( tx:Number, ty:Number, persepective:Number ):void {
view.x = tx + screenX;
view.y = ty + screenY;
view.scaleX = view.scaleY = persepective;
view.alpha = Math.min( 1, persepective);
}
public function set visible( value:Boolean ) :void {
view.visible = value;
}
public function get visible() :Boolean {
return view.visible;
}
}
class Camera3D extends Object3D {
public var focus:Number = 500;
public function getPersepective( tz :Number ):Number {
return focus/( focus+tz );
}
public function isInFocus( tz:Number ):Boolean {
var bool:Boolean = tz > -focus;
return bool;
}
}
import flash.filters.*;
class Ball extends Sprite {
public function Ball() {
//graphics.lineStyle(0,0xffffff);
graphics.beginFill(0xff9900, 1 );
graphics.drawCircle( 0, 0, 5 );
graphics.endFill();
// filters = [ new BlurFilter() ];
// cacheAsBitmap = true;
}
}