Advertisement
Guest User

BEPU physics demo - bad broken new object type

a guest
Nov 12th, 2015
119
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. using BEPUphysics.BroadPhaseEntries;
  2. using BEPUphysics.Entities.Prefabs;
  3. using BEPUutilities;
  4. using BEPUphysics.CollisionShapes.ConvexShapes;
  5. using BEPUphysics.Entities;
  6. using BEPUphysics.Constraints.SolverGroups;
  7. using BEPUphysics.Paths;
  8. using BEPUphysics.Paths.PathFollowing;
  9. using BEPUphysics.Constraints.TwoEntity.Motors;
  10. using BEPUphysics.CollisionShapes;
  11. using System.Collections.Generic;
  12. using Microsoft.Xna.Framework.Graphics;
  13. // MCMONKEY - pay no mind to me "using" the everything.
  14. using BEPUphysics.BroadPhaseEntries.MobileCollidables;
  15. using System;
  16. using BEPUphysics.BroadPhaseEntries.Events;
  17. using BEPUphysics.OtherSpaceStages;
  18. using BEPUphysics.NarrowPhaseSystems;
  19. using BEPUphysics.BroadPhaseSystems;
  20. using BEPUphysics.NarrowPhaseSystems.Pairs;
  21. using BEPUphysics.CollisionRuleManagement;
  22. using BEPUutilities.DataStructures;
  23. using BEPUphysics.CollisionTests.Manifolds;
  24. using BEPUphysics.Constraints.Collision;
  25. using BEPUphysics.CollisionTests.CollisionAlgorithms.GJK;
  26. using BEPUphysics.PositionUpdating;
  27. using BEPUphysics.Settings;
  28. using BEPUphysics.Materials;
  29. using System.Linq;
  30. using System.Text;
  31. using BEPUphysics.CollisionTests.CollisionAlgorithms;
  32. using BEPUutilities.ResourceManagement;
  33. using BEPUphysics.CollisionTests;
  34. // MCMONKEY - end spam of "using" statements
  35.  
  36. namespace BEPUphysicsDemos.Demos
  37. {
  38.  
  39.     // MCMONKEY - begin custom stuffs
  40.    
  41.     public class VoxelWorldShape : CollisionShape
  42.     {
  43.         // NOTE: No need for an entire voxel system yet... let's just pretend the voxels make up a flat terrain at Y=0, covering 10,000*10,000 units.
  44.         Box testShape = new Box(new Vector3(0, -5000, 0), 10 * 1000, 10 * 1000, 10 * 1000);
  45.  
  46.         public bool RayCast(ref Ray ray, float maximumLength, out RayHit hit)
  47.         {
  48.             return testShape.CollisionInformation.RayCast(ray, maximumLength, out hit);
  49.         }
  50.  
  51.  
  52.         public bool ConvexCast(ConvexShape castShape, ref RigidTransform startingTransform, ref Vector3 sweep, out RayHit hit)
  53.         {
  54.             return testShape.CollisionInformation.ConvexCast(castShape, ref startingTransform, ref sweep, out hit);
  55.         }
  56.     }
  57.  
  58.     public class VoxelWorldObject : StaticCollidable
  59.     {
  60.         public static void RegisterMe()
  61.         {
  62.             NarrowPhasePairFactory<ConvexVoxelPairHandler> fact = new NarrowPhasePairFactory<ConvexVoxelPairHandler>();
  63.             NarrowPhaseHelper.CollisionManagers.Add(new TypePair(typeof(ConvexCollidable<BoxShape>), typeof(VoxelWorldObject)), fact);
  64.             NarrowPhaseHelper.CollisionManagers.Add(new TypePair(typeof(ConvexCollidable<SphereShape>), typeof(VoxelWorldObject)), fact);
  65.             NarrowPhaseHelper.CollisionManagers.Add(new TypePair(typeof(ConvexCollidable<CapsuleShape>), typeof(VoxelWorldObject)), fact);
  66.             NarrowPhaseHelper.CollisionManagers.Add(new TypePair(typeof(ConvexCollidable<TriangleShape>), typeof(VoxelWorldObject)), fact);
  67.             NarrowPhaseHelper.CollisionManagers.Add(new TypePair(typeof(ConvexCollidable<CylinderShape>), typeof(VoxelWorldObject)), fact);
  68.             NarrowPhaseHelper.CollisionManagers.Add(new TypePair(typeof(ConvexCollidable<ConeShape>), typeof(VoxelWorldObject)), fact);
  69.             NarrowPhaseHelper.CollisionManagers.Add(new TypePair(typeof(ConvexCollidable<TransformableShape>), typeof(VoxelWorldObject)), fact);
  70.             NarrowPhaseHelper.CollisionManagers.Add(new TypePair(typeof(ConvexCollidable<MinkowskiSumShape>), typeof(VoxelWorldObject)), fact);
  71.             NarrowPhaseHelper.CollisionManagers.Add(new TypePair(typeof(ConvexCollidable<WrappedShape>), typeof(VoxelWorldObject)), fact);
  72.             NarrowPhaseHelper.CollisionManagers.Add(new TypePair(typeof(ConvexCollidable<ConvexHullShape>), typeof(VoxelWorldObject)), fact);
  73.             NarrowPhaseHelper.CollisionManagers.Add(new TypePair(typeof(TriangleCollidable), typeof(VoxelWorldObject)), fact);
  74.         }
  75.  
  76.         public VoxelWorldObject()
  77.         {
  78.             WorldShape = new VoxelWorldShape();
  79.             boundingBox = new BoundingBox(new Vector3(-5 * 1000, -10 * 1000, -5 * 1000), new Vector3(5 * 1000, 0, 5 * 1000));
  80.         }
  81.  
  82.         public VoxelWorldShape WorldShape;
  83.  
  84.         public ContactEventManager<VoxelWorldObject> Events = new ContactEventManager<VoxelWorldObject>();
  85.  
  86.         protected override IContactEventTriggerer EventTriggerer
  87.         {
  88.             get { return Events; }
  89.         }
  90.  
  91.         protected override IDeferredEventCreator EventCreator
  92.         {
  93.             get { return Events; }
  94.         }
  95.  
  96.         public override void UpdateBoundingBox()
  97.         {
  98.             boundingBox = new BoundingBox(new Vector3(-5 * 1000, -10 * 1000, -5 * 1000), new Vector3(5 * 1000, 0, 5 * 1000));
  99.         }
  100.  
  101.         public override bool ConvexCast(ConvexShape castShape, ref RigidTransform startingTransform, ref Vector3 sweep, Func<BroadPhaseEntry, bool> filter, out RayHit hit)
  102.         {
  103.             return WorldShape.ConvexCast(castShape, ref startingTransform, ref sweep, out hit);
  104.         }
  105.  
  106.         public override bool ConvexCast(ConvexShape castShape, ref RigidTransform startingTransform, ref Vector3 sweep, out RayHit hit)
  107.         {
  108.             return ConvexCast(castShape, ref startingTransform, ref sweep, null, out hit);
  109.         }
  110.  
  111.         public override bool RayCast(Ray ray, float maximumLength, Func<BroadPhaseEntry, bool> filter, out RayHit rayHit)
  112.         {
  113.             return WorldShape.RayCast(ref ray, maximumLength, out rayHit);
  114.         }
  115.  
  116.         public override bool RayCast(Ray ray, float maximumLength, out RayHit rayHit)
  117.         {
  118.             return RayCast(ray, maximumLength, null, out rayHit);
  119.         }
  120.     }
  121.  
  122.     public class ConvexVoxelPairHandler : StandardPairHandler
  123.     {
  124.         VoxelWorldObject VWO = null;
  125.  
  126.         ConvexCollidable convex = null;
  127.  
  128.         private NonConvexContactManifoldConstraint contactConstraint;
  129.        
  130.         public override Collidable CollidableA
  131.         {
  132.             get { return convex; }
  133.         }
  134.  
  135.         public override Collidable CollidableB
  136.         {
  137.             get { return VWO; }
  138.         }
  139.  
  140.         public override Entity EntityA
  141.         {
  142.             get { return convex.Entity; }
  143.         }
  144.  
  145.         public override Entity EntityB
  146.         {
  147.             get { return null; }
  148.         }
  149.  
  150.         public override ContactManifoldConstraint ContactConstraint
  151.         {
  152.             get { return contactConstraint; }
  153.         }
  154.  
  155.         public override ContactManifold ContactManifold
  156.         {
  157.             get { return contactManifold; }
  158.         }
  159.  
  160.         VoxelContactManifold contactManifold = new VoxelContactManifold();
  161.  
  162.         public ConvexVoxelPairHandler()
  163.         {
  164.             contactConstraint = new NonConvexContactManifoldConstraint(this);
  165.         }
  166.  
  167.         bool noRecurse = false;
  168.        
  169.         public override void Initialize(BroadPhaseEntry entryA, BroadPhaseEntry entryB)
  170.         {
  171.             if (noRecurse) // NOTE: Needed because UpdateMaterialProperties will call this,
  172.             { // because we can't access the internal method that does the same code without calling init :(
  173.                 return;
  174.             }
  175.             noRecurse = true;
  176.             VWO = entryA as VoxelWorldObject;
  177.             convex = entryB as ConvexCollidable;
  178.             if (VWO == null || convex == null)
  179.             {
  180.                 VWO = entryB as VoxelWorldObject;
  181.                 convex = entryA as ConvexCollidable;
  182.                 if (VWO == null || convex == null)
  183.                 {
  184.                     throw new ArgumentException("Inappropriate types used to initialize pair.");
  185.                 }
  186.             }
  187.             BroadPhaseOverlap = new BEPUphysics.BroadPhaseSystems.BroadPhaseOverlap(convex, VWO);
  188.             UpdateMaterialProperties(convex.Entity != null ? convex.Entity.Material : null, VWO.Material);
  189.             base.Initialize(entryA, entryB);
  190.             // NOTE: Just in case, force friction off for testing's sake
  191.             InteractionProperties ip = contactConstraint.MaterialInteraction;
  192.             ip.StaticFriction = 0f;
  193.             ip.KineticFriction = 0f;
  194.             ip.Bounciness = 0.5f;
  195.             contactConstraint.MaterialInteraction = ip;
  196.             noRecurse = false;
  197.         }
  198.        
  199.         ///<summary>
  200.         /// Cleans up the pair handler.
  201.         ///</summary>
  202.         public override void CleanUp()
  203.         {
  204.             base.CleanUp();
  205.  
  206.             VWO = null;
  207.             convex = null;
  208.         }
  209.        
  210.         public override void UpdateTimeOfImpact(Collidable requester, float dt)
  211.         {
  212.             if (convex.Entity != null && convex.Entity.ActivityInformation.IsActive && convex.Entity.PositionUpdateMode == PositionUpdateMode.Continuous)
  213.             {
  214.                 timeOfImpact = 1;
  215.                 RigidTransform rt = new RigidTransform(convex.Entity.Position, convex.Entity.Orientation);
  216.                 Vector3 sweep = convex.Entity.LinearVelocity;
  217.                 sweep *= dt;
  218.                 RayHit rh;
  219.                 if (VWO.ConvexCast(convex.Shape, ref rt, ref sweep, out rh))
  220.                 {
  221.                     timeOfImpact = rh.T;
  222.                 }
  223.                 if (TimeOfImpact < 0)
  224.                 {
  225.                     timeOfImpact = 0;
  226.                 }
  227.             }
  228.         }
  229.        
  230.         protected override void GetContactInformation(int index, out ContactInformation info)
  231.         {
  232.             ContactInformation ci = new ContactInformation();
  233.             ci.Contact = contactManifold.ctcts[index];
  234.             ci.Pair = this;
  235.             ReadOnlyList<ContactPenetrationConstraint> list = contactConstraint.ContactPenetrationConstraints;
  236.             float totalimp = 0;
  237.             for (int i = 0; i < list.Count; i++)
  238.             {
  239.                 totalimp += list[i].NormalImpulse;
  240.             }
  241.             ci.NormalImpulse = list[index].NormalImpulse;
  242.             ci.FrictionImpulse = (ci.NormalImpulse / totalimp) * list[index].RelativeVelocity;
  243.             if (convex.Entity != null)
  244.             {
  245.                 Vector3 velocity;
  246.                 Vector3 cep = convex.Entity.Position;
  247.                 Vector3 ceav = convex.Entity.AngularVelocity;
  248.                 Vector3 celv = convex.Entity.LinearVelocity;
  249.                 Vector3.Subtract(ref ci.Contact.Position, ref cep, out velocity);
  250.                 Vector3.Cross(ref ceav, ref velocity, out velocity);
  251.                 Vector3.Add(ref velocity, ref celv, out ci.RelativeVelocity);
  252.             }
  253.             else
  254.             {
  255.                 ci.RelativeVelocity = new Vector3(0, 0, 0);
  256.             }
  257.             info = ci;
  258.         }
  259.     }
  260.  
  261.  
  262.     public class VoxelContactManifold : ContactManifold
  263.     {
  264.         protected ConvexCollidable convex;
  265.  
  266.         protected VoxelWorldObject vwo;
  267.  
  268.         public override void Initialize(Collidable newCollidableA, Collidable newCollidableB)
  269.         {
  270.             convex = newCollidableA as ConvexCollidable;
  271.             vwo = newCollidableB as VoxelWorldObject;
  272.             if (convex == null || vwo == null)
  273.             {
  274.                 convex = newCollidableB as ConvexCollidable;
  275.                 vwo = newCollidableA as VoxelWorldObject;
  276.                 if (convex == null || vwo == null)
  277.                 {
  278.                     throw new ArgumentException("Inappropriate types used to initialize contact manifold.");
  279.                 }
  280.             }
  281.         }
  282.  
  283.         public VoxelContactManifold()
  284.         {
  285.             contacts = new RawList<Contact>();
  286.             unusedContacts = new UnsafeResourcePool<Contact>(4);
  287.             contactIndicesToRemove = new RawList<int>();
  288.         }
  289.  
  290.         public RawList<Contact> ctcts
  291.         {
  292.             get
  293.             {
  294.                 return contacts;
  295.             }
  296.         }
  297.  
  298.         public static bool IsNaNOrInfOrZero(ref Vector3 vec)
  299.         {
  300.             return float.IsInfinity(vec.X) || float.IsNaN(vec.X)
  301.                 || float.IsInfinity(vec.Y) || float.IsNaN(vec.Y)
  302.                 || float.IsInfinity(vec.Z) || float.IsNaN(vec.Z) || (vec.X == 0 && vec.Y == 0 && vec.Z == 0);
  303.         }
  304.  
  305.         public static bool IsNaNOrInf(ref Vector3 vec)
  306.         {
  307.             return float.IsInfinity(vec.X) || float.IsNaN(vec.X)
  308.                 || float.IsInfinity(vec.Y) || float.IsNaN(vec.Y)
  309.                 || float.IsInfinity(vec.Z) || float.IsNaN(vec.Z);
  310.         }
  311.  
  312.         public override void Update(float dt)
  313.         {
  314.  
  315.             RigidTransform rt = convex.Entity == null ? convex.WorldTransform : new RigidTransform(convex.Entity.Position, convex.Entity.Orientation);
  316.             if (IsNaNOrInf(ref rt.Position))
  317.             {
  318.                 for (int i = contacts.Count - 1; i >= 0; i--)
  319.                 {
  320.                     Remove(i);
  321.                 }
  322.                 return;
  323.             }
  324.             Vector3 sw = new Vector3(0, 0, 1f);
  325.             if (convex.Entity != null)
  326.             {
  327.                 sw = convex.Entity.LinearVelocity;
  328.             }
  329.             RayHit rh;
  330.             bool hit = vwo.ConvexCast(convex.Shape, ref rt, ref sw, out rh);
  331.             if (!hit || IsNaNOrInfOrZero(ref rh.Normal))
  332.             {
  333.                 for (int i = contacts.Count - 1; i >= 0; i--)
  334.                 {
  335.                     Remove(i);
  336.                 }
  337.                 return;
  338.             }
  339.             float pendef = convex.BoundingBox.Min.Y; // NOTE: not sure whether to negate this
  340.             Vector3 norm;
  341.             RigidTransform rtx = new RigidTransform(Vector3.Zero, rt.Orientation);
  342.             RigidTransform.Transform(ref rh.Normal, ref rtx, out norm);
  343.             norm = -norm; // TODO: Why must we negate here?
  344.             for (int i = contacts.Count - 1; i >= 0; i--)
  345.             {
  346.                 contacts[i].Normal = norm;
  347.                 contacts[i].Position = rh.Location;
  348.                 contacts[i].PenetrationDepth = pendef;
  349.             }
  350.             if (Contacts.Count == 0)
  351.             {
  352.                 ContactData cd = new ContactData();
  353.                 cd.Normal = norm;
  354.                 cd.Position = rh.Location;
  355.                 cd.PenetrationDepth = pendef;
  356.                 cd.Id = contacts.Count;
  357.                 Add(ref cd);
  358.             }
  359.         }
  360.  
  361.         public override void CleanUp()
  362.         {
  363.             convex = null;
  364.             vwo = null;
  365.             base.CleanUp();
  366.         }
  367.     }
  368.  
  369.     // MCMONKEY - end custom stuffs
  370.  
  371.     /// <summary>
  372.     /// A playground for the character controller to frolic in.
  373.     /// </summary>
  374.     public class CharacterPlaygroundDemo : StandardDemo
  375.     {
  376.         /// <summary>
  377.         /// Constructs a new demo.
  378.         /// </summary>
  379.         /// <param name="game">Game owning this demo.</param>
  380.         public CharacterPlaygroundDemo(DemosGame game)
  381.             : base(game)
  382.         {
  383.             VoxelWorldObject.RegisterMe(); // MCMONKEY -> Register the voxel world!
  384.             Space.Add(new VoxelWorldObject()); // MCMONKEY -> Add a voxel world to the space!
  385.  
  386.             game.Camera.Position = new Vector3(-10, 7, 5);
  387.             game.Camera.ViewDirection = new Vector3(0, 0, 1);
  388.             //Since this is the character playground, turn on the character by default.
  389.             character.Activate();
  390.             //Having the character body visible would be a bit distracting.
  391.             character.CharacterController.Body.Tag = "noDisplayObject";
  392.  
  393.             //Load in mesh data for the environment.
  394.             Vector3[] staticTriangleVertices;
  395.             int[] staticTriangleIndices;
  396.  
  397.  
  398.             var playgroundModel = game.Content.Load<Model>("CharacterControllerTestTerrain");
  399.             //This is a little convenience method used to extract vertices and indices from a model.
  400.             //It doesn't do anything special; any approach that gets valid vertices and indices will work.
  401.             ModelDataExtractor.GetVerticesAndIndicesFromModel(playgroundModel, out staticTriangleVertices, out staticTriangleIndices);
  402.             var staticMesh = new StaticMesh(staticTriangleVertices, staticTriangleIndices, new AffineTransform(new Vector3(0.01f, 0.01f, 0.01f), Quaternion.Identity, new Vector3(0, 0, 0)));
  403.             staticMesh.Sidedness = TriangleSidedness.Counterclockwise;
  404.  
  405.             Space.Add(staticMesh);
  406.             game.ModelDrawer.Add(staticMesh);
  407.  
  408.  
  409.  
  410.             //Add a spinning blade for the character to ram itself into.
  411.             var fanBase = new Cylinder(new Vector3(-13, .5f, 50), 1.1f, 1);
  412.             var fanBlade = new Box(fanBase.Position + new Vector3(0, .8f, 0), 5, .1f, 1f, 5);
  413.             var fanJoint = new RevoluteJoint(fanBase, fanBlade, (fanBase.Position + fanBlade.Position) * .5f, Vector3.Up);
  414.             fanJoint.Motor.IsActive = true;
  415.             fanJoint.Motor.Settings.VelocityMotor.GoalVelocity = 30;
  416.             fanJoint.Motor.Settings.MaximumForce = 300;
  417.             Space.Add(fanBase);
  418.             Space.Add(fanBlade);
  419.             Space.Add(fanJoint);
  420.  
  421.             //Add a bridge connecting the two towers.
  422.             Vector3 startPosition = new Vector3(-19.3f, 10.5f - .25f, 23 - .85f);
  423.             var startPlatform = new Box(startPosition - new Vector3(0, 0, 2.2f), 4, .5f, 6);
  424.             Space.Add(startPlatform);
  425.             Vector3 offset = new Vector3(0, 0, 1.7f);
  426.             Box previousLink = startPlatform;
  427.             Vector3 position = new Vector3();
  428.             for (int i = 1; i <= 7; i++)
  429.             {
  430.                 position = startPosition + offset * i;
  431.                 Box link = new Box(position, 3, .3f, 1.5f, 50);
  432.                 link.LinearDamping = .1f;
  433.                 link.AngularDamping = .1f;
  434.                 Space.Add(link);
  435.                 Space.Add(new RevoluteJoint(previousLink, link, position - offset * .5f, Vector3.Right));
  436.  
  437.                 previousLink = link;
  438.             }
  439.             var endPlatform = new Box(position - new Vector3(0, 0, -3.8f), 4, .5f, 6);
  440.             Space.Add(endPlatform);
  441.  
  442.             Space.Add(new RevoluteJoint(previousLink, endPlatform, position + offset * .5f, Vector3.Right));
  443.  
  444.  
  445.             //Add in a floating platform controlled by a curve to serve as an elevator.
  446.             Entity movingEntity = new Box(new Vector3(-10, 0, -10), 3, 1, 3);
  447.  
  448.             var positionCurve = new CardinalSpline3D();
  449.  
  450.             positionCurve.PreLoop = CurveEndpointBehavior.Mirror;
  451.             positionCurve.PostLoop = CurveEndpointBehavior.Mirror;
  452.  
  453.             positionCurve.ControlPoints.Add(-1, new Vector3(-19.3f, 0, 43));
  454.             positionCurve.ControlPoints.Add(0, new Vector3(-19.3f, 0, 43));
  455.             positionCurve.ControlPoints.Add(2, new Vector3(-19.3f, 0, 43));
  456.             positionCurve.ControlPoints.Add(3, new Vector3(-19.3f, 0, 43));
  457.             positionCurve.ControlPoints.Add(4, new Vector3(-19.3f, 5, 43));
  458.             positionCurve.ControlPoints.Add(5f, new Vector3(-19.3f, 10, 43));
  459.             positionCurve.ControlPoints.Add(6f, new Vector3(-19.3f, 10, 43));
  460.             positionCurve.ControlPoints.Add(8f, new Vector3(-19.3f, 10, 43));
  461.             positionCurve.ControlPoints.Add(9f, new Vector3(-19.3f, 10, 43));
  462.  
  463.             elevatorMover = new EntityMover(movingEntity);
  464.             Space.Add(elevatorMover);
  465.             Space.Add(movingEntity);
  466.  
  467.             elevatorPath = positionCurve;
  468.  
  469.             //Add in another floating platform controlled by a curve for horizontal transport.
  470.             movingEntity = new Box(new Vector3(-10, 0, -10), 2.5f, .5f, 2.5f);
  471.  
  472.             var platformCurve = new LinearInterpolationCurve3D();
  473.  
  474.             platformCurve.PreLoop = CurveEndpointBehavior.Mirror;
  475.             platformCurve.PostLoop = CurveEndpointBehavior.Mirror;
  476.  
  477.             platformCurve.ControlPoints.Add(0, new Vector3(-1.75f, 10, 21.5f));
  478.             platformCurve.ControlPoints.Add(2, new Vector3(-1.75f, 10, 21.5f));
  479.             platformCurve.ControlPoints.Add(5, new Vector3(-1.75f, 10, 15.5f));
  480.             platformCurve.ControlPoints.Add(10, new Vector3(-19.3f, 10, 15.5f));
  481.             platformCurve.ControlPoints.Add(12, new Vector3(-19.3f, 10, 15.5f));
  482.             platformCurve.ControlPoints.Add(15, new Vector3(-25, 10, 15.5f));
  483.             platformCurve.ControlPoints.Add(22, new Vector3(-25, 10, 38));
  484.             platformCurve.ControlPoints.Add(23, new Vector3(-22.75f, 10, 38));
  485.             platformCurve.ControlPoints.Add(25, new Vector3(-22.75f, 10, 38));
  486.  
  487.             //Make it spin too.  That'll be fun.  Or something.
  488.             var platformRotationCurve = new QuaternionSlerpCurve();
  489.             platformRotationCurve.PreLoop = CurveEndpointBehavior.Mirror;
  490.             platformRotationCurve.PostLoop = CurveEndpointBehavior.Mirror;
  491.             platformRotationCurve.ControlPoints.Add(0, Quaternion.Identity);
  492.             platformRotationCurve.ControlPoints.Add(15, Quaternion.Identity);
  493.             platformRotationCurve.ControlPoints.Add(22, Quaternion.CreateFromAxisAngle(Vector3.Up, MathHelper.PiOver2));
  494.             platformRotationCurve.ControlPoints.Add(25, Quaternion.CreateFromAxisAngle(Vector3.Up, MathHelper.PiOver2));
  495.  
  496.             platformMover = new EntityMover(movingEntity);
  497.             platformRotator = new EntityRotator(movingEntity);
  498.             Space.Add(platformMover);
  499.             Space.Add(platformRotator);
  500.             Space.Add(movingEntity);
  501.  
  502.             platformPath = platformCurve;
  503.             platformOrientationPath = platformRotationCurve;
  504.  
  505.             //Add in a diving board.
  506.  
  507.             Box divingBoardBase = new Box(new Vector3(-9, 10, 39.3f), 5, 1, 3);
  508.             Box divingBoard = new Box(divingBoardBase.Position + new Vector3(-2, 0, 3.5f), 1, .3f, 3, 5);
  509.             var divingBoardJoint = new RevoluteJoint(divingBoardBase, divingBoard, divingBoard.Position + new Vector3(0, 0, -1.5f), Vector3.Right);
  510.             divingBoardJoint.Motor.IsActive = true;
  511.             divingBoardJoint.Motor.Settings.Mode = MotorMode.Servomechanism;
  512.             divingBoardJoint.Motor.Settings.Servo.Goal = 0;
  513.             divingBoardJoint.Motor.Settings.Servo.SpringSettings.Stiffness = 5000;
  514.             divingBoardJoint.Motor.Settings.Servo.SpringSettings.Damping = 0;
  515.  
  516.             Space.Add(divingBoardBase);
  517.             Space.Add(divingBoard);
  518.             Space.Add(divingBoardJoint);
  519.  
  520.  
  521.             //Add a second diving board for comparison.
  522.  
  523.             Box divingBoard2 = new Box(divingBoardBase.Position + new Vector3(2, 0, 5f), 1, .3f, 6, 5);
  524.             var divingBoardJoint2 = new RevoluteJoint(divingBoardBase, divingBoard2, divingBoard2.Position + new Vector3(0, 0, -3), Vector3.Right);
  525.             divingBoardJoint2.Motor.IsActive = true;
  526.             divingBoardJoint2.Motor.Settings.Mode = MotorMode.Servomechanism;
  527.             divingBoardJoint2.Motor.Settings.Servo.Goal = 0;
  528.             divingBoardJoint2.Motor.Settings.Servo.SpringSettings.Stiffness = 10000;
  529.             divingBoardJoint2.Motor.Settings.Servo.SpringSettings.Damping = 0;
  530.  
  531.             Space.Add(divingBoard2);
  532.             Space.Add(divingBoardJoint2);
  533.  
  534.             //Add a seesaw for people to jump on.
  535.             Box seesawBase = new Box(new Vector3(-7, .45f, 52), 1, .9f, .3f);
  536.             Box seesawPlank = new Box(seesawBase.Position + new Vector3(0, .65f, 0), 1.2f, .2f, 6, 3);
  537.             RevoluteJoint seesawJoint = new RevoluteJoint(seesawBase, seesawPlank, seesawPlank.Position, Vector3.Right);
  538.             Space.Add(seesawJoint);
  539.             Space.Add(seesawBase);
  540.             Space.Add(seesawPlank);
  541.  
  542.             Space.Add(new Box(seesawPlank.Position + new Vector3(0, 1.3f, 2), 1, 1, 1, 5));
  543.  
  544.  
  545.             //Add in some boxes to bump and jump on.
  546.             int numColumns = 3;
  547.             int numRows = 3;
  548.             int numHigh = 3;
  549.             float xSpacing = 1.01f;
  550.             float ySpacing = 1.01f;
  551.             float zSpacing = 1.01f;
  552.             for (int i = 0; i < numRows; i++)
  553.                 for (int j = 0; j < numColumns; j++)
  554.                     for (int k = 0; k < numHigh; k++)
  555.                     {
  556.                         Space.Add(new Box(new Vector3(
  557.                                                  5 + xSpacing * i - (numRows - 1) * xSpacing / 2f,
  558.                                                  1.58f + k * (ySpacing),
  559.                                                  45 + zSpacing * j - (numColumns - 1) * zSpacing / 2f),
  560.                                              .5f, .5f, .5f, 5));
  561.                     }
  562.  
  563.  
  564.  
  565.             //Add a log to roll!
  566.             //Make it a compound so some boxes can be added to let the player know it's actually spinning.
  567.             CompoundBody log = new CompoundBody(new List<CompoundShapeEntry>()
  568.             {
  569.                 new CompoundShapeEntry(new CylinderShape(4, 1.8f), Quaternion.CreateFromAxisAngle(Vector3.Forward, MathHelper.PiOver2), 20),
  570.                 new CompoundShapeEntry(new BoxShape(.5f, .5f, 3.7f),  new Vector3(1.75f, 0,0), 0),
  571.                 new CompoundShapeEntry(new BoxShape(.5f, 3.7f, .5f), new Vector3(1.75f, 0,0), 0),
  572.                 new CompoundShapeEntry(new BoxShape(.5f, .5f, 3.7f),  new Vector3(-1.75f, 0,0), 0),
  573.                 new CompoundShapeEntry(new BoxShape(.5f, 3.7f, .5f), new Vector3(-1.75f, 0,0), 0)
  574.             }, 50);
  575.             log.Position = new Vector3(-14.5f, 10, 41);
  576.             log.AngularDamping = 0;
  577.  
  578.  
  579.             RevoluteJoint logJointA = new RevoluteJoint(divingBoardBase, log, log.Position + new Vector3(2.5f, 0, 0), Vector3.Right);
  580.             RevoluteJoint logJointB = new RevoluteJoint(endPlatform, log, log.Position + new Vector3(-2.5f, 0, 0), Vector3.Right);
  581.             Space.Add(logJointA);
  582.             Space.Add(logJointB);
  583.  
  584.             Space.Add(log);
  585.  
  586.  
  587.             //Put some planks to stand on that show various slopes.
  588.             int numPads = 10;
  589.             for (int i = 0; i < numPads; i++)
  590.             {
  591.                 offset = new Vector3(0, 0, 4);
  592.                 Box a = new Box(new Vector3(i * 1.5f + 3.5f, 10, 24), 1.5f, 1, 4);
  593.                 Box b = new Box(new Vector3(i * 1.5f + 3.5f, 10, 24), 1.5f, 1, 4);
  594.                 float angle = -i * MathHelper.PiOver2 / numPads;
  595.                 b.Orientation = Quaternion.CreateFromAxisAngle(Vector3.Right, angle);
  596.                 b.Position += offset * .5f + Quaternion.Transform(offset * .5f, b.Orientation);
  597.  
  598.                 Space.Add(a);
  599.                 Space.Add(b);
  600.             }
  601.  
  602.         }
  603.  
  604.         EntityMover elevatorMover;
  605.         Path<Vector3> elevatorPath;
  606.         EntityMover platformMover;
  607.         EntityRotator platformRotator;
  608.         Path<Vector3> platformPath;
  609.         Path<Quaternion> platformOrientationPath;
  610.         double pathTime;
  611.  
  612.  
  613.         public override void Update(float dt)
  614.         {
  615.             //Increment the time.  Note that the space's timestep is used
  616.             //instead of the method's dt.  This is because the demos, by
  617.             //default, update the space once each game update.  Using the
  618.             //space's update time keeps things synchronized.
  619.             //If the engine is using internal time stepping,
  620.             //the passed in dt should be used instead (or put this logic into
  621.             //an updateable that runs with space updates).
  622.             pathTime += Space.TimeStepSettings.TimeStepDuration;
  623.             elevatorMover.TargetPosition = elevatorPath.Evaluate(pathTime);
  624.             platformMover.TargetPosition = platformPath.Evaluate(pathTime);
  625.             platformRotator.TargetOrientation = platformOrientationPath.Evaluate(pathTime);
  626.             base.Update(dt);
  627.         }
  628.  
  629.         public override void DrawUI()
  630.         {
  631. #if XBOX360
  632.             Game.DataTextDrawer.Draw("Press \"A\" to toggle the character.", new Microsoft.Xna.Framework.(50, 50));
  633. #else
  634.             Game.DataTextDrawer.Draw("Press \"C\" to toggle the character.", new Microsoft.Xna.Framework.Vector2(50, 50));
  635. #endif
  636.             base.DrawUI();
  637.         }
  638.  
  639.         /// <summary>
  640.         /// Gets the name of the simulation.
  641.         /// </summary>
  642.         public override string Name
  643.         {
  644.             get { return "Character Playground"; }
  645.         }
  646.     }
  647. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement