public static Tuple<HingeJoint, AngleJoint> ConnectWith(this BaseModelBody parentBody, BaseModelBody childBody, Vector2D hingeLocation) { var hinge = new HingeJoint(parentBody, childBody, hingeLocation, new Lifespan()) { DistanceTolerance = 50, Softness = 10000.1 }; var angle = new AngleJoint(parentBody, childBody, new Lifespan()) { Softness = -0.00000001, BiasFactor = 0.3}; return new Tuple<HingeJoint, AngleJoint>(hinge, angle); }
public static DisposeCallback CreateTank(DemoOpenInfo info, Vector2D position,List<Body> result) { Lifespan avatarLifespan = new Lifespan(); IShape shape = ShapeFactory.CreateSprite(Cache<SurfacePolygons>.GetItem("tank.png"), 4, 18, 2); ObjectIgnorer ignorer = new ObjectIgnorer(); Body tankBody = new Body(new PhysicsState(new ALVector2D(0, 0, 0)), shape, 300,//new MassInfo(40, Scalar.PositiveInfinity), new Coefficients(0, 1), avatarLifespan); result.Add(tankBody); tankBody.State.Position.Linear += position; tankBody.ApplyPosition(); tankBody.CollisionIgnorer = ignorer; BodyGraphic graphic = CreateGraphic(tankBody); graphic.ZOrder = 2; info.Scene.AddGraphic(graphic); Scalar wheelSize = 18; Scalar wheelSpacing = -9; Scalar lenghtPercent = .84f; Matrix2x3 ident = Matrix2x3.Identity; BoundingRectangle rect; shape.CalcBoundingRectangle(ref ident, out rect); Scalar y = (rect.Max.Y + 4); Body lastWheel = null; BoundingPolygon polygon = new BoundingPolygon(shape.Vertexes); Ray ray2 = new Ray(new Vector2D(rect.Max.X, y), -Vector2D.YAxis); Scalar y3 = y - polygon.Intersects(ray2); Vector2D avatarBarrelOffset = new Vector2D(rect.Max.X + 10, y3); CircleShape wheelShape = ShapeFactory.CreateColoredCircle(wheelSize, 30); Scalar force = 0; for (Scalar x = rect.Min.X + wheelSize; x < (rect.Max.X - wheelSize) * lenghtPercent; x += (wheelSize * 2 + wheelSpacing)) { Ray ray = new Ray(new Vector2D(x, y), -Vector2D.YAxis); Scalar y2 = y - polygon.Intersects(ray); Vector2D offset = new Vector2D(x, y2); Body wheel = new Body( new PhysicsState(new ALVector2D(0, offset + position)), wheelShape, 10, new Coefficients(0, 3),// coefficients.Duplicate(), avatarLifespan); result.Add(wheel); wheel.CollisionIgnorer = ignorer; wheel.AngularDamping = .9f; wheel.Updated += delegate(object sender, UpdatedEventArgs e) { wheel.State.ForceAccumulator.Angular += force; }; info.Scene.AddGraphic(CreateGraphic(wheel)); HingeJoint joint = new HingeJoint(tankBody, wheel, offset + position, avatarLifespan); joint.Softness = .1f; info.Scene.Engine.AddJoint(joint); if (lastWheel != null) { AngleJoint joint2 = new AngleJoint(lastWheel, wheel, avatarLifespan); info.Scene.Engine.AddJoint(joint2); } lastWheel = wheel; } CircleShape weaponShape = ShapeFactory.CreateColoredCircle(5, 8); //now begins the abuse of anominous delegates (BIG TIME) EventHandler<KeyboardEventArgs> keyDownHandler = delegate(object sender, KeyboardEventArgs e) { switch (e.Key) { case Key.LeftArrow: force = -1500000; break; case Key.RightArrow: force = 1500000; break; case Key.Space: Scalar velocity = 2000; Matrix2x3 toWorld = tankBody.Matrices.ToWorld; Matrix2x2 toWorldNormal = tankBody.Matrices.ToWorldNormal; // Matrix2D mat = avatarBodies[0].Matrices.ToWorld; Vector2D direction = toWorldNormal * Vector2D.XAxis; PhysicsState state = new PhysicsState(); state.Position.Linear = toWorld * (avatarBarrelOffset); state.Velocity.Linear = velocity * direction + tankBody.State.Velocity.Linear; Body weapon = new Body(state, weaponShape, 5, new Coefficients(1, 1), new Lifespan(10)); //weapon.CollisionIgnorer = tankBody.CollisionIgnorer; weapon.Collided += delegate(object sender2, CollisionEventArgs e2) { if (!weapon.Lifetime.IsExpired) { weapon.Lifetime.IsExpired = true; AddParticles(info, weapon.State.Position.Linear, weapon.State.Velocity.Linear * .5f, 50); } }; // weapon.Collided += weapon_Collided; tankBody.State.Velocity.Linear -= (velocity * weapon.Mass.Mass * tankBody.Mass.MassInv) * direction; info.Scene.AddGraphic(CreateGraphic(weapon)); break; } }; EventHandler<KeyboardEventArgs> keyUpHandler = delegate(object sender, KeyboardEventArgs e) { switch (e.Key) { case Key.LeftArrow: force = 0; break; case Key.RightArrow: force = 0; break; } }; Events.KeyboardDown += keyDownHandler; Events.KeyboardUp += keyUpHandler; return delegate() { Events.KeyboardDown -= keyDownHandler; Events.KeyboardUp -= keyUpHandler; }; }
void CreateAvatar() { Lifespan avatarLifespan = new Lifespan(); Sprite sprite = GetSprite("tank.png"); Vector2D[][] polygons = sprite.Polygons; MultiPolygonShape shape = new MultiPolygonShape(polygons, 4); shape.Tag = sprite; ObjectIgnorer ignorer = new ObjectIgnorer(); Body a = new Body(new PhysicsState(new ALVector2D(0, 0, 0)), shape, 300,//new MassInfo(40, Scalar.PositiveInfinity), coefficients.Duplicate(), avatarLifespan); a.Updated += new EventHandler<UpdatedEventArgs>(avatar_Updated); avatarBodies = new List<Body>(); avatarOffsets = new List<Vector2D>(); avatarJoints = new List<Joint>(); avatarBodies.Add(a); a.CollisionIgnorer = ignorer; Scalar wheelSize = 18; Scalar wheelSpacing = -9; Scalar lenghtPercent = .84f; Matrix2x3 ident = Matrix2x3.Identity; BoundingRectangle rect; shape.CalcBoundingRectangle(ref ident, out rect); Scalar y = (rect.Max.Y +4) ; Body lastWheel = null ; BoundingPolygon polygon = new BoundingPolygon(polygons[0]); Ray ray2 = new Ray(new Vector2D(rect.Max.X, y), -Vector2D.YAxis); Scalar y3 = y - polygon.Intersects(ray2); avatarBarrelOffset = new Vector2D(rect.Max.X, y3); for (Scalar x = rect.Min.X + wheelSize ; x < (rect.Max.X - wheelSize ) * lenghtPercent; x += (wheelSize*2 + wheelSpacing)) { Ray ray = new Ray(new Vector2D(x, y), -Vector2D.YAxis); Scalar y2 = y- polygon.Intersects(ray); Vector2D offset = new Vector2D(x, y2); Body wheel = new Body( new PhysicsState(new ALVector2D(0, offset)), new CircleShape(wheelSize, 30), 10, new Coefficients(0,3),// coefficients.Duplicate(), avatarLifespan); HingeJoint joint = new HingeJoint(a, wheel, offset, avatarLifespan); joint.Softness = .1f; wheel.CollisionIgnorer = ignorer; if (lastWheel != null) { AngleJoint joint2 = new AngleJoint(lastWheel, wheel, avatarLifespan); avatarJoints.Add(joint2); } avatarJoints.Add(joint); avatarOffsets.Add(offset); avatarBodies.Add(wheel); lastWheel = wheel; } }
private void AddSlot(BaseGeneViewModel gene) { Will.Instance.RunPauseWilling(false); var slotGene = (NodeGeneViewModel)gene; var boneBody = Will.Instance.Bodies.RandomOrDefault<BoneBody>(b => b.Model.ChildSlots.Any(s => s.IsOccupied == false)); if (boneBody == null) { Will.Instance.RunPauseWilling(true); return; } var parPos = boneBody.State.Position; var randSlot = boneBody.Model.ChildSlots.Where(s => s.IsOccupied == false).RandomOrDefault(); var slot = slotGene.GetModelDuplicate(); slot.Direction = randSlot.Direction; slot.DistanceFromCenter = randSlot.DistanceFromCenter; slot.Orientation = randSlot.Orientation; randSlot.IsOccupied = true; var slotBody = WillHelper.CreateConnectionSlotBody(slot, boneBody.ModelId); var slotXAngle = slot.Direction + parPos.Angular; var slotCenter = Vector2D.Rotate(slotXAngle, new Vector2D(slot.DistanceFromCenter, 0.0f)); var slotPos = new ALVector2D(slot.Orientation + slotXAngle, slotCenter + parPos.Linear); slotBody.State.Position = slotPos; slotBody.ApplyPosition(); slotBody.Parent = boneBody; boneBody.Children.Add(slotBody); var joints = new List<Joint>(); var nodePos = slotBody.State.Position; var hinge = new HingeJoint(boneBody, slotBody, (slot.Size * nodePos.Linear + boneBody.Model.Length * parPos.Linear) * (1/(slot.Size + boneBody.Model.Length)), new Lifespan()) { DistanceTolerance = 50, Softness = 10.1 }; var angle = new AngleJoint(boneBody, slotBody, new Lifespan()) { Softness = 0.00001 }; joints.Add(hinge); joints.Add(angle); Will.Instance.AddBody(slotBody); Will.Instance.AddJoints(joints); Will.Instance.RunPauseWilling(true); }
private void AddCore(Guid geneApplicationId, BaseGeneViewModel gene) { var core = (CoreGeneViewModel)gene; var model = core.GetModelDuplicate(); model.Id = geneApplicationId; var coreBody = WillHelper.CreateCoreBody(model, geneApplicationId); var nodes = WillHelper.BuildNodeSlots(coreBody, geneApplicationId); coreBody.Children = nodes; var corePos = coreBody.State.Position; var joints = new List<Joint>(); foreach (var node in nodes) { var hinge = new HingeJoint(coreBody, node, (2* node.State.Position.Linear + 8 * corePos.Linear) * 0.1f, new Lifespan()) { DistanceTolerance = 10, Softness = 100.0 }; var angle = new AngleJoint(coreBody, node, new Lifespan()) { Softness = 0.0001, BiasFactor = 0.2f }; joints.Add(hinge); joints.Add(angle); } Will.Instance.AddModelBodies(new List<BaseModelBody>{ coreBody }.Concat(nodes).ToList()); Will.Instance.AddJoints(joints); }
private void AddChainCommandExecute(object parameter) { Will.Instance.Purge(); Will.Instance.RunPauseWilling(false); var startPoint = new Vector2D(300, 800); double angle = MathHelper.ToRadians(15.0f); double boxlength = 50; double spacing = 2; double anchorLength = 30; double anchorGap = (boxlength / 2) + spacing + (anchorLength / 2); var chainId = Guid.NewGuid(); var chain = WillHelper.BuildChain(startPoint, boxlength, 3, 1200, spacing, 600, chainId); var point2 = new Vector2D(chain[chain.Count - 1].State.Position.Linear.X + anchorGap, startPoint.Y); var end2 = WillHelper.AddCircle(anchorLength / 2, 6, double.PositiveInfinity, new ALVector2D(0, point2), chainId); end2.IgnoresGravity = true; var joint2 = new HingeJoint(chain[chain.Count - 1], end2, point2, new Lifespan()) {DistanceTolerance = 20}; var joint21 = new AngleJoint(chain[chain.Count - 1], end2, new Lifespan()) { Angle = angle }; var point1 = new Vector2D(chain[0].State.Position.Linear.X - anchorGap, startPoint.Y); var end1 = WillHelper.AddCircle(anchorLength / 2, 6, double.PositiveInfinity, new ALVector2D(0, point1), chainId); chain.Add(end1); chain.Add(end2); end1.IgnoresGravity = true; var joint1 = new HingeJoint(chain[0], end1, point1, new Lifespan()) {DistanceTolerance = 20}; var joint11 = new AngleJoint(end1, chain[0], new Lifespan()) { Angle = angle }; Will.Instance.AddJoint(joint1);Will.Instance.AddJoint(joint11); Will.Instance.AddJoint(joint2);Will.Instance.AddJoint(joint21); Representation.Instance.RegisterModel(chainId, chain); Will.Instance.RunPauseWilling(true); }