Skip to content

Commit

Permalink
Added accessors for a Body's velocity_func and position_func.
Browse files Browse the repository at this point in the history
  • Loading branch information
philomory committed Apr 9, 2010
1 parent d9fd07d commit be264bd
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 2 deletions.
62 changes: 60 additions & 2 deletions lib/chipmunk-ffi/body.rb
Expand Up @@ -5,8 +5,8 @@ module CP

class BodyStruct < NiceFFI::Struct
layout(
:bodyVelocityFunc, :cpBodyVelocityFunc,
:bodyPositionFunc, :cpBodyPositionFunc,
:velocity_func, :cpBodyVelocityFunc,
:position_func, :cpBodyPositionFunc,
:m, CP_FLOAT,
:m_inv, CP_FLOAT,
:i, CP_FLOAT,
Expand Down Expand Up @@ -54,9 +54,12 @@ def initialize(*args)
when 2
ptr = CP.cpBodyNew(*args)
@struct = BodyStruct.new ptr
set_data_pointer
else
raise "wrong number of args for Body, got #{args.size}, but expected 2"
end
set_default_velocity_lambda
set_default_position_lambda
end

def m
Expand Down Expand Up @@ -194,5 +197,60 @@ def update_position(dt)
CP.cpBodyUpdatePosition(@struct.pointer,dt)
end

def velocity_func
@user_level_velocity_lambda
end

def velocity_func=(l)
@user_level_velocity_lambda = l

# We keep the lambda in an ivar to keep it from being GCed
@body_velocity_lambda = Proc.new do |body_ptr,g,dmp,dt|
body_struct = BodyStruct.new(body_ptr)
obj_id = body_struct.data.get_long(0)
body = ObjectSpace._id2ref(obj_id)
l.call(body,g,dmp,dt)
end
@struct.velocity_func = @body_velocity_lambda
end

def position_func
@user_level_position_lambda
end

def position_func=(l)
@user_level_position_lambda = l

# We keep the lambda in an ivar to keep it from being GCed
@body_position_lambda = Proc.new do |body_ptr,dt|
body_struct = BodyStruct.new(body_ptr)
obj_id = body_struct.data.get_long(0)
body = ObjectSpace._id2ref(obj_id)
l.call(body,dt)
end
@struct.position_func = @body_position_lambda
end

private
def set_data_pointer
mem = FFI::MemoryPointer.new(:long)
mem.put_long 0, object_id
# this is needed to prevent data corruption by GC
@body_pointer = mem
@struct.data = mem
end

def set_default_velocity_lambda
@user_level_velocity_lambda = Proc.new do |body,g,dmp,dt|
body.update_velocity(g,dmp,dt)
end
end

def set_default_position_lambda
@user_level_position_lambda = Proc.new do |body,dt|
body.update_position(dt)
end
end

end
end
44 changes: 44 additions & 0 deletions spec/body_spec.rb
Expand Up @@ -152,5 +152,49 @@
b.v.x.should be_close(0.1,0.001)
b.v.y.should be_close(0,0.001)
end

it 'can get its velocity function' do
b = CP::Body.new(5, 7)
b.apply_impulse(vec2(1,0), ZERO_VEC_2)
b.velocity_func.call(b,vec2(0,0), 0.5, 25)
b.v.x.should be_close(0.1,0.001)
b.v.y.should be_close(0,0.001)
end

it 'can set its velocity function' do
b = CP::Body.new(5, 7)

b.velocity_func = Proc.new do |body,gravity,damping,dt|
d = body.p - vec2(5,5)
g = (d * (-500.0/(d.dot(d))))
body.update_velocity(g,damping,dt)
end

b.velocity_func.call(b,ZERO_VEC_2,0.5,25)
b.v.x.should be_close(1250.0,10)
b.v.y.should be_close(1250.0,10)

end

it 'can get its position function' do
b = CP::Body.new(5, 7)
b.apply_impulse(vec2(1,0), ZERO_VEC_2)
b.position_func.call(b,25)
b.p.x.should be_close(5,0.001)
b.p.y.should be_close(0,0.001)
end

it 'can set its position function' do
b = CP::Body.new(5,7)

b.position_func = Proc.new do |body,dt|
body.p = vec2(5,5)
end

b.position_func.call(b,25)
b.p.should == vec2(5,5)
end



end

0 comments on commit be264bd

Please sign in to comment.