3D Image Ring
Matrix3DとVector3Dのsample
詳細は「ActionScript3.0による三次元表現ガイドブック」を
http://linktale.net/
画像はr-type-lさんの
http://r-type-l.net/
/**
* Copyright linktale ( http://wonderfl.net/user/linktale )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/ovps
*/
/*
Matrix3DとVector3Dのsample
詳細は「ActionScript3.0による三次元表現ガイドブック」を
http://linktale.net/
画像はr-type-lさんの
http://r-type-l.net/
*/
package {
import com.flashdynamix.utils.SWFProfiler;
import flash.display.BitmapData;
import flash.display.Loader;
import flash.display.Sprite;
import flash.events.Event;
import flash.geom.Matrix3D;
import flash.geom.PerspectiveProjection;
import flash.geom.Vector3D;
[SWF(backgroundColor="0xffffff", frameRate="40")]
public class Trick extends Sprite {
//Image
private var _imgList:Array;
private var _imgLoader:ImageLoader;
private var _bmpList:Array = new Array();
private var _loadCnt:uint = 0;
//3D
private var _viewMatrix3D:Matrix3D = new Matrix3D();
private var _nDistance:Number = 1000;
private var _myPerspective:PerspectiveProjection = new PerspectiveProjection();
public function Trick() {
//SWFProfiler.init(stage, this);
Wonderfl.disable_capture();
_imgList = new Array("http://linkalink.jp/enok/wonderfl/3d/images/1-2.jpg", "http://linkalink.jp/enok/wonderfl/3d/images/1-4.jpg", "http://linkalink.jp/enok/wonderfl/3d/images/1-3.jpg");
//_imgList = new Array("images/1-2.jpg", "images/1-4.jpg", "images/1-3.jpg");
getImage();
}
private function getImage():void {
_imgLoader = new ImageLoader(_imgList[_loadCnt]);
_imgLoader.addEventListener(ImageLoader.LOAD_COMPLETE, onImageLoaded);
}
private function onImageLoaded(e:Event):void {
var _currentLoader:Loader = e.currentTarget.getLoader();
_bmpList[_loadCnt] = new BitmapData(_currentLoader.width, _currentLoader.height);
_bmpList[_loadCnt].draw(_currentLoader);
_loadCnt++;
if (_loadCnt < _imgList.length) {
getImage();
}else{
init();
}
}
private function init():void {
_myPerspective.focalLength = _nDistance;
_viewMatrix3D.appendTranslation(0, 0, _nDistance*1.2);
_viewMatrix3D.append(_myPerspective.toMatrix3D());
createPlanes(_bmpList[0], 250, 16, 0.01);
createPlanes(_bmpList[1], 150, 12, 0.007);
createPlanes(_bmpList[2], 50, 4, 0.003);
addEventListener(Event.ENTER_FRAME, loop);
}
private function createPlanes(pBmpData:BitmapData, pRadius:Number, pNum:uint, pNDeceleration:Number=0.01):void {
var i:uint;
var x:Number = 0, y:Number = 0, z:Number = 0, angle:Number = 0;
var plane:Plane;
var radius:Number = pRadius;
//4の倍数
var num:uint = pNum;
var mnum:uint = num / 4;
for (i = 0; i < num; i++ ) {
x = Math.cos(Math.PI * 2 / num * i) * radius;
y = 0;
z = Math.sin(Math.PI * 2 / num * i) * radius;
angle = Math.atan2(x, z) + Math.PI;
plane = new Plane(stage, pBmpData, _viewMatrix3D, x, y, z, angle, new Vector3D(0, 1, 0), pNDeceleration);
addChild(plane);
}
for (i = 1; i < num; i++ ) {
x = 0;
y = Math.sin(Math.PI * 2 / num * i) * radius;
z = Math.cos(Math.PI * 2 / num * i) * radius;
angle = -Math.atan2(y, z) + Math.PI;
plane = new Plane(stage, pBmpData, _viewMatrix3D, x, y, z, angle, new Vector3D(1, 0, 0), pNDeceleration);
addChild(plane);
}
for (i = 1; i < num; i++ ) {
if(i%mnum==0){continue;}
x = Math.sin(Math.PI * 2 / num * i) * radius;
y = Math.cos(Math.PI * 2 / num * i) * radius;
z = 0
angle = -Math.atan2(x, y) + Math.PI;
plane = new Plane(stage, pBmpData, _viewMatrix3D, x, y, z, angle, new Vector3D(0, 0, 1), pNDeceleration);
plane._worldMatrix3D.prependRotation(Math.PI / 2 * 3 * (180 / Math.PI), new Vector3D(1, 0, 0));
addChild(plane);
}
}
private function loop(e:Event):void {
var i:uint;
var nChildren:uint = numChildren;
var pList:Array = new Array();
var p:Plane;
for (i = 0; i < nChildren; i++ ) {
p = getChildAt(i) as Plane;
pList.push({"p":p, "z":p._worldMatrix3D.position.z});
}
pList.sortOn("z", Array.NUMERIC | Array.DESCENDING);
for (i = 0; i < nChildren; i++ ) {
p = pList[i].p;
p.loop();
setChildIndex(p, i);
}
//viewを回してもOK
/*
_viewMatrix3D.prependRotation(0.1, new Vector3D(0, 1, 0));
_viewMatrix3D.prependRotation(0.1, new Vector3D(1, 0, 0));
_viewMatrix3D.prependRotation(0.1, new Vector3D(0, 0, 1));
*/
}
}
}
import flash.display.BitmapData;
import flash.display.DisplayObjectContainer;
import flash.display.Graphics;
import flash.display.Sprite;
import flash.events.Event;
import flash.geom.Matrix3D;
import flash.geom.Utils3D;
import flash.geom.Vector3D;
import flash.system.LoaderContext;
class Plane extends Sprite {
private var _s:DisplayObjectContainer;
private var _bmpData:BitmapData;
public var _radiusX:Number;
public var _radiusY:Number;
public var _radiusZ:Number;
private var _angle:Number;
private var _axis:Vector3D;
private var _nUnit:Number;
private var _nDeceleration:Number ;
private var _mySprite:Sprite = new Sprite();
private var _myGraphics:Graphics = _mySprite.graphics;
private var _myTexture:BitmapData;
private var _vertices3D:Vector.<Number> = new Vector.<Number>();
private var _indices:Vector.<int> = new Vector.<int>();
private var _uvtData:Vector.<Number> = new Vector.<Number>();
private var _viewMatrix3D:Matrix3D = new Matrix3D();
public var _worldMatrix3D:Matrix3D = new Matrix3D();
public function Plane(ps:DisplayObjectContainer, pBmpData:BitmapData, pViewMatrix3D:Matrix3D, pRadiusX:Number, pRadiusY:Number, pRadiusZ:Number, pAngle:Number, pAxis:Vector3D, pNDeceleration:Number):void {
_s = ps;
_bmpData = pBmpData;
_viewMatrix3D = pViewMatrix3D;
_radiusX = pRadiusX;
_radiusY = pRadiusY;
_radiusZ = pRadiusZ;
_angle = pAngle;
_axis = pAxis;
_nDeceleration = pNDeceleration;
_nUnit = _bmpData.width / 2;
_myTexture= new BitmapData(_bmpData.width, _bmpData.height);
init();
}
private function init():void {
_mySprite.x = _s.stage.stageWidth / 2;
_mySprite.y = _s.stage.stageHeight / 2;
addChild(_mySprite);
_vertices3D.push(-_nUnit, -_nUnit, 0);
_vertices3D.push(_nUnit, -_nUnit, 0);
_vertices3D.push(-_nUnit, _nUnit, 0);
_vertices3D.push(_nUnit, _nUnit, 0);
_indices.push(0, 1, 2);
_indices.push(1, 3, 2);
_uvtData.push(0, 0, 0);
_uvtData.push(1, 0, 0);
_uvtData.push(0, 1, 0);
_uvtData.push(1, 1, 0);
_worldMatrix3D.prependRotation(_angle * (180 / Math.PI), _axis);
_worldMatrix3D.appendTranslation(_radiusX, _radiusY, _radiusZ);
}
public function loop(e:Event=null):void {
var vertices2D:Vector.<Number> = new Vector.<Number>();
var nRotationX:Number = _mySprite.mouseY * _nDeceleration;
var nRotationY:Number = _mySprite.mouseX * _nDeceleration;
_worldMatrix3D.appendRotation(nRotationX, Vector3D.X_AXIS);
_worldMatrix3D.appendRotation(nRotationY, Vector3D.Y_AXIS);
var myMatrix3D:Matrix3D = _worldMatrix3D.clone();
myMatrix3D.append(_viewMatrix3D);
Utils3D.projectVectors(myMatrix3D, _vertices3D, vertices2D, _uvtData);
_myGraphics.clear();
_myGraphics.beginBitmapFill(_bmpData);
_myGraphics.drawTriangles(vertices2D, _indices, _uvtData);
_myGraphics.endFill();
}
}
import flash.display.DisplayObjectContainer;
import flash.display.Loader;
import flash.display.LoaderInfo;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.net.URLRequest;
class ImageLoader extends EventDispatcher {
public static const LOAD_COMPLETE:String = "LOAD_COMPLETE";
public static const IOERROR:String = "IOERROR";
protected var loader:Loader;
public function ImageLoader(purl:String) {
loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loaded);
init(purl);
}
protected function init(purl:String):void {
var loaderContext:LoaderContext = new LoaderContext(true);
var urlReq:URLRequest = new URLRequest(purl);
loader.load(urlReq, loaderContext);
}
protected function loaded(e:Event):void {
//trace(LOAD_COMPLETE);
dispatchEvent(new Event(LOAD_COMPLETE));
}
public function getLoader():Loader { return loader; }
}