Pickinfo getNormal() not working properly after subdividing a mesh

Hi, I was trying to get the normal of the pickedpoint after a scene.pick and I’ve found that if the mesh is subdivided the getNormal() method seems to give a wrong value.
Here you have a simple playground I’ve modified based on an existing one:

https://www.babylonjs-playground.com/#0K21B2%234

With the subdivisions, the cube is not getting the right orientation when moving the pointer over the sphere, but if you remove line 19 (the subdivision thing), the cube gets oriented properly.
I’ve found that if you downgrade to Babylon version 4.0.3 the normal is kind of right even with the subdivisions (but the orientation change on the cube while moving is not as smooth as in version 4.2 without the subdivisions).

I think the problem is that when subdividing the mesh, the indices are messed up somehow. Adding an updateIndices to the mesh after subdividing it seems to solve the problem. Here is an updated playground with this fix:
https://www.babylonjs-playground.com/#0K21B2%235

Is there something that maybe can be fixed inside of the mesh.subdivide() code?

Regards

I’ve further tested that updateIndices() suposed fix, but it doesn’t really solve the issue because after updating the indices that way I loose the performance boost I get with the picking and mesh subdivision.

updateIndices won’t help you there because it removes the subMeshes created by subdivide, so it’s as you didn’t call subdivide in the first place.

There’s a bug in the picking process when sub meshes are involved, but I don’t know how to solve it, will let @Deltakosh tell:

The problem is that PickingInfo.faceId is an index local to the sub mesh, not global to the whole mesh, whereas PickingInfo.getNormal (and getTextureCoordinates) expects it to be global.

The easiest fix is to do this in AbstractMesh.intersects:

pickingInfo.faceId = intersectInfo.faceId + 
       subMeshes.data[intersectInfo.subMeshId].indexStart / 3;

instead of:

pickingInfo.faceId = intersectInfo.faceId;

However, it could be a breaking change for people that would use PickingInfo.faceId as an index local to the sub mesh pointed by PickingInfo.subMeshId (note that the doc is saying The index of the face on the mesh that was picked, or the index of the Line if the picked Mesh is a LinesMesh for faceId, so probably that it should be global). Also, I’m not sure it’s always “/ 3”, maybe it depends on the mesh type (there are different values for the step variable in SubMesh.intersects)…

As I’m not familiar with the intersection code, I prefer letting someone more knowledgeable handle this.

1 Like

This is the right fix…I’ll push it in the next commit!

thanks team

2 Likes

Thanks for this fast response. Now is fixed in the latest version and the playground works perfectly with that sticky cube! :wink: