Esempio n. 1
0
        public override void Initialize()
        {
            var model = TryAndGetModelFromOwner();

            if (model != null)
            {
                Vector3[] vertices;
                int[]     indices;

                ModelDataExtractor.GetVerticesAndIndicesFromModel(model, out vertices, out indices);

                BoundingBox _aabb = BoundingBox.CreateFromPoints(vertices);
                Vector3     xsize = _aabb.Max - _aabb.Min;

                if (Mass <= 0)
                {
                    //kinematic
                    Entity = new Cylinder(MathConverter.Convert(Owner.World.Translation),
                                          xsize.Y, xsize.X / 2);
                }
                else
                {
                    //dynamic
                    Entity = new Cylinder(MathConverter.Convert(Owner.World.Translation),
                                          xsize.Y, xsize.X / 2, Mass);
                }
            }

            base.Initialize();
        }
Esempio n. 2
0
        public override void Initialized()
        {
            var Model = TryAndGetModelFromOwner();

            if (Model != null)
            {
                Vector3[] Vertices;
                int[]     indices;

                ModelDataExtractor.GetVerticesAndIndicesFromModel(Model, out Vertices, out indices);
                BoundingBox aabb = BoundingBox.CreateFromPoints(Vertices);
                Vector3     size = aabb.Max - aabb.Min;

                if (Mass <= 0)
                {
                    Entity = new Box(MathConverter.Convert(Owner.World.Translation), size.X, size.Y, size.Z);
                }
                else
                {
                    Entity = new Box(MathConverter.Convert(Owner.World.Translation), size.X, size.Y, size.Z, Mass);
                }
            }



            base.Initialized();
        }
Esempio n. 3
0
        /// <summary>
        /// Constructs a new demo.
        /// </summary>
        /// <param name="game">Game owning this demo.</param>
        public DetectorVolumeDemo(DemosGame game)
            : base(game)
        {
            var tubeModel = game.Content.Load <Model>("tube");

            Vector3[] modelVertices;
            int[]     modelIndices;
            ModelDataExtractor.GetVerticesAndIndicesFromModel(tubeModel, out modelVertices, out modelIndices);
            var detectorVolume = new DetectorVolume(new StaticMeshData(modelVertices, modelIndices), Space.BroadPhase.QueryAccelerator);

            Space.Add(detectorVolume);

            game.ModelDrawer.Add(detectorVolume.TriangleMesh);

            Entity toAdd = new Box(new Vector3(0, -10, 0), 1, 1, 1);

            toAdd.Tag  = "noDisplayObject";
            displayBox = game.ModelDrawer.Add(toAdd);
            displayBox.TextureIndex      = 0;
            game.ModelDrawer.IsWireframe = true;
            toAdd.LinearVelocity         = new Vector3(0, 1, 0);
            Space.Add(toAdd); //Create the ground

            detectorVolume.EntityBeginsTouching         += BeginsTouching;
            detectorVolume.EntityStopsTouching          += StopsTouching;
            detectorVolume.VolumeBeginsContainingEntity += BeginsContaining;
            detectorVolume.VolumeStopsContainingEntity  += StopsContaining;

            game.Camera.Position = new Microsoft.Xna.Framework.Vector3(0, 0, 22);
        }
Esempio n. 4
0
        public override void Initialize()
        {
            var model = TryAndGetModelFromOwner();

            if (model != null)
            {
                Vector3[] vertices;
                int[]     indices;

                ModelDataExtractor.GetVerticesAndIndicesFromModel(model, out vertices, out indices);

                BoundingSphere _aabb = BoundingSphere.CreateFromPoints(vertices);

                if (Mass <= 0)
                {
                    //kinematic
                    Entity = new Sphere(MathConverter.Convert(Owner.World.Translation),
                                        _aabb.Radius);
                }
                else
                {
                    //dynamic
                    Entity = new Sphere(MathConverter.Convert(Owner.World.Translation),
                                        _aabb.Radius, Mass);
                }
            }

            base.Initialize();
        }
        public override void Initialized()
        {
            if (Owner.HasComponent <BasicEffectModel>())
            {
                BasicEffectModel modelComp = Owner.GetComponent <BasicEffectModel>();

                Vector3[] vertices;
                int[]     indices;

                ModelDataExtractor.GetVerticesAndIndicesFromModel(modelComp.Model, out vertices, out indices);

                AABB = BoundingBox.CreateFromPoints(vertices);
                AABS = BoundingSphere.CreateFromPoints(vertices);

                AABS.Center = Vector3.Transform(AABS.Center, Owner.World);
                AABB.Max    = Vector3.Transform(AABB.Max, Owner.World);
                AABB.Min    = Vector3.Transform(AABB.Min, Owner.World);

                ray = new Ray(Owner.World.Translation, new Vector3(-1, 0, 0));
            }
            else
            {
                Destroy();
            }
            base.Initialized();
        }
        /// <summary>
        /// Constructs a new demo.
        /// </summary>
        /// <param name="game">Game owning this demo.</param>
        public PrimitiveSceneBugDemo(DemosGame game)
            : base(game)
        {
            character = new BugShowerCharacterController(Space, game.Camera, game);
            Space.ForceUpdater.Gravity = new Vector3(0, -16, 0);
            game.Camera.Position       = new Vector3(5, 0.85f, 4);
            game.Camera.ViewDirection  = new Vector3(0, 0, 1);
            //Since this is the character playground, turn on the character by default.
            character.Activate();
            //Having the character body visible would be a bit distracting.
            character.CharacterController.Body.Tag = "noDisplayObject";

            //Load in mesh data for the environment.
            Vector3[] staticTriangleVertices;
            int[]     staticTriangleIndices;


            var playgroundModel = game.Content.Load <Model>("bugPrimitiveRoom");

            //This is a little convenience method used to extract vertices and indices from a model.
            //It doesn't do anything special; any approach that gets valid vertices and indices will work.
            ModelDataExtractor.GetVerticesAndIndicesFromModel(playgroundModel, out staticTriangleVertices, out staticTriangleIndices);
            var staticMesh = new StaticMesh(staticTriangleVertices, staticTriangleIndices, new AffineTransform(new Vector3(1, 1, 1), Quaternion.Identity, new Vector3(0, 0, 0)));

            staticMesh.Sidedness = TriangleSidedness.Counterclockwise;

            Space.Add(staticMesh);
            game.ModelDrawer.Add(staticMesh);
        }
        /// <summary>
        /// Constructs a new demo.
        /// </summary>
        /// <param name="game">Game owning this demo.</param>
        public AddRemoveStressDemo(DemosGame game)
            : base(game)
        {
            Space.Remove(vehicle.Vehicle);

            var compoundShape = new CompoundShape(new List <CompoundShapeEntry>
            {
                new CompoundShapeEntry(new BoxShape(1, 1, 1), new Vector3(0, 1, 0), 1),
                new CompoundShapeEntry(new BoxShape(2, 1, 2), new Vector3(), 1),
                new CompoundShapeEntry(new BoxShape(1, 1, 1), new Vector3(0, -1, 0), 1)
            });

            for (int i = 0; i < 300; ++i)
            {
                var toAdd = new Entity(compoundShape, 10);
                addedEntities.Add(toAdd);
            }

            var boxShape = new BoxShape(1, 1, 1);

            for (int i = 0; i < 300; ++i)
            {
                var toAdd = new Entity(boxShape, 10);
                addedEntities.Add(toAdd);
            }

            Vector3[] vertices;
            int[]     indices;
            ModelDataExtractor.GetVerticesAndIndicesFromModel(game.Content.Load <Model>("cube"), out vertices, out indices);
            var mobileMeshShape = new MobileMeshShape(vertices, indices, new AffineTransform(Matrix3x3.CreateScale(1, 2, 1), new Vector3()), MobileMeshSolidity.Counterclockwise);

            for (int i = 0; i < 300; ++i)
            {
                var toAdd = new Entity(mobileMeshShape, 10);
                addedEntities.Add(toAdd);
            }

            for (int i = 0; i < addedEntities.Count; ++i)
            {
                var entity = addedEntities[i];
                entity.Gravity        = new Vector3();
                entity.Position       = GetRandomPosition(random);
                entity.LinearVelocity = 3 * Vector3.Normalize(entity.Position);
                Space.Add(entity);
            }


            var playgroundModel = game.Content.Load <Model>("playground");

            ModelDataExtractor.GetVerticesAndIndicesFromModel(playgroundModel, out vertices, out indices);
            var staticMesh = new StaticMesh(vertices, indices, new AffineTransform(Matrix3x3.CreateFromAxisAngle(Vector3.Up, MathHelper.Pi), new Vector3(0, -30, 0)));

            staticMesh.Sidedness = TriangleSidedness.Counterclockwise;

            Space.Add(staticMesh);
            game.ModelDrawer.Add(staticMesh);

            game.Camera.Position = new Vector3(0, 6, 15);
        }
Esempio n. 8
0
        private void CreateBoundingBox(Model model)
        {
            Vector3[] vertices;
            int[]     indices;
            ModelDataExtractor.GetVerticesAndIndicesFromModel(model, out vertices, out indices);

            BoundingBox = BoundingBox.CreateFromPoints(vertices);
        }
        /// <summary>
        /// Constructs a new demo.
        /// </summary>
        /// <param name="game">Game owning this demo.</param>
        public GraphicMatchingDemo(DemosGame game)
            : base(game)
        {
            //When creating a collision shape based on a model, the graphic will generally be offset at first.
            //This is because the collision shape computes the center of mass and offsets itself to align with the local origin.
            //That offset must be applied to the graphic to make it match the collision shape.

            //Check out the documentation page for more information:
            //http://bepuphysics.codeplex.com/wikipage?title=Shape%20Recentering

            var model = game.Content.Load <Model>("guy");

            BEPUutilities.Vector3[] vertices;
            int[] indices;
            ModelDataExtractor.GetVerticesAndIndicesFromModel(model, out vertices, out indices);

            //Create an entity based on the model.
            ConvexHull hull = new ConvexHull(vertices, 10);

            Space.Add(hull);
            //Create a graphic for the hull.  The BEPUphysicsDrawer will also automatically receive a visualization of the convex hull which we can compare our graphic against.
            //The graphic will be offset from the collision shape because we have not attempted to offset it to match the collision shape's origin.
            var graphic = new DisplayEntityModel(hull, model, game.ModelDrawer);

            game.ModelDrawer.Add(graphic);


            //Now let's create another entity from the same vertices.
            hull = new ConvexHull(vertices, 10);
            Space.Add(hull);

            //Note that the prefab entity type ConvexHull uses the ConvexHullShape constructor internally, which outputs the computed center of the shape
            //prior to offset.  The ConvexHull constructor sets the entity's Position to that position so that the initial world space location of the vertices
            //matches what was passed into the constructor.
            //The same process could be performed using this code:

            //Vector3 computedCenter;
            //var shape = new ConvexHullShape(vertices, out computedCenter); //<-- It spits out the computed center here; this is what is used to offset the graphic!
            //var entity = new Entity(shape, 10);
            //entity.Position = computedCenter;
            //Space.Add(entity);

            //For more information about constructing entities, check out the EntityConstructionDemo.

            //But for now, let's just use the prefab entity type.  As mentioned earlier, the constructor set the entity's Position using the computed center.
            //Since we didn't overwrite it with some other position yet, we can still use it.
            graphic = new DisplayEntityModel(hull, model, game.ModelDrawer);
            graphic.LocalTransform = Matrix.CreateTranslation(-hull.Position);
            game.ModelDrawer.Add(graphic);

            //This graphic is perfectly aligned with the collision shape!  Hooray!


            Box ground = new Box(new Vector3(0, -1.5m, 0), 50, 1, 50);

            Space.Add(ground);
            game.Camera.Position = new Vector3(0, 6, 15);
        }
Esempio n. 10
0
        /// <summary>
        /// Constructs a new demo.
        /// </summary>
        /// <param name="game">Game owning this demo.</param>
        public MobileMeshDemo(DemosGame game)
            : base(game)
        {
            Vector3[] vertices;
            int[]     indices;

            //Create a big hollow sphere (squished into an ellipsoid).
            ModelDataExtractor.GetVerticesAndIndicesFromModel(game.Content.Load <Model>("hollowsphere"), out vertices, out indices);
            var transform = new AffineTransform(new Vector3(.06f, .04f, .06f), Quaternion.Identity, new Vector3(0, 0, 0));

            //Note that meshes can also be made solid (MobileMeshSolidity.Solid).  This gives meshes a solid collidable volume, instead of just
            //being thin shells.  However, enabling solidity is more expensive.
            var mesh = new MobileMesh(vertices, indices, transform, MobileMeshSolidity.Counterclockwise);

            mesh.Position = new Vector3(0, 0, 0);
            //Make the mesh spin a bit!
            mesh.AngularVelocity = new Vector3(0, 1, 0);
            Space.Add(mesh);

            //Add another mobile mesh inside.
            ModelDataExtractor.GetVerticesAndIndicesFromModel(game.Content.Load <Model>("tube"), out vertices, out indices);
            transform     = new AffineTransform(new Vector3(1, 1, 1), Quaternion.Identity, new Vector3(0, 0, 0));
            mesh          = new MobileMesh(vertices, indices, transform, MobileMeshSolidity.Counterclockwise, 10);
            mesh.Position = new Vector3(0, 10, 0);
            Space.Add(mesh);

            //Create a bunch of boxes.
#if WINDOWS
            int numColumns = 5;
            int numRows    = 5;
            int numHigh    = 5;
#else
            //Keep the simulation a bit smaller on the xbox.
            int numColumns = 4;
            int numRows    = 4;
            int numHigh    = 4;
#endif
            float separation = 1.5f;


            for (int i = 0; i < numRows; i++)
            {
                for (int j = 0; j < numColumns; j++)
                {
                    for (int k = 0; k < numHigh; k++)
                    {
                        Space.Add(new Box(new Vector3(separation * i, k * separation, separation * j), 1, 1, 1, 5));
                    }
                }
            }

            //Space.Add(new Box(new Vector3(0, -10, 0), 1, 1, 1));
            game.Camera.Position = new Microsoft.Xna.Framework.Vector3(0, -10, 5);
            game.Camera.Yaw      = 0;
            game.Camera.Pitch    = 0;
        }
Esempio n. 11
0
        public void Generate(BasicEntity entity)
        {
            //Extract all triangles
            //foreach (ModelMesh modelmesh in entity.Model.Meshes)
            //{
            //    foreach (ModelMeshPart part in modelmesh.MeshParts)
            //    {
            //        VertexPositionNormalTexture[] vertices = new VertexPositionNormalTexture[part.VertexBuffer.VertexCount];
            //        part.VertexBuffer.GetData<VertexPositionNormalTexture>(vertices);

            //        ushort[] drawOrder = new ushort[part.IndexBuffer.IndexCount];
            //        part.IndexBuffer.GetData<ushort>(drawOrder);

            //        foreach (var vertex in vertices)
            //        {
            //            points.Add(vertex.Position);
            //        }
            //    }
            //}

            generateTris = Task.Factory.StartNew(() =>
            {
                int[] indices;
                ModelDataExtractor.GetVerticesAndIndicesFromModel(entity.Model, out vertices, out indices);

                triangles = new Triangle[indices.Length / 3];

                for (var index = 0; index < vertices.Length; index++)
                {
                    vertices[index] = Vector3.Transform(vertices[index], entity.WorldTransform.World);
                }

                int baseIndex = 0;
                for (var i = 0; i < triangles.Length; i++, baseIndex += 3)
                {
                    triangles[i].a = vertices[indices[baseIndex]];
                    triangles[i].b = vertices[indices[baseIndex + 1]];
                    triangles[i].c = vertices[indices[baseIndex + 2]];
                    //normal
                    triangles[i].n = Vector3.Cross(triangles[i].c - triangles[i].a, triangles[i].b - triangles[i].a);

                    triangles[i].ba = triangles[i].b - triangles[i].a;
                    triangles[i].cb = triangles[i].c - triangles[i].b;
                    triangles[i].ac = triangles[i].a - triangles[i].c;
                }
            });
            //for (var index = 0; index < points.Length; index++)
            //{
            //    points[index] = Vector3.Transform(points[index], entity.WorldTransform.World);
            //}
        }
Esempio n. 12
0
        /// <summary>
        /// Constructs a new demo.
        /// </summary>
        /// <param name="game">Game owning this demo.</param>
        public StaticMeshDemo(DemosGame game)
            : base(game)
        {
            //Load in mesh data and create the group.
            Vector3[] staticTriangleVertices;
            int[]     staticTriangleIndices;

            var playgroundModel = game.Content.Load <Model>("playground");

            //This load method wraps the TriangleMesh.GetVerticesAndIndicesFromModel method
            //to output vertices of type StaticTriangleGroupVertex instead of TriangleMeshVertex or simply Vector3.
            ModelDataExtractor.GetVerticesAndIndicesFromModel(playgroundModel, out staticTriangleVertices, out staticTriangleIndices);
            var staticMesh = new StaticMesh(staticTriangleVertices, staticTriangleIndices, new AffineTransform(Matrix3X3.CreateFromAxisAngle(Vector3.Up, MathHelper.Pi), new Vector3(0, -10, 0)));

            staticMesh.Sidedness = TriangleSidedness.Counterclockwise;

            Space.Add(staticMesh);
            game.ModelDrawer.Add(staticMesh);



            //Dump some boxes on top of it for fun.
            int    numColumns = 8;
            int    numRows    = 8;
            int    numHigh    = 1;
            float  separation = 8;
            Entity toAdd;

            for (int i = 0; i < numRows; i++)
            {
                for (int j = 0; j < numColumns; j++)
                {
                    for (int k = 0; k < numHigh; k++)
                    {
                        toAdd = new Box(
                            new Vector3(
                                separation * i - numRows * separation / 2,
                                30f + k * separation,
                                separation * j - numColumns * separation / 2),
                            2, 2, 2, 15);

                        Space.Add(toAdd);
                    }
                }
            }



            game.Camera.Position = new Microsoft.Xna.Framework.Vector3(0, 10, 40);
        }
Esempio n. 13
0
        public Vector3 MeasureMesh(Model meshToMeasure)
        {
            Vector3[] vertices;
            int[]     indices;

            ModelDataExtractor.GetVerticesAndIndicesFromModel(
                meshToMeasure,
                out vertices,
                out indices);

            var box = BoundingBox.CreateFromPoints(vertices);

            return(box.Max - box.Min);//size of box
        }
Esempio n. 14
0
        /// <summary>
        /// Create a static physics mesh from a model and scale.
        /// </summary>
        /// <param name="entity"></param>
        private void AddStaticPhysics(BasicEntity entity)
        {
            BEPUutilities.Vector3[] vertices;
            int[] indices;
            ModelDataExtractor.GetVerticesAndIndicesFromModel(entity.Model, out vertices, out indices);
            var mesh = new StaticMesh(vertices, indices,
                                      new AffineTransform(
                                          new BEPUutilities.Vector3(entity.Scale.X, entity.Scale.Y, entity.Scale.Z),
                                          Quaternion.CreateFromRotationMatrix(MathConverter.Convert(entity.RotationMatrix)),
                                          MathConverter.Convert(entity.Position)));

            entity.StaticPhysicsObject = mesh;
            _physicsSpace.Add(mesh);
        }
        /// <summary>
        /// Constructs a new demo.
        /// </summary>
        /// <param name="game">Game owning this demo.</param>
        public DetectorVolumeDemo(DemosGame game)
            : base(game)
        {
            var model = game.Content.Load <Model>("tube");

            Vector3[] modelVertices;
            int[]     modelIndices;
            ModelDataExtractor.GetVerticesAndIndicesFromModel(model, out modelVertices, out modelIndices);
            detectorVolume = new DetectorVolume(new TriangleMesh(new StaticMeshData(modelVertices, modelIndices)));
            Space.Add(detectorVolume);

            game.ModelDrawer.Add(detectorVolume.TriangleMesh);

            //The detector volume works on all of the entity types:
            //Convexes!
            testEntity = new Box(new Vector3(0, -10, 0), 1, 1, 1);

            //Compounds!
            //var bodies = new List<CompoundShapeEntry>
            //{
            //    new CompoundShapeEntry(new SphereShape(.5f), new Vector3(0, -8.2f, 0), 1),
            //    new CompoundShapeEntry(new SphereShape(.5f), new Vector3(0, -9f, 0), 1),
            //    new CompoundShapeEntry(new SphereShape(.5f), new Vector3(0, -9.8f, 0), 1)
            //};
            //testEntity = new CompoundBody(bodies);

            //Mobile meshes!
            //model = game.Content.Load<Model>("tube");
            //TriangleMesh.GetVerticesAndIndicesFromModel(model, out modelVertices, out modelIndices);
            //testEntity = new MobileMesh(modelVertices, modelIndices, new AffineTransform(new Vector3(.2f, .2f, .2f), Quaternion.Identity, new Vector3(0, -10, 0)), MobileMeshSolidity.Solid);

            testEntity.Tag = "noDisplayObject";
            displayBox     = game.ModelDrawer.Add(testEntity);
            SetColor(0);
            game.ModelDrawer.IsWireframe = true;
            testEntity.LinearVelocity    = new Vector3(0, 1, 0);
            Space.Add(testEntity);

            //The color of the entity will change based upon events.
            //The events don't pay attention to the causing events, so you can toss a ball through the volume to recolor the entity.
            detectorVolume.EntityBeganTouching           += BeganTouching;
            detectorVolume.EntityStoppedTouching         += StoppedTouching;
            detectorVolume.VolumeBeganContainingEntity   += BeganContaining;
            detectorVolume.VolumeStoppedContainingEntity += StoppedContaining;

            game.Camera.Position       = new Vector3(0, 0, 22);
            Space.ForceUpdater.Gravity = new Vector3();
        }
        void FillSpace(Space space, ModelDrawer modelDrawer = null)
        {
            Entity ground = new MorphableEntity(new BoxShape(50, 1, 50));

            space.Add(ground);
            space.ForceUpdater.Gravity = new Vector3(0, -10, 0);

            ModelDataExtractor.GetVerticesAndIndicesFromModel(Game.Content.Load <Model>("playground"), out Vector3[] vertices, out int[] indices);
            var mesh = new StaticMesh(vertices, indices, new AffineTransform(new Vector3(50, -20, 0)));

            space.Add(mesh);
            modelDrawer?.Add(mesh);

            for (int i = 0; i < 100; i++)
            {
                Entity e = new Box(new Vector3(.1f * i, 1 * i + 1, 0), 1, 1, 1, 1);
                //Entity e = new Capsule(new Vector3(.1f * i, 1 * i + 1, 0), .5f, .5f, 1);
                //Entity e = new Sphere(new Vector3(.1f * i, 1 * i + 1, 0), .5f, 1);
                e.ActivityInformation.IsAlwaysActive = true;
                e.CollisionInformation.Tag           = i;
                space.Add(e);
            }
            for (int i = 0; i < 200; i++)
            {
                //Entity e = new Box(new Vector3(.1f * i, 1 * i + 1, 2), 1, 1, 1, 1);
                Entity e = new Capsule(new Vector3(.1f * i, 1 * i + 1, 2), .5f, .5f, 1);
                //Entity e = new Sphere(new Vector3(.1f * i, 1 * i + 1, 2), .5f, 1);
                e.ActivityInformation.IsAlwaysActive = true;
                e.CollisionInformation.Tag           = i;
                space.Add(e);
            }
            for (int i = 0; i < 300; i++)
            {
                //Entity e = new Box(new Vector3(.1f * i, 1 * i + 1, 4), 1, 1, 1, 1);
                //Entity e = new Capsule(new Vector3(.1f * i, 1 * i + 1, 4), .5f, .5f, 1);
                Entity e = new Sphere(new Vector3(.1f * i, 1 * i + 1, 4), .5f, 1);
                e.ActivityInformation.IsAlwaysActive = true;
                e.CollisionInformation.Tag           = i;
                space.Add(e);
            }
            if (modelDrawer != null)
            {
                for (int i = 0; i < space.Entities.Count; ++i)
                {
                    modelDrawer.Add(space.Entities[i]);
                }
            }
        }
Esempio n. 17
0
        /// <summary>
        /// Constructs a new demo.
        /// </summary>
        /// <param name="game">Game owning this demo.</param>
        public StaticMeshDemo(DemosGame game)
            : base(game)
        {
            //Load in mesh data and create the collision mesh.
            Vector3[] staticTriangleVertices;
            int[]     staticTriangleIndices;

            var playgroundModel = game.Content.Load <Model>("playground");

            //This is a little convenience method used to extract vertices and indices from a model.
            //It doesn't do anything special; any approach that gets valid vertices and indices will work.
            ModelDataExtractor.GetVerticesAndIndicesFromModel(playgroundModel, out staticTriangleVertices, out staticTriangleIndices);
            var staticMesh = new StaticMesh(staticTriangleVertices, staticTriangleIndices, new AffineTransform(Matrix3x3.CreateFromAxisAngle(Vector3.Up, MathHelper.Pi), new Vector3(0, -10, 0)));

            staticMesh.Sidedness = TriangleSidedness.Counterclockwise;

            Space.Add(staticMesh);
            game.ModelDrawer.Add(staticMesh);


            //Dump some boxes on top of it for fun.
            int   numColumns = 8;
            int   numRows    = 8;
            int   numHigh    = 1;
            Fix64 separation = 8;

            for (int i = 0; i < numRows; i++)
            {
                for (int j = 0; j < numColumns; j++)
                {
                    for (int k = 0; k < numHigh; k++)
                    {
                        var toAdd = new Box(
                            new Vector3(
                                separation * i - numRows * separation / 2,
                                30 + k * separation,
                                separation * j - numColumns * separation / 2),
                            2, 2, 2, 15);
                        Space.Add(toAdd);
                    }
                }
            }



            game.Camera.Position = new Vector3(0, 10, 40);
        }
Esempio n. 18
0
        public Teapot(GameEngine GameEngine, Vector3 StartPosition) :
            base(GameEngine, GameEngine.Model_Items_Teapot, StartPosition)
        {
            //NormalMap = vxEngine.Game.Content.Load<Texture2D>("Models/teapot/teapot_nm");
            //SpecularMap = vxEngine.Game.Content.Load<Texture2D>("Models/teapot/teapot_sm");
            XRotation_ModelOffset = -MathHelper.PiOver2;
            //Vector_ModelOffSet = new Vector3(-0.5f, 1 / 2, 0.5f);
            //entity = new Box(StartPosition - Vector_ModelOffSet, 1, 1, 1, 1000);

            entity      = new Box(StartPosition, 1, 1, 1); //Set up Entity Mover
            entityMover = new EntityMover(entity);

            //Add Entities too Physics Sim
            vxEngine.Current3DSceneBase.BEPUPhyicsSpace.Add(entity);
            vxEngine.Current3DSceneBase.BEPUDebugDrawer.Add(entity);
            vxEngine.Current3DSceneBase.BEPUPhyicsSpace.Add(entityMover);


            ModelDataExtractor.GetVerticesAndIndicesFromModel(vxModel.ModelMain, out staticTriangleVertices, out staticTriangleIndices);
        }
Esempio n. 19
0
        public ConcreteCube(GameEngine GameEngine, Vector3 StartPosition) :
            base(GameEngine, GameEngine.Model_Items_Concrete, StartPosition)
        {
            //NormalMap = vxEngine.Game.Content.Load<Texture2D>("Models/concrete_cube/texture_nm");
            //SpecularMap = vxEngine.Game.Content.Load<Texture2D>("Models/concrete_cube/texture_sm");
            XRotation_ModelOffset = -MathHelper.PiOver2;

            ModelDataExtractor.GetVerticesAndIndicesFromModel(vxModel.ModelMain, out staticTriangleVertices, out staticTriangleIndices);

            entity      = new Box(StartPosition, 1, 1, 1); //Set up Entity Mover
            entityMover = new EntityMover(entity);

            //Add Entities too Physics Sim
            vxEngine.Current3DSceneBase.BEPUPhyicsSpace.Add(entity);
            vxEngine.Current3DSceneBase.BEPUDebugDrawer.Add(entity);
            vxEngine.Current3DSceneBase.BEPUPhyicsSpace.Add(entityMover);
            SpecularIntensity = 1;

            GameEngine.Model_Items_Concrete.SetTexturePackLevel(vxEnumTextureQuality.Ultra);
        }
Esempio n. 20
0
        /// <summary>
        /// Constructs a new demo.
        /// </summary>
        /// <param name="game">Game owning this demo.</param>
        public InstancedMeshDemo(DemosGame game)
            : base(game)
        {
            Vector3[] vertices;
            int[]     indices;
            ModelDataExtractor.GetVerticesAndIndicesFromModel(game.Content.Load <Model>("guy"), out vertices, out indices);
            var meshShape = new InstancedMeshShape(vertices, indices);

            var random = new Random();

            for (int i = 0; i < 10; i++)
            {
                for (int j = 0; j < 10; j++)
                {
                    //Create a transform and the instance of the mesh.
                    var transform = new AffineTransform(
                        new Vector3((Fix64)random.NextDouble() * 6 + .5m, (Fix64)random.NextDouble() * 6 + .5m, (Fix64)random.NextDouble() * 6 + .5m),
                        Quaternion.CreateFromAxisAngle(Vector3.Normalize(new Vector3((Fix64)random.NextDouble(), (Fix64)random.NextDouble(), (Fix64)random.NextDouble())), (Fix64)random.NextDouble() * 100),
                        new Vector3(i * 2, 3, j * 2));
                    var mesh = new InstancedMesh(meshShape, transform);
                    //Making the triangles one-sided makes collision detection a bit more robust, since the backsides of triangles won't try to collide with things
                    //and 'pull' them back into the mesh.
                    mesh.Sidedness = TriangleSidedness.Counterclockwise;
                    Space.Add(mesh);
                    game.ModelDrawer.Add(mesh);
                }
            }

            for (int i = 0; i < 5; i++)
            {
                for (int j = 0; j < 5; j++)
                {
                    //Drop a box on the mesh.
                    Space.Add(new Box(new Vector3((i + 1) * 4, 10, (j + 1) * 4), 1, 1, 1, 10));
                }
            }

            Space.Add(new Box(new Vector3(10, 0, 10), 20, 1, 20));

            game.Camera.Position = new Vector3(10, 6, 30);
        }
        /// <summary>
        /// Constructs a new demo.
        /// </summary>
        /// <param name="game">Game owning this demo.</param>
        public FishInABarrelDemo(DemosGame game)
            : base(game)
        {
            game.Camera.Position = new Vector3(0, 7, 30);

            var detector = new Box(new Vector3(0, 0, 0), 1.5f, 1.5f, 1.5f);

            detector.CollisionInformation.CollisionRules.Personal = CollisionRule.NoSolver;
            var acceptedTriggerEntity = new Box(new Vector3(5, 0, 0), 1.6f, .7f, .4f, 1);

            acceptedTrigger = acceptedTriggerEntity.CollisionInformation;

            detector.Tag = "noDisplayObject";
            acceptedTriggerEntity.Tag = "noDisplayObject";
            Space.Add(detector);
            Space.Add(acceptedTriggerEntity);

            var fish = game.Content.Load <Model>("fish");

            game.ModelDrawer.Add(new DisplayEntityModel(acceptedTriggerEntity, fish, game.ModelDrawer));

            var barrelAndPlatform = game.Content.Load <Model>("barrelAndPlatform");

            Vector3[] staticTriangleVertices;
            int[]     staticTriangleIndices;
            ModelDataExtractor.GetVerticesAndIndicesFromModel(barrelAndPlatform, out staticTriangleVertices, out staticTriangleIndices);

            //Note that the final 'margin' parameter is optional, but can be used to specify a collision margin on triangles in the static triangle group.
            var fishDepositoryGroup = new StaticMesh(staticTriangleVertices, staticTriangleIndices);

            CollisionRules.AddRule(fishDepositoryGroup, detector, CollisionRule.NoBroadPhase);
            Space.Add(fishDepositoryGroup);
            game.ModelDrawer.Add(fishDepositoryGroup);


            movedBox = new Box(new Vector3(-4, 5, 0), 1, 1, 1, 1);
            detector.Space.Add(movedBox);
            detector.CollisionInformation.Events.InitialCollisionDetected += InitialCollisionDetected;
            detector.CollisionInformation.Events.CollisionEnded           += CollisionEnded;
        }
Esempio n. 22
0
        public override void Initialize()
        {
            var model = TryAndGetModelFromOwner();

            if (model != null)
            {
                Vector3[] vertices;
                int[]     indices;

                ModelDataExtractor.GetVerticesAndIndicesFromModel(model, out vertices, out indices);

                var mesh = new StaticMesh(MathConverter.Convert(vertices), indices,
                                          new BEPUutilities.AffineTransform(MathConverter.Convert(Owner.World.Translation)));

                mesh.Tag = Owner.ID;

                //static mesh is the only exception when working with physics entities
                PhysicsManager.AddStaticMesh(mesh);
            }

            base.Initialize();
        }
Esempio n. 23
0
        public void GenerateTriangles(Model model, out Triangle[] triangles)
        {
            Vector3[] vertexPositions;
            int[]     indices;
            ModelDataExtractor.GetVerticesAndIndicesFromModel(model, out vertexPositions, out indices);
            triangles = new Triangle[indices.Length / 3];
            int baseIndex = 0;

            for (var i = 0; i < triangles.Length; i++, baseIndex += 3)
            {
                triangles[i].a = vertexPositions[indices[baseIndex]];
                triangles[i].b = vertexPositions[indices[baseIndex + 1]];
                triangles[i].c = vertexPositions[indices[baseIndex + 2]];
                //normal
                triangles[i].ba = triangles[i].b - triangles[i].a;
                triangles[i].cb = triangles[i].c - triangles[i].b;
                triangles[i].ac = triangles[i].a - triangles[i].c;

                triangles[i].n = Vector3.Cross(triangles[i].ba, triangles[i].ac);
                triangles[i].n.Normalize();
                triangles[i].n *= 0.03f;
            }
        }
Esempio n. 24
0
        public override void Initialize()
        {
            var model = GetModelFromOwner();

            if (model != null)
            {
                Vector3[] vertices;
                int[]     indices;

                ModelDataExtractor.GetVerticesAndIndicesFromModel(
                    model,
                    out vertices,
                    out indices);

                Mesh = new StaticMesh(
                    MathConverter.Convert(vertices),
                    indices,
                    new BEPUutilities.AffineTransform(
                        MathConverter.Convert(Manager.Owner.Location)));
                Mesh.Tag = Manager.Owner.ID;

                PhysicsEngine.AddStaticMesh(Mesh);
            }
        }
Esempio n. 25
0
        /// <summary>
        /// Constructs a new demo.
        /// </summary>
        /// <param name="game">Game owning this demo.</param>
        public StaticGroupDemo(DemosGame game)
            : base(game)
        {
            //Creating a bunch of separate StaticMeshes or kinematic Entity objects for an environment can pollute the broad phase.
            //This is because the broad phase implementation doesn't have guarantees about what elements can collide, so it has to
            //traverse the acceleration structure all the way down to pairs to figure it out.  That can get expensive!

            //Individual objects, like StaticMeshes, can have very complicated geometry without hurting the broad phase because the broad phase
            //has no knowledge of the thousands of triangles in the mesh.  The StaticMesh itself knows that the triangles within the mesh
            //never need to collide, so it never needs to test them against each other.

            //Similarly, the StaticGroup can be given a bunch of separate collidables.  The broad phase doesn't directly know about these child collidables-
            //it only sees the StaticGroup.  The StaticGroup knows that the things inside it can't ever collide with each other, so no tests are needed.
            //This avoids the performance problem!

            //To demonstrate, we'll be creating a set of static objects and giving them to a group to manage.
            var collidables = new List <Collidable>();

            //Start with a whole bunch of boxes.  These are entity collidables, but without entities!
            float xSpacing = 6;
            float ySpacing = 6;
            float zSpacing = 6;


            //NOTE: You might notice this demo takes a while to start, especially on the Xbox360.  Do not fear!  That's due to the creation of the graphics data, not the physics.
            //The physics can handle over 100,000 static objects pretty easily.  The graphics, not so much :)
            //Try disabling the game.ModelDrawer.Add() lines and increasing the number of static objects.
            int xCount = 15;
            int yCount = 7;
            int zCount = 15;


            var random = new Random();

            for (int i = 0; i < xCount; i++)
            {
                for (int j = 0; j < yCount; j++)
                {
                    for (int k = 0; k < zCount; k++)
                    {
                        //Create a transform and the instance of the mesh.
                        var collidable = new ConvexCollidable <BoxShape>(new BoxShape((float)random.NextDouble() * 6 + .5f, (float)random.NextDouble() * 6 + .5f, (float)random.NextDouble() * 6 + .5f));

                        //This EntityCollidable isn't associated with an entity, so we must manually tell it where to sit by setting the WorldTransform.
                        //This also updates its bounding box.
                        collidable.WorldTransform = new RigidTransform(
                            new Vector3(i * xSpacing - xCount * xSpacing * .5f, j * ySpacing + 3, k * zSpacing - zCount * zSpacing * .5f),
                            Quaternion.CreateFromAxisAngle(Vector3.Normalize(new Vector3((float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble())), (float)random.NextDouble() * 100));

                        collidables.Add(collidable);
                        game.ModelDrawer.Add(collidable);
                    }
                }
            }


            //Now create a bunch of instanced meshes too.
            xSpacing = 6;
            ySpacing = 6;
            zSpacing = 6;

            xCount = 10;
            yCount = 2;
            zCount = 10;

            Vector3[] vertices;
            int[]     indices;
            ModelDataExtractor.GetVerticesAndIndicesFromModel(game.Content.Load <Model>("fish"), out vertices, out indices);
            var meshShape = new InstancedMeshShape(vertices, indices);

            for (int i = 0; i < xCount; i++)
            {
                for (int j = 0; j < yCount; j++)
                {
                    for (int k = 0; k < zCount; k++)
                    {
                        //Create a transform and the instance of the mesh.
                        var transform = new AffineTransform(
                            new Vector3((float)random.NextDouble() * 6 + .5f, (float)random.NextDouble() * 6 + .5f, (float)random.NextDouble() * 6 + .5f),
                            Quaternion.CreateFromAxisAngle(Vector3.Normalize(new Vector3((float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble())), (float)random.NextDouble() * 100),
                            new Vector3(i * xSpacing - xCount * xSpacing * .5f, j * ySpacing + 50, k * zSpacing - zCount * zSpacing * .5f));
                        var mesh = new InstancedMesh(meshShape, transform);
                        //Making the triangles one-sided makes collision detection a bit more robust, since the backsides of triangles won't try to collide with things
                        //and 'pull' them back into the mesh.
                        mesh.Sidedness = TriangleSidedness.Counterclockwise;
                        collidables.Add(mesh);
                        game.ModelDrawer.Add(mesh);
                    }
                }
            }

            var ground = new ConvexCollidable <BoxShape>(new BoxShape(200, 1, 200));

            ground.WorldTransform = new RigidTransform(new Vector3(0, -3, 0), Quaternion.Identity);
            collidables.Add(ground);
            game.ModelDrawer.Add(ground);

            var group = new StaticGroup(collidables);

            Space.Add(group);


            //Create a bunch of dynamic boxes to drop on the staticswarm.
            xCount   = 8;
            yCount   = 3;
            zCount   = 8;
            xSpacing = 3f;
            ySpacing = 5f;
            zSpacing = 3f;
            for (int i = 0; i < xCount; i++)
            {
                for (int j = 0; j < zCount; j++)
                {
                    for (int k = 0; k < yCount; k++)
                    {
                        Space.Add(new Box(new Vector3(
                                              xSpacing * i - (xCount - 1) * xSpacing / 2f,
                                              100 + k * (ySpacing),
                                              2 + zSpacing * j - (zCount - 1) * zSpacing / 2f),
                                          1, 1, 1, 10));
                    }
                }
            }



            game.Camera.Position = new Vector3(0, 60, 90);
        }
Esempio n. 26
0
        /// <summary>
        /// Constructs a new demo.
        /// </summary>
        /// <param name="game">Game owning this demo.</param>
        public DeterminismTestDemo(DemosGame game)
            : base(game)
        {
            //while (Space.ThreadManager.ThreadCount > 0)
            //    Space.ThreadManager.RemoveThread();
            //Resources.ResetPools();

            //Space.BroadPhase.AllowMultithreading = false;
            //Space.Solver.AllowMultithreading = false;
            ////Space.NarrowPhase.AllowMultithreading = false;

            ////Space.BoundingBoxUpdater.AllowMultithreading = false;
            ////Space.DeactivationManager.AllowMultithreading = false;
            ////Space.ForceUpdater.AllowMultithreading = false;
            ////Space.PositionUpdater.AllowMultithreading = false;

            //Space.BeforeNarrowPhaseUpdateables.Enabled = false;
            //Space.DuringForcesUpdateables.Enabled = false;
            //Space.EndOfFrameUpdateables.Enabled = false;
            //Space.EndOfTimeStepUpdateables.Enabled = false;

            //Space.BroadPhase = new BruteForce();
            //Space.NarrowPhase.BroadPhaseOverlaps = Space.BroadPhase.Overlaps;

            //SolverSettings.DefaultMinimumImpulse = 0;
            //SolverSettings.DefaultMinimumIterations = 10;

            Entity ground = new MorphableEntity(new BoxShape(50, 1, 50));

            Space.Add(ground);

            Vector3[] vertices;
            int[]     indices;
            ModelDataExtractor.GetVerticesAndIndicesFromModel(Game.Content.Load <Model>("playground"), out vertices, out indices);
            var mesh = new StaticMesh(vertices, indices, new AffineTransform(new Vector3(50, -20, 0)));

            Space.Add(mesh);
            game.ModelDrawer.Add(mesh);

            for (int i = 0; i < 100; i++)
            {
                Entity e = new Box(new Vector3(.1f * i, 1 * i + 1, 0), 1, 1, 1, 1);
                //Entity e = new Capsule(new Vector3(.1f * i, 1 * i + 1, 0), .5f, .5f, 1);
                //Entity e = new Sphere(new Vector3(.1f * i, 1 * i + 1, 0), .5f, 1);
                e.ActivityInformation.IsAlwaysActive = true;
                entities.Add(e);
                e.CollisionInformation.Tag = i;
                Space.Add(e);
            }
            for (int i = 0; i < 200; i++)
            {
                //Entity e = new Box(new Vector3(.1f * i, 1 * i + 1, 2), 1, 1, 1, 1);
                Entity e = new Capsule(new Vector3(.1f * i, 1 * i + 1, 2), .5f, .5f, 1);
                //Entity e = new Sphere(new Vector3(.1f * i, 1 * i + 1, 2), .5f, 1);
                e.ActivityInformation.IsAlwaysActive = true;
                entities.Add(e);
                e.CollisionInformation.Tag = i;
                Space.Add(e);
            }
            for (int i = 0; i < 300; i++)
            {
                //Entity e = new Box(new Vector3(.1f * i, 1 * i + 1, 4), 1, 1, 1, 1);
                //Entity e = new Capsule(new Vector3(.1f * i, 1 * i + 1, 4), .5f, .5f, 1);
                Entity e = new Sphere(new Vector3(.1f * i, 1 * i + 1, 4), .5f, 1);
                e.ActivityInformation.IsAlwaysActive = true;
                entities.Add(e);
                e.CollisionInformation.Tag = i;
                Space.Add(e);
            }
        }
        /// <summary>
        /// Constructs a new demo.
        /// </summary>
        /// <param name="game">Game owning this demo.</param>
        public MobileMeshSolidityTestDemo(DemosGame game)
            : base(game)
        {
            Vector3[] vertices;
            int[]     indices;

            //Hardcoded box
            vertices = new Vector3[]
            {
                new Vector3(0.5m, 0.5m, 0.5m),
                new Vector3(0.5m, 0.5m, -0.5m),
                new Vector3(-0.5000001m, 0.5m, -0.4999999m),
                new Vector3(-0.4999998m, 0.5m, 0.5000002m),
                new Vector3(-0.4999998m, -0.5m, 0.5000002m),
                new Vector3(-0.5000001m, -0.5m, -0.4999999m),
                new Vector3(0.5m, -0.5m, -0.5m),
                new Vector3(0.5m, -0.5m, 0.5m),
                new Vector3(0.5m, 0.5m, 0.5m),
                new Vector3(0.5m, -0.5m, 0.5m),
                new Vector3(0.5m, -0.5m, -0.5m),
                new Vector3(0.5m, 0.5m, -0.5m),
                new Vector3(0.5m, 0.5m, -0.5m),
                new Vector3(0.5m, -0.5m, -0.5m),
                new Vector3(-0.5000001m, -0.5m, -0.4999999m),
                new Vector3(-0.5000001m, 0.5m, -0.4999999m),
                new Vector3(-0.5000001m, 0.5m, -0.4999999m),
                new Vector3(-0.5000001m, -0.5m, -0.4999999m),
                new Vector3(-0.4999998m, -0.5m, 0.5000002m),
                new Vector3(-0.4999998m, 0.5m, 0.5000002m),
                new Vector3(-0.4999998m, 0.5m, 0.5000002m),
                new Vector3(-0.4999998m, -0.5m, 0.5000002m),
                new Vector3(0.5m, -0.5m, 0.5m),
                new Vector3(0.5m, 0.5m, 0.5m)
            };

            indices = new[]
            {
                2, 1, 0,
                3, 2, 0,
                6, 5, 4,
                7, 6, 4,
                10, 9, 8,
                11, 10, 8,
                14, 13, 12,
                15, 14, 12,
                18, 17, 16,
                19, 18, 16,
                22, 21, 20,
                23, 22, 20
            };

            var mesh = new MobileMesh(vertices, indices, AffineTransform.Identity, MobileMeshSolidity.Solid, 10);

            Space.Add(mesh);

            //Tube
            ModelDataExtractor.GetVerticesAndIndicesFromModel(game.Content.Load <Model>("tube"), out vertices, out indices);
            mesh          = new MobileMesh(vertices, indices, AffineTransform.Identity, MobileMeshSolidity.Solid, 10);
            mesh.Position = new Vector3(-10, 10, 0);
            Space.Add(mesh);

            //Cube
            ModelDataExtractor.GetVerticesAndIndicesFromModel(game.Content.Load <Model>("cube"), out vertices, out indices);
            mesh          = new MobileMesh(vertices, indices, AffineTransform.Identity, MobileMeshSolidity.Solid, 10);
            mesh.Position = new Vector3(10, 0, 0);
            Space.Add(mesh);

            //Guy
            ModelDataExtractor.GetVerticesAndIndicesFromModel(game.Content.Load <Model>("guy"), out vertices, out indices);
            mesh          = new MobileMesh(vertices, indices, AffineTransform.Identity, MobileMeshSolidity.Solid, 10);
            mesh.Position = new Vector3(0, 0, 10);
            Space.Add(mesh);

            //Barrel Platform
            ModelDataExtractor.GetVerticesAndIndicesFromModel(game.Content.Load <Model>("barrelandplatform"), out vertices, out indices);
            mesh          = new MobileMesh(vertices, indices, AffineTransform.Identity, MobileMeshSolidity.Solid, 10);
            mesh.Position = new Vector3(0, 0, -10);
            Space.Add(mesh);

            //FloaterTube
            ModelDataExtractor.GetVerticesAndIndicesFromModel(game.Content.Load <Model>("tube"), out vertices, out indices);
            mesh          = new MobileMesh(vertices, indices, new AffineTransform(new Vector3(1, 1, 1), Quaternion.Identity, new Vector3(0, 0, 0)), MobileMeshSolidity.Solid);
            mesh.Position = new Vector3(5, 18, 0);
            Space.Add(mesh);

            //Float a box through the last mesh to check contact generation controllably.
            var solidityTester = new Box(new Vector3(5, 8, 0), 1, 1, 1);

            solidityTester.LinearVelocity = new Vector3(0, 1, 0);
            CollisionRules.AddRule(solidityTester, mesh, CollisionRule.NoSolver);
            Space.Add(solidityTester);


            Space.Add(new Box(new Vector3(0, -5, 0), 50, 1, 50));

            game.Camera.Position = new Vector3(0, 10, 20);
        }
        /// <summary>
        /// Constructs a new demo.
        /// </summary>
        /// <param name="game">Game owning this demo.</param>
        public CharacterAddRemoveStressTestDemo(DemosGame game)
            : base(game)
        {
            //Load in mesh data and create the group.
            Vector3[] staticTriangleVertices;
            int[]     staticTriangleIndices;

            var playgroundModel = game.Content.Load <Model>("playground");

            //This is a little convenience method used to extract vertices and indices from a model.
            //It doesn't do anything special; any approach that gets valid vertices and indices will work.
            ModelDataExtractor.GetVerticesAndIndicesFromModel(playgroundModel, out staticTriangleVertices, out staticTriangleIndices);
            var meshShape = new InstancedMeshShape(staticTriangleVertices, staticTriangleIndices);
            var meshes    = new List <Collidable>();

            var xSpacing = 400;
            var ySpacing = 400;
            var xCount   = 3;
            var yCount   = 3;

            for (int i = 0; i < xCount; i++)
            {
                for (int j = 0; j < yCount; j++)
                {
                    var staticMesh = new InstancedMesh(meshShape, new AffineTransform(Matrix3x3.Identity, new Vector3(-xSpacing * (xCount - 1) / 2 + i * xSpacing, 0, -ySpacing * (yCount - 1) / 2 + j * ySpacing)));
                    staticMesh.Sidedness = TriangleSidedness.Counterclockwise;
                    Space.Add(staticMesh);
                    //meshes.Add(staticMesh);
                    game.ModelDrawer.Add(staticMesh);
                }
            }
            //var group = new StaticGroup(meshes);
            //Space.Add(group);



            //Now drop the characters on it!
            var   numColumns = 8;
            var   numRows    = 8;
            var   numHigh    = 8;
            float separation = 8;

            for (int i = 0; i < numRows; i++)
            {
                for (int j = 0; j < numColumns; j++)
                {
                    for (int k = 0; k < numHigh; k++)
                    {
                        var character = new CharacterController();
                        character.Body.Position =
                            new Vector3(
                                separation * i - numRows * separation / 2,
                                40f + k * separation,
                                separation * j - numColumns * separation / 2);

                        characters.Add(character);

                        Space.Add(character);
                    }
                }
            }

            //Now drop the ball-characters on it!
            numColumns = 8;
            numRows    = 8;
            numHigh    = 8;
            separation = 8;
            for (int i = 0; i < numRows; i++)
            {
                for (int j = 0; j < numColumns; j++)
                {
                    for (int k = 0; k < numHigh; k++)
                    {
                        var character = new SphereCharacterController();
                        character.Body.Position =
                            new Vector3(
                                separation * i - numRows * separation / 2,
                                48f + k * separation,
                                separation * j - numColumns * separation / 2);

                        sphereCharacters.Add(character);

                        Space.Add(character);
                    }
                }
            }


            game.Camera.Position = new Vector3(0, 10, 40);

            //Dump some boxes on top of the characters for fun.
            numColumns = 8;
            numRows    = 8;
            numHigh    = 8;
            separation = 8;
            for (int i = 0; i < numRows; i++)
            {
                for (int j = 0; j < numColumns; j++)
                {
                    for (int k = 0; k < numHigh; k++)
                    {
                        var toAdd = new Box(
                            new Vector3(
                                separation * i - numRows * separation / 2,
                                52f + k * separation,
                                separation * j - numColumns * separation / 2),
                            0.8f, 0.8f, 0.8f, 15);
                        toAdd.PositionUpdateMode = BEPUphysics.PositionUpdating.PositionUpdateMode.Continuous;

                        Space.Add(toAdd);
                    }
                }
            }
        }
        /// <summary>
        /// Constructs a new demo.
        /// </summary>
        /// <param name="game">Game owning this demo.</param>
        public CharacterPlaygroundDemo(DemosGame game)
            : base(game)
        {
            game.Camera.Position = new Microsoft.Xna.Framework.Vector3(-10, 7, 5);
            game.Camera.Yaw      = MathHelper.Pi;
            //Since this is the character playground, turn on the character by default.
            character.Activate();
            //Having the character body visible would be a bit distracting.
            character.CharacterController.Body.Tag = "noDisplayObject";

            //Load in mesh data for the environment.
            Vector3[] staticTriangleVertices;
            int[]     staticTriangleIndices;


            var playgroundModel = game.Content.Load <Model>("CharacterControllerTestTerrain");

            //This load method wraps the TriangleMesh.GetVerticesAndIndicesFromModel method
            //to output vertices of type StaticTriangleGroupVertex instead of TriangleMeshVertex or simply Vector3.
            ModelDataExtractor.GetVerticesAndIndicesFromModel(playgroundModel, out staticTriangleVertices, out staticTriangleIndices);
            var staticMesh = new StaticMesh(staticTriangleVertices, staticTriangleIndices, new AffineTransform(new Vector3(.01f, .01f, .01f), Quaternion.Identity, new Vector3(0, 0, 0)));

            staticMesh.Sidedness = TriangleSidedness.Counterclockwise;

            Space.Add(staticMesh);
            game.ModelDrawer.Add(staticMesh);



            //Add a spinning blade for the character to ram itself into.
            var fanBase  = new Cylinder(new Vector3(-13, .5f, 50), 1.1f, 1);
            var fanBlade = new Box(fanBase.Position + new Vector3(0, .8f, 0), 5, .1f, 1f, 5);
            var fanJoint = new RevoluteJoint(fanBase, fanBlade, (fanBase.Position + fanBlade.Position) * .5f, Vector3.Up);

            fanJoint.Motor.IsActive = true;
            fanJoint.Motor.Settings.VelocityMotor.GoalVelocity = 30;
            fanJoint.Motor.Settings.MaximumForce = 300;
            Space.Add(fanBase);
            Space.Add(fanBlade);
            Space.Add(fanJoint);

            //Add a bridge connecting the two towers.
            Vector3 startPosition = new Vector3(-19.3f, 10.5f - .25f, 23 - .85f);
            var     startPlatform = new Box(startPosition - new Vector3(0, 0, 2.2f), 4, .5f, 6);

            Space.Add(startPlatform);
            Vector3 offset       = new Vector3(0, 0, 1.7f);
            Box     previousLink = startPlatform;
            Vector3 position     = new Vector3();

            for (int i = 1; i <= 7; i++)
            {
                position = startPosition + offset * i;
                Box link = new Box(position, 3, .3f, 1.5f, 50);
                link.LinearDamping  = .1f;
                link.AngularDamping = .1f;
                Space.Add(link);
                Space.Add(new RevoluteJoint(previousLink, link, position - offset * .5f, Vector3.Right));

                previousLink = link;
            }
            var endPlatform = new Box(position - new Vector3(0, 0, -3.8f), 4, .5f, 6);

            Space.Add(endPlatform);

            Space.Add(new RevoluteJoint(previousLink, endPlatform, position + offset * .5f, Vector3.Right));


            //Add in a floating platform controlled by a curve to serve as an elevator.
            Entity movingEntity = new Box(new Vector3(-10, 0, -10), 3, 1, 3);

            var positionCurve = new CardinalSpline3D();

            positionCurve.PreLoop  = CurveEndpointBehavior.Mirror;
            positionCurve.PostLoop = CurveEndpointBehavior.Mirror;

            positionCurve.ControlPoints.Add(-1, new Vector3(-19.3f, 0, 43));
            positionCurve.ControlPoints.Add(0, new Vector3(-19.3f, 0, 43));
            positionCurve.ControlPoints.Add(2, new Vector3(-19.3f, 0, 43));
            positionCurve.ControlPoints.Add(3, new Vector3(-19.3f, 0, 43));
            positionCurve.ControlPoints.Add(4, new Vector3(-19.3f, 5, 43));
            positionCurve.ControlPoints.Add(5f, new Vector3(-19.3f, 10, 43));
            positionCurve.ControlPoints.Add(6f, new Vector3(-19.3f, 10, 43));
            positionCurve.ControlPoints.Add(8f, new Vector3(-19.3f, 10, 43));
            positionCurve.ControlPoints.Add(9f, new Vector3(-19.3f, 10, 43));

            elevatorMover = new EntityMover(movingEntity);
            Space.Add(elevatorMover);
            Space.Add(movingEntity);

            elevatorPath = positionCurve;

            //Add in another floating platform controlled by a curve for horizontal transport.
            movingEntity = new Box(new Vector3(-10, 0, -10), 2.5f, .5f, 2.5f);

            var platformCurve = new LinearInterpolationCurve3D();

            platformCurve.PreLoop  = CurveEndpointBehavior.Mirror;
            platformCurve.PostLoop = CurveEndpointBehavior.Mirror;

            platformCurve.ControlPoints.Add(0, new Vector3(-1.75f, 10, 21.5f));
            platformCurve.ControlPoints.Add(2, new Vector3(-1.75f, 10, 21.5f));
            platformCurve.ControlPoints.Add(5, new Vector3(-1.75f, 10, 15.5f));
            platformCurve.ControlPoints.Add(10, new Vector3(-19.3f, 10, 15.5f));
            platformCurve.ControlPoints.Add(12, new Vector3(-19.3f, 10, 15.5f));
            platformCurve.ControlPoints.Add(15, new Vector3(-25, 10, 15.5f));
            platformCurve.ControlPoints.Add(22, new Vector3(-25, 10, 38));
            platformCurve.ControlPoints.Add(23, new Vector3(-22.75f, 10, 38));
            platformCurve.ControlPoints.Add(25, new Vector3(-22.75f, 10, 38));

            //Make it spin too.  That'll be fun.  Or something.
            var platformRotationCurve = new QuaternionSlerpCurve();

            platformRotationCurve.PreLoop  = CurveEndpointBehavior.Mirror;
            platformRotationCurve.PostLoop = CurveEndpointBehavior.Mirror;
            platformRotationCurve.ControlPoints.Add(0, Quaternion.Identity);
            platformRotationCurve.ControlPoints.Add(15, Quaternion.Identity);
            platformRotationCurve.ControlPoints.Add(22, Quaternion.CreateFromAxisAngle(Vector3.Up, MathHelper.PiOver2));
            platformRotationCurve.ControlPoints.Add(25, Quaternion.CreateFromAxisAngle(Vector3.Up, MathHelper.PiOver2));

            platformMover   = new EntityMover(movingEntity);
            platformRotator = new EntityRotator(movingEntity);
            Space.Add(platformMover);
            Space.Add(platformRotator);
            Space.Add(movingEntity);

            platformPath            = platformCurve;
            platformOrientationPath = platformRotationCurve;

            //Add in a diving board.

            Box divingBoardBase  = new Box(new Vector3(-9, 10, 39.3f), 5, 1, 3);
            Box divingBoard      = new Box(divingBoardBase.Position + new Vector3(-2, 0, 3.5f), 1, .3f, 3, 5);
            var divingBoardJoint = new RevoluteJoint(divingBoardBase, divingBoard, divingBoard.Position + new Vector3(0, 0, -1.5f), Vector3.Right);

            divingBoardJoint.Motor.IsActive            = true;
            divingBoardJoint.Motor.Settings.Mode       = MotorMode.Servomechanism;
            divingBoardJoint.Motor.Settings.Servo.Goal = 0;
            divingBoardJoint.Motor.Settings.Servo.SpringSettings.StiffnessConstant = 5000;
            divingBoardJoint.Motor.Settings.Servo.SpringSettings.DampingConstant   = 0;

            Space.Add(divingBoardBase);
            Space.Add(divingBoard);
            Space.Add(divingBoardJoint);


            //Add a second diving board for comparison.

            Box divingBoard2      = new Box(divingBoardBase.Position + new Vector3(2, 0, 5f), 1, .3f, 6, 5);
            var divingBoardJoint2 = new RevoluteJoint(divingBoardBase, divingBoard2, divingBoard2.Position + new Vector3(0, 0, -3), Vector3.Right);

            divingBoardJoint2.Motor.IsActive            = true;
            divingBoardJoint2.Motor.Settings.Mode       = MotorMode.Servomechanism;
            divingBoardJoint2.Motor.Settings.Servo.Goal = 0;
            divingBoardJoint2.Motor.Settings.Servo.SpringSettings.StiffnessConstant = 10000;
            divingBoardJoint2.Motor.Settings.Servo.SpringSettings.DampingConstant   = 0;

            Space.Add(divingBoard2);
            Space.Add(divingBoardJoint2);

            //Add a seesaw for people to jump on.
            Box           seesawBase  = new Box(new Vector3(-7, .45f, 52), 1, .9f, .3f);
            Box           seesawPlank = new Box(seesawBase.Position + new Vector3(0, .65f, 0), 1.2f, .2f, 6, 3);
            RevoluteJoint seesawJoint = new RevoluteJoint(seesawBase, seesawPlank, seesawPlank.Position, Vector3.Right);

            Space.Add(seesawJoint);
            Space.Add(seesawBase);
            Space.Add(seesawPlank);

            Space.Add(new Box(seesawPlank.Position + new Vector3(0, 1.3f, 2), 1, 1, 1, 5));


            //Add in some boxes to bump and jump on.
            int   numColumns = 3;
            int   numRows    = 3;
            int   numHigh    = 3;
            float xSpacing   = 1.01f;
            float ySpacing   = 1.01f;
            float zSpacing   = 1.01f;

            for (int i = 0; i < numRows; i++)
            {
                for (int j = 0; j < numColumns; j++)
                {
                    for (int k = 0; k < numHigh; k++)
                    {
                        Space.Add(new Box(new Vector3(
                                              5 + xSpacing * i - (numRows - 1) * xSpacing / 2f,
                                              1.58f + k * (ySpacing),
                                              45 + zSpacing * j - (numColumns - 1) * zSpacing / 2f),
                                          .5f, .5f, .5f, 5));
                    }
                }
            }



            //Add a log to roll!
            //Make it a compound so some boxes can be added to let the player know it's actually spinning.
            CompoundBody log = new CompoundBody(new List <CompoundShapeEntry>()
            {
                new CompoundShapeEntry(new CylinderShape(4, 1.8f), Quaternion.CreateFromAxisAngle(Vector3.Forward, MathHelper.PiOver2), 20),
                new CompoundShapeEntry(new BoxShape(.5f, .5f, 3.7f), new Vector3(1.75f, 0, 0), 0),
                new CompoundShapeEntry(new BoxShape(.5f, 3.7f, .5f), new Vector3(1.75f, 0, 0), 0),
                new CompoundShapeEntry(new BoxShape(.5f, .5f, 3.7f), new Vector3(-1.75f, 0, 0), 0),
                new CompoundShapeEntry(new BoxShape(.5f, 3.7f, .5f), new Vector3(-1.75f, 0, 0), 0)
            }, 50);

            log.Position       = new Vector3(-14.5f, 10, 41);
            log.AngularDamping = 0;


            RevoluteJoint logJointA = new RevoluteJoint(divingBoardBase, log, log.Position + new Vector3(2.5f, 0, 0), Vector3.Right);
            RevoluteJoint logJointB = new RevoluteJoint(endPlatform, log, log.Position + new Vector3(-2.5f, 0, 0), Vector3.Right);

            Space.Add(logJointA);
            Space.Add(logJointB);

            Space.Add(log);


            //Put some planks to stand on that show various slopes.
            int numPads = 10;

            for (int i = 0; i < numPads; i++)
            {
                offset = new Vector3(0, 0, 4);
                Box   a     = new Box(new Vector3(i * 1.5f + 3.5f, 10, 24), 1.5f, 1, 4);
                Box   b     = new Box(new Vector3(i * 1.5f + 3.5f, 10, 24), 1.5f, 1, 4);
                float angle = -i * MathHelper.PiOver2 / numPads;
                b.Orientation = Quaternion.CreateFromAxisAngle(Vector3.Right, angle);
                b.Position   += offset * .5f + Vector3.Transform(offset * .5f, b.Orientation);

                Space.Add(a);
                Space.Add(b);
            }
        }
        /// <summary>
        /// Constructs a new demo.
        /// </summary>
        /// <param name="game">Game owning this demo.</param>
        public CharacterStressierTestDemo(DemosGame game)
            : base(game)
        {
            //Load in mesh data and create the group.
            Vector3[] staticTriangleVertices;
            int[]     staticTriangleIndices;

            var playgroundModel = game.Content.Load <Model>("playground");

            //This is a little convenience method used to extract vertices and indices from a model.
            //It doesn't do anything special; any approach that gets valid vertices and indices will work.
            ModelDataExtractor.GetVerticesAndIndicesFromModel(playgroundModel, out staticTriangleVertices, out staticTriangleIndices);
            var meshShape = new InstancedMeshShape(staticTriangleVertices, staticTriangleIndices);
            var meshes    = new List <Collidable>();

            var xSpacing = 400;
            var ySpacing = 400;
            var xCount   = 11;
            var yCount   = 11;

            for (int i = 0; i < xCount; i++)
            {
                for (int j = 0; j < yCount; j++)
                {
                    var staticMesh = new InstancedMesh(meshShape, new AffineTransform(Matrix3x3.Identity, new Vector3(-xSpacing * (xCount - 1) / 2 + i * xSpacing, 0, -ySpacing * (yCount - 1) / 2 + j * ySpacing)));
                    staticMesh.Sidedness = TriangleSidedness.Counterclockwise;
                    Space.Add(staticMesh);
                    //meshes.Add(staticMesh);
                    game.ModelDrawer.Add(staticMesh);
                }
            }
            //var group = new StaticGroup(meshes);
            //Space.Add(group);

            //To demonstrate, we'll be creating a set of static objects and giving them to a group to manage.
            var collidables = new List <Collidable>();

            //Start with a whole bunch of boxes.  These are entity collidables, but without entities!
            xSpacing = 25;
            ySpacing = 16;
            float zSpacing = 25;

            xCount = 25;
            yCount = 7;
            int zCount = 25;


            var random = new Random();

            for (int i = 0; i < xCount; i++)
            {
                for (int j = 0; j < yCount; j++)
                {
                    for (int k = 0; k < zCount; k++)
                    {
                        //Create a transform and the instance of the mesh.
                        var collidable = new ConvexCollidable <BoxShape>(new BoxShape((float)random.NextDouble() * 25 + 5.5f, (float)random.NextDouble() * 25 + 5.5f, (float)random.NextDouble() * 25 + 5.5f));

                        //This EntityCollidable isn't associated with an entity, so we must manually tell it where to sit by setting the WorldTransform.
                        //This also updates its bounding box.
                        collidable.WorldTransform = new RigidTransform(
                            new Vector3(i * xSpacing - xCount * xSpacing * .5f, j * ySpacing + -50, k * zSpacing - zCount * zSpacing * .5f),
                            Quaternion.CreateFromAxisAngle(Vector3.Normalize(new Vector3((float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble())), (float)random.NextDouble() * 100));

                        collidables.Add(collidable);
                        game.ModelDrawer.Add(collidable);
                    }
                }
            }
            var group = new StaticGroup(collidables);

            Space.Add(group);


            //Now drop the characters on it!
            var   numColumns = 16;
            var   numRows    = 16;
            var   numHigh    = 16;
            float separation = 24;

            for (int i = 0; i < numRows; i++)
            {
                for (int j = 0; j < numColumns; j++)
                {
                    for (int k = 0; k < numHigh; k++)
                    {
                        var character = new CharacterController();
                        character.Body.Position =
                            new Vector3(
                                separation * i - numRows * separation / 2,
                                50f + k * separation,
                                separation * j - numColumns * separation / 2);

                        characters.Add(character);

                        Space.Add(character);
                    }
                }
            }



            game.Camera.Position = new Vector3(0, 10, 40);

            //Dump some boxes on top of the characters for fun.
            numColumns = 16;
            numRows    = 16;
            numHigh    = 8;
            separation = 24;
            for (int i = 0; i < numRows; i++)
            {
                for (int j = 0; j < numColumns; j++)
                {
                    for (int k = 0; k < numHigh; k++)
                    {
                        var toAdd = new Box(
                            new Vector3(
                                separation * i - numRows * separation / 2,
                                52f + k * separation,
                                separation * j - numColumns * separation / 2),
                            0.8f, 0.8f, 0.8f, 15);
                        toAdd.PositionUpdateMode = BEPUphysics.PositionUpdating.PositionUpdateMode.Continuous;

                        Space.Add(toAdd);
                    }
                }
            }
        }