[アイデア]Easy Rocket インターフェース案
適当に書きながらイメージを固めていきたい。
2D
まずウィンドウの生成と 2D 表示。 とりあえずウィンドウ生成のオプションは置いておく。
requre 'er' screen = ER::Screen.new prim = ER::PrimImage.new screen prim.position = 100,100,0 prim.disp
次のような実装もありかと思うがどうだろう。違うかな。
prim = screen.create_image_prim
3D
次に 3D オブジェクト。
requre 'er' screen = ER::Screen.new model = ER::Model.new screen, data model.position = 100,100,0 model.disp model.anim anim_id
シンプルだけどモデルをグループ分けしてソートしたり、ライティングを考慮してない。あ、視点のコントロールができない。カメラも追加しよう。
requre 'er' screen = ER::Screen.new ot = ER::OT.new screen camera = ER::Camera.new screen.camera = camera model = ER::Model.new data model.position = 100,100,0 model.disp ot.add_obj model ot.disp model.anim anim_id
OT は任意で生成すればいいか。カメラは複数存在する可能性があって、切り替える場合はスクリーンの設定を変更すればよい。
画面分割
画面分割する場合を考えてみる。例えば、画面を上下に分けて対戦できるマリオカートとか、レースゲームのバックミラーのような処理の場合。
まずモデルオブジェクトは複数の画面でもひとつのものを使いまわすべきだろう。む、 カメラと OT はどうだろう。難しい。あくまでクライアントの都合だけで考えよう。そう考えると使いまわせてもいいし、別々のものを使ってもいいがいいかな。
screen1 = ER::Screen.new screen2 = ER::Screen.new ot = ER::OT.new screen1
あ、これだと OT が使いまわせない。そうか、 OT と Model はポリモルフィズムというやつでないとダメだ。 2D プリミティブもこの「描画オブジェクト」の仲間だ。スクリーンがこの仲間に入るかどうかは微妙。
screen1 = ER::Screen.new screen2 = ER::Screen.new ot = ER::OT.new screen1.add_obj ot screen2.add_obj ot
とすればいいか。以下のように続けて、
camera1 = ER::Camera.new screen1.camera = camera1 camera2 = ER::Camera.new screen2.camera = camera2
カメラはこれで OK 。ひとつのカメラを使ってもよい。
model = ER::Model.new data model.position = 100,100,0 model.disp ot.add_obj model ot.disp
ここまではいいか。いや、よくないな。ウィンドウがひとつなのか複数なのかが明示されていない。
win = ER::Window.new screen1 = ER::Screen.new win, rect screen2 = ER::Screen.new win, rect
のようにすればいいか。 Window.new は省略できる方向で。
OT 単位でソート
次に OT 単位で描画の優先順位を設定することについて考えてみる。
screen = ER::Screen.new ot1 = ER::OT.new ot2 = ER::OT.new screen.add_obj ot1 screen.add_obj ot2 ot1.z = 0 ot2.z = 1 #ot1.position = 0,0,0 #ot2.position = 0,0,1
単にこれでいいか。
OT を省略
screen = ER::Screen.new prim = ER::PrimImage.new screen prim.disp
最初にこう書いたけど、これまでの考察で行くと次のようにならなければいけない。
screen = ER::Screen.new prim = ER::PrimImage.new prim.disp screen.add_obj screen
前者の方がいい気がするが。次のようなパタンもありか。
screen = ER::Screen.new prim = ER::PrimImage.new prim.parent = screen prim.disp
むむむ。こんがらがってきた。親と子は相互リンクだろうか。少なくとも子は親を知っていなければならないはず。子オブジェクトから階層関係を考慮してワールド座標を取得するときとか。親は子を知る必要があるだろうか。描画プライオリティは階層関係を超えて設定したいから内部的には描画オブジェクト自体から……まあ複雑な話は考えてもあまりあてにならないからいいか。
下の図を考えていたら気づいたが、描画プライオリティは階層関係を超えてはいけない。スクリーン内に描画されたウィンドウの表示順序を帰るときに不便だし、そもそも OT の意味がない。
クラス階層図
これまでの考察を踏まえると、こんな感じだろうか。
DrawObject(OT) …… position(x,y,z),disp,hide | +--DrawPrim …… size(w,h,d) | +--Window | +--Screen …… camera | +--Prim2D | | | +--PrimImage | +--Model3D
この中で new の引数に parent をとれないのは Window だけ。Window 生成の省略系があるからその限りではないか。
省略なし
win = Window.new nil screen = Screen.new win prim = PrimImage.new screen
win 省略
screen = Screen.new prim = PrimImage.new screen
ただ実際はスクリーンサイズくらいは設定したい。
screen = Screen.new 640,400 prim = PrimImage.new screen
としたいけど確か Ruby でこういうのできない。
def ER.CreateScreen w,h,x=nil,y,nil screen = Screen.new DefaultWindow,640,400 end
を用意しておいて、
screen = CreateScreen 640,400 prim = PrimImage.new screen
とすればいいか。
これは画像表示 new にも言える事だな。難しい。
まとめ 1( 間違い版 )
2D プリミティブ表示。
requre 'er' screen = ER::CreateScreen 640,400 prim = ER::PrimImage.new screen prim.position = 100,100,0 prim.disp
3D モデル表示。disp はデフォルトでいいか。
requre 'er' camera = ER::Camera.new screen = ER::CreateScreen 640,400 screen.camera = camera ot = ER::OT.new screen model = ER::Model.new ot model.position = 100,100,100 model.anim anim_id
次に画面分割。あれ、このクラス構造だとダメだ。むむむ。カメラが描画するというアプローチが必要か。いや、スクリーンは描画オブジェクトじゃなくて表示領域だ。ウィンドウとスクリーンを描画オブジェクトに入れたのが間違いだ。
まとめ 2
2D プリミティブ表示修正版。
requre 'er' screen = ER::CreateScreen 640,400 prim = ER::PrimImage.new prim.position = 100,100,0 screen.add_obj prim
3D モデル表示修正版。
requre 'er' camera = ER::Camera.new screen = ER::CreateScreen 640,400 screen.camera = camera ot = ER::OT.new screen.add_obj ot model = ER::Model.new ot model.position = 100,100,100 model.anim anim_id
画面分割
win = ER::Window.new screen1 = ER::Screen.new win, 640,400 screen2 = ER::Screen.new win, 640,400 ot = ER::OT.new nil screen1.add_obj ot screen2.add_obj ot camera1 = ER::Camera.new camera2 = ER::Camera.new screen.camera1 = camera1 screen.camera2 = camera2 model = ER::Model.new ot model.position = 100,100,100 model.anim anim_id
--
あ、ライトを忘れてた。ライトはカメラと同じようにスクリーンに追加すればよさそうだ。ただライトは複数設定することができる。
light1 = ER::Light.new light2 = ER::Light.new screen.lights << light1 screen.lights << light2
こういう書き方できただろうか。
screen.push_light light1 screen.push_light light2
ダメならこれで。
クラス階層図 ( 修正版 )
Window Screen …… camera,lights DrawObject(OT) …… position(x,y,z),disp,hide | +--Prim2D …… size(w,h) | | | +--PrimImage | +--Model3D