2016/10/26

ThreadLocal と Closeable を利用した一時変数のプール管理

Java で 3D Graphics Engine を実装するに辺り、算術演算の過程で避けられない一時変数の取り扱いに悩んでいました。

例えば、Matrix と Vector3 クラスを作り、位置とターゲット地点と up ベクトルから姿勢行列を生成する createLookAt メソッドの実装を考えます。
この処理の過程では X/Y/Z 軸の算出が不可欠であり、通常は軸を Vector3 インスタンスで表現したいと考えます。しかし、メソッド内部に閉じた一時変数であるため、GC 負荷の軽減を考慮すると単純な new による Vector3 生成は避けるべきです。

で、どうすりゃいいの?って話です。

jMonkeyEngine (JME) のコードを見ると、そのような一時変数用に TempVars クラスを定義し、そのインスタンスを TheadLocal 変数として管理しているようです。

コレだ!と。

ただまぁ、JME では、ありとあらゆる一時変数を TempVars クラスで一括定義している事に違和感があるため、自分のコードでは純粋に 1 つのクラスのインスタンスのみを管理する MatrixPool や Vector3Pool クラスを定義して利用することにしました。要するに、必要のないクラス間の依存を避けたいってことです。コード量は増えますが、僕は不要な依存を避ける方が重要だと思っています。

後は、Java 7 より try-with-resources 構文が使えるため、プールへのインスタンスの返却を簡素化するために、プールするクラスに Closeable を implements し、close メソッドでプールへ返却する仕組みとしました。
インスタンスのプール管理では、インスタンスのプールへの返却忘れというミスが十分に考えられます。このミスを減らすために try-with-resources を利用するわけです。
まぁ、可読性も向上しているんじゃないなかな・・・と、僕は感じます。

2016/10/16

Far Cry4 クリア

今更感ですが、Far Cry4 をクリアしました。Easy モード。

やっぱ拠点攻略は楽しいですね~。
敵の位置、警報機の位置を確認し、ステルスでそれらを撃破・・・凄く楽しいです。
肉を投げて野生生物に敵を殺らせるのも楽しい。

Far Cry3 と比べるとストレスなくやれましたね。
糞 QTE を廃止してくれてありがとう!
この調子でゲーム業界から QTE が撲滅されることを僕は祈ります。

まぁ、シナリオが相変わらず糞でしたねぇ・・・。
良いと思わない、悪いと思わない、どうでも良い、そんな感じでした。
シナリオが糞なゲームはシーンもスキップできない仕様、それは世の理でしょう。

次は Far Cry Primal ですかね。

また 3D エンジンを自作するかもしれない

Project Tango のバグと Rajawali のバグのコンボで参ったので、ちょっと Rajawali を捨てて 3D エンジンを自作しようかなぁと思い始めています。

自分達で作るアプリは自分達で最後まで面倒を見ることになりますからね。
その観点では、Rajawali の利用には無理があんなーと。
自作した方が健全やなーと。

2016/09/30

STEINS;GATE 0 やってました

STEINS;GATE 0 (ゼロ) の全ルートを一気にクリアしました。
って言うか、STEINS;GATE (初代) の続編が出ている事に全く気付いていませんでした。

ストアで見付けて速攻 DL して始めましたが、やっぱ面白いですねぇ。
初代やアニメ版を楽しめた人なら、ゼロも楽しめるんじゃないのかなーと。

まぁ、僕は、初代の頃から一番好きなキャラが「橋田至 (ダル)」で、相変わらず HENTAI を交えながらも、要所でイケメンなダルを見れて嬉しかったです。ダルを見たくてプレイしたと行っても過言ではありません。

でも、初代をプレイしたのが数年前という事もあり、既に初代シナリオの記憶は朧げで、世界線やアトラクタ フィールドの概念も忘れていたため、「これ何だっけ・・・」と悩んだので、クリア後には初代の真ルートを再プレイしました。

ゼロって、初代で β 世界線に戻ってからシュタインズ ゲートに入るまでの過程には、実は大変な苦労が隠されていて、それがゼロで語られている、って解釈で良いんですよね?
初代の初見プレイ時には、あまりにトントン拍子であることに違和感があったので、ゼロで補完されたのだとすると納得します。あの時のまゆりのビンタも、その性格やタイミングを考えると変でしたし。

悪い所を挙げると、初代と比べてゼロは理解に悩む演出でした。

初代では、過去改変の内容が明確に語られています。
一方、ゼロでは、過去改変を行う人が未来の存在であり、それが誰であるかは語られず、そこに至る未来も語られず、過去改変の内容も語られない。
それを想像や推測で補うのは流石に難しいですよ・・・。
ゲーム プレイ中に、いちいち事象をメモって関係性を把握するなんて事はしませんし。

で、凄く気になったので、ネットで考察を検索してなんとなく理解した、って感じです。
それでも、仮説を理解するしかなく、真相が分からんのですけどね。

まぁ、そんな事を気にするってのも遊び方の 1 つで、悪くないです。

2016/09/29

Rajawali はオススメできない

しばらく Rajawali で実装してみましたが、これはオススメできないですねぇ・・・。

ひとえに低品質。

リポジトリに付随する example の範囲ならば概ね問題は無いのですが、その枠を超えて利用するとバグだらけ。
UV 座標が明らかに誤っている、行列クラスのメソッドが起こす副作用を無視して演算している、深度バッファの制御を必要とする所で抜けている・・・などなど。
そもそも、まともに動かない example もあり、自分でバグを見つけて修正して動かしてみたりしてます。
実際に利用すると明白であるはずの誤りがそのままってのは、テスト無しで master に入れている開発者が混じっているってことですよね。
要するに、プロジェクトを制御できていないんじゃねーかなぁ、と。

てなわけで、最近は自身のデバッグよりも、Rajawali のデバッグをしている感じでキツイ。
Fork して修正して報告して・・・とも考えましたが、クラス設計そのものに誤りがあると感じる所もあり、なんかそういうレベルじゃないんじゃねーかなぁと。

ですが、まだ Rajawali で行こうかと思っています。
動く物を作る事を優先しているので、とりあえず・・・って所で。
今の所は、Rajawali のクラスを丸ごと破棄して自作したり、回避コードで何とか出来ていますが、その枠を越えたら考えます。

代替を求めており、それを探してもみましたが、他はライブラリというよりも Unity のような統合環境化されたものであるか、あるいは、より単純な OpenGL ラッパーであり、丁度良い粒度のライブラリを見つけられません。

今は Rajawali のデバッグみたいな時間が多いですが、それを続けるうちに OpenGL への知識を僕が獲得できるという利点があるので、かなりイライラしながらも、このままやってみるのも悪くないと思っています。

2016/08/27

仕事がなかなか進まない

仕事では、かれこれ数ヶ月 Project Tango を用いたアプリの実装を行っていますが、なかなか前に進まないですね。

他の調査と実装も平行していることが大きな原因の 1 つですが、Tango を用いた開発についての情報が少ないことや (公式ドキュメントも説明が足りない)、Android での 3D グラフィックス実装に対する経験のなさから難儀しています。

Unity から Java への移行


始めは Unity で開発を進めていましたが、途中から Java での開発へ移行しました。
このまま Java で進めようかなと。

3D の経験は僕自身が趣味レベルですし、まして会社はその分野に何一つ関係していないため、OpenGL を直接使うよりも Unity をベースにした方が適切だろうと始めは考えたのですが、最終的にはやりたい事が Unity にマッチしないという判断をしました。

今はツール的な意味合いの強い AR アプリを目指している所で、Android の標準 API で提供される UI との統合がどうしても欲しくなります。
また、クラウド サービスを前提にしており、多様なデータのリアルタイムな送受信や同期なども必要です。

Java ならば Android 標準 API で簡単に出せる UI があるのに、Unity 上で同等の UI を自作するのはナンセンスですし、僕らはクロスプラットフォーム開発を必要としていないため、Unity のプラグインを作ることもナンセンスです。
また、Unity では通信関連ライブラリが充実しておらず、これにも自作やプラグインの問題がまとわりつきます。

どのようなツールもライブラリにも想定する利用方法が必ず存在し、その想定にマッチする場合は恩恵を得られ、さもなくば足枷になります。
そして、僕らのやりたい事は Unity の想定から外れているため、他の方法を選択すべきということです。

でまぁ・・・それはそれでキツイなぁ、と。

Rajawali の利用


Android の OpenGL API を直接使うのもキツイので、今は Tango の公式サンプルで利用されている Rajawali という 3D ライブラリを利用しています。

Rajawali/Rajawali | GitHub

Rajawali は、Android OpenGL API のラッパー群を用意し、更にシーンを作るためのフレームワークや各種 3D モデルのロード機能などを備えている感じです。

Rajawali のソースコードを見ていると、Android での 3D 実装未経験の僕にとって勉強になりますね。

Java には構造体がなく、プリミティブ型以外の全てがオブジェクトとなるため、GC 効率に対する考慮が随所に見られます。
Vector3 や Matrix4 では、あえてメソッド元オブジェクトの状態変更で new を避けられるようにし、オブジェクトを new したい状況のためには専用の静的メソッドが提供されていたり、clone メソッドが用意されていたりします。
あるいは、演算中に発生する短命オブジェクトを避けるために、クラス内部でキャッシュを設けて上手く処理している部分が多く見受けられます。

でもなぁ・・・と。
ラッパーを使うと、どうしてもラッパー オブジェクトの new が発生するんですよね。
Tango から得られるベクトル配列や行列配列に対してラッパー オブジェクトの new が発生しますし、ラッパー メソッド内部では Android OpenGL API からの戻りで得られる配列に対するラッパー オブジェクトの new が発生します。

まぁ、あまり拘り過ぎると物が出来なくなるので、まずはこれでやってみようという感じです。

 

2016/02/16

Project Tango いじり開始

仕事で Project Tango 開発用タブレットを購入しました。日本では買えなかったので輸入です。
Project Tango - Google
一応、今年の夏頃には 3D センサ搭載 Android が発売されるそうです。

まだ、公式サイトを見ながら開発環境を整えたり、サンプル アプリを Google Play から DL していじたり、チュートリアルに従って少しだけ開発してみたりしている段階です。

ひとまずは Unity 版チュートリアルに従って試していますが、お世辞にもチュートリアルとは呼べない内容なので、Unity を単体で学ぶ必要と、サンプル コードから直接理解する必要があると感じてます。
過去には、そこそこ 3D グラフィックス関連の知識を得ているので、そこそこ気軽に Unity を理解できるのが救いです。でも、Script を C# で書いて、Android でどうデバッグするのかなど、開発での基礎的な部分が理解できていません。

Unity をいじるとなると、Tango とは関係しないテーマをひとまずは立てたいですね。その方が効率よく学べると思うので。過去に遊んでたプログラムを Unity でやってみる・・・とか。

libgdx いじり

Google が提供している Java 版の Tango Examples は Rajawali をベースにしているため、自分が仕事で開発する Tango アプリも Rajawali ベースとしていましたが、最近は libGDX への移行を進めています。一応、要点については移行が...