1 /*
2 * pybox2d -- http://pybox2d.googlecode.com
3 *
4 * Copyright (c) 2010 Ken Lauer / sirkne at gmail dot com
5 *
6 * This software is provided 'as-is', without any express or implied
7 * warranty.  In no event will the authors be held liable for any damages
8 * arising from the use of this software.
9 * Permission is granted to anyone to use this software for any purpose,
10 * including commercial applications, and to alter it and redistribute it
11 * freely, subject to the following restrictions:
12 * 1. The origin of this software must not be misrepresented; you must not
13 * claim that you wrote the original software. If you use this software
14 * in a product, an acknowledgment in the product documentation would be
15 * appreciated but is not required.
16 * 2. Altered source versions must be plainly marked as such, and must not be
17 * misrepresented as being the original software.
18 * 3. This notice may not be removed or altered from any source distribution.
19 */
20 
21 //These operators do not work unless explicitly defined like this
22 %ignore operator  + (const b2Vec2& a, const b2Vec2& b);
23 %ignore operator  + (const b2Mat22& A, const b2Mat22& B);
24 %ignore operator  - (const b2Vec2& a, const b2Vec2& b);
25 %ignore operator  * (float32 s, const b2Vec2& a);
26 %ignore operator == (const b2Vec2& a, const b2Vec2& b);
27 
28 %ignore operator * (float32 s, const b2Vec3& a);
29 %ignore operator + (const b2Vec3& a, const b2Vec3& b);
30 %ignore operator - (const b2Vec3& a, const b2Vec3& b);
31 
32 //Since Python (apparently) requires __imul__ to return self,
33 //these void operators will not do. So, rename them, then call them
34 //with Python code, and return self. (see further down in b2Vec2)
35 %rename(__add_vector) b2Vec2::operator += (const b2Vec2& v);
36 %rename(__sub_vector) b2Vec2::operator -= (const b2Vec2& v);
37 %rename(__mul_float ) b2Vec2::operator *= (float32 a);
38 %rename(__add_vector) b2Vec3::operator += (const b2Vec3& v);
39 %rename(__sub_vector) b2Vec3::operator -= (const b2Vec3& v);
40 %rename(__mul_float ) b2Vec3::operator *= (float32 a);
41 
42 /**** Vector classes ****/
43 %extend b2Vec2 {
44 public:
b2Vec2()45     b2Vec2() {
46         return new b2Vec2(0.0f, 0.0f);
47     }
48 
b2Vec2(b2Vec2 & other)49     b2Vec2(b2Vec2& other) {
50         return new b2Vec2(other.x, other.y);
51     }
52 
53     %pythoncode %{
54     __iter__ = lambda self: iter( (self.x, self.y) )
55     __eq__ = lambda self, other: self.__equ(other)
56     __ne__ = lambda self,other: not self.__equ(other)
57     def __repr__(self):
58         return "b2Vec2(%g,%g)" % (self.x, self.y)
59     def __len__(self):
60         return 2
61     def __neg__(self):
62         return b2Vec2(-self.x, -self.y)
63     def copy(self):
64         """
65         Return a copy of the vector.
66         Remember that the following:
67             a = b2Vec2()
68             b = a
69         Does not copy the vector itself, but b now refers to a.
70         """
71         return b2Vec2(self.x, self.y)
72     __copy__ = copy
73 
74     def __iadd__(self, other):
75         self.__add_vector(other)
76         return self
77     def __isub__(self, other):
78         self.__sub_vector(other)
79         return self
80     def __imul__(self, a):
81         self.__mul_float(a)
82         return self
83     def __itruediv__(self, a):
84         self.__div_float(a)
85         return self
86     def __idiv__(self, a):
87         self.__div_float(a)
88         return self
89     def __set(self, x, y):
90         self.x = x
91         self.y = y
92     def __nonzero__(self):
93         return self.x!=0.0 or self.y!=0.0
94 
95     tuple = property(lambda self: (self.x, self.y), lambda self, value: self.__set(*value))
96     length = property(__Length, None)
97     lengthSquared = property(__LengthSquared, None)
98     valid = property(__IsValid, None)
99     skew = property(__Skew, None)
100 
101     %}
102     float32 cross(b2Vec2& other) {
103         return $self->x * other.y - $self->y * other.x;
104     }
105     b2Vec2 cross(float32 s) {
106         return b2Vec2(s * $self->y, -s * $self->x);
107     }
108 
109     float32 __getitem__(int i) {
110         if (i==0)
111             return $self->x;
112         else if (i==1)
113             return $self->y;
114         PyErr_SetString(PyExc_IndexError, "Index must be in (0,1)");
115         return 0.0f;
116     }
117     void __setitem__(int i, float32 value) {
118         if (i==0)
119             $self->x=value;
120         else if (i==1)
121             $self->y=value;
122         else
123             PyErr_SetString(PyExc_IndexError, "Index must be in (0,1)");
124     }
125     bool __equ(b2Vec2& other) {
126         return ($self->x == other.x && $self->y == other.y);
127     }
128     float32 dot(b2Vec2& other) {
129         return $self->x * other.x + $self->y * other.y;
130     }
131     b2Vec2 __truediv__(float32 a) { //python 3k
132         return b2Vec2($self->x / a, $self->y / a);
133     }
134     b2Vec2 __div__(float32 a) {
135         return b2Vec2($self->x / a, $self->y / a);
136     }
137     b2Vec2 __mul__(float32 a) {
138         return b2Vec2($self->x * a, $self->y * a);
139     }
140     b2Vec2 __add__(b2Vec2* other) {
141         return b2Vec2($self->x + other->x, $self->y + other->y);
142     }
143     b2Vec2 __sub__(b2Vec2* other) {
144         return b2Vec2($self->x - other->x, $self->y - other->y);
145     }
146 
147     b2Vec2 __rmul__(float32 a) {
148         return b2Vec2($self->x * a, $self->y * a);
149     }
150     b2Vec2 __rdiv__(float32 a) {
151         return b2Vec2($self->x / a, $self->y / a);
152     }
153     void __div_float(float32 a) {
154         $self->x /= a;
155         $self->y /= a;
156     }
157 }
158 
159 %rename (__Length) b2Vec2::Length;
160 %rename (__LengthSquared) b2Vec2::LengthSquared;
161 %rename (__IsValid) b2Vec2::IsValid;
162 %rename (__Skew) b2Vec2::Skew;
163 
164 %extend b2Vec3 {
165 public:
166     b2Vec3() {
167         return new b2Vec3(0.0f, 0.0f, 0.0f);
168     }
169 
170     b2Vec3(b2Vec3& other) {
171         return new b2Vec3(other.x, other.y, other.z);
172     }
173 
174     b2Vec3(b2Vec2& other) {
175         return new b2Vec3(other.x, other.y, 0.0f);
176     }
177 
178     %pythoncode %{
179     __iter__ = lambda self: iter( (self.x, self.y, self.z) )
180     __eq__ = lambda self, other: (self.x == other.x and self.y == other.y and self.z == other.z)
181     __ne__ = lambda self, other: (self.x != other.x or self.y != other.y or self.z != other.z)
182     def __repr__(self):
183         return "b2Vec3(%g,%g,%g)" % (self.x, self.y, self.z)
184     def __len__(self):
185         return 3
186     def __neg__(self):
187         return b2Vec3(-self.x, -self.y, -self.z)
188     def copy(self):
189         """
190         Return a copy of the vector.
191         Remember that the following:
192             a = b2Vec3()
193             b = a
194         Does not copy the vector itself, but b now refers to a.
195         """
196         return b2Vec3(self.x, self.y, self.z)
197     __copy__ = copy
198     def __iadd__(self, other):
199         self.__add_vector(other)
200         return self
201     def __isub__(self, other):
202         self.__sub_vector(other)
203         return self
204     def __imul__(self, a):
205         self.__mul_float(a)
206         return self
207     def __itruediv__(self, a):
208         self.__div_float(a)
209         return self
210     def __idiv__(self, a):
211         self.__div_float(a)
212         return self
213     def dot(self, v):
214         """
215         Dot product with v (list/tuple or b2Vec3)
216         """
217         if isinstance(v, (list, tuple)):
218             return self.x*v[0] + self.y*v[1] + self.z*v[2]
219         else:
220             return self.x*v.x + self.y*v.y + self.z*v.z
221     def __set(self, x, y, z):
222         self.x = x
223         self.y = y
224         self.z = z
225     def __nonzero__(self):
226         return self.x!=0.0 or self.y!=0.0 or self.z!=0.0
227 
228     tuple = property(lambda self: (self.x, self.y, self.z), lambda self, value: self.__set(*value))
229     length = property(_Box2D.b2Vec3___Length, None)
230     lengthSquared = property(_Box2D.b2Vec3___LengthSquared, None)
231     valid = property(_Box2D.b2Vec3___IsValid, None)
232 
233     %}
234 
235     b2Vec3 cross(b2Vec3& b) {
236         return b2Vec3($self->y * b.z - $self->z * b.y, $self->z * b.x - $self->x * b.z, $self->x * b.y - $self->y * b.x);
237     }
238     float32 __getitem__(int i) {
239         if (i==0)
240             return $self->x;
241         else if (i==1)
242             return $self->y;
243         else if (i==2)
244             return $self->z;
245         PyErr_SetString(PyExc_IndexError, "Index must be in (0,1,2)");
246         return 0.0f;
247     }
248     void __setitem__(int i, float32 value) {
249         if (i==0)
250             $self->x=value;
251         else if (i==1)
252             $self->y=value;
253         else if (i==2)
254             $self->z=value;
255         else
256             PyErr_SetString(PyExc_IndexError, "Index must be in (0,1,2)");
257     }
258     bool __IsValid() {
259         return b2IsValid($self->x) && b2IsValid($self->y) && b2IsValid($self->z);
260     }
261     float32 __Length() {
262         return b2Sqrt($self->x * $self->x + $self->y * $self->y + $self->z * $self->z);
263     }
264     float32 __LengthSquared() {
265         return ($self->x * $self->x + $self->y * $self->y + $self->z * $self->z);
266     }
267     b2Vec3 __truediv__(float32 a) {
268         return b2Vec3($self->x / a, $self->y / a, $self->z / a);
269     }
270     b2Vec3 __div__(float32 a) {
271         return b2Vec3($self->x / a, $self->y / a, $self->z / a);
272     }
273     b2Vec3 __mul__(float32 a) {
274         return b2Vec3($self->x * a, $self->y * a, $self->z * a);
275     }
276     b2Vec3 __add__(b2Vec3* other) {
277         return b2Vec3($self->x + other->x, $self->y + other->y, $self->z + other->z);
278     }
279     b2Vec3 __sub__(b2Vec3* other) {
280         return b2Vec3($self->x - other->x, $self->y - other->y, $self->z - other->z);
281     }
282 
283     b2Vec3 __rmul__(float32 a) {
284         return b2Vec3($self->x * a, $self->y * a, $self->z * a);
285     }
286     b2Vec3 __rdiv__(float32 a) {
287         return b2Vec3($self->x / a, $self->y / a, self->z / a);
288     }
289     void __div_float(float32 a) {
290         $self->x /= a;
291         $self->y /= a;
292         $self->z /= a;
293     }
294 }
295 
296 /**** Mat22 ****/
297 %extend b2Mat22 {
298 public:
299     b2Mat22() {
300         return new b2Mat22(b2Vec2(1.0f, 0.0f), b2Vec2(0.0f, 1.0f));
301     }
302 
303     // backward-compatibility
304     float32 __GetAngle() const
305     {
306         return b2Atan2($self->ex.y, $self->ex.x);
307     }
308 
309     void __SetAngle(float32 angle)
310     {
311         float32 c = cosf(angle), s = sinf(angle);
312         $self->ex.x = c; $self->ey.x = -s;
313         $self->ex.y = s; $self->ey.y = c;
314     }
315 
316     %pythoncode %{
317         # Read-only
318         inverse = property(__GetInverse, None)
319         angle = property(__GetAngle, __SetAngle)
320         ex = property(lambda self: self.col1,
321                       lambda self, v: setattr(self, 'col1', v))
322         ey = property(lambda self: self.col2,
323                       lambda self, v: setattr(self, 'col2', v))
324         set = __SetAngle
325     %}
326     b2Vec2 __mul__(b2Vec2* v) {
327         return b2Vec2($self->ex.x * v->x + $self->ey.x * v->y,
328                       $self->ex.y * v->x + $self->ey.y * v->y);
329     }
330     b2Mat22 __mul__(b2Mat22* m) {
331         return b2Mat22(b2Mul(*($self), m->ex), b2Mul(*($self), m->ey));
332     }
333     b2Mat22 __add__(b2Mat22* m) {
334         return b2Mat22($self->ex + m->ex, $self->ey + m->ey);
335     }
336     b2Mat22 __sub__(b2Mat22* m) {
337         return b2Mat22($self->ex - m->ex, $self->ey - m->ey);
338     }
339     void __iadd(b2Mat22* m) {
340         $self->ex += m->ex;
341         $self->ey += m->ey;
342     }
343     void __isub(b2Mat22* m) {
344         $self->ex -= m->ex;
345         $self->ey -= m->ey;
346     }
347 }
348 
349 %rename(__SetAngle) b2Mat22::Set;
350 %rename(__GetInverse) b2Mat22::GetInverse;
351 %rename(col1) b2Mat22::ex;
352 %rename(col2) b2Mat22::ey;
353 
354 %feature("shadow") b2Mat22::__iadd__ {
355     def __iadd__(self, other):
356         self.__iadd(other)
357         return self
358 }
359 %feature("shadow") b2Mat22::__isub__ {
360     def __iadd__(self, other):
361         self.__iadd(other)
362         return self
363 }
364 
365 /**** Mat33 ****/
366 %extend b2Mat33 {
367 public:
368     b2Mat33() {
369         return new b2Mat33(b2Vec3(1.0f, 0.0f, 0.0f),
370                            b2Vec3(0.0f, 1.0f, 0.0f),
371                            b2Vec3(0.0f, 0.0f, 1.0f));
372     }
373 
374     %pythoncode %{
375         ex = property(lambda self: self.col1, lambda self, v: setattr(self, 'col1', v))
376         ey = property(lambda self: self.col2, lambda self, v: setattr(self, 'col2', v))
377         ez = property(lambda self: self.col3, lambda self, v: setattr(self, 'col3', v))
378     %}
379     b2Vec3 __mul__(b2Vec3& v) {
380         return v.x * $self->ex + v.y * $self->ey + v.z * $self->ez;
381     }
382     b2Mat33 __add__(b2Mat33* other) {
383         return b2Mat33($self->ex + other->ex, $self->ey + other->ey, $self->ez + other->ez);
384     }
385     b2Mat33 __sub__(b2Mat33* other) {
386         return b2Mat33($self->ex - other->ex, $self->ey - other->ey, $self->ez - other->ez);
387     }
388     void __iadd(b2Mat33* other) {
389         $self->ex += other->ex;
390         $self->ey += other->ey;
391         $self->ez += other->ez;
392     }
393     void __isub(b2Mat33* other) {
394         $self->ex -= other->ex;
395         $self->ey -= other->ey;
396         $self->ez -= other->ez;
397     }
398 }
399 
400 %feature("shadow") b2Mat33::__iadd__ {
401     def __iadd__(self, other):
402         self.__iadd(other)
403         return self
404 }
405 %feature("shadow") b2Mat33::__isub__ {
406     def __isub__(self, other):
407         self.__isub(other)
408         return self
409 }
410 
411 %rename(set) b2Mat33::Set;
412 %rename(col1) b2Mat33::ex;
413 %rename(col2) b2Mat33::ey;
414 %rename(col3) b2Mat33::ez;
415 
416 /**** Transform ****/
417 %extend b2Transform {
418 public:
419     b2Rot __get_rotation_matrix() {
420         return $self->q;
421     }
422 
423     %pythoncode %{
424         def __get_angle(self):
425             return self.q.angle
426         def __set_angle(self, angle):
427             self.q.angle = angle
428 
429         def __set_rotation_matrix(self, rot_matrix):
430             self.q.angle = rot_matrix.angle
431 
432         angle = property(__get_angle, __set_angle)
433         R = property(__get_rotation_matrix, __set_rotation_matrix)
434     %}
435 
436     b2Vec2 __mul__(b2Vec2& v) {
437         float32 x = ($self->q.c * v.x - $self->q.s * v.y) + $self->p.x;
438         float32 y = ($self->q.s * v.x + $self->q.c * v.y) + $self->p.y;
439 
440         return b2Vec2(x, y);
441     }
442 }
443 
444 %rename(position) b2Transform::p;
445 
446 /**** Rot ****/
447 %extend b2Rot {
448 public:
449     %pythoncode %{
450         angle = property(__GetAngle, __SetAngle)
451 
452         x_axis = property(GetXAxis, None)
453         y_axis = property(GetYAxis, None)
454 
455     %}
456     b2Vec2 __mul__(b2Vec2& v) {
457         return b2Mul(*($self), v);
458     }
459 }
460 
461 %rename(__SetAngle) b2Rot::Set;
462 %rename(__GetAngle) b2Rot::GetAngle;
463 
464 /**** AABB ****/
465 %rename(__contains__) b2AABB::Contains;
466 %rename(__IsValid) b2AABB::IsValid;
467 %rename(__GetExtents) b2AABB::GetExtents;
468 %rename(__GetCenter) b2AABB::GetCenter;
469 %rename(__GetPerimeter) b2AABB::GetPerimeter;
470 
471 %include "Box2D/Collision/b2Collision.h"
472 
473 %extend b2AABB {
474 public:
475     %pythoncode %{
476         # Read-only
477         valid = property(__IsValid, None)
478         extents = property(__GetExtents, None)
479         center = property(__GetCenter, None)
480         perimeter = property(__GetPerimeter, None)
481 
482     %}
483 
484     bool __contains__(const b2Vec2& point) {
485         //If point is in aabb (including a small buffer around it), return true.
486         if (point.x < ($self->upperBound.x + b2_epsilon) &&
487             point.x > ($self->lowerBound.x - b2_epsilon) &&
488             point.y < ($self->upperBound.y + b2_epsilon) &&
489             point.y > ($self->lowerBound.y - b2_epsilon))
490                 return true;
491         return false;
492     }
493 
494     bool overlaps(const b2AABB& aabb2) {
495         //If aabb and aabb2 overlap, return true. (modified from b2BroadPhase::InRange)
496         b2Vec2 d = b2Max($self->lowerBound - aabb2.upperBound, aabb2.lowerBound - $self->upperBound);
497         return b2Max(d.x, d.y) < 0.0f;
498     }
499 
500 }
501 
502 
503 
504