In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

Matrix3D.recompose()

Matrix3D.recompose();
と同じ機能の関数を作ってみる。
MAC 10,0,2,54,MAC 10,0,12,36で動作確認。

処理としては
eulerAngles to Matrix3D
axisAngle to Matrix3D
quaternion to Matrix3D
を行う。


拡大 / 縮小エレメントのをかけかたに
プレイヤーのバージョンによって違いがあるっぽい。
MAC 10,0,2,54ではappendScale
MAC 10,0,12,36ではprependScale
のように処理しているので、それに合わせて分岐処理をしている。

実制作の場合には気をつけないといけなさそう。

helpには「拡大 / 縮小エレメントのいずれかが 0 の場合は、false を返します。」
とあるがtrueしか返さないっぽい、、



各要素をrandomで値を入れて、recomposeし、
行列の各要素を比較して確認とした。

Matrix3D.recompose()
http://help.adobe.com/ja_JP/AS3LCR/Flash_10.0/flash/geom/Matrix3D.html#recompose()
Get Adobe Flash player
by umhr 18 Feb 2009
    Embed
/**
 * Copyright umhr ( http://wonderfl.net/user/umhr )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/rLU6
 */

/*
Matrix3D.recompose();
と同じ機能の関数を作ってみる。
MAC 10,0,2,54,MAC 10,0,12,36で動作確認。

処理としては
eulerAngles to Matrix3D
axisAngle to Matrix3D
quaternion to Matrix3D
を行う。


拡大 / 縮小エレメントのをかけかたに
プレイヤーのバージョンによって違いがあるっぽい。
MAC 10,0,2,54ではappendScale
MAC 10,0,12,36ではprependScale
のように処理しているので、それに合わせて分岐処理をしている。

実制作の場合には気をつけないといけなさそう。

helpには「拡大 / 縮小エレメントのいずれかが 0 の場合は、false を返します。」
とあるがtrueしか返さないっぽい、、



各要素をrandomで値を入れて、recomposeし、
行列の各要素を比較して確認とした。

Matrix3D.recompose()
http://help.adobe.com/ja_JP/AS3LCR/Flash_10.0/flash/geom/Matrix3D.html#recompose()
*/
package {
  import flash.display.Sprite;
  import flash.geom.Matrix3D;
  import flash.geom.Orientation3D;
  import flash.text.TextField;
  import flash.geom.Vector3D;
  import flash.system.Capabilities;
  public class FlashTest extends Sprite {
    public function FlashTest() {
      var txt:String="◆同機能関数Mtrx3D.recompose "+Capabilities.version+"での実行結果\n\n";

      //確認用の値を用意
      var entityMatrix3D:Matrix3D=new Matrix3D(Util.random9());
      var entity1:Matrix3D=new Matrix3D();
      var entity2:Matrix3D=new Matrix3D();
      var orientationStyle:String;
      if (Math.random()<1/3) {
        orientationStyle="eulerAngles";
      } else if (Math.random()<1/2) {
        orientationStyle="axisAngle";
      } else {
        orientationStyle="quaternion";
      }
      var entity:Vector.<Vector3D>=entityMatrix3D.decompose(orientationStyle);
      
      // == "10,0,2,54"
//      entity[2].x = 0;
//      entity[2].y = 0;
//      entity[2].z = 0;
      
      //実行
      entity1.recompose(entity,orientationStyle);
      Mtrx3D.recompose(entity2,entity,orientationStyle);
      
      //確認
      txt+="orientationStyle = "+orientationStyle+"で確認\n\n";
      var entity1RawData:Vector.<Number>=entity1.rawData;
      txt+="↓Matrix3D.recomposeの結果\n"+entity1RawData+"\n";
      var entity2RawData:Vector.<Number>=entity2.rawData;
      txt+="\n↓同機能関数Mtrx3D.recomposeの結果\n"+entity2RawData+"\n\n";
      txt+=Util.hikaku(entity1RawData,entity2RawData);

      //テキストフィールドを作りtxtを流し込み。
      var tf:TextField = new TextField();
      tf.width=stage.stageWidth;
      tf.height=stage.stageHeight;
      tf.wordWrap=true;
      stage.addChild(tf);
      tf.text=txt;
    }
  }
}
import flash.display.Sprite;
class Mtrx3D extends Sprite {
  import flash.geom.Matrix3D;
  import flash.geom.Vector3D;
  import flash.system.Capabilities;
  public static function recompose(entity:Matrix3D,components:Vector.<Vector3D>, orientationStyle:String = "eulerAngles"):Boolean {
    
    //プレヤーのバージョンによって乗算の仕方が違うっぽい。
    var ver_array:Array = Capabilities.version.substr(4).split(",");
    var scale:Vector.<Number>=new Vector.<Number>(16,true);
    if(int(ver_array[2])*1000+int(ver_array[3]) > 2054){
      //prependScale的な乗算
      scale[0] = scale[1] = scale[2] = components[2].x;
      scale[4] = scale[5] = scale[6] = components[2].y;
      scale[8] = scale[9] = scale[10] = components[2].z;
    }else{
      //10,0,2,54以下の場合はこちら
      //appendScale的な乗算
      scale[0] = scale[4] = scale[8] = components[2].x;
      scale[1] = scale[5] = scale[9] = components[2].y;
      scale[2] = scale[6] = scale[10] = components[2].z;
    }
    trace(scale)
    
    var v:Vector.<Number>=new Vector.<Number>(16,true);
    if (orientationStyle=="eulerAngles") {
      //eulerAngles to Matrix3D
      var cx:Number=Math.cos(components[1].x);
      var cy:Number=Math.cos(components[1].y);
      var cz:Number=Math.cos(components[1].z);
      var sx:Number=Math.sin(components[1].x);
      var sy:Number=Math.sin(components[1].y);
      var sz:Number=Math.sin(components[1].z);
      v[0]=cy*cz*scale[0];
      v[1]=cy*sz*scale[1];
      v[2]=- sy*scale[2];
      v[3]=0;
      v[4] = (sx*sy*cz-cx*sz)*scale[4];
      v[5] = (sx*sy*sz+cx*cz)*scale[5];
      v[6]=sx*cy*scale[6];
      v[7]=0;
      v[8] = (cx*sy*cz+sx*sz)*scale[8];
      v[9] = (cx*sy*sz-sx*cz)*scale[9];
      v[10]=cx*cy*scale[10];
      v[11]=0;
      v[12]=components[0].x;
      v[13]=components[0].y;
      v[14]=components[0].z;
      v[15]=1;
    } else {
      //"quaternion" to Matrix3D
      var x:Number=components[1].x;
      var y:Number=components[1].y;
      var z:Number=components[1].z;
      var w:Number=components[1].w;
      if (orientationStyle=="axisAngle") {
        //"axisAngle" to Matrix3D
        x*=Math.sin(w/2);
        y*=Math.sin(w/2);
        z*=Math.sin(w/2);
        w=Math.cos(w/2);
      }
      v[0] = (1-2*y*y-2*z*z)*scale[0];
      v[1] = (2*x*y+2*w*z)*scale[1];
      v[2] = (2*x*z-2*w*y)*scale[2];
      v[3]=0;
      v[4] = (2*x*y-2*w*z)*scale[4];
      v[5] = (1-2*x*x-2*z*z)*scale[5];
      v[6] = (2*y*z+2*w*x)*scale[6];
      v[7]=0;
      v[8] = (2*x*z+2*w*y)*scale[8];
      v[9] = (2*y*z-2*w*x)*scale[9];
      v[10] = (1-2*x*x-2*y*y)*scale[10];
      v[11]=0;
      v[12]=components[0].x;
      v[13]=components[0].y;
      v[14]=components[0].z;
      v[15]=1;
    }
    //v[0],v[4],v[8]が三つとも0だと
    //ArgumentError: Error #2188: 行マトリックスが無効です。マトリックスは反転可能である必要があります。
    //というエラーでMatrix3Dを作れないので、設定可能な最小値を入れている。
    //0.000000000000000000000000000000000000000000001;
    //これは1e-45と書ける。
    //ただしx,y,z三つとも1e-45には設定できないので、1e-15にしてる。
    if(components[2].x == 0){v[0] = 1e-15};
    if(components[2].y == 0){v[5] = 1e-15};
    if(components[2].z == 0){v[10] = 1e-15};
    entity.rawData = v;
    //helpには拡大 / 縮小エレメントのいずれかが 0 の場合は、false を返します。
    //とあるがtrueしか返さないっぽい、、
    //return !(components[2].x == 0 || components[2].y == 0 || components[2].y == 0)
    return true;
  }
}
class Util {
  import flash.geom.Matrix3D;
  import flash.geom.Vector3D;
  public static function hikaku(v0:Vector.<Number>,v1:Vector.<Number>):String {
    var _str:String="↓二つのMatrix3Dの要素毎の差\n";
    var _n:int=v0.length;
    for (var i:int=0; i<_n; i++) {
      _str += "["+i+"]:"+(v0[i]-v1[i])+"\n";
    }
    return _str;
  }

  public static function random16():Vector.<Number> {
    var _v:Vector.<Number>=new Vector.<Number>(16,true);
    for (var i:int=0; i<16; i++) {
      _v[i]=Math.random()*200-100;
    }
    return _v;
  }
  public static function random9():Vector.<Number> {
    var _mt:Matrix3D = new Matrix3D();
    var v:Vector.<Vector3D>=new Vector.<Vector3D>  ;
    v[0]=new Vector3D(200*Math.random()-100,200*Math.random()-100,200*Math.random()-100);//平行移動、
    v[1]=new Vector3D(10*Math.random()-5,10*Math.random()-5,10*Math.random()-5);//回転
    v[2]=new Vector3D(100*Math.random(),100*Math.random(),100*Math.random());//拡大 / 縮小
    _mt.recompose(v);
    return _mt.rawData;
  }
}