chipmunk-ffi 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,49 @@
1
+ module CP
2
+ INFINITY = 1.0/0.0
3
+
4
+ attach_variable :cpVersionString, :string
5
+ def self.version
6
+ cpVersionString
7
+ end
8
+ VERSION = version.freeze
9
+
10
+ attach_variable :cp_bias_coef, CP_FLOAT
11
+ def bias_coef
12
+ cp_bias_coef
13
+ end
14
+ def bias_coef=(coef)
15
+ cp_bias_coef = coef
16
+ end
17
+
18
+ attach_variable :cp_collision_slop, CP_FLOAT
19
+ def collision_slop
20
+ cp_collision_slop
21
+ end
22
+ def collision_slop=(slop)
23
+ cp_collision_slop = slop
24
+ end
25
+
26
+ func :cpMomentForCircle, [CP_FLOAT,CP_FLOAT,CP_FLOAT,Vect.by_value], CP_FLOAT
27
+ def moment_for_circle(m,r1,r2,offset)
28
+ cpMomentForCircle(m, r1, r2, offset.struct);
29
+ end
30
+
31
+ func :cpMomentForSegment, [CP_FLOAT,Vect.by_value,Vect.by_value], CP_FLOAT
32
+ def moment_for_segment(m,v1,v2)
33
+ cpMomentForCircle(m, v1.struct, v2.struct)
34
+ end
35
+
36
+ func :cpMomentForPoly, [CP_FLOAT,:int,:pointer,Vect.by_value], CP_FLOAT
37
+ def moment_for_poly(m,verts,offset)
38
+ mem_pointer = FFI::MemoryPointer.new Vect, verts.size
39
+ vert_structs = verts.collect{|s|s.struct}
40
+
41
+ size = Vect.size
42
+ tmp = mem_pointer
43
+ vert_structs.each_with_index {|i, j|
44
+ tmp.send(:put_bytes, 0, i.to_bytes, 0, size)
45
+ tmp += size unless j == vert_structs.length-1 # avoid OOB
46
+ }
47
+ cpMomentForPoly(m, verts.size, mem_pointer, offset.struct)
48
+ end
49
+ end
@@ -0,0 +1,160 @@
1
+ module CP
2
+
3
+ ShapeType = enum(
4
+ :circle_shape,
5
+ :segment_shape,
6
+ :poly_shape,
7
+ :num_shapes
8
+ )
9
+
10
+ callback :cacheData, [:pointer,Vect.by_value,Vect.by_value], BBStruct.by_value
11
+ callback :destroy, [:pointer], :void
12
+ callback :pointQuery, [:pointer,Vect.by_value], :int
13
+ callback :segmentQuery, [:pointer,Vect.by_value,Vect.by_value,:pointer], :void
14
+
15
+ class ShapeClassStruct < NiceFFI::Struct
16
+ layout( :type, ShapeType,
17
+ :cacheData, :pointer,
18
+ :destroy, :pointer,
19
+ :pointQuery, :pointer,
20
+ :segmentQuery, :pointer
21
+ )
22
+ end
23
+
24
+ class ShapeStruct < NiceFFI::Struct
25
+ layout( :klass, :pointer,
26
+ :body, :pointer,
27
+ :bb, BBStruct.by_value,
28
+ :sensor, :int,
29
+ :e, CP_FLOAT,
30
+ :u, CP_FLOAT,
31
+ :surface_v, Vect.by_value,
32
+ :data, :pointer,
33
+ :collision_type, :uint,
34
+ :group, :uint,
35
+ :layers, :int
36
+ )
37
+ end
38
+ class SegmentQueryInfoStruct < NiceFFI::Struct
39
+ layout(:shape, ShapeStruct,
40
+ :t, CP_FLOAT,
41
+ :n, Vect
42
+ )
43
+ end
44
+
45
+ func :cpCircleShapeNew, [BodyStruct,CP_FLOAT,Vect.by_value], ShapeStruct
46
+ func :cpSegmentShapeNew, [BodyStruct,Vect.by_value,Vect.by_value,CP_FLOAT], ShapeStruct
47
+ func :cpPolyShapeNew, [BodyStruct,:int,:pointer,Vect.by_value], ShapeStruct
48
+ func :cpShapeCacheBB, [ShapeStruct], :void
49
+ func :cpResetShapeIdCounter, [], :void
50
+
51
+ module Shape
52
+ attr_reader :struct
53
+
54
+ def body
55
+ # Body.new BodyStruct.new(@struct.body)
56
+ @body
57
+ end
58
+ def body=(new_body)
59
+ @struct.body = new_body.struct.pointer
60
+ @body = new_body
61
+ end
62
+
63
+ def collision_type
64
+ @collType
65
+ end
66
+ def collision_type=(col_type)
67
+ @collType = col_type
68
+ @struct.collision_type = col_type.object_id
69
+ end
70
+
71
+ def group
72
+ @group
73
+ end
74
+ def group=(group_obj)
75
+ @group = group_obj
76
+ @struct.group = group_obj.object_id
77
+ end
78
+
79
+ def layers
80
+ @struct.layers
81
+ end
82
+ def layers=(l)
83
+ @struct.layers = l
84
+ end
85
+
86
+ def bb
87
+ our_bb = @struct.bb
88
+ size = BBStruct.size
89
+ bb_ptr = FFI::MemoryPointer.new size
90
+ bb_ptr.send(:put_bytes, 0, our_bb.to_bytes, 0, size)
91
+ BB.new(BBStruct.new(bb_ptr))
92
+ end
93
+
94
+ def cache_bb
95
+ CP.cpShapeCacheBB(@struct.bb)
96
+ bb
97
+ end
98
+
99
+ def e
100
+ @struct.e
101
+ end
102
+ def e=(new_e)
103
+ @struct.e = new_e
104
+ end
105
+
106
+ def u
107
+ @struct.u
108
+ end
109
+ def u=(new_u)
110
+ @struct.u = new_u
111
+ end
112
+
113
+ def surface_v
114
+ Vec2.new @struct.surface_v
115
+ end
116
+ def surface_v=(new_sv)
117
+ @struct.surface_v = new_sv.struct
118
+ end
119
+
120
+ def self.reset_id_counter
121
+ CP.cpResetShapeIdCounter
122
+ end
123
+
124
+ class Circle
125
+ include Shape
126
+ def initialize(body, rad, offset_vec)
127
+ @body = body
128
+ ptr = CP.cpCircleShapeNew body.struct.pointer, rad, offset_vec.struct
129
+ @struct = ShapeStruct.new ptr
130
+ end
131
+ end
132
+ class Segment
133
+ include Shape
134
+ def initialize(body, v1, v2, r)
135
+ @body = body
136
+ ptr = CP.cpSegmentShapeNew body.struct.pointer, v1.struct, v2.struct, r
137
+ @struct = ShapeStruct.new ptr
138
+ end
139
+ end
140
+ class Poly
141
+ include Shape
142
+ def initialize(body, verts, offset_vec)
143
+ @body = body
144
+ mem_pointer = FFI::MemoryPointer.new Vect, verts.size
145
+ vert_structs = verts.collect{|s|s.struct}
146
+
147
+ size = Vect.size
148
+ tmp = mem_pointer
149
+ vert_structs.each_with_index {|i, j|
150
+ tmp.send(:put_bytes, 0, i.to_bytes, 0, size)
151
+ tmp += size unless j == vert_structs.length-1 # avoid OOB
152
+ }
153
+ ptr = CP.cpPolyShapeNew body.struct.pointer, verts.size, mem_pointer, offset_vec.struct
154
+ @struct = ShapeStruct.new ptr
155
+ end
156
+ end
157
+ end
158
+
159
+
160
+ end
@@ -0,0 +1,213 @@
1
+ module CP
2
+ class CollisionHandlerStruct < NiceFFI::Struct
3
+ layout(
4
+ :a, :uint,
5
+ :b, :uint,
6
+ :begin, :pointer,
7
+ :pre_solve, :pointer,
8
+ :post_solve, :pointer,
9
+ :separate, :pointer,
10
+ :data, :pointer
11
+ )
12
+ end
13
+
14
+ class SpaceStruct < NiceFFI::Struct
15
+ layout( :iterations, :int,
16
+ :elastic_iterations, :int,
17
+ :gravity, Vect.by_value,
18
+ :damping, CP_FLOAT,
19
+ :stamp, :int,
20
+ :static_shapes, :pointer,
21
+ :active_shapes, :pointer,
22
+ :bodies, :pointer,
23
+ :arbiters, :pointer,
24
+ :contact_set, :pointer,
25
+ :constraints, :pointer,
26
+ :coll_func_set, :pointer,
27
+ :default_handler, :pointer,
28
+ :post_step_callbacks, :pointer
29
+ )
30
+ def self.release(ptr)
31
+ CP.cpSpaceFreeChildren(ptr)
32
+ end
33
+ end
34
+
35
+ callback :cpCollisionBeginFunc, [:pointer,:pointer,:pointer], :int
36
+ callback :cpCollisionPreSolveFunc, [:pointer,:pointer,:pointer], :int
37
+ callback :cpCollisionPostSolveFunc, [:pointer,:pointer,:pointer], :int
38
+ callback :cpCollisionSeparateFunc, [:pointer,:pointer,:pointer], :int
39
+
40
+
41
+ func :cpSpaceNew, [], :pointer
42
+ func :cpSpaceFreeChildren, [:pointer], :void
43
+
44
+ func :cpSpaceAddShape, [:pointer, :pointer], :pointer
45
+ func :cpSpaceAddStaticShape, [:pointer, :pointer], :pointer
46
+ func :cpSpaceAddBody, [:pointer, :pointer], :pointer
47
+ func :cpSpaceAddConstraint, [:pointer, :pointer], :pointer
48
+
49
+ func :cpSpaceRemoveShape, [:pointer, :pointer], :void
50
+ func :cpSpaceRemoveStaticShape, [:pointer, :pointer], :void
51
+ func :cpSpaceRemoveBody, [:pointer, :pointer], :void
52
+ func :cpSpaceRemoveConstraint, [:pointer, :pointer], :void
53
+
54
+ func :cpSpaceRehashStatic, [:pointer], :void
55
+ func :cpSpaceStep, [:pointer,:double], :void
56
+ func :cpSpaceResizeActiveHash, [:pointer,CP_FLOAT,:int], :void
57
+ func :cpSpaceResizeStaticHash, [:pointer,CP_FLOAT,:int], :void
58
+
59
+
60
+ # TODO seems like a broken name here
61
+ func :cpSpaceSetDefaultCollisionPairFunc, [:pointer, :uint, :uint,
62
+ :pointer, :pointer, :pointer, :pointer, :pointer], :void
63
+ func :cpSpaceAddCollisionHandler, [:pointer, :uint, :uint,
64
+ :pointer, :pointer, :pointer, :pointer, :pointer], :void
65
+ func :cpSpaceRemoveCollisionHandler, [:pointer, :uint, :uint], :void
66
+ class Space
67
+ attr_reader :struct
68
+ def initialize
69
+ @struct = SpaceStruct.new(CP.cpSpaceNew)
70
+ @static_shapes = []
71
+ @active_shapes = []
72
+ @bodies = []
73
+ @constraints = []
74
+ @blocks = {}
75
+ end
76
+
77
+ def iterations
78
+ @struct.iterations
79
+ end
80
+ def iterations=(its)
81
+ @struct.iterations = its
82
+ end
83
+
84
+ def elastic_iterations
85
+ @struct.elastic_iterations
86
+ end
87
+ def elastic_iterations=(elastic_its)
88
+ @struct.elastic_iterations = elastic_its
89
+ end
90
+
91
+ def damping
92
+ @struct.damping
93
+ end
94
+ def damping=(damp)
95
+ @struct.damping = damp
96
+ end
97
+
98
+ def gravity
99
+ Vec2.new @struct.gravity
100
+ end
101
+ def gravity=(v)
102
+ @struct.gravity = v.struct
103
+ end
104
+
105
+ def add_collision_func(a,b,&block)
106
+ # TODO huh?
107
+ beg = nil
108
+ pre = nil
109
+ post = nil
110
+ sep = nil
111
+ data = block
112
+ a_id = a.object_id
113
+ b_id = b.object_id
114
+ # CP.cpSpaceAddCollisionHandler(@struct.pointer, a_id, b_id,
115
+ # beg,pre,post,sep,data)
116
+ @blocks[[a_id,b_id]] = block
117
+ nil
118
+ end
119
+
120
+ def remove_collision_func(a,b)
121
+ a_id = a.object_id
122
+ b_id = b.object_id
123
+ # CP.cpSpaceRemoveCollisionHandler(@struct.pointer, a_id, b_id)
124
+ @blocks.delete [a_id,b_id]
125
+ nil
126
+ end
127
+
128
+ def set_default_collision_func(&block)
129
+ @blocks[:default] = block
130
+ end
131
+
132
+ def add_shape(shape)
133
+ CP.cpSpaceAddShape(@struct.pointer, shape.struct.pointer)
134
+ @active_shapes << shape
135
+ shape
136
+ end
137
+
138
+ def add_static_shape(shape)
139
+ CP.cpSpaceAddStaticShape(@struct.pointer, shape.struct.pointer)
140
+ @static_shapes << shape
141
+ shape
142
+ end
143
+
144
+ def add_body(body)
145
+ CP.cpSpaceAddBody(@struct.pointer, body.struct.pointer)
146
+ @bodies << body
147
+ body
148
+ end
149
+
150
+ def add_constraint(con)
151
+ CP.cpSpaceAddConstraint(@struct.pointer, con.struct.pointer)
152
+ @constraints << con
153
+ con
154
+ end
155
+
156
+ def remove_shape(shape)
157
+ CP.cpSpaceRemoveShape(@struct.pointer, shape.struct.pointer)
158
+ @active_shapes.delete shape
159
+ shape
160
+ end
161
+
162
+ def remove_static_shape(shape)
163
+ CP.cpSpaceRemoveStaticShape(@struct.pointer, shape.struct.pointer)
164
+ @static_shapes.delete shape
165
+ shape
166
+ end
167
+
168
+ def remove_body(body)
169
+ CP.cpSpaceRemoveBody(@struct.pointer, body.struct.pointer)
170
+ @bodies.delete body
171
+ body
172
+ end
173
+
174
+ def remove_constraint(con)
175
+ CP.cpSpaceRemoveConstraint(@struct.pointer, con.struct.pointer)
176
+ @constraints.delete con
177
+ con
178
+ end
179
+
180
+ def resize_static_hash(dim, count)
181
+ CP.cpSpaceResizeStaticHash @struct.pointer, dim, count
182
+ end
183
+
184
+ def resize_active_hash(dim, count)
185
+ CP.cpSpaceResizeActiveHash @struct.pointer, dim, count
186
+ end
187
+
188
+ def rehash_static
189
+ CP.cpSpaceRehashStatic @struct.pointer
190
+ end
191
+
192
+ def step(dt)
193
+ # CP.cpSpaceStep @struct.pointer, dt
194
+ end
195
+
196
+ def shape_point_query(*args)
197
+ raise "Not Implmented yet"
198
+ end
199
+
200
+ def static_shape_point_query(*args)
201
+ raise "Not Implmented yet"
202
+ end
203
+
204
+ def each_body(&block)
205
+ @bodies.each &block
206
+ # typedef void (*cpSpaceBodyIterator)(cpBody *body, void *data);
207
+ # void cpSpaceEachBody(cpSpace *space, cpSpaceBodyIterator func, void *data);
208
+ end
209
+
210
+
211
+ end
212
+ end
213
+
@@ -0,0 +1,187 @@
1
+ module CP
2
+ class Vect < NiceFFI::Struct
3
+ layout( :x, CP_FLOAT,
4
+ :y, CP_FLOAT )
5
+ end
6
+
7
+ cp_static_inline :cpv, [CP_FLOAT,CP_FLOAT], Vect.by_value
8
+ cp_static_inline :cpvneg, [Vect.by_value], Vect.by_value
9
+ cp_static_inline :cpvadd, [Vect.by_value,Vect.by_value], Vect.by_value
10
+ cp_static_inline :cpvsub, [Vect.by_value,Vect.by_value], Vect.by_value
11
+ cp_static_inline :cpvmult, [Vect.by_value,CP_FLOAT], Vect.by_value
12
+ cp_static_inline :cpvdot, [Vect.by_value,Vect.by_value], Vect.by_value
13
+ cp_static_inline :cpvcross, [Vect.by_value,Vect.by_value], Vect.by_value
14
+
15
+ cp_static_inline :cpvperp, [Vect.by_value], Vect.by_value
16
+ cp_static_inline :cpvrperp, [Vect.by_value], Vect.by_value
17
+ cp_static_inline :cpvproject, [Vect.by_value,Vect.by_value], Vect.by_value
18
+ cp_static_inline :cpvrotate, [Vect.by_value,Vect.by_value], Vect.by_value
19
+ cp_static_inline :cpvunrotate, [Vect.by_value,Vect.by_value], Vect.by_value
20
+
21
+ cp_static_inline :cpvlengthsq, [Vect.by_value], CP_FLOAT
22
+
23
+ cp_static_inline :cpvlerp, [Vect.by_value,Vect.by_value], Vect.by_value
24
+
25
+ cp_static_inline :cpvnormalize, [Vect.by_value], Vect.by_value
26
+ cp_static_inline :cpvnormalize_safe, [Vect.by_value], Vect.by_value
27
+
28
+ cp_static_inline :cpvclamp, [Vect.by_value,Vect.by_value], Vect.by_value
29
+ cp_static_inline :cpvlerpconst, [Vect.by_value,Vect.by_value], Vect.by_value
30
+ cp_static_inline :cpvdist, [Vect.by_value,Vect.by_value], CP_FLOAT
31
+ cp_static_inline :cpvdistsq, [Vect.by_value,Vect.by_value], CP_FLOAT
32
+
33
+ cp_static_inline :cpvnear, [Vect.by_value,Vect.by_value, CP_FLOAT], :int
34
+
35
+ func :cpvlength, [Vect.by_value], CP_FLOAT
36
+ func :cpvforangle, [CP_FLOAT], Vect.by_value
37
+ func :cpvslerp, [Vect.by_value, Vect.by_value, CP_FLOAT], Vect.by_value
38
+ func :cpvslerpconst, [Vect.by_value, Vect.by_value, CP_FLOAT], Vect.by_value
39
+ func :cpvtoangle, [Vect.by_value], CP_FLOAT
40
+ func :cpvstr, [Vect.by_value], :string
41
+
42
+ class Vec2
43
+ attr_accessor :struct
44
+ def initialize(*args)
45
+ case args.size
46
+ when 1
47
+ @struct = args.first
48
+ when 2
49
+ @struct = CP.cpv(*args)
50
+ else
51
+ raise "wrong number of args for Vec, got #{args.size}, but expected 2"
52
+ end
53
+ end
54
+
55
+ def x
56
+ @struct.x
57
+ end
58
+ def x=(new_x)
59
+ raise TypeError "cant't modify frozen object" if frozen?
60
+ @struct.x = new_x
61
+ end
62
+ def y
63
+ @struct.y
64
+ end
65
+ def y=(new_y)
66
+ raise TypeError "cant't modify frozen object" if frozen?
67
+ @struct.y = new_y
68
+ end
69
+
70
+ def self.for_angle(angle)
71
+ Vec2.new CP.cpvforangle(angle)
72
+ end
73
+
74
+ def to_s
75
+ CP.cpvstr @struct
76
+ end
77
+
78
+ def to_angle
79
+ CP.cpvtoangle @struct
80
+ end
81
+
82
+ def to_a
83
+ [@struct.x,@struct.y]
84
+ end
85
+
86
+ def -@
87
+ Vec2.new CP.cpvneg(@struct)
88
+ end
89
+
90
+ def +(other_vec)
91
+ Vec2.new CP.cpvadd(@struct, other_vec.struct)
92
+ end
93
+
94
+ def -(other_vec)
95
+ Vec2.new CP.cpvsub(@struct, other_vec.struct)
96
+ end
97
+
98
+ def *(s)
99
+ Vec2.new CP.cpvmult(@struct, s)
100
+ end
101
+
102
+ def /(s)
103
+ factor = 1.0/s
104
+ Vec2.new CP.cpvmult(@struct, factor)
105
+ end
106
+
107
+ def dot(other_vec)
108
+ CP.cpvdot(@struct, other_vec.struct)
109
+ end
110
+
111
+ def cross(other_vec)
112
+ CP.cpvcross(@struct, other_vec.struct)
113
+ end
114
+
115
+ def perp
116
+ Vec2.new CP.cpvperp(@struct)
117
+ end
118
+
119
+ def rperp
120
+ Vec2.new CP.cpvperp(@struct)
121
+ end
122
+
123
+ def project(other_vec)
124
+ Vec2.new CP.cpvproject(@struct, other_vec.struct)
125
+ end
126
+
127
+ def rotate(other_vec)
128
+ Vec2.new CP.cpvrotate(@struct, other_vec.struct)
129
+ end
130
+
131
+ def unrotate(other_vec)
132
+ Vec2.new CP.cpvunrotate(@struct, other_vec.struct)
133
+ end
134
+
135
+ def lengthsq
136
+ CP.cpvlengthsq(@struct)
137
+ end
138
+
139
+ def lerp(other_vec)
140
+ Vec2.new CP.cpvlerp(@struct, other_vec.struct)
141
+ end
142
+
143
+ def normalize
144
+ Vec2.new CP.cpvnormalize(@struct)
145
+ end
146
+
147
+ def normalize!
148
+ @struct = CP.cpvnormalize(@struct)
149
+ self
150
+ end
151
+
152
+ def normalize_safe
153
+ Vec2.new CP.cpvnormalize_safe(@struct)
154
+ end
155
+
156
+ def clamp(other_vec)
157
+ Vec2.new CP.cpvclamp(@struct)
158
+ end
159
+
160
+ def lerpconst(other_vec)
161
+ Vec2.new CP.cpvlerpconst(@struct)
162
+ end
163
+
164
+ def dist(other_vec)
165
+ CP.cpvdist(@struct)
166
+ end
167
+
168
+ def distsq(other_vec)
169
+ CP.cpvdistsq(@struct)
170
+ end
171
+
172
+ def near?(other_vec, dist)
173
+ delta_v = CP.cpvsub(@struct, other_vec.struct)
174
+ CP.cpvdot(delta_v, delta_v) < dist*dist
175
+ end
176
+
177
+ def length
178
+ CP::cpvlength @struct
179
+ end
180
+
181
+ end
182
+ ZERO_VEC_2 = Vec2.new(0,0).freeze
183
+
184
+ end
185
+ def vec2(x,y)
186
+ CP::Vec2.new x, y
187
+ end