/**在编辑器更改碰撞器Center时*/ public void onEditShapeCenter(object[] args) { Collider2D collider = (Collider2D)args [0]; float cx = (float)args [1]; float cy = (float)args [2]; float oldCX = (float)args[3]; float oldCY = (float)args[4]; b2Fixture[] fixtures = _fixtureDict [collider]; if (fixtures != null) { for (int i = 0; i < fixtures.Length; i++) { b2Fixture fixture = fixtures[i]; b2Shape s = fixture.GetShape(); if (collider is BoxCollider2D) { b2PolygonShape boxShape = s as b2PolygonShape; BoxCollider2D boxColl = collider as BoxCollider2D; boxShape.SetAsOrientedBox(boxColl.size.x * 0.5f, boxColl.size.y * 0.5f, new b2Vec2(cx, cy), 0); scaleShape(boxShape); _body.SetAwake(true); } else if (collider is CircleCollider2D) { b2CircleShape circleShape = s as b2CircleShape; circleShape.SetLocalPosition(new b2Vec2(cx, cy)); scaleShape(circleShape, true); _body.SetAwake(true); } else if (collider is PolygonCollider2D) { b2PolygonShape polyShape = s as b2PolygonShape; PolygonCollider2D polyColl = collider as PolygonCollider2D; List <b2Vec2> vertices = polyShape.GetVertices(); for (int j = 0; j < vertices.Count; j++) { b2Vec2 v = vertices[j]; v.x -= oldCX; v.y -= oldCY; v.x += cx; v.y += cy; } //scaleShape(polyShape); _body.SetAwake(true); } } } }
/**在编辑器更改碰撞器Density时*/ private void onEditColliderDensity(object[] args) { Collider2D collider = (Collider2D)args [0]; float density = (float)args [1]; b2Fixture[] fixtures = _fixtureDict[collider]; if (fixtures != null) { b2Fixture[] nFixtures = new b2Fixture[fixtures.Length]; for (int i = 0; i < fixtures.Length; i++) { b2Fixture fixture = fixtures[i]; b2Shape s = fixture.GetShape(); _body.DestroyFixture(fixture); nFixtures[i] = _body.CreateFixture2(s, density); } _fixtureDict[collider] = nFixtures; _body.SetAwake(true); } }
/**在编辑器更改碰撞器的形状Shape时*/ private void onEditShape(object[] args) { Collider2D collider = (Collider2D)args [0]; b2Fixture[] fixtures = _fixtureDict [collider]; if (collider is BoxCollider2D) { b2Fixture fixture = fixtures[0]; b2Shape s = fixture.GetShape(); float sizeX = (float)args [1]; float sizeY = (float)args [2]; BoxCollider2D boxColl = collider as BoxCollider2D; b2PolygonShape polygon = s as b2PolygonShape; polygon.SetAsOrientedBox(sizeX * 0.5f, sizeY * 0.5f, new b2Vec2(boxColl.offset.x, boxColl.offset.y), 0); scaleShape(polygon); _body.SetAwake(true); } else if (collider is PolygonCollider2D) { Vector2[] points = (Vector2[])args[1]; int len = points.Length; b2Vec2[] vertices = new b2Vec2[len]; for (int i = 0; i < len; i++) { vertices[i] = new b2Vec2(points[i].x, points[i].y); } b2FixtureDef fixtureDef = new b2FixtureDef(); fixtureDef.density = fixtures[0].GetDensity(); fixtureDef.friction = fixtures[0].GetFriction(); fixtureDef.isSensor = fixtures[0].IsSensor(); fixtureDef.restitution = fixtures[0].GetRestitution(); int j = fixtures.Length; while (--j >= 0) { _body.DestroyFixture(fixtures[j]); } b2Separator sep = new b2Separator(); _fixtureDict [collider] = sep.Separate(_body, fixtureDef, vertices, 1); fixtures = _fixtureDict [collider]; for (j = 0; j < fixtures.Length; j++) { scaleShape(fixtures[j].GetShape()); } _body.SetAwake(true); } else if (collider is CircleCollider2D) { b2Fixture fixture = fixtures[0]; float radius = (float)args[1]; float cx = (float)args[2]; float cy = (float)args[3]; b2Shape s = fixture.GetShape(); b2CircleShape circle = s as b2CircleShape; circle.SetRadius(radius); circle.SetLocalPosition(new b2Vec2(cx, cy)); scaleShape(circle); _body.SetAwake(true); } }
public override byte[] Render(bool toRgbArray = false) { if (Viewer == null) { Viewer = new Rendering.Viewer(VIEWPORT_W, VIEWPORT_H); } Viewer.SetBounds(scroll, VIEWPORT_W / SCALE + scroll, 0, VIEWPORT_H / SCALE); Viewer.DrawPolygon(new List <float[]> { new float[] { scroll, 0 }, new float[] { scroll + VIEWPORT_W / SCALE, 0 }, new float[] { scroll + VIEWPORT_W / SCALE, VIEWPORT_H / SCALE }, new float[] { scroll, VIEWPORT_H / SCALE } }).SetColor(0.9f, 0.9f, 1.0f); foreach (var cloud_data in cloud_poly) { var poly = cloud_data.Item1; var pos_data = cloud_data.Item2; if (pos_data.y < scroll / 2) { continue; } if (pos_data.x > scroll / 2 + VIEWPORT_W / SCALE) { continue; } Viewer.DrawPolygon(poly.Select(p => new[] { p[0] + scroll / 2, p[1] }).ToList()).SetColor(1, 1, 1); } foreach (var terrain_data in terrain_poly) { var poly = terrain_data.Item1; var color = terrain_data.Item2; if (poly[1][0] < scroll) { continue; } if (poly[0][0] > scroll + VIEWPORT_W / SCALE) { continue; } Viewer.DrawPolygon(poly).SetColor(color.x, color.y, color.z); } lidar_render = (lidar_render + 1) % 100; int i = lidar_render; if (i < 2 * lidar.Length) { var l = i < lidar.Length ? lidar[i] : lidar[2 * lidar.Length - i - 1]; Viewer.DrawPolyline(new List <float[]> { new float[] { l.P1.x, l.P1.y }, new float[] { l.P2.x, l.P2.y } }).SetColor(1, 0, 0).SetLineWidth(1); } foreach (var obj in drawlist) { for (b2Fixture f = obj.GetFixtureList(); f != null; f = f.GetNext()) { var xform = f.GetBody().GetTransform(); if (f.GetShape() is b2CircleShape) { var shape = (f.GetShape() as b2CircleShape); var customData = (obj.GetUserData() as CustomBodyData); var trans = Utils.b2Mul(xform, shape.m_p); var t = new Rendering.Transform(new float[] { trans[0], trans[1] }); Viewer.DrawCircle(shape.m_radius, 30).SetColor(customData.Color1.x, customData.Color1.y, customData.Color1.z).AddAttr(t); Viewer.DrawCircle(shape.m_radius, 30, false).SetColor(customData.Color2.x, customData.Color2.y, customData.Color2.z).SetLineWidth(2).AddAttr(t); } else { var shape = f.GetShape(); var customData = (obj.GetUserData() as CustomBodyData); var path = shape.GetVertices().Select(v => { var trans = Utils.b2Mul(xform, v); return(new float[] { trans[0], trans[1] }); }).ToList(); Viewer.DrawPolygon(path).SetColor(customData.Color1.x, customData.Color1.y, customData.Color1.z); path.Add(path[0]); Viewer.DrawPolyline(path).SetColor(customData.Color2.x, customData.Color2.y, customData.Color2.z).SetLineWidth(2); } } } var flagy1 = TERRAIN_HEIGHT; var flagy2 = flagy1 + 50 / SCALE; var x = TERRAIN_STEP * 3; Viewer.DrawPolyline(new List <float[]> { new float[] { x, flagy1 }, new float[] { x, flagy2 } }).SetColor(0, 0, 0).SetLineWidth(2); var flagVert = new List <float[]> { new float[] { x, flagy2 }, new float[] { x, flagy2 - 10 / SCALE }, new float[] { x + 25 / SCALE, flagy2 - 5 / SCALE } }; Viewer.DrawPolygon(flagVert).SetColor(0.9f, 0.2f, 0); flagVert.Add(flagVert[0]); Viewer.DrawPolyline(flagVert).SetColor(0, 0, 0).SetLineWidth(2); Viewer.Render(); return(null); }
public override byte[] Render(bool toRgbArray = false) { if (Viewer == null) { Viewer = new Rendering.Viewer(VIEWPORT_W, VIEWPORT_H); Viewer.SetBounds(0, VIEWPORT_W / SCALE, 0, VIEWPORT_H / SCALE); } foreach (var obj in particles) { var data = obj.GetUserData() as CustomBodyData; data.TimeToLive -= 0.15f; data.Color1 = new b2Vec3((float)Math.Max(0.2, 0.2 + data.TimeToLive), (float)Math.Max(0.2, 0.5 * data.TimeToLive), (float)Math.Max(0.2, 0.5 * data.TimeToLive)); data.Color2 = new b2Vec3((float)Math.Max(0.2, 0.2 + data.TimeToLive), (float)Math.Max(0.2, 0.5 * data.TimeToLive), (float)Math.Max(0.2, 0.5 * data.TimeToLive)); } CleanParticles(false); foreach (var p in sky_polys) { Viewer.DrawPolygon(p).SetColor(0, 0, 0); } foreach (var obj in particles.Concat(drawlist)) { for (b2Fixture f = obj.GetFixtureList(); f != null; f = f.GetNext()) { var xform = f.GetBody().GetTransform(); if (f.GetShape() is b2CircleShape) { var shape = (f.GetShape() as b2CircleShape); var customData = (obj.GetUserData() as CustomBodyData); var trans = Utils.b2Mul(xform, shape.m_p); var t = new Rendering.Transform(new float[] { trans[0], trans[1] }); Viewer.DrawCircle(shape.m_radius, 20).SetColor(customData.Color1.x, customData.Color1.y, customData.Color1.z).AddAttr(t); Viewer.DrawCircle(shape.m_radius, 20, false).SetColor(customData.Color2.x, customData.Color2.y, customData.Color2.z).SetLineWidth(2).AddAttr(t); } else { var shape = f.GetShape(); var customData = (obj.GetUserData() as CustomBodyData); var path = shape.GetVertices().Select(v => { var trans = Utils.b2Mul(xform, v); return(new float[] { trans[0], trans[1] }); }).ToList(); Viewer.DrawPolygon(path).SetColor(customData.Color1.x, customData.Color1.y, customData.Color1.z); path.Add(path[0]); Viewer.DrawPolyline(path).SetColor(customData.Color2.x, customData.Color2.y, customData.Color2.z).SetLineWidth(2); } } } foreach (var x in new[] { helipad_x1, helipad_x2 }) { var flagy1 = helipad_y; var flagy2 = flagy1 + 50 / SCALE; Viewer.DrawPolyline(new List <float[]> { new float[] { x, flagy1 }, new float[] { x, flagy2 } }).SetColor(1, 1, 1); Viewer.DrawPolygon(new List <float[]> { new float[] { x, flagy2 }, new float[] { x, flagy2 - 10 / SCALE }, new float[] { x + 25 / SCALE, flagy2 - 5 / SCALE } }).SetColor(0.8f, 0.8f, 0); } Viewer.Render(); return(null); }
public b2ContactSolver(b2ContactSolverDef def) { m_step = def.step; m_count = def.count; m_positionConstraints = Arrays.InitializeWithDefaultInstances <b2ContactPositionConstraint>(m_count); m_velocityConstraints = Arrays.InitializeWithDefaultInstances <b2ContactVelocityConstraint>(m_count); m_positions = def.positions; m_velocities = def.velocities; m_contacts = def.contacts; // Initialize position independent portions of the constraints. for (int i = 0; i < m_count; ++i) { b2Contact contact = m_contacts[i]; b2Fixture fixtureA = contact.m_fixtureA; b2Fixture fixtureB = contact.m_fixtureB; b2Shape shapeA = fixtureA.GetShape(); b2Shape shapeB = fixtureB.GetShape(); float radiusA = shapeA.m_radius; float radiusB = shapeB.m_radius; b2Body bodyA = fixtureA.GetBody(); b2Body bodyB = fixtureB.GetBody(); b2Manifold manifold = contact.GetManifold(); int pointCount = manifold.pointCount; Debug.Assert(pointCount > 0); b2ContactVelocityConstraint vc = m_velocityConstraints[i]; vc.friction = contact.m_friction; vc.restitution = contact.m_restitution; vc.tangentSpeed = contact.m_tangentSpeed; vc.indexA = bodyA.m_islandIndex; vc.indexB = bodyB.m_islandIndex; vc.invMassA = bodyA.m_invMass; vc.invMassB = bodyB.m_invMass; vc.invIA = bodyA.m_invI; vc.invIB = bodyB.m_invI; vc.contactIndex = i; vc.pointCount = pointCount; vc.K.SetZero(); vc.normalMass.SetZero(); b2ContactPositionConstraint pc = m_positionConstraints[i]; pc.indexA = bodyA.m_islandIndex; pc.indexB = bodyB.m_islandIndex; pc.invMassA = bodyA.m_invMass; pc.invMassB = bodyB.m_invMass; pc.localCenterA = bodyA.m_sweep.localCenter; pc.localCenterB = bodyB.m_sweep.localCenter; pc.invIA = bodyA.m_invI; pc.invIB = bodyB.m_invI; pc.localNormal = manifold.localNormal; pc.localPoint = manifold.localPoint; pc.pointCount = pointCount; pc.radiusA = radiusA; pc.radiusB = radiusB; pc.type = manifold.type; for (int j = 0; j < pointCount; ++j) { b2ManifoldPoint cp = manifold.points[j]; b2VelocityConstraintPoint vcp = vc.points[j]; if (m_step.warmStarting) { vcp.normalImpulse = m_step.dtRatio * cp.normalImpulse; vcp.tangentImpulse = m_step.dtRatio * cp.tangentImpulse; } else { vcp.normalImpulse = 0.0f; vcp.tangentImpulse = 0.0f; } vcp.rA.SetZero(); vcp.rB.SetZero(); vcp.normalMass = 0.0f; vcp.tangentMass = 0.0f; vcp.velocityBias = 0.0f; pc.localPoints[j] = cp.localPoint; } } }
public override void Step(b2TimeStep step) { if (m_bodyList == null) { return; } if (useWorldGravity) { gravity = GetWorld().GetGravity().Copy(); } for (b2ControllerEdge i = m_bodyList; i != null; i = i.nextBody) { b2Body body = i.body; if (body.IsAwake() == false) { //Buoyancy force is just a function of position, //so unlike most forces, it is safe to ignore sleeping bodes continue; } b2Vec2 areac = new b2Vec2(); b2Vec2 massc = new b2Vec2(); float area = 0.0f; float mass = 0.0f; for (b2Fixture fixture = body.GetFixtureList(); fixture != null; fixture = fixture.GetNext()) { b2Vec2 sc = new b2Vec2(); float sarea = fixture.GetShape().ComputeSubmergedArea(normal, offset, body.GetTransform(), sc); area += sarea; areac.x += sarea * sc.x; areac.y += sarea * sc.y; float shapeDensity; if (useDensity) { //TODO: Figure out what to do now density is gone shapeDensity = 1.0f; } else { shapeDensity = 1.0f; } mass += sarea * shapeDensity; massc.x += sarea * sc.x * shapeDensity; massc.y += sarea * sc.y * shapeDensity; } areac.x /= area; areac.y /= area; massc.x /= mass; massc.y /= mass; if (area < float.MinValue) { continue; } //Buoyancy b2Vec2 buoyancyForce = gravity.GetNegative(); buoyancyForce.Multiply(density * area); body.ApplyForce(buoyancyForce, massc); //Linear drag b2Vec2 dragForce = body.GetLinearVelocityFromWorldPoint(areac); dragForce.Subtract(velocity); dragForce.Multiply(-linearDrag * area); body.ApplyForce(dragForce, areac); //Angular drag //TODO: Something that makes more physical sense? body.ApplyTorque(-body.GetInertia() / body.GetMass() * area * body.GetAngularVelocity() * angularDrag); } }