Sign in to follow this  

3DS Loader very slow on ComputeNormals! Help!!

This topic is 4866 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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
thats for the link man! But if you like post your way here to get some ideas.
thanks in advnace!

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
Sign in to follow this