MMDモデルの視線を自然な感じに見せる(視線IKを使わない方法)
タイトルの通り、MMDモデルを手軽にカメラ目線(ぽく)見せるためのTipsです。
効果
この動画の左がこれから書く方法で目を調整したもの。
アリアンナさんのMMDモデル更新しました。
— あやちぎん (@AyachiGin) 2016年4月16日
足がスカートを貫通しにくくなりました。顔色が良くなりました。目を調整してカメラ目線ぽく見えるようにしました。
動画は左が目を調整したもの。 pic.twitter.com/cR6ni4MKRi
YesodのfileAFormReqでinput要素にrequired属性ついてない
わりとタイトルのまんまです。
uploadForm = renderDivs $ fileAFormReq "file"
と書いて生成されるhtmlが
<div class="required "> <label for="hident2">file</label> <input id="hident2" type="file" name="f1"><!-- required属性がない! --> </div> <input type="submit" value="Upload">
これは困った!
areqを使いましょう。
uploadForm = renderDivs $ areq fileField "file" Nothing
<div class="required "> <label for="hident2">file</label> <input id="hident2" type="file" required="" name="f1"><!-- required属性ある! --> </div> <input type="submit" value="Upload">
fileAFormReqのほうは古いapiなのでしょうか。
とうらぶえくすてんしょんから通知されるイベントで独自の内容を喋らせる
この記事はゴーストを制作している人向けです。
刀剣乱舞の遠征通知とかをゴーストに喋らせる何かを作りました。
導入方法はこっちを見てください
刀剣乱舞の遠征通知を伺かのゴーストに喋らせる - アヤチノオト
動作の仕組み
とうらぶえくすてんしょん(ブラウザ)からちょっと特殊な方法でSSTP(NOTIFY)を送っています。
SSTP(NOTIFY)はイベントの名前(OnTourabuConquestStartとか)のほか、Scriptを指定しています。
Scriptとは、ゴーストが通知されたイベントに反応しなかった場合、かわりに喋らせる内容です。
とうらぶえくすてんしょんとWebSocketSSTPになにか対応をしたわけではないゴーストでも通知を喋らせることが出来るのはこのためです。
遠征や内番の通知を受け取ったときに独自の内容を喋らせる方法は次の段落へ
イベントに対応
里々の記法のみサンプルを記載します(ほかの書き方わかんないので……
普通のイベントとおんなじです。
通知されるのは以下の4つのイベントです(2015/03/14現在)
OnTourabuConquestStart
遠征が開始されたときに発生します。2つのリファレンスを持ちます。
Reference0: 部隊の番号。1~4の整数です。
Reference1: 遠征が終わるまでのおよその時間で単位は分です。
```
記述例とトークの様子
*OnTourabuConquestStart :第(R0)部隊が遠征を開始しました。(R1)分後に帰還します。 :遠征……てなに?
OnTourabuConquestEnd
遠征が終了したっぽいときに発生します。仕様上実際の遠征終了より通知が数秒早いことがあります(2015/03/14現在)
1つのリファレンスを持ちます
Reference0: 部隊の番号。1~4の整数です。
記述例とトークの様子
*OnTourabuConquestEnd :第(R0)部隊が遠征から帰還しました。 :だから遠征ってなんなの
OnTourabuDutyStart
内番が開始されたときに発生します。 リファレンスはありません。
記述例とトークの様子
*OnTourabuDutyStart :内番を開始しました。 :内番てうちばん?ないばん?
OnTourabuDutyEnd
内番が終了したっぽいときに発生します。リファレンスはありません。
記述例とトークの様子
*OnTourabuDutyEnd :内番が終了しました。 :お疲れ様でした。
これでぜんぶだ。
刀剣乱舞の遠征通知を伺かのゴーストに喋らせる
何が出来るものなのか
刀剣乱舞の遠征とか内番の通知をデスクトップマスコットに喋らせることができます。
必要なもの
必要な物は3つありますがインストールはどれも簡単です。
それぞれの項目については下で説明します。
SSPの説明とインストール
SSPはデスクトップマスコットのベースウェアと呼ばれるもの。
ゲームでいうとゲーム機のようなものです。
これとは別にゴーストと呼ばれるキャラクターが配布されていて、これはゲームでいうとゲームソフトに当たります。刀剣乱舞のキャラクターのゴーストもたくさん制作されています。
インストール
SSPは独立伺か研究施設 ばぐとら研究所からダウンロード出来ます。
ページ左のダウンロードボタンをクリック(画像赤枠部分)
ダウンロードしたファイルを開いて
書庫名でフォルダを作成にチェックを入れてOKを押します
展開されたフォルダからssp.exeを開くとデスクトップに猫耳の女の子が出てきます。
これでインストール完了です。
ゴースト(キャラクター)を増やす方法はここでは説明しません。
どうやって新しいキャラクターを増やすかや、どんなキャラクターが居るのかは以下を参照してください。
『刀剣乱舞』二次創作デスクトップマスコットまとめ
とうらぶえくすてんしょんの説明とインストール
とうらぶえくすてんしょんは刀剣乱舞をちょっと遊びやすくするChromeの拡張機能です。
Google chromeで普通にぽっちっとインストールしてください。
とうらぶえくすてんしょん - Chrome ウェブストア
これだけでも遠征や内番の通知を表示することは出来ます。
しかし、伺かと連携させるためにはあとひとつSSPのプラグインが必要です。
WebSocketSSTPの説明とインストール
WebSocketSSTPはとうらぶえくすてんしょんとSSPを繋ぐものです。
WebSocketSSTPのリンクをクリックしてダウンロードします。
ダウンロードされたWebSocketSSTP.narをさっきの猫耳の女の子にドラッグ・アンド・ドロップします。
これで準備は完了です。お疲れ様でした。
DMMのブラウザゲーを間違って閉じちゃうのを防ぐプラグイン作った
これは動的な弱い型けなのではと思ったけどそうでもないのか
すごいErlangゆかいに学ぼう!を読んでいるのですが、12章にでてくるregisterという関数の動作がちょっと気になったのでした。
registerは第一引数にatom、第二引数にpidをとってpidをatomで参照出来るようにする関数です。
しかし、すでに存在する関数名をregisterで名前をつけるとおかしなことが……
%% hello.erl -module(hello). -compile([export_all]). start_link() -> register(loop, spawn_link(?MODULE, loop, [])). hi() -> % loopという名前のプロセスにメッセージを送っている loop ! {self(), "Hi"}, receive Mes -> Mes end. loop() -> receive {Pid, Mes} -> Pid ! Mes, % こっちではloopを関数として呼び出している? loop() end.
これは動的な弱い型付けなのでは?
と、ここまで書いて思ったのですが。
上のコードでloopがpidのように振る舞ったり関数のように振る舞ったりしているように見えるのはこういうことなのでしょうか。
つまり、atomとそれに関連付けられたものを同じものと思ってしまったからおかしく感じた、のかな。よくわかりません。
すごいE本読んでる記録
すごいE本ことすごいErlangゆかいに学ぼう!を読んでいます。
タイトルからわかるとおり、すごいHaskellたのしく学ぼう!の読みやすく、それでいて深い内容のスタイルを真似て書かれています。
すごいH本とおなじ問題がすごいE本にも出ていて、その中の逆ポーランド記法電卓をやってみました。
逆ポーランド記法とは
まずポーランド記法が何かというと。Lispの括弧を取ったようなやつです。
// 普通の式 (1 + 2) * 3 // ポーランド記法 * 3 + 1 2
逆ポーランド記法はこれをひっくり返したものです。
// 逆ポーランド記法 1 2 + 3 *
被演算子が必ず先に来るので評価がシンプルに出来ます。
書いてみた
本の中のコードでは演算子が"+"みたいに文字列だったんですがこれをaddみたいにatomを使ってみた。
%% rpn("1 2 add 3 mul") = 9 rpn(L) when is_list(L) -> % 文字列を空白で区切って,integerかfloatかatomのリストにする Values = lists:map(fun read/1, string:tokens(L, " ")), [Res] = lists:foldl(fun rpn/2, [], Values), Res. rpn(add, [X, Y|Stack]) -> [X + Y| Stack]; rpn(sub, [X, Y|Stack]) -> [X - Y| Stack]; rpn(mul, [X, Y|Stack]) -> [X * Y| Stack]; rpn(div, [X, Y|Stack]) -> [X / Y| Stack]; rpn(pow, [X, Y|Stack]) -> [math:pow(X, Y)| Stack]; rpn(X, Stack) -> [X| Stack]. %% 実数として読めるか試して失敗したら整数として読む %% 整数でもなかったらアトムにする %% なんか美しくない read(X) -> case string:to_float(X) of {error,no_float} -> try list_to_integer(X) of Y -> Y catch error:_ -> list_to_atom(X) end; {F, _} -> F end.
書いてみて思ったこと
doctest欲しい。欲しいすぎる。もしかしたらある?かも?
エラーメッセージ読みなれるまではつまらないミスでぬおおおお!ってなる日々になりそう。