/* Matrix3DとVector3Dのsample Dragすると回転します @enok00 画像は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.events.MouseEvent; import flash.geom.Matrix3D; import flash.geom.PerspectiveProjection; import flash.geom.Point; 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(); //Drag private var _downFlg:Boolean = false; private var _downPoint:Point; public function Trick() { //SWFProfiler.init(stage, this); Wonderfl.disable_capture(); _imgList = new Array("http://linkalink.jp/enok/wonderfl/3d/images/2-1.jpg", "http://linkalink.jp/enok/wonderfl/3d/images/2-2.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++; (_loadCnt < _imgList.length) ? getImage() : init(); } private function init():void { _myPerspective.focalLength = _nDistance; _viewMatrix3D.appendTranslation(0, 0, _nDistance*1.2); _viewMatrix3D.append(_myPerspective.toMatrix3D()); createPlanes(_bmpList[0], 200, 20, 8, 0.003); createPlanes(_bmpList[1], 100, 12, 4, 0.012); addEventListener(Event.ENTER_FRAME, loop); stage.addEventListener(MouseEvent.MOUSE_DOWN, function():void { _downPoint = new Point(stage.mouseX, stage.mouseY); _downFlg = true; }); stage.addEventListener(MouseEvent.MOUSE_UP, function():void { _downFlg = false; }); } private function createPlanes(pBmpData:BitmapData, pRadius:Number, pNum:uint, pNum2: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; var num2:uint = pNum2; for (var j:uint = 0; j < num2; j++ ) { for (i = 1; i < num; i++ ) { if(i%(mnum*2)==0){continue;} x = 0; y = Math.sin(Math.PI * 2 / num * i - Math.PI / 2) * radius; z = Math.cos(Math.PI * 2 / num * i - Math.PI / 2) * radius; angle = -Math.atan2(y, z) + Math.PI; plane = new Plane(stage, pBmpData, _viewMatrix3D, x, y, z, angle, new Vector3D(1, 0, 0), pNDeceleration); plane._worldMatrix3D.appendRotation(Math.PI / num2 * j * (180 / Math.PI), new Vector3D(0, 1, 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; setChildIndex(p, i); if (_downFlg) { p.aRotation(new Point(stage.mouseX - _downPoint.x, stage.mouseY - _downPoint.y)); } else { p.aRotation(null);} p.draw(); } //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.Point; import flash.geom.Utils3D; import flash.geom.Vector3D; 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; public var _worldMatrix3D:Matrix3D = new Matrix3D(); 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 _vertices2D: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(); private var _a:Point = new Point(0, 0); private var _v:Point = new Point(0, 0); 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 aRotation(pPoint:Point):void { if(pPoint!=null){ _a.x = pPoint.x * _nDeceleration; _a.y = pPoint.y * _nDeceleration; }else { _a.x = 0; _a.y = 0; } _v.x = (_v.x + _a.x) * 0.95; _v.y = (_v.y + _a.y) * 0.95; _worldMatrix3D.appendRotation(-_v.x, Vector3D.Y_AXIS); _worldMatrix3D.appendRotation(_v.y, Vector3D.X_AXIS); } public function draw():void { var myMatrix3D:Matrix3D = _worldMatrix3D.clone(); myMatrix3D.append(_viewMatrix3D); _vertices2D = new Vector.<Number>(); Utils3D.projectVectors(myMatrix3D, _vertices3D, _vertices2D, _uvtData); _myGraphics.clear(); _myGraphics.beginBitmapFill(_bmpData); _myGraphics.drawTriangles(_vertices2D, _indices, _uvtData); _myGraphics.endFill(); } } import flash.system.LoaderContext; 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 { dispatchEvent(new Event(LOAD_COMPLETE)); } public function getLoader():Loader { return loader; } } 3D Image Sphere