Sign in to follow this  
Unreal

3DS Loader very slow on ComputeNormals! Help!!

Recommended Posts

Hello guys! I have a problem with 3DS Loader from www.gametutorials.com The Function ComputeNormals() is VERY VERY VERY slow for Hi Polygon Models. I made 2-3 Spheres with sum vertices be 25.000. To compute the Normals made about 22 seconds! And if I put more... oh.. i dont want to know... It will be much more!Any idea how to speed up this function? My CPU is an AMD Athlon Barton Core 512Cache 2000MHz with 200FSB thank you!

Share this post


Link to post
Share on other sites
you're right, digiben's averaging-normals-function is a mess.

i had the same problem with it. my comp needed between 60-90 seconds to compute models with 10k+ polys. so i rewrote it, now it takes about 2-3 seconds for the same models. but the source is kinda complicated and it doesnt determine hard edges (yet). but if you like, i can post it here nonetheless...

for now i can give you this link:
Smooth Normal Generation with Preservation of Edges

it's by Nate Robins. look for the file glm.c and for the function named glmVertexNormals(). i think that's all you'll need :)

Share this post


Link to post
Share on other sites
well, you've asked for it! [smile]
please dont bitch about the source. the snippet is a part of a reeeally huge project of mine (my diploma thesis; game engine + game). some parts arent really polished because of the lack of time and all the code just had to work... blah.


void c_mesh_manipulator::smooth_normals( i_mesh* mesh, t_f32 angle_degree )
{
debug_assert( mesh );

t_f32 angle = angle_degree * math::deg_to_rad_factor;

std::vector < s_face_list > store;

size_t i, j;
size_t buffer_count = mesh->get_vertex_buffer_count();

for ( i = 0; i < buffer_count; ++i )
{
i_vertex_buffer* buffer = mesh->get_vertex_buffer( i );
debug_assert( buffer );

vid::s_vertex_data& vertex_data = buffer->get_vertex_data();
math::t_vector3f* vertices = vertex_data.get_vertex_pointer();
t_u32 num_vertices = vertex_data.get_vertex_count();

vid::s_index_data& index_data = buffer->get_index_data();
t_u16* indices = index_data.get_index_pointer();

t_u32 num_indices = index_data.get_index_count();
t_u32 num_triangles = num_indices / 3;

store.clear();
store.resize( num_vertices );

t_u16 a, b, c;
s_face s;

for ( j = 0; j < num_triangles; ++j )
{
a = indices[ 3 * j + 0 ];
b = indices[ 3 * j + 1 ];
c = indices[ 3 * j + 2 ];

math::t_vector3f& v0 = vertices[ a ];
math::t_vector3f& v1 = vertices[ b ];
math::t_vector3f& v2 = vertices[ c ];

s.idx = j;
s.a = a; s.b = b; s.c = c;
s.normal = ( v0 - v1 ).cross_product( v2 - v1 );
s.normal.normalize();

store[ a ].list.push_back( s );
store[ b ].list.push_back( s );
store[ c ].list.push_back( s );
}


math::t_vector3f* normals = vertex_data.get_normal_pointer();

for ( j = 0; j < num_vertices; ++j )
{
math::t_vector3f sum( 0, 0, 0 );
bool averaged = false;
int shared = 0;

size_t size = store[ j ].list.size();
for ( size_t idx = 0; idx < size; ++idx )
{
s_face& tri = store[ j ].list[ idx ];

// TODO: determine hard edges here

sum += tri.normal;
++shared;
}

t_f32 scale = -shared;
math::t_vector3f tv;
tv.x = sum.x / scale;
tv.y = sum.y / scale;
tv.z = sum.z / scale;
tv.normalize();

normals[ j ] = tv;
}
}
}

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