Commit 6e91cfa4 authored by Viktor Lidholt's avatar Viktor Lidholt

Merge pull request #1623 from vlidholt/master

Fixes touch handling and refactors sprite physics
parents 0442b642 5fa5971b
......@@ -14,6 +14,7 @@ import 'package:box2d/box2d.dart' as box2d;
import 'package:mojo/core.dart';
import 'package:sky_services/media/media.mojom.dart';
import 'package:flutter/animation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/painting.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
......@@ -33,6 +34,7 @@ part 'src/node3d.dart';
part 'src/node_with_size.dart';
part 'src/particle_system.dart';
part 'src/physics_body.dart';
part 'src/physics_debug.dart';
part 'src/physics_joint.dart';
part 'src/physics_node.dart';
part 'src/physics_shape.dart';
......
part of flutter_sprites;
class _PhysicsDebugDraw extends box2d.DebugDraw {
_PhysicsDebugDraw(
box2d.ViewportTransform transform,
this.physicsNode
) : super(transform);
PhysicsNode physicsNode;
PaintingCanvas canvas;
void drawSegment(Vector2 p1, Vector2 p2, box2d.Color3i color) {
Paint paint = new Paint()..color = _toColor(color);
canvas.drawLine(_toPoint(p1), _toPoint(p2), paint);
}
void drawSolidPolygon(
List<Vector2> vertices,
int vertexCount,
box2d.Color3i color
) {
Path path = new Path();
Point pt = _toPoint(vertices[0]);
path.moveTo(pt.x, pt.y);
for (int i = 1; i < vertexCount; i++) {
pt = _toPoint(vertices[i]);
path.lineTo(pt.x, pt.y);
}
Paint paint = new Paint()..color = _toColor(color);
canvas.drawPath(path, paint);
}
void drawCircle(Vector2 center, num radius, box2d.Color3i color, [Vector2 axis]) {
print("drawCircle: $center");
Paint paint = new Paint()
..color = _toColor(color)
..setStyle(ui.PaintingStyle.stroke)
..strokeWidth = 1.0;
canvas.drawCircle(_toPoint(center), _scale(radius), paint);
}
void drawSolidCircle(Vector2 center, num radius, Vector2 axis, box2d.Color3i color) {
Paint paint = new Paint()
..color = _toColor(color);
canvas.drawCircle(_toPoint(center), _scale(radius), paint);
}
void drawPoint(Vector2 point, num radiusOnScreen, box2d.Color3i color) {
drawSolidCircle(point, radiusOnScreen, null, color);
}
void drawParticles(
List<Vector2> centers,
double radius,
List<box2d.ParticleColor> colors,
int count
) {
// TODO: Implement
}
void drawParticlesWireframe(
List<Vector2> centers,
double radius,
List<box2d.ParticleColor> colors,
int count
) {
// TODO: Implement
}
void drawTransform(box2d.Transform xf, box2d.Color3i color) {
drawCircle(xf.p, 0.1, color);
// TODO: Improve
}
void drawStringXY(num x, num y, String s, box2d.Color3i color) {
// TODO: Implement
}
Color _toColor(box2d.Color3i color) {
return new Color.fromARGB(255, color.x, color.y, color.z);
}
Point _toPoint(Vector2 vec) {
return new Point(
vec.x * physicsNode.b2WorldToNodeConversionFactor,
vec.y * physicsNode.b2WorldToNodeConversionFactor
);
}
double _scale(double value) {
return value * physicsNode.b2WorldToNodeConversionFactor;
}
}
......@@ -25,6 +25,14 @@ class PhysicsNode extends Node {
void _init() {
_contactHandler = new _ContactHandler(this);
b2World.setContactListener(_contactHandler);
box2d.ViewportTransform transform = new box2d.ViewportTransform(
new Vector2.zero(),
new Vector2.zero(),
1.0
);
_debugDraw = new _PhysicsDebugDraw(transform, this);
b2World.debugDraw = _debugDraw;
}
box2d.World b2World;
......@@ -35,6 +43,8 @@ class PhysicsNode extends Node {
List<box2d.Body> _bodiesScheduledForDestruction = [];
_PhysicsDebugDraw _debugDraw;
double b2WorldToNodeConversionFactor = 10.0;
Offset get gravity {
......@@ -143,161 +153,8 @@ class PhysicsNode extends Node {
}
void paintDebug(PaintingCanvas canvas) {
Paint shapePaint = new Paint();
shapePaint.setStyle(ui.PaintingStyle.stroke);
shapePaint.strokeWidth = 1.0;
for (box2d.Body body = b2World.bodyList; body != null; body = body.getNext()) {
canvas.save();
Point point = new Point(
body.position.x * b2WorldToNodeConversionFactor,
body.position.y * b2WorldToNodeConversionFactor);
canvas.translate(point.x, point.y);
canvas.rotate(body.getAngle());
if (body.getType() == box2d.BodyType.DYNAMIC) {
if (body.isAwake())
shapePaint.color = new Color(0xff00ff00);
else
shapePaint.color = new Color(0xff666666);
}
else if (body.getType() == box2d.BodyType.STATIC)
shapePaint.color = new Color(0xffff0000);
else if (body.getType() == box2d.BodyType.KINEMATIC)
shapePaint.color = new Color(0xffff9900);
for (box2d.Fixture fixture = body.getFixtureList(); fixture != null; fixture = fixture.getNext()) {
box2d.Shape shape = fixture.getShape();
if (shape.shapeType == box2d.ShapeType.CIRCLE) {
box2d.CircleShape circle = shape;
Point cp = new Point(
circle.p.x * b2WorldToNodeConversionFactor,
circle.p.y * b2WorldToNodeConversionFactor
);
double radius = circle.radius * b2WorldToNodeConversionFactor;
canvas.drawCircle(cp, radius, shapePaint);
} else if (shape.shapeType == box2d.ShapeType.POLYGON) {
box2d.PolygonShape poly = shape;
List<Point> points = [];
for (int i = 0; i < poly.getVertexCount(); i++) {
Vector2 vertex = poly.getVertex(i);
Point pt = new Point(
vertex.x * b2WorldToNodeConversionFactor,
vertex.y * b2WorldToNodeConversionFactor
);
points.add(pt);
}
if (points.length >= 2) {
for (int i = 0; i < points.length; i++) {
canvas.drawLine(points[i], points[(i + 1) % points.length], shapePaint);
}
}
}
}
canvas.restore();
// Draw contacts
for (box2d.ContactEdge edge = body.getContactList(); edge != null; edge = edge.next) {
box2d.Contact contact = edge.contact;
Vector2 cA = new Vector2.zero();
Vector2 cB = new Vector2.zero();
box2d.Fixture fixtureA = contact.fixtureA;
box2d.Fixture fixtureB = contact.fixtureB;
fixtureA.getAABB(contact.getChildIndexA()).getCenterToOut(cA);
fixtureB.getAABB(contact.getChildIndexB()).getCenterToOut(cB);
Point p1 = new Point(
cA.x * b2WorldToNodeConversionFactor,
cA.y * b2WorldToNodeConversionFactor
);
Point p2 = new Point(
cB.x * b2WorldToNodeConversionFactor,
cB.y * b2WorldToNodeConversionFactor
);
shapePaint.color = new Color(0x33ffffff);
canvas.drawLine(p1, p2, shapePaint);
box2d.WorldManifold worldManifold = new box2d.WorldManifold();
contact.getWorldManifold(worldManifold);
shapePaint.color = new Color(0xffffffff);
for (Vector2 pt in worldManifold.points) {
Point pCenter = new Point(
pt.x * b2WorldToNodeConversionFactor,
pt.y * b2WorldToNodeConversionFactor
);
Offset offset = new Offset(
worldManifold.normal.x * 5.0,
worldManifold.normal.y * 5.0
);
Point p2 = pCenter + offset;
Point p1 = new Point(pCenter.x - offset.dx, pCenter.y - offset.dy);
canvas.drawLine(p1, p2, shapePaint);
canvas.drawCircle(pCenter, 5.0, shapePaint);
}
}
// Draw joints
shapePaint.color = new Color(0xff0000ff);
for (box2d.JointEdge edge = body.getJointList(); edge != null; edge = edge.next) {
box2d.Joint joint = edge.joint;
// Make sure we only draw each joint once
if (joint.getBodyB() == body)
continue;
// Get anchor A
Vector2 anchorA = new Vector2.zero();
joint.getAnchorA(anchorA);
Point ptAnchorA = new Point(
anchorA.x * b2WorldToNodeConversionFactor,
anchorA.y * b2WorldToNodeConversionFactor
);
// Get anchor B
Vector2 anchorB = new Vector2.zero();
joint.getAnchorB(anchorB);
Point ptAnchorB = new Point(
anchorB.x * b2WorldToNodeConversionFactor,
anchorB.y * b2WorldToNodeConversionFactor
);
// Get body A position
Point ptBodyA = new Point(
joint.getBodyA().position.x * b2WorldToNodeConversionFactor,
joint.getBodyA().position.y * b2WorldToNodeConversionFactor
);
Point ptBodyB = new Point(
joint.getBodyB().position.x * b2WorldToNodeConversionFactor,
joint.getBodyB().position.y * b2WorldToNodeConversionFactor
);
// Draw the joint depending on type
box2d.JointType type = joint.getType();
if (type == box2d.JointType.WELD || type == box2d.JointType.REVOLUTE) {
// Draw weld joint
canvas.drawCircle(ptAnchorA, 5.0, shapePaint);
canvas.drawLine(ptBodyA, ptAnchorA, shapePaint);
canvas.drawLine(ptAnchorB, ptBodyB, shapePaint);
}
}
}
_debugDraw.canvas = canvas;
b2World.drawDebugData();
}
}
......
......@@ -185,11 +185,11 @@ class SpriteBox extends RenderBox {
}
}
void handleEvent(ui.Event event, _SpriteBoxHitTestEntry entry) {
void handleEvent(InputEvent event, _SpriteBoxHitTestEntry entry) {
if (!attached)
return;
if (event is ui.PointerEvent) {
if (event is PointerInputEvent) {
if (event.type == 'pointerdown') {
// Build list of event targets
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment