Accesing information of points in a model to calculate things like gradient etc

Say I have a model loaded in babylon.js.
Say I want to calculate what is the gradient at any point of the model, for example the point that user clicks on. Is there a way to access the data of individual points, I guess the vertex or face etc where user clicks, and the surrounding ones to be able to calculate the gradient at a point? do you know of any playground doing something similar? thank you :slight_smile:

All you need can be provided by the PickedPoint info:
Mesh Picking | Babylon.js Documentation

1 Like

@Deltakosh thank you, yes I can see that if i do:

var pickInfo = scene.pick(scene.pointerX, scene.pointerY);

I can get the x,y,z of that point:

  1. _x: 47.682925649841536
  2. _y: -25.51151170152741
  3. _z: 67.58982080705515

but now to calculate gradient i need to access the very near points, how can I access nearby points I wonder, possibly simply changing the scene.pointerX, scene.pointerY? but i dont think so as a nearby points in scene coordinates may fall outside the model, thats my doubt, how to get the position within the model of nearby points to the point selected

For that you can use mesh.getVerticesData or one of its overloads :wink:

@Deltakosh thank you, I read about it but mmm not sure how to use it exactly; im trying to find the simplest way to calculate the derivative or gradient of the model’s surface at any point; I found this derivativeblock thing:
var Derivative = new BABYLON.DerivativeBlock(“Derivative”);
does this have to do anything with the derivative-gradient at a point? any other suggestions very welcome :slight_smile:

@javismiles, would getNormal() PickingInfo | Babylon.js Documentation help in approximating the gradient?

@gbz that is a great question, I was wondering about that some minutes ago, I am not sure; in principle the gradient at a point in the surface doesn’t point in the direction of the normal, it points in the direction of maximum increase of the function, but then see this:

so maybe they are connected. What I am really trying to calculate and show the user is what is the gradient, the derivative, the direction of maximum steepness in the surface at a point; maybe that can be calculated from the normal at that point?

math+babylon experts around? :slight_smile:

@gbz so doing this
I get the normal data:

  1. _x: 0.6858474159230478
  2. _y: -0.30693171528917734
  3. _z: -0.6598531989930198

at that point, so thats the question now, can I from that get the info about the direction of steepest ascent (in reality i want the direction of steepest descent which would be the opposite direction)

@gbz, aha lets see this:

" If you already have the normal vector, you’re almost there. What you now need is the angle (look for dot product) between the normal and a vertical line (what exactly vertical means depends on your application).

If your normal vectors are actually normalized (have length 1) and the vertical is (0 0 1), the cosine of the slope angle is simply the z coordinate of the normal vector."


Ah, you’re right, @javismiles, perhaps the normal is not enough, and instead we may need all the points surrounding the picked point

I’m not yet sure how to do this and am hoping more experienced members could help point us in the right direction :smiley:

In the meantime, perhaps the source code for getNormal(), which calls getVerticesData() can give us hints on how the points are managed

1 Like

@gbz actually according to

this may be easier. Because the dot product of the normal vector with a vertical line could give us the cosine, and then doing an arccos maybe we get it, if the normals are normalized, unit vectors, I think they are, they seem to be unit normalized

lets see if an expert of the team can confirm this :slight_smile:

1 Like

@gbz, question, in babylon, which coordinate is pointing up, the vertical, is that the Y? whats the convention, if I have to do a dot product between the normal vector and a vertical line ,and if the normal is a unit vector normalized, then I just need to decide if the product is with 0, 1, 0 or with 0, 0 , 1, depends which is the vertical line in babylon.js

It seems that the Y-axis is pointing up according to Display World Axes | Babylon.js Documentation, which has the playground Babylon.js Playground

@gbz, thank you very much, this is very interesting, i just checked that if i look at the normal of a flat point in the model, flat horizontal point in a flat part of mesh that is horizontal, the value of the normal is:

this is very interesting, i would have expected: 0,1,0, with the normal pointing up in the Y,
why does it return 0,-1,0 , negative Y?

@gbz not a trivial thing because doing dot product between 0,1,0 and 0,1,0 (vertical line) we would get 1 and the arccos of 1 is 0, 0 degrees, flat, makes sense; but that doesnt happen if it is 0,-1,0, mmm

In the 3D modeling software used to produce your model, there should be an option to view normals. There is also an option in Blender, for example, to flip the direction of normals

Maybe the model has inverted faces in your 3D modeling software and the normals need to be flipped?

@gbz the good news is that I can totally see that using the normal it should be possible to calculate the steepness at each point between the normal and a vertical line and a dot product, just have to clarify the direction of each thing etc

that would give the steepness at each point, which is a beginning

next would be to calculate the direction of maximum steepness from that point, so not a value, but a vector, a direction

math+babylon experts of the group, waiting for your help :slight_smile:

@gbz great point about inverted normals, yes indeed i can check that in the 3d software

@gbz this may be the way to get the steepness if the normals pointed up

const normal=pickInfo.getNormal();
const steepness=Math.acos(normal._y);

could an expert confirm please? :slight_smile:

and what would then be the way to get not just the steepness at a point but also the vector, the direction of greatest steepness from that point?

thank you :slight_smile:

@gbz yes just tested and yes this definitely provides the steepness at a point yeah:
const normal=pickInfo.getNormal();
const steepness=Math.acos(normal._y);

if normals are inverted its enough to do:
const normal=pickInfo.getNormal();
const steepness=Math.acos(-normal._y);

this is great, so now thats the steepness at the point. What would be the way to get the full vector that indicates the direction of maximum steepness from that point?