Sign in to follow this  
Pryme8

Math Question - Normal to Rotation?

Recommended Posts

Ok so if I have a normal vector of lets say a section of terrain.  Now I want to get a 'orientation' value for the direction of the slope. So that I can point an arrow in that direction with the formula:

rotation = vec2(cos(orientation), sin(orientation));

as seen in this mock up shader I made that has the arrow being rotated by the time float:
https://cyos.babylonjs.com/#DV2KWT

I hope that makes sense?

Share this post


Link to post
Share on other sites

Hi P8/others.  Direction to rotation?  Common stackoverflow question.  We have some code onboard that does SOMETHING similar... called billboardMode.

https://github.com/BabylonJS/Babylon.js/blob/master/src/Mesh/babylon.transformNode.ts#L751

What a pile of demented math.  :)  I got a brain tumor by just clicking that URL. heh.  Others will surely comment, soon.

Share this post


Link to post
Share on other sites

I guess I kinda phrased it wrong, I would more or less be looking for the direction of the slope vector first then convert that to radians.  This is all assuming it is a terrain like object.

So I think its like the dot product of the normal to a vector 0,1,0 

Share this post


Link to post
Share on other sites

I don't think any of that terrain stuff... matters.  A face normal is a direction, yes?

But I think I understand better... and maybe... https://www.babylonjs-playground.com/#53YWDR#1

(not my PG)   Click on various sides of the mesh... see that the cylinders align with the faces. Lines 50-51 might do the dirty work.

Share this post


Link to post
Share on other sites

If you have the normal to the terrain, you can get the slope with  2 cross products :

cross(normal, Y) will be give you a vector orthogonal to the normal, let"s call it binorm

cross(normal, binorm) will give you a vector orthogonal to both the normal and binorm, it's the terrain slope

If these 3 vectors are normalized and orthogonal to each other, then you have a rotated normalized system. You can get the rotation to apply to any mesh to align it to this rotated system with the method RotationFromAxis(normal, binormal, slope)

Share this post


Link to post
Share on other sites

I was looking at the method RotationFromAxis, and I do not know how that will return a float that I can use as in the documentation it says it returns a vector3.

I am doing all this in a shader as well so I do not have access to that method, but I was looking to see what it does to see if I could of redone it in glsl format.

https://cyos.babylonjs.com/#DV2KWT#1

lines 78-91 on this are where I am trying to figure this out.

Share this post


Link to post
Share on other sites

Ok, you can then do the same thing GPU side.

Just compute the 2 vectors binorm and slope from the normal vector (2 cross products)

now if you consider the 3*3 matrix :

norm_x     norm_ y    norm_z

binorm_x binorm_y binorm_z

slope_x    slope_y     slope_z

Well, this matrix is actually the rotation matrix (let's call it rotMat) to apply directly to any vector you would rotate so it's in the same position in this new system than it used to be in its local one originally. Said differently :

rotMat * Vec3 = rotatedVec3

you just have to multiply the arrow vectors by this rotation matrix to get the arrow rotated along the slope :)

Share this post


Link to post
Share on other sites

https://cyos.babylonjs.com/#DV2KWT#4

This is closer, but I think its still off... plus I'm not sure how to get rid of that distortion.

I ended up using atan(vNormal.z, vNormal.x) to get the radians conversion... but I still feel like this is wrong.

*EDIT*

I think I got it!
https://cyos.babylonjs.com/#DV2KWT#7

Change model to sphere for best preview.

vec3 up = vec3(0.,1.,0.);
    vec3 biNorm = cross(vNormal, up);
    float a = atan(biNorm.x, biNorm.z);
    vec2 rotation = vec2(cos(a), sin(a));

 

Share this post


Link to post
Share on other sites

this all would have been so much easier if I had heightmaps and a nice smooth normal map >_< but yeah that is not what I was provided...

Now I gotta figure out how to get rid of the choppiness when the arrows go onto another face... maybe a better solution would be to make a cube over the whole mesh that you cant see and raymarch some arrows with some wizardry....

Share this post


Link to post
Share on other sites

So I am still having trouble with this, 

I have the shader which "works" but has some glitchs when the arrow transfers to a different normal so I am looking for a different solution.

I am following your instructions but can not get the markers to be in the correct rotation basically flat on the surface and the arrow pointing down the slope.
https://www.babylonjs-playground.com/#SHW98H#2

I am at least able to get the correct y rotation:
https://www.babylonjs-playground.com/#SHW98H#3
https://www.babylonjs-playground.com/#SHW98H#4 <- Better but slow because of how many arrows Im making.
https://www.babylonjs-playground.com/#SHW98H#8 <- scaling the arrows by slope.

>_< uhhg this is giving me a headache...

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.