Sphere Normals

A place to discuss everything related to Newton Dynamics.

Moderators: Sascha Willems, walaber

Sphere Normals

Postby Markus » Wed May 04, 2011 11:46 am

Hey,

I'm rendering objects using the vertex data from NewtonCollisions. I convert the Collision to a NewtonMesh and call NewtonMeshGetVertexStreams. When doing that with spheres it becomes obvious that the vertex normals are not smooth. In the picture, the sphere in the foreground is rendered with gluSphere (correct normals) and the four in the background are rendered using the normals from Newton. I tried to use NewtonMeshCalculateVertexNormals without success. Is there any way to get the correct normals with Newton, or do I have to do that myself?
Attachments
normals.jpg
normals.jpg (36.49 KiB) Viewed 2457 times
Markus
 
Posts: 52
Joined: Sat Mar 19, 2011 6:31 am

Re: Sphere Normals

Postby Julio Jerez » Wed May 04, 2011 12:04 pm

NewtonMeshCreateFromCollision shoudl produce a mesh with smooth normals,
but I beleive you are correct, I just noticed that all the demo do no show smooth normal and it is call NewtonMeshCalculateVertexNormals too.
I will find out why this is happening tonight, it is certainlly not averaging then or doing it wrong.

Thanks for that bug, and I am glad you are usin teh MeshEffect, it is very peweful mesh Ultility, and if peopel use it tehn it will get cleannee am pullished

this is the function tah calculate the normals, it seems right, but there mus tbe a bug some were,
Code: Select all
void dgMeshEffect::CalculateNormals (dgFloat64 angleInRadians)
{
   dgStack<dgBigVector>faceNormal (GetCount());
   dgStack<dgVertexAtribute>attribArray (GetCount());
   EnumerateAttributeArray (&attribArray[0]);

   dgInt32 mark = IncLRU();
   dgPolyhedra::Iterator iter (*this);   
   for(iter.Begin(); iter; iter ++){
      dgEdge* const edge = &(*iter);
      if ((edge->m_mark < mark) && (edge->m_incidentFace > 0)) {
         dgBigVector normal (FaceNormal (edge, &m_points[0].m_x, sizeof (m_points[0])));
         normal = normal.Scale (dgFloat32 (1.0f) / (sqrt(normal % normal) + dgFloat32(1.0e-16f)));

         dgEdge* ptr = edge;
         do {
            dgInt32 index = dgInt32 (ptr->m_userData);
            _ASSERTE (index < GetCount());
            dgVertexAtribute& attrib = attribArray[index];
            faceNormal[index] = normal;
            attrib.m_normal_x = normal.m_x;
            attrib.m_normal_y = normal.m_y;
            attrib.m_normal_z = normal.m_z;

            ptr->m_mark = mark;
            ptr = ptr->m_next;
         } while (ptr !=  edge);
      }
   }


   dgFloat32 smoothValue = dgCos (angleInRadians);
   mark = IncLRU();
   for(iter.Begin(); iter; iter ++){
      dgEdge* edge = &(*iter);
      if (edge->m_incidentFace > 0) {
         dgEdge* const twin = edge->m_twin->m_prev;
         if (twin->m_incidentFace > 0) {
            dgInt32 edgeIndex = dgInt32 (edge->m_userData);
            dgInt32 twinIndex = dgInt32 (twin->m_userData);
            dgFloat64 test = faceNormal[edgeIndex] % faceNormal[twinIndex];
            if (test >= smoothValue) {
               dgVertexAtribute& attrib = attribArray[edgeIndex];
               attrib.m_normal_x += faceNormal[twinIndex].m_x;
               attrib.m_normal_y += faceNormal[twinIndex].m_y;
               attrib.m_normal_z += faceNormal[twinIndex].m_z;
            }
         }
      }
   }

   for(iter.Begin(); iter; iter ++){
      dgEdge* const edge = &(*iter);
      if (edge->m_incidentFace > 0) {
         dgInt32 edgeIndex = dgInt32 (edge->m_userData);
         _ASSERTE (edgeIndex < GetCount());
         dgVertexAtribute& attrib = attribArray[edgeIndex];

         dgBigVector normal (attrib.m_normal_x, attrib.m_normal_y, attrib.m_normal_z, dgFloat32 (0.0f));
         normal = normal.Scale (dgFloat32 (1.0f) / (sqrt (normal % normal) + dgFloat32(1.0e-16f)));
         attrib.m_normal_x = normal.m_x;
         attrib.m_normal_y = normal.m_y;
         attrib.m_normal_z = normal.m_z;
      }
   }

   ApplyAttributeArray (&attribArray[0]);
}
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Sphere Normals

Postby Julio Jerez » Wed May 04, 2011 12:30 pm

Oh I fugure out wha teh bug is, teh funtion is right bu teh funtion does not solve teh right problems

The function average the edge normals, and it needs to averae the Vertex normals instead. ups what a blunder.
I will rewrite it tonight.
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Sphere Normals

Postby Markus » Wed May 04, 2011 12:42 pm

Thanks Julio, I'm looking forward to it!

Another question: Is it possible to control the quality of the sphere approximation of NewtonMesh, i.e. the number of triangles/vertices?
Markus
 
Posts: 52
Joined: Sat Mar 19, 2011 6:31 am

Re: Sphere Normals

Postby Julio Jerez » Thu May 05, 2011 9:30 am

Ok the smooth normal s is fixed now, if you sinc to svn you will get it.

The resultion of the debug promitives can not be adjusted not, however the MehEffect allows you to build promitive anywun you one.

if yo wna to make somethon like a sphere at lower of highet res, you cna simple use

NEWTON_API NewtonMesh* NewtonMeshCreate(const NewtonWorld* const newtonWorld);
void NewtonMeshBeginFace(const NewtonMesh* const mesh);

// in a loop use the parametric equation of the spher, and add one face at a time
void NewtonMeshAddFace(const NewtonMesh* const mesh, int vertexCount, const dFloat* const vertex, int strideInBytes, int materialIndex);


void NewtonMeshEndFace(const NewtonMesh* const mesh);

the you cna apply us eteh oteh funtion like
NEWTON_API void NewtonMeshCalculateVertexNormals(const NewtonMesh* const mesh, dFloat angleInRadians);
NEWTON_API void NewtonMeshApplySphericalMapping(const NewtonMesh* const mesh, int material);

to make give it visual quality.
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Sphere Normals

Postby Markus » Thu May 05, 2011 11:51 am

It seems to work, thanks!

However, the changes you made to other parts of the code do not work with gcc:

../../source/core/dgGoogol.cpp:368: error: invalid suffix "ui64" on integer constant
I changed "ui64" to "LL"

../../source/physics/dgMeshEffectSolidTree.h:111: error: ISO C++ forbids declaration of ‘dgMeshTreeCSGFace’ with no type
I added a forward declaration of dgMeshTreeCSGFace at the top of the header.
Markus
 
Posts: 52
Joined: Sat Mar 19, 2011 6:31 am

Re: Sphere Normals

Postby Julio Jerez » Thu May 05, 2011 10:31 pm

Thank you the debugging, It is fixed now.
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles


Return to General Discussion

Who is online

Users browsing this forum: No registered users and 0 guests

cron