※現在、「wonderfl build flash online」求人コンテンツ制作に関してのアンケートを実施中です!みなさまのお力添えを頂いて、続々とアンケート結果が集まっていますが、まだまだ募集しております。ご協力のほど、どうぞよろしくお願いいたします!

wonderfl運営事務局
→アンケートページ(※ログインしてからお答えいただけるようになっています。)

 notice: Flash editor updated! Join the development! Thanks to MiniBuilder


TALK
Your Code is very useful. Thank You
at 2010/01/04 17:11:57 by
FORKED
  1. // forked from alumican_net's [Study] Sphere using Graphics.drawTriangles
  2. /**
  3.  * FlashPlayer10から追加になったdrawTrianglesで球面マッピング
  4.  * 重複頂点はできるだけマージ
  5.  * あとクォータニオンで回転とか
  6.  * 
  7.  * ブログでちょっとだけ解説
  8.  * http://blog.alumican.net/2009/12/20_014813
  9.  * 
  10.  * @author alumican.net
  11.  * @see texture http://visibleearth.nasa.gov/
  12.  */
  13. package
  14. {
  15.     import com.bit101.components.HUISlider;
  16.     import com.bit101.components.Label;
  17.     import com.bit101.components.RadioButton;
  18.     import flash.display.Bitmap;
  19.     import flash.display.BitmapData;
  20.     import flash.display.Loader;
  21.     import flash.display.Sprite;
  22.     import flash.display.StageAlign;
  23.     import flash.display.StageScaleMode;
  24.     import flash.events.Event;
  25.     import flash.net.URLRequest;
  26.     import flash.system.LoaderContext;
  27.     import net.hires.debug.Stats;
  28.     
  29.     /**
  30.      * FP10Sphere
  31.      * 
  32.      * @author alumican
  33.      */
  34.     public class FP10Sphere extends Sprite
  35.     {
  36.         //----------------------------------------
  37.         //CLASS CONSTANTS
  38.         
  39.         
  40.         
  41.         
  42.         
  43.         //----------------------------------------
  44.         //VARIABLES
  45.         
  46.         /**
  47.          * スフィア
  48.          */
  49.         private var _sphere:Sphere;
  50.         
  51.         /**
  52.          * 回転速度
  53.          */
  54.         private var _vx:Number;
  55.         private var _vy:Number;
  56.         
  57.         
  58.         
  59.         
  60.         
  61.         //----------------------------------------
  62.         //STAGE INSTANCES
  63.         
  64.         
  65.         
  66.         
  67.         
  68.         //----------------------------------------
  69.         //METHODS
  70.         
  71.         /**
  72.          * コンストラクタ
  73.          */
  74.         public function FP10Sphere():void
  75.         {
  76.             stage.align     = StageAlign.TOP_LEFT;
  77.             stage.scaleMode = StageScaleMode.NO_SCALE;
  78.             stage.frameRate = 60;
  79.             addChild(new Stats());
  80.             
  81.             _createSphere();
  82.         }
  83.         
  84.         /**
  85.          * 初期化
  86.          */
  87.         private function _createSphere():void
  88.         {
  89.             var texture:BitmapData;
  90.             var loader:Loader = new Loader();
  91.             loader.contentLoaderInfo.addEventListener(Event.COMPLETE, function(e:Event):void
  92.             {
  93.                 var texture:BitmapData = Bitmap(loader.contentLoaderInfo.content).bitmapData;
  94.                 
  95.                 _vx = 0;
  96.                 _vy = 0;
  97.                 
  98.                 //UI色々
  99.                 var vertexCountLabel:Label  = new Label(stage, 10086"");
  100.                 var surfaceCountLabel:Label = new Label(stage, 18086"");
  101.                 function updateCount():void
  102.                 {
  103.                     vertexCountLabel.text  = "vertex : "  + String(_sphere.vertexCount);
  104.                     surfaceCountLabel.text = "surface : " + String(_sphere.surfaceCount);
  105.                 }
  106.                 
  107.                 new Label(stage, 30010"PROJECTOR");
  108.                 new RadioButton(stage, 30030"Utils3D.projectVectors"   , true , function(e:Event):void { _sphere.useProjectVectors = true;  } );
  109.                 new RadioButton(stage, 30050"Matrix3D.transformVectors"falsefunction(e:Event):void { _sphere.useProjectVectors = false; } );
  110.                 
  111.                 new Label(stage, 10010"SHAPE");
  112.                 var segWSlider:HUISlider   = new HUISlider(stage, 10026"Segment W"function(e:Event):void { _sphere.segmentW = Math.round(e.target.value); updateCount(); } );
  113.                 var segHSlider:HUISlider   = new HUISlider(stage, 10046"Segment H"function(e:Event):void { _sphere.segmentH = Math.round(e.target.value); updateCount(); } );
  114.                 var radiusSlider:HUISlider = new HUISlider(stage, 10066"Radius"   , function(e:Event):void { _sphere.radius   = Math.round(e.target.value); } );
  115.                 radiusSlider.minimum = 10;
  116.                 radiusSlider.maximum = 200;
  117.                 radiusSlider.labelPrecision = 0;
  118.                 radiusSlider.value = 150;
  119.                 segWSlider.minimum = segHSlider.minimum = 2;
  120.                 segWSlider.maximum = segHSlider.maximum = 64;
  121.                 segWSlider.labelPrecision = segHSlider.labelPrecision = 0;
  122.                 segWSlider.value = 16;
  123.                 segHSlider.value = 8;
  124.                 
  125.                 //スフィアを生成する
  126.                 _sphere   = addChild(new Sphere(texture, radiusSlider.value, segWSlider.value, segHSlider.value)) as Sphere;
  127.                 _sphere.x = stage.stageWidth  * 0.5;
  128.                 _sphere.y = stage.stageHeight * 0.5 + 50;
  129.                 
  130.                 updateCount();
  131.                 
  132.                 addEventListener(Event.ENTER_FRAME, _update);
  133.             });
  134.             loader.load(new URLRequest("http://lab.alumican.net/wonderfl/fp10sphere/texture.png"), new LoaderContext(true));
  135.         }
  136.         
  137.         /**
  138.          * 毎フレーム実行
  139.          * @param    e
  140.          */
  141.         private function _update(e:Event):void 
  142.         {
  143.             //回転
  144.             _sphere.rotateByQuaternion(
  145.                 _vx += (-(mouseY / stage.stageHeight - 0.5) * 10 - _vx) * 0.3,
  146.                 _vy += ( (mouseX / stage.stageWidth  - 0.5) * 10 - _vy) * 0.3,
  147.                 0
  148.             );
  149.             
  150.             //レンダリング
  151.             _sphere.render();
  152.         }
  153.     }
  154. }
  155. import flash.display.BitmapData;
  156. import flash.display.Graphics;
  157. import flash.display.Sprite;
  158. import flash.display.TriangleCulling;
  159. import flash.geom.Matrix3D;
  160. import flash.geom.Utils3D;
  161. import flash.geom.Vector3D;
  162. /*****************************************//**
  163.  * 頂点座標情報
  164.  * 
  165.  * @author alumican.net
  166.  */
  167. internal class Vertex3D
  168. {
  169.     //----------------------------------------
  170.     //CLASS CONSTANTS
  171.     
  172.     
  173.     
  174.     
  175.     
  176.     //----------------------------------------
  177.     //VARIABLES
  178.     
  179.     /**
  180.      * 3D座標
  181.      */
  182.     public var x:Number;
  183.     public var y:Number;
  184.     public var z:Number;
  185.     
  186.     /**
  187.      * UV座標
  188.      */
  189.     public var u:Number;
  190.     public var v:Number;
  191.     
  192.     /**
  193.      * 頂点インデックス
  194.      */
  195.     public var index:int;
  196.     
  197.     
  198.     
  199.     
  200.     
  201.     //----------------------------------------
  202.     //STAGE INSTANCES
  203.     
  204.     
  205.     
  206.     
  207.     
  208.     //----------------------------------------
  209.     //METHODS
  210.     
  211.     /**
  212.      * コンストラクタ
  213.      */
  214.     public function Vertex3D():void 
  215.     {
  216.         index = -1;
  217.     }
  218. }
  219. /*****************************************//**
  220.  * 3Dオブジェクトの基底クラス
  221.  * 
  222.  * @author alumican.net
  223.  */
  224. internal class Object3D extends Sprite
  225. {
  226.     //----------------------------------------
  227.     //CLASS CONSTANTS
  228.     
  229.     static public const PI:Number        = Math.PI;
  230.     static public const PI2:Number       = PI * 2;
  231.     static public const TO_RADIAN:Number = PI  / 180;
  232.     static public const TO_DEGREE:Number = 180 / PI;
  233.     
  234.     
  235.     
  236.     
  237.     
  238.     //----------------------------------------
  239.     //VARIABLES
  240.     
  241.     /**
  242.      * レンダリング先
  243.      */
  244.     public var _viewport:Sprite;
  245.     
  246.     /**
  247.      * テクスチャ画像
  248.      */
  249.     public var _texture:BitmapData;
  250.     
  251.     /**
  252.      * 3D変形マトリックス
  253.      */
  254.     private var _transform3D:Matrix3D;
  255.     
  256.     /**
  257.      * 3D頂点情報
  258.      */
  259.     private var _vertices3D:Vector.<Number>;
  260.     private var _indices:Vector.<int>;
  261.     private var _uvData:Vector.<Number>;
  262.     
  263.     /**
  264.      * 頂点/サーフィス数
  265.      */
  266.     public function get vertexCount():uint { return _vertices3D.length / 3; }
  267.     public function get surfaceCount():uint { return _indices.length / 3; }
  268.     
  269.     /**
  270.      * プロジェクト後の座標
  271.      */
  272.     private var _transformedVertices3D:Vector.<Number>;
  273.     private var _transformedVertices2D:Vector.<Number>;
  274.     
  275.     /**
  276.      * projectVectors用
  277.      */
  278.     private var _uvtData:Vector.<Number>;
  279.     
  280.     /**
  281.      * クォータニオン
  282.      */
  283.     private var _qx:Number;
  284.     private var _qy:Number;
  285.     private var _qz:Number;
  286.     private var _qw:Number;
  287.     
  288.     /**
  289.      * レンダリング方法の指定
  290.      * true  : projectVectors
  291.      * false : transformVectors
  292.      */
  293.     public var useProjectVectors:Boolean;
  294.     
  295.     
  296.     
  297.     
  298.     
  299.     //----------------------------------------
  300.     //STAGE INSTANCES
  301.     
  302.     
  303.     
  304.     
  305.     
  306.     //----------------------------------------
  307.     //METHODS
  308.     
  309.     /**
  310.      * コンストラクタ
  311.      */
  312.     public function Object3D(texture:BitmapData = null):void 
  313.     {
  314.         _viewport = addChild( new Sprite() ) as Sprite;
  315.         
  316.         _texture = texture;
  317.         
  318.         useProjectVectors = true;
  319.         
  320.         _transform3D = new Matrix3D();
  321.         _transform3D.identity();
  322.         
  323.         _qx = _qy = _qz = 0;
  324.         _qw = 1;
  325.         
  326.         create();
  327.     }
  328.     
  329.     /**
  330.      * オブジェクトを生成する
  331.      */
  332.     public function create():void
  333.     {
  334.         _vertices3D = new Vector.<Number>();
  335.         _indices    = new Vector.<int>();
  336.         _uvData     = new Vector.<Number>();
  337.         
  338.         _createVetices(_vertices3D, _indices, _uvData);
  339.         
  340.         _transformedVertices2D = new Vector.<Number>(_uvData.length, true);
  341.         _transformedVertices3D = new Vector.<Number>(_vertices3D.length, true);
  342.         
  343.         _uvtData = new Vector.<Number>(_vertices3D.length, true);
  344.         var n:uint = _uvData.length;
  345.         var i:uint = 0;
  346.         var j:uint = 0;
  347.         while (i < n)
  348.         {
  349.             _uvtData[j++] = _uvData[i++];
  350.             _uvtData[j++] = _uvData[i++];
  351.             _uvtData[j++] = null;
  352.         }
  353.     }
  354.     
  355.     /**
  356.      * 3D頂点座標、頂点インデックス、UVデータを生成する(オーバーライド用)
  357.      * @param    vertices3D
  358.      * @param    indices
  359.      * @param    uvData
  360.      */
  361.     protected function _createVetices(vertices3D:Vector.<Number>, indices:Vector.<int>, uvData:Vector.<Number>):void
  362.     {
  363.     }
  364.     
  365.     /**
  366.      * オブジェクトをレンダリングする
  367.      */
  368.     public function render():void
  369.     {
  370.         if (!_texture) return;
  371.         
  372.         if (useProjectVectors)
  373.         {
  374.             //projectVectorsを使う
  375.             Utils3D.projectVectors(_transform3D, _vertices3D, _transformedVertices2D, _uvtData);
  376.         }
  377.         else
  378.         {
  379.             //transformVectorsを使う
  380.             _transform3D.transformVectors(_vertices3D, _transformedVertices3D);
  381.             
  382.             var n:uint = _uvData.length,
  383.                 j:uint = 0;
  384.             for (var i:uint = 0; i < n; i += 2)
  385.             {
  386.                 _transformedVertices2D[i    ] = _transformedVertices3D[j    ];
  387.                 _transformedVertices2D[i + 1] = _transformedVertices3D[j + 1];
  388.                 j += 3;
  389.             }
  390.         }
  391.         
  392.         var g:Graphics = _viewport.graphics;
  393.         g.clear();
  394.         g.beginBitmapFill(_texture, nullfalsefalse);
  395.         g.drawTriangles(_transformedVertices2D, _indices, _uvData, TriangleCulling.NEGATIVE);
  396.     }
  397.     
  398.     /**
  399.      * クォータニオンを用いた回転を付与する
  400.      * @param    rotateX
  401.      * @param    rotateY
  402.      * @param    rotateZ
  403.      * @param    useDegree
  404.      */
  405.     public function rotateByQuaternion(rotateX:Number, rotateY:Number, rotateZ:Number, useDegree:Boolean = true):void
  406.     {
  407.         if (useDegree)
  408.         {
  409.             rotateX *= TO_RADIAN;
  410.             rotateY *= TO_RADIAN;
  411.             rotateZ *= TO_RADIAN;
  412.         }
  413.         
  414.         //----------------------------------------
  415.         //回転クォータニオンの生成
  416.         var fSinPitch:Number       = Math.sin(rotateY * 0.5),
  417.             fCosPitch:Number       = Math.cos(rotateY * 0.5),
  418.             fSinYaw:Number         = Math.sin(rotateZ * 0.5),
  419.             fCosYaw:Number         = Math.cos(rotateZ * 0.5),
  420.             fSinRoll:Number        = Math.sin(rotateX * 0.5),
  421.             fCosRoll:Number        = Math.cos(rotateX * 0.5),
  422.             fCosPitchCosYaw:Number = fCosPitch * fCosYaw,
  423.             fSinPitchSinYaw:Number = fSinPitch * fSinYaw,
  424.             
  425.             rx:Number = fSinRoll * fCosPitchCosYaw     - fCosRoll * fSinPitchSinYaw,
  426.             ry:Number = fCosRoll * fSinPitch * fCosYaw + fSinRoll * fCosPitch * fSinYaw,
  427.             rz:Number = fCosRoll * fCosPitch * fSinYaw - fSinRoll * fSinPitch * fCosYaw,
  428.             rw:Number = fCosRoll * fCosPitchCosYaw     + fSinRoll * fSinPitchSinYaw,
  429.             
  430.             //----------------------------------------
  431.             //元のクォータニオンに回転を合成
  432.             qx:Number = _qw * rx + _qx * rw + _qy * rz - _qz * ry,
  433.             qy:Number = _qw * ry - _qx * rz + _qy * rw + _qz * rx,
  434.             qz:Number = _qw * rz + _qx * ry - _qy * rx + _qz * rw,
  435.             qw:Number = _qw * rw - _qx * rx - _qy * ry - _qz * rz,
  436.             
  437.             //----------------------------------------
  438.             //正規化
  439.             norm:Number = Math.sqrt(qx * qx + qy * qy + qz * qz + qw * qw),
  440.             inv:Number,
  441.             
  442.             //----------------------------------------
  443.             //行列へ変換
  444.             xx:Number,
  445.             xy:Number,
  446.             xz:Number,
  447.             xw:Number,
  448.             
  449.             yy:Number,
  450.             yz:Number,
  451.             yw:Number,
  452.             
  453.             zz:Number,
  454.             zw:Number,
  455.             
  456.             m:Vector.<Number> = _transform3D.rawData;
  457.         
  458.         //----------------------------------------
  459.         //正規化
  460.         
  461.         if(((norm < 0) ? -norm : norm) < 0.000001)
  462.         {
  463.             qx = qy = qz = 0.0;
  464.             qw = 1.0;
  465.         }
  466.         else
  467.         {
  468.             inv = 1 / norm;
  469.             qx *= inv;
  470.             qy *= inv;
  471.             qz *= inv;
  472.             qw *= inv;
  473.         }
  474.         
  475.         //----------------------------------------
  476.         //行列へ変換
  477.         xx = qx * qx;
  478.         xy = qx * qy;
  479.         xz = qx * qz;
  480.         xw = qx * qw;
  481.         
  482.         yy = qy * qy;
  483.         yz = qy * qz;
  484.         yw = qy * qw;
  485.         
  486.         zz = qz * qz;
  487.         zw = qz * qw;
  488.         
  489.         m[0]  = 1 - 2 * (yy + zz);
  490.         m[1]  =     2 * (xy - zw);
  491.         m[2]  =     2 * (xz + yw);
  492.         
  493.         m[4]  =     2 * (xy + zw);
  494.         m[5]  = 1 - 2 * (xx + zz);
  495.         m[6]  =     2 * (yz - xw);
  496.         
  497.         m[8]  =     2 * (xz - yw);
  498.         m[9]  =     2 * (yz + xw);
  499.         m[10] = 1 - 2 * (xx + yy);
  500.         
  501.         _transform3D.rawData = m;
  502.         
  503.         //----------------------------------------
  504.         //クォータニオンの保存
  505.         _qx = qx;
  506.         _qy = qy;
  507.         _qz = qz;
  508.         _qw = qw;
  509.     }
  510. }
  511. /*****************************************//**
  512.  * スフィア
  513.  * 
  514.  * @author alumican.net
  515.  */
  516. class Sphere extends Object3D
  517. {
  518.     //----------------------------------------
  519.     //CLASS CONSTANTS
  520.     
  521.     
  522.     
  523.     
  524.     
  525.     //----------------------------------------
  526.     //VARIABLES
  527.     
  528.     /**
  529.      * 半径
  530.      */
  531.     public function get radius():Number { return _radius; }
  532.     public function set radius(value:Number):void { _radius = value;  create(); }
  533.     private var _radius:Number;
  534.     
  535.     /**
  536.      * 水平方向の分割数
  537.      */
  538.     public function get segmentW():uint { return _segmentW; }
  539.     public function set segmentW(value:uint):void { _segmentW = value; create(); }
  540.     private var _segmentW:uint;
  541.     
  542.     /**
  543.      * 垂直方向の分割数
  544.      */
  545.     public function get segmentH():uint { return _segmentH; }
  546.     public function set segmentH(value:uint):void { _segmentH = value; create(); }
  547.     private var _segmentH:uint;
  548.     
  549.     
  550.     
  551.     
  552.     
  553.     //----------------------------------------
  554.     //METHODS
  555.     
  556.     /**
  557.      * コンストラクタ
  558.      */
  559.     public function Sphere(texture:BitmapData = null, radius:Number = 100, segmentW:uint = 8, segmentH:uint = 6):void
  560.     {
  561.         _radius   = radius;
  562.         _segmentW = segmentW;
  563.         _segmentH = segmentH;
  564.         
  565.         super(texture);
  566.     }
  567.     
  568.     /**
  569.      * 頂点情報を生成する
  570.      */
  571.     override protected function _createVetices(vertices3D:Vector.<Number>, indices:Vector.<int>, uvData:Vector.<Number>):void 
  572.     {
  573.         var i:uint,
  574.             j:uint,
  575.             n:uint,
  576.             p:Vertex3D,
  577.             index:uint,
  578.             x:Number,
  579.             y:Number,
  580.             u:Number,
  581.             v:Number,
  582.             angleU:Number,
  583.             angleV:Number,
  584.             points:Vector.<Vertex3D> = new Vector.<Vertex3D>(),
  585.             poly:Vector.<Vertex3D> = new Vector.<Vertex3D>(4),
  586.             poleN:Vertex3D,
  587.             poleS:Vertex3D,
  588.             segW:uint = _segmentW + 1,
  589.             segH:uint = _segmentH + 1;
  590.         
  591.         //頂点の生成
  592.         for (i = 0; i < segH; ++i)
  593.         {
  594.             for (j = 0; j < segW; ++j)
  595.             {
  596.                 p = new Vertex3D();
  597.                 
  598.                 //このあたりの頂点をマージしたい
  599.                 //if (i == 0       ) { if (j == 0) poleN = p; else p = poleN; }        // テクスチャ上端に対応する頂点
  600.                 //if (i == segH - 1) { if (j == 0) poleS = p; else p = poleS; }        // テクスチャ下端に対応する頂点
  601.                 //if (j == segW - 1) { p = _points[_points.length - segW + 1]; }    // テクスチャ右端に対応する頂点
  602.                 
  603.                 u = j / (segW - 1);
  604.                 v = i / (segH - 1);
  605.                 
  606.                 angleU = u * PI2;
  607.                 angleV = v * PI;
  608.                 
  609.                 y = -_radius * Math.cos(angleV);
  610.                 x =  _radius * Math.sin(angleU) * Math.sin(angleV);
  611.                 z = -_radius * Math.cos(angleU) * Math.sin(angleV);
  612.                 
  613.                 p.x = x;
  614.                 p.y = y;
  615.                 p.z = z;
  616.                 p.u = u;
  617.                 p.v = v;
  618.                 
  619.                 points.push(p);
  620.             }
  621.         }
  622.         
  623.         //ポリゴンの生成
  624.         n = points.length;
  625.         index = 0;
  626.         for (i = 0; i < n; ++i)
  627.         {
  628.             if (i + segW + 1 >= n) break;
  629.             if ((i + 1) % segW == 0continue;
  630.             
  631.             poly[0] = points[i];
  632.             poly[1] = points[i + 1];
  633.             poly[2] = points[i + segW];
  634.             poly[3] = points[i + segW + 1];
  635.             
  636.             for (j = 0; j < 4; ++j)
  637.             {
  638.                 //新規頂点を追加
  639.                 if ((p = poly[j]).index == -1)
  640.                 {
  641.                     p.index = index++;
  642.                     
  643.                     //3D座標
  644.                     vertices3D.push(p.x, p.y, p.z);
  645.                     
  646.                     //UV座標
  647.                     uvData.push(p.u, p.v);
  648.                 }
  649.             }
  650.             
  651.             //頂点インデックスに追加(時計回り)
  652.             indices.push(
  653.                 poly[0].index, poly[1].index, poly[2].index,
  654.                 poly[1].index, poly[3].index, poly[2].index
  655.             );
  656.         }
  657.     }
  658. }
noswf
Get Adobe Flash Player