Pa works very hard

URL:http://blog.pa-n.com/
RSS:http://blog.pa-n.com/feeds/posts/default
なかなか進みませんがゲーム作ってます。Blender, OpenGL, Bullet, iOS など。
[変更]
最終更新日2017/07/04 10:21:00

タグ

記事

1クリックで VALU の損益まとめが見れる Chrome拡張「VALUの売買損益をみるお」を作りました。

2017-09-09 11:48:00
これでなにができるの?💁 VALU ごとの損益まとめと通算損益を見ることができます。💁 約定済取引履歴を CSV で取得することができます。使ってみよう1. 「VALUの売買損益をみるお」のページに行って Chrome に追加します。2. VALU にログインします。3. VALU 内の適当なページを右クリックして「🔥売買損益表を出す」をクリック。 (出ない時はVALUページをリロードしてみてください。)4. 新しいタブが開かれ、取引履歴のダウンロードが始まります。5. 集計が表示されます。はいできた!NOTE約定済みの VALU 数量 × 価格をすべて合計したものを通算損益としています。VALU ごとの損益の降順にソートして表示するようになっています。作者のVALUの 1VA 保有者は全員分、それ以外の方は 5 人分の集計が見れます。あまり取引していない方は無料で使えるということで。正確な集計を心がけていますが、バグってるかもしれないので集計結果は参考程度にしていただければ。なんか動作がおかしい? と思ったら、kojingharang:馬場タク作者 までお知らせくださいませ。その際、詳しい方は、Chrome の右側のメニュー → その他のツール → デベロッパツール → コンソールを開いて javascript のログを送って頂けると調査がしやすいです。 開発よもやま話初めて Chrome 拡張を作りました。概念を理解するのに手こずりましたが、着手して12時間くらいでなんとか完成。平均取得単価を求めておいて売却ごとに損益を出すのも考えましたが、そもそも元データの約定日がなくて注文日しかないのでどうせ正確に出ないだろうということで断念。

iOSアプリ「自動立体削り器」をリリースしました。

2017-07-04 10:21:00
iOSアプリ「自動立体削り器」をリリースしました。どんなアプリ?立方体を 3 方向から文字の形に削っていく様子が見れるアプリです。どういうことかって??正面から見ると「う」、上からみると「ん」、横から見ると「こ」に見えるような不思議な立体が作れます。立方体からうんこを削り出してみた。#うんこ#立体 pic.twitter.com/Pz0sKaTrFm— 暇人ランド四段 (@kojingharang) 2017年7月3日どこがどうなっているんだ? オオォー〜 などと、不思議な立体をグリグリ動かして眺めてみたい方にオススメのアプリとなっております。削り出す文字は自由に決められます。いろんな文字を削り出して観察してみよう!ジャンル: 教育 / ライフスタイルスクリーンショットマンションポエムっぽいノリにしてみました。以上、よろしくお願いいたします。

2016活動まとめ

2017-01-01 02:20:00
2017 年になったということで、2016 年の個人としての活動 + 一言コメントをまとめてみました。1. 馬場タクシー3D作ってて一番おもしろいのがこれ。ゲームを作るゲーム超楽しい。【アプリ紹介】馬場タクシー3D: 人手が足りません! / BabaTaxi3D7.6 万ダウンロード (12/31)ほんとは 10 万ダウンロードを目標にしていましたが未達成。無料レーシングカテゴリ 1 位 (一瞬だけ)アスファルト8 や CSR Racing など並み居る強豪を抑えて一瞬だけ 1 位を獲得させていただきました✨年後半になって Twitter 広告の単価が上がってしまったのが残念。前半にもっと攻めるべきだった。2017 は上位に定住できるようになりたいもんです。デザインを一新 (4/22)すっきりさせました。てか、昔のデザインを見ると文字がデカイし画面を無駄に使ってて相当いけてない。3D ポリゴンを動的生成に切り替えた見た目ではわからないですが、アプリサイズの削減や表現力の向上に役立ってます。山手線上半分の全建物が 40MB 以内に収まっています。このあたりはアルゴリズムを考えたりするのがとても楽しかったです。(小並感)課金系を強化これで食べてるわけじゃないので完全無料でもべっ...べつに構わないんだから。なんですが、せっかくなので楽しんでもらって馬場コインも買って頂こうということでいろいろ工夫しました。広告も出しすぎたり減らしたりしながら調整しています。無料でも楽しめるが、課金してくれた方にはもっともっと楽しんでもらえるようなゲームにしていきたいっすね。実況機能を強化Lobi SDK から UIView も録画できる ReplayKit に乗り換え。これに伴って(?) ゲーム実況してくれる方がちらほら登場。まごいちさんのやつは特に面白かった。マックスむらいチャンネルで取り上げられる (6/2)最近おもしろいアプリを教えて!というコーナーでなんと 5 分間くらい紹介いただきました。「タクシー業務を通じて圧倒的成長」「これ絶対圧倒的成長言いたいだけや」のくだり、ウケた。レースモードで必ずクラッシュするバグを埋め込んでしまう【レースコース補修工事のお知らせ】コース老朽化に伴う補修により、馬場タクシー3.3ではレースがご利用頂けません。数日後に出る3.4にて工事が完了する予定です。ご安全に。 pic.twitter.com/9MKTuBeX4F— 馬場タクシー3D (@BabaTaxi3D) 2016年6月21日新 PV 公開 (11/13)PV 作るの結構楽しい。【5万DL突破】あなたはタクシードライバー。舞台は新宿。人手が足りなくて困っています助けてください!#BabaTaxi3D #iOS #Game #Racinghttps://t.co/nUlJbxxetX— 馬場タクシー3D (@BabaTaxi3D) 2016年11月13日こういう反応をみるとニヤけます。@BabaTaxi3D 久々に面白い広告みた— 永徳@イヴP (@mukuro_mokuro) 2016年12月2日Twitterの広告で唯一許せるのは」馬場タクシー」3Dだけ— つうつら 🐇の怪 (@rip_ura22) 2016年9月13日馬場タクシーの宣伝動画が見るたびに振り切れていってていいぞもっとやれ https://t.co/7LcsLaZME1— DJ DAIはにくじゃが教。 (@DJ_DAI) 2016年11月19日今の俺、ポケモン<馬場タクシーくだらないからこそ面白いww— ワンダフルりょじ (@persona_Fenrir) 2016年7月23日馬場タクシー!わたし東京の地理知らないんだから目的地にスムーズにお客運べないよ!— すぎもも(9) (@CNM_grr) 2016年5月3日馬場タクシー3D久々に面白い広告を見た— 赤城落狼@百合提督ドーラーお絵描きマン (@fall_law) 2016年4月22日2. 電飾カメラ リリース (1/12)【アプリ紹介】電飾カメラ / IllumiCameraこんな感じで使って楽しんでくれてるのを見るとほっこり嬉しくなります。とってもヤバイ可愛いアプリ見つけてしまった!!!電飾カメラっていう無料アプリ、、、夜景とか暗めのイラストでやるとチカチカして本当に可愛い、、、 pic.twitter.com/pKpXyZkcqL— 💉苛芥(かけ) (@kake_annoyed) 2016年12月6日3. ディスコマシン リリース (10/24)【アプリ紹介】ディスコマシン / DiscoMachine前々から作りたかったやつがやっと出せてよかった。セブ島のビーチで開発。(帰国後めっちゃ風邪ひいた)4. 熱々の料理 リリース (10/26)【アプリ紹介】熱々の料理: 例えるならコーヒーから湯気を出そうネタ枠。開発期間 2 時間。5. 旅してQ! リリース (11/4)【アプリ紹介】旅してQ!: スタジオと中継がつながっています 個人が簡単に動画やライブブロードキャストできる時代になってきたけど、放送主は比較的ネタに困っているんじゃないかという予想ドリブンでもって勢いで開発したやつ。6. 競技プログラミングこれは問題の本質を考えたりコードを書く前に見通しを立てたり短時間で素早く実装する訓練になるので普通に仕事や個人の開発に役立っています。でも 2016 はあまりやらなかったような。今年はもうちょっと出たいし黄色定住したい。7. コンサルなんでも相談にのります実際に、何件かコンサルさせていただきました。これまで培ってきた知見や技術を使ってクライアント様の問題解決をする、これはこれで楽しいですな。というわけで 2017 も楽しく活動していきたいと思っております。2017/1/1 バンコク某所のホテルより。

【アプリ紹介】馬場タクシー3D: 人手が足りません! / BabaTaxi3D

2016-11-12 20:00:00
今日は 2013/10/7 に公開した「馬場タクシー3D」の紹介です。こんなアプリ東京を舞台にお客さんを乗せて目的地まで爆走する、東京エリアとしては世界初のタクシードライビングシミュレーターです。結構本格的な 3D ゲーです。(個人の感想です。)ゲーム実況する方も出現。馬場タクシー草。 pic.twitter.com/Eue6DXKVwM— 😇エモQ☆彡😇 尾久公開行きまふ (@irY2L1Fx7hHnD7M) 2016年9月11日開発の経緯とこれからリアル東京を走れるドライビングシミュレータがやりたくなったので作りました。今後も引き続き、もっとリアルに、もっと面白くしていく予定です。定期的なチーム戦の充実化、Android 対応とかも。開発期間大学生のころプロトタイプを DirectX で作り始めてそのうち飽きて放置していましたが、iPhone が普及しだして「あぁこれはスマホで作るべきだ」とまた作り始めて、途中飽きて放置してまた作り始めてを繰り返して今も改良を続けているので期間としては結構な年数やっていて、なんというかもはやライフワークみたいになっています。人生何もしないには長いですが、巨大資本や人手が大量に必要なものはいまいち自分でコントロールした感がなく、そういう意味では自分にとって退屈しない手頃なサイズのプロジェクトだなぁと思っています。技術的な解説簡単に言うと、ODbL に基づいて無料で商用利用できる地図 OpenStreetMap のデータから動的に 3D ポリゴンを作って、Bullet で物理演算して OpenGL ES で描画しています。車やキャラクター、木などのモデルは Blender で作りました。山手線上半分にある建物をすべて収録してアプリ配布サイズを 100MB に収めるためにいろいろな部分にて独自技術を編み出して使っています。その他ノウハウとかアルゴリズムとか 1 記事にはとても入らないほどあるのでここでは省略。一部は以前書いた 馬場タクシー3Dと競技プログラミング にて紹介しています。以上、「馬場タクシー3D」の紹介でした。

【アプリ紹介】分身カメラ / CloneVideo

2016-11-11 19:13:00
今日は 2012/11/18 に公開した「分身カメラ」の紹介です。こんなアプリ動画の中の動いている人や物を分身させる、不思議な動画作成アプリです。公園で走り回る人http://t.co/aA8cI2raHI #CloneVideo— 分身カメラ (@CloneVideo) 2015年1月10日分身カメラ+Cinemagramのハイハイ動画、YouTubeにもアップしておいた http://t.co/QuCMCwIz— UT (@utdesign) 2012年12月1日@kojingharang 分身カメラ、面白すぎです! http://t.co/JXaiSMYd— たにおかすすむ (@sumutare) 2012年11月24日@CloneVideo You make a really great app!!!!http://t.co/yW2iY1poIL— Shawn L Callaway (@shawnlcallaway) 2015年6月30日みなさん面白い動画を作っているようで。開発の経緯とこれからあまりよく覚えていませんが、前景と背景が分離できればこんな分身動画が作れそうだなと思ったのがきっかけだった気がします。今後としては、リアルタイム生成あたりができたらもっといいかなと思います。作った当時は iPhone5 が最新でしたが、今はその頃と比べると性能もかなり良くなっているはずなので。今後もこういう「おやっ?」と思うようなひとクセあるアプリを作っていきたいところです。(感じ方には個人差があります。)開発期間開発日誌を書いてなかったころのやつなので不明ですが、ソースコードのタイムスタンプからすると 2012/10/13 あたりから作っていたような記録があります。レビュー待ちを 1 週間として、3 週間くらい?技術的な解説入力動画の最初のフレームを「背景」として、「背景」を作業のための N フレームにコピーします。次のフレームからは背景と差があるピクセル付近を「物体」とみなし、フレーム i の「物体」を i % N 番目の作業フレームに合成します。「物体」の検出については、単純な画素の差だけだと結構ノイズが出てしまうので、いろいろごにょごにょしています。入力をすべて処理し終わったら、作業フレームと BGM を AVAssetWriter を使ってファイルに書き出します。改めて振り返ってみると、かなりシンプルなアルゴリズムですね。以上、「分身カメラ」の紹介でした。

【アプリ紹介】97days

2016-11-10 20:57:00
今日は 2014/4/25 に公開した「97days」の紹介です。こんなアプリスマホに入っているたくさんの写真や動画を自動的にまとめて音楽付きのハイライト動画を作るアプリです。「あなたの 2016 年を 15 秒の動画にまとめる」「あなたの歴代クリスマスを 30 秒の動画にまとめる」「あなたの最近 1 ヶ月を 5 秒の動画にまとめる」といったことができちゃいます。撮影場所を大まかにまとめた地名や、撮影時刻に近い自分のツイートも字幕として映像に合成することができます。なので「そのとき何をしていたか」が分かって懐かしい気分に浸ることができます。開発の経緯とこれからスマホで写真をたくさん撮るけど、昔のやつってめったに見返さないよなぁ、なんか面白いことできないかな〜と考えてて、ハイライト動画を作ったら過去を思い出しておもしろいかも、と思いついたのがきっかけです。今 (iOS 10, 2016/9/13 以降) では iOS 標準アプリにも似たような自動生成機能が搭載されるようになってしまいましたが、これを作った当時はなかったので自分なりに欲しい感じのものを作ってみました。この手のはどうせデバイス側の容量不足で写真をどこかに移さざるを得ないので、スマホでやると比較的最近のハイライトしか出せないなぁ、バックアップ先の PC なりクラウド側でやらないとつらいよなぁと思いつつ作っていましたが、その後 Google Photos のアシスタント機能で写真バックアップからまとめ動画自動生成や昔の写真紹介ができるようになって、あーもうこれでいいや、充分便利だ、となりました。  〜完〜悔しいのでちょっとあがくと、撮影日時付近のツイートを動画に合成する機能は上記 2 サービスにはまだ入ってないようです。写真や動画に限らず、「そのとき何をしていたか」が分かる情報って後から見返すと結構楽しかったりするので、そのうち似たような機能が追加される、かもしれません。あと、スマホの容量がさらにでかくなるとそれに伴ってスマホ内で完結する人も増えるはずなので、そしたら需要も増える...かもしれません。開発期間開発日誌を書いてなかったころのやつなので不明ですが、ソースコードのタイムスタンプからすると 2014/3/25 あたりから作っていたような記録があります。レビュー待ちを 1 週間として、3 週間くらい?技術的な解説ユーザがスタートボタンを押すと、まず Social framework の SLRequest.performRequestWithHandler でツイートを取得します。並行して、ALAssetsLibrary.enumerateGroupsWithTypes と ALAssetsGroup.enumerateAssetsUsingBlock を使ってカメラロールから写真を全部リストアップします。そのうち日付条件にマッチするものだけ取り出して、指定した長さになるように使用する画像と動画をピックアップします。ピックアップの方法としては、過去のサマリーということで、対象となる日時範囲に対してなるべく均等に写真や動画を採用するようになっています。例えば「去年の写真や動画を10秒の動画にする」場合で、去年の 1 月に 100 枚, それ以降の月に 10 枚ずつ写真を撮った場合、1 月のものが他の月の 10 倍多く採用されるんではなく、なるべくどの月からも同じ枚数採用するようにする、という動作をします。ただし、そもそも写真が少なければ 1 月のやつが結果的に大量に採用されます。具体的には、日付条件にマッチする画像や動画すべてを前から見ていって、直前に採用したものの時刻から Interval 秒以上なら採用する、を繰り返して出来上がる動画の長さを求めるルーチンを Interval について二分探索して、動画が指定した長さになったときの配置を採用するというロジックになっています。ということで、時間でなるべく均一にサンプリングすることで、自分は平均的には何してたんだろうというのが分かる仕組みになっています。また、写真に含まれる GPS 情報を CLGeocoder.reverseGeocodeLocation で地名に変換して、K-means 法でクラスタリングして写真や動画を何個かのクラスタに分類しておきます。...なんというかオーバースペックな気もしますが、ある程度近いところで撮った写真はまとめて「石垣島」とか「港区」みたいなそれを代表するような名前を付けたかったものと思われます。あとは全部同じ国なら国情報は描画しないようになっていたりもします。ピックアップしたら、あとはいい感じにじわじわズームIN/OUTしながら出力映像に貼り付けて、ツイートや GPS 情報も合成していきます。動画と音声のフェードイン/アウトも加味して AVAssetWriter とかで出力します。結構込み入った動画生成処理を書いたので、今後何かに使いまわせるといいな〜と思います。例えば自分のツイートや任意のタイムラインをテンポよく次々と画像化して動画にする、とか?写真や動画はかなりプライベートな内容を含むだろうからハイライト動画も public には共有したくないだろうけど、公開ツイートであればハイライト動画も公開できるだろうから、ありかもしれません。作りたいアプリの TODO リストに追加ということで。このアプリを作った頃は一般ピーポーは Twitter に動画をアップロードできなかったはずで (2015年1月に Twitter Video リリース)、今ならもっと気軽にネタ動画作成→投稿できる環境にある気がします。以上、「97days」の紹介でした。

【アプリ紹介】1コマまんが

2016-11-09 19:58:00
今日は 2012/11/15 に公開した「1コマまんが」の紹介です。こんなアプリ吹き出しにテキストを入れるだけでちょっとした1コマまんがが瞬時に作れて、共有もできるアプリです。キャラクターやシチュエーションはいくつか用意されている中から選べます。吹き出しもキャラクターも自由に拡大縮小、移動できます。プロモーションビデオです。 pic.twitter.com/aIsrUlkyJz— 薄情なイヌとウマの1コマまんが (@1_koma_manga) 2016年11月9日若者の車離れ対策が#1コマまんが https://t.co/4JAauSMEAp pic.twitter.com/g0YeTyOqYN— 薄情なイヌとウマの1コマまんが (@1_koma_manga) 2016年9月20日黙れ小童ァァ‼️‼️‼️#真田丸#1コマまんが https://t.co/4JAauT4frX pic.twitter.com/tofl0oPNty— 薄情なイヌとウマの1コマまんが (@1_koma_manga) 2016年2月21日まだ東京で消耗してるの? #聞いてよ https://t.co/4JAauT4frX pic.twitter.com/rddrdfPo42— 薄情なイヌとウマの1コマまんが (@1_koma_manga) 2015年10月20日開発の経緯と今後ちょっとした出来事をまんがで気軽に表現したいなと思って作りました。Webサービスで作っていた時期もありましたがもうスマホだろうということで乗り換え。今後の発展としては、選べるイラストを増やすとか、流行ってるハッシュタグなど、あるテーマについてまんがが作れるようにするとかかなぁと思っています。開発期間開発日誌を書いてなかったころのやつなので不明ですが、ソースコードのタイムスタンプからすると 2012/10/18 あたりから作っていたような記録があります。レビュー待ちを 1 週間として、3 週間くらい?技術的な解説特別凝ったことはしてないです。UILabel や UIImageView を作ったり動かしたりして、共有するときには CGLayer.renderInContext で画像化して UIActivityViewController を呼び出します。ちなみに、アプリ名は「1コマまんが」ではありますが、2 コマ以上のまんがも作れます。なんというか、技術的にはなんでもない感じです。以上、「1コマまんが」の紹介でした。

【アプリ紹介】クロスわ〜ず

2016-11-08 23:05:00
今日は 2014/3/15 に公開した「クロスわ〜ず」の紹介です。こんなアプリ全 695 問のクロスワードです。制限時間はございませんので、すきま時間に、旅のお供に、どうぞごゆっくりお楽しみください。スクリーンショットです。 pic.twitter.com/lkao2VaY0D— クロスわ〜ず (@TheCrosswordApp) 2016年11月8日開発の経緯なんかこう、コンピュータっぽいことをして作ったなぁ、みたいなアプリを作りたいなぁと思ったのがきっかけです。コンピュータっぽいというのは、ここではアルゴリズムを 1 回書けば大量のデータに対してほぼノーコストでそれを適用できちゃう、というあたりです。おー、みたいな。あとは、世の中には暇な人が相当数存在しているだろう、というファンダメンタル予想。開発期間開発日誌を書かなかったっぽいので明確ではないですが、ソースコードのタイムスタンプを見ると 2014/3/1〜3/9 あたりに更新されているので 9 日間くらいと思われます。技術的な解説Wiktionary から単語の読みと説明を抽出して、それを元にちゃちゃっとクロスワードを生成してアプリに組み込んでいます。まずデータ取得部について。Wiktionary から全ページの最新版のダンプ(jawiktionary-YYYYMMDD-pages-meta-current.xml) を落としてきて、SAX で parse します。これがまた XML になっているようでなっていないので困ったものです。具体的には以下のような page 要素がだーっと並んで 250MB くらいのファイルになっています。どういうことかと言うと...text 要素がなかなかキてます。しかも単語ごとにいろんなバリエーションがあります。なので、心折れそうになりながらも、ひたすら泥臭く解析します。parser handler はこんな感じ(抜粋)。Ad hoc 楽しいめう!こうしてなんとか (単語の読み, ヒント)[] が揃います。これを pickle にしておきます。今やるなら JSON にするところです。そしたら今度はクロスワード生成部分です。まず (単語の読み, ヒント)[] をシャッフルして、適当な大きさの白紙の問題ボードを作っておきます。あとはひたすら、単語の置き方を全列挙してその中から 1 つランダムに選んで置いていきます。単語の置き方とは、単語を置いた時ボードからはみ出なくて、置こうとしているところに既に違う文字や同じ方向に置かれた単語に含まれる同じ文字が置かれていなくて、これまで 1 個も置かれていない、または置こうとしているところに既に今回置く方向と直行する方向に置かれた単語の一部である同じ文字が置かれていてるようなものが 1 個以上あって、置こうとしている単語の周りのマスが既に置かれた同じ文字の所以外すべて空白であるような置き方 (x, y, direction) のことです。意外とややこしいです...。単語が 6 つ以上置けたらクロスワードが 1 問できたことになるので、実際に使われている大きさにボードをリサイズして記録します。で、ボードを空にして次の問題作成に移ります。置き方がなくて詰んだ場合は使用単語を後ろにまわしてから再試行します。未使用単語の残りが少なくなってくると何回やっても詰むことがあるのでそういう単語は捨てます。よく覚えていないですが、695 問の生成に 30 秒くらいかかった気がします。この程度で終わるなら高速化は不要ですね。問題セットが出来上がったら problems.js に出力します。こんな感じ。ということで、コンピュータっぽいことをして作ったなぁという実感が湧いてきます。UI 部分については、ちとチープさが否めない感があります。これは今後の課題です。以上、「クロスわ〜ず」の紹介でした。

【アプリ紹介】ちょっと読書

2016-11-08 02:13:00
今日は 2014/11/06 に公開した「ちょっと読書」の紹介です。こんなアプリ160人の文豪が、自分達の小説計 400 作品以上を自ら断片的につぶやく、ツイッター風の読書アプリです。夏目漱石や森鴎外、宮沢賢治など有名どころは一通り揃っています(感じ方には個人差があります)。気に入った一節があったらSNSなどでシェアすることもできます。アプリのスクリーンショットです。#ちょっと読書 pic.twitter.com/EOHkTHp27f— ちょっと読書 (@greatWritersBot) 2016年11月7日小説の最後までつぶやいたらまた最初に戻ります。文豪たちは毎日不定期につぶやくので偶然面白いサムシングと出会えるかもよ、というわけです。作者のアイコンをタッチすると Wikipedia のページが開きます。作品一覧のページでは気になる作品をフォローすることができます。てかそれツイッターbotでいいんじゃね?という気持ちも僅かばかりありますが、一応ですね、ちょっと読書ならネットに繋がってなくても読めるしわざわざフォローしなくても最初から読めるし、...まあとにかく、作ってみたかったんですよ。開発の経緯とこれから隙間時間で受動的に読めて意外な発見がある読書アプリが欲しかったのがきっかけです。本を読み始める動機として、本屋をウロウロしてちょっと読んでみて良かったからとか友達からのおすすめとか書評ブログを見たとかいろいろあると思いますが、それ以外、例えば「なんとなく本文の一部が流れてきたけどなんか面白そう」みたいな仕組みが作れたら意外な本との素敵な出会いが待っているかもしれない、といったところです。データは、権利的に問題ないやつということで青空文庫の作品のうち著作権が切れているものを使うことにしました。で、作ってやってみた感想としては文脈を多少なりとも理解するには 140 字は足りないなというのと、あと古い文体の本が多くていまいち興味をそそられない、あたり。今後の展開としては、もうちょっと最近の本とか雑誌、ブログとかが流れてくるようにできたら面白いんじゃないかなあと思っています。例えば RSS フィードと組み合わせるとか、カクヨムで活動している作家さんの作品宣伝ツールの 1 つとしてちょっと読書に流してもらうとか。ランキングだけだといまいち未知との出会いがないし、かといって新着はすぐ流れていっちゃうから困るなあみたいな方がいて、なんかコラボできたら楽しいなあと思っています。開発期間2014/10/11(Sat)〜2014/10/15(Wed) の 5 日間データ取得/整形とそこそこ凝った画面ということで少し手こずりました。技術的な解説まずはデータ取得/整形です。python スクリプトを書きました。青空文庫のランキングデータを DL して parse し、そこから図書カードを DL して parse し、そして作者の wikipedia へのリンクやアイコンを取得し、なんと XHTML の本文を DL して頑張ってタイトルや作者名を抽出します。<meta name="DC.Title" content="坊っちゃん" />だったり<h1 class="title">詩集〈月に吠える〉全篇</h1>だったりまちまちなので、"BE ADHOC!" なる勇ましい掛け声が脳内をこだまします。さらに本文の読み仮名などのマークアップを消して、115字以内のきりがいいところでカットします。// 115文字で切る.// できるだけ句読点 (,.、。)で切るが, その結果50文字以下 or 116文字以上になってしまうようならやむなく115文字で切る.// 改行が6つ出現したらそこで切る.こんな感じのコメントが発掘されました。そしたらマクロ呼出し形式でデータを出力します。以下のような感じです。BEGIN_BOOK()AUTHOR("ツルゲーネフ")TITLE("はつ恋")WIKIPEDIA_BOOK_URL("")WIKIPEDIA_AUTHOR_URL("http://ja.wikipedia.org/wiki/%E7%A5%9E%E8%A5%BF%E6%B8%85")AUTHOR_IMAGE("author_photo_0006.png")PUBLISHER("青空文庫")BEGIN_CONTENTS(782)CONTENT("[#ページの左右中央]\n\n\nP・V・アンネンコフに捧げる\n\n")::これをこんな感じで include してデータ化します。#define BEGIN_BOOK() { Book* book = Book.alloc.init; book.ID = (int)_books.size();#define AUTHOR(s) book.authorName = @s;#define TITLE(s) book.name = @s;#define WIKIPEDIA_BOOK_URL(s) ss=@s; if(ss) book.wikipediaBookURL = [NSURL URLWithString:ss];#define WIKIPEDIA_AUTHOR_URL(s) ss=@s; if(ss) book.wikipediaAuthorURL = [NSURL URLWithString:ss];#define AUTHOR_IMAGE(s) book.authorIconURL = authorImage(@s);#define PUBLISHER(s)#define BEGIN_CONTENTS(n) book.contentsOffset = contentsOffset; book.contentsSize = n;#define CONTENT(s)#define END_CONTENTS() contentsOffset += book.contentsSize;#define END_BOOK() /*cout<<"ct.size "<<book.contentsSize<<endl;*/ _books.push_back(book); }#include "books.h"ただし本文までこの形式で初期化したらたしかコンパイルがやたら遅くて困ったので本文だけは const char* theContents[] にすべて格納するようになっています。そしたらデータが 150MB になってしまい大きすぎて困ったので、減らす仕組みも用意しました。データサイズは減らしたいけど収録する作品数は最大化したかったので、あるしきい値以下のサイズの作品だけ収録するようにして合計で指定したサイズ以下になるように二分探索してしきい値を決めるなどして、402 作品収録、データサイズ 21MB ほどに収めました。各作者によるつぶやきのタイミングは、ランダムに見せかけて実はすべて決まっています。とはいえ明らかにパターンが分かってしまってはおもしろくないので 1 日 86400 秒のうち何秒目につぶやくかというつぶやきパターンを何種類も用意しておいてうまいこと不定期に見せかけるということをしています。実のところ、フォロー集合さえ決まれば、ある時刻における最新のタイムラインはすべて求まるようになっています。とするといろいろ実装が楽なのです。あとはそれっぽい UI をいくつか作って繋ぎ合わせました。無限スクロールが意外と手こずった気がします。UIScrollView の表示領域に加えて画面の高さ 5 個分の範囲内のつぶやきについてだけ UIView を配置するようにして、範囲に入ったら作成、外れたら破棄する制御をしているわけですが、新たに表示すべきデータが現れたとき、一度に全部を addSubview すると数ミリ秒かかってスクロールがカクつくし、かといって UI に関することなので別スレッドでやるわけにもいかず、結局 0.1 秒間に 3 回までしか addSubview しないようにしてヌルヌルスクロールを実現しました。以上、「ちょっと読書」の紹介でした。

【アプリ紹介】電飾カメラ / IllumiCamera

2016-11-07 00:05:00
今日は 2016/01/12 に公開した「電飾カメラ」の紹介です。こんなアプリ夜景にネオンのような電飾を合成した動画を作るアプリです。アプリを起動するとカメラ映像の上にほぼリアルタイムで電飾が合成されます。シャッターを押すと、その時の風景に対して5秒分の動画が作られ、アルバムに保存されます。汐留シティセンターShiodome city center#汐留 #東京 #Tokyo #NightMade with #電飾カメラ #IllumiCamera #iOS #App #Camerahttps://t.co/QB1QexmdOt pic.twitter.com/UX5drmqN5c— 電飾カメラ (@IllumiCamera) 2017年5月8日pic.twitter.com/iKqlF3YCQb— ニャース@無人在来線爆弾 (@kojingharang) 2016年8月31日#日本橋 #東京 #Tokyo #Nihonbashi#電飾カメラ #IllumiCamera #iOS #App #Camera pic.twitter.com/boyLbRTb0F— 電飾カメラ (@IllumiCamera) 2017年5月8日アプリの紹介ビデオです。汐留パークシティの電飾写真のメイキングも。 pic.twitter.com/fsGgrt6ZcI— 電飾カメラ (@IllumiCamera) 2015年12月29日▼普通の景色を電飾でキラキラさせるカメラです▼5秒の動画が保存できます▼暗めの人工物を写すのがおすすめ▼ループビデオとしてVineに投稿しようアプリ説明にこんなこと書きましたが、Vine 終わっちゃいますね〜。開発の経緯詳しくはディスコマシンの紹介記事に書いた通りですが、前から作りたかったやつです(適当)。あ、思いだした、元はと言えば休暇で香港に行った時、Symphony of lights という高層ビル群が音楽に合わせてピカピカ光ったりレーザービームが出まくる派手なショーを見たのがきっかけです。ああいうのをアプリで再現できたら面白かろうということで作りました。ちなみに Symphony of lights は毎日 20 時からやっているので香港に行ったら是非見てみてください。ちなみに香港といえば、毎日正午に撃たれる大砲「午砲(Noonday Gun)」も外せません。これは元々 Jardine Matheson 社が銅鑼湾に入港した自社のエグゼクティブを歓迎するために祝砲を撃っていた所、1860 年に香港に赴任したてでその習慣を知らなかった英国海軍将官が一民間企業が祝砲を撃つなんぞケシカラン、罰として以後ずっと毎日正午に時砲を撃つべし、と命令して行われるようになったのが今でも残っているものだそうです。(1941〜1947の間は日本による占領のため中断)話を戻しまして、電飾カメラでは Symphony of lights のような音楽を鳴らすところまではできなかったですが、後に出した「ディスコマシン」ではアガる音楽が付いたりより派手になったり、リアルタイムに動画生成できるようになったりといろいろ改良されて今に至ります。開発期間開発日誌によると、2015/12/19(Sat) 15:58 に着手開始とあります。OpenCV on iOS が初めてだったのでやや手こずったものの、19:46 にはカメラ映像を輪郭データ Vector3[][] にしてダミーの点灯パターンで描画して映像と合成するところまで完成、21:00 には人間の感性を揺さぶる電飾点灯アルゴリズム「IlluminationEngine™」が完成したようです。翌日は起床〜 14:00 と 18:00 〜 21:30 で作業、21:40 にレビュー提出完了。その後スクショやビデオの準備。Apple レビューチームが 12/22〜12/29 と冬休みに入ったのと iPad で落ちるバグがあって再提出したので公開は年明けの 2016/1/12 になりました。ということで、メインの開発期間としては 2 日間、実質 13 時間くらいでしょうか。技術的な解説カメラ映像に対して OpenCV で輪郭検出をして、ノイズっぽい輪郭を除去した上で今回独自開発した人間の感性を揺さぶる電飾点灯アルゴリズム IlluminationEngine™ により点灯パターンを算出し、ほぼリアルタイムで OpenCV の API により輪郭を描画します。フレーム間で同じ輪郭に対して異なる色を出力してしまうと脈絡のないチカチカした映像になってしまうので、そうならないようにするなどわりかし考えることはいろいろありました。OpenGL を使うともっといろんな表現が高速に描画できるだろうなあと思いつつ、それは後でということで妥協しています。当時は ReplayKit が出たばかりでその存在を知らず、わざわざオフラインで動画生成しています。そうすると生成中のくるくるやプログレスバーとか中断ボタンとか完了後の共有ボタンとかいろいろ作る必要があって今から振り返ると結構面倒ですね。当時でもリアルタイムに動画出力することは理論上できたはずですが、輪郭検出から描画までの処理が結構重かったのでそこまで頑張る必要もなかろうということで軽やかにボツに決定。動画出力には AVAssetWriter などの API を使っています。結構面倒な API ですが、以前作った分身カメラで使ったルーチンをライブラリ化していたのでそれを使い回せました。分身カメラについてもそのうち紹介記事を書こうと思います。以上、「電飾カメラ」の紹介でした。

【アプリ紹介】よいしょカメラ - お世辞だって、いいじゃないか

2016-11-05 22:01:00
今日は 2015/12/20 に公開した「よいしょカメラ」の紹介です。こんなアプリ独自開発した DeepRandom™ 技術により年齢推定できちゃう賢いカメラアプリです。じゃなくてジョークアプリです。突然ですが、年齢推定機能つきジョークアプリ「よいしょカメラ」をリリースしました。今度の忘年会や接待の場にて、ぜひお楽しみください!よいしょカメラhttps://t.co/8UAnsNPG5Z(写真はCC-BY) pic.twitter.com/nphU4N67IC— よいしょカメラ (@YoishoCamera) 2015年12月20日他にも、左右スワイプすることでおちんぎんやヘソクリ、かわいさ、総資産、友達の数、留年回数を推定することができます。ともだち同士とかで使って頂けるとよいかと思われます。pic.twitter.com/r4TWNAwOOI— よいしょカメラ (@YoishoCamera) 2016年5月7日pic.twitter.com/d3jPCKqrdv— よいしょカメラ (@YoishoCamera) 2016年5月7日最後の 2 枚は今年の GW にベトナムのホイアンを訪れた時の写真です。開発の経緯オーシャンズ 13 にて、最高の人工知能セキュリティ「グレコ」に守られたカジノをオーシャンたちが攻略して客にたんまり儲けさせる場面で客の映像に儲け額を AR で重ね合わせて描画してたのが着想のきっかけです。8 年前なんですね。結構寝かせていたネタでしたが、開発開始からレビュー提出までの期間は 10 時間でした。このアプリもタイムアタック案件。開発日誌によると、2015/12/13(Sun) 14:43 ころカフェで開発開始、自宅で夕食(鍋)を挟んで翌日 0:44 提出完了となっています。ちょっとそこ、開発日誌とかつけてんのエモいとか言わないでください。技術的な解説カメラからリアルタイムに取得した映像に対して OpenCV の CIDetector.featuresInImage で顔認識をして、その位置に黄色い枠と DeepRandom™ エンジンにより算出された各種推定値を描画します。無駄にスマホの横画面(Landscape)モードに対応ようとしたため、スマホの向き 4 通りすべてについて顔検出における上方向 (CIDetectorImageOrientation) を正しく指定しないと顔認識できなかったり、AVCaptureVideoPreviewLayer に表示される画像と実際にデータとして取得できる画像のサイズが合わなかったりして苦労しました。結局時間がないので 4 通りそれぞれ場合分けしてパラメータを設定したりしていました。case UIDeviceOrientationLandscapeLeft: // なんか逆だと思うんだがこっちじゃないと認識しない exifOrientation = PHOTOS_EXIF_0ROW_LEFT_0COL_BOTTOM; break;こんなコードが残ってたりして、1 年前の心の葛藤を思い出さずにはいられません。シャッターが押されたらその時の UIImage を iOS アルバムに出力します。一応ガイドライン的なものを尊守すべく、シャッターを押したらわざわざシャッター音を鳴らしています。えらい。よくアプリ内で撮影した写真の一覧を見る画面が出たりしますが、そういうの面倒なのでアルバムアイコンを押したらアルバムアプリに飛ぶようにしました。ちょうど 2015/9/16 にリリースされた iOS9 から「前のアプリに戻る」ボタンが出るようになっていたのでこの仕様でOK。アルバムアプリに飛ぶには UIApplication.openURL で "photos-redirect:" を開けばよいです。簡単です。DeepRandom™ エンジンの開発には、中でも特に苦労させられませんでした。Random だけに。人間が使ってほっこりするようなアプリにしたいというコンセプトもあったので、ちょっと若めに推定するようにできています。以上、投げやりですが「よいしょカメラ」の紹介でした。

【アプリ紹介】旅してQ!: スタジオと中継がつながっています

2016-11-05 06:02:00
今日は 2016/11/4 に公開したセルフィビデオアプリ「旅してQ!: スタジオと中継がつながっています」の紹介です。こんなアプリあなたは旅のリポーター。スタジオのアナウンサーと中継でつながってスタンバイ中です。さて次のコーナーは世界各地からの旅行リポートをお届けする「旅してQ!」。いよいよ始まります。あなたの様子が全国放送され、左下にはスタジオのアナウンサーが PinP で小さく映っています。それではリポートをどうぞ!という設定で、テレビ中継っぽい自撮り動画を撮影する新しいスタイルのセルフィビデオアプリです。中継中は、画面下のアイコンを押すと拍手や歓声などテレビのバラエティーっぽい効果音を鳴らすことができます。自撮りで滑ったら効果音で流してしまいましょう。有料版なら、「がっかり」「えー?!」「爆笑」など、流せる効果音の種類が増えます。中継(撮影)が終わったら、SNSで旅行先にいることをアピールしてもいいし、友達や恋人や親に送ってもいいし、単に保存しておいてあとで見返してもOK。開発の経緯ディスコマシン、熱々の料理の構想中に、これ同じデータフローで自撮りも行けるんじゃね?と気付いたのがきっかけです。それに、今 YouTuber とか流行ってるし、その中で放送ネタに困ってる人もいるはずだとか、自撮りは恥ずかしくてできないという人でもアプリが質問してあげてテンプレを提供してあげれば自撮りの敷居も低くなるだろうというファンダメンタルもあり、作ってみました。...と書いてたら関連ネタを思いつきました。そのうち作ろうと思います。技術的な解説カメラ映像を表示する AVCaptureVideoPreviewLayer の上に、アナウンサーのおねえさん画像やテロップ、スタッフの指示を描画して、画面録画フレームワークの ReplayKit で動画に出力しています。AVAssetWriter みたいないかにも動画出力ガチ勢みたいな API は一切使わず、単に ReplayKit の RPScreenRecorder.startRecordingWithHandler とかを呼んでいるだけです。AVAssetWriter で出力するとそのままではどんな仕上がりになるのかわからんので、プレビューみたいな UI が欲しければ自分で作らないといけないわけですが、ReplayKit なら画面に出た内容がそのまま記録される (WYSIWYG) と分かっているのでユーザ体験としても分かりやすいし開発が簡単なのでいいことばかりです。2016 年に WYSIWYG という言葉を使うとは思わなかったです。ReplayKit だと記録したくないものがある場合や画面の一部だけ出力したいということは今の所出来ないですが、そのくらいならそのうち公式に対応してもおかしくないでしょう。そしたら正方形動画とかも作れるし、プラットホームとしてもできることの幅が広がって良いことばかりでありましょう。なんかもういろいろ応用が効いて簡単なので、馬場タクシー3D、ディスコマシン、熱々の料理、旅してQ! と最近はやたら ReplayKit ばかり使っています。アナウンサーの声は Mac の say コマンドで喋らせました。ちなみに。アナウンサーのおねえさんは馬場タクシー3Dに出てくるガチャのおねえさんと同一人物です。背景のアルファ化がめっちゃ甘くてすいません(笑)以上、旅してQ!の紹介でした。

【アプリ紹介】熱々の料理: 例えるならコーヒーから湯気を出そう

2016-11-04 00:43:00
今日は 2016/10/26 にリリースした 「熱々の料理: 例えるならコーヒーから湯気を出そう」 の紹介です。こんなアプリカメラ映像に映ったコーヒーなどの料理に対して湯気を合成することであったか〜い感じにする(だけの)アプリです。有料版では映像の保存ができます。サンプル動画。本日の珈琲になります。https://t.co/wZlcn2TSS3#熱々の料理#iOS#App pic.twitter.com/TYePrKfIvB— 熱々の料理 (@YumSteam) 2016年11月3日開発の経緯ディスコマシンでスモークを出す機能を作ってたら、これコーヒーから湯気を出すのに使えるんじゃね?と思ったのでスピンオフアプリとして作りました。とある日曜日、20時の NHK 大河ドラマ「真田丸」視聴までに作って帰るという目標でカフェにて 17:30 からタイムアタック作業開始。ん〜、後から考えると、そもそも作業開始が遅い気がしますね。ディスコマシンのソースをコピペして不要な機能を削ってスモークを中心から出すように変えたりして 19:00 には有料版/無料版共に機能完成、そこからアイコンとスクショを作って、iOS dev center で AppID とか登録してアプリ概要を書いて 2 種類リリースビルドして iTunesConnect で 19:33 審査提出、ぎりぎり 2 時間で間に合いました。ヘルプは UIWebView で外部サイトを表示しているだけなので審査待ちの間にゆっくり作成。高校生の時は センター試験英語に出てきたゲーム を 2 日で作ったりしていたので、昔からタイムアタックは好きだったようです。技術的な解説馬場タクシーやディスコマシンで使っている自作の煙描画ライブラリを使って、カメラ映像の上に画面中央からほのかに立ち昇る湯気を描画しています。コーヒーや料理をどうやって認識してるの?と友達に聞かれましたが、認識はしてなくて人間がコーヒーに合わせてスマホの位置や角度を調整するようになっています。コンピュータと人間の共同作業であります。ちなみに審査用にスクリーンショットを 2 枚、それを iPhone/iPad 用、日本語英語用、合わせて 4 種類ずつ合計 8 枚の画像を作ったわけですが、これまでにいくつもアプリを作っているのもあってその辺はかなり効率化されています。具体的には、日本語/英語 2 種類の SVG ファイルを Inkscape で作っておいてスクリプトで iPhone/iPad 用のサイズで分けて画像にエクスポートするような仕組みがすでにあり、それを使ったのでスクショ作成はそこまで面倒ではなかったです。むしろアップロードが面倒。アイコンを作るパイプラインも結構効率化されています。iOS の場合 20 29 58 87 40 80 120 60 120 180 76 152 512 167 57 114 50 100 72 144px など実に様々な大きさのアイコン画像を用意する必要がありますが、1 コだけマスターアイコンとして SVG ファイルを作っておいて、それを 1024x1024 画像にエクスポートしてから ImageMagick とスクリプトで各サイズに縮小したり、起動画面やホムペ(死語)用に角丸の部分が透明になるように自動加工したり、さらに生成したアイコン画像を xcode の Assets ファイルに自動コピーしたりする仕組みを過去に作ったので、それを使って面倒な作業がコマンド一発で終わるようになっています。ということで、技術的な解説というかアプリ作成効率化の話がほとんどでした。以上、熱々の料理: 例えるならコーヒーから湯気を出そう の紹介でした。

【アプリ紹介】ディスコマシン / DiscoMachine

2016-11-03 20:03:00
今年作りたかったものがだいたい開発し終わって落ち着いてきたので、作ったものについていろいろ書いていきたいと思います。まずは 2016/10/24 にリリースした ディスコマシン について。 こんなアプリディスコマシンは、スマホのカメラで写した夜景などの映像にディスコっぽいグラフィックといい感じの音楽を合成して楽しむアプリです。有料版では画面と音を録画して保存したり、SNS で共有できたりします。分野としては拡張現実(AR)あたりでしょう。例えば、夜の銀座4丁目交差点でアプリを起動するとこんな映像になります。 プロモ映像#DiscoMachine pic.twitter.com/iAm08pQYOo— DiscoMachine (@TheDiscoMachine) 2016年10月23日開発の経緯このアプリ、実は結構前からこういうの作りたいなぁと思っていました。その記録が 2014 のインタビュー記事 アプリ開発者に訊く! ~ 「馬場タクシー3D」 に残っています。 今後出すつもりのアプリは?という質問に対して「いつもの風景がズンチャカピカピカみたいなものを作る予定です。」と答えたやつ、あれがディスコマシンです。 作りたいなぁ作りたいなぁと思いつつも 馬場タクシー3D の方がもっと作りたかったので、しばらくはなかなかガッツリ時間を取って作れなかったわけですが、2016年秋に馬場タクがバージョン 4.5 になってようやくそこそこ満足する形に落ち着いてきたのでディスコマシンに着手し、休日のカフェや休暇で訪れたセブ島のビーチで 日の出タイムラプス動画 を撮影したりしながらガリガリ開発していました。発想のきっかけとしては、クラブでいい感じの音楽や演出を見ると楽しいけどスマホで AR にしたらもっと気軽にそういうのが体験できていいんじゃね?的な感じです。アプリによって時間制約と移動コストがなくせるよねみたいな感じで。 ただスマホの画面はとても小さいこともあって臨場感はまだまだですな。家のあらゆる壁がディスプレイになったり VR が安く普及したりすると、また違う体験になるかなーと思っています。ちなみに、いきなりディスコマシンを作ったわけではなくて、1年弱前の 2015 冬には 電飾カメラ という似たようなアプリを作っています。電飾カメラについてもそのうち記事を書こうかなと思っています。技術的な解説 技術的にはたいしたことないというか、すでにある技術を組み合わせた感じです。まずカメラ映像をリアルタイムに取得して、OpenCV で輪郭とコーナー検出をします。同時にアプリ組み込みの音楽やユーザの iTunes ライブラリから選んだ音楽をデコードして再生しつつ、raw data を DSP で FFT します。検出した輪郭情報 Vector3[][] とコーナー情報 Vector3[] と FFT データ float[] を、今回開発した人間の感性を揺さぶる DiscoEngine™ により解析し、OpenGL ES 2.0 を使っていい感じに輪郭やレーザー光線やピカピカ光ってる感じの画像やスモークを描画します。 ちなみに、電飾カメラでは撮った写真をキラキラデコって動画として出力することができますが、そのときは出たばかりの iOS ReplayKit framework の存在を知らなかったので 1 フレームごとに UIImage を生成して AVAssetWriter を使って動画を生成していました。 今回ディスコマシンでは画面に出たものがそのまま動画になる ReplayKit を使ったので、そのあたりを作らなくて済んだのでめっちゃ楽でした。 ReplayKit は生放送にも対応したようだし、アプリによっては独自でそのあたりを作り込まなくて済むのでいろいろ可能性があると思っています。ということで、ディスコマシンの紹介でした。

【アプリ紹介】馬場タクシー2をリリースしました

2015-10-14 10:36:00
ドライバーの皆さん、こんにちは!初代馬場タクシー3Dのリリースから早2年が経とうとしています。その間、1万DL突破、AppStoreレーシングカテゴリ7位獲得など、まぁまぁご好評頂いており、あざま〜す。そして今日、大きなバージョンアップがようやくリリースとなりました。グラフィックがきれいに、より面白くなった馬場タクシー2へようこそ。↓もうちょっと長いゲーム紹介動画↓▼主な変更点- ドライブ可能エリア拡大(山手線内上半分対応)- ミッションをクリアするとドライブ可能範囲が広がる「エリアレベル」システムを導入- 車の各種消耗をシミュレート- 画面デザイン、グラフィック、キャラクタアクション、表現の改善- 効果音、BGM を多数追加- バッジを多数追加- 「馬場コイン」を導入(消耗品の回復を早めることができます。毎日プレゼント。)- いくつかのバグ修正- がんばってアプリ配布サイズを 100MB 以下にしました- 今までの走行データは引き継がれます↓一応、宣伝ぽいもの↓▼世界初の東京エリア対応iOSドライビングシミュレータ▼1万DL突破!▼レーシングカテゴリ7位獲得▼たった1分。無性にドライブしたくなったらこのアプリ。▼ユーザの声「競争ではなく、自由に走れる車ゲームが欲しかった!」「ゴチャゴチャした道路とゆるい感じに好感が持てます」「こーゆーの待ってた!」▼こんな人にオススメ運転が好きな方タクシー業務を通じお客様を満足させ、圧倒的成長! したい方▼こんなゲームです山手線内上半分をドライブできますタクシー業務モード ... Twitterでフォローしている人が客として登場レースモード ... 早稲田グランプリ、裏馬場耐久レース、新宿三丁目チャレンジ、鶴巻カップ、新宿周遊カップ>> もっと詳しいゲーム紹介はこちらからどうぞ。 <<ではでは、Enjoy driving!

Happy 2015

2014-12-04 19:13:00
そろそろ年末ということで、拙作iOSアプリ「分身カメラ」でキラキラした動画を作ってみましたよ。  仕組みはどうなってるかというと、東京タワーを背にペンライトで空中に "2015" と描く様子を動画で撮影しておいて、 キラキラした部分を「分身カメラ」を使って分身させると冒頭の動画になる、という感じです。身の回りに適当なペンライトがなかったので、以前使っていた iPhone5 で http://pa-n.com/light/ を表示させてペンライトとしてみました。ちなみに、Safari でそのまま表示すると白いアドレスバーが動画に映り込んでしまいますが、「ホーム画面に追加」して出来たアイコンを起動すると全画面モードになりタイトルバーもナビゲーション部分も表示されなくなるのでGOODです。鏡文字を一定のペースでゆっくり描かないといけない所が結構難しく、何回か練習が必要でした。というわけで、キミもイルミネーションをバックにキラキラ動画を作ってみよう!三脚は必須だぞー!! (こっそりおまけ)Apple本社に行った時に撮影した、Infinite Loop 看板の周りをぐるぐる走る分身動画も載せておきます。手持ち撮影なのでうまく分身できていないです... 手ぶれ補正とか課題。

馬場タクシー3Dと競技プログラミング

2013-12-18 08:07:00
はじめにこれは Competitive Programming Advent Calendar Div2013 の 18 日目の記事です。今年も残り僅かとなりましたが、皆様いかがお過ごしでしょうか。今日は、@nodchip さんから始まった「拙作○○○(作品名)の中で競技プログラミングがどのように生かされているか」シリーズの続編として、「拙作iOSアプリ『馬場タクシー3D』の中で競技プログラミングがどのように生かされているか」を書いてみます。いつも寝不足になりながらコドフォをやってる人も、競技プログラミングって何の役に立つのん?って人も、ぜひ読んで頂けたら嬉しいです。馬場タクシー3Dとは?いきなり宣伝ですいませんが、これは趣味で作っているiOSアプリでして、東京でタクシー業務やレースを楽しめるドライビング・シミュレータです。「新宿や銀座でクレタクやグランツーリスモをやりたいなぁと思って作ったゲーム」と言った方がピンと来る方も多いかもしれません。プレイ動画にある通り、Twitterのフォロワーがお客さんとして乗ってくるのでタクシー業務に勤しみます。もたもたしてるとお客さんが怒り出すので頑張りましょう。おまけ機能としてお客さんの最新のツイートが画面に表示されるので、遊びながら友達の近況がゆるやかに伝わってきたりもします。タクシーの他にレースモードもありまして、いくつかの市街地コースでレースをすることができます。 カートを運転したことがある方はより分かってもらえるかもしれませんが、 作者は「次のコーナーをタイヤのグリップぎりぎりまで使ってスリップせずに曲がるにはどんなライン取りでいつフルブレーキすればいいのか?」「コーナーの前にある起伏でちょっと浮く時に荷重が減ってグリップも弱くなるのでちょっとスピードを落とさないと」「前を走ってる車はこういうライン取りをするだろうからこのタイミングでこっちに出るとぶつからずにジェントルに美しく抜けるかな」などと考えながらタイムアタックするのが大好きなんですね(笑)。 そのなんというか物理法則と世界の成り立ちとライバル車が何を考えているかをより正確に理解することが速いタイムにつながるみたいな仕組みが好きなんだと思います。 なので、このゲームでもそういう世界を再現すべく、アイテムを使うと爆速になるとかそういうのじゃなくてできるだけ物理法則に沿った動きになるように頑張っています。といっても実態はすべて物理エンジンの Bullet に丸投げしており、ちゃんとブレーキを踏んで十分に速度を落とさないとタイヤが滑ってまともに曲がれなくなるようになってるとかその程度ではありますが。で、市場の反応はというと、日本の AppStore の「iPad→ゲーム→レーシング→無料」カテゴリで最高 25 位になったほか、 海外ではカリブ海に浮かぶ人口 1.5 万人のアンギラ(Anguilla)という国のiPhone版同カテゴリでなぜか 10 位になるなど、 まずまずの出だしかもしれませんがもっともっと面白くして多くの方に楽しんで頂きたいと思っています。ちなみに、アンギラはスペイン語やフランス語で競プロ界に時おり出てくるウナギの意味で、島の形がウナギに似ていることから命名されたそうです。wikipediaによると。ゲームで使うマップデータは Open Database License という緩めのライセンスの元に使用できる OpenStreetMap の地図データを元にしています。 元データは XML になっているので、それを python スクリプトで読み込んでビルや街路樹などの 3D ポリゴンデータや道路グラフを自動生成して、それをアプリから使っています。馬場タクシー3D内で競技プログラミングが生かされている所というわけで早速競プロに関連する部分に行きます。まぁコードの大部分はいたって普通のコードなんですが、マップデータがそれなりに大きいので、マップに関連するところでは計算量を落とす工夫をしたり、ちょっとしたグラフのアルゴリズムを使ったりしています。今日はそんな処理 2 つをピックアップして紹介します。 道路グラフを検証する処理 道路グラフの行き止まりをなくす処理 競プロっぽい所その(1) - 道路グラフを検証する処理道路グラフとは何かと言うと、道の要所要所の座標や接続関係を表した有向グラフです。OSM(OpenStreetMap) データを元に作ります。 // 道路グラフ struct RoadGraph { vector<Vector3> 頂点配列 vector<vector<int> > 隣接リスト }いたって普通の隣接リスト表現です。で、山手線をまるごと含むエリアの道路グラフは頂点数 82,474、辺数 115,738 で、図にするとこんなんです。結構濃ゆいですね。いかにも TLE しそうな香りがします。実はこの道路グラフ、馬場タク内のいろんな所で使われています。例えば: AI車がそれっぽい動きをするように道路グラフ上をランダムウォークさせる タクシーモードのとき、プレイヤーの現在地から目的地までの最短経路を A* で計算して表示する ガードレール、街路樹、放置自転車、ビルの看板、ジャンプ台、客の初期位置、AI車の初期位置など、各種データを道路グラフを元に生成する などなど。さてこの道路グラフですが、何しろ手動で入力された OSM データを元にしているので、素性の良さを検証したいと思います。例えば、交差点は中央の頂点が図のように周囲の4頂点とつながっていることが期待されますが、次の図のように交差点が別々の頂点に分かれていると、例えば目的地までの経路を計算する時に「下から来て左折するルート」を導出できなかったりするかもしれません。というわけで、もし 2m 以内に点が複数ある場合はそこは交差点とみなして 1 頂点にまとめることにします。 まとめる処理は後でやるとして、ひとまず全ての頂点について「2m 以内に他の頂点があるかどうか」を計算したいですよね!さてそこで問題です。Problem (Div1 250)time limit: 2sLittle Petya は誕生日に平面上の点の集合をプレゼントされました。Petya は、すべての点について「2m 以内に他の点があるかどうか」を調べるゲームをしていましたが、途中で気持ちよくなって寝てしまいました。点の座標が与えられるので、あなたが Petya の代わりに最初から調べてください。Inputvector<pair<double, double> > points1≦points.size()≦100,000-10,000≦points[i].first (x座標)≦10,000-10,000≦points[i].second (y座標)≦10,000単位は m任意の半径 5m の円に含まれるの点の個数 ≦ 10Outputvector<bool> resultresult[i] ... points[i] の周囲 2m 以内に他の点(points[j], i≠j)があるかどうかresult.size() should be equals to points.size()Coding phase start3...2...1...おわり回答例では実際に採用した方法を紹介します。(いろんな方法があると思うので一例です)空間データ構造としては kd tree, BSP, BVH みたいなのとかいろいろあると思いますが、シンプルで書きやすそうな 2D bucket を使いました。// データ構造const double grid_size = 5; // 2m * 2 以上map<pair<int, int>, vector<pair<double, double> > > data;空間を正方形のセルに分割したと思って、点は「その点を含むセル」が持つリストに登録します。 具体的にはセルの左下の整数点 pair<int, int> をキーとして map に点リストを格納します。(右上が X+, Y+ とします)// grid_size==5 で// (2.5, 0.0), (5.1, 101.5), (4.0, 4.0) を登録したところdata = { (0, 0) -> [ (2.5, 0.0), (4.0, 4.0) ], (1, 20) -> [ (5.1, 101.5) ],}クエリは、点の座標から(セルの幅/2, セルの幅/2)を引いた地点のセルと、その右、上、右上の計4セルに含まれる全ての点に対して距離チェックをします。円がセルからはみ出るかもしれないので周辺のセルも見るというわけです。はみ出る対策は、面倒なら無条件に点の座標のセルの周囲 8 個を見るとかでもいいと思います。セルの 1 辺の長さが 4m 以上であれば、点から 2m 以内の領域は必ずこの4セルに含まれるので、それらをチェックすれば十分です。 また、点の密度に上限があるので、リストに点がたくさん入ってて結局全探索に近くなるといったこともありません。// クエリbool query(double x, double y) { const double within = 2.0; pair<int, int> base_key(floor(x/grid_size - 0.5), floor(y/grid_size - 0.5)); int dx[] = {0, 1, 0, 1}; int dy[] = {0, 0, 1, 1}; int count = 0; for(int i=0;i<4;i++) { pair<int, int> key(base_key.first+dx[i], base_key.second+dy[i]); if(!data.count(key)) continue; for(size_t j=0;j<data[key].size();j++) { double lx = x - data[key][j].first; double ly = y - data[key][j].second; if(lx*lx+ly*ly <= within * within) count++; } } return count > 1; // 自分の点はカウントしない}計算量は、点の数を N, 1セルに入るデータ数の平均を M とすると map を引くところが O(log(N/M)), リストを全部見るところが O(M) なのでクエリ全体は O(Mlog(N/M)), 点の密度の上限があるので M を小さな定数とすると O(logN), 実際は定数項が大事とはいえ、まぁいい感じだと思います。// データ構造の構築void build(const vector<pair<double, double> >& points) { data.clear(); for(size_t i=0;i<points.size();i++) { pair<int, int> key(floor(points[i].first/grid_size), floor(points[i].second/grid_size)); data[key].push_back(points[i]); }}// 本体void solve() { build(points); for(size_t i=0;i<points.size();i++) { result[i] = query(points[i].first, points[i].second); }}実際のマップデータの処理は python でやっています。さきほどの山手線を含むグラフの場合、総当りで O(N^2) だと終わらなかったのが 2D bucket を使うことで 2.8 秒で終わるようになりました。2D bucket は他にもこんな所で使っています。大活躍です。(マップデータ生成時) ガードレールの生成アルゴリズム: 道路グラフの辺それぞれについて辺を太くしたような長方形を作って、それらの union の輪郭をポリゴン化するとガードレールの出来上がりです。union を計算するために Clipper を使っています。 (マップデータ生成時) ジャンプ台を大きな道路のガードレール沿いに設置する処理アルゴリズム: 細い道のも含むすべてのガードレール沿いに 20m 間隔で候補点を生成して、その後大きな道路上を 50m 間隔で見ていって 20m 以内に候補点があればそこにジャンプ台を設置します。 (マップデータ生成時) 繁華街のビルの角に看板を設置する処理。看板がよく見えるように道に一番近いビルの角に取り付けます。ジャンプ台と看板 アルゴリズム: すべての道上に 10m 間隔で点を設置して、あるビルに含まれるすべての頂点に対して5m以内の点を探す→一番道上の点に近いビルの角に看板を設置します。 (アプリ実行時) AI車の前方に車がいるかどうか判定する処理アルゴリズム: AI車は基本的に道路グラフ上をランダムウォークしますが、自車の前方 2m, 4m, 6m, 15m の地点から半径 3m 以内に車がいる場合はブレーキを踏みます。車の位置を適宜更新しつつ、2D bucket のクエリで判定します。 (アプリ実行時) プレイヤーとの距離が 30m〜100m の歩道上に客を配置して待機させる処理アルゴリズム: 歩道沿いの候補点をたくさん生成しておいて、プレイヤー近くの候補点を探して客を配置します。プレイヤーに近すぎるといきなり現れたように見えるので 30m 以上遠くの候補点だけ選びます。 (アプリ実行時) プレイヤーとの距離が 100m〜200m の道路上に AI 車を配置する処理マップ全体を数千台の車が走っているとすると物理シミュレーションが終わらないので、プレイヤーから 200m くらいの範囲内で車を最大 75 台走らせるようにしています。遠くなった車は GC で回収され、何事もなかったかのようにプレイヤーの近くに配置されます。アルゴリズム: 道路沿いの候補点をたくさん生成しておいて、プレイヤーからの距離が 100m〜200m の候補点を探して車を配置します。これも近すぎるといきなり現れたように見えるので 100m 以上遠くの点だけを選びます。 (アプリ実行時) プレイヤーに最も近い場所(駅, 信号機, 店とか)の名前を表示する処理 2D bucket のいいところは、単純でスケールアウトしやすい所だと思います。局所的で場所ごとに独立なデータ構造になってるので、将来もっと広いエリアをサポートする時にマップデータを分割したら 2D bucket のデータ構造もそのまま分割できますし、プレイヤーの移動に合わせてサーバから新たなタイルデータをダウンロードするとか、そもそもマップデータの生成を並列実行するとかも自然にできそうです。競プロっぽい所その(2) - 道路グラフの行き止まりをなくす処理長いので飽きてきましたが、もうちょいやります。。プレイヤーが動ける範囲はガードレールの内側(道路側)に限られています。 そのガードレールは前述の通り道路グラフの輪郭なので、 道路グラフ上で行き止まりがあるとそこに入ったプレイヤーも行き止まりになってしまいます。 しばらく一本道を行ったら実は行き止まりで戻るしかない、という状況はつまんないのでなくしたいですね!そこで、道路グラフ上で行き止まりに通ずる一本道の道路を消すという前処理をしておきます。 普通は道路の行き止まりってあんまりないものですが、マップデータの端の方とかはどうしても行き止まりになってしまうんで、やります。というわけで問題です。Problem (Div2 475)time limit: 20sFox Ciel は森で見つけた無向グラフをたどるゲームを始めるところです。Ciel は行き止まりが嫌いなので、行き止まりにくると泣いてしまいます。Ciel を泣かせないように、与えられたグラフから最低限の頂点と辺を取り除いて、行き止まりを含まないグラフを作ってください。|V|≦80,000|E|≦120,000行き止まりの数≦1000Coding phase start3...2...1...おわり回答例(面倒なので擬似コード)これはアルゴリズム的な工夫というよりは実装問題かなと思います。グラフと仲良くなろうみたいな。行き止まりを見つけたら、そこから戻って1本道である間消すフラグを立てていくみたいな感じです。# alive[v] な頂点だけからなるグラフは行き止まりを含まないalive ← [True for i in range(len(g))]# alive なサブグラフ上で次数 1 の頂点がないように alive[i] を False にしていくchanged ← Truewhile changed: changed ← False for v in すべての頂点番号: while alive[v] かつ v から出る辺のうち、向こう側が live な頂点の個数が 1 なら: alive[v] ← False changed ← True v ← その向こう側の頂点# alive[v] の頂点だけからなるグラフを構築old_new_map ← [-1 for i in range(頂点数)]new_v ← []new_e ← []for v in すべての頂点: if alive[v]: old_new_map[new_v.length] = v new_v.append(v) new_e.append([]) for v2 in v から出るすべての頂点: if old_new_map[v2] != -1: # 新頂点に入れるべきなので辺を追加する。 new_e[-1].append(old_new_map[v2])O(|V|+|E|) くらいだと思います。実際には道路グラフでの行き止まりはそんなに多くないし、サクサク軽快に動いています。ほか詳細は省きますが、アルゴリズムっぽい部分は他にこんなものがありました。 目的: ガードレールや白線を複雑な凹凸のある地表にぴったり配置するアルゴリズム: 白線を表す線分をグリッド(直線 X=500N, 直線 Y=500N)との交点で分割する→グリッドの各地点での高さにセット目的: 現在地から目的地までの最短経路を表示するアルゴリズム: 2D 距離をヒューリスティックとする A* 探索目的: Draw call を抑えるために、複数のビルや看板のテクスチャを1つにまとめるアルゴリズム: 長方形を大きな正方形の中に効率よく敷き詰める(マラソンぽいですね)→その座標を元に Imagemagick で画像合成まとめ長々書きましたがいかがでしたでしょうか。おれならこうするとか、質問とか、ここ間違ってるとか気づいたら遠慮なくお知らせください。自分としては、ふつうのアプリにしては結構アルゴリズムっぽいことをしてるな〜という印象ですね。作ってても楽しかったです。というわけで競技プログラミングの先にこんな応用例もありますよという記事でした。明日 12/19 は @tatuyan_edsonさん, @akenshoさんです。お楽しみに!

Xcode でシェーダーをコンパイルさせないようにする

2011-10-02 20:25:00
シェーダーがコンパイルされてしまうOpenGL ES のプログラマブルシェーダーはアプリ実行時にコンパイルされるものなので、アプリビルドの際は何もせずにファイルとしてパッケージングしたいわけですが、Xcode 4.0.2 で拡張子が .vsh や .fsh のシェーダーファイルを追加してアプリをビルドするとシェーダーまでコンパイルされてしまい、シェーダーの独自構文が Objective C コンパイラで通らなくてビルドエラーになったりします。Xcode 4.0.2 でシェーダーをコンパイルしないようにする方法左側ペインのProject navigatorでプロジェクトを選択右側ペインの左側部分でTARGETSを選択右側ペインの右側部分で Build Phases タブを選択Compile Sources を開くとシェーダーファイルが表示されるので、ドラッグ&ドロップでCopy Bundle Resources のところに移動スクリーンショット

Blender 2.5 をコマンドラインツールとして使う

2011-09-23 13:00:00
Blender をコマンドラインツールとして使う以下のようにすると Blender をコマンドラインから起動して指定した Python スクリプトを実行することができます。 $ blender --background --python test.py--background オプションを付けると Blender の UI を出さないモードで起動します。 コマンドラインツールとして大量のレンダリングを実行したり、モデルを自動生成するのに使えます。blender コマンドにはパスを通すなどしてシェルから実行できるようにしておく必要があります。当方では以下のように alias を設定しています。alias blender='/Applications/blender-2.59-OSX_10.5_i386/blender.app/Contents/MacOS/blender'視点をスクリプトから設定したいで、当方ではモデルを自動生成するのに使っているんですが、その blend ファイルを開いて確認する際、毎回決まった視点で表示したいと思ったので調べました。以下のようなスクリプトで設定できます。(ついでにテクスチャ付きで描画するようにしてあります) # -*- coding: utf-8 -*-import bpyfrom mathutils import Quaternionfor a in bpy.context.window.screen.areas: for s in a.spaces: if s.type == "VIEW_3D": # テクスチャ付きで描画する設定 s.viewport_shade = "TEXTURED" # ビューの設定 s.region_3d.view_rotation = Quaternion((1,0,0),-1.57) s.region_3d.view_distance = 5# 保存bpy.ops.wm.save_as_mainfile(filepath="sample.blend", relative_remap=True)Quaternion を使ってビューを設定します。Blender の座標系は右手系なので、Quaternion((1,0,0), -1.57) は「X軸の方向を向いて反時計回りに-90度の回転」を表します。何も回転しないと「X 軸が右、Y 軸が上、 Z 軸が手前」のビューになるので、上記の回転を施すと「X 軸が右、Y 軸が手前、Z 軸が下」になります。スクリーンショット生成された sample.blend を開いたところです。確かに X 軸が右、Y 軸が手前、Z 軸が下になっています。

Bullet - strange collision of TriangleMesh

2011-02-13 22:24:00
しばらくブログを更新しない間に SIO2 が v1.4 -> v2.0 になったりしているようです。今日は Bullet の不具合?回避のネタです。TriangleMesh の道路だと引っくり返るSIO2 ゲームエンジンは物理エンジンとして Bullet を使っています。で、Vehicle を TriangleMesh 製の道路上で走らせてみたところ、Triangle の境界で急に車体がひっくり返ってしまい、ゲームにならない!ということがあって困っていました。で、調べたところ、こんなスレがありました。http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?p=&f=9&t=3052そこに載っている NotifyOnCollision 関数を定義して、gContactAddedCallback = NotifyOnCollision;を初期化時に実行するようにしたところ、解決。gContactAddedCallback というのは bullet で定義されているシンボルで、以下の extern 宣言をすれば参照できます。extern ContactAddedCallback gContactAddedCallback;

Blender - シーンの自動生成(5) 横断歩道を作るの巻き

2010-05-20 08:25:00
前回は壁とガードレールを新設、コーナーを丸く、単位をメートルとするあたりをやりました。今回は、横断歩道を作ります。さらに、横断歩道の部分はガードレールを作らないようにします。出来上がりの図テクスチャを作ってないので分かりづらいですが、テクスチャを貼るために横断歩道の部分だけ独立したポリゴンになっているのが分かるかと思います。ガードレールの途切れ具合もこんな感じかと。ガードレール生成部分「作る予定だったガードレールポリゴンのうち横断歩道の部分だけを消す」ということをするために、Python の区間演算ライブラリであるInterval moduleを使いました。これを使うと区間集合 list of (float, float) 同士の差分が計算できるので、ガードレール区間 - 横断歩道区間を計算してポリゴンを作るということをしています。横断歩道生成部分今度は「作る予定だった路面ポリゴンのうち、横断歩道部分に頂点を追加する」ということをしたいのですが、interval module だと連続した区間は1つにまとめられてしまうので、区間の和をとる感じではできませんでした。路面と横断歩道の頂点集合をソートしつつマージ。TODOなんといってもテクスチャですね。これがないと地味すぎます。なんすかこれ、業務用ポリゴンですかみたいな。テクスチャを作って、UV座標をセットして貼り付けるみたいなことをする予定です。

Blender - シーンの自動生成(4)

2010-04-21 23:22:00
ゲーム開発の方、しばらく放置してしまいましたが、道路メッシュができないと進まない!ということで久しぶりに進めることにしました。前回は、踊り場の形をちゃんとしたり、坂を滑らかにしたりする所までやりました。成功イメージ今回はこんなです。壁を作る壁がないとすぐに車が落ちてしまうので、あった方がいいだろうということで作りました。長い道路の両側すべてに作りこんだ店を配置するわけにもいかないので、ほとんどの部分はテクスチャでハリボテを作ってそれっぽく見せる、という用途にも使えます。ちなみに、せっかく作った convex hull コードですが、要らないというかうまくいかない場合があると分かったので外しました。素直に「道路部分の延長」と「踊り場」のそれぞれについてポリゴンを作ったらうまくいきました。重複頂点が出るので、Blender の "Remove Doubles" 機能を最後に呼んでいます。ガードレールを作る今までは床と壁が1個ずつでしたが、壁を1個増やして小さくしてガードレールとしました。原理はたいしたことないですが、今まで1個だったローカル変数とかを2つにするのが面倒。四角いコーナーをまあるくする前回ので少し走らせてみたところ、コーナーが丸くないと曲がるときすぐ壁にぶつかってイライラすることが分かったので、角を取ってみました。コードの変更は少ないですが、なんかもうぐちゃぐちゃになりつつあって、さらに横断歩道の部分はガードレールなしにしたいとか思ったらどこを変えればいいんだろうって感じになってます。む~ん。単位をあわせる単位をメートルとする。...とても地味ですが重要なポイントです。車の大きさ、道路の幅、ガードレールの高さ、建物の高さ等単位を揃えておかないと、なんかサイズ感が違ったオブジェクトが集まってどれを調整したらいいかわかんなくなってしまいます。スクリーンショットでは、道路の幅は 8m, 歩道の幅は 3m, ガードレールの高さは 1.2m という設定になっています。おまけ壁とガードレールを取り付けた時点でのスクリーンショットが残っていたので貼りつけておきます。次回triangle mesh の上で車(raycast vehicle)を走らせると、ポリゴンの継ぎ目で車にとんでもない力がかかって横転してしまう、という大きな問題があったので、Bullet 界隈のフォーラムを調べて解決した、という話を書こうかと思います。オフラインでは進んでたりするんですが、記事化するのが面倒で書いてないネタもいくつかあったりします。

SIO2でサウンドを鳴らす(2)

2010-02-05 01:08:00
前回は、iPhone/iPad 向けゲームエンジンである SIO2 で音を出す方法を調べました。今回は、Tutorial06 をベースに作っているオレオレゲームに、実際に BGM を追加するところまでやってみます。動いている様子いまのところこんな感じで動いています。Blender でサウンドファイルを指定前回調べた通り、適当なマテリアルの3番目のテクスチャに ogg ファイルを指定して、適当なオブジェクトにそのマテリアルを設定します。これで sio2_exporter.py を実行して .sio2 ファイルにエクスポートします。ソースコードの変更tutorial09 のサウンド関連っぽい行をそのままコピペしてくれば良いです。初期化したあと、sio2 ファイルに含まれるサウンドを取り出したり登録したりする便利関数を呼びます。//// Add to createFramebuffer (file EAGLView.mm) sio2InitAL();//// Add to templateLoading (file template.mm) // Bind all unique sound buffer (.ogg) currently in // the resource manager with to its appropriate material. sio2ResourceBindAllSoundBuffers( sio2->_SIO2resource ); // Also generate the sound source buffer ID. sio2ResourceGenId( sio2->_SIO2resource ); // Bind all the sound source to their respective // sound buffer. sio2ResourceBindAllSounds( sio2->_SIO2resource ); // Set the volume for the ambient (music) sound source. sio2->_SIO2window->volume = 0.65f; // Set the volume for the FX sound source. sio2->_SIO2window->fx_volume = 0.85f; // Affect the ambient volume to all ambient sound. sio2ResourceSetAmbientVolume( sio2->_SIO2resource, sio2->_SIO2window ); // Affect FX sound volume to all the FX sound. sio2ResourceSetFxVolume( sio2->_SIO2resource, sio2->_SIO2window );Xcode のデバッガについて当初、(sio2InitAL の呼び忘れで)クラッシュしていたのでデバッガで調べていましたが、変数の値とかいろいろ調べる UI が良かったです。マウスでポイントしていくだけで構造を辿れるのが便利。なんでも GUI でやろうとしないで、中断状態のまま CUI の gdb に移れるのもポイント高いと思いました。

SIO2でサウンドを鳴らす

2010-02-03 23:40:00
SIO2 を使った iPhone/iPad アプリでサウンドを再生する方法を調べました。これといったドキュメントはないみたいですが、tutorial09, SIO2 source, SIO2 exporter を読んだ感じでは、以下のようになっているようです。内部で OpenAL を使っている。Ogg 形式のサウンドファイルが再生できる。Blender にて Material と ogg ファイルを関連付ける。具体的には、Material の 3 番目の texture に ogg ファイルを指定する。(ちなみに、1 番目は Diffuse, 2 番目は Shadowmap として使われるらしい。)sio2_exporter.py が .sio2 ファイルに ogg ファイルを入れてくれる。sio2ResourceBindAllSounds() を呼ぶと、Object に ogg ファイルが関連付けられる。1 つの sound につき 1 つの SIO2sound インスタンス。SIO2sound の属性として、AUTOPLAY, LOOP, AMBIENT, FX, STREAM がある。AUTOPLAY は起動時に自動的に再生。Blender texture の MipMap 属性でセットされる。LOOP はループ再生。Blender texture の Repeat 属性でセットされる。FX はドップラー効果とか距離に応じた減衰の効果。Blender texture の Interpol 属性でセットされる。AMBIENT はそういう効果なし。STREAM はストリーム再生。ネットとかからダウンロードしつつ再生できる。Blender texture の UseAlpha 属性でセットされる。AUTOPLAY, LOOP, AMBIENT にすると BGM になる。FX にして sio2SoundPlay を呼ぶと、単発のサウンドが再生される。まだ自分のプロジェクトでやってみたわけじゃないですが、これで音が出せそうな気がします。exporter と独自パラメータSIO2sound の属性のような独自のパラメータは Blender UI に項目がないので、AUTOPLAY: MipMap, LOOP: Repeat のようになんとかして対応付ける必要があります。自分も以前そういうことをやったことがあって、Blender から Collada export したファイルの Spe.R が photon の最大検索半径、Spe.G が云々... という感じで苦労しながら無理やり対応付けていました。SIO2 でも同じことをしているのを見ると共感を覚えます。LOOP: Repeat なんかは意味が通じるのでとても良いマッピングだと思います:)

shortest path

2010-01-13 01:28:00
人材獲得作戦・4 試験問題ほかに出てる問題、pythonで書いてみました。1時間ちょいかかりました。30分とか速いな....