[アイデア]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