def DrawBodyShape(self, shape, transform, color, selected=False): """ Draw any type of shape. To get rid of these isinstance checks, it's possible to monkey patch each b2Shape to have a specific rendering function. It's probably more Pythonic that way. Same deal with the joints. """ if isinstance(shape, b2PolygonShape): self.DrawPolygon(shape, transform, color) elif isinstance(shape, b2EdgeShape): v1 = b2Mul(transform, shape.vertex1) v2 = b2Mul(transform, shape.vertex2) self.DrawSegment(v1, v2, color) elif isinstance(shape, b2CircleShape): self.DrawSolidCircle(shape, transform, color) elif isinstance(shape, b2LoopShape): vertices = shape.vertices v1 = b2Mul(transform, vertices[-1]) for v2 in vertices: v2 = b2Mul(transform, v2) self.DrawSegment(v1, v2, color) v1 = v2
def DrawShape(self, shape, transform, color, selected=False): """ Draw any type of shape """ cache_hit = False if hash(shape) in self.item_cache: cache_hit = True items = self.item_cache[hash(shape)] items[0].setRotation(transform.angle * 180.0 / b2_pi) if isinstance(shape, b2CircleShape): radius = shape.radius if items[0].radius == radius: center = b2Mul(transform, shape.pos) items[0].setPos(*center) line = items[1] axis = transform.R.x_axis line.setLine(center[0], center[1], (center[0] - radius * axis[0]), (center[1] - radius * axis[1])) else: self._remove_from_cache(shape) cache_hit = False else: items[0].setPos(*transform.position) if not selected or cache_hit: return if selected: color = b2Color(1, 1, 1) temporary = True else: temporary = False if isinstance(shape, b2PolygonShape): self.DrawPolygonShape(shape, transform, color, temporary) elif isinstance(shape, b2EdgeShape): v1 = b2Mul(transform, shape.vertex1) v2 = b2Mul(transform, shape.vertex2) self.DrawSegment(v1, v2, color) elif isinstance(shape, b2CircleShape): self.DrawCircleShape(shape, transform, color, temporary) elif isinstance(shape, b2LoopShape): vertices = shape.vertices v1 = b2Mul(transform, vertices[-1]) for v2 in vertices: v2 = b2Mul(transform, v2) self.DrawSegment(v1, v2, color) v1 = v2
def DrawCircleShape(self, shape, transform, color, temporary=False): center = b2Mul(transform, shape.pos) radius = shape.radius axis = transform.R.x_axis border_color = color.bytes + [255] inside_color = (color / 2).bytes + [127] brush = QtGui.QBrush(QtGui.QColor(*inside_color)) pen = QtGui.QPen(QtGui.QColor(*border_color)) ellipse = self.scene.addEllipse(-radius, -radius, radius * 2, radius * 2, brush=brush, pen=pen) line = self.scene.addLine(center[0], center[1], (center[0] - radius * axis[0]), (center[1] - radius * axis[1]), pen=QtGui.QPen(QColor(255, 0, 0))) ellipse.setPos(*center) ellipse.radius = radius if temporary: self.temp_items.append(ellipse) self.temp_items.append(line) else: self.item_cache[hash(shape)] = [ellipse, line]
def GetWorldPoint(self, point): """ A slower version of b2Body.GetWorldPoint(), however this doesnt require the body to be a real body. Useful for rendering """ xform = b2XForm() xform.R.Set(self.body.angle) xform.position = self.body.position p = b2Mul(xform, point) return p