Sign in to follow this  
Dragon_Strike

normal calculation

Recommended Posts

Dragon_Strike    264
could someone please write me a function to calculate normals of a mesh... the function should use the value of float WaterHeight[x][y] and calculate the normals into the field float WaterNormal[x1][y1][z1][x][y] (yea i know its a bit wierd but i dont want to use vectors... i have my reasons...) thx...

Share this post


Link to post
Share on other sites
_DarkWIng_    602
Since it looks like you are calculating normals for planar mesh (water/terrain) this thread will help you.

If you are thinking about general meshes then tell us and we'll give you more specific answer.

PS: And you better have very good reasons for using WaterNormal[x1][y1][z1][x][y]. You probably know it requires 4 multiplications and 4 additions to get a single value from that, right?

Share this post


Link to post
Share on other sites
Guest Anonymous Poster   
Guest Anonymous Poster
lol i dont understand either of those... thats the reason id like to have an alrdy finished function that uses float HeightMap[x][z] and calculates CVECTOR NormalMap[x][z].. ive programmed all the vector operators but not the crossproduct...

if somebopdy could do this for me id be very thankful... shouldnt take much time jsut reprogram some function uve alrdy got..

Share this post


Link to post
Share on other sites
_DarkWIng_    602
Quote:
Original post by Anonymous Poster
lol i dont understand either of those... thats the reason id like to have an alrdy finished function that uses float HeightMap[x][z] and calculates CVECTOR NormalMap[x][z]..

People will generally not just give you the code in the form you need. First you have to show that you did put some work in it. The links posted above or a quick google search would give you more than you need to implement it yourself.

Quote:
Original post by Anonymous Poster
ive programmed all the vector operators but not the crossproduct...

a) Generating terrain/water normals does not require cross product.
b) You should be able to write it yourself in 5 min with a help of math book/Google/open-source projects/.. if you actualy need it.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster   
Guest Anonymous Poster
well the reason i want somebody else to write it is because i cant get it to work myself... here is my code if u can find whats wrong id apprecieate that also...

void CTERRAIN::SetUpNormals(int a)
{

// m_fVec[0]= x;
// m_fVec[1]= y;
// m_fVec[2]= z;

CVECT0R HeightMap[128][128];

for (int z = 0; z 0 && z 0 && x 0 && z 0 && x <

Share this post


Link to post
Share on other sites
Dragon_Strike    264
void CTERRAIN::SetUpNormals(int a)
{

// m_fVec[0]= x;
// m_fVec[1]= y;
// m_fVec[2]= z;

CVECT0R HeightMap[128][128];

for (int z = 0; z < 128; z++){
for (int x = 0; x < 128; x++){
HeightMap[z][x][a].m_fVec[0] = x;
HeightMap[z][x][a].m_fVec[1] = GetWaterHeight(x, z, a);
HeightMap[z][x][a].m_fVec[2] = z;
}
}


CVECTOR v1,v2,v3,v4,v5,v6;
CVECTOR n,n1,n2,n3,n4,n5,n6;

for (int z = 0; z < 128; z++ ) {
for (int x = 0; x < 128; x++ ) {
if ( z == 0 && x == 0 ) {
// back left corner - 1 tri 2 vertices
v1 = HeightMap[z+1][x] - HeightMap[z][x];
v2 = HeightMap[z][x+1] - HeightMap[z][x];

n = Cross(v1,v2);

} else if ( (z > 0 && z < (128-1)) && x == 0 ) {
// left edge - 3 tri 4 vertices
v1 = HeightMap[z][x+1] - HeightMap[z][x];
v2 = HeightMap[z-1][x+1] - HeightMap[z][x];
v3 = HeightMap[z-1][x] - HeightMap[z][x];
v4 = HeightMap[z][x+1] - HeightMap[z][x];

n1 = Cross(v1,v2);
n2 = Cross(v2,v3);
n3 = Cross(v3,v4);

n = (n1+n2+n3)/3.0f;

} else if ( z == (128-1) && x == 0 ) {
// front left corner - 2 tri 3 vertices
v1 = HeightMap[z][x+1] - HeightMap[z][x];
v2 = HeightMap[z-1][x+1] - HeightMap[z][x];
v3 = HeightMap[z-1][x] - HeightMap[z][x];

n1 = Cross(v1,v2);
n2 = Cross(v2,v3);

n = (n1+n2)/2.0f;

} else if ( z == (128-1) && (x > 0 && x < (128-1)) ) {
// front edge - 3 tri 4 vertices
v1 = HeightMap[z][x+1] - HeightMap[z][x];
v2 = HeightMap[z-1][x+1] - HeightMap[z][x];
v3 = HeightMap[z-1][x] - HeightMap[z][x];
v4 = HeightMap[z][x-1] - HeightMap[z][x];

n1 = Cross(v1,v2);
n2 = Cross(v2,v3);
n3 = Cross(v3,v4);

n = (n1+n2+n3)/3.0f;

} else if ( z == (128-1) && x == (128-1) ) {
// front right corner - 1 tri 2 vertices
v1 = HeightMap[z-1][x] - HeightMap[z][x];
v2 = HeightMap[z][x-1] - HeightMap[z][x];

n1 = Cross(v1,v2);

n = n1;

} else if ( ( z > 0 && z < (128-1)) && x == (128-1) ) {
// right edge - 3 tri 4 vertices
v1 = HeightMap[z-1][x] - HeightMap[z][x];
v2 = HeightMap[z][x-1] - HeightMap[z][x];
v3 = HeightMap[z+1][x-1] - HeightMap[z][x];
v4 = HeightMap[z+1][x] - HeightMap[z][x];

n1 = Cross(v1,v2);
n2 = Cross(v2,v3);
n3 = Cross(v3,v4);

n = (n1+n2+n3)/3.0f;

} else if ( z == 0 && x == (128-1) ) {
// back right corner - 2 tri 3 vertices
v1 = HeightMap[z][x-1] - HeightMap[z][x];
v2 = HeightMap[z+1][x-1] - HeightMap[z][x-1];
v3 = HeightMap[z+1][x-1] - HeightMap[z][x];
v4 = HeightMap[z+1][x] - HeightMap[z][x];

n1 = Cross(v1,v2);
n2 = Cross(v3,v4);

n = (n1+n2)/2.0f;

} else if ( z == 0 && ( x > 0 && x < (128-1)) ) {
// back edge - 3 tri 4 vertices
v1 = HeightMap[z][x-1] - HeightMap[z][x];
v2 = HeightMap[z+1][x-1] - HeightMap[z][x];
v3 = HeightMap[z+1][x] - HeightMap[z][x];
v4 = HeightMap[z][x+1] - HeightMap[z][x];

n1 = Cross(v1,v2);
n2 = Cross(v2,v3);
n3 = Cross(v3,v4);

n = (n1+n2+n3)/3.0f;

} else {
// internal - 6 tri 6 vertices
v1 = HeightMap[z][x+1] - HeightMap[z][x];
v2 = HeightMap[z-1][x+1] - HeightMap[z][x];
v3 = HeightMap[z-1][x] - HeightMap[z][x];
v4 = HeightMap[z][x-1] - HeightMap[z][x];
v5 = HeightMap[z+1][x-1] - HeightMap[z][x];
v6 = HeightMap[z+1][x] - HeightMap[z][x];

n1 = Cross(v1,v2);
n2 = Cross(v2,v3);
n3 = Cross(v3,v4);
n4 = Cross(v4,v5);
n5 = Cross(v5,v6);
n6 = Cross(v6,v1);

n = (n1+n2+n3+n4+n5+n6)/6.0f;

}
Normalize(n);

/*inline void SetNormal(int x, int z, int a, float x1, float y1, float z1){

//CVECTOR NormalMap[128][128][128];
// m_fVec[0]= x;
// m_fVec[1]= y;
// m_fVec[2]= z;

NormalMap[x][y][a].m_fVec[0] = x1;
NormalMap[x][y][a].m_fVec[1] = y1;
NormalMap[x][y][a].m_fVec[2] = z1;
}
*/


SetNormal(x, z , a, n.m_fVec[0], n.m_fVec[1], n.m_fVec[2]);
}
}
}

CVECTOR CTERRAIN::Cross(const CVECTOR &vec1, const CVECTOR &vec2){

// m_fVec[0]= x;
// m_fVec[1]= y;
// m_fVec[2]= z;

return CVECTOR(vec1.m_fVec[1] * vec2.m_fVec[2] - vec1.m_fVec[2] * vec2.m_fVec[1],
vec1.m_fVec[2] * vec2.m_fVec[0] - vec1.m_fVec[0] * vec2.m_fVec[2],
vec1.m_fVec[0] * vec2.m_fVec[1] - vec1.m_fVec[1] * vec2.m_fVec[0],);
}

void CTERRAIN::Normalize(CVECTOR &vec){

// m_fVec[0]= x;
// m_fVec[1]= y;
// m_fVec[2]= z;

CVECTOR temp = vec;

float mag = sqrtf(temp.m_fVec[0] * temp.m_fVec[0] + temp.m_fVec[1] * temp.m_fVec[1] + temp.m_fVec[2] * temp.m_fVec[2]);

vec.m_fVec[0] = temp.m_fVec[0] / mag;
vec.m_fVec[1] = temp.m_fVec[1] / mag;
vec.m_fVec[2] = temp.m_fVec[2] / mag;
}

Share this post


Link to post
Share on other sites
Dragon_Strike    264
it seems to be working now (the program starts..) ... but then the next question how do i add lighting to it? right now it looks just like a flat surface although there are waves...

Share this post


Link to post
Share on other sites
Fahrenheit451    498
It seems like you are doing much more than just calculating normals in your SetNormals() routine. You should keep this routine down to just the job of traversing your heightmap and calculating and setting the normals per vertex, and not doing all of things like defining and initialising the heightmap.

Your problem of your surface being flat might be because you pass a value into your SetNormals routine, define yourheightmap (which, btw, exists only for the life of the routine and gets automatically destroyed when the routine ends), **set all vertices in your heightmap to the value passed in**, and then calculate the same normal value for each vertex (since all are the same height). If you are repeatedly calling this routine from inside the rendering code, then you could be potentially setting the heightmap to one value over and over again.

The normal calcs you are using are fine for a one-time setup of a static terrain. Do the terrain initialisation and normal calculation *before* the render routine (ie. in the InitGL() routine). Also, I wouldn't use this lengthy normal calculations for a water mesh. It's prohibitively expensive. Water needs to have the normals calculated every frame (execution of the render routine essentially). For that you should use something more optimised and/or a shortcut method that approximates the normals. I gave an example of one of those routines in the link I provided earlier. It was something like 10 lines long - compared to the 50+ lines of the static mesh routine.

hth
F451

Share this post


Link to post
Share on other sites
Dragon_Strike    264
the temporary heightmap in the routine retrives the values from the "real" heightmap.. i had to do this since the normal calculations uses another "form" of heightmap... soo the heightmap during rendering is still there...

all my waves are precalculated using perlin noise and some of my simple mods in a 3d array WaterHeight[x][z][a]... where i change the a after every rendering... it gives a long initialization but fast rendering...

and about those 10 lines... im clueless of how to use them...

but it looks like this problem wont be solved unless u see all the code which would be to much to post here... thx anyways..

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