何となくお勉強デー
盆休みで呆けた頭を活性化すべく、ビデオ編集作業を再開した。
まあ、不要な部分をカットしたり、怠惰な部分のスピード調整をするくらいなので、
否応無くCG制作が目の前に立ちはだかってくる。
今回のビデオは地下鉄用のトンネル築造の記録なので、またしてもシールド機とシールド
セグメントが関わって来る。
まあ、全体におけるCGの比率はかなり低めなのだが、作品の品質とアピールする上でも
多少インパクトのある映像を作る必要があるのだ。
今回で言うと都会のど真ん中&浅い場所を掘る工事なので、既設埋設物を方々で避けながら
行ったらしい。
それを2次元の図面で説明する方法もあるが、専門的過ぎて素人には全く分からない
映像になってしまう。
それをCGで説明すれば何倍か分かり易い物になるはずなのだ。
ところが、いざ作る段階になると色々と悩ましい事に直面する。
地上のビルや車は添え物なので思い切って簡略化(手抜き?)する事が可能だし、シールド
トンネルも其れなりにデータ量を落とす事もできる。
しかし、穴を掘っているそばからトンネルが出来てゆく様子を表現するのには大量に
作った部品を的確なタイミングで表示したり消したりする必要があるのだ。
これを実現する方法はいくつもあって無手勝流もその1つなのだが、場合によっては
100を超える数の部品に逐一アニメーション設定を加えることを意味する。
正直に言ってやる前から気が遠くなってくるし、後日スピード調整の必要が出てきたら
それを何度も繰り返す事になるのでゾッとする。
そこで便利な道具の登場だ。
幸いにして3DCGソフト『blender』はこの辺の対策として『Python』という
プログラミング言語を使うことが出来る。
今回で言うと『ある条件になったら特定の部品を表示する』だけの初歩的なプログラムで
事足りるが、本来はもっと複雑怪奇な事をクールにこなす事が出来る。
しかし、ここに至ってもまた悩ましい事に直面する。
Pythonを使ってセグメントのON/OFFを制御するプログラムは何年か前にも作った
事があるのだが、残念ながら其のまま動いてくれない。
blenderがバージョンアップを繰り返した際に微妙に仕様変更が加わる為か、Pythonの
仕様変更かは分からないが、『構文が違います』とつっけんどんに言われるのだ・・・
当時も付け焼刃の知識で辛うじて作ったプログラムなので、当然何処がいけないか早々
理解できるはずも無い。
そんな訳で勉強のしなおしをする事にした。
時間が無い時には落ち着いて出来ないが、ある時にやっておけば後から楽が出来るからだ。
先ずは取っ掛かりを探すべくチュートリアルの類を検索したのだが、不思議と見つからない。
仕方が無いのでPython自体のチュートリアルをポチポチと打ち込みながら雰囲気を
確かめていったところ、夜になってようやく古いプログラムレベルでのON/OFFが
出来るようになった。
#
import Blender
CF=Blender.Get("curframe") # 現在のフレームを取得 #
DebugFrame=45 # デバッグ用のフレーム設定 #
ON= (1.0,1.0,1.0) # ONの定義 縮尺=1.0 #
OFF=(0.0,0.0,0.0) # OFFの定義 縮尺=0.0 #
## Object Data Get ##
DSeg01=Blender.Object.Get("Seg001") # オブジェクト"Seg001"をDSeg01に代入 #
DSeg02=Blender.Object.Get("Seg002") # オブジェクト"Seg002"をDSeg02に代入 #
:
: (繰り返しなので途中は省略)
:
DSeg39=Blender.Object.Get("Seg039") # オブジェクト"Seg039"をDSeg40に代入 #
DSeg40=Blender.Object.Get("Seg040") # オブジェクト"Seg040"をDSeg40に代入 #
#########################
# Tunnel ON/OFF #
#########################
if CF < DebugFrame:
DSeg01.size= ON # デバッグフレーム以下では表示 #
elif CF > 249:
DSeg01.size= ON # 249コマ目以降で表示 #
else:
DSeg01.size= OFF # それ以外では非表示 #
if CF < DebugFrame:
DSeg02.size= ON
elif CF > 252:
DSeg02.size= ON
else:
DSeg02.size= OFF
:
: (繰り返しなので途中は省略)
:
if CF < DebugFrame:
DSeg40.size= ON
elif CF > 322:
DSeg40.size= ON
else:
DSeg40.size= OFF
→ test01blen(lzh形式にて圧縮)
→ test01.py
(BlenderはVer2.37 PythonはVer2.4を使用)
まあ、これはこれで良いのだが、セグメントを表示するタイミングを人間が考え、
コマ数を指定する点でスマートではない。
否、元のプログラムを見たところシールド機の位置を取得してどうにかしようと考えた
跡があるのだが、当時は無手勝流で押し通してしまったらしい・・・
そこでプログラムを最初から見直し、『シールド機が通過したらON』になるような
プログラムにしてみた。
また、取得したオブジェクトの代入部分が煩雑だったので配列(?)を使って多少
なりともスッキリさせてみた。
#
import Blender
CF=Blender.Get("curframe") # 現在のフレームを取得 #
SF=10 # デバッグ用の表示コマ #
ON = (1.0,1.0,1.0) # ONの定義 縮尺=1.0 #
OFF= (0.0,0.0,0.0) # OFFの定義 縮尺=0.0 #
Body=Blender.Object.Get("Body") # オブジェクト"Body"を代入 #
BX=Body.LocX # BodyのX座標を取得 #
# 配列DSegに"Seg001"〜"Seg040"を代入#
DSeg = [Blender.Object.Get("Seg001"),
Blender.Object.Get("Seg002"),
:
:(長いので省略)
:
Blender.Object.Get("Seg039"),
Blender.Object.Get("Seg040")]
if CF < SF : DSeg[0].size= ON # 現在のフレームがSF未満なら DSeg[0]をON #
elif DSeg[0].LocX < BX:
DSeg[0].size= ON # BodyのX座標値がDSeg[0]のX座標を超えたらDSeg[0]をON #
else:
DSeg[0].size= OFF # それ以外ならDSeg[0]をOFF #
:
:(長いので省略)
:
if CF < SF : DSeg[39].size= ON # 現在のフレームがSF未満なら DSeg[39]をON #
elif DSeg[39].LocX < BX:
DSeg[39].size= ON # BodyのX座標値がDSeg[39]のX座標を超えたらDSeg[39]をON #
else:
DSeg[39].size= OFF # それ以外ならDSeg[39]をOFF #
→ test02.py
これでシールド機の移動スピードを調整してもセグメントの出現タイミングは調整不要
なので随分と楽になった。
しかし、まだ納得のいかない部分もある。
現在のテストモデルではセグメントを40しか用意していないものの、Pythonにおける
制御部分は手作業で長々と入力する必要がある。
この部分を『for文』とか『While文』で自動化できれば部品数が100でも1000でも
楽に制御できる筈だが、いざやってみると思った事が出来ないのだ。
結局、日付が変わるまであれこれ試してみたが、所詮は付け焼刃の知識・・・
勉強が足りない事を痛感した。
− − − − − − − − − − − − − − − − − − − −
『使えないインターネット』
盆休み中、日記の更新は自宅のADSL回線で行っていたのだが、繋がらない時があった。
回線にノイズが紛れ込んでいる為なのか、地域のADSL回線全体に問題があるのかは
不明だが、開設当初から繋がらない時は徹底的に繋がらないのだ。
我家のADSLは一番安価な1Mbpsなので接続スピードが遅いのは納得できるのだが、
調べ物をしたい時などに何時間も繋がらないと存在意義が怪しくなってくる。
それこそ『光回線に変更しろ!と、いう暗黙の圧力では?』と冗談の1つも言いたくなる。
使えないと言えば昨日は一日中ブログの更新が出来なかったのには面食らった。
当初はブログサービスを提供してくれているTeacupのサーバーメンテナンスにより
夜までには復帰するはずだったのだが、トラブルが発生したらしく夜中になっても
復旧しなかったらしい。
まあ、基本的な文章はテキスト打ちをして自分のWebSiteにアップしているので
レンタルblogは、あくまでも補助に過ぎない。
しかし、Blog版のみにリンクをしている人や携帯電話からアクセスしている人も
多いのでおざなりにする訳には行かない。
そんな訳でデータが飛ばずに復旧した事に一先ず胸を撫で下ろした次第だ。
去年の今日、
一昨年今日
(2006.08.22)