CyanPrime


«
Posted
20120527 23:42:05 » 

Alright, so I need to know the y axis angle of a plane made by 4 points in 3d space. basically I want code to where if it's _ (flat) I can walk on it and if its  (a wall) I run into it. So could anyone explain to me a good way to figure this out?




theagentd


«
Reply #1  Posted
20120527 23:51:09 » 

Calculate the normal using 3 of the vertices (a triangle) and check the value of y?

Myomyomyo.



CyanPrime


«
Reply #2  Posted
20120528 05:45:47 » 

Okay, this is what I got so far. Assume quadToCheck is 4 Vector3f's with random values. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
 public float getNormal(Vector3f[] quadToCheck){ Vector3f ab = new Vector3f(0,0,0); Vector3f.sub(quadToCheck[1], quadToCheck[0], ab); Vector3f ac = new Vector3f(0,0,0); Vector3f.sub(quadToCheck[2], quadToCheck[0], ac); Vector3f crossed = new Vector3f(0,0,0); Vector3f.cross(ac, ab, crossed); Vector3f backup = new Vector3f(crossed); try{ crossed.normalise(); } catch(Exception e){ crossed = backup; } return crossed.y; } 
Am I doing this right? Cause I'm not seeing good results, and it tends to hit that catch like every time, or every other time :<




Games published by our own members! Check 'em out!


theagentd


«
Reply #3  Posted
20120528 09:29:24 » 

This is some GLSL code I have to calculate the normal of a triangle in a geometry shader: 1 2 3 4 5 6
 vec3 calculateNormal(){ vec3 u = gl_in[1].gl_Position.xyz  gl_in[0].gl_Position.xyz; vec3 v = gl_in[2].gl_Position.xyz  gl_in[0].gl_Position.xyz; return normalize(cross(u, v)); } 
Shouldn't it be Vector3f.cross( ab, ac, crossed)? Mine works as it should. EDIT: I love how clean GLSL code looks for this kind of math. =>

Myomyomyo.



Roquen


«
Reply #4  Posted
20120528 09:58:38 » 

There's no need to normalize unless you really want the normal. The original question only needs the direction.




theagentd


«
Reply #5  Posted
20120528 13:08:29 » 

There's no need to normalize unless you really want the normal. The original question only needs the direction.
But to calculate the angle to y+ you need to do a dot product with a vector pointing up > you need normalize it and just look at y. Maybe that's not the best way of doing it...

Myomyomyo.



Roquen


«
Reply #6  Posted
20120528 13:17:26 » 

Really this just isn't the way to handle the problem. If polys are always in XZ (floor/ceiling) and X^Z=0 (walls), then just have three lists floors, ceilings and walls and be done with it...which I assume is the case since only the Y component is being returned. But if you don't need distance from test point, then no normalization is needed...the sign is the answer.




Danny02


«
Reply #7  Posted
20120528 13:35:24 » 

ofcourse you can always check if some plane/triangle/quad is walkable with the normal(angle between the normal and the 90° flat plane). Another possibility is to generate a navigation mesh(something in the direction of Roquens idea). Just generate a list of areas/triangles ... which are wakable. By hand or an algorithm, there are also nice opensource tools for that see recast




theagentd


«
Reply #8  Posted
20120528 14:01:39 » 

I was assuming that OP wanted something similar to most shooters/RPGs, where you can walk on everything that isn't too steep. My idea was to look at the y value of the normal and check if it was above a certain threshold...

Myomyomyo.



Danny02


«
Reply #9  Posted
20120528 14:10:44 » 

I was assuming that OP wanted something similar to most shooters/RPGs, where you can walk on everything that isn't too steep. My idea was to look at the y value of the normal and check if it was above a certain threshold...
sure that works, the y value of a normalized plane normal should be the cosinus angle between the plane and the ground, right?




Games published by our own members! Check 'em out!


Roquen


«
Reply #10  Posted
20120528 16:38:32 » 

Doesn't work. For arbitrary surfaces you need the full direction and not a single component. Consider rotating the surface about 'y'. You can find the slope but not the maximum direction of change.




Icecore


«
Reply #11  Posted
20120528 17:25:19 » 

Check this out Where Y and X 2 axis distance Let sta you have 1.3 and 2.4 X = 2 – 1 Y = 4 – 3 Play with dif axis to find what you need 1 2 3 4 5
 static public float Angle360(float y, float x){ float ret = (float) (Math.atan2(y, x) * 180 / Math.PI); if(ret < 0)ret += 360; return ret; } 
try google Atan2 http://polygeek.com/1819_flex_exploringmathatan2




Danny02


«
Reply #12  Posted
20120528 18:02:38 » 

Doesn't work. For arbitrary surfaces you need the full direction and not a single component. Consider rotating the surface about 'y'. You can find the slope but not the maximum direction of change.
sry, I don't get what you are saying. A first thought how to handle player movement would be to check if the surface the player is standing on has a slope below a given threshold. When the slope is high the player starts sliding according to the slope.




Roquen


«
Reply #13  Posted
20120528 18:20:51 » 

In what direction does the player start to slide?




Danny02


«
Reply #14  Posted
20120528 18:36:41 » 

to get direction where to slide you need of course the normal, but to check if you slide is another calculation(the one above)
to get the direction: slideDir = normal x (normal x up)
slope: cos(a) = up * normalize(normal) cos(a) = (normalize(normal)).y // because up = (0, 1, 0)




Roquen


«
Reply #15  Posted
20120528 19:28:04 » 

That was a rhetorical question...you require all three components to know the direction. cross gives direction of plane, project back into plane is direction of max slope..normalize if needed.




theagentd


«
Reply #16  Posted
20120529 12:37:07 » 

That was a rhetorical question...you require all three components to know the direction. cross gives direction of plane, project back into plane is direction of max slope..normalize if needed.
I don't understand the math behind that, so I'll just tell you how I would do it: 1 2 3 4 5 6 7 8 9 10 11 12 13 14
 vec3 t0, t1, t2;
Vec3 u = t1  t0; Vec3 v = t2  t0;
Vec3 n = cross(u, v);
float cosSlopeAngle = n.y / sqrt(n.x*n.x + n.y*n.y + n.z*n.z);
if(cosSlopeAngle > cos(maximumAngle){ vec2 slidingDirection = vec2(n.x, n.z); slidingDirection.normalize(); } 
Excuse my psuedoGLSL...

Myomyomyo.



