2012年10月19日金曜日

映画 ロボジー

矢口史靖監督作品 ロボジーを鑑賞。


 この手の映画は恐らく映画館に行っても声を出して笑ってしまうので、自宅で見る他ない。ニュー潮風が自分の手でレンズを調整したシーンは爆笑であった。まぁ、アトムも自分のお腹を手で開閉するわけで、そうおかしい話では無いのかもしれないのだが。

 しかし、やはりSEが重要なのだなと実感。人々がどんどんと騙されていく展開にリアリティがあったのは、観客もそれがロボだと感じられたからなのだろう。そしてそう感じられたのは、やはり歩き出した時のSEに、おおっと思わせられたからだ。(私の場合は

2012年10月8日月曜日

Blender Bmesh Introduction

 Blenderは動画チュートリアルがたくさんある。どんな機能があるかを知るにはとてもいいのだが、どう使うのか思い出したいときには少し不便だ。ということでメモを取っておく。

 とりあえずBmeshについて主要な操作を抑えておきたいので、初回はBmesh Introductionだ。

 BmeshとはN-gonをサポートするモデリングシステムで、N-gonとは4つ以上の頂点を持つポリゴンのことだ。
  • ナイフ機能が強化された。「k」を押すとナイフモードに変わる。(今までは押下している時だけナイフモードになっていた。)頂点とエッジにスナップされるようになった。決定はスペースか、エンターで行う。
  • 頂点を2つ以上選択して「j」を押すと、面が分割されてエッジが引かれる。(「f」では面に重なる形でエッジが引かれるだけ)
  • Vertex Slide 「Ctrl + v」のVertex Menuから選択できる。もしくは「Shift + v」。カーソルでエッジを選択すると、頂点をエッジに沿って移動できる。
  • Insert Faces 「Ctrl + f」のFace Menuから選択できる。もしくは「w」のメニューからも。選択された面の厚みと高さを設定して押し出せる。「e」とは違い法線方向に押し出す。
  • 面を選択した上で「Shift + k」でナイフモードにした場合、選択面だけが切られる。通常のナイフモードでは視点から見て、表になっている面しか切れないが、このシフトのモードでは選択されていれば裏の面も切ることができる。
  • ナイフモードで「Ctrl」を押していると、エッジの中点にスナップされる。
  • Dissolve 隣り合った面を選択して、「x」メニューから選択できる。選択面が結合される。
  • Bevel 一時的な機能後退なのだろうか、よく聞き取れなかったが、複数の面を追加して滑らかにベベルすることはできないらしい。「Ctrl + f」のFace Menuから選択できる。
  • Bridge Two Edge Loop 同じ頂点数のエッジのループの間に面をはる。面と面の間でもいいが、選択面は削除されずに残る。「Ctrl + e」のEdge Menuから選択できる。
  • MeshLint アドオン。選択中のメッシュにどのような面があるか情報を得ることができる。プロパティ画面のmeshの欄に追加される。3角メッシュの数、N-gonの数、nonmanifold Elementsの数(一つのエッジに3つ以上の面が接続している場所)、Interior Faceの数(内側に入り込んで見えない面)、さらに6+-edge polesもカウントしてくれる(これは謎)。「Select Lint」ボタンを押すと問題のある面を選択する。 nonmanifold Elementsがあると、Subdivision Surfaceモディファイアで丸めた際に不適切な形状に丸められる。

2012年10月4日木曜日

Visual C++ インクルードディレクトリを相対パスで

 Visual C++ 2008では、追加のインクルードディレクトリを設定する方法には2通りある。
 1つは全てのプロジェクトに対して設定する方法で、「ツール→オプション」から「プロジェクト及びソリューション→VC++ディレクトリ」、そして右上のプルダウンメニューから「インクルード ファイル」を選択し、リストにパスを追加する。
 2つ目は個々のプロジェクトに対して設定する方法で、プロジェクト→(プロジェクト名)のプロパティ」から「構成プロパティ→C/C++→全般」にある「追加のインクルードディレクトリ」に設定するものだ。

 さて、ここからがメモなのだが、2つ目の「追加のインクルードディレクトリ」は相対パスが設定可能らしい。「.」で「VC++ Project」ファイルのあるディレクトリを指すので、そこからの相対パスを設定してやる。

 プロジェクトを複数台のPCに同期していたため、PCごとに絶対パスが異なるという状況にあり、今までは「VC++ディレクトリ」の方の設定でパスをはることで対応していた。しかし同名のヘッダが存在すると優先順位の高いもの(リストの昇順)が呼ばれてしまうため問題となる。開発中などで唯一性が保証できないヘッダにパスをはる際にはプロジェクトのプロパティで相対パスをはる方法が良さそうだ。

2012年9月27日木曜日

映画 コクリコ坂から

 何故か最初の映画論評がコクリコ坂である。ブログを初めてから「カウボーイ&エイリアン」と「猿の惑星 ジェネシス」も観ていたのだが。ともかく最初なのでちょっと前置きを。

 断っておくと、論評するような柄ではない。最近一番のお気に入りが「世界侵略 ロサンゼルス決戦」なのだから言わずもがなだ。
 方針としては、多少覚えておきたい映画、もしくは最初の感想を覚えておきたい映画について取り上げる。必要ならばネタバレも辞さない。画像は作法が分からないし、現状の閲覧数では不要だろう。
 多くの映画には原作があるが、当然こちらまでフォローはしない。あくまで映画、そして映画脚本に対する感想というスタンスで行くことにしよう。

 では「コクリコ坂から」について感想をまとめてしまう。最近のジブリ映画は、手放しに誉めた評判は聞かないという印象がある。したがって、結構身構えて見るわけだが、今回気になったのは2点。

 まず1点目から、舞台、背景の雰囲気が結構良かった。斜面に広がる住宅地から、曲がった坂道で港まで繋がっており、海岸線と平行する通りに商店が並んでいる。橙色の電灯を灯して賑わう商店街の雰囲気が良い。またそれとは対照的に、朝霧に霞む住宅地も涼やかで良い。
 確かに千と千尋などと比べると、いくらか絵が味気ないようだが、いい塩梅といったところなのではと感じた。

ここからネタバレ含む

 2点目、なにやら全てがハッピーエンドになっていないだろうか。主人公メルと風間は兄妹だと思ったら、兄妹ではなく、カルチェラタンの取り壊しは、これもまた土壇場でひっくり返る。
 せめてカルチェラタンは取り壊されて欲しかった。頑張ったけどどうにもなからなかった、というようなストーリーを一個踏まえておけば、兄妹じゃなくて良かったねと、共感することもできるのだ。ストーリーも引き締まるのではないだろうか、大団円から大団円へと、まさしく駆け足で移動するというのは如何なものだろう。

 タグボートから商船のタラップに乗り移るシーン、シータとパズーかよ、という描写だったが、少し重点を置いているのだろうか。たしかに普通の高校生だと考えれば結構なアクションシーンだ。こんな事までして聞きに行かなくてもいいよとちょっと迷っても良かったのではないか。もっとも、ハッピーエンドラッシュで気が大きくなっているメルの思考には、そんな逡巡が入り込む余地は無さそうである。

 まとまりが無いが、こんなところで。ジブリ作品であるので、これからテレビで幾度と無く見ることになるだろう。ゲド戦記は滅多に見ない気がするが。


2012年9月24日月曜日

Haskell GHC 導入メモ

 C++erはHaskellでコメントを書く、などと言われるHaskellだ。Real World Haskellのまえがきを読んだところ、面白そうだったので、ちょっと迷ったが買ってしまった。

 環境を整えるのは非常に簡単だったが、いつまでも覚えられるという事もない。後々別のPCに40秒でHaskellを入れたいという事もあるかもしれないので、導入メモを載せておこう。

 HaskellのコンパイラはGHCだ。念のため、もう一つあるということだけは記載しておく。..もう一つある。
 さて、執筆時の最新版は7.6.1だが、導入時は7.4.2であった。ちょっと違和感を覚えたので軽く調べたところ、7.6.1は一般用ではなく、一般ユーザーは11月にリリースされるHaskell Platformを待つようにとの記載があった。 Haskell Platformというものを初めて知ったが、ライブラリやツール等も付属した開発環境らしい、期待大である。
 勉強用には7.4.2を使えばよいのではないだろうか。ちなみにReal World Haskellでは6.8.2以上を対象としている。

 ダウンロードしたらwin版はインストーラーになっているので、後は勝手にやってくれる。場所はパスに日本語を含まないフォルダがいいだろう。
 これだけでGHCiを起動してHaskellをいじることが可能だ。

 Haskellのソースファイルは「.hs」ファイルだ。コメントとコードがひっくり返る「.lhs」ファイルもあるが、何時役立つのだろうか。このソースファイルを書くために、別途エディタが必要だ。

 GHCiの「:e」というコマンドで、エディタが立ち上がるのだが、デフォルトではシステムで設定されたエディタが呼び出される。特にいじっていなければメモ帳が開くだろう。システム設定を変えずにエディタを変更するには、GHCiが起動時に実行する設定ファイルで指定する必要がある。

 HOMEディレクトリと、GHCiの実行ファイルがあるディレクトリ上に存在する「.ghci」ファイルがコマンドとして実行されるが、デフォルトではこのようなファイルは用意されていないため、勝手に作ってやればいい。今回は実行ファイルのあるディレクトリに設定ファイルを置いた。例としては次のような配置である。

C:\ghc\ghc-7.4.2\bin\.ghci

 中身は次の通り。一行目で作業ディレクトリを変更している。「/」がCを指すので注意。そして2行目でエディタの設定を変更している。実行ファイルを指定してやればよい。またgvim.exeにはパスが通っているので、そのまま呼び出すことができており、パスはシステム環境変数に追加している。

:cd /ghc/work

:set editor gvim.exe

 さて、これで一応完了であるが、エディタを閉じなければGHCiが動かないという状態になっている。少々都合が悪いので、runvimを導入すると良いだろう。http://wlog.flatlib.jp/archive/1/2009-08/category/15から入手することができる。
 runvimを使うには、ダウンロード、解凍し、gvim.exeと同じフォルダに入れればよい。そしてrunvimを通してgvimを起動するには、設定ファイルを次のように書き換える。

:set editor /vim73_kaoriya_win32/runvim.exe -e/vim73_kaoriya_win32/gvim.exe

コマンドオプションとの兼ね合いで絶対パスで指定している。上記の例ではVim関連の実行ファイルは次のような位置にあることを、念のため記載する。

C:\vim73_kaoriya_win32

 以上で導入完了だ。GHCiとVimでHaskellがいじれる。

 元々香り屋Vimにはvimrun.exeという実行ファイルが含まれている。名前が似ていてややこしいのだが、vimrunの方は、ちょっといじってみたがrunvimのような動作はせず、本来の用途も不明だ。

2012年9月19日水曜日

Unity&C#ではインターフェースが使えない?

 次のような状況を考える。
  • Aという動作を行えるオブジェクトと、Bという動作を行えるオブジェクトがある 
  • 重複したオブジェクトもある。
  • Bの動作の可否に関わらず、Aの動作が可能なオブジェクトを1カ所に格納し、それらに適宜、動作を呼び出す
  • Bも同様に格納し動作を呼び出す
Unityではコンポーネントの型による検索機能があるので、AとBをコンポーネント(MonoBeheaviorを継承したclass)とすることで、こういった要求に応えることができる。重複する場合には両方をゲームオブジェクトにアタッチすることで、分かりやすい解決となる。

 しかし、両方の動作を行える性質を持ちながら、それぞれ派生した動作を定義したいという要求が発生した場合どうするのだろうか。
 恐らくUnityの作法としては、Aの派生クラス、Bの派生クラスを定義し、2つをアタッチするのが正解なのだが、これではスクリプトファイルが一気に2つ増えてしまう。また性質を統合しているという意味を明確に示すためにも、1つのスクリプトとしてまとめたい。

 ところが、C#では多重継承が使えない。これは厄介なダイヤモンド継承と、それを回避するための複雑な手順を省きたいという考えからなのだろう。実際上記の例をそのまま多重継承できてしまうと、MonoBehaviorをA、Bそれぞれから2つ継承することになってしまう。

 今回はこういった経緯で...
C#の仕様である、インターフェースを使用して多重継承を行う方法を模索してみた。

 さて、前提条件としてA、Bというコンポーネントが存在した。コードとしては次のようになる。

// script file : ComponentA ------------------------
public class ComponentA : MonoBehavior
{
        public void funcA()
        {
                // do something
        }
}

// script file : ComponentB ------------------------
public class ComponentB : MonoBehavior
{
        public void funcB()
        {
                // do something
        }
}

 C#では多重継承が使えないが、インターフェースは多重継承が可能だ。しかも、1つのクラスと、複数のインターフェースを継承したクラスを定義することが許されている。

 まずA、Bそれぞれに対応するインターフェースを用意する。これはファイルを分ける必要はないので、それぞれのファイルにでも書き足せばいいだろう。

// script file : ComponentA ------------------------
        :
        :
public interface InterfaceA
{
        public void callA();
}

// script file : ComponentB ------------------------
        :
        :
public interface InterfaceB
{
        public void callB();
}

 インターフェースに定義されたメソッド宣言は、テンプレートでいうインターフェースのようなもの(謎)で、これを継承したクラスは同型、同名のメソッドを定義する必要がある。

 そしてUnity&C#で多重継承を模擬したクラスは以下のようなものだ。

// script file : DeriveAB ---------------------------
public class DeriveAB : MonoBehavior, InterfaceA, InterfaceB
{
        ComponentA implA;
        ComponentB implB;

        public void callA()
        {
                implA.funcA();
        }

        public void callB()
        {
                implB.funcB();
        }

        void Start()
        {
                implA = new ComponentA();
                implB = new ComponentB();
        }
}

 果てしなく、ださい。かつ幾つか致命的なトレードオフがあることを説明しなければならない。
  • このようにComponentA、ComponentBの実体をスクリプト内で生成した場合、2つのコンポーネントはUnityの検索対象に入らない。検索したい場合、スタート関数内でgameObjectにコンポーネントとしてアタッチしてやる必要がある。
  • Unityエディタはインターフェース型をインスペクターに表示しない。従って手動で参照を設定することができない。
  • スクリプト内ではインターフェース型を扱うことができるが、検索して得られるComponentAはDeriveABの基底クラスというわけではなく、ただの実体。多態性が存在しない。したがって、DeriveABを検索し、インターフェース型に変換した参照をとらなえれば、派生した動作を行うことはできない。
絶望的である。だが、それぞれのインターフェースの生成時に、別途用意した静的クラスの配列などに参照を格納することはできる。あるオブジェクトの子供のコンポーネントを検索、といった事をするには、相応の前準備が必要となるが、全検索だけなら許容範囲内の手間だろう。

 無い物ねだりだが、Unityにインターフェース型の検索機能がつけば万々歳である。もしくは、せめてインスペクターで表示してくれれば、細かな関連性の設定に使えるのではないだろうか。

 そのようなことがなければ、セオリー通りおとなしく派生クラスを2つ作り、お互いの参照を持たせるのが得策であるようだ。

2012年9月9日日曜日

Unity 複数のレイヤーマスク

 Unityでは全てのオブジェクトに対して、必ず1つレイヤーが指定されている。Unityでゲームを作るなら必ず使用することになるレイヤーの用途は、カメラのカリングマスクとしての使用だ。
 カリングというと「間引く」といった意味なので、名称に混乱するかもしれないが、カリングマスクに指定することで、カメラはそのレイヤーのオブジェクトを描画するようになる。

 カメラのセッティングをいじったことがあれば気付かれたろうが、カリングマスクには複数のレイヤーを指定することが可能だ。そしてこのカリングマスクの情報は全て1つのint値に保存される。
 レイヤーは31個まで追加することができるが、これらも全てintであり、ビットシフトによって生成される。順に
1 << 0
1 << 1
    :
    :
1 << 31
という具合である。10進数でみれば複雑に混ざり合った値に見えるが、2進数では全て異なる桁に1が入った値であるため、これらの足しあわせは全て固有の値を取ることが分かる。したがってint値1つから、31のレイヤーのうち、選択されたレイヤー全てを割り出すことが可能なのだ。

 例えばカメラが映し出すレイヤーから、スクリプトによって動的にレイヤーを追加、除外するには、以下のようにすることができる。

void Start()
{
    // push No.8 Layer & pop No.9 Layer
    camera.cullingMask += 1 << 8 - 1 << 9;
}