Terrain from heightmap

Discuss any questions about BEPUphysics or problems encountered.
Post Reply
Neith
Posts: 4
Joined: Mon Sep 10, 2012 10:54 pm

Terrain from heightmap

Post by Neith »

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?
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Terrain from heightmap

Post by Norbo »

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:

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)));
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.
Neith
Posts: 4
Joined: Mon Sep 10, 2012 10:54 pm

Re: Terrain from heightmap

Post by Neith »

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.

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.
Also, I'm assuming the terrain's collidable would show up in the Drawer?
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Terrain from heightmap

Post by Norbo »

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.
Also, I'm assuming the terrain's collidable would show up in the Drawer?
If it is added to the drawer and the drawer is properly updated/drawn, yes.
Neith
Posts: 4
Joined: Mon Sep 10, 2012 10:54 pm

Re: Terrain from heightmap

Post by Neith »

cool, thanks for the explanation! so this does the trick:

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)));
well...sort of. It's only creating, like, a third of it.

Image

I don't get it...where's the rest of it? other that that, it's lining up great (except for the artifacts, obviously).
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Terrain from heightmap

Post by Norbo »

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.
Neith
Posts: 4
Joined: Mon Sep 10, 2012 10:54 pm

Re: Terrain from heightmap

Post by Neith »

haha, wow. I hadn't even tried to test it out yet. :oP thanks!
Post Reply