3
votes

've been working on a game engine using the WebGL library Three.js. I have basic terrain collision working to the point where I can find the face the user is standing on. Using the average or maximum Y position of the faces vertices is not sufficient.

What formula can I use to find the exact Y position of an object relative to the terrain face that is "standing" on? Assuming I know the faces four vertex positions and the objects vector position.

enter image description here

The plane is a THREE.PlaneGeometry(2000,2000,128,128) augmented by a heightmap. The image above is one of it's faces.

2
There is a geometry.computeCentroids() function you can use and then use the centroid of the face. - gaitat
I've done geo.computeCentroids() but the problem is the character is not always standing in the center of the face. - Hobbes
Since you are doing collision, you are already sending rays (I assume). When you succeed finding a face why dont you do ray-plane intersection to find the exact spot. Dont know if three.js has this build in. - gaitat
I'm using an alternate method to find the face. Ray projection performance was not as good as I'd liked it to be. Either way I'm left finding one face. I need to know the precise y position of the part of the face i am standing on. Since there are no vertices within this face (only on the corners), one could only extrapolate this data using some kind of math that i just don't know heh. - Hobbes

2 Answers

5
votes

I cannot put code in the comment so I am putting it here. You dont need to do the math. Let three.js do it for you. You can do something like the following:

var plane = new THREE.Plane();
plane.setFromCoplanarPoints (v1, v2, v3);

// x, y, z: position of your object
var ray = new THREE.Ray (new THREE.Vector3(x, y, z), new THREE.Vector3(0, 1, 0));
var where = ray.intersectPlane (plane);

and from the Vector3 'where' you use the y component to change the position of your object.

0
votes

You can easily find the height of the face your object is standing on

const down = new THREE.Vector3(0, -1, 0);
const raycaster = new THREE.Raycaster();

raycaster.set(obj.position, down);
const collisionResults = raycaster.intersectObject(terrain);

if (collisionResults.length > 0 && collisionResults[0].distance > 0)
   const pointHeight = collisionResults[0].point.y;

at this point just subtract pointHeight from the y coordinate of your object, to get the relative height.

const relativeHeight = obj.position.y - pointHeight;