I'm looking for information on how to setup a bepuphysics terrain from a heightmap. My XNA terrain class creates a hightmap from a .bmp file (as in riemer's tutorials).
It holds a float[,] of heights, and I'm assuming I pass the BEPUphysics.Collidables.Terrain constructor that. What else would I need to create a collision-detectable terrain? What do I use for the AffineTransform?
Terrain from heightmap
Re: Terrain from heightmap
Check out the TerrainDemo in the BEPUphysicsDemos source for an example.
An AffineTransform is the combination of a linear transform and a translation. Linear transforms include things like shear, scaling, and rotation. If the Terrain is given an identity transform (AffineTransform.Identity), each quad will be 1 unit across and the heights will be used as is. It is common to scale up the width and length of the terrain so that each quad is more than 1 unit across. In the TerrainDemo, it looks like this:
The first parameter to the AffineTransform is the scale, the second parameter is the rotation, and the third parameter is the translation. These are combined by the AffineTransform constructor to create an AffineTransform for the terrain.
An AffineTransform is the combination of a linear transform and a translation. Linear transforms include things like shear, scaling, and rotation. If the Terrain is given an identity transform (AffineTransform.Identity), each quad will be 1 unit across and the heights will be used as is. It is common to scale up the width and length of the terrain so that each quad is more than 1 unit across. In the TerrainDemo, it looks like this:
Code: Select all
var terrain = new Terrain(heights, new AffineTransform(
new Vector3(xSpacing, 1, zSpacing),
Quaternion.Identity,
new Vector3(-xLength * xSpacing / 2, 0, -zLength * zSpacing / 2)));
Re: Terrain from heightmap
I'm aware of the demo, but I don't know what to use for the x-y Spacing and Length. What would that correspond to in a terrain class like the one I'm using?
I've tried the following but it doesn't seem to work.
Also, I'm assuming the terrain's collidable would show up in the Drawer?
I've tried the following but it doesn't seem to work.
Code: Select all
AffineTransform wt = new AffineTransform(new Vector3(width, height, length),
Quaternion.Identity,
Vector3.Zero);
body = new BEPUphysics.Collidables.Terrain(heights, wt);
physicsEngine.Add(body);
// 'width' is the heightMap's Texture2D width, 'length' is the texture's height, and 'height' is based on cell-size height strength.
Re: Terrain from heightmap
The first parameter to that AffineTransform constructor is scaling. If a scaling of (1,1,1) is used, then the terrain vertices are not expanded nor compressed. It multiplies the components by 1. The unscaled width of a single quad is 1 unit.
So, with a horizontal scaling of 1 and a 513x513 vertex terrain (512x512 quads), the terrain is 512x512 units across. If you passed in (2,1,2) for the scaling, each quad would be 2 units across, but the heights would remain unscaled. The resulting terrain would be 1024x1024 units across.
If you passed in (2,1,1.5f), the terrain would be a bit squished along one horizontal axis; the quads would be rectangles when viewed from above instead of squares.
If you passed in (8,2,8), each quad would be 8x8 units across and the heights associated with each vertex would be multiplied by 2.
To get a feel for this, try fiddling with the values in the TerrainDemo.
So, with a horizontal scaling of 1 and a 513x513 vertex terrain (512x512 quads), the terrain is 512x512 units across. If you passed in (2,1,2) for the scaling, each quad would be 2 units across, but the heights would remain unscaled. The resulting terrain would be 1024x1024 units across.
If you passed in (2,1,1.5f), the terrain would be a bit squished along one horizontal axis; the quads would be rectangles when viewed from above instead of squares.
If you passed in (8,2,8), each quad would be 8x8 units across and the heights associated with each vertex would be multiplied by 2.
To get a feel for this, try fiddling with the values in the TerrainDemo.
If it is added to the drawer and the drawer is properly updated/drawn, yes.Also, I'm assuming the terrain's collidable would show up in the Drawer?
Re: Terrain from heightmap
cool, thanks for the explanation! so this does the trick:
well...sort of. It's only creating, like, a third of it.

I don't get it...where's the rest of it? other that that, it's lining up great (except for the artifacts, obviously).
Code: Select all
body = new BEPUphysics.Collidables.Terrain(heights,
new AffineTransform(new Vector3(cellSize, 1, cellSize),
Quaternion.Identity,
new Vector3(-width * cellSize / 2, 0, -length * cellSize / 2)));

I don't get it...where's the rest of it? other that that, it's lining up great (except for the artifacts, obviously).
Re: Terrain from heightmap
The BEPUphysicsDrawer is built for Reach and can't handle tons of triangles in a single batch. It doesn't try to subdivide large objects like Terrains, so it just falls over. The actual physics has no such limit, so stuff will still collide correctly with immense terrains even if the BEPUphysicsDrawer can't visualize the shape.
Re: Terrain from heightmap
haha, wow. I hadn't even tried to test it out yet.
P thanks!
