🔒 Locked
The $1,000,000 question.
Advertisement
Original Post
I''m sure this has been asked a billion times here, but here goes anyway.
I have a 3d grid made up of triangle strips to make terrain. Any triangle may have any or all of its vertices raised or lowered -- to give the terrain features.
I have a camera on an object that moves over the terrain in first-person view. And, for all intents and purposes, it''s only over one triangle at a time.
The question is: based on the 3 triangle vertices that the camera is over, and the camera''s x and z value, how do I calculate the camera''s Y value so that it is "sitting" on the triangle plane at all times?
I''m guessing it involves the plane formula Ax+By+Cz+D. But I don''t know where to plug in what.
If you have the plane formula of the triangle, you just insert the cameras x and y and solve for z.
So,
Ax+By+Cz+D=0
=>
Ax+By+D=-Cz
=>
(Ax+By+D)/(-C)=z
It''s that simple
Oh, and before I forget ... please enter a meaningful topic the next time ... people will not answer or look at ''stupid''-seeming posts.
Ciao,
MK42
So,
Ax+By+Cz+D=0
=>
Ax+By+D=-Cz
=>
(Ax+By+D)/(-C)=z
It''s that simple
Oh, and before I forget ... please enter a meaningful topic the next time ... people will not answer or look at ''stupid''-seeming posts.
Ciao,
MK42
Hmm. Ok, I guess my problem then is that I don''t understand how to "define" the plane using ABCD.
Can you tell me exactly how I would define those constants using a simple triangular surface?
BTW, I would assume I''d need to find the Y coordinate (ax+cz+d)/-b=y... not the Z; since Y would adjust the camera height and the "surface" is orthogonal to the Y axis.
Can you tell me exactly how I would define those constants using a simple triangular surface?
BTW, I would assume I''d need to find the Y coordinate (ax+cz+d)/-b=y... not the Z; since Y would adjust the camera height and the "surface" is orthogonal to the Y axis.
Oops, you were right about the y/z thing. I got my coordinate system mixed up. Anyways, finding the plane equation given a triangle is not that hard. All you need is the normal vector (Crossproduct of two the edges p0p1 and p0p2, where p0 is the first point in your triangle)
Now, you have a normal vector. In order to get the plane equation, you do this:
A = N.x
B = N.y
C = N.z
D = N.Dot(any point on the plane/triangle ... e.g. p0)
That should do it,
MK42
Now, you have a normal vector. In order to get the plane equation, you do this:
A = N.x
B = N.y
C = N.z
D = N.Dot(any point on the plane/triangle ... e.g. p0)
That should do it,
MK42
Arg! So close. But you are right about the formula. I just have one slight problem.
Here''s what I did. Drew a triangle polygon in a counterclockwise fashion: (0,0,0) (10,0,0) (0,0,10). I''m using OpenGL so Z is left(?) handed.
I used a function to make vectors out of those 3 vertices and called them p1, p2 and p3. Then I called a CalcPlaneNormal function with those 3 vectors -- which basically does this:
VectorSubstract(p2, p1, v1);
VectorSubstract(p3, p1, v2);
VectorCrossProduct(v1, v2, Result);
NormalizeVector(Result);
I plant a Sphere object within the triangular area... say (2,0,2). Then I use the formula to calculate my Y coordinate for the sphere based on its x,z coordinate:
SphereY:=(normalX*SphereX+normalZ*SphereZ+a_value)/-(normalY);
..where normalX, normalY and normalZ are from the CalcPlaneNormal function. a_value just seems to give me a "hover" value that lets the object sit above the plane... quite convenient actually. I just popped in 0.5 to make the sphere sit above the plane instead of in it. Not sure if this "D" value is causing the problem but I don''t think so.
Now, to test this I varied the Y coordinates of all the triangle''s vertices. In theory, regardless of the angle, the formula should generate a Y value that makes the sphere sit just on the plane.
Well, it works perfectly if I alter the second or third triangle vertices. BUT for some strange reason, if I touch the *first* vertices of the triangle, the sphere drops below the plane.
The only thing I can think of is that the normal is not getting generated correctly (or inversely?) when I touch that first vertices. Any ideas? I''m so close, yet... ack.
Here''s what I did. Drew a triangle polygon in a counterclockwise fashion: (0,0,0) (10,0,0) (0,0,10). I''m using OpenGL so Z is left(?) handed.
I used a function to make vectors out of those 3 vertices and called them p1, p2 and p3. Then I called a CalcPlaneNormal function with those 3 vectors -- which basically does this:
VectorSubstract(p2, p1, v1);
VectorSubstract(p3, p1, v2);
VectorCrossProduct(v1, v2, Result);
NormalizeVector(Result);
I plant a Sphere object within the triangular area... say (2,0,2). Then I use the formula to calculate my Y coordinate for the sphere based on its x,z coordinate:
SphereY:=(normalX*SphereX+normalZ*SphereZ+a_value)/-(normalY);
..where normalX, normalY and normalZ are from the CalcPlaneNormal function. a_value just seems to give me a "hover" value that lets the object sit above the plane... quite convenient actually. I just popped in 0.5 to make the sphere sit above the plane instead of in it. Not sure if this "D" value is causing the problem but I don''t think so.
Now, to test this I varied the Y coordinates of all the triangle''s vertices. In theory, regardless of the angle, the formula should generate a Y value that makes the sphere sit just on the plane.
Well, it works perfectly if I alter the second or third triangle vertices. BUT for some strange reason, if I touch the *first* vertices of the triangle, the sphere drops below the plane.
The only thing I can think of is that the normal is not getting generated correctly (or inversely?) when I touch that first vertices. Any ideas? I''m so close, yet... ack.
First of all, you should use this:
SphereY:=(normalX*SphereX+normalZ*SphereZ)/-(normalY) + a_value;
You calculate the Y on the plane and then offset it by a_value.
I don''t quite understand what''s you are doing. You have a triangle and then you are modifying the vertices to see, if the sphere is moving the way you expect?
Are you recalculating the plane equation, after modifying the triangle?
- MK42
SphereY:=(normalX*SphereX+normalZ*SphereZ)/-(normalY) + a_value;
You calculate the Y on the plane and then offset it by a_value.
I don''t quite understand what''s you are doing. You have a triangle and then you are modifying the vertices to see, if the sphere is moving the way you expect?
Are you recalculating the plane equation, after modifying the triangle?
- MK42
<this is turning into an epic...
>
Yes, basically I have a triangle lying flat on the "ground" ie: the xz axis. Therefore all three of the triangle''s vertices have a Y coordinate that is zero.
So, when I raise the Y coordinate of any of those vertices, the angle of the triangle face (ie: the plane) changes. I do this to simulate any combination of slopes the face could possibly take on my terrain grid.
Depending on where I put my sphere within the triangle''s area (specifically the X and Z coordinate), the Y coordinate of the sphere should adjust up or down to make it "sit on" the triangle face. That is what the formula you gave me is for. It finds that point on the face for the sphere to sit. And I *think* it works fine.
Now, after playing a bit more with it, I''m beginning to think that my normals are not correct somehow. But it''s deceiving because it does work sometimes.
First of all, if I move the triangle *away* from the origin of 0,0,0 everything goes wacky. For example, if I make the triangle at (10,0,0)(0,0,10)(10,0,10) and then try my experiment, the sphere will be all over the place (too high, or even way below the face)... unlike origin 0,0,0 where only one vertex gives me a problem.
I decided to remove the CalcPlaneNormal function and do it myself, just to see if that was the problem. Maybe you can see something wrong. It''s in Delphi so pretty self explanatory:
///here is the meat of the code///
SetVector(p1,Polygon1.Nodes[0].x,Polygon1.Nodes[0].y,Polygon1.Nodes[0].z); //makes vector p1 for triangle node 0
SetVector(p2,Polygon1.Nodes[1].x,Polygon1.Nodes[1].y,Polygon1.Nodes[1].z); //makes vector p1 for triangle node 1
SetVector(p3,Polygon1.Nodes[2].x,Polygon1.Nodes[2].y,Polygon1.Nodes[2].z); //makes vector p1 for triangle node 2
va:=VectorSubtract(p2,p1); //remove object''s position from vector
vb:=VectorSubtract(p3,p1);
pnormal:=VectorCrossProduct(va,vb);
{so pnormal[0] = normal x, pnormal[1] = normal y, pnormal[2] = z }
//the rest is basic but uses your formula
with Sphere1.Position do begin
px:=x;
py:=y;
pz:=z;
end;
pa:=pnormal[0];
pb:=pnormal[1];
pc:=pnormal[2];
pd:=1.0;
// (ax+cz+d)/-b=y
presult:=(pa*px+pc*pz+pd)/-(pb);
Sphere1.Position.y:=presult;
//// end of the insanity /////////////
So after doing this manually, it turns out that the CalcPlaneNormal function was giving me the same results
. I''m really stumped. I think I''m missing some basic vector concept or something.
I''ll have a few beers and see if that helps
Yes, basically I have a triangle lying flat on the "ground" ie: the xz axis. Therefore all three of the triangle''s vertices have a Y coordinate that is zero.
So, when I raise the Y coordinate of any of those vertices, the angle of the triangle face (ie: the plane) changes. I do this to simulate any combination of slopes the face could possibly take on my terrain grid.
Depending on where I put my sphere within the triangle''s area (specifically the X and Z coordinate), the Y coordinate of the sphere should adjust up or down to make it "sit on" the triangle face. That is what the formula you gave me is for. It finds that point on the face for the sphere to sit. And I *think* it works fine.
Now, after playing a bit more with it, I''m beginning to think that my normals are not correct somehow. But it''s deceiving because it does work sometimes.
First of all, if I move the triangle *away* from the origin of 0,0,0 everything goes wacky. For example, if I make the triangle at (10,0,0)(0,0,10)(10,0,10) and then try my experiment, the sphere will be all over the place (too high, or even way below the face)... unlike origin 0,0,0 where only one vertex gives me a problem.
I decided to remove the CalcPlaneNormal function and do it myself, just to see if that was the problem. Maybe you can see something wrong. It''s in Delphi so pretty self explanatory:
///here is the meat of the code///
SetVector(p1,Polygon1.Nodes[0].x,Polygon1.Nodes[0].y,Polygon1.Nodes[0].z); //makes vector p1 for triangle node 0
SetVector(p2,Polygon1.Nodes[1].x,Polygon1.Nodes[1].y,Polygon1.Nodes[1].z); //makes vector p1 for triangle node 1
SetVector(p3,Polygon1.Nodes[2].x,Polygon1.Nodes[2].y,Polygon1.Nodes[2].z); //makes vector p1 for triangle node 2
va:=VectorSubtract(p2,p1); //remove object''s position from vector
vb:=VectorSubtract(p3,p1);
pnormal:=VectorCrossProduct(va,vb);
{so pnormal[0] = normal x, pnormal[1] = normal y, pnormal[2] = z }
//the rest is basic but uses your formula
with Sphere1.Position do begin
px:=x;
py:=y;
pz:=z;
end;
pa:=pnormal[0];
pb:=pnormal[1];
pc:=pnormal[2];
pd:=1.0;
// (ax+cz+d)/-b=y
presult:=(pa*px+pc*pz+pd)/-(pb);
Sphere1.Position.y:=presult;
//// end of the insanity /////////////
So after doing this manually, it turns out that the CalcPlaneNormal function was giving me the same results
I''ll have a few beers and see if that helps
The fuction I have available is VectorDotProduct(const V1, V2 : TAffineVector) Single; (plug in two vectors and get a real result).
So I plugged in two of the vertices from the triangle to get the real result, and made it D. Now I''m getting crazy Y values like 200+.
What am I doing wrong?
So I plugged in two of the vertices from the triangle to get the real result, and made it D. Now I''m getting crazy Y values like 200+.
What am I doing wrong?
Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement