Stellaqua - TOMの技術日記 このページをアンテナに追加 RSSフィード

2010年07月25日

[][]ジブリ作品を混ぜ合わせて新しい作品のタイトルとキャッチコピーを作っちゃうWebサービスを作ってみた

最近、もはや趣味の域に達してきた感のある、誰得Webサービス作りのお時間でございます。

今回は、ジブリ作品最新作公開記念という事で、ジブリ作品のタイトルとキャッチコピーを使ったWebサービスを作ってみました。

ジブリブレンダー

アイデア元は、例によって(?)、2chまとめサイトからです。

ジブリの題名混ぜて一番おもしろかったヤツが優勝 - おはようwwwお前らwwwwwwww

元スレではタイトルのブレンドだけでしたが、「キャッチコピーもブレンドしてみたら面白いんじゃね?」と思い付いて、タイトルとキャッチコピーをブレンドするようにしてみました。

元スレの方の下らなさ(いい意味で…)も相当なものでしたが、Webサービスができあがって試してみたら、キャッチコピーのブレンド具合が絶妙で、かなり破壊力抜群の仕上がりになりました。(笑)

という訳で、ぜひ遊んでみて下さいね〜。

2009年09月24日

[][]Redminegitコミットログが取得できない

以前の記事(「Redmineをインストールしてみた - Stellaqua - TOMの技術日記」)の時にRedmineインストールした後、結局まともに使ってなかったんですが、最近ちょっとまともに使い始めています。

Redmineはホントによくできていて使い易くて素晴らしいんですが、使い始めたところで、「リポジトリの画面で、gitコミットログが表示されない」という問題に当たってしまいました。という訳で、せっかくなので情報共有も兼ねて覚え書きを。

見え方としては、リポジトリのツリー自体は見えていてツリーを辿っていく事もできるんですが、ファイル名以外の情報が表示されていなくて、"最新リビジョン"の項目については項目自体がそもそも表示されない状態でした。

で、Google先生にすがりついた挙句に、どうやらgitコマンドでカラー表示させていたのがよくなかったっぽい事が判明。

そこで、

git config --global color.branch always

git config --global color.diff always

git config --global color.interactive always

git config --global color.status always

みたいにして、常にカラー表示しようとするんですが、

そうすると、周辺ツールなどで予期しない結果がアプリにわたってしまうためか不具合がおきます。

例えば、redminegitリポジトリを使うと、コミットログが反映されなかったりします。

バージョン管理システムについて語るスレ4

普段、gitの設定は上記のように"always"でカラー表示するようにしてたので、どうもこれでビンゴっぽい。

カラー設定を"auto"に変えてあげたら、無事にRedmine上でコミットログが表示されるようになりました、めでたしめでたし。

2009年03月30日

[][][]四角い地球の歩き方 その1「地箱を作ろう」

前回の記事の内容がめでたくシリーズモノに昇格いたしました。パチパチ。

きっかけは1年越しに唐突に…

前回、唐突に3Dの話をし始めたのには理由がありまして…もう1年以上も前なんですが、2chまとめサイトで、"もしも地球が正方形だったら"っていうタイトル*1のスレを見たのが、そもそものきっかけでした。

F速VIP(・ω・)y-? もしも地球が正方形だったら

これが非常に想像力を掻き立てられて、自分なりに「どうなるんだろうか?」と色々と想像を膨らませておりました。*2

この時は「面白いなぁ。」だけで終わったんですが、最近急に「これって、Flashとかで3D処理すれば、実際に立方体の地球の上を歩くシミュレーションが作れるんじゃね?」となぜだか急に思ってしまい、Flashの3D処理について唐突に調べ始めた…というのが事の顛末だったりします。

このシリーズの趣旨

Flashの3D処理の勉強も兼ねて、立方体の地球の上を自由に歩き回れるシミュレーションを作る事を目標に、備忘録として記事を書きながら、少しずつ実装を進めていきたいと思います。

教科書代わりのサイト

前回の記事のリンクにも入れたんですが、rectさんという方のnote.xというブログが激しく参考になるので、こちらを教科書代わりに利用させて頂こうと思っています。

note.xさんの記事を一通りざっと読ませて頂いて、PaperVision3D 2.0を使った方が良さそう、という事と、あとAway3DっていうPaperVision3Dからの派生プロダクトも良さげ、という事が分かりました。

今回のシリーズ記事では、基本的にはPaperVision3D 2.0を使って、場合によってAway3Dを使ってみたり、あとは物理エンジンにも手を出せたらいいなと思っています。

今回の目標

という訳で、ここからが本題。今回は、立方体の地球を表示させるところまでをやってみます。

ちなみに、"立方体の地球"といちいち書くのも面倒なので、以降は"地箱"と書いていこうと思います。

世界地図のテクスチャを用意する

地箱を作るには、基本的には世界地図の絵を立方体に貼り付ければいいだけなので、まずは世界地図のテクスチャを探します。

幸い、note.xさんでフリーで使える地球テクスチャについて言及されている記事があって、それによると、以下のサイトでダウンロードできるとの事。

Planet Earth Texture Maps

「サイズが1KBytesのものはフリー」と書いてあるので、ありがたく使わせて頂く事にします。

テクスチャを立方体に貼り付ける

テクスチャが手に入ったので、続いて、note.xさんの以下の記事を参考に、テクスチャを立方体にペタペタと貼り付けていきます。

no title

ただ、立方体の展開図は当然長方形ではない訳で、そのままじゃうまく貼れないので、以下のような展開図で貼り付ける事にしました。

f:id:stellaqua:20090330201343j:image

当然、上面と下面はおかしな事になるけど、本筋ではないので今回はこれで妥協…。

図に示した前後左右上下は、camera.zの値を負に設定した時に手前に見えている面を前とした時の方向です。三角形ごとに付いている番号は、cube.geometry.faces[no]として面を取得した時に、どの番号がどの三角形に対応するかを記したものです。

ちなみに、note.xさんの記事で"Planeの頂点とUVとの関連づけ"の説明図通りにUVを設定すると向きがずれてしまったんですが、以下のような対応にしてやったらうまくいきました。

f:id:stellaqua:20090330201437p:image

Planeでやると確かにnote.xさんの記事の通りになるので、どうやらPlaneとCubeで生成される三角形面の頂点の定義が異なるようですな。

今回の成果物

という事で、ひとまず地箱のベースの完成です。

直リンク→http://www.stellaqua.com/swf/EarthCube1.swf

せっかくなので、地軸を見えるようにして、地軸が傾いた状態で自転させてみました。

ソースコードはこの記事の最後に載せておきたいと思います。

次回は?

最終的には一人称視点で自由に歩き回れるようにしたいんですが、その前にまずは地箱の面上を歩き回った時に、面上の自分の座標から三次元座標への変換ができないといけないので、次回はその辺りに挑戦してみたいと思います。

それにしても、3Dの世界は、一歩足を踏み入れると泥沼の楽しさでヤバ過ぎる…。(笑)

ソースコード

package
{
    import flash.display.*;
    import flash.events.*;

    import org.papervision3d.view.*;
    import org.papervision3d.events.*;
    import org.papervision3d.core.math.*;
    import org.papervision3d.objects.*;
    import org.papervision3d.objects.primitives.*;
    import org.papervision3d.materials.*;
    import org.papervision3d.materials.utils.*;

    [SWF(backgroundColor=0x000000)]

    public class EarthCube1 extends BasicView
    {
        private var rootNode   : DisplayObject3D;
        private var objCube    : Cube
        private var ang        : Number = 0;

        [Embed(source='earthmap1k.jpg')] public var texBitmap:Class;

        public function EarthCube1()
        {
            stage.frameRate = 30;
            stage.align = StageAlign.TOP_LEFT;
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.quality = StageQuality.MEDIUM;

            //viewportの定義とカメラタイプ定義
            super (0,0,true,true,"Target");
            init3D();
        }

        public function init3D():void
        {
            rootNode = new DisplayObject3D();
            scene.addChild(rootNode);

            //カメラ設定
            camera.z = -1200;
            camera.y = 500;
            camera.fov = 30;

            //マテリアル設定
            var material:BitmapMaterial = new BitmapMaterial(new texBitmap().bitmapData, true);
            material.interactive = true;
            material.precise = true;
            var materials:MaterialsList = new MaterialsList({all : material});

            //Cubeオブジェクト生成
            objCube = new Cube(materials, 250, 250, 250, 1, 1, 1);
            rootNode.addChild(objCube);

            //テクスチャ変更(前面)
            objCube.geometry.faces[ 2].uv0 = new NumberUV(0.75, 0.25);
            objCube.geometry.faces[ 2].uv1 = new NumberUV(1.00, 0.25);
            objCube.geometry.faces[ 2].uv2 = new NumberUV(0.75, 0.75);
            objCube.geometry.faces[ 3].uv0 = new NumberUV(1.00, 0.25);
            objCube.geometry.faces[ 3].uv1 = new NumberUV(1.00, 0.75);
            objCube.geometry.faces[ 3].uv2 = new NumberUV(0.75, 0.75);

            //テクスチャ変更(後面)
            objCube.geometry.faces[ 0].uv0 = new NumberUV(0.25, 0.25);
            objCube.geometry.faces[ 0].uv1 = new NumberUV(0.50, 0.25);
            objCube.geometry.faces[ 0].uv2 = new NumberUV(0.25, 0.75);
            objCube.geometry.faces[ 1].uv0 = new NumberUV(0.50, 0.25);
            objCube.geometry.faces[ 1].uv1 = new NumberUV(0.50, 0.75);
            objCube.geometry.faces[ 1].uv2 = new NumberUV(0.25, 0.75);

            //テクスチャ変更(左面)
            objCube.geometry.faces[ 4].uv0 = new NumberUV(0.00, 0.25);
            objCube.geometry.faces[ 4].uv1 = new NumberUV(0.25, 0.25);
            objCube.geometry.faces[ 4].uv2 = new NumberUV(0.00, 0.75);
            objCube.geometry.faces[ 5].uv0 = new NumberUV(0.25, 0.25);
            objCube.geometry.faces[ 5].uv1 = new NumberUV(0.25, 0.75);
            objCube.geometry.faces[ 5].uv2 = new NumberUV(0.00, 0.75);

            //テクスチャ変更(右面)
            objCube.geometry.faces[ 6].uv0 = new NumberUV(0.50, 0.25);
            objCube.geometry.faces[ 6].uv1 = new NumberUV(0.75, 0.25);
            objCube.geometry.faces[ 6].uv2 = new NumberUV(0.50, 0.75);
            objCube.geometry.faces[ 7].uv0 = new NumberUV(0.75, 0.25);
            objCube.geometry.faces[ 7].uv1 = new NumberUV(0.75, 0.75);
            objCube.geometry.faces[ 7].uv2 = new NumberUV(0.50, 0.75);

            //テクスチャ変更(上面)
            objCube.geometry.faces[ 8].uv0 = new NumberUV(0.75, 0.75);
            objCube.geometry.faces[ 8].uv1 = new NumberUV(1.00, 0.75);
            objCube.geometry.faces[ 8].uv2 = new NumberUV(0.75, 1.00);
            objCube.geometry.faces[ 9].uv0 = new NumberUV(0.25, 1.00);
            objCube.geometry.faces[ 9].uv1 = new NumberUV(0.25, 0.75);
            objCube.geometry.faces[ 9].uv2 = new NumberUV(0.50, 0.75);

            //テクスチャ変更(下面)
            objCube.geometry.faces[10].uv0 = new NumberUV(1.00, 0.25);
            objCube.geometry.faces[10].uv1 = new NumberUV(0.75, 0.25);
            objCube.geometry.faces[10].uv2 = new NumberUV(1.00, 0.00);
            objCube.geometry.faces[11].uv0 = new NumberUV(0.50, 0.00);
            objCube.geometry.faces[11].uv1 = new NumberUV(0.50, 0.25);
            objCube.geometry.faces[11].uv2 = new NumberUV(0.25, 0.25);

            //地軸オブジェクト生成
            var objAxis:DisplayObject3D = drawAxis(0xff3333);
            rootNode.addChild(objAxis);

            //地軸を傾ける
            rootNode.rotationZ = -23.4;

            //レンダリング開始
            startRendering();
        }

        override protected function onRenderTick(event:Event=null):void
        {
            ang = ( ang - 1 ) % 360;
            objCube.rotationY = ang;

            super.onRenderTick(event);
        }

        private function drawAxis(color:uint):DisplayObject3D {
            //色設定
            var colorMaterial:ColorMaterial = new ColorMaterial(color, 1);
            colorMaterial.doubleSided = true;
            
            //円柱を作る
            var axis:DisplayObject3D = new Cylinder(colorMaterial, 2, 400);
            
            //円柱の先に球を作る
            var sphere1:DisplayObject3D = new Sphere(colorMaterial, 10);
            var sphere2:DisplayObject3D = new Sphere(colorMaterial, 10);
            sphere1.y = 200;
            sphere2.y = -200;
            
            var node:DisplayObject3D = new DisplayObject3D();
            node.addChild(axis);
            node.addChild(sphere1);
            node.addChild(sphere2);
            
            return node;
        }
    }
}

*1:スレを立てた人は立方体の事を言いたかったようなので、そもそもタイトルが変ではありますが…。

*2:こういう科学系の思考実験は大好きなんです。