Advertisement
Guest User

BreakableBody Farseer 3.0

a guest
May 5th, 2010
253
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 4.79 KB | None | 0 0
  1. /*
  2. * Box2D.XNA port of Box2D:
  3. * Copyright (c) 2009 Brandon Furtwangler, Nathan Furtwangler
  4. *
  5. * Original source Box2D:
  6. * Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com
  7. *
  8. * This software is provided 'as-is', without any express or implied
  9. * warranty.  In no event will the authors be held liable for any damages
  10. * arising from the use of this software.
  11. * Permission is granted to anyone to use this software for any purpose,
  12. * including commercial applications, and to alter it and redistribute it
  13. * freely, subject to the following restrictions:
  14. * 1. The origin of this software must not be misrepresented; you must not
  15. * claim that you wrote the original software. If you use this software
  16. * in a product, an acknowledgment in the product documentation would be
  17. * appreciated but is not required.
  18. * 2. Altered source versions must be plainly marked as such, and must not be
  19. * misrepresented as being the original software.
  20. * 3. This notice may not be removed or altered from any source distribution.
  21. */
  22.  
  23. using System;
  24. using System.Collections.Generic;
  25. using FarseerPhysics.Collision.Shapes;
  26. using FarseerPhysics.Dynamics.Contacts;
  27. using FarseerPhysics.Factories;
  28. using Microsoft.Xna.Framework;
  29. using FarseerPhysics.Common;
  30. using FarseerPhysics.Collision;
  31.  
  32. namespace FarseerPhysics.Dynamics
  33. {
  34.     public class BreakableBody
  35.     {
  36.         public List<Fixture> Parts = new List<Fixture>(8);
  37.         public float Strength = 500.0f;
  38.         public bool Broken;
  39.         private bool _break;
  40.         private Vector2 _breakPoint;
  41.         public Vector2[] _velocitiesCache = new Vector2[8];
  42.         public float[] _angularVelocitiesCache = new float[8];
  43.         public Body MainBody;
  44.         private World _world;
  45.  
  46.         public BreakableBody(World world)
  47.         {
  48.             _world = world;
  49.             MainBody = new Body(world);
  50.             MainBody.BodyType = BodyType.Dynamic;
  51.         }
  52.  
  53.         private void PostSolve(ContactConstraint contactConstraint)
  54.         {
  55.             if (!Broken)
  56.             {
  57.                 Vector2 contactPoint = Vector2.Zero;
  58.                 float maxImpulse = 0.0f;
  59.                 for (int i = 0; i < contactConstraint.Manifold.PointCount; ++i)
  60.                 {
  61.                     maxImpulse = Math.Max(maxImpulse, contactConstraint.Manifold.Points[i].NormalImpulse);
  62.                     contactPoint += contactConstraint.Manifold.Points[i].LocalPoint;
  63.                 }
  64.                 _breakPoint = contactPoint / contactConstraint.Manifold.PointCount;
  65.  
  66.                 if (maxImpulse > Strength)
  67.                 {
  68.                     // Flag the body for breaking.
  69.                     _break = true;
  70.                 }
  71.             }
  72.         }
  73.  
  74.         public void AddPart(Fixture fixture)
  75.         {
  76.             fixture.PostSolve += PostSolve;
  77.             //fixture.OnCollision += OnCollision;
  78.             Parts.Add(fixture);
  79.         }
  80.  
  81.         public void Update()
  82.         {
  83.             if (_break)
  84.             {
  85.                 Break();
  86.                 Broken = true;
  87.                 _break = false;
  88.             }
  89.  
  90.             // Cache velocities to improve movement on breakage.
  91.             if (Broken == false)
  92.             {
  93.                 //Enlarge the cache if needed
  94.                 if (Parts.Count > _angularVelocitiesCache.Length)
  95.                 {
  96.                     _velocitiesCache = new Vector2[Parts.Count];
  97.                     _angularVelocitiesCache = new float[Parts.Count];
  98.                 }
  99.  
  100.                 //Cache the linear and angular velocities.
  101.                 for (int i = 0; i < Parts.Count; i++)
  102.                 {
  103.                     _velocitiesCache[i] = Parts[i].Body.LinearVelocity;
  104.                     _angularVelocitiesCache[i] = Parts[i].Body.AngularVelocity;
  105.                 }
  106.             }
  107.         }
  108.  
  109.         public void Break()
  110.         {
  111.             Vector2 mainCenter = MainBody.WorldCenter;
  112.  
  113.             for (int i = 0; i < Parts.Count; i++)
  114.             {
  115.                 Fixture fixture = Parts[i];
  116.                 Shape shape = fixture.Shape.Clone();
  117.                 MainBody.DestroyFixture(fixture);
  118.  
  119.                 Body body = BodyFactory.CreateBody(_world);
  120.                 body.BodyType = BodyType.Dynamic;
  121.                 body.Position = MainBody.Position;
  122.                 body.Rotation = MainBody.GetAngle();
  123.                 body.CreateFixture(shape);
  124.  
  125.                 // We calculate velocities
  126.                 Vector2 center = body.WorldCenter;
  127.                 Vector2 velocity = _velocitiesCache[i] +
  128.                     MathUtils.Cross(_angularVelocitiesCache[i],
  129.                     center - mainCenter);
  130.  
  131.                 body.AngularVelocity = _angularVelocitiesCache[i];
  132.                 body.LinearVelocity = velocity;
  133.             }
  134.         }
  135.     }
  136. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement