///<summary> /// Initializes the pair handler. ///</summary> ///<param name="entryA">First entry in the pair.</param> ///<param name="entryB">Second entry in the pair.</param> public override void Initialize(BroadPhaseEntry entryA, BroadPhaseEntry entryB) { terrain = entryA as Terrain; convex = entryB as ConvexCollidable; if (terrain == null || convex == null) { terrain = entryB as Terrain; convex = entryA as ConvexCollidable; if (terrain == null || convex == null) throw new Exception("Inappropriate types used to initialize pair."); } //Contact normal goes from A to B. broadPhaseOverlap.entryA = convex; broadPhaseOverlap.entryB = terrain; UpdateMaterialProperties(convex.entity != null ? convex.entity.material : null, terrain.material); base.Initialize(entryA, entryB); }
public Map(Terrain terrain) : base(MobileFortressClient.Game) { Terrain = terrain; var map = Terrain.Shape.Heights; int width = map.GetLength(0); int x, y; vertexPNTs = new VertexMultitextured[width * width]; ResetVertexBuffer(); indices = new int[(width - 1) * (width - 1) * 6]; int counter = 0; for (y = 0; y < width - 1; y++) { for (x = 0; x < width - 1; x++) { int lowerLeft = x + y * width; int lowerRight = (x + 1) + y * width; int topLeft = x + (y + 1) * width; int topRight = (x + 1) + (y + 1) * width; indices[counter++] = topLeft; indices[counter++] = lowerRight; indices[counter++] = lowerLeft; indices[counter++] = topLeft; indices[counter++] = topRight; indices[counter++] = lowerRight; } } MobileFortressClient.Game.Components.Add(this); CopyToBuffers(); }
///<summary> /// Cleans up the pair handler. ///</summary> public override void CleanUp() { base.CleanUp(); terrain = null; }
/// <summary> /// Constructs a new demo. /// </summary> /// <param name="game">Game owning this demo.</param> public TerrainDemo(DemosGame game) : base(game) { //x and y, in terms of heightmaps, refer to their local x and y coordinates. In world space, they correspond to x and z. //Setup the heights of the terrain. //[The size here is limited by the Reach profile the demos use- the drawer draws the terrain as a big block and runs into primitive drawing limits. //The physics can support far larger terrains!] int xLength = 180; int zLength = 180; float xSpacing = 8f; float zSpacing = 8f; var heights = new float[xLength, zLength]; for (int i = 0; i < xLength; i++) { for (int j = 0; j < zLength; j++) { float x = i - xLength / 2; float z = j - zLength / 2; //heights[i,j] = (float)(x * y / 1000f); heights[i, j] = (float)(10 * (Math.Sin(x / 8) + Math.Sin(z / 8))); //heights[i,j] = 3 * (float)Math.Sin(x * y / 100f); //heights[i,j] = (x * x * x * y - y * y * y * x) / 1000f; } } //Create the terrain. var terrain = new Terrain(heights, new AffineTransform( new Vector3(xSpacing, 1, zSpacing), Quaternion.Identity, new Vector3(-xLength * xSpacing / 2, 0, -zLength * zSpacing / 2))); //terrain.Thickness = 5; //Uncomment this and shoot some things at the bottom of the terrain! They'll be sucked up through the ground. Space.Add(terrain); for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { for (int k = 0; k < 5; k++) { Space.Add(new Box( new Vector3(0 + i * 4, 100 - j * 10, 0 + k * 4), 2 + i * j * k, 2 + i * j * k, 2 + i * j * k, 4 + 20 * i * j * k)); } } } game.ModelDrawer.Add(terrain); game.Camera.Position = new Vector3(0, 30, 20); }
///<summary> /// Initializes the pair handler. ///</summary> ///<param name="entryA">First entry in the pair.</param> ///<param name="entryB">Second entry in the pair.</param> public override void Initialize(BroadPhaseEntry entryA, BroadPhaseEntry entryB) { terrain = entryA as Terrain; if (terrain == null) { terrain = entryB as Terrain; if (terrain == null) { throw new Exception("Inappropriate types used to initialize pair."); } } base.Initialize(entryA, entryB); }
/// <summary> /// Constructs a new demo. /// </summary> /// <param name="game">Game owning this demo.</param> public AccumulationTestDemo(DemosGame game) : base(game) { //x and y, in terms of heightmaps, refer to their local x and y coordinates. In world space, they correspond to x and z. //Setup the heights of the terrain. int xLength = 256; int zLength = 256; float xSpacing = .5f; float zSpacing = .5f; var heights = new float[xLength, zLength]; for (int i = 0; i < xLength; i++) { for (int j = 0; j < zLength; j++) { float x = i - xLength / 2; float z = j - zLength / 2; heights[i, j] = (float)(10 * (Math.Sin(x / 8) + Math.Sin(z / 8))); } } //Create the terrain. var terrain = new Terrain(heights, new AffineTransform( new Vector3(xSpacing, 1, zSpacing), Quaternion.Identity, new Vector3(-xLength * xSpacing / 2, 0, -zLength * zSpacing / 2))); Space.Add(terrain); game.ModelDrawer.Add(terrain); eventHandler = (sender, other, pair) => { var entityCollidable = other as EntityCollidable; if (entityCollidable == null || !entityCollidable.Entity.IsDynamic) { sender.Events.RemoveAllEvents(); sender.Entity.LinearVelocity = new Vector3(); sender.Entity.AngularVelocity = new Vector3(); sender.Entity.BecomeKinematic(); sender.CollisionRules.Group = CollisionRules.DefaultDynamicCollisionGroup; } }; game.Camera.Position = new Vector3(0, 30, 20); }
/// <summary> /// Constuct a TerrainPhysics entity. /// </summary> /// <param name="terrainName">The name of the terrain.</param> /// <param name="translation">The position of the terrain.</param> /// <param name="orientation">The orientation of the terrain.</param> /// <param name="scale">The amount to scale the terrain</param> public TerrainPhysics(String terrainName, Vector3 translation, Quaternion orientation, Vector3 scale) { float[,] heights = null;// AssetLibrary.LookupTerrainHeightMap(terrainName).GetHeights(); StaticCollidable = new Terrain( heights, new AffineTransform(scale, orientation, translation - new Vector3(scale.X * .5f * heights.GetLength(0), 0f, scale.Z * .5f * heights.GetLength(1))) ); StaticCollidable.CollisionRules.Group = TerrainPhysicsGroup; StaticCollidable.Tag = this; Position = translation; XNAOrientationMatrix = Matrix.CreateFromQuaternion(orientation); Scale = scale; mTerrainRenderable = new TerrainRenderable(terrainName); }
void CreateTerrain() { float peakValue = 0; for (int x = 0; x < map.GetLength(0); x++) for (int y = 0; y < map.GetLength(0); y++) if (map[x, y] > peakValue) peakValue = map[x, y]; float half = (map.GetLength(0) * lateralScale) / 2; AffineTransform transform = new AffineTransform( new Vector3(lateralScale, verticalScale, -lateralScale), Quaternion.Identity, new Vector3(-half, 0, half)); Terrain = new Terrain(map, transform); Sector.Redria.Space.Add(Terrain); }
private void CreateStaticCollidable() { float[,] heights = AssetLibrary.LookupHeightMap(mName).Mesh.Heights; Vector3 collidableScale = new Vector3(Scale.X / (float)(heights.GetLength(0) - 1), Scale.Y, Scale.Z / (float)(heights.GetLength(1) - 1)); StaticCollidable = new Terrain(heights, new BEPUphysics.MathExtensions.AffineTransform(collidableScale, OrientationQuaternion, Position)); StaticCollidable.CollisionRules.Group = HeightMapPhysicsGroup; StaticCollidable.Tag = this; }
///<summary> /// Cleans up the pair handler. ///</summary> public override void CleanUp() { base.CleanUp(); mesh = null; }
/// <summary> /// Constructs a new demo. /// </summary> /// <param name="game">Game owning this demo.</param> public TornadoDemo(DemosGame game) : base(game) { shape = new BoundingBoxForceFieldShape(new BoundingBox(new Vector3(-100, -20, -40), new Vector3(-20, 120, 40))); tornado = new Tornado(shape, (shape.BoundingBox.Min + shape.BoundingBox.Max) / 2, new Vector3(0, 1, 0), 150, false, 50, 10, 200, 200, 80, 2000, 40, 10); tornado.ForceWakeUp = true; //The tornado will be moving, so it should wake up things that it comes into contact with. Space.Add(tornado); //Create the unfortunate box-like citizens about to be hit by the tornado. int numColumns = 10; int numRows = 10; int numHigh = 1; float separation = 1.5f; 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, 5 + k * separation, separation * j - numColumns * separation / 2), 1, 1, 1, 10); Space.Add(toAdd); } //x and y, in terms of heightmaps, refer to their local x and y coordinates. In world space, they correspond to x and z. //Setup the heights of the terrain. //[The size here is limited by the Reach profile the demos use- the drawer draws the terrain as a big block and runs into primitive drawing limits. //The physics can support far larger terrains!] int xLength = 180; int zLength = 180; float xSpacing = 8f; float zSpacing = 8f; var heights = new float[xLength,zLength]; for (int i = 0; i < xLength; i++) { for (int j = 0; j < zLength; j++) { float x = i - xLength / 2; float z = j - zLength / 2; //heights[i,j] = (float)Math.Pow(1.2 * Math.Sqrt(x * x + y * y), 2); //heights[i,j] = -1f / (x * x + y * y); //heights[i,j] = (float)(x * y / 100f); heights[i,j] = (float)(5 * (Math.Sin(x / 8f) + Math.Sin(z / 8f))); //heights[i,j] = 3 * (float)Math.Sin(x * y / 100f); //heights[i,j] = (x * x * x * y - y * y * y * x) / 1000f; } } //Create the terrain. var terrain = new Terrain(heights, new AffineTransform( new Vector3(xSpacing, 1, zSpacing), Quaternion.Identity, new Vector3(-xLength * xSpacing / 2, 0, -zLength * zSpacing / 2))); Space.Add(terrain); game.ModelDrawer.Add(terrain); game.Camera.Position = new Vector3(0, 5, 60); }
/// <summary> /// Constructs a new demo. /// </summary> /// <param name="game">Game owning this demo.</param> public ReverseTrikeDemo(DemosGame game) : base(game) { game.Camera.Position = new Vector3(0, 2, 15); game.Camera.Yaw = 0; game.Camera.Pitch = 0; Space.Add(new Box(new Vector3(0, -5, 0), 20, 1, 20)); var body = new Box(new Vector3(0, 0, 0), 2, 1, 3, 10); body.CollisionInformation.LocalPosition = new Vector3(0, .8f, 0); Space.Add(body); #region First Wheel var wheel = new Cylinder(body.Position + new Vector3(-1.3f, 0, -1.5f), .2f, .5f, 4); wheel.Material = new Material(1.5f, 1.5f, 0); wheel.Orientation = Quaternion.CreateFromAxisAngle(Vector3.Forward, MathHelper.PiOver2); //Preventing the occasional pointless collision pair can speed things up. CollisionRules.AddRule(body, wheel, CollisionRule.NoBroadPhase); //Connect the wheel to the body. var ballSocketJoint = new BallSocketJoint(body, wheel, wheel.Position); var swivelHingeAngularJoint = new SwivelHingeAngularJoint(body, wheel, Vector3.Up, Vector3.Right); //Motorize the wheel. drivingMotor1 = new RevoluteMotor(body, wheel, Vector3.Left); drivingMotor1.Settings.VelocityMotor.Softness = .2f; //Let it roll when the user isn't giving specific commands. drivingMotor1.IsActive = false; steeringMotor1 = new RevoluteMotor(body, wheel, Vector3.Up); steeringMotor1.Settings.Mode = MotorMode.Servomechanism; //The constructor makes a guess about how to set up the constraint. //It can't always be right since it doesn't have all the information; //in this case, it chooses the basis and test axis incorrectly. //This leads to a 'flipping' behavior when the wheel is rolling //(the test axis is 'rolling' with the wheel, and passes over //a singularity which causes a flip). //To fix this, we configure the constraint directly. //The basis is aligned with how the wheel is set up; we choose 'up' as //the motorized axis, and right/forward to define the angle measurement plane. //The test axis is set to be perpendicular to the wheel's rotation so that //it only measures the steering angle. //If you're curious, the angle measurement is just a Math.Atan2. //The current world test axis is dotted against the two plane axes (Right and Forward here). //This gives an x and y value. These can be plugged into Atan2 just like when //you compute an angle on a normal 2d graph. steeringMotor1.Basis.SetWorldAxes(Vector3.Up, Vector3.Right); steeringMotor1.TestAxis = Vector3.Right; //Add the wheel and connection to the space. Space.Add(wheel); Space.Add(ballSocketJoint); Space.Add(swivelHingeAngularJoint); Space.Add(drivingMotor1); Space.Add(steeringMotor1); #endregion #region Second Wheel wheel = new Cylinder(body.Position + new Vector3(1.3f, 0, -1.5f), .2f, .5f, 4); wheel.Material = new Material(1.5f, 1.5f, 0); wheel.Orientation = Quaternion.CreateFromAxisAngle(Vector3.Forward, MathHelper.PiOver2); //Preventing the occasional pointless collision pair can speed things up. CollisionRules.AddRule(body, wheel, CollisionRule.NoBroadPhase); //Connect the wheel to the body. ballSocketJoint = new BallSocketJoint(body, wheel, wheel.Position); swivelHingeAngularJoint = new SwivelHingeAngularJoint(body, wheel, Vector3.Up, Vector3.Right); //Motorize the wheel. drivingMotor2 = new RevoluteMotor(body, wheel, Vector3.Left); drivingMotor2.Settings.VelocityMotor.Softness = .2f; //Let it roll when the user isn't giving specific commands. drivingMotor2.IsActive = false; steeringMotor2 = new RevoluteMotor(body, wheel, Vector3.Up); steeringMotor2.Settings.Mode = MotorMode.Servomechanism; //Configure the motor. See wheel 1 for more description. steeringMotor2.Basis.SetWorldAxes(Vector3.Up, Vector3.Right); steeringMotor2.TestAxis = Vector3.Right; //Add the wheel and connection to the space. Space.Add(wheel); Space.Add(ballSocketJoint); Space.Add(swivelHingeAngularJoint); Space.Add(drivingMotor2); Space.Add(steeringMotor2); #endregion #region Third Wheel wheel = new Cylinder(body.Position + new Vector3(0, -.3f, 1.5f), .2f, .5f, 4); wheel.Material = new Material(1.5f, 1.5f, 0); wheel.Orientation = Quaternion.CreateFromAxisAngle(Vector3.Forward, MathHelper.PiOver2); //Preventing the occasional pointless collision pair can speed things up. CollisionRules.AddRule(body, wheel, CollisionRule.NoBroadPhase); //Connect the wheel to the body. ballSocketJoint = new BallSocketJoint(body, wheel, wheel.Position); //Notice that the third wheel isn't a swivel hinge, it's just a revolute axis. //This lets it roll, but prevents flopping around like the wheels of a grocery cart. //Could have used a RevoluteJoint solver group here, but this shows it's possible to do //the same things without using the combo-constraints. var revoluteAngularJoint = new RevoluteAngularJoint(body, wheel, Vector3.Right); //Add the wheel and connection to the space. Space.Add(wheel); Space.Add(ballSocketJoint); Space.Add(revoluteAngularJoint); #endregion int xLength = 256; int zLength = 256; float xSpacing = 8f; float zSpacing = 8f; var heights = new float[xLength, zLength]; for (int i = 0; i < xLength; i++) { for (int j = 0; j < zLength; j++) { float x = i - xLength / 2; float z = j - zLength / 2; //heights[i,j] = (float)(x * y / 1000f); heights[i, j] = (float)(10 * (Math.Sin(x / 8) + Math.Sin(z / 8))); //heights[i,j] = 3 * (float)Math.Sin(x * y / 100f); //heights[i,j] = (x * x * x * y - y * y * y * x) / 1000f; } } //Create the terrain. var terrain = new Terrain(heights, new AffineTransform( new Vector3(xSpacing, 1, zSpacing), Quaternion.Identity, new Vector3(-xLength * xSpacing / 2, -10, -zLength * zSpacing / 2))); Space.Add(terrain); game.ModelDrawer.Add(terrain); }
///<summary> /// Initializes the manifold. ///</summary> ///<param name="newCollidableA">First collidable.</param> ///<param name="newCollidableB">Second collidable.</param> public override void Initialize(Collidable newCollidableA, Collidable newCollidableB) { convex = newCollidableA as ConvexCollidable; terrain = newCollidableB as Terrain; if (convex == null || terrain == null) { convex = newCollidableB as ConvexCollidable; terrain = newCollidableA as Terrain; if (convex == null || terrain == null) throw new Exception("Inappropriate types used to initialize contact manifold."); } }
///<summary> /// Cleans up the manifold. ///</summary> public override void CleanUp() { terrain = null; convex = null; base.CleanUp(); }
private void LoadHeightData(Texture2D heightMap) { terrainWidth = heightMap.Width; terrainHeight = heightMap.Height; Color[] heightMapColors = new Color[terrainWidth * terrainHeight]; heightMap.GetData(heightMapColors); heightData = new float[terrainWidth, terrainHeight]; var bepuHehighData = new float[terrainWidth, terrainHeight]; for (int x = 0; x < terrainWidth; x++) { for (int y = 0; y < terrainHeight; y++) { heightData[x, y] = heightMapColors[x + y * terrainWidth].R / 5.0f; } } int yy = 0; for (int x = 0; x < terrainWidth; x++) { for (int y = terrainHeight - 1; y >= 0 ; y--) { bepuHehighData[x, y] = heightMapColors[x + yy * terrainWidth].R / 5.0f; yy++; } yy = 0; } bepuTerrain = new BEPUphysics.Collidables.Terrain(bepuHehighData, new AffineTransform( new Vector3(1, 1, 1) , Quaternion.Identity ,new Vector3(0, 0, -terrainHeight) )); XNAGame.Instance.Space.Add(bepuTerrain); //XNAGame.Instance.ModelDrawer.Add(bepuTerrain); }
/// <summary> /// Create a Terrain Physic Object /// </summary> /// <param name="gfactory">The gfactory.</param> /// <param name="heighmapName">Name of the heighmap texture</param> /// <param name="translation">The translation.</param> /// <param name="rotation">The rotation.</param> /// <param name="materialDesc">The material desc.</param> /// <param name="XSpacing">The X spacing.</param> /// <param name="ZSpacing">The Z spacing.</param> /// <param name="heightMultipler">Default 10 - controla a altura, menor mais alto</param> public TerrainObject(GraphicFactory gfactory, String heighmapName, Vector3 translation, Matrix? rotation = null, MaterialDescription materialDesc = null, float XSpacing = 1, float ZSpacing = 1, float heightMultipler = 10) { if (!rotation.HasValue) rotation = Matrix.Identity; if (materialDecription == null) materialDecription = MaterialDescription.DefaultBepuMaterial(); //Used to calculate ther proportion of the xNormalized in the getHeightFast method xScale = XSpacing; zScale = ZSpacing; this.heightMultipler = heightMultipler; this.image = heighmapName; sourceImage = gfactory.GetTexture2D(image); int xLength = sourceImage.Width; int yLength = sourceImage.Height; terrainWidth = xLength; terrainHeight = yLength; this.rotation = rotation.Value; //this.scale = scale; Color[] colorData = new Color[xLength * yLength]; sourceImage.GetData<Color>(colorData); var heightStore = new float[xLength, yLength]; for (int i = 0; i < xLength; i++) { for (int j = 0; j < yLength; j++) { Color color = colorData[j * xLength + i]; heightStore[i, j] = (color.R) / heightMultipler; if (heightStore[i, j] > maxHeight) { maxHeight = heightStore[i, j]; } if (heightStore[i, j] < minHeight) { minHeight = heightStore[i, j]; } } } //Create the terrain. BEPUphysics.CollisionShapes.TerrainShape shape = new BEPUphysics.CollisionShapes.TerrainShape(heightStore, BEPUphysics.CollisionShapes.QuadTriangleOrganization.BottomLeftUpperRight); terrain = new Terrain(shape, new BEPUphysics.MathExtensions.AffineTransform(new Vector3(XSpacing, 1, ZSpacing), Quaternion.CreateFromRotationMatrix(rotation.Value), new Vector3(-xLength * XSpacing / 2, 0, -yLength * ZSpacing / 2) + translation)); terrain.ImproveBoundaryBehavior = true; SetMaterialDescription(materialDesc); }
/// <summary> /// Constructs a new demo. /// </summary> /// <param name="game">Game owning this demo.</param> public SuspensionCarDemo(DemosGame game) : base(game) { game.Camera.Position = new Vector3(0, 2, 15); game.Camera.Yaw = 0; game.Camera.Pitch = 0; Space.Add(new Box(new Vector3(0, -5, 0), 20, 1, 20)); var body = new Box(new Vector3(0, 0, 0), 4, .5f, 5, 20); body.CollisionInformation.LocalPosition = new Vector3(0, .8f, 0); Space.Add(body); AddBackWheel(new Vector3(-1.8f, -.2f, 2.1f), body); AddBackWheel(new Vector3(1.8f, -.2f, 2.1f), body); var wheel1 = AddDriveWheel(new Vector3(-1.8f, -.2f, -2.1f), body, out drivingMotor1, out steeringMotor1); var wheel2 = AddDriveWheel(new Vector3(1.8f, -.2f, -2.1f), body, out drivingMotor2, out steeringMotor2); //Add a stabilizer so that the wheels can't point different directions. var steeringStabilizer = new RevoluteAngularJoint(wheel1, wheel2, Vector3.Right); Space.Add(steeringStabilizer); //x and y, in terms of heightmaps, refer to their local x and y coordinates. In world space, they correspond to x and z. //Setup the heights of the terrain. int xLength = 256; int zLength = 256; float xSpacing = 8f; float zSpacing = 8f; var heights = new float[xLength, zLength]; for (int i = 0; i < xLength; i++) { for (int j = 0; j < zLength; j++) { float x = i - xLength / 2; float z = j - zLength / 2; //heights[i,j] = (float)(x * y / 1000f); heights[i, j] = (float)(10 * (Math.Sin(x / 8) + Math.Sin(z / 8))); //heights[i,j] = 3 * (float)Math.Sin(x * y / 100f); //heights[i,j] = (x * x * x * y - y * y * y * x) / 1000f; } } //Create the terrain. var terrain = new Terrain(heights, new AffineTransform( new Vector3(xSpacing, 1, zSpacing), Quaternion.Identity, new Vector3(-xLength * xSpacing / 2, -10, -zLength * zSpacing / 2))); //terrain.Thickness = 5; //Uncomment this and shoot some things at the bottom of the terrain! They'll be sucked up through the ground. Space.Add(terrain); game.ModelDrawer.Add(terrain); }
public TerrainObject(GraphicFactory gfactory, Vector3 translation, Matrix rotation, float[,] heights, MaterialDescription materialDesc,BEPUphysics.CollisionShapes.QuadTriangleOrganization triangleorientation = BEPUphysics.CollisionShapes.QuadTriangleOrganization.BottomLeftUpperRight ) { terrainWidth = heights.GetLength(0); terrainHeight = heights.GetLength(1); //Create the terrain. BEPUphysics.CollisionShapes.TerrainShape shape = new BEPUphysics.CollisionShapes.TerrainShape(heights, triangleorientation); terrain = new Terrain(shape, new BEPUphysics.MathExtensions.AffineTransform(Vector3.One, Quaternion.CreateFromRotationMatrix(rotation), translation)); terrain.ImproveBoundaryBehavior = true; SetMaterialDescription(materialDesc); }