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 /**** JointDef ****/
22 %extend b2JointDef {
23 public:
24     %pythoncode %{
25         def to_kwargs(self):
26             """
27             Returns a dictionary representing this joint definition
28             """
29             def is_prop(attr):
30                 try:
31                     is_property = isinstance(getattr(cls, attr), property)
32                 except AttributeError:
33                     return False
34 
35                 return is_property and attr not in skip_props
36 
37             skip_props = ['anchor', 'anchorA', 'anchorB', 'axis']
38             cls = type(self)
39             return {attr: getattr(self, attr)
40                     for attr in dir(self)
41                     if is_prop(attr)
42                     }
43     %}
44 }
45 
46 /**** Joint ****/
47 %extend b2Joint {
48 public:
49     %pythoncode %{
50     __eq__ = b2JointCompare
51     __ne__ = lambda self,other: not b2JointCompare(self,other)
52 
53     # Read-only
54     next = property(__GetNext, None)
55     bodyA = property(__GetBodyA, None)
56     bodyB = property(__GetBodyB, None)
57     type = property(__GetType, None)
58     active = property(__IsActive, None)
59     anchorB = property(__GetAnchorB, None)
60     anchorA = property(__GetAnchorA, None)
61     collideConnected = property(__GetCollideConnected, None)
62 
63     def getAsType(self):
64         """
65         Backward compatibility
66         """
67         return self
68     %}
69 
70 }
71 
72 %rename(__GetNext) b2Joint::GetNext;
73 %rename(__GetBodyA) b2Joint::GetBodyA;
74 %rename(__GetBodyB) b2Joint::GetBodyB;
75 %rename(__GetType) b2Joint::GetType;
76 %rename(__IsActive) b2Joint::IsActive;
77 %rename(__GetAnchorA) b2Joint::GetAnchorA;
78 %rename(__GetAnchorB) b2Joint::GetAnchorB;
79 %rename(__GetCollideConnected) b2Joint::GetCollideConnected;
80 
81 /**** RevoluteJoint ****/
82 %extend b2RevoluteJoint {
83 public:
84     %pythoncode %{
85 
86         # Read-write properties
87         motorSpeed = property(__GetMotorSpeed, __SetMotorSpeed)
88         upperLimit = property(__GetUpperLimit, lambda self, v: self.SetLimits(self.lowerLimit, v))
89         lowerLimit = property(__GetLowerLimit, lambda self, v: self.SetLimits(v, self.upperLimit))
90         limits = property(lambda self: (self.lowerLimit, self.upperLimit), lambda self, v: self.SetLimits(*v) )
91         motorEnabled = property(__IsMotorEnabled, __EnableMotor)
92         limitEnabled = property(__IsLimitEnabled, __EnableLimit)
93 
94         # Read-only
95         angle = property(__GetJointAngle, None)
96         speed = property(__GetJointSpeed, None)
97 
98         # Write-only
99         maxMotorTorque = property(None, __SetMaxMotorTorque)
100 
101     %}
102 }
103 
104 %rename(__IsMotorEnabled) b2RevoluteJoint::IsMotorEnabled;
105 %rename(__GetUpperLimit) b2RevoluteJoint::GetUpperLimit;
106 %rename(__GetLowerLimit) b2RevoluteJoint::GetLowerLimit;
107 %rename(__GetJointAngle) b2RevoluteJoint::GetJointAngle;
108 %rename(__GetMotorSpeed) b2RevoluteJoint::GetMotorSpeed;
109 %rename(__GetJointSpeed) b2RevoluteJoint::GetJointSpeed;
110 %rename(__IsLimitEnabled) b2RevoluteJoint::IsLimitEnabled;
111 %rename(__SetMotorSpeed) b2RevoluteJoint::SetMotorSpeed;
112 %rename(__EnableLimit) b2RevoluteJoint::EnableLimit;
113 %rename(__SetMaxMotorTorque) b2RevoluteJoint::SetMaxMotorTorque;
114 %rename(__EnableMotor) b2RevoluteJoint::EnableMotor;
115 
116 /**** WheelJoint ****/
117 %extend b2WheelJoint {
118 public:
119     %pythoncode %{
120 
121         # Read-write properties
122         motorSpeed = property(__GetMotorSpeed, __SetMotorSpeed)
123         motorEnabled = property(__IsMotorEnabled, __EnableMotor)
124         maxMotorTorque = property(__GetMaxMotorTorque, __SetMaxMotorTorque)
125         springFrequencyHz = property(__GetSpringFrequencyHz , __SetSpringFrequencyHz)
126         springDampingRatio = property(__GetSpringDampingRatio , __SetSpringDampingRatio)
127 
128         # Read-only
129         speed = property(__GetJointSpeed, None)
130         translation = property(__GetJointTranslation, None)
131 
132     %}
133 }
134 
135 %rename(__IsMotorEnabled) b2WheelJoint::IsMotorEnabled;
136 %rename(__GetMotorSpeed) b2WheelJoint::GetMotorSpeed;
137 %rename(__GetJointSpeed) b2WheelJoint::GetJointSpeed;
138 %rename(__GetJointTranslation) b2WheelJoint::GetJointTranslation;
139 %rename(__IsLimitEnabled) b2WheelJoint::IsLimitEnabled;
140 %rename(__SetMotorSpeed) b2WheelJoint::SetMotorSpeed;
141 %rename(__GetSpringFrequencyHz) b2WheelJoint::GetSpringFrequencyHz;
142 %rename(__SetSpringFrequencyHz) b2WheelJoint::SetSpringFrequencyHz;
143 %rename(__GetSpringDampingRatio) b2WheelJoint::GetSpringDampingRatio;
144 %rename(__SetSpringDampingRatio) b2WheelJoint::SetSpringDampingRatio;
145 %rename(__GetMaxMotorTorque) b2WheelJoint::GetMaxMotorTorque;
146 %rename(__SetMaxMotorTorque) b2WheelJoint::SetMaxMotorTorque;
147 %rename(__EnableMotor) b2WheelJoint::EnableMotor;
148 
149 /**** PrismaticJoint ****/
150 %extend b2PrismaticJoint {
151 public:
152     %pythoncode %{
153 
154         # Read-write properties
155         motorSpeed = property(__GetMotorSpeed, __SetMotorSpeed)
156         motorEnabled = property(__IsMotorEnabled, __EnableMotor)
157         limitEnabled = property(__IsLimitEnabled, __EnableLimit)
158         upperLimit = property(__GetUpperLimit, lambda self, v: self.SetLimits(self.lowerLimit, v))
159         lowerLimit = property(__GetLowerLimit, lambda self, v: self.SetLimits(v, self.upperLimit))
160         limits = property(lambda self: (self.lowerLimit, self.upperLimit), lambda self, v: self.SetLimits(*v) )
161         maxMotorForce = property(__GetMaxMotorForce, __SetMaxMotorForce)
162 
163         # Read-only
164         translation = property(__GetJointTranslation, None)
165         speed = property(__GetJointSpeed, None)
166 
167     %}
168 }
169 
170 %rename(__IsMotorEnabled) b2PrismaticJoint::IsMotorEnabled;
171 %rename(__GetMotorSpeed) b2PrismaticJoint::GetMotorSpeed;
172 %rename(__GetJointTranslation) b2PrismaticJoint::GetJointTranslation;
173 %rename(__GetUpperLimit) b2PrismaticJoint::GetUpperLimit;
174 %rename(__GetJointSpeed) b2PrismaticJoint::GetJointSpeed;
175 %rename(__IsLimitEnabled) b2PrismaticJoint::IsLimitEnabled;
176 %rename(__GetLowerLimit) b2PrismaticJoint::GetLowerLimit;
177 %rename(__SetMotorSpeed) b2PrismaticJoint::SetMotorSpeed;
178 %rename(__EnableLimit) b2PrismaticJoint::EnableLimit;
179 %rename(__SetMaxMotorForce) b2PrismaticJoint::SetMaxMotorForce;
180 %rename(__GetMaxMotorForce) b2PrismaticJoint::GetMaxMotorForce;
181 %rename(__EnableMotor) b2PrismaticJoint::EnableMotor;
182 
183 /**** DistanceJoint ****/
184 %extend b2DistanceJoint {
185 public:
186     %pythoncode %{
187 
188         # Read-write properties
189         length = property(__GetLength, __SetLength)
190         frequency = property(__GetFrequency, __SetFrequency)
191         dampingRatio = property(__GetDampingRatio, __SetDampingRatio)
192 
193     %}
194 }
195 
196 %rename(__GetLength) b2DistanceJoint::GetLength;
197 %rename(__GetFrequency) b2DistanceJoint::GetFrequency;
198 %rename(__GetDampingRatio) b2DistanceJoint::GetDampingRatio;
199 %rename(__SetDampingRatio) b2DistanceJoint::SetDampingRatio;
200 %rename(__SetLength) b2DistanceJoint::SetLength;
201 %rename(__SetFrequency) b2DistanceJoint::SetFrequency;
202 
203 /**** RopeJoint ****/
204 %extend b2RopeJoint {
205 public:
206     %pythoncode %{
207 
208         # Read-only properties
209         maxLength = property(__GetMaxLength, None)
210         limitState = property(__GetLimitState, None)
211 
212         # Read-write properties
213 
214     %}
215 }
216 %rename(__GetLimitState) b2RopeJoint::GetLimitState;
217 %rename(__GetMaxLength) b2RopeJoint::GetMaxLength;
218 
219 /**** PulleyJoint ****/
220 %extend b2PulleyJoint {
221 public:
222     %pythoncode %{
223 
224         # Read-only
225         groundAnchorB = property(__GetGroundAnchorB, None)
226         groundAnchorA = property(__GetGroundAnchorA, None)
227         ratio = property(__GetRatio, None)
228         lengthB = length2 = property(__GetLengthB, None)
229         lengthA = length1 = property(__GetLengthA, None)
230 
231     %}
232 }
233 
234 %rename(__GetGroundAnchorB) b2PulleyJoint::GetGroundAnchorB;
235 %rename(__GetGroundAnchorA) b2PulleyJoint::GetGroundAnchorA;
236 %rename(__GetLengthB) b2PulleyJoint::GetLengthB;
237 %rename(__GetLengthA) b2PulleyJoint::GetLengthA;
238 %rename(__GetRatio) b2PulleyJoint::GetRatio;
239 
240 /**** MouseJoint ****/
241 %extend b2MouseJoint {
242 public:
243     %pythoncode %{
244 
245         # Read-write properties
246         maxForce = property(__GetMaxForce, __SetMaxForce)
247         frequency = property(__GetFrequency, __SetFrequency)
248         dampingRatio = property(__GetDampingRatio, __SetDampingRatio)
249         target = property(__GetTarget, __SetTarget)
250 
251     %}
252 }
253 
254 %rename(__GetMaxForce) b2MouseJoint::GetMaxForce;
255 %rename(__GetFrequency) b2MouseJoint::GetFrequency;
256 %rename(__GetDampingRatio) b2MouseJoint::GetDampingRatio;
257 %rename(__GetTarget) b2MouseJoint::GetTarget;
258 %rename(__SetDampingRatio) b2MouseJoint::SetDampingRatio;
259 %rename(__SetTarget) b2MouseJoint::SetTarget;
260 %rename(__SetMaxForce) b2MouseJoint::SetMaxForce;
261 %rename(__SetFrequency) b2MouseJoint::SetFrequency;
262 
263 /**** GearJoint ****/
264 %extend b2GearJoint {
265 public:
266     %pythoncode %{
267         # Read-write properties
268         ratio = property(__GetRatio, __SetRatio)
269 
270     %}
271 }
272 
273 %rename(__GetRatio) b2GearJoint::GetRatio;
274 %rename(__SetRatio) b2GearJoint::SetRatio;
275 
276 /**** WeldJoint ****/
277 %extend b2WeldJoint {
278 }
279 
280 /**** FrictionJoint ****/
281 %extend b2FrictionJoint {
282 public:
283     %pythoncode %{
284         # Read-write properties
285         maxForce = property(__GetMaxForce, __SetMaxForce)
286         maxTorque = property(__GetMaxTorque, __SetMaxTorque)
287     %}
288 }
289 
290 %rename(__GetMaxForce) b2FrictionJoint::GetMaxForce;
291 %rename(__GetMaxTorque) b2FrictionJoint::GetMaxTorque;
292 %rename(__SetMaxTorque) b2FrictionJoint::SetMaxTorque;
293 %rename(__SetMaxForce) b2FrictionJoint::SetMaxForce;
294 
295 /**** Add some of the functionality that Initialize() offers for joint definitions ****/
296 /**** DistanceJointDef ****/
297 %extend b2DistanceJointDef {
298     %pythoncode %{
299         def __update_length(self):
300             if self.bodyA and self.bodyB:
301                 d = self.anchorB - self.anchorA
302                 self.length = d.length
303         def __set_anchorA(self, value):
304             if not self.bodyA:
305                 raise ValueError('bodyA not set.')
306             self.localAnchorA=self.bodyA.GetLocalPoint(value)
307             self.__update_length()
308         def __set_anchorB(self, value):
309             if not self.bodyB:
310                 raise ValueError('bodyB not set.')
311             self.localAnchorB=self.bodyB.GetLocalPoint(value)
312             self.__update_length()
313         def __get_anchorA(self):
314             if not self.bodyA:
315                 raise ValueError('bodyA not set.')
316             return self.bodyA.GetWorldPoint(self.localAnchorA)
317         def __get_anchorB(self):
318             if not self.bodyB:
319                 raise ValueError('bodyB not set.')
320             return self.bodyB.GetWorldPoint(self.localAnchorB)
321 
322         anchorA = property(__get_anchorA, __set_anchorA,
323                 doc="""Body A's anchor in world coordinates.
324                     Getting the property depends on both bodyA and localAnchorA.
325                     Setting the property requires that bodyA be set.""")
326         anchorB = property(__get_anchorB, __set_anchorB,
327                 doc="""Body B's anchor in world coordinates.
328                     Getting the property depends on both bodyB and localAnchorB.
329                     Setting the property requires that bodyB be set.""")
330     %}
331 }
332 
333 %feature("shadow") b2DistanceJointDef::b2DistanceJointDef() %{
334     def __init__(self, **kwargs):
335         _Box2D.b2DistanceJointDef_swiginit(self,_Box2D.new_b2DistanceJointDef())
336         _init_jointdef_kwargs(self, **kwargs)
337         if 'localAnchorA' in kwargs and 'localAnchorB' in kwargs and 'length' not in kwargs:
338             self.__update_length()
339 %}
340 
341 
342 /**** FrictionJointDef ****/
343 %extend b2FrictionJointDef {
344     %pythoncode %{
345         def __set_anchor(self, value):
346             if not self.bodyA:
347                 raise ValueError('bodyA not set.')
348             if not self.bodyB:
349                 raise ValueError('bodyB not set.')
350             self.localAnchorA=self.bodyA.GetLocalPoint(value)
351             self.localAnchorB=self.bodyB.GetLocalPoint(value)
352         def __get_anchor(self):
353             if self.bodyA:
354                 return self.bodyA.GetWorldPoint(self.localAnchorA)
355             if self.bodyB:
356                 return self.bodyB.GetWorldPoint(self.localAnchorB)
357             raise ValueError('Neither body was set; unable to get world point.')
358 
359         anchor = property(__get_anchor, __set_anchor,
360                 doc="""The anchor in world coordinates.
361                     Getting the property depends on either bodyA and localAnchorA or
362                     bodyB and localAnchorB.
363                     Setting the property requires that both bodies be set.""")
364     %}
365 }
366 
367 %feature("shadow") b2FrictionJointDef::b2FrictionJointDef() %{
368     def __init__(self, **kwargs):
369         _Box2D.b2FrictionJointDef_swiginit(self,_Box2D.new_b2FrictionJointDef())
370         _init_jointdef_kwargs(self, **kwargs)
371 %}
372 
373 
374 /**** WheelJointDef ****/
375 %extend b2WheelJointDef {
376     %pythoncode %{
377         def __set_anchor(self, value):
378             if not self.bodyA:
379                 raise ValueError('bodyA not set.')
380             if not self.bodyB:
381                 raise ValueError('bodyB not set.')
382             self.localAnchorA=self.bodyA.GetLocalPoint(value)
383             self.localAnchorB=self.bodyB.GetLocalPoint(value)
384         def __get_anchor(self):
385             if self.bodyA:
386                 return self.bodyA.GetWorldPoint(self.localAnchorA)
387             if self.bodyB:
388                 return self.bodyB.GetWorldPoint(self.localAnchorB)
389             raise ValueError('Neither body was set; unable to get world point.')
390         def __set_axis(self, value):
391             if not self.bodyA:
392                 raise ValueError('bodyA not set.')
393             self.localAxisA=self.bodyA.GetLocalVector(value)
394         def __get_axis(self):
395             if self.bodyA:
396                 return self.bodyA.GetWorldVector(self.localAxisA)
397             raise ValueError('Body A unset; unable to get world vector.')
398 
399         anchor = property(__get_anchor, __set_anchor,
400                 doc="""The anchor in world coordinates.
401                     Getting the property depends on either bodyA and localAnchorA or
402                     bodyB and localAnchorB.
403                     Setting the property requires that both bodies be set.""")
404         axis = property(__get_axis, __set_axis,
405                 doc="""The world translation axis on bodyA.
406                     Getting the property depends on bodyA and localAxisA.
407                     Setting the property requires that bodyA be set.""")
408     %}
409 }
410 %feature("shadow") b2WheelJointDef::b2WheelJointDef() %{
411     def __init__(self, **kwargs):
412         _Box2D.b2WheelJointDef_swiginit(self,_Box2D.new_b2WheelJointDef())
413         _init_jointdef_kwargs(self, **kwargs)
414 %}
415 
416 
417 
418 /**** PrismaticJointDef ****/
419 %extend b2PrismaticJointDef {
420     %pythoncode %{
421         def __set_anchor(self, value):
422             if not self.bodyA:
423                 raise ValueError('bodyA not set.')
424             if not self.bodyB:
425                 raise ValueError('bodyB not set.')
426             self.localAnchorA=self.bodyA.GetLocalPoint(value)
427             self.localAnchorB=self.bodyB.GetLocalPoint(value)
428         def __get_anchor(self):
429             if self.bodyA:
430                 return self.bodyA.GetWorldPoint(self.localAnchorA)
431             if self.bodyB:
432                 return self.bodyB.GetWorldPoint(self.localAnchorB)
433             raise ValueError('Neither body was set; unable to get world point.')
434         def __set_axis(self, value):
435             if not self.bodyA:
436                 raise ValueError('bodyA not set.')
437             self.localAxisA=self.bodyA.GetLocalVector(value)
438         def __get_axis(self):
439             if not self.bodyA:
440                 raise ValueError('Body A unset; unable to get world vector.')
441             return self.bodyA.GetWorldVector(self.localAxisA)
442 
443         anchor = property(__get_anchor, __set_anchor,
444                 doc="""The anchor in world coordinates.
445                     Getting the property depends on either bodyA and localAnchorA or
446                     bodyB and localAnchorB.
447                     Setting the property requires that both bodies be set.""")
448         axis = property(__get_axis, __set_axis,
449                 doc="""The world translation axis on bodyA.
450                     Getting the property depends on bodyA and localAxisA.
451                     Setting the property requires that bodyA be set.""")
452     %}
453 }
454 
455 %feature("shadow") b2PrismaticJointDef::b2PrismaticJointDef() %{
456     def __init__(self, **kwargs):
457         _Box2D.b2PrismaticJointDef_swiginit(self,_Box2D.new_b2PrismaticJointDef())
458         _init_jointdef_kwargs(self, **kwargs)
459         if self.bodyA and self.bodyB and 'referenceAngle' not in kwargs:
460             self.referenceAngle = self.bodyB.angle - self.bodyA.angle
461 %}
462 
463 /**** PulleyJointDef ****/
464 %extend b2PulleyJointDef {
465     %pythoncode %{
466         def __update_length(self):
467             if self.bodyA:
468                 d1 = self.anchorA - self.groundAnchorA
469                 self.lengthA = d1.length
470             if self.bodyB:
471                 d1 = self.anchorB - self.groundAnchorB
472                 self.lengthB = d1.length
473         def __set_anchorA(self, value):
474             if not self.bodyA:
475                 raise ValueError('bodyA not set.')
476             self.localAnchorA=self.bodyA.GetLocalPoint(value)
477             self.__update_length()
478         def __set_anchorB(self, value):
479             if not self.bodyB:
480                 raise ValueError('bodyB not set.')
481             self.localAnchorB=self.bodyB.GetLocalPoint(value)
482             self.__update_length()
483         def __get_anchorA(self):
484             if not self.bodyA:
485                 raise ValueError('bodyA not set.')
486             return self.bodyA.GetWorldPoint(self.localAnchorA)
487         def __get_anchorB(self):
488             if not self.bodyB:
489                 raise ValueError('bodyB not set.')
490             return self.bodyB.GetWorldPoint(self.localAnchorB)
491 
492         anchorA = property(__get_anchorA, __set_anchorA,
493                 doc="""Body A's anchor in world coordinates.
494                     Getting the property depends on both bodyA and localAnchorA.
495                     Setting the property requires that bodyA be set.""")
496         anchorB = property(__get_anchorB, __set_anchorB,
497                 doc="""Body B's anchor in world coordinates.
498                     Getting the property depends on both bodyB and localAnchorB.
499                     Setting the property requires that bodyB be set.""")
500     %}
501 }
502 
503 %feature("shadow") b2PulleyJointDef::b2PulleyJointDef() %{
504     def __init__(self, **kwargs):
505         _Box2D.b2PulleyJointDef_swiginit(self,_Box2D.new_b2PulleyJointDef())
506         _init_jointdef_kwargs(self, **kwargs)
507         self.__init_pulley__(**kwargs)
508 
509     def __init_pulley__(self, anchorA=None, anchorB=None, lengthA=None, lengthB=None, groundAnchorA=None, groundAnchorB=None, maxLengthA=None, maxLengthB=None, ratio=None, **kwargs):
510         lengthA_set, lengthB_set = False, False
511         if anchorA is not None or anchorB is not None:
512             # Some undoing -- if the user specified the length, we might
513             # have overwritten it, so reset it.
514             if lengthA is not None:
515                 self.lengthA = lengthA
516                 lengthA_set = True
517             if lengthB is not None:
518                 self.lengthB = lengthB
519                 lengthB_set = True
520 
521         if anchorA is not None and groundAnchorA is not None and lengthA is None:
522             d1 = self.anchorA - self.groundAnchorA
523             self.lengthA = d1.length
524             lengthA_set = True
525 
526         if anchorB is not None and groundAnchorB is not None and lengthB is None:
527             d2 = self.anchorB - self.groundAnchorB
528             self.lengthB = d2.length
529             lengthB_set=True
530 
531         if ratio is not None:
532             # Ratio too small?
533             assert(self.ratio > globals()['b2_epsilon'])
534             if lengthA_set and lengthB_set and maxLengthA is None and maxLengthB is None:
535                 C = self.lengthA + self.ratio * self.lengthB
536                 self.maxLengthA = C - self.ratio * b2_minPulleyLength
537                 self.maxLengthB = (C - b2_minPulleyLength) / self.ratio
538 %}
539 /*
540 TODO:
541 Note on the above:
542     assert(self.ratio > globals()['b2_epsilon']) # Ratio too small
543 Should really just be:
544     assert(self.ratio > b2_epsilon) # Ratio too small
545 But somehow SWIG is renaming b2_epsilon to FLT_EPSILON after it sees the #define,
546 but does not export the FLT_EPSILON symbol to Python. It then crashes once it reaches
547 this point. So, figure out a way around this, somehow.
548 */
549 
550 
551 /**** RevoluteJointDef ****/
552 %extend b2RevoluteJointDef {
553     %pythoncode %{
554         def __set_anchor(self, value):
555             if not self.bodyA:
556                 raise ValueError('bodyA not set.')
557             if not self.bodyB:
558                 raise ValueError('bodyB not set.')
559             self.localAnchorA=self.bodyA.GetLocalPoint(value)
560             self.localAnchorB=self.bodyB.GetLocalPoint(value)
561         def __get_anchor(self):
562             if self.bodyA:
563                 return self.bodyA.GetWorldPoint(self.localAnchorA)
564             if self.bodyB:
565                 return self.bodyB.GetWorldPoint(self.localAnchorB)
566             raise ValueError('Neither body was set; unable to get world point.')
567         anchor = property(__get_anchor, __set_anchor,
568                 doc="""The anchor in world coordinates.
569                     Getting the property depends on either bodyA and localAnchorA or
570                     bodyB and localAnchorB.
571                     Setting the property requires that both bodies be set.""")
572     %}
573 }
574 
575 %feature("shadow") b2RevoluteJointDef::b2RevoluteJointDef() %{
576     def __init__(self, **kwargs):
577         _Box2D.b2RevoluteJointDef_swiginit(self,_Box2D.new_b2RevoluteJointDef())
578         _init_jointdef_kwargs(self, **kwargs)
579         if self.bodyA and self.bodyB and 'referenceAngle' not in kwargs:
580             self.referenceAngle = self.bodyB.angle - self.bodyA.angle
581 %}
582 
583 /**** WeldJointDef ****/
584 %extend b2WeldJointDef {
585     %pythoncode %{
586         def __set_anchor(self, value):
587             if not self.bodyA:
588                 raise ValueError('bodyA not set.')
589             if not self.bodyB:
590                 raise ValueError('bodyB not set.')
591             self.localAnchorA=self.bodyA.GetLocalPoint(value)
592             self.localAnchorB=self.bodyB.GetLocalPoint(value)
593         def __get_anchor(self):
594             if self.bodyA:
595                 return self.bodyA.GetWorldPoint(self.localAnchorA)
596             if self.bodyB:
597                 return self.bodyB.GetWorldPoint(self.localAnchorB)
598             raise ValueError('Neither body was set; unable to get world point.')
599         anchor = property(__get_anchor, __set_anchor,
600                 doc="""The anchor in world coordinates.
601                     Getting the property depends on either bodyA and localAnchorA or
602                     bodyB and localAnchorB.
603                     Setting the property requires that both bodies be set.""")
604     %}
605 }
606 
607 %feature("shadow") b2WeldJointDef::b2WeldJointDef() %{
608     def __init__(self, **kwargs):
609         _Box2D.b2WeldJointDef_swiginit(self,_Box2D.new_b2WeldJointDef())
610         _init_jointdef_kwargs(self, **kwargs)
611         if self.bodyA and self.bodyB and 'referenceAngle' not in kwargs:
612             self.referenceAngle = self.bodyB.angle - self.bodyA.angle
613 %}
614 
615 /**** Add some of the functionality that Initialize() offers for joint definitions ****/
616 /**** RopeJointDef ****/
617 %extend b2RopeJointDef {
618     %pythoncode %{
619         def __set_anchorA(self, value):
620             if not self.bodyA:
621                 raise ValueError('bodyA not set.')
622             self.localAnchorA=self.bodyA.GetLocalPoint(value)
623         def __set_anchorB(self, value):
624             if not self.bodyB:
625                 raise ValueError('bodyB not set.')
626             self.localAnchorB=self.bodyB.GetLocalPoint(value)
627         def __get_anchorA(self):
628             if not self.bodyA:
629                 raise ValueError('bodyA not set.')
630             return self.bodyA.GetWorldPoint(self.localAnchorA)
631         def __get_anchorB(self):
632             if not self.bodyB:
633                 raise ValueError('bodyB not set.')
634             return self.bodyB.GetWorldPoint(self.localAnchorB)
635 
636         anchorA = property(__get_anchorA, __set_anchorA,
637                 doc="""Body A's anchor in world coordinates.
638                     Getting the property depends on both bodyA and localAnchorA.
639                     Setting the property requires that bodyA be set.""")
640         anchorB = property(__get_anchorB, __set_anchorB,
641                 doc="""Body B's anchor in world coordinates.
642                     Getting the property depends on both bodyB and localAnchorB.
643                     Setting the property requires that bodyB be set.""")
644     %}
645 }
646 
647 %feature("shadow") b2RopeJointDef::b2RopeJointDef() %{
648     def __init__(self, **kwargs):
649         _Box2D.b2RopeJointDef_swiginit(self,_Box2D.new_b2RopeJointDef())
650         _init_jointdef_kwargs(self, **kwargs)
651 %}
652 
653 /**** Add some of the functionality that Initialize() offers for joint definitions ****/
654 /**** MotorJointDef ****/
655 %extend b2MotorJointDef {
656     %pythoncode %{
657 
658     %}
659 }
660 
661 %feature("shadow") b2MotorJointDef::b2MotorJointDef() %{
662     def __init__(self, bodyA=None, bodyB=None, **kwargs):
663         _Box2D.b2MotorJointDef_swiginit(self,_Box2D.new_b2MotorJointDef())
664         _init_jointdef_kwargs(self, bodyA=bodyA, bodyB=bodyB, **kwargs)
665         if bodyA is not None and bodyB is not None:
666             if not kwargs:
667                 self.Initialize(bodyA, bodyB)
668 %}
669 
670 %extend b2MotorJoint {
671 public:
672     %pythoncode %{
673         # Read-write properties
674         maxForce = property(__GetMaxForce, __SetMaxForce)
675         maxTorque = property(__GetMaxTorque, __SetMaxTorque)
676         linearOffset = property(__GetLinearOffset, __SetLinearOffset)
677         angularOffset = property(__GetAngularOffset, __SetAngularOffset)
678     %}
679 }
680 
681 %rename(__GetMaxForce) b2MotorJoint::GetMaxForce;
682 %rename(__SetMaxForce) b2MotorJoint::SetMaxForce;
683 %rename(__GetMaxTorque) b2MotorJoint::GetMaxTorque;
684 %rename(__SetMaxTorque) b2MotorJoint::SetMaxTorque;
685 %rename(__GetLinearOffset) b2MotorJoint::GetLinearOffset;
686 %rename(__SetLinearOffset) b2MotorJoint::SetLinearOffset;
687 %rename(__GetAngularOffset) b2MotorJoint::GetAngularOffset;
688 %rename(__SetAngularOffset) b2MotorJoint::SetAngularOffset;
689 
690 /**** Hide the now useless enums ****/
691 %ignore e_atLowerLimit;
692 %ignore e_atUpperLimit;
693 %ignore e_distanceJoint;
694 %ignore e_equalLimits;
695 %ignore e_frictionJoint;
696 %ignore e_gearJoint;
697 %ignore e_inactiveLimit;
698 %ignore e_lineJoint;
699 %ignore e_mouseJoint;
700 %ignore e_prismaticJoint;
701 %ignore e_pulleyJoint;
702 %ignore e_revoluteJoint;
703 %ignore e_unknownJoint;
704 %ignore e_weldJoint;
705 %ignore e_motorJoint;;
706