note.x

メインで使ってたPowerBook のHDDのb-treeがスっ飛んじゃったんで、これを期にサブで使ってたMacBookProに環境移行中。
んで、rascutがまともに動かないトラブルに遭遇したんでメモっとく。

環境は、OSX10.5.6。
いきなりgemが使えるので、普通にインストール。

sudo gem install rascut --include-dependencies

これだと/Library/Ruby/Gems/1.8/gems/rascut-0.1.3/にインストールされる。

このままだと不具合が起きるので、
下記のページを参考に各ファイルを修正

rascutが動かない。 – 俺はまだ死んではいない
Flex [てきとうにめも]

■/Library/Ruby/Gems/1.8/gems/rascut-0.1.3/lib/rascut/fcsh_wrapper.rb

    @@ -60,10 +60,10 @@
    def process
    unless @process
    - orig_lang = ENV['LANG']
    - ENV['LANG'] = 'C' # for flex3 sdk beta locale
    + orig_java_options = ENV['_JAVA_OPTIONS']
    + ENV['_JAVA_OPTIONS'] = '-Duser.language=en' # for flex3 sdk beta locale
    @process = IO.popen(@config[:fcsh_cmd] + ' 2>&1', 'r+') unless @process
    - ENV['LANG'] = orig_lang
    + ENV['_JAVA_OPTIONS'] = orig_java_options
    end
    @process
    end

■/Library/Ruby/Gems/1.8/gems/rascut-0.1.3/lib/rascut/httpd.rb

   @path = env["PATH_INFO"] == '/' ? @root : F.join(@root, env['PATH_INFO'])
   ↓
   @path = env["PATH_INFO"].empty? || env["PATH_INFO"] == '/' ? @root : F.join(@root, env['PATH_INFO'])

mime-typesが足りないようなので、インストールして

sudo gem install mime-types

/Library/Ruby/Gems/1.8/gems/rascut-0.1.3/lib/rascut/httpd.rbを追加修正

require'mime/types' を追記

"Content-Type"   => MIME_TYPES[ext] || "text/plain",
↓
"Content-Type"   => MIME::Types.type_for(@path).to_s || "text/plain",

てとこまでで、ようやくrascutがサーバーモードで起動できた。
ところが、.asファイルを編集→保存しても、ブラウザをリロードしてくれなかったりいろいろおかしい。

んで、困ってたとこでRUNELEAF_LOGさんの記事を発見。
rack のバージョンが問題とのことで、

sudo /usr/bin/gem install -v 0.3.0 rack
sudo /usr/bin/gem uninstall -v 0.9.1 rack

にて解決した。やれやれだぜ。

追記
コメント欄で、os0x さんに正しい解決策を伝授していただきました。
なんという無駄エントリー。やれやれなのはオレ自身だぜ。


たまには3D以外のこともやってみるべーということで、NUTSUさん作の、Processing気分を味わうAS3.0ライブリラリ「Frocessing」で遊んでみた。

nutsu/Frocessing – Spark project

svnリポジトリに上がってるサンプルが .flaファイルしか無いので、FlexSDKで扱う方法を模索。とりあえず F5MovieClip2DとかF5MovieClip3Dを継承しとけばいいみたいだということにオレの中で結論づいたので、なんぞ作ってみる。

で、これまたP5ライクな「NodeBox」のサンプルを移植して若干イジったのが下記。
Hello Froce55ing(要:FlashPlayer9)

package
{
    import flash.display.*;
    import frocessing.display.F5MovieClip2D;
 
    public class main extends F5MovieClip2D
    {
        private var count:int;
 
        public function main()
        {
            stage.frameRate = 30;
            stage.align = StageAlign.TOP_LEFT;
            stage.scaleMode = StageScaleMode.NO_SCALE;
 
            super();
            QBest();
        }
 
        public function draw():void
        {
            clear();
            background(255,255,255);
 
            count++;
            translate(fg.width/2, fg.height/2);
            fill(0, 153, 230, 0.1);
            stroke(0, 153, 230, 0.4);
            strokeWeight(0);
 
            for (var i:int = 0; i < 150; i++)
            {
                var x:Number = random(fg.width/2, -fg.width/2) * cos(radians(count));
                var y:Number = random(fg.height/2, -fg.height/2) * cos(radians(count));
                var r:Number = cos(radians(count)) * 50;
                circle(x,y,r);
            }
        }
 
    }
}

ステージプロパティ設定してるあたりがかなりビミョーだけど、こんな感じでいいのかなぁ?FlashIDEのドキュメントクラス設定と同等のことってFlexSDKで出来るのかしら。このあたり激しく勉強不足でワカンネー。けど動いたからまぁいいや(えー)

もっとP5っぽいものを、と思ってストレンジアトラクタ系ネタも作ってみたものの、lineで描画しまくったら予想通りのブラクラになっちゃったんで静止画のみで。

setBmpMode()を使えばBitmapが描画対象になる…のか?軽くする方法が解かるまでひとまず保留っと。

FlexSDK3 + Rascut + mi という修行僧のような環境でもそこそこ楽しめた。
でもまぁ素直にFlashIDEつかってフレームスクリプト書いたほうがシンプルに書けて、よりP5気分に浸れるのかも。ただこれ、慣れちゃうとAS3.0本来のシンタックス忘れるわ、間違いなく確実にオレは(笑)


astro_test.swf(要:FlashPlayer10 beta)

Astro触ってみた。好評現実逃避中。
Targeting Flash Player 10 Beta with Flex SDK 3.0.x – Adobe Open Sourceを参照しつつFlashPlayer10向け環境をセットアップ。SDKはBuild 3.0.1.1739 を使った。

Sprite、MovieClipで使える3DEffect(.z とか、rotationX,Y,Z とか)って、flash.geom.Transform 使った変形をお手軽に使えるようにしたものっていう解釈でいいのかな? 簡単だし軽いんで、ちょっと3Dっぽくしたい時はこれで充分かと。
んで、もうちょっとマジメに3Dしたい場合はやっぱり頂点シェーダー的なものを実装しなくちゃならないわけで、その辺に挑戦してみたのが上記のデモ。
キモになる部分をまとめたソースが以下。

※09/01/10 コードを若干修正

package
{
    import flash.display.*;
    import flash.events.*;
    import flash.geom.*;
 
    [SWF(backgroundColor="#000000")]
 
    public class astro_sample extends Sprite
    {
        private var view:Sprite;
        private var fov:PerspectiveProjection = new PerspectiveProjection();
        private var vertex:Vector.<Vector3D>;
        private var deg:Number = 0;
        private var dot:Vector.<Sprite> = new Vector.<Sprite>();
        private var pivot:Vector3D = new Vector3D(0,0,0);
        private var wid:Number = 200;
        private var hei:Number = 200;
        private var dep:Number = 200;
 
        public function astro_sample()
        {
            stage.frameRate = 60;
            stage.align = StageAlign.TOP_LEFT;
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.quality = StageQuality.BEST;
 
            init3D();
        }
 
        private function init3D():void
        {
            view = new Sprite();
            addChild(view);
            view.x = stage.stageWidth >> 1;
            view.y = stage.stageHeight >> 1;
            view.z = 0;
 
            //視野角の設定
            fov.fieldOfView = 55;
 
            //頂点の定義
            vertex = Vector.<Vector3D>
            ([
                new Vector3D(-wid/2, +hei/2, -dep/2),
                new Vector3D(+wid/2, +hei/2, -dep/2),
                new Vector3D(+wid/2, -hei/2, -dep/2),
                new Vector3D(-wid/2, -hei/2, -dep/2),
                new Vector3D(-wid/2, +hei/2, +dep/2),
                new Vector3D(+wid/2, +hei/2, +dep/2),
                new Vector3D(+wid/2, -hei/2, +dep/2),
                new Vector3D(-wid/2, -hei/2, +dep/2)
            ]);
 
            //表示オブジェクト定義
            for (var i:int = 0; i < 8; i++)
            {
                var s:Sprite = new Sprite();
                view.addChild(s);
                s.graphics.beginFill(0x0099CC);
                s.graphics.drawCircle(0, 0, 5);
                s.graphics.endFill();
                dot.push(s);
            }
 
            stage.addEventListener(Event.RESIZE, onStageResize);
            addEventListener(Event.ENTER_FRAME, onEnterFrame);
        }
 
        //Render Loop
        private function onEnterFrame(event:Event):void
        {
            //回転角度を増加
            deg++;
 
            var matrix:Matrix3D = new Matrix3D();
            //回転行列生成
            matrix.appendRotation(deg, Vector3D.Y_AXIS, pivot);
            matrix.appendRotation(deg, Vector3D.Z_AXIS, pivot);
 
            var vs:int = vertex.length;
            for(var i:int = 0; i < vs; i++ )
            {
                //座標変換
                var v:Vector3D = matrix.transformVector(vertex[i]);
                v.w = fov.focalLength / (fov.focalLength + v.z);
                v.project();
 
                //表示オブジェクト座標に割り当て
                dot[i].x = v.x;
                dot[i].y = v.y;
            }
        }
 
        private function onStageResize(event:Event):void
        {
            view.x = stage.stageWidth >> 1;
            view.y = stage.stageHeight >> 1;
        }
 
    }
}

下記の記事が大いに参考になりました。

地味で実装が辛いコアクラスが一通りビルトインされてるってのはスゲェ。
Vector3DとMatrix3DとPerspectiveProjectionクラスだけでそれっぽいものが出来た。やっててよかったPV3D。
PV3DやSandyをはじめとする既存3Dエンジンは、このへんのコアクラスを全部入れ替えて、Arrayの代わりにVectorは積極的に使いつつ、drawTrianglesで描画するように変更するだけでかなり高速化されるんじゃないのかなぁ。パースペクティブコレクトのおまけ付きだし。


来るべきPhysics時代(何)に備えてAPE(Actionscript Physics Engine)を触ってみる。とりあえず、パーティクル掴んでポイポイできるようにしてみた。もっと簡単にできると思ってたら結構めんどうだった。付属のデモにはマウスイベント絡めたものが無くて、GoogleGroup – APE Generalの「Tunnelling Problem w/ Interactivity」が参考になった。

e_apestudy.jpg

Ape_study.swf(要:FlashPlayer9)

なんか挙動がおかしいのを何とかしたいのと、もうちょっと軽くしたいところ。