Page 1 of 1

Terrain from heightmap

Posted: Fri Sep 14, 2012 5:20 am
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?

Re: Terrain from heightmap

Posted: Fri Sep 14, 2012 6:16 pm
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.

Re: Terrain from heightmap

Posted: Fri Sep 14, 2012 8:43 pm
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?

Re: Terrain from heightmap

Posted: Sat Sep 15, 2012 12:25 am
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.

Re: Terrain from heightmap

Posted: Sat Sep 15, 2012 7:19 am
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).

Re: Terrain from heightmap

Posted: Sat Sep 15, 2012 4:08 pm
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.

Re: Terrain from heightmap

Posted: Mon Sep 17, 2012 2:01 am
by Neith
haha, wow. I hadn't even tried to test it out yet. :oP thanks!