CyanPrime
|
 |
«
Posted
2012-05-27 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
2012-05-27 23:51:09 » |
|
Calculate the normal using 3 of the vertices (a triangle) and check the value of y?
|
Myomyomyo.
|
|
|
CyanPrime
|
 |
«
Reply #2 - Posted
2012-05-28 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
2012-05-28 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
2012-05-28 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
2012-05-28 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
2012-05-28 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
2012-05-28 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
2012-05-28 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
2012-05-28 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
2012-05-28 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
2012-05-28 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_exploring-math-atan2
|
Last known State: Reassembled in Cyberspace End Transmission.... .. . Journey began Now)
|
|
|
Danny02
|
 |
«
Reply #12 - Posted
2012-05-28 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
2012-05-28 18:20:51 » |
|
In what direction does the player start to slide?
|
|
|
|
Danny02
|
 |
«
Reply #14 - Posted
2012-05-28 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
2012-05-28 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
2012-05-29 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 psuedo-GLSL...
|
Myomyomyo.
|
|
|
|