ビルトインクラスで3Dの習作
via alumican_net [Study] Sphere using Graphics.drawTriangles
http://wonderfl.net/c/4Hj9
@author ue
/**
* Copyright _ueueueueue ( http://wonderfl.net/user/_ueueueueue )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/caEb
*/
package
{
import com.bit101.components.HUISlider;
import com.bit101.components.PushButton;
import flash.display.*;
import flash.events.*;
import flash.geom.*;
import flash.net.FileReference;
import flash.text.*;
import flash.ui.*;
import net.hires.debug.Stats;
[SWF(width=465,height=465,backgroundColor=0x0)]
/**
* via alumican_net [Study] Sphere using Graphics.drawTriangles
* http://wonderfl.net/c/4Hj9
*
* @author ue
*/
public class Main extends Sprite
{
private var obj:TriangleObject;
private var bmp:Bitmap;
private var ref:FileReference;
public function Main():void
{
ref = new FileReference();
var loadButton:PushButton = new PushButton(stage, 350, 430, "load", onClick);
Wonderfl.capture_delay( 7 );
addChild(new Stats());
}
private function onClick(e:Event):void
{
ref.addEventListener(Event.SELECT, onSelect);
ref.browse();
}
private function onSelect(e:Event):void
{
ref.removeEventListener(Event.SELECT, onSelect);
ref.addEventListener(Event.COMPLETE, onComplete);
ref.load();
}
private function onComplete(e:Event):void
{
var loader:Loader = new Loader();
loader.loadBytes(ref.data);
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadComplete);
}
private function loadComplete(e:Event):void
{
bmp = e.target.content as Bitmap;
initialize();
obj.draw();
addEventListener(Event.ENTER_FRAME, update);
}
private function initialize():void
{
obj = null;
obj = new TriangleObject(bmp.bitmapData);
obj.x = stage.stageWidth / 2;
obj.y = stage.stageHeight / 2 -30;
obj.z = 0;
addChild(obj);
var colsSlider:HUISlider = new HUISlider(stage, 10, 375, "cols", function(e:Event):void
{
obj.cols = Math.floor(e.target.value);
}
);
colsSlider.minimum = 3;
colsSlider.maximum = 32;
colsSlider.value = 15;
var rowsSlider:HUISlider = new HUISlider(stage, 10, 390, "rows", function(e:Event):void
{
obj.rows = Math.floor(e.target.value);
}
);
rowsSlider.minimum = 3;
rowsSlider.maximum = 32;
rowsSlider.value = 15;
var radiusSlider:HUISlider = new HUISlider(stage, 10, 405, "radius", function(e:Event):void
{
obj.radius = e.target.value;
}
);
radiusSlider.minimum = 50;
radiusSlider.maximum = 300;
radiusSlider.value = 150;
var meshButton:PushButton = new PushButton(stage, 10, 430, "mesh", function(e:Event):void
{
obj.isDisp = !obj.isDisp;
}
);
}
private function update(e:Event):void
{
obj.draw();
}
}
}
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.display.TriangleCulling;
class TriangleObject extends Sprite
{
public static const PLANE:String = "plane";
public static const SPHERE:String = "sphere";
private var _vetices:Vector.<Number>;
private var _indices:Vector.<int>;
private var _uvtData:Vector.<Number>;
private var _offset:Number = 0;
private var _source:BitmapData;
private var _res:Number;
private var _cols:int;
private var _rows:int;
private var _type:String;
private var _isDisp:Boolean;
private var _radius:Number;
private var _focalLength:Number = 1000;
private var _center:Number = 200;
public function TriangleObject(source:BitmapData=null,type:String =TriangleObject.SPHERE,radius:Number=150, cols:int = 10, rows:int = 10)
{
_source = source;
_radius = radius;
_cols = cols;
_rows = rows;
_res = res;
_type = type;
_isDisp = true;
_vetices = new Vector.<Number>();
_indices = new Vector.<int>();
_uvtData = new Vector.<Number>();
makeTriangles();
draw();
}
/**
* 頂点データの生成
*/
private function makeTriangles():void
{
_indices.length = 0;
for (var i:int = 0; i < _rows; i++)
{
for (var j:int = 0; j < _cols; j++)
{
if (i < rows - 1 && j < cols - 1)
{
_indices.push(i * cols + j,
i * cols + j + 1,
(i + 1) * cols + j);
_indices.push(i * cols + j + 1,
(i + 1) * cols + j + 1,
(i + 1) * cols + j);
}
}
}
}
/**
* 描画の更新
*/
public function draw():void
{
_vetices.length = 0;
_uvtData.length = 0;
_offset += 0.02;
switch(_type)
{
case TriangleObject.PLANE:
drawPlane();
break;
case TriangleObject.SPHERE:
drawSphere();
break;
default:
break;
}
graphics.clear();
graphics.beginBitmapFill(_source);
graphics.drawTriangles(_vetices, _indices, _uvtData, TriangleCulling.NEGATIVE);
graphics.endFill();
if (_isDisp)
{
graphics.lineStyle(0,0xffffff, .3);
graphics.drawTriangles(_vetices, _indices, _uvtData, TriangleCulling.NEGATIVE);
graphics.endFill();
}
}
/**
* 平面の描画
*/
private function drawPlane():void
{
for (var i:int = 0; i < _rows; i++)
{
for (var j:int = 0; j < _cols; j++)
{
_vetices.push(j * res - (res * (_cols - 1) / 2), i * res - (res * (_rows - 1) / 2));
_uvtData.push(j / (cols - 1), i / (rows - 1));
}
}
}
/**
* 球体の描画
*/
private function drawSphere():void
{
for (var i:int = 0; i < _rows; i++)
{
for (var j:int = 0; j < _cols; j++)
{
var angle1:Number = Math.PI * 2 / (_cols - 1) * j;
var angle2:Number = Math.PI * i / (_rows - 1) - Math.PI / 2;
var xpos:Number = Math.cos(angle1+_offset) * _radius * Math.cos(angle2);
var ypos:Number = Math.sin(angle2) * _radius;
var zpos:Number = Math.sin(angle1+_offset) * _radius * Math.cos(angle2);
var scale:Number = _focalLength / (_focalLength + zpos+center);
_vetices.push(xpos * scale, ypos * scale);
_uvtData.push(j / (cols - 1), i / (rows - 1));
_uvtData.push(scale);
}
}
}
/**
* 横の分割数
*/
public function get cols():int { return _cols; }
public function set cols(value:int):void
{
_cols = value;
makeTriangles();
draw();
}
/**
* 縦の分割数
*/
public function get rows():int { return _rows; }
public function set rows(value:int):void
{
_rows = value;
makeTriangles();
draw();
}
/**
* 解像度
*/
public function get res():Number { return _res; }
public function set res(value:Number):void
{
_res = value;
makeTriangles();
draw();
}
/**
* 描画タイプ
*/
public function get type():String { return _type; }
public function set type(value:String):void
{
_type = value;
draw();
}
/**
* 3Dメッシュの表示/非表示
*/
public function get isDisp():Boolean { return _isDisp; }
public function set isDisp(value:Boolean):void
{
_isDisp = value;
draw();
}
/**
* 球体の半径
*/
public function get radius():Number { return _radius; }
public function set radius(value:Number):void
{
_radius = value;
draw();
}
/**
* 焦点距離
*/
public function get focalLength():Number { return _focalLength; }
public function set focalLength(value:Number):void
{
_focalLength = value;
draw();
}
/**
* z座標の中心
*/
public function get center():Number { return _center; }
public function set center(value:Number):void
{
_center = value;
draw();
}
public function get source():BitmapData { return _source; }
public function set source(value:BitmapData):void
{
_source = value;
draw();
}
}