日付け越え。
RIB出力プラグインいじり。というかErlangいじり(^^;
メモ。
count_down(F,N) -> if N > 0 -> io:format(F, "~p ", [N]), count_down(F,N-1); N =< 0 -> N end.てな感じで書くとうまく動くけど、
count_down(F,N) -> if N > 0 -> io:format(F, "~p ", [N]), count_down(F,N-1); end, N.だと何故かダメ。でもコンパイルが通るのが謎。
日付け越え。
RIB出力プラグインいじり。ところが、Erlangの難解な仕様につっかかって死亡。
Erlangでは、一度しか変数に値を代入できず、一度値がセットされた変数は
内容を更新する事ができません。つまり「x=x+1」のようなプログラム言語の
特徴とも言える代入ができないのです。さて、この条件の下、1からnまでの
合計を求めるプログラムはどう書けば良いでしょうか? 答えは10秒後(ぉぃ
TANEも判らなかったので(^^; Webを探ってみた所、
このような参考ページを見つけてみたり。
えーと、関数の再帰呼び出しを使えば良いらしい........................
....................................................................
....................................................................
はぇ? マジっすか?! そんな感じ(笑 あまりにひねりが効きすぎていて、
よく判りませんでしたが、確かに関数の戻り値を「一度だけ代入」して
1からnまでの合計が求められます。という訳で、確かにWingsのソースとか
見てても、再帰呼び出しされているものとかあって、何がなんだか判らない
感じになっていましたが、良く見るとそういう事をしているのかも。
それにしても、こういった基本的な事でもひねりを効かせて書く必要が
ある為、前にも述べましたが 可読性が非常に悪いプログラム言語という
印象を受けるのかも知れません。
ところで、再帰呼び出しを行なうと、普通に考えるとスタックを消費
するのではないかと思うのですが、例えば 入力ファイルに行番号を振りながら
出力する「cat -n」っぽいプログラムを書こうとした時、再帰で番号付け
してしまうと、例えば1000000行のファイルを食わせるとスタックが
オーバーフローして死ぬのでは?という疑問を抱いたり。
で、実験。D言語で以下のようなプログラムを書いてみました。ただし、
何故かgdcでコンパイルすると、標準入力がうまく使えない様で、引数に
ファイル指定した時しかうまく動作しませんでした。
import std.stream; int main(char[][] args) { FileMode fmd ; if( args.length==1 ){ stdin.open(0,fmd.In) ; catn(stdin,1) ; }else{ File infile ; for( int i=1 ; i<args.length ; i++ ){ infile = new File() ; infile.open(args[i],fmd.In) ; catn(infile,1) ; infile.close() ; } } return(0) ; } void catn(File infile, int no) { char[] line ; line=infile.readLine() ; if( infile.eof()==true ) return ; if( line is null ) line="" ; /*** Dのstrema.readLine()の空行に対する謎な振るまい ***/ stdout.printf("%8d : %s\n",no,cast(char*)(line)) ; catn(infile,no+1) ; }
gawk 'BEGIN{for(i=0;i<1000000;i++){print("testlines");}}' > xxx.lst
昼前に起床。
Wings出力のRIBを観察してみたり。
マテリアルの読み込みがうまくできていなかったのを修正したり。
ReadArchive文に食わせるファイル名をダブルクオートで括っていなかったので、
エラーしてました。これで一応テクスチャマップもExportできるように
なりました。
Pixieで赤○白×でずっこかすには、透明属性である_hole_をマテリアル
に指定し、Subdivisionメッシュとして出力したRIBファイルを食わせると
良いらしい。ただ、何故それでずっこけるのかがイマイチ不明。というのも
Subdivision文の正しさが良く判っていないので、文法チェックをすり抜ける
文法間違いなのか、文法は合っているがPixieの対応がまずいのかが
区別できないというのがその理由です。むー。
RIB出力オプションとして、PointsPolygonsで出力してみた所、
法線を一緒に出力するとPixieで文法エラーになるみたい。PointsPolygons出力で
且つ、法線無しだとうまくレンダリングできるRIBファイルが出力されるよう
です。で、法線あり出力が何故文法エラーになるか調べてみたところ、
どうやら頂点リストと頂点法線リストのサイズは同じでなくてはならないようですが、
そうならない場合があり、それを食ったPixieが期待する頂点法線リストのサイズと
異なるといってエラーしているようです。頂点リストと頂点法線リストのサイズが
異なる場合ですが、例えば直方体のようなモデルの場合、頂点数は8個ですが、
頂点法線数はシェーディングの条件によって異なります。スムーズシェーディング
ならば、頂点法線数は頂点数と同じ8個になりますが、フラットシェーディング
の場合は、一つの頂点について共有する面ごとに法線の向きが異なるので、
合計24個必要な事になります。POVでは、頂点も法線も別々にインデックス配列を持って
いるので、頂点と法線の数が異なる場合でもうまく表現できます。RIBでは
そうではないようなので、面が参照する頂点を共有しているかどうかに関係
無く全て展開して、展開した頂点にくくりつけるように法線を並べる必要が
ありそうです。むーん。
ぐうたらTVを見ていたら、いきなりTVが映らなくなったり。いきなりというと
ウソですが、前から少し兆候があって、少し暖めないと画面が出ない状態に
なってました。それが昨日から画面が時々揺れる様になり、今日になって
プツリと音がして切れちゃいました(^^; ブラウン管に全く電気が通っていない
という映らなさかげんで、通電に問題があるだけっぽいので、コネクタとか
接点部分をちょっと触れば直りそうな予感はしなくもありませんが、
もう12年くらい使っているX68kのディスプレイテレビ(ここ4年くらいは
TVとしてのみ活躍)なので、買いかえ時かなぁと思ったりしています。
因みに音だけは出るのですが、絵が出ないTVがこれほど退屈なものだとは
思いませんでした(^^;
Pixieでのレンダリングを実験してみたり。
レイトレースの設定などは手で書きたす必要がありますが、適当に設定して
次のような感じ。法線無しのPointsPolygonなので、よく見るとポリポリしています
(<なんだそれ?)。因みにシェーダーは使用してませんので、RenderManの
特徴を活かしていない使い方になってます(^^;
PointsPolygonを使用すれば、メモリの消費もレンダリング時間もそんなにかから
ないようで、POVのmesh2出力したそれと同じレベルなのかも。これで法線を
うまく出力できれば、POVのそれと同じレベルの変換ができる事になるので、
どうにかしたいなぁと思ったり思わなかったり。因みに、髪の毛は
テクスチャで貼ってみたのですが、透明がうまく透けてくれませんでした。
形状から見ても影ではないので、
以前POVで問題になった、
透明なテクスチャを貼っているのに影はテクスチャを貼ったポリゴンの
形状で出るという問題とは違う模様。
午後もいい時間に起床。
ビルドしたWingsのプラグインソースを眺めてみたり。POV出力のカメラ
は何故かWingsの作業画面の絵よりもカメラが近寄ったアングルでレンダリング
されているような気がする
(以前作画した例)
ので、どのようにカメラ設定を行なっているかを
見てみました。結構面倒な変換を行なっていますが、極座標系の全体座標
変換パラメータを入力として、カメラと注目点の二点に変換しているようです。
しかしながら、これといった不審な点を見つけられず。因みに、RIB変換プラグイン
では、前述の極座標系変換をそのままTranslateやRotateといったモデルビュー
変換につっこんでいるだけという感じ。
そういやPOV変換でlight_source文のライト位置の座標記述で','コンマが
抜けていて、Wingsで変換したPOVファイルのパーサーをうまく書けなかった
点を修正してみたり。
あと、RIB出力プラグインも再コンパイルしてみたり。こちらは特にエラーする
事はありませんでしたが、新しいPixieを使ってのレンダリングができるかどうか
を試してみました。結果、赤○白×でPixieがずっこけてみたり。そもそも
出力しているファイルが正しいのか、Pixieがダメなのかを切り分ける為、
簡単なモデルで試した所、それはうまくレンダリングできる模様。更に調べて
みると、レンダリングできるモデルと赤○白×でずっこけるモデルが存在
する事が判ってみたり。どうやらなにかしらの変換不具合がありそうで、
それを食ったPixieが腹を下してcoredumpという流れにありそうな予感。
ただ、Pixieのコンパイルはうまくいった事が無いのでgdbなどで具体的に死んでいる
場所まで特定できない訳ですが。以前も同じ理由で原因追求は断念したのですが、
Wingsの方で少しモデルを変化させてみて
コケる/コケないの境界を見つけ出せば何かわかるかも。
プラグインをいじってみるという選択肢ができたので、モデル変換でどうにか
対処できるならそれもアリかと。でも、実際のところレンダリングできない
モデルがあるという事よりも、レンダリングにかかる時間の方が問題かも。
レンダリングできるモデルをPixieでレンダリングさせてみたのですが、
驚くほどメモリを食うみたいで、POVのそれに比べると最終的な絵を得るまでの
手番が長くなりそうです。
ハタと思いついて、POVの教科書を眺めてみたり。POVのカメラのパラメータ
である所のangleですが、これはいわゆるfov(field of view)に相当する
ものです。気になったのが、OpenGLでもRIBでも、fovと言えばfovYの事を
指していて、画像の高さに対して働く要素になっています
(以前描いたイメージ図)。所が、
POVの教科書の図では、画像の幅に対して働く要素になっています。POV出力プラグインでは
Fovという変数値をそのままPOVのcameraのangleに指定しています。
fovXのつもりでfovYを入れてしまうと、横長画像では「fovX>fovY」の関係が
必ず成り立ちますので、思ったよりも画面に入る幅が狭くなると推測されます。
という訳で、もしやこれがWingsでPOV出力した時に思ったよりも近寄っている
原因でないかと考えました。
そんな訳で、fovYからfovXを計算する式を立ててプラグインをいじってみたり。
次のような感じ。元のFovがdegreeなので、radianに変換して計算する必要が
あります。
254,255c254 < FovX=(math:atan((math:tan((Fov/2.0)*Ro))*(Width/Height)))*180.0*2.0/math:pi(), < io:format(F, " angle ~p~n",[FovX]), --- > io:format(F, " angle ~p~n",[Fov]),
少し早めに帰着。今日は風が強くて、自転車置き場の自転車がほとんど
全て倒れていたり。
蛍光灯交換。うーん明るい。
以前惨敗したWings3Dのソースからのビルドに再挑戦してみたり。
以下Cygwinは基本的に開発系ツール一式が問題無く使える状態にあるとします。
まずは
Erlangのパッケージダウンロード。
ダウンロードページ
から、WindowsBinary のパッケージアーカイブをダウンロードして、
インストール。この時、「c:/Program Files」の下にインストールしたとき、
Cygwinのbashのパスに/cygdrive/c/Program Files/erl5.4.2.1/binを追加しても
何故か反応しなかったため、/usr/local の下にerl5.4.2.1ディレクトリの
シンボリックリンクを張って/usr/local/erl5.4.2.1/bin にパスを通しました。
次に
ESDLのダウンロードとインストール。
前回惨敗したのは、このESDLというSDLのErlangのラッパーをどうしてもうまく
認識できなかったのが原因でした。で、ESDLのテストなどを実行していて、
以下の様にするとうまく反応しました。
% erl Eshell V5.4.2.1 (abort with ^G) 1> testgl:go().てな感じに実行すればうまくゆきました。前述のlibディレクトリに一式 コピーせず、説明書通りにテストプログラムを実行しても、何故かうまく ゆかなかったのが謎ですが。
accel% diff Makefile.org Makefile 54c54 < mingw32-gcc -I$(ERL_INC) -o $(LIBDIR)/wings_ogla_drv.dll \ --- > gcc -mno-cygwin -I$(ERL_INC) -o $(LIBDIR)/wings_ogla_drv.dll \
% werl -pa c:/tane/develop/work/wings/wings-0.98.26/ebin -run wings_start start_halt
229c229 < L = e3d_vec:norm_cross(Rev, {0.0,1.0,0.0}), --- > L = e3d_vec:norm(e3d_vec:cross(Rev, {0.0,1.0,0.0})), 236c236 < DownN = e3d_vec:norm_cross(Rev, LeftN), --- > DownN = e3d_vec:norm(e3d_vec:cross(Rev, LeftN)),
日付け越え。
蛍光灯が一本切れたままで、しばらく使っていたのですが、ついに残りの
一本が切れてしまい、居間のあかりが無くなって死亡。どうしようもない
ので寝る。
日付け越え。
先日の法線の方向の話。取りあえず3Dの場合は辺の法線を使って
頂点法線と辺法線のなす平面上に経路を乗せれば、取りあえず2Dと
同じ問題までは絞り込めそうな予感。曲線の進行方向に対して右方向(もしくは
左方向)に法線が向くように、曲線上の位置に対する法線を更新していけば
良いのかなぁ。でも、それって凄く重そうな予感が。
後、辺の法線を使用した時、二点の頂点が真逆を向いていて辺法線が0に
の場合に失速するという問題がありそう。でも、極端な話、表向きと裏向き
のポリゴンが隣り合わせにならないと、そういうケースというのは普通には
存在しないと思われる為、その場合は例外的に飛ばないようにコントロール
すれば良さそうな予感。
SAIの6版がリリースされてますが試す事ができず。
普通に目が覚めるも、風邪気味で一日中寝てたり。
サブディビジョン。頂点の法線と重なる直線の交点から適当な円を決めて、
近似できないかと考えて、シンデレラで取りあえず2点について平面作図を行なって
みたのですが、法線が平行の時には当然のことながら、交点が存在する場合
でも、交点からそれぞれの頂点までの距離が同じでないと円周上に乗らないと
いう当然の事に気づいて惨敗。
その後、ベジェ的な物で補完すれば良いのじゃないかと作図を行なって
みました。多少ハンドルの長さを見直す必要がありそうですが、
法線をどんなにいじってもそれなりの結果が得られそうで、3Dへの拡張も
可能そうな予感。新たに増殖させる頂点の位置としては、曲線の長さの
半分の距離の位置を利用し、法線はその位置から二つ頂点法線の混合割合
を求めれば良いのかなぁという感じに考えてみました。テクスチャマッピング
座標も同じような感じで求めるのが良いかなぁと思います。実際うまく
いくかどうかは判りませんが。そんな感じで作図は以下のような感じ。
二点の位置と頂点法線から曲線を補完する図
ベジェ作図がよく判ってないので(シンデレラ自体にはベジェ描画プリミティブは
ありません)ベジェっぽいものになってますが、それはそれとして。
んーー、よく観察してみると、新しく追加する点の法線は良く考えない
とダメな予感。例えば、二点の頂点法線をどちらも左斜め上45度くらいに
設定した時、補完したベジェ曲線はS字型のようになるのですが、
単純に二つの頂点法線を混合率で法線を求めるのでは、曲線のどの点においても
法線は左斜め上45度の方向を向くことになります(平均値を取っている感じなの
で当然です)。でもそれは期待と違う結果になると思います。
所が単純に曲線を微分した傾きベクトルに垂直な
ベクトルを法線にしたとすると、2Dでは二つの方向(表方向と裏方向)、
3Dだと外積ベクトルの元になる平面上のベクトル全てがその答えの対象
となります。という訳で、あんまうまくない予感がしてきました。
はて.......
どんどん具合が悪くなってきて死亡。
日付け越え。
なんだか具合が悪くてすぐ寝たり。
昼頃起床。
すっかりシンデレラにはまっている感じ。点の従属関係がきちんと管理
されている為、正しく描けばマジックハンドのような作図も可能なようです。
点の移動倍率を変更したり、動きを変換したりする作図方法(機械製図の分野
にあてはまるかも知れませんが)について興味が湧き始めている所。そんな感じで
パース作図の例を描いてみました。赤い点を動かせばぐにぐに動かせ
ます。茶色の点は赤い点の従属関係にある点なので動かせません。
画面の外に点が飛んだ時はリロードという事で。
ふむ、でも実際の所、「Windowsだから」という理由以上の根拠って
特に見当たらないのですよね。XboxもWindowsにDirectXだったようにも
思うのですが、あれも、作る所によるといった感じが大きい気がしますし。
色々なソフトメーカーが参入するようなので、その結果によって真価が判ると
いう気もします。どこが作っても同じ感じになるのであれば、共通部分に
問題があるのでしょうし、そうでなければ、作る所によるというのが大きい
のかも知れません。
それよりも、専用開発機材が不要という点はやっぱり大きいところなので
しょうかね。「PCで開発できる」ってPCで開発できなかったの?と逆に
疑問に思ったりしましたが。
朝普通に目が覚めたものの、そのまま二度寝して起きたら昼過ぎ。
サブディビジョン。何か無いかとWebをぐるぐるしていたら、
「
シンデレラ」なる平面作図ソフトの存在を知りました。
リンクしたページはそのソフトを使用して色々な作図の例を示した
ページなのですが、作図された結果をアップレットとして動かしたり
する事ができて、なかなか楽しいです。TANE自身も机上で考えるのに
時々Tgifで作図する事があるのですが、解像度(Tgif上の最小グリッド)
の問題でニ直線の交点から更に線を引く場合など、交点自体がグリッド上
に無い時は微妙にずれてたり、円周上にうまく点が打てないなど難儀な事が
あります。やっぱこういうソフトは存在するんだと思いました。
このシンデレラ上には自己証明機能があるらしく、例えばその作図が一般解
なのか、その図形だけに当てはまる特殊解なのかを検査できるようです。
使う人が使えば、IKの机上検証なんかにも応用できそうな予感。
よくよく調べてみると、シンデレラのソフトは解説本にバンドルされている
ようで、本屋で買えるらしいという事で、散髪のついでに本屋を覗いて
みることに。こういうのに限って見つからないというのがいつものパターン
なのですが、数学分野の書棚であっさり発見。4000円也と普通に買うには
少々高価に感じられるかも知れませんが、そんな事は気にしません。
そんな感じで試してみたり。どうやらJavaで書かれているらしく、JavaVMも
インストールされるのですが、どうも我が家のシステムに既に入っているJavaの
それと相性が良くないようで、描画にマウスカーソルを消すためのゴミが残る
とか、OSを再起動した後、シンデレラを起動するとそのままシステムがハング状態
に陥るとかハマり事がありました。1.4.2のVMを指定してインストールする事で、
OKとなりました。うーむ。
で、早速遊んでみました。基本操作を覚えれば、後はアイコンに出てくる
ツールチップを読めば、大体何をするものなのか判るというシンプルな操作が
良い感じ。後は、作図に必要なコツを少々掴めば結構思い通りに図が描けます。
作図したデータをHTML形式で保存するとJavaアップレットになるようで、
オンラインで操作できる作図データやアニメーション表示という事が行なえるようです。
PostScript形式にも変換できるので、いくつかの画像変換ツールを用いれば、
画像への変換も可能です。GhostScriptを使用して、次のような感じでpng
に変換してみました。
gs -q -dNOPAUSE -dBATCH -sDEVICE=ppm -sOutputFile=- foo.eps | pnmscale -width=320 | pnmtopng.exe > foo.png
日付け越え少し前に帰着。
そういや全然関係無い話ですが、水曜の深夜にやっている「BECK」って
TVアニメ。動きが固い所とかある様にも思うのですが、所どころに
散りばめられた微妙な「間」が個人的に良いなぁと思ったり。そんだけ。
眠くて死亡。
日付け越え前に帰着。
Pixieのサブディビジョンの実装やWingsのスムーズなんかが参考に
なるかな?とソースを見てみたのですがよく判らず。
久しぶりにWingsの新しいの(0.98.26)を入れてみたり。POV出力プラグインを
インストールして実際に出力確認をした所、failしてExportできず。
0.98.22cでは大丈夫だったので、単に対応の問題かも。
問題は、POVプラグインの対応が最近は止まっているという点かもしれませんが。
むーん。
日付け越え。
サブディビジョンを行なう際の、面の曲率を考慮した分割時の
頂点位置の決定について、Webを少し漁ってみたり。毎度の事ながら、
探し方が悪いのか、これっていう感じのは見つけられず。
日付け越え前に帰着。
ポリゴン細分化。やっと理解できたり。というか、正20面体から
球に近似する話を扱っていたのですが、球を近似する前提で話を
しているのを、一般解と混同していた為、訳の判らない事になって
ました(^^; で、一般化された例では、一部具体的なコードが欠けて
いるので、そのままでは使用できず。でも、なんとなくイメージは
判った感じ。
雰囲気としては、
三角ポリゴンの各辺を約半分に分ける点を決めて、その点を繋ぐ
のが分割の基本手順で、
V1 V1 /\ /\ / \ → V12/____\V31 / \ /\ /\ V2/ \ V3 V2/ \/ \V3  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄  ̄ ̄ ̄ ̄V23  ̄ ̄
日付け越え。
赤本に載っているポリゴンの細分化のコードを見ながら机上で作図をして、
どういう事なのか確認してみたり。所が、作図がマズいのか、何か間違っている
のか、細分化される感じにならず。何故これでうまく細分化できるのか
全く理解できないまま、眠くて死亡。
昼前起床。
gcc-3.4.3が出てたのでPPCクロスビルドしてみたり。しばらく終りそうに
ないので、ちょっこりお出かけ。
先日思いついたスキニングのアイデアについて少し考えてみたのですが、
もう一つ問題がある事に気づいたり。変形後の形状を用意したとして、
そうした場合、1自由度の曲げしかうまくゆかない気がしてきました。
例えば、ひじやひざのような個所ならばそれでも良いのですが、
肩の場合、上下に前横と変形後の期待値が非常に多いです。なので、
もうちっとうまい方法でないとダメかも。やっぱ、関節球をブロブの
ようなものでひっつけるのが良いのかなぁ......
あと、ハイポリモデルとローポリモデルの関係について。今の所、
Wings上で作成するのは、ある程度ローポリ寄りのモデルで作成し、
POV出力する際にSubdivisionで細分化モデルにしたものをハイポリと
してレンダラに渡しています。つまり、ハイポリを手で変更する
事は無いというのが現状で、SubdivisionさえWingsの外でできれば
良いという事が言えそうです。問題は、その方法が良くわからないと
いう点なのですが(^^;、赤本に基本的な手法が載っていたのでちょっと
調べてみようと思ったところ。
帰ったらエラーなくgccビルドは終っていたり。make installして
POVRayをクロスコンパイルして、ppcsim上で実行してみた所、
3.4.2よりも0.000112%程度実行命令数が減っていました。実行結果も
一応問題無さげ。
SAIの新版を本格的に使ってみたり。いくつか挙動が不審な点があった
のですが、再現性などがイマイチはっきりしないので、取りあえず
メモ。
昼過ぎ起床。
そういや、gdcで生成した実行バイナリのファイルサイズについて調べて
みました。先日のPNGのラッパー関数を、CとDで使用した場合の差は、以下
のような感じ。
% gcc -DDEBUG -O2 _load_png.c -lpng -o cexe % gdc -O2 load_png.d _load_png.o -lpng -o dexe % ls -l cexe dexe -rwxr-xr-x 1 tane mkgroup 17841 Nov 13 15:51 cexe -rwxr-xr-x 1 tane mkgroup 197747 Nov 13 15:51 dexe % strip cexe.exe dexe.exe % ls -l cexe dexe -rwxr-xr-x 1 tane mkgroup 6656 Nov 13 15:51 cexe -rwxr-xr-x 1 tane mkgroup 97792 Nov 13 15:51 dexe
日付け越え。
PNGローダのテスト。その前にDでファイル操作を行なう方法を調査したり。
色々とハマりましたが、ファイル書き込みは次の様な感じにするのが良いらしい。
因みに、PPMファイルへの書き込みです。
1: import std.stream; : 2: FileMode fmd ; 3: File outfile = new File() ; 4: char[] img=image[0..(width*height*(bpp/8))] ; 5: outfile.create("wtest.ppm",fmd.Out) ; 6: outfile.printf("P6\n%d %d\n255\n",width,height) ; 7: outfile.writeString(img) ; 8: outfile.close() ;
日付け越え。
先日のPNGローダのデバッグ。しょーもない間違いでえらく時間がかかったり。
そのせいで、Dからの使用テストまで到達できず(汗;
日付け越え前に帰着。
テクスチャ読み込み用にPNGロードのラッパーを書いてみたり。
コンパイルできる所までで終了。
日付け越え前に帰着。
OpenGLのマテリアルについて。lib3dsを使用した時は、OpenGLの
glMaterial()にそのまま突っ込める値が取得できたのですが、
POV読みで得た場合は、一連のPOV-finish値とglMaterial()に突っ込む
形式と若干の違いがある為、変換が必要な模様。
しばらく放置しているスキニングについて、ちょいといいかもという
アイデアを思いついたり。基本型を0、変形型を1とした時、その間の変形
係数を回転量を示すクォータニオンと位置の変位で表し、その係数を
全頂点に対して保持するというもの。そもそも放置状態になった理由は、
変形をコントロールするのに、一意のアルゴリズムでは、全ての変形
ケースを表現できないというのが問題だったからです。
以前はこの分割を回転軸からの距離で決めていたのですが、
その方法で得られた変形後の結果は極めて狭いでしか適合しないものでした。
で、今回思いついたのは、変形後の形状と変形前形状との差を
補完する係数を探し出す訳ですから、少なくとも、変形後の形状が
思ったものと違うという事は無いハズという目論みです。
大抵の場合、変形前と変形後の形状は一意に決まっている場合が殆どなので、
その間をどう分割するかというのが今回のアイデアのポイントになると思います。
枯れた言葉で言うならば、モーフィングの一種なのかも知れませんが(^^;
問題は、頂点に係数をくくり付けてしまうと、ローポリモデルで
確認し、ハイポリでその骨格をそのまま使用するという事や、モデル
の差し替えなどができなくなってしまいます。なので、代表頂点を使ったり、
変形影響度を表現するうまい方法を考える必要があるかも。それを
考えると、ハイポリをもっちりもっちりいじる方が楽だったりして。
ほんの少し早めに帰着。
SAIの新しいのをちょっとだけ試してみたり。以前報告したバグについては
修正されている模様。マスクの方が実装されたとの事だったので、少し
試してみたのですが、何か挙動が不審な予感。というか、仕様なのかしら?
マスクを解除すると全面がマスク状態となるようで、自動選択ツールは、
この状態から非マスク領域となる部分を選択する様です。
今までと逆になっており、「マスキング」という直感的意味と合わない
ので混乱しそう。マスクペンとマスク消しゴムも、作業内容の直感と違う記号
(ペンの方が現在のマスクを消す方で、消しゴムの方がマスクを塗る)なので、
気持ち悪さを感じます。まぁ、大抵の場合はマスキングした領域を
反転させるので、それを直接穴をあける領域を作成するようにしたものと
推測されますが、これぁどうでしょう。
あと、手で同じ事をすればできますが、選択領域をレイヤーに自動変換する
パスが無いようなのでちょっと辛いも。
そんな感じ。ちょろっと触った程度なので、まだバグっぽい感じのものは
発見できす。
きょうもダメぽで早めに寝ます(x_x)
風邪気味で一日中寝てたり。
POVパーサー。取りあえずサーフェスだけをOpenGLで表示してみたり。OKそう。
テクスチャや色はどうするか考え中。
どんどん具合が悪くなってきて早めに死亡。SAIの新しいのが出ているのですが、
試せず。
朝から、はす向かいの建物の取り壊し工事を行なっていて、うるさくて起きたり。
POVパーサーの整理の続き。なんとなく形になってきたような予感。
テクスチャーで思い出したのですが、テクスチャマップ表示を行なう事を
考えると、画像ローダのラッパークラスを書く必要がありそうな予感。
Dでは配列の連結を行なう事ができますが、これが便利過ぎてヤバいです。
例えば、読み込む「数(サイズ)」が事前に判っているデータであれば、
データの数が収まるバッファを用意してそこに読み込めば良いです。
POVの場合、mesh2文の頂点データなどは、全体の数が最初に出てきて、
その後に頂点データが続きます。もし予め宣言した数よりも多い場合は、
エラーにするなり読み捨てるなりすれば良い訳です。
逆に、読み込むデータの数が不定の場合、方法としては、挿入可能な
連結リストを使用するか、予め適当なサイズを想定しておき、それを超える場合は
ポインタリストのサイズを拡張するなどの方法が考えられます。
あえて言うなら、前者の方は実装が面倒、後者の方はリストのサイズを
バンドルした構造体で扱い、その構造体を操作する関数を用意する必要が
あるでしょう。で、Dの配列は、
後者のポインタリストを拡張するものに近いと考えられますが、
演算子で連結でき、変更後の配列サイズも.lengthプロパティで
取得できます。言語仕様の範囲で配列サイズの拡張が実装されている
のが良い感じです。
Dでは文字列はchar型の配列なので(即ちCと同じ感じ)、文字列の連結は、
この配列の連結そのものという事のようです。
ただ、JavaのStringクラスの様にコード変換を行ないたい場合など
に比べると、低レベル過ぎるかも知れませんが、その場合は
Stringクラスっぽいものを実装すれば良い訳でして、演算子をオーバーロード
できるDでは、演算子も含めたStringクラスと同等のクラスを実現すること
は可能な範囲内と思われます。
ちょっこり本屋に。「DEATH NOTE (4)」が出てたので買ってみたり。
帰りにゲーセンに寄って、翼神をやってみたり。あー、なんか体が
受け付けないかも。目がチカチカするし、自機が極端に動き過ぎて弾が避け
にくいような感じがしました。
PCアーキテクチャ+WinXP(Embeded)という事らしいのですが、
システムやOSが今回の翼神のデキにどれだけ関係しているのかは
よく判らず。DreamcastもWindowsCE搭載だったように思いますが、
DCはどのゲームを見てもOSがゲームのシステムに影響している感じには
見えませんでしたので、WinXP(Embeded)もそれと同じく大した影響を与えない
とするならば、PC(ハード)アーキテクチャや、それを駆動するドライバの方に
問題があるんじゃと思ったり思わなかったり。本当にPCそのままだと、
あんな感じになりそうですが。
帰ってデスノ読んでぴひゅ〜、こうなるか、そういう感じ。それにしても、
(2)辺りからですが、読むのにスゲー時間がかかります(^^;
だんだんと具合が悪くなってきた。
日付け越え前に帰着。
今日のタモリ倶楽部は鳥瞰図。手描きの立体地図なのですが、
すんげー細かくて驚き。こういうのを専門で描くイラストレーター
の存在を初めて知りました。
POVパーサー整理の続き。テクスチャーどうしようかと考え中。
日付け越え前に帰着。
昨日のPOVパーサーを少し整理してみたり。
昼過ぎ起床。
D言語から、yaccを利用する方法を考えてみたり。
DではCの関数をそのまま利用できると共に、逆にextern(C)宣言された
Dの関数をCからも利用できる事になっています。また、Dで書かれた
Cコンパチ関数の中では普通にDの文法が利用できる為、ガベージコレクタ
などの機能も有効になるハズです。
yaccでは、パース時に文のパターンにマッチした時点でアクションとなる
関数を実行する事で、自前のデータ登録だとか、エラー処理だとかを
行ないます。このアクションで実行する関数をCコンパチのDで書かれた
関数を利用する事で、yaccパーサーを利用して、Dのみで有効なクラス
などで書かれたデータの読み込みが可能ではなかろうか?と考えました。
実際のインプリメントについて考えてみました。例えば、
obj { pos=10,10; speed=0.1 ; }
class CharObj{ int posx,posy ; double speed ; }
obj_primitive : OBJ '{' /* OBJ は "obj"をlexでパースしたものとする */ { newobj = new CharObj() ; } obj_params '}' { List.add(newobj) ; newobj=null ; } obj_params : POS '=' NUM ',' NUM ';' /* POS は "pos"をlexでパースしたものとする */ { newobj.setpos($3,$5) ; } | SPEED '=' NUM ';' /* SPEED は "speed"をlexでパースしたものとする */ { newobj.setspeed($3) ; }
日付け越え前に帰着。
Dのマニュアルを眺めていると、先日のオブジェクトとnullとの比較式で、
「===」が「is」という演算子に変わっているのが判りました。
で、内容をよくよく読んでみると、「==」の方は構造体にしろ、オブジェクト
にしろ、その内容のビットパターンが等しいかどうか
を検査するという事のようで、「is」の方はオブジェクトの参照の同一性
を検査する、というように動作に微妙な差がある事が判りました。
オブジェクト同士を「==」で比較すると、例えば「a == b」の場合「a.opCmp(b)」
のような形に変わって、opCmp()メソッドは
/usr/include/d/object.dを見る感じ、
「return (int)(void *)this - (int)(void *)o;」というような演算
の結果が返されるという事のようです(んー?本当にこれで構造体の内容も
比較できるのか?)。
先日のnullとの比較を「==」で行なうと、nullポインタの内容を引き
出そうとして、Segfaultで死ぬという事みたいです。マニュアルを読む感じでは、
インスタンスの内容比較ができるという様に読めたのですが、
実際にテストコードを書いてみたところ、何故か一致を検出できず。
% cat obj_cmp.d import std.stream; class Test{ int a ; int b ; this(){ a=0 ; b=0 ; } } int main(char[][] args){ Test test_a = new Test() ; Test test_b = null ; printf("step1\n") ; if( test_a is test_b ){ printf(" test_a eq test_b\n") ; } test_b = test_a ; printf("step2\n") ; if( test_a is test_b ){ printf(" test_a eq test_b\n") ; } printf("step3\n") ; test_b = new Test() ; if( test_a is test_b ){ printf(" test_a eq test_b\n") ; } printf("step4\n") ; if( test_a == test_b ){ printf(" *test_a eq *test_b\n") ; } printf("test_a: a=%d, b=%d\n",test_a.a,test_a.b) ; printf("test_b: a=%d, b=%d\n",test_b.a,test_b.b) ; return 0; } % gdc obj_cmp.d % ./a.exe step1 step2 test_a eq test_b step3 step4 test_a: a=0, b=0 test_b: a=0, b=0
int opEquals(Object o) { return this === o; }
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜 注意: クラスオブジェクトへの参照と null を比較するには次のように書きます。 if (a === null) 下のようには書きません: if (a == null) 後者は次のように変換され: if (a.opCmp(null)) opCmp()が仮想関数であった場合失敗します。 〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
日付け越え前に帰着。
風呂を沸かそうと風呂場に入ったらゴキブリの姿が(汗;
しとめてやろうと新聞紙を丸めて叩ける位置に移動するのを伺っていたら、
いきなり動いて湯船の中にポチャって.....うわーん、溜めてあった水を
落とさなくちゃならないやん! それよりも、泳いで出てこようとしていたので、
すかさず放水して溺死させる事に。でもこれがなかなかしつこくて、
数分間 水を浴びせてやっと動かなくなったり。と、思ったらまだ
触覚が動いていたりして、むひーー!。これぁ死なないと判断し、
バスマジックリンを浴びせてやっと動かなくなったり。
割り箸でつまんで厳重に袋詰した後、風呂掃除して、また水溜め直して
ってやってたら、すっかり時間が無くなって死亡。なんてこった。