回転もうまくいき、実時間問題もなんとかのりきった。目標としていた「多関節物体」も
どうやらうまくいきそうだ。しかし..... ここでさらに、新たな問題が。 タイトルのとおり、計算が遅い。はっきりいって遅すぎます。 確かに、遅くなる、というのはある程度わかっていたつもりでしたが、ここまでとは....!! (火の玉オブジェクト50個くらい)+(ExtremeShootersの自機 三つ)程度でここまで 重い原因は何か? おそらく一番重いと思われるところは、「物体座標系 → 絶対座標系」の計算部分です。 コードを持ってくると・・・・ procedure TMover.Transform; var temp:TVector; mat:TMatrix; fp:TMover; begin if Self = Movers.SceneFrame then exit; if SceneFrame = nil then exit; temp:=ZeroVector; //(軸ベクトル)×(位置ベクトル)+ (座標軸の位置ベクトル) fp:=Self; mat:=MatrixRotateZ(trunc(fp.Coord.Z)); IncVector(temp,TransformVector(fp.FMoveMent,mat)); IncVector(temp,FPos); //親フレームがNULLになるまでループ while fp.SceneFrame <> nil do begin fp:=fp.SceneFrame; mat:=MatrixRotateZ(trunc(fp.Coord.Z)); IncVector(temp,TransformVector(fp.FMoveMent,mat)); temp:=TransformVector(temp,mat); IncVector(temp,fp.FPos); end; //絶対座標をセット FGPos:=temp; end;この赤で示した部分でしょうね、時間かかってるのは。 ベクトルと行列の合成部分がwhileループ一度につきなんと2回も!! 考えるだけでも恐ろしいですね。ちなみに、このベクトルと行列の合成には 乗算が9回もでてきます。 つまり、浮動小数点の乗算が18回!! これは遅くないほうがおかしいです。しかも、これはまだZ軸回転しか計算していない場合です。 もし、X,Y軸回転も計算しちゃったら.....うーむ。 んじゃ、どうやって高速化を図るかを考えてみます。
まず、一つ目。固定小数点は「もどき」みたいなのをやったことがありますが、その適当なやつでも
浮動少数よりは速かったと思います。もっとちゃんとすればかなりよくなるでしょう。
二つ目。回転角度が0、っていいきってますが、
合成結果が容易に想像できるものはこっちで簡単に処理する、ってなことがいいたいわけです。
実際回転角度0のときは、「1」をかけるだけなので、計算時間の無駄なんです。
三つ目。これはプログラムをごちゃごちゃいじくってるときに出てきた「ゴミ」でしょう。無駄。
四つ目。これができるとかなり速くなりそう。しかし実装は結構面倒くさそう。
まず、「子を多く持つフレーム(ていうか親を持たない)」の順番でオブジェクトをソートして、
位置ベクトルを算出して、自分のIDといっしょにテーブルにいれます。
んで、使うときはテーブルから親のIDを参照して引っ張ってくる、と。
これは、同じ親を持つオブジェクトが多ければ多いほど効果が見込めます。
でも、親を持つオブジェクトが少ないとあまり効果は見込めません。
しかし、いつもやってれば遅くなることはないでしょう。
五つ目。結局は計算をできることならハードウェアに任せよう、ってことです。
しかしこれにはハードウェアがまだ全然そろってきてない、という問題があります。
とはいうものの、僕みたいな高速化のシロートが書いたプログラムよりも、
HELの方が速いかな、という考えです。
六つ目。これは明らかに無理ですね(^^;)
|
※高速化 「速くしたいならループを見直せ」とはよくいったもの。 ループ部分には魔物が住んでいるのです。
|