今まで色々計算式をいじってきました。その目的が「0~1で操作したい」ということでしたね。この0~1の値が、この「どのくらい進んだか」を意味するわけです。500フレーム動いたときには、この動いた割合0.5を、式に代入して計算すればよいのです。「変化する量」とはいくつでしたか?要するに、全部動かしたらどのくらいでしょうか?それは3で出ていますね。「0.5の変化に対して、実際に動く量はいくつか」ということを計算します。ここでいう変化が、2のXに相当します。実際に動く量の割合が2式でのYです。「実際に動く量」が求められます。0.5))=1/(1+e^0)=1/(1+1)=0.5となります。2.5最終的に、500フレーム経過したときのカメラの座標は500F後のXの値=2500+25.0=2525.0500F後のYの値=1300+50.0=1350.0500F後のZの値=20+2.5=22.5となりました。これが本当に求めたい答えです。これが出れば、あとはプログラムコードを組むだけです。ゆーことで、今までの流れを一般化してみましょう。実際に動く量の割合」を計算し、「実際に動く量」を求めるという流れになります。これこそが「理論を実装に変えた」瞬間です。あーだこーだ机上で述べてきた空論が、形を持って結果として出てきました。ついでに、実際の計算も一般化しておきましょう。ΔZはい!できましたー!このrX,rY,rZが、nフレーム目におけるカメラ座標となるわけです。GTAは変数に名前を付けられない上に、わずか31個しか使用できないのでこの記事のように分かりやすいまま実装することはできませんが、なんとかうまくコーディングすれば同じ処理を実現できます。いうことで、あとはプログラムの話になりますので以降は割愛。誰も、どころか自分もわからないと思うので。こんな感じで、1つ1つ目標に向かって適切に考えて、しっかり理論と数式を結び付けていくことで、プログラムコードという実装へ落とし込むことができます。最初は何をやっていて、どこを目指しているのかわからなくなることも多いと思いますが、その時は素直に一旦諦めて棚上げしてしまった方がいいです。小型の、シンプルなアイデアを形にすることを何度か実践して練習し、その流れを身体で覚えた方がいいでしょう。今回のようにカメラワークのエンジンそのものを作ろうとすると、今がどうなっていて、何が不便で、どうすれば改善できて、そのためには何が必要で、どれだけ複雑なのか、ちゃんと把握できていないとパンクしてしまいます。今回の改良も、これまでのSlideCameraWorkという実績があるからこそスムーズに行えたものなんだということを知っておいてください。本当の最初は、確か何かキーを押すと今の視点で固定されるだけ、という極めてシンプルなものだった気がします。そこから、カメラを動かすコードの存在を知り、でも2つのコードがセットになっていて、試行錯誤しながら動作を覚えていき、カメラを移動させる方法を考えたけれども満足できず、もしかして、ものすごく細かく瞬間移動カメラを連続実行させれば、滑らかなカメラワークとして機能するんじゃないかと思ったらうまくいって、そこから始点と終点を決定するためのインタフェース作りに悩んで、変数が多すぎて大混乱の中でメモリ操作を覚えて、そしてカメラの回転なども改良に改良を重ねて、そして現在のSlideCameraWorkがあるという感じです。Pixivだったら評価点100点ももらえないような子供のおもちゃレベルのものからのスタートだったわけです。なんとかなるものですね。これが実装へ漕ぎつくための唯一のやり方ではありません。いい加減なところがあってはそこから先へは進まないということは分かってもらえたと思います。漠然としたやる気だけで事に臨まず、堅実に着実に、真剣に取り組んで作ってみて下さい。よくなっていき、次第にできることが広がっていくと思います。以上、また何かあったらそのときに。この新しいエンジンを積んだSlideCameraWorkは、なるべく早く公開まで持っていきたいと思います・・・。見ての通りの、円月輪です。元々は円状のもので、モーションを円形になぞるのを補助するために作ったものです。「フランの風切」と同じ、補助ツールになります。武器として使えなくもありません。物理演算を入れたので、投げられます。新しい理論を実装する場合、何から手を付けていいのか分からないと思います。そんなとき、まず自分がやりたいことを思い出してみましょう。最初と最後がゆっくりなカメラワークですが、それは具体的にどのように動くでしょうか?カメラワークを実行するには何が必要で、実行した結果どうなるんでしたでしょうか。・nフレーム目での進行度合いを計算してくれる式(nは任意のフレーム位置)でした。nフレーム目の現在位置が求まります。これを繰り返すことで連続的なカメラワークが実現できるわけです。よって、実行した結果は・nフレーム目に、或る位置にカメラが移動するとなります。言葉にしてしまうとシンプルな話ですね。要するに、「動作」には「入力」と「出力」が存在するわけです。何かを入力したら、入力したものを加工して何かが出力される。あらゆる処理のシーケンス(順序)は1,初期値を与える2,初期値による出力の計算3,結果の出力4,次の値へカウントアップ、もしくは次の値を計算5,次の値による出力の計算6,結果の出力7,4に戻る。提示しておいた条件を満たしたら終了となるのです。どんなものでも、これに当てはめれば動作します。動作し得ないのなら、この1~7の何かが抜けているのです。実際に当てはめてみましょうか。初期カメラ位置(ユーザーが指定する)。nが総フレーム数と等しくなったらはい。今までに提示した内容で全部埋まりましたね。次に、一番重要な中核部分、「Yを求める」です。これを確認してみましょう。式はコレだと言いましたが、数学やプログラムの関数に触れていない人にはそれでもピンと来ないかもしれませんので、実際のカメラ位置も含めて手順をなぞってみましょう。この「手順を手動でなぞる」というのは極めて大切です。これを何ループか繰り返して、全体を把握してから「一般化」を行うのが正しい道筋です。Y=X+2がどういう軌跡を成すか分かりますか?ある程度数学を身に付けた人ならすぐに分かりますが、そうでないと直感的には難しいでしょう。いうときは、1つずつ値を入力していくはずです。Y=2+2=4こんな感じです。これで、XがY軸と同じ位置にあるとき、Y=2に点があることが分かり、Xが1増えるごとにYも1増えていくことが分かります。Y=2を通る、傾きが1(Xの増分1/Yの増分1)の直線だと言えます。実のところ、上で書いた複雑な式がどういう軌跡を描くかはもう分かってますよね。X軸が-6~+6になっていますが、将来的には0~1になるように調整したいです。するかって?X=1を入れたら、実際にはX=6を入れたのと同じになればいいんですよね。X=0ならX=ー6を入れたのと同じになればいい。X=0.5を入れたらX=0入れたみたいになればいい。これはつまり、X=0の時はY=ー6,X=1の時はY=6っていう直線を示してるのと同じですよね。Y=12Xー6じゃあありませんか。この(便宜上の)YっていうのはグラフのX軸の値を示してますので、式のaxがYだと思えばOKです。実際は-xですから、まとめるとeの指数は6-12Z(Zは0~1)となります。Zを0にすると-xが6になったことになります。-xが6ということは、X=-6を入れたのと同義です。Zを1にすると-xがー6になったことになります。X=6を入れたのと同義です。Zに0~1を入れるだけで、上のグラフのX=-6~+6を行っているのと同じ効果が得られるということです。これからeの指数は「6-12Z」と置き換えます。上の式のZに、まずは0.5を入れてみます。σa(x)=1/(1+1)=0.5となりました。グラフ上でもY=0.5ですね。グラフ上の「X=2」の値になるようなZを入れてみます。Zは端から端までが0~1ですから、X=2に対応するならZ=4/6=0.667ですね。eの指数は6-12×0.667≒-2です。σa(x)=1/(1+e^-2)=1/(1+0.135)=1/1.135=0.881うん、グラフを見ても、0.9にほど近い値ですから、この値も合ってる感じです。Z=2/6=0.333を入れてみましょう。σa(x)=1/(1+e^+2)=1/(1+7.389)=1/8.389=0.1192はい、対象形ですから、これも正しいですね。それじゃもう一つ、Z=1を入れてみます。eの指数はー6ですね。これは元々X=6を入れているのと同じ。-axがー6になってるのと同じでした。σa(x)=1/(1+e^-6)=1/(1+0.002)=1/1.002≒1成りました。正確な1ではありませんから、正確に1になるのを待っていたらいつまでも1にならないので、プログラム的にはどこかで値を丸めるなりしてあげる必要があります。1/1.002=0.998なので、Yが0.997を超えたらもう終了しちゃおう!という終了条件にするのです。この辺は、プログラムを知らない人なら「こまっけえなあ」って思うでしょうが、プログラムは「一切の融通が利かない」ので、やらないとダメです。いうことで、とうとう0~1という入力を与えると、0~1の範囲でYが滑らかに変化する式が得られました。Y=1/(1+e^(6-12Z))です。これで、次の節で具体的なカメラ座標の計算ができそうですね。実際のGTAの値との調整になります。難しいのは、理論を実際の動作へ落とし込むことです。EXCELだって、1行おきに1、2、3と入力するのは簡単ですが、その理論をプログラムに落とし込んで、自動で1000まで、2000行の入力を一瞬でやってくれるようにするには、意外にできないものです。いわゆる「動くアルゴリズム」ができてこそ、モノづくりと言えます。高尚な理論や理想ばかりを語る人よりも、稚拙なオモチャでもいいから実際に動くモノにしてみて下さい。いう人の方が「できる」人だと思いますよ。2,どんな風に動くのか前回こんなイメージを載せました。これを元に話を進めます。カメラはそもそもどう動くのかを確認しましょう。いうものかを把握していないと何も始まりません。カメラ位置を指定する方法はこんな感じです。2-------------------------------------まず、カメラはカメラ本体とターゲット、2つを動かすということになります。目の場所、そして見る対象の場所です。この2点が決まって初めてどこかを見るという動作が成り立ちます。ターゲット位置にならないように留意する必要があります。カメラとターゲットが近いほど、どちらかが少し動いただけで視点が大きく動くのは想像できるでしょうか?逆に2者の距離が離れているほど、少しくらい動いただけでは画面はほとんど動かないですよね。目の前の蚊を追うのは大変ですが、東京ドームでランナーを追うのに目はほとんど動かす必要がありません。要するに、動かす「利き量」が違うわけです。目の前のコップを5cm動かせと言われたら、4.5cm~5.5cmくらいのところに収まっていれば、早々文句は言われないでしょう。1cm動かせと言われたら、せめて9mm~11mmくらいには収めないと1cmとは言い難いかもしれません。1mm単位の要求があるのだから、その精度で動かす必要があります。操作が難しくなるわけです。いえ、動かすのはパソコンの中のカメラですから、小さい数字を与えればいいじゃない、と思うわけですが、これがまた微々たる数字なのです。0.001とか、そういう数字なわけです。これを2乗3乗するような計算が入ると0.000001とかになります。ここまでくると、いかにパソコンといえど計算誤差が出てきて、ひょっとすると小さすぎるからゼロだと見なしてしまうかもしれません。カメラとターゲットの距離をそれなりにとっておけば、同じ視線の動き量に対して2とか3くらいの数字を与えてもOKになったりします。これなら2乗3乗しても4とか27とか。人間でさえ困らない数字で処理できます。逆に大きすぎる数字でも困るので、とにかくゼロに近い数字、利き量がほどよい数字で操作をしたいですね。留意してプログラムする必要があります。そんな基本を語ったかと言うと、今までの動作がまさにその問題を受けていたからです。移動距離が短いのに、その距離を1000フレームかけて動けと言われたりしたら、パソコンの計算精度でも無理があります。具体的には、0.2くらいの距離を1000フレームで動けと、つまり1フレームを0.0002で動けという命令になりかねなかった。実はGTAにおいて、カメラの最小動作は確か0.0006くらい。これ以上小さいと、カメラの位置が変わらないんです。変わらないということは、動かして、その位置を取得しても同じ座標のままです。0.0002動けと指示しても、動いたつもりで位置は変わらないから、またそのまま。これがずっと続いてしまい、カメラはまったく動かないことになる。これが動作不良の正体の一つです。いうわけで、数字の最小精度というものを常に意識して下さいね、ってことなのです。カメラのモードは、確か2だと瞬時に、1だと現在地点から指定地点までフェード移動です。先に言っておきますが、このフェードは動作時間が固定のため、どんなに距離が離れていても凄い速度で移動しますし、逆もしかり。代用はとても無理です。いうことで、カメラ位置は瞬時に移動するわけです。移動量は小さくないと滑らかに見えません。滑らかかつスローに動くとなると、1フレーム当たりの移動量はさらに小さくなります。上で述べた問題が生じやすいわけです。繰り返しますが重々留意して下さい。ここで上のグラフを見て下さい。カメラは最初と最後がゆっくりですから、つまり「時間の経過に対して変化量が小さい」と言えます。縦軸を変化量として見るべきだということが分かります。カメラには始点と終点があり、総フレーム数を指定するわけですが、始点と終点が距離に、総フレーム数が時間に関わってくることは言うまでもないでしょう。要するに、始点から終点までの間の、ある座標を与えることが「移動」、総フレームの中の任意のフレームについて処理することが「時間の経過」となります。この解釈に辿り着けるかがカギです。ちなみに、「総フレーム数じゃなくて総動作時間で管理して、そこからフレーム数を割り出した方が、使う人にとっては使いやすいのでは?」と思った人はいませんか?1フレームが何秒になるかなんてわかりにくいのだから、「5秒間かけて動く」という方が確かに使いやすいかもしれませんね。残念ながらGTAはフレームリミットモードというものがあり、これを解除するとパソコンの性能によって1フレーム当たりの時間がかわってきます。オンにすれば一定になるのでしょうが、カクカクし過ぎて撮影には使えません。規定時間が何フレームになるのか事前に知ることができませんから、総フレーム数を指定せざるをえないのです。あとは使用者が試行錯誤で、フレームをいくつくらいにするとそのパソコンでは何秒くらいになるという感覚を身に付けてもらうしかありません。グラフの横軸の端から端が「動作開始~動作終了」を意味し、縦の下から上が「始点・終点」を意味することになります。いうより、自分でそう意味付けします。軌跡は既に「開始直後と終了直前は移動量が小さい」ことを意味する曲線を描いているわけですから、「フレームを一定間隔で進めれば、勝手にフェード移動を行う」ということが分かります。あるフレームにおいての座標は、グラフが描かれる式がありますので、そのあるフレームをχとして、座標がσa(χ)として求まります。いえ、実際には逆です。この曲線を描いてくれる式を見つけ出したのです。この式の通りに座標を求めれば理想の動きになるのです。この式が出てきて「なにこれ」と思ったかもしれませんが、上のグラフはこの式で表されるのです。χを入力すると、グラフのような曲線を描くYを出力してくれる式はないだろうかと、探して見つけてきたわけです。湧いて出たわけではありません。そんな曲線だけからどうやって式が見つかったのかというなら、探し回ったというのが正解です。1で表されることを知ってますよね?じゃあ楕円なら?渦巻きなら?そうやって似たような曲線を探して、ようやく見つけたのがコレというわけです。ことで、どんな風に動かすべきかが分かってきたと思います。次回は実際に値を入れてみて、机上で動作の確認をしてみましょう。