height over terrain

Hi,

I used plib (C++ 3d library) some years ago and there was a ssgHOT() function that gave the height over terrain. That way I could follow the roughness on the terrain quite easily for a FPS game. It could even handle stairs well.

Is there a way to do that in xith? I tried with Ode but it’s tricky as it wants to roll down my bounding sphere off hills, etc.
Such a function should be very fast as it’s called with every move of the character (resp. the camera).

Galun

I do it in ode by using the heightmap array that originally generated the terrain. I don’t use it for terrain following though (ode collisions can do this for me), I just use it for spawning. Unfortunately the height I get is just the average height of that triangle, no the specific height at the point. It’s good enough for me currently though.

Will.

I use a TriangleArray as terrain and as the map might get quite big sometime I think I would have a problem with average height. Don’t you have a problem with a stair effect in your application?

Maybe there is an easy way to stop Ode from doing certain things, like bouncing, adding force, rolling down hills, … ?
It’s designed to take control over the simulation, but that’s not what I want. The only thing I would need Ode to do is collision detection. I think Ode is not really what I need and am looking for alternatives.

when using a heightmap you don’t necessarily have to have the stair effect. I for one use also a Heightmap (also for terrain following) and I simply interpolate between the positions, where I specified the heights, so It moves smoothly. If you’re not able to use a heightmap I can only suggest to split your terrain in several smaller parts and then make a pick downwards. (Thats probably also the way you’re c++ lib was working) You can find the picking algorithm I use by using the search function here in the forums and searching after “picking” and by the author “arne” in the “xith3d” forums. Note that the code is not optimal (I’ve also improved mine, but I kept the old one there), so you’ll probably have to pay attention with the garbage that get’s created. The garbage collector takes lot of time!!

Thanks for the hint, I’ll try.

IMHO something like that should be put into xith3d or xith3d-tk.
Is it just me who missed such a function? I think HOT and LOS functions are essential for a game where you want to move a character over a non-flat ground and target something.

yeah it really should be in the xith-tk or even into the xith core, because it’s pretty elemental. But for my code I made optimisations that only work with the structure of the game I’m making. But as it seems that there is great need for this code, I could post a fresh and better version of the code. It’ll be some work to make an standalone out of it, so that you can use it.

Hi,

As a very first try I used an intersection function I found in the web and put a class Intersection around that offers a getHOT() function. You can find it here : http://www.world-of-mystery.de/download/Intersection.java

It’s not optimized yet, e.g. it should check which mesh is out of question and skip the triangles. It only works with triples of coordinates forming a triangle.

To use it I have something like the following in the code:


private Intersection terrain;
terrain = new Intersection();
aseReader = new AseReader(new BufferedReader(new FileReader("simple.ASE")),aseFile,false);
aseFile.parse(aseReader);
aseModel = aseFile.getModel();
		for (Node ch : (ArrayList<Node>)aseModel.getChildren())
		{
			if (ch instanceof Shape3D && ch.getName().startsWith("Plane"))
			{
				System.out.println("found: "+ch.getName()+" is "+ch.getClass());
				Shape3D sh = (Shape3D)ch;
				Geometry g = sh.getGeometry();
				System.out.println(" with "+g.getClass());
				if (!(g instanceof GeometryArray))
					continue;
				GeometryArray ga = (GeometryArray)g;
				Point3f[] vertices = new Point3f[ga.getValidVertexCount()];
				for (int i = 0; i < vertices.length; i++)
					vertices[i] = new Point3f();
				ga.getCoordinates(0,vertices);
				terrain.addTriMesh(vertices, ch.getName());
			}
		}

	private Point3f skyVector;
	private Vector3f earthVector;
		skyVector = new Point3f(0,0,1);
		earthVector = new Vector3f(skyVector);
		earthVector.negate();

			float hot = terrain.getHOT(new Vector3f(playerPosition), earthVector);
			if (Math.abs(hot) < 30 && (hot > eyeHeight || hot < eyeHeight))
				playerPosition.z -= hot - eyeHeight;

(These are snippets from different places in the code, not a complete function.)

This way it follows the terrain quite well. Checks for heights that a character cannot climb and depth too big to jump down can be done in the function that steers the character.