Advertisement

Which is the fastest way of calcing point normals?

Started by April 30, 2002 06:54 AM
9 comments, last by brewski 22 years, 9 months ago
I''ve always used this method, but it''s very slow. Adding surfaceNormals of the polys surrounding the vertex, dividing by nrOfPolysSurrounding and normalizing. I set up a lookup-table with indexes to surrounding polys for each vertex.
Brewski
the method you use for calculating normals is well done
in my experience i have found a way of storing information
for a single vertex , normally i use this structure

typedef struct
{
float x,y,z; // coordinate of point in space
float r,g,b,alpha; // color components
float nx,ny,nz; // normal
float t,s; // texture coordintates
};

you compute the normals aas you are doing right now, then
fill the nx,ny,nz values for each relevant point index,
when you need to retrieve the normal just use the index you are using to access the point''s coordinaes in space.

Advertisement
set all normals to 0,0,0
for each face, calculate its normal, and add this to the the 3 normals of the 3 vertices building the face

normalize them all..

that way you get them in O(n), and you get them even with having normals more looking to big faces than to small faces (makes more sence if you take a shit of paper)

"take a look around" - limp bizkit
www.google.com
If that's not the help you're after then you're going to have to explain the problem better than what you have. - joanusdmentia

My Page davepermen.net | My Music on Bandcamp and on Soundcloud

Sorry i was thinking you had some probelm storing the normals , not calculating....


V71-> Thanks for the reply, No appologies needed, gave birth to some new ideas actually.

Davepermen->That''s a faster method than i''ve been using for sure.

Improvement of your method would require a faster calcing of the
surface normal, right?, or is there some other way to do it all?



Brewski
well.. my method uses one crossproduct per face, and one sqrt per vertex (and a lot of additions)

crossproduct can''t be optimized (except you want to code the whole solution in assembler with SSE or 3DNOW instructions)

sqrt _can_ be optimized, and if you say pleaseplease, i''ll post the code for a faster normalization-sqrt (rsq x = 1/sqrt x)

"take a look around" - limp bizkit
www.google.com
If that's not the help you're after then you're going to have to explain the problem better than what you have. - joanusdmentia

My Page davepermen.net | My Music on Bandcamp and on Soundcloud

Advertisement
Please do. I''d love to see that - and probably others too.
I got source for high or low precision fast fixed point sqrt :

I did''nt write it, it''s written by ''Night Stalker'', from a doc named fpt1, I leeched it from somewhere, can''t remember.
It''s for Watcom compiler though, looks a bit weird:

#pragma aux FixedSqrtLP = \
" xor eax, eax" \
" mov ebx, 40000000h" \
"sqrtLP1: mov edx, ecx" \
" sub edx, ebx" \
" jl sqrtLP2" \
" sub edx, eax" \
" jl sqrtLP2" \
" mov ecx,edx" \
" shr eax, 1" \
" or eax, ebx" \
" shr ebx, 2" \
" jnz sqrtLP1" \
" shl eax, 8" \
" jmp sqrtLP3" \
"sqrtLP2: shr eax, 1" \
" shr ebx, 2" \
" jnz sqrtLP1" \
" shl eax, 8" \
"sqrtLP3: nop" \
parm caller [ecx] \
value [eax] \
modify [eax ebx ecx edx];

#pragma aux FixedSqrtHP = \
" xor eax, eax" \
" mov ebx, 40000000h" \
"sqrtHP1: mov edx, ecx" \
" sub edx, ebx" \
" jb sqrtHP2" \
" sub edx, eax" \
" jb sqrtHP2" \
" mov ecx,edx" \
" shr eax, 1" \
" or eax, ebx" \
" shr ebx, 2" \
" jnz sqrtHP1" \
" jz sqrtHP5" \
"sqrtHP2: shr eax, 1" \
" shr ebx, 2" \
" jnz sqrtHP1" \
"sqrtHP5: mov ebx, 00004000h" \
" shl eax, 16" \
" shl ecx, 16" \
"sqrtHP3: mov edx, ecx" \
" sub edx, ebx" \
" jb sqrtHP4" \
" sub edx, eax" \
" jb sqrtHP4" \
" mov ecx, edx" \
" shr eax, 1" \
" or eax, ebx" \
" shr ebx, 2" \
" jnz sqrtHP3" \
" jmp sqrtHP6" \
"sqrtHP4: shr eax, 1" \
" shr ebx, 2" \
" jnz sqrtHP3" \
"sqrtHP6: nop" \
parm caller [ecx] \
value [eax] \
modify [eax ebx ecx edx];

Brewski
inline float rsq(float x)
{
const float half = 0.5f;
const float one_half = 1.5f;

__asm
{
fld x
fmul half

mov eax, x
mov edx, 05F400000h
shr eax, 1
sub edx, eax
mov x, edx

fmul x
fmul x
fsubr one_half
fmul x
fstp x
}

return x;
}

thats the code for a very fast and quite accurate reverse square root.. usage:

assuming your vec is described with x,y,z

float div = rsq(x*x+y*y+z*z);
x*=div;
y*=div;
z*=div;

works in vc and is quite fast..

if you can use sse-instructions you can even use sse (wich supports a fast rsq as well.. and the rest can be done faster then, too..)

"take a look around" - limp bizkit
www.google.com
If that's not the help you're after then you're going to have to explain the problem better than what you have. - joanusdmentia

My Page davepermen.net | My Music on Bandcamp and on Soundcloud

quote:
Original post by v71
the method you use for calculating normals is well done
in my experience i have found a way of storing information
for a single vertex , normally i use this structure

typedef struct
{
float x,y,z; // coordinate of point in space
float r,g,b,alpha; // color components
float nx,ny,nz; // normal
float t,s; // texture coordintates
};

you compute the normals aas you are doing right now, then
fill the nx,ny,nz values for each relevant point index,
when you need to retrieve the normal just use the index you are using to access the point''s coordinaes in space.





Is this a typical representation of a 3d vertex in OpenGL? Would it be a good idea to build such a class to so i dont have to use my Vector objects to represent 3d vertices as well?
Well, that structure contains a lot of the information OGL needs to render the point, color any polygons it''s in, do any lighting, and texture any polygons it''s in.

This topic is closed to new replies.

Advertisement