Ruby-FFIでODEを動かす実験4
それっぽくなってきました。
細かいところでおかしなところありますが、当初イメージしていた形に近づいてきています。
とりあえず動いています。
require 'ffi-ode' require 'ffi-draw_stuff' ODE.dInitODE @world = ODE::World.new do |w| w.gravity = [0,0,-9.8] end @space = ODE::Space.new :Hash @collide = ODE::Collide.new @world, @space ODE::Geom::Plane.new @space, [0.0, 0.0, 1.0, 0] @shapes = [] @shapes << (ODE::Geom::Sphere.new @space do |g| g.radius = 1.0 g.body = ODE::Body.new @world do |b| b.mass.sphere_total = [1.0, g.radius] end g.position = [0,0,10] g.instance_eval do def draw DrawStuff.set_color(1,0,0) DrawStuff.draw_sphere position, rotation, radius end end end) DrawStuff.simulation do |fn| fn.size = "600x400" fn.start = Proc.new { DrawStuff.set_viewpoint [5,0,3], [180,-20,0] } fn.step = Proc.new do |pause| @collide.check @world.step 0.01 if pause == 0 @shapes.each {|shape| shape.draw} end end
APIは元の関数名を変形しています。
たとえば、dBodyGetPosition なら、
第一引数のdBodyIDをクラスメンバーにしておいて、
メソッド名はdBodyを除いたget_positionもしくはaliasとしてpositionでアクセスできるようにしています。
collideは記述が面倒なので、デフォルトは隠しておいて、カスタマイズしたい時はオーバーライドのようにできるようにしたいと思っています。
ひつようなのは、
@collide = ODE::Collide.new @world, @space
@collide.check
だけです。checkは適当にメソッド名付けました。もう少し良いネーミングあれば。。
world,spaceをそれぞれのオブジェクトに渡さないといけないところなんとかなるかなぁ。
ただ、これ以上隠してしまうと使いにくくなりそうなので考えどころです。
あと、DrawStuff.simulationで実行してしまっているが、設定と実行を分けたほうが使いやすいかもしれないです。.simuation書いてから.runで実行とか。