Facet Data Issue

I’m trying to get physics working using facet data in my latest project. There seems to be an issue with getting the closest facet data and the projection. The projection it returns is sometimes very far away from the mesh. I think the same issue can be seen when you remove the morph from this example in the docs:

https://playground.babylonjs.com/#XVGK0#5
https://playground.babylonjs.com/#XVGK0#6

Let it run for a while and you see the balls registering collisions when they aren’t close to the mesh.

It looks like increasing the partition subdivisions helps, but it makes me think there is an issue with getting the closest facet data.

https://playground.babylonjs.com/#XVGK0#7

Is the definition of a facet an infinite plane? I thought a facet was a face / triangle. I also thought that the projection would be confined to that triangle.

Looks like this iangilman had a similar issue.

How can I get the 3 vertices of a facet?

edit:

I found this in computeNormals which looks promising:

        v1x = indices[index * 3] * 3;
        v1y = v1x + 1;
        v1z = v1x + 2;

        v2x = indices[index * 3 + 1] * 3;
        v2y = v2x + 1;
        v2z = v2x + 2;

        v3x = indices[index * 3 + 2] * 3;
        v3y = v3x + 1;
        v3z = v3x + 2;
1 Like

I figured out how to get the vertices that make up a facet:

let index = mesh.getClosestFacetAtCoordinates(x, y, z);
let facetPosition = BABYLON.Vector3.Zero();
mesh.getFacetPositionToRef(index, facetPosition);

let positions = mesh.getVerticesData(BABYLON.VertexBuffer.PositionKind);
let indices = mesh.getIndices();

let v1x = indices[index * 3] * 3;
let v1y = v1x + 1;
let v1z = v1x + 2;

let v2x = indices[index * 3 + 1] * 3;
let v2y = v2x + 1;
let v2z = v2x + 2;

let v3x = indices[index * 3 + 2] * 3;
let v3y = v3x + 1;
let v3z = v3x + 2;

let vert1 = BABYLON.Vector3.Zero();
let vert2 = BABYLON.Vector3.Zero();
let vert3 = BABYLON.Vector3.Zero();

vert1.x = positions[v1x];
vert1.y = positions[v1y];
vert1.z = positions[v1z];

vert2.x = positions[v2x];
vert2.y = positions[v2y];
vert2.z = positions[v2z];

vert3.x = positions[v3x];
vert3.y = positions[v3y];
vert3.z = positions[v3z];

let wm = mesh.getWorldMatrix();
BABYLON.Vector3.TransformCoordinatesToRef(vert1, wm, vert1);
BABYLON.Vector3.TransformCoordinatesToRef(vert2, wm, vert2);
BABYLON.Vector3.TransformCoordinatesToRef(vert3, wm, vert3);

//check facet position
let fpx = (vert1.x + vert2.x + vert3.x)/3;
let fpy = (vert1.y + vert2.y + vert3.y)/3;
let fpz = (vert1.z + vert2.z + vert3.z)/3;
	
if(facetPosition.x != fpx || facetPosition.y != fpy || facetPosition.z != fpz){
    //something went wrong
}

I solved my issue after simply modifying the getClosestFacetAtLocalCoordinates function to check the distance of the facet position rather than the projected point.

1 Like

I can see why the code uses the projected point. Some meshes have large and small faces. Maybe it should make sure the projected point is actually on the triangle or maybe there should be an option for that.

Thank you for tagging me. I ended up using an entirely different strategy, but it’s good to know you’ve made progress on this front, if we ever do return to it :slight_smile:

1 Like

The definition of a projection make this impossible. You are projecting a point onto a plane and it hits the plane where it hits the plane which may be outside the facet. The point and projection point form a line at right angles to the plane. It does imply this in the docs, There is only one point on the plane that does this.

This method can also compute for you the coordinates of the projection of (x, y, z) on the closest facet plane.

You found the way to do what you need so well done.

I dont see how it would be impossible. You just check if the point is on the triangle. If it isn’t you reject it. I’m talking about the algo for computing the closest facet.

OK misunderstood your intention.

It might cause other issues, though.