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