inosyanのブログ

プログラム、家庭菜園、僕が興味を持ったことを書いていきます

「cubiio」でのレーザー工作に使用するイラストレーター用の拡張スクリプト「G-CODE Generator」

先日Kickstarterで「cubiio」というレーザーを発するガジェットを手に入れました。これはレーザーで木や紙や革などを切断したり模様をつけたり加工する道具です。レーザーで物を切る様子はなかなかかっこいいです。小型なのも購入の理由です。大きいと邪魔になりますからね。

f:id:inosyan:20180529004641p:plain

f:id:inosyan:20180529004658j:plain

ですが、実際使ってみると、いろんな細かいことに気づきました。それらを解決するために、私は「G-CODEジェネレーター」を作りました。

G-CODE Generator
ソースコード

課題

G-CODEをイラストレーターから書き出したい

cubiioが扱えるファイルは、ビットマップとG-CODEの2種類があります。 ビットマップは写真などのピクセルのデータを焼き付けるのに使います。フォトショップなどビットマップが扱えるアプリであれば作れるので手軽で良いですが、レーザーの出方がインクジェットプリンターと同じように、横方向にドットを描くように照射されるので、切断には向きません。切断にはG-CODEのほうが向いています。

G-CODEは機械加工で使うデータで、レーザーのON/OFF、移動、回転などのコマンドを文字列で表したものです。cubiioのサイトには、G-CODEを書き出すアプリとして、Inkscapeが紹介されていました。

How to Generate G-code Files?

普段はイラストレーターを使うので、Inkscapeの操作にはなれていませんが、イラストレーターからデータを持ってくることは可能です。はじめはその方法でやろうと思いましたが、原因不明のエラーがおきてG-CODEを書き出すことができなくなってしまいました。エラーの原因を探ろうかと思いましたが、そうしませんでした。そもそもイラストレーターから直接書き出せたほうが良いので、イラストレーター用のプラグインのようなものは無いか探してみました。ですが思っていたようなものは見つからなかったので、自分で作ってみることにしました。

照射範囲を広げたい

以前ペーパークラフトをやっていたことがあったのですが、カッターで切り抜くのが面倒なので、レーザーで切り抜くのに期待していました。ところが実際に使ってみると、10x10cmの範囲しか照射できないことがわかりました。レーザーはまっすぐに飛ぶものなので、対象物から距離をおけばいくらでも広い範囲を照射できるものだと思っていたのですが、cubiioのレーザーには焦点距離があるようです。虫眼鏡で光を集めるのに、光が一点に集まる距離が決まっているのと同じように、cubiioは15.5cmの距離に固定されているので、照射範囲も最大10x10cmです。これではペーパークラフトには狭いです。

ペーパークラフトには少なくともA4サイズの加工ができる必要があります。cubiioか紙のいずれかを動かして複数回にわけて照射すれば理論上は可能ですが、それには、正確に照射することが大事で、例えば5x5cmの正方形を照射したら、その形で正確に切り抜けるということです。ですが、照射する角度や距離をあわせるのは何度も照射と調整を繰り返さなければならないので大変そうです。そこをなんとかしたいと思いました。

解決方法

イラストレーターの拡張スクリプトを作成

イラストレーターには、スクリプトで様々な操作を自動化することができる「拡張スクリプト」という仕組みが用意されています。G-CODEの書き出しをするためにそれを使うことにしました。記述にはJavascriptを使うことができます。ですが、ES3時代の古い書式しか使えないので注意が必要です。

G-CODEの仕様を把握

スクリプトを書く前に、G-CODEについての仕様を把握する必要がありました。いろんなデバイスに対応するため様々なコマンドがありますが全部使うわけではありません。Cubiioのホームページに書いてあったコマンドは以下のとおりでした。

2. Vector graphics (G-code)

G-Code Reference :
G0 - TRAVEL XY
G1 - LINEAR XY
G2 - CW_ARC XYIJ
G3 - CCW_ARC XYIJ
G20 - UNIT_INCH
G21 - UNIT_MM (default)
G90 - ABSOLUTE (default)
G91 - INCREMENTAL
M03 - LASER ON
M05 - LASER OFF
F - SPEED 0-600 (mm/min)
S - POWER 0-255

ですが、実際にやってみると、G4 (待機)がないとうまく動きませんでしたので、上記以外にもそれを使っています。

ベジェ曲線をコマンドに変換

イラストレーターの図形はベジェ曲線で表現されています。ですが、G-CODEにはベジェ曲線はありません。あるのは

  • 2点をつなぐ直線
  • 2点を通る円(中心点、時計回りかどうかを指定)

の2つです。直線は問題ないのですが、曲線を円に変換するのは大変でした。ベジェ曲線を細かく分割して、直線と半円に変換しました。

f:id:inosyan:20180529004717j:plain

IllustratorからG-CODEデータを作れるようになったので、これからいろいろ工作してみます。

f:id:inosyan:20180529004729j:plain

ウルティマオンラインの画像解析ツール「Ultima Online image analysis tool」公開

先日の記事「ウルティマオンライン月額課金無料化した記念にjsで画像解析ツールを作成」で紹介したツールを改良したものを公開しました。

f:id:inosyan:20180428151746p:plain

「Ultima Online image analysis tool」

画面上部に説明文があります。 f:id:inosyan:20180428151813j:plain

このアプリはオンラインゲーム「ウルティマ オンライン」のツールです。

まず、プレイ中にゲーム画面のスクリーンショットを撮ります。
画像ファイルを下の領域にドラッグ&ドロップして画像を解析し、ステータス、スキル、ペーパードール画像を見ることができます。

ウルティマ オンラインのクライアントアプリには、「クラシック クライアント」と「エンハンスド クライアント」の2つのバージョンがありますが、このアプリは「クラシック クライアント」専用です。

スクリーンショットには、1つのペーパードールウィンドウ、ステータスウィンドウ、およびスキルウィンドウが含まれている必要があります。

・スキルウィンドウの各スキルを展開する必要があります。グループ名は不要なので、最初のスキルを上にスクロールアップする必要があります。

・ペーパードールには、ペーパードールウィンドウの上部に星印が含まれている必要があります。

・画像に複数のペーパードールが含まれている場合は、最初に見つかったものだけが表示されます。

・分析後、結果の表の下に「Copy Columns(カラムのコピー)」と「Copy Values(値のコピー)」ボタンが表示されます。タップして結果をクリップボードにコピーし、スプレッドシートに貼り付けることができます。

下にスクロールすると、カバンの中に

Drop Screenshot Here!
OR
Tap To Select a File

と書かれています。ここにスクリーンショットをドラッグするか、タップしてファイルを選択します。

f:id:inosyan:20180428151856j:plain

デモ用にサンプルのゲーム画面のスクリーンショットを用意しました。「Show sample image」ボタンで見ることが出来ます。

f:id:inosyan:20180428151926j:plain

その隣のボタン「Perform demo」を押すと、サンプル画像を使って実行した結果を見ることが出来ます。

f:id:inosyan:20180428151944j:plain

分析結果の表の下に、「Copy Columns(カラムのコピー)」と「Copy Values(値のコピー)」ボタンが表示されますが、これは、スプレッドシートに結果を記録するためのものです。 ボタンを押すと、クリップボードにデータがコピーされます。

コピーされるデータはタブ区切りの文字列です。テキストエディタに貼り付けるとこのように見えます。 f:id:inosyan:20180428152021p:plain

スプレッドシートに貼り付けるとカラムがセルに入ります。
f:id:inosyan:20180428152035p:plain

「Copy Values(値のコピー)」の結果をカラムの下に貼り付けていけば、カラムのセルの下にそれぞれの値が入ります。 f:id:inosyan:20180428152050p:plain

スプレッドシートに貼り付けたあとは、デザインを整えたり、目標値と比較するのも良いでしょう。 f:id:inosyan:20180428152107p:plain

プログラムの説明

プログラムについて少し説明します。 前回の記事の時点から、ペーパードールの画像分析を強化しました。

前回の時点では、ペーパードールの周りの黒い部分を除いた部分を切り抜くところま出来ていました。しかし、エッジ部分にジャギーが出ていました。
f:id:inosyan:20180428152135p:plain f:id:inosyan:20180428152208p:plain

ジャギーの原因はエッジ部分に半透明のピクセルが無いことです。なので、アンチエイリアシングの処理を行うことにしました。そのためにはエッジを半透明にすれば良いのですが、小さな画像ではすべてのエッジをすべて半透明にしてしまうとぼやけた画像になってしまいます。なので、出っ張っているピクセルだけ半透明にしてみました。
出っ張っているピクセルとは

  • 上と左が透明
  • 上と右が透明
  • 下と左が透明
  • 下と右が透明

のいずれかの場合のピクセルです。

f:id:inosyan:20180428152252p:plain f:id:inosyan:20180428152303p:plain

良くなりました。しかし、まだジャギー感があります。なので、出っ張っているピクセルの隣のピクセルも弱めの半透明にしました。ただし、赤で印を付けた箇所のように窪んでいるところは避けないと、その部分がえぐれたような結果になってしまいます。

f:id:inosyan:20180428152316p:plain f:id:inosyan:20180428152328p:plain

だいぶ良くなりました。大きな画像ではもっと入念な処理が必要ですが、これくらいの大きさの画像ではこの程度のアンチエイリアシング処理で十分です。

しかし、他のキャラクターの画像を解析した時に困ったことがおきました。このキャラクターはローブを着ているのですが、右下が変です。
f:id:inosyan:20180428152401p:plain

もとの画像はこちらです。キャラクターの画像だけ抜き出したいので余分なものを除去しているのですが、カバンの後ろに衣装が隠れていたため、カバンの形にくり抜かれています。
f:id:inosyan:20180428152419j:plain

これを解決するに、まず、このペーパードールがローブを着ているのかどうかを調べます。
マッチング用の画像を用意し、アンチエイリアシング処理をする前の状態の画像を比較します。アルファで抜かれている箇所が一致すればローブを着ていることになります。
f:id:inosyan:20180428152437p:plain

次に、抜けている穴を埋めるのですが、単純に塗りつぶすわけにはいかないので画像を使います。その画像はフォトショップで埋められている状態を想像しながら描きました。ローブの色は赤以外にもたくさんあります。すべての色に対応するためにグレースケールの画像を用意し、穴埋め処理の際にローブの色にあうように調整します。
f:id:inosyan:20180428152449p:plain

グレー画像から描画するピクセルの色を求めるのは、次の式です。

ピクセルの色 = その位置のグレー画像の色 / 基準となるグレーの色 * 対象画像から採取した色

はじめ、赤いローブをもとにグレー画像を作ったのですが、その画像だと暗すぎて、ピンク色のローブの時には合いませんでした。
グレーにも明るさやコントラストによって結果が変わってきます。なるべく平均的な明るさで作るほうが良さそうです。
どの色にもあうようにするためには、適切な明るさとコントラストのグレー画像と、基準となるグレーの色を調整する必要があります。
今回はトライアンドエラーで調整し、赤とピンクのローブではうまくいくことを確認しましたが、もしかしたらこれらを調整するうまい方法があるのかもしれません。

f:id:inosyan:20180428152511p:plain

ツールのjavascriptは小さく軽量化の必要はないため、改行や空白はそのまま残っています。ご興味のある方は御覧ください。
javascriptソース

ウルティマオンライン月額課金無料化した記念にjsで画像解析ツールを作成

UO (ウルティマオンライン) との再会

f:id:inosyan:20180418014232j:plain

ウルティマオンライン無料化の記事を読んだ時には「おお!」と心の中で叫びました。そして、しばらくしたら、Mythic Entertainmentからメールが届き、「これはやるしかない!」と思いました。

This mail contains important information on changes to your Ultima Online account.

All Ultima Online accounts that have been closed for more than 120 days can be used to access Endless Journey. The Endless Journey account allows play (with some restrictions) for free without an end date. In addition, all accounts now have access to the Stygian Abyss expansion. More information on the new Endless Journey account type and on the Stygian Abyss expansion can be found here.

UO Team

若い人たちはきっとこのゲームを知らないと思います。名前は聞いたことがあったとしてもプレイしたことがある人は少ないでしょう。私が初めてプレイしたMMORPG(Massively multiplayer online role-playing game = 規模多人数同時参加型オンラインRPG)がこのゲームでした。今から18年ほど前の話です。

そのころはだいぶ流行ってきてたころで、雑誌か何かで知って、MMORPGとはどんなものか体験するためにはじめました。特に知り合いがいるわけでもなかったし、ネットでのコミュニケーションは苦手だったので、いつも一人でプレイしていました。はじめのうちは、ヘイブンという初心者の島からはじまりチュートリアルをこなした後に、どの場所にいくのかを選択する場面になりました。どこに行っていいのかさっぱりわからずにいると、操作を間違ったのか勝手にそうなったのかわからないけど、サーペンツホールドという島に飛ばされました。

そこは毒を持った蛇がうようよいる小さな島でした。後で知りましたが初心者がいく場所ではなかったようです。でも周りは海なので船や魔法がないと他の場所にはいけません。頑張ってスキルをあげようにも敵が強すぎて初心者にはなかなか倒せません。でもなんとか生き延びて、たまに来る上級冒険者が捨てていくアイテム(重量オーバーで捨てたり、上級者には価値が無いものだったり)をせっせと拾い集めてショップで売ってお金をためて、船を買ってようやく島から脱出できました。それがはじめの1ヶ月間のプレイでした。なんてむちゃくちゃなゲームなんだと思いながらも、なんとも言えないその世界観にハマっていきました。

それから1年くらいやってて、仕事がいそがしくなってやめてしまいました。廃人になる前に卒業できてよかったのですが、5年ほど前にまたふと思い立って半年くらいやりました。その時は、なんとマイホームを持つことができました。UOの世界では自分の家を建てて住むことができるのですが、以前は土地不足で家を建てることのできる土地が余っていませんでした。リアルマネー数十万円で取引されている時代もありました。それが5年前では、プレイ人口が減ったからか、どこでも空いているというわけではなかったけど探し回ってやっと空き地に家を建てることができました。でも残念ながらまた仕事がいそがしくなってやめました。

UOをやめることは、つまり月額課金をやめることです。リアルの生活がいそがしくプレイ時間がほとんととれない状況だと、月額課金はもったいないので結局やめてしまいます。でもたまにまたやりたくなります。なので、今回のこのニュースはとても嬉しいです。

いざプレイ

アカウント画面を見てみると、Endless Journey が有効になっていました。 f:id:inosyan:20180418014254j:plain

久しぶりすぎてすっかり忘れています。だいぶたったのでmac版もでてるかと思ったけど、そんなことはありませんでした。ParallelsWindows版のクライアントをダウンロードしました。昔ながらの2D表示のクラシック版と、3D表示のエンハンスド版がありますが、5年前の経験でmac上でエンハンスド版が重くて動かなかったのでクラシック版にしました。macも新しくなったのでもしかしたら動くかもしれませんが、初回起動時のパッチ適用にもエンハンスド版はすごく時間かかった経験があり、いまはすぐにプレイしたいのでリスクを避けました。

f:id:inosyan:20180418014310j:plain

プレイ画面で入れるIDとパスワードは、ブラウザでのアカウント管理画面のそれとは違うようです。メモも残っておらず、おぼろげな記憶をたよりにようやくログインできました。 5年前にプレイした時はどこのシャードだったか、なんとか思い出しました。

f:id:inosyan:20180418014324j:plain

キャラ選択画面にいくと、5年前にプレイしていたキャラがみんないました! たしか、家具、道具、薬、巻物、洋服、料理などを作る人と、冒険する人とにそれぞれ役割をわけてた気がするけど、細かいことは忘れています。 まずは思い出すところからはじめようと思います。

スキルやステータスの情報を記録するためのツールを作成

UOにはレベルの概念がありません。その代わりにスキルとステータスがあって、どの組み合わせで成長させるかを選ぶことによって個性が生まれます。また、どれも無限に伸ばせるわけではなく、合計値の上限が決まっているので、組み合わせが重要になってきます。

f:id:inosyan:20180418014343j:plain

f:id:inosyan:20180418014354j:plain

たぶん今後は、昔みたいに取り憑かれたように毎日やるのではなく、たまに気が向いた時にプレイする感じになると思います。そうすると前回どのキャラがどういう状態だったのかを忘れてしまうので、ステータスやスキルを記録したいと思いました。

そのためには、ゲームから情報を取得できなくてはいけません。たぶんエンハンスドクライアントなら簡単にできます。Luaという言語で独自UIを作れるので、情報取得のAPIがあるはずです。でもクラシック版にはその機能はありません。データの保存してありそうな場所を見てみましたが、これはオンラインゲームなので、ほとんどのデータはサーバー上にあり、ローカルにはほぼありません。不正行為のようなこともやりたくありません。そうなると、ゲーム画面に表示されているものが得られる情報のすべてということになりますが、目で見て書き写すのは面倒です。

そこで、画面をキャプチャし、javascriptで解析してみることにしました。昔ならありえない発想ですが、最近のパソコンやjavascriptエンジンの性能を目の当たりにしているので、できるような気がしたのです。やってみたところ、キャプチャ画像を白黒に変換し、アルファベットや数字の画像とピクセルが一致するかどうかを調べて、画像の中に書いてある文字や数字を解析するという、いかにも重そうな処理が全く問題なくできました。

f:id:inosyan:20180418014417p:plain

これが解析結果画面です。ステータスとスキルを一覧できます。デザインはスプレットシートにコピーしやすくするためにあえてUIは装飾していません。

f:id:inosyan:20180418014435p:plain

解析結果をスプレッドシートにコピペしてみました。これで成長の記録はばっちりです。

f:id:inosyan:20180418014449p:plain

ついでにペーパードールというキャラクターの画像を、背景やかばんや巻物などを除いてキャラクターだけをアルファで抜いて切り出すこともできました。

f:id:inosyan:20180418014503j:plain

f:id:inosyan:20180418014514p:plain

javascriptで画像処理も問題なくできました。コンパイル無しで試せるところがとても良いです。プログラムのやる気がわきます。ゲームをきっかけにしたプログラム作成は楽しいしモチベーションを維持しやすいのでおすすめです。jsでの画像処理、もうすこし深掘ってみようと思います。

スニペッチ バージョン0.0.7 リリース & ドキュメント一通り完成

f:id:inosyan:20180303135022p:plain

スニペッチのドキュメントを書いていて、見つかった不具合を修正しました。

バージョン 0.0.7 (2018.3.29) - 「イベント」の「~が押された時」の選択肢「どれかの」にあたる定数 KEY_ANY を追加 - 「調べる」の「ビデオ」の選択肢「モーション」にあたる定数 SENSOR_VIDEO_MOTION を追加 - 「制御」の「~を止める」の選択肢「ステージの他のスクリプト」にあたる定数 STOPTARGET_OTHER_IN_STAGE を追加 - 「制御」の「~を止める」の選択肢「スプライトの他のスクリプト」にあたる定数 STOPTARGET_OTHER_IN_SPRITE を追加 - 「演算」のブロックに「余り」を追加 (書き方の例: 10 % 3) - 「base」を削除したときに落ちる不具合を修正 - 「演算」の「=」のブロックのスニペットが 1 = 1 だったので、正しく 1 == 1 に修正 - 「イベント」の「~ > ~ のとき」のブロックのスニペットに引数が抜けていたので修正 - コスチュームとサウンドの画面で、コスチューム名/サウンド名のラベルが言語切替で切り替わるように修正

そして、ドキュメントを一通り書きあげました。これで、スニペッチのすべての機能が明らかになりました。 中学生くらいの人を対象に書いたつもりですが、たぶんわかりにくいと思うのでこれから直していきます。

以下が、今回追加したドキュメントです。

計算式の書き方
条件文の書き方
カスタムメソッドで新しいブロックを作る
「ベース」でカスタムメソッドを再利用しよう
コメントの書き方
目的別にコンパイル結果を変える「プリプロセッサ」
こまめに保存し、バージョン管理システムを活用しよう
色コードについて
コマンド一覧 動き
コマンド一覧 見た目
コマンド一覧 音
コマンド一覧 ペン
コマンド一覧 データ
コマンド一覧 イベント
コマンド一覧 制御
コマンド一覧 調べる
コマンド一覧 演算
コマンド一覧 その他

スニペッチの中で私が一番気に入っている機能は、「ベース」です。なぜなら、スクラッチで高度なプログラムを作れる可能性を、この機能は持っているからです。

簡単に説明すると、この機能はプログラムを細かく分解し、再利用する機能です。
作ったものを再利用できるという点では、オンライン版のスクラッチの「バックパック」の機能に似ています。バックパックは作ったものをとっておき、使いたい箇所にコピーする機能です。 https://blog.hatena.ne.jp/inosyan/inosyan.hateblo.jp/entries

ですが、「ベース」は、コピーするのではなく、呼び出すものです。これは、プログラミングでクラスをインスタンス化して使うのに似ています。
実際、スニペッチでベースのメソッドを呼び出すときには new します。

var base = new BaseSample();

function scripts(){
    whenKeyPressed(KEY_RIGHT_ARROW, function(){
        base.sample(true);
    });
    
    whenKeyPressed(KEY_LEFT_ARROW, function(){
        base.sample(false);
    });
}

そして、ベースから、さらに別のベースを利用することができます。つまり、部品と部品をつなげて、さらに高機能な部品「ライブラリ」を作ることができるということです。 ライブラリの開発、共有、利用のサイクルで、さらに高度なアプリを生み出すことができるでしょう。

そもそも、スクラッチで効率を追い求めるのは教育的に良いことなのかどうか、私はプログラマであって教育の専門家ではないので判断できませんが、プログラマの視点で言えば、効率化は当然やるべきことです。「同じコードを2度書かない」「車輪を再発明しない」を実践しようとすればたどり着く結論です。もちろん、学習者が勉強のために何度も同じコードを書いてみることは悪いことではありません。

使っていくと、いろいろ改善したい箇所が出てきました。作品を作りつつ、引き続きスニペッチも改良していこうと思います。

スニペッチのドキュメントを追加しました

f:id:inosyan:20180303135022p:plain

いまスニペッチのドキュメントを書いていますが、いくつか出来たのでホームページに追加しました。まだ足りないので引き続き書いていきます。

コスチューム&サウンド
作品をスクラッチのサイトにアップロードしよう
スクリプトのメソッド
変数、リスト、定数
if文とrepeat文の書き方

それと、スニペッチでスクラッチのゲームを作ってみました。(Flash Playerが必要です)
Star Shooter

githubにソースを上げています。
github

f:id:inosyan:20180319082444p:plain

これについては詳しく説明したいのですが、それはまた次の機会に。

スクラッチ上級者向けのアプリ「スニペッチ」を更新しました

f:id:inosyan:20180303135022p:plain

スニペッチ

スニペッチとは

スクラッチという、子供向けのプログラム言語があります。マウス操作でブロックを並べるだけでプログラムを作れることが大きな特徴で、キーボードの操作に慣れてない子どもたちでも、タイプミスでつまづくことがありません。英語がわからなくても大丈夫です。

ただ、複雑なプログラムを作るためにはたくさんのブロックを並べなけばならず、マウス操作で行うのは大変です。スニペッチは、文字で書いたプログラムをスクラッチに変換するアプリです。

クラッチはWebアプリですが、オフライン用のScratch 2 Offline Editorがあります。これで作った作品をWebにアップロードしたり、Webから作品をダウンロードしてオフラインエディタで続きを作ったりできます。

f:id:inosyan:20180303135058p:plain

スニペッチは、このオフラインエディタといっしょに使います。スニペッチでコードを書き、緑の旗(スクラッチの世界では再生を意味する)を押すと、コードが作品ファイルにコンパイルされ、オフラインエディタが起動して作品が読み込まれます。

クラッチと同じブロックが並んでいて、それをコードエディタにドラッグ&ドロップすると、ブロックがコードに変わります。これを繰り返すことで、ブロックとコードが同じ意味だということに気づき、やがてはブロック無しでコードをかけるようになるのです。

また、「スニペッチ」の語源でもあるのですが、繰り返し使う処理「スニペット」を別ファイルにしておき、他のファイルから参照することができます。スクラッチでは、同じ処理を複数のスプライトにコピペすることがよくありますが、そうすると修正する際に複数箇所で行わなければならなくなります。ですが、スニペッチでは共通処理のコードを修正するだけで済みます。

スニペッチの特徴

  • コードエディタ
    • JavaScript風のコード
    • 単語のハイライト
    • コード補完
    • 自動インデント
  • クラッチと同じブロックからコードを作成
  • 共通コードの再利用
  • コードをスクラッチ用の形式にコンパイル

f:id:inosyan:20180303135113p:plain

作ったきっかけ

今から5年ほど前、ネットでスクラッチのことを知り、当時小学生だった娘といっしょにはじめました。スクラッチのイベントに足を運んだり、プログラム教室にボランティアで参加したりもしました。スクラッチのアカウントを作り、子どもたちの参考になればといろいろ作品を作りました。

ある時、スクラッチのファイルの中を見てみたら、JSONとメディアファイルで出来ていることに気づきました。これなら、ブロックじゃなくてテキストで編集できるのでは?と思ったのがはじめのきっかけです。 ブロックとJSON構造の関係を解析して、JSONを手書きで作品を作ってみました。

f:id:inosyan:20180303135133p:plain 「ねこのおさんぽ」

JSONを手書きではなく、普通にプログラム言語で書きたい。そのようなツールがあれば、スクラッチの作品を効率よくつくれるし、娘にも文字で書くプログラムを覚えてもらいたい。そういう思いからスニペッチを作り、2014年11月にはじめのバージョンを公開しました。

ですが、娘はあまり興味をしめしてくれず、スクラッチもあまりやらなくなってしまいました。私もモチベーションが下がり、最近までなにもしていませんでした。

復活した理由

先日、配布していたスニペッチのインストーラーが動かなくなっていることに気づきました。理由はインストーラーの証明書の問題でしたが、この記事「昔作った Adobe AIR のアプリをメンテしようとしたら、リリースビルドが出来ずに苦労した件」に書いたように解決できました。

久しぶりに動かすとちゃんと動き、また昔のようにスクラッチの作品を作ってみたいと思いました。自分で作ったものを褒めるのも変ですが、このまま埋もれさせるのももったいないし、みんなに知ってもらい、役に立ててもらいたいです。

今後の予定

クラッチFlashで作られています。Flashは2020年でサポートが終わることもあり、スクラッチ本家ではReactで作りなおそうとしているようです。

AIRは今後もサポートが続くとアナウンスされているので、AIRでの開発は可能です。ですが、いま仕事でReactをやってることもあり、React + Electron で作りなおしてみたいです。いま流行っている言語で書きたいし、ReactならWebサービスにもできる可能性もあります。

でも、まずはスニペッチのドキュメントをまとめないと、詳しいコーディングの方法をわかってもらえないので、それをやろうと思います。ドキュメントはホームページに掲載していきます。 一人でも多くの人に便利だと思ってもらえるとうれしいです。

f:id:inosyan:20180303135154p:plain

Tokyo HoloLens ミートアップ vol.7 に行ってきました

品川で行われた HoloLensのイベント「Tokyo HoloLens ミートアップ vol.7」 に行ってきました。 会場にはアイボを連れてこられている方もいらっしゃいました。はじめて見ましたが、しぐさが本物の犬みたいでとても可愛いです。

f:id:inosyan:20180219143700j:plain

「HoloLens製カードゲームHADO KARTを現場に導入した話」増田博志@trappleさん

もうこんなサービスが始まっているんですね。乗り物とMRを組み合わせているところが面白そうです。 プロトタイプはLuggieという電動カートを使って作ったそうです。なにもないところから試作品を作って試行錯誤の末にサービス化させるのって大変なことだと思います。

f:id:inosyan:20180219143727j:plain
f:id:inosyan:20180219143740j:plain

ホロレンズの頭の上につけるバンド部分は、現場ではよく破損するそうです。私のはまだ壊れてませんが、毎日使うと壊れやすい部品なのかもしれません。

会場でHoloLensを持ってきている人を見ると、バンドを付けてない人が多いです。バンドはなくても後ろの調整ネジで閉めれば落ちてこないので、かならずしも必要ではないのかもしれません。また、バンドがなければそのまま下におろして首にかけることができます。
でも、ネジで締めるとこめかみが痛いんですよね。今日懇親会でピザを食べたときに気づきましたが、ホロレンズつけたまま食べるとこめかみがいたくなります。

f:id:inosyan:20180219143759j:plain

電源アダプターによっては充電されないことがあるそうです。純正のものを使用したほうが無難ですね。バッテリーの持続時間はHADO KARTの場合3時間だそうです。

f:id:inosyan:20180219143814j:plain

ホロレンズおよび観覧者を考慮したシステム構成になっていました。 ホロレンズの開発は、ホロレンズのことに意識が行ってしまいがちですが、観覧する人のことも考えてることも大事ですね。

f:id:inosyan:20180219143834j:plain

開発に使用されたライブラリ - UniRx: Object Pool - BestHTTP: Socket.IO - LeanTween: UWPで使える - Vuforia: WorldAnchor

HoloLensは高いので複数端末での開発は気軽にはできませんが、実際にやったひとの話を聞くと、複数になると直面する苦労もいろいろとあるようです。みんなで同じ座標を共有するためには、原点がどこなのかを揃えなければなりません。 2つのマーカーをそれぞれのHoloLensやiPhoneで読み取っていました。

f:id:inosyan:20180219143848j:plain

「HoloLensで高品質なグラフィックスを実現する」MIRO@MobileHackerzさん

以前、初音ミクが歌舞伎を演じる様子をテレビで見ましたが、その制作の話を聞かせてもらいました。テレビで見てるときは、スクリーンに映っているようにも見えるし、画面に重なっているようにも見えるし、不思議だなと思ってましたが、正解は両方でした。
会場ではスクリーンにプロジェクターで投影したものを上映し、ネットではスクリーンの映像を消して3Dを重ね合わせたものを配信していたそうです。

f:id:inosyan:20180219143914j:plain

でもスクリーンにした映像は、斜めから見ると歪んでしまいます。会場でも立体を表示したいということでHoloLensでの表現を研究しているそうです。 もともとのモデルは17万ポリゴンあったそうですが、HoloLensで動かすために7.7万ポリゴンまで削減したそうです。60fpsを実現するチャレンジはロマンを感じました。

技術メモ - アニメーションは、スキニング計算は重いしモーションが固定なので事前に計算し、全頂点の情報を持つ
- Alembic ImporterはUWP非対応
- Unity上でSkinned meshを1フレームずつコマ送りしてファイルに頂点情報を書き出すツールを制作
- 全頂点分のアニメーションのファイルサイズは 30fps換算で2分33秒のアニメーションが 8.8GB
- 30fpsのデータを補間し60fpsで再生
- IndexとUVは全フレーム共通なのでまとめる
- PositionとNormalだけがアニメーションする
- floatではなく固定小数(-2.0f~2.0fをUInt16Maxで分割) 8.8GB が 2.5GBに削減
- 頂点圧縮はCPUコストがかかるので断念
- 着物の箔押し部分を再現するためMetallic Smoothnessマップに対応
- AmbientOcclusionマップに対応
- 内部はLinearで計算、最終段でGammaに変換
- XRenderViewportScaleを対象物との距離、描画面積などによって値を調整し、60fpsでるように調整

f:id:inosyan:20180219143928j:plain

セットを実際に作ってみるということも大事という話、そのとおりだと思いました。HoloLensは現実とバーチャルが重ね合わさってはじめて一つの表現が完成するものなので、現実のほうもなにか凝ったものを作ってみたくなりました。

f:id:inosyan:20180219143946j:plain

超歌舞伎、興味がわきました。

f:id:inosyan:20180219144000j:plain

「Unityを使わずHoloLensアプリを作ってみた」河原田清和さん

優れたミドルウェアのおかげでHoloLensアプリの開発は難しくありません。誰でも簡単に、プログラムが書けなくても作ることができます。しかしそこに依存するあなたは自分をエンジニアと胸を張っていえますか?

UE4は結局今の段階では速度を出すのは厳しく、DirectXは速度があがる可能性があるという結論でした。 効率を考えるとミドルウェアを使うのが現実的だと思います。ですが、仕組みを知るため、DirectXからHoloLensに出してみる工程に一度触れてみることはありだと思います。

f:id:inosyan:20180219144018j:plain

技術メモ(DirectX)
- 必要なもの
- Visual Studio 2017 - HoloLens Emulator
- テンプレートからプロジェクトを作る
- Visual C++ -> Windowsユニバーサル -> Holographic から Holographic DirectX 11 App を選択
- ビルドしてHoloLensへ転送
- ここをいじればいろいろできる
- コンテンツ初期化、シェーダー読み込み
- インプットイベントハンドラ
- SpinningCubeRenderer:CreateDeviceDependentResources()内の
- Vertex/Pixelシェーダーファイルのロード、作成
- 頂点フォーマットを定義
- キューブモデルを生成(8頂点をプログラム内に記述)
- 頂点バッファ、インデックスバッファを作成
を改造する


会場の端で、私の作ったアプリ Window Breaker のデモをさせていただきました。
見に来ていただいた皆様ありがとうございました。いろんな方との交流ができてよかったです。 持参したHoloLens以外はなにも用意してなかったので、デモなのかどうかわかりずらかったですね。次回は「デモやってます」くらいのプレートは用意します。

f:id:inosyan:20180219144039j:plain

次回も都合がつけば行きたいです。

次回イベント
HoloLens MeetUp Vol.8
日程: 2018 4/21(土)
時間: 13:00~18:30
会場: 日本マイクロソフト株式会社