chipmunk-ffi 0.0.1 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/VERSION +1 -1
- data/chipmunk-ffi.gemspec +25 -3
- data/lib/chipmunk-ffi.rb +7 -185
- data/lib/chipmunk-ffi/bb.rb +71 -0
- data/lib/chipmunk-ffi/body.rb +171 -0
- data/lib/chipmunk-ffi/core.rb +49 -0
- data/lib/chipmunk-ffi/shape.rb +160 -0
- data/lib/chipmunk-ffi/space.rb +213 -0
- data/lib/chipmunk-ffi/vec2.rb +187 -0
- data/spec/bb_spec.rb +12 -0
- data/spec/body_spec.rb +42 -0
- data/spec/core_spec.rb +16 -0
- data/spec/shape_spec.rb +61 -0
- data/spec/space_spec.rb +11 -0
- data/spec/spec_helper.rb +5 -0
- data/spec/vec2_spec.rb +152 -0
- metadata +23 -4
@@ -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
|