NewtonCreateConvexHull returns NIL with valid vertex data.

Report any bugs here and we'll post fixes

Moderators: Sascha Willems, Thomas

NewtonCreateConvexHull returns NIL with valid vertex data.

Postby Corpsman » Sun Jun 19, 2011 4:15 am

Sorry for the subject but i did not now how to descripe it better.

Heres the Problem.

I have a cloud of points and want to create a collider with NewtonCreateConvexHull

In Newton version 2.15 it worked now with 2.31 ( or maybe 2.33 see here why i'm not shure about the version) it did not wok.

Here is how i create the point cloud

the first n points describ a circle with radius r1 and the second n points descibe a second circle with radius r2. Both circles lie in the x1, x3 plane. The second circle with different x2 coordinates by 0.2 so the result gives a tin with r1,r2 and a height of 0.2.

If i choose r1 and r2 > 0.2 there is no problem. But if i choose one of the radius less than 0.2 the NewtonCreateConvexHull returns NIL, tolerance is always 0.0

So the question is, how do i have to modify my cloud that NewtonCreateConvexHull did not return NIL ?

sincerely

Corpsman

[Edit Update]

The NewtonCreateConvexHull returns nil even if e replace the circle with radius less than 0.2 through only one point in the middle.
--
You want to Know more about me and my projects visit http://www.Corpsman.de
I use Newton in Balanced2
Corpsman
 
Posts: 38
Joined: Mon May 01, 2006 11:42 am

Re: NewtonCreateConvexHull returns NIL with valid vertex dat

Postby Julio Jerez » Sun Jun 19, 2011 8:58 am

I made some changes to the function when I added the voronoid decomposition, but it sodu no affect the full creation.
My guess is that some tolerance funtion is failing and teh funtion is bailn withopu creating the hull .

can you post the function you use to create the point cloud so that I can test it?
Julio Jerez
Moderator
Moderator
 
Posts: 12249
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: NewtonCreateConvexHull returns NIL with valid vertex dat

Postby Corpsman » Sun Jun 19, 2011 10:32 am

After some Research in your Wiki i found the NewtonCreateCone funktion, which gave me a way of Workaround. The Creating Routines are shared along my whole Projekt here are the relevant parts, ...

1. I Create the Disk with :

Code: Select all
Procedure Tdisk.Reset;
Var
  d: Single;
  x: INteger;
  winkel: integer;
Begin
  If High(FPoints) = -1 Then exit; // Abfangen der Division durch 0
  d := 360 / (high(Fpoints) + 1);
  // Berechnen der Position der Punkte so das sie senkrecht im Raum stehen um "0" herum auf der Y - X - Ebene.
  For x := 0 To high(Fpoints) Do Begin
    winkel := round(d * x);
    winkel := max(0, min(359, winkel));
    Fpoints[x] := v3(btypes.aCoSinus[winkel] * fradius, btypes.aSinus[winkel] * fradius, 0);
  End;
  FTranslated := v3(0, 0, 0);
End;

2.
After this there where some Rotations and Translations ( the Code above creates the circle disk at the x,y plane ). And here is the Newton Code

Code: Select all
Procedure TNewtonConvexHull.AddtoNewtonworld(Const Newtonworld: Pnewtonworld; Mass_, Material: Integer);
Var
  tp: Array Of TVector3f;
  Collision: PNewtonCollision;
  i: Integer;
  ot, Inertia, Origin: TVector3f;
  id: TOpenGL_0_to_15_Matrix;
Begin
  If high(fpoints) = -1 Then exit;
  fmass := Mass_;
  //Calculate the "middle" point, so that we can move it to Origin.
  Origin := Fpoints[0];
  i := 1;
  While i < high(Fpoints) Do Begin
    Origin := Addv3(Origin, Fpoints[i]);
    inc(i);
  End;
  Origin := ScaleV3(1 / (high(Fpoints) + 1), Origin);
  setlength(tp, high(fpoints) + 1);
  For i := 0 To high(tp) Do
    tp[i] := SubV3(Fpoints[i], Origin);
  ot := Origin;
  (*
  Version 2.11 Added ShapeID = 0
  *)
  Collision := NewtonCreateConvexHull(newtonworld, high(fpoints) + 1, @tp[0].x, 12, 0, 0, Nil);
  If Not assigned(Collision) Then Begin
    writeln('Error coud not execute "NewtonCreateConvexHull" call from "TNewtonConvexHull.AddtoNewtonworld", return value is NIL.');
  End;
  Else
  Begin
    //  id[3] := fPosition.x + ot.x;      Eigentlich sollte das allein genügen aber anscheinend ist dem nicht so ..
    //  id[7] := fPosition.y + ot.y;
    //  id[11] := fPosition.z + ot.z;
    // Create the rigid body
    id := IdentityOpenGL_0_to_15_Matrix;
    fNewtonBody := NewtonCreateBody(NewtonWorld, Collision, @id[0]);
    // Da wir unbewegliche Objecte Haben ist das Berechnen des Schwerpunktes sehr einfach !!!
    If Mass_ = 0 Then
      NewtonBodySetMassMatrix(fNewtonBody, 0, 0, 0, 0)
    Else Begin
      NewtonConvexCollisionCalculateInertialMatrix(Collision, @Inertia, @Origin);
      NewtonBodySetMassMatrix(fNewtonBody, Mass_, inertia.x * Mass_, inertia.y * Mass_, inertia.z * Mass_)
    End;
    // Remove the collider, we don't need it anymore
    NewtonReleaseCollision(NewtonWorld, Collision);
    // Now set the position of the body's matrix  wird nun mit ID gemacht !!
    NewtonBodyGetMatrix(fNewtonBody, @FMatrix[0, 0]);
    fMatrix[3, 0] := fPosition.x + ot.x;
    fMatrix[3, 1] := fPosition.y + ot.y;
    fMatrix[3, 2] := fPosition.z + ot.z;
    NewtonBodySetMatrix(fNewtonBody, @fMatrix[0, 0]);
    oldpos := addv3(Fposition, ot);
    fio := ot;
    //   Finally set the callback in which the forces on this body will be applied
    NewtonBodySetForceAndTorqueCallBack(fNewtonBody, @ForceAndTorqueCallBack);
    NewtonBodySetMaterialGroupID(fnewtonbody, Material);
  End;
End;


I Hope this helps.
--
You want to Know more about me and my projects visit http://www.Corpsman.de
I use Newton in Balanced2
Corpsman
 
Posts: 38
Joined: Mon May 01, 2006 11:42 am

Re: NewtonCreateConvexHull returns NIL with valid vertex dat

Postby Julio Jerez » Sun Jun 19, 2011 2:22 pm

I do not undertand tha code,
can you print the point array, and post it instead.
It should be an array of floats like this

1.0 2.0 3.1
2.3 2.1 4.55
..
..
Julio Jerez
Moderator
Moderator
 
Posts: 12249
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: NewtonCreateConvexHull returns NIL with valid vertex dat

Postby Corpsman » Mon Jun 20, 2011 11:34 am

here the coordinates : this one is the "Cone" version. the most common case.

0.65 -0.10 0.15
0.58 -0.10 0.40
0.40 -0.10 0.58
0.15 -0.10 0.65
-0.10 -0.10 0.58
-0.29 -0.10 0.40
-0.35 -0.10 0.15
-0.29 -0.10 -0.10
-0.10 -0.10 -0.29
0.15 -0.10 -0.35
0.40 -0.10 -0.29
0.58 -0.10 -0.10
0.15 0.10 0.15
0.15 0.10 0.15
0.15 0.10 0.15
0.15 0.10 0.15
0.15 0.10 0.15
0.15 0.10 0.15
0.15 0.10 0.15
0.15 0.10 0.15
0.15 0.10 0.15
0.15 0.10 0.15
0.15 0.10 0.15
0.15 0.10 0.15


the second version crashes too, this one is with the try to avoid same points more than one time

0.30 0.17 0.25
0.80 -0.03 0.25
0.74 -0.03 0.50
0.55 -0.03 0.68
0.30 -0.03 0.75
0.05 -0.03 0.68
-0.13 -0.03 0.50
-0.20 -0.03 0.25
-0.13 -0.03 -0.00
0.05 -0.03 -0.18
0.30 -0.03 -0.25
0.55 -0.03 -0.18
0.74 -0.03 -0.00
--
You want to Know more about me and my projects visit http://www.Corpsman.de
I use Newton in Balanced2
Corpsman
 
Posts: 38
Joined: Mon May 01, 2006 11:42 am

Re: NewtonCreateConvexHull returns NIL with valid vertex dat

Postby Julio Jerez » Mon Jun 20, 2011 2:58 pm

They look very straighforward ste of points, I will test it tonight and see what is goin on.
are you using version 33 or are you sync to SVN?
Julio Jerez
Moderator
Moderator
 
Posts: 12249
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: NewtonCreateConvexHull returns NIL with valid vertex dat

Postby Corpsman » Mon Jun 20, 2011 3:31 pm

Like i posted in this post i downloaded the source from here and compiled it with g++

The NewtonImport.pas begins with :

{*******************************************************************************}
{ }
{ Newton Game Dynamics Delphi-Headertranslation }
{ Current SDK version 2.33 (Beta)(Revision #1) }
{ }
{ Copyright (c) 2004-2011 }


But NewtonWorldGetVersion tells me
Newton Version : 2.31


I viewed the Points with OpenGL, and they look like described, a circle with one point above it. The translation of the second point cload came from the mass centre calculation bevor i pass the points to newton.
--
You want to Know more about me and my projects visit http://www.Corpsman.de
I use Newton in Balanced2
Corpsman
 
Posts: 38
Joined: Mon May 01, 2006 11:42 am

Re: NewtonCreateConvexHull returns NIL with valid vertex dat

Postby Julio Jerez » Wed Jun 22, 2011 10:16 am

I pasted this code function in 2.33
Code: Select all
void xxxxx (NewtonWorld* const world)
{
   float points[] = {
      0.65, -0.10, 0.15,
      0.58, -0.10, 0.40,
      0.40, -0.10, 0.58,
      0.15, -0.10, 0.65,
      -0.10, -0.10, 0.58,
      -0.29, -0.10, 0.40,
      -0.35, -0.10, 0.15,
      -0.29, -0.10, -0.10,
      -0.10, -0.10, -0.29,
      0.15, -0.10, -0.35,
      0.40, -0.10, -0.29,
      0.58, -0.10, -0.10,
      0.15, 0.10, 0.15,
      0.15, 0.10, 0.15,
      0.15, 0.10, 0.15,
      0.15, 0.10, 0.15,
      0.15, 0.10, 0.15,
      0.15, 0.10, 0.15,
      0.15, 0.10, 0.15,
      0.15, 0.10, 0.15,
      0.15, 0.10, 0.15,
      0.15, 0.10, 0.15,
      0.15, 0.10, 0.15,
      0.15, 0.10, 0.15};

      NewtonCollision* coll = NewtonCreateConvexHull(world, sizeof (points) / (3 * sizeof (points[0])), points, 3 * sizeof (float), 0.0f, 0, NULL );
      _ASSERTE (coll);
      NewtonReleaseCollision(world, coll);

}

and you are correct the convex hull is bailing out with a null hull, this was because the convex hull initially was written, to be used for collision detection,
if the size of a shape was too small it does not generates the hull because it was going to be problematic anyway.

you have two solutions, sync to SVN and or edit the file that creates the problem. if you just edit the file here is the solution
open file ..\coreLibrary_200\source\core\dgConvexHull3d.cpp
find function dgConvexHull3d::InitVertexArray and replace it with this one
Code: Select all
dgInt32 dgConvexHull3d::InitVertexArray(dgHullVertex* const points, const dgFloat64* const vertexCloud, dgInt32 strideInBytes, dgInt32 count, void* const memoryPool, dgInt32 maxMemSize)
{
   dgInt32 stride = dgInt32 (strideInBytes / sizeof (dgFloat64));
   if (stride >= 4) {
      for (dgInt32 i = 0; i < count; i ++) {
         dgInt32 index = i * stride;
         dgBigVector& vertex = points[i];
         vertex = dgBigVector (vertexCloud[index], vertexCloud[index + 1], vertexCloud[index + 2], vertexCloud[index + 3]);
         _ASSERTE (dgCheckVector(vertex));
         points[i].m_index = 0;
      }
   } else {
      for (dgInt32 i = 0; i < count; i ++) {
         dgInt32 index = i * stride;
         dgBigVector& vertex = points[i];
         vertex = dgBigVector (vertexCloud[index], vertexCloud[index + 1], vertexCloud[index + 2], dgFloat64 (0.0f));
         _ASSERTE (dgCheckVector(vertex));
         points[i].m_index = 0;
      }
   }

   dgSort(points, count, ConvexCompareVertex);

   dgInt32 indexCount = 0;
   for (int i = 1; i < count; i ++) {
      for (; i < count; i ++) {
         if (ConvexCompareVertex (&points[indexCount], &points[i], NULL)) {
            indexCount ++;
            points[indexCount] = points[i];
            break;
         }
      }
   }
   count = indexCount + 1;
   if (count < 4) {
      m_count = 0;
      _ASSERTE (0);
      return count;
   }

   dgAABBPointTree3d* tree = BuildTree (NULL, points, count, 0, (dgInt8**) &memoryPool, maxMemSize);

   dgBigVector boxSize (tree->m_box[1] - tree->m_box[0]);   
   m_diag = dgFloat32 (sqrt (boxSize % boxSize));

   dgStack<dgBigVector> normalArrayPool (256);
   dgBigVector* const normalArray = &normalArrayPool[0];
   dgInt32 normalCount = BuildNormalList (&normalArray[0]);

   dgInt32 index = SupportVertex (&tree, points, normalArray[0]);
   m_points[0] = points[index];
   points[index].m_index = 1;

   bool validTetrahedrum = false;
   dgBigVector e1 (dgFloat64 (0.0f), dgFloat64 (0.0f), dgFloat64 (0.0f), dgFloat64 (0.0f)) ;
   for (dgInt32 i = 1; i < normalCount; i ++) {
      dgInt32 index = SupportVertex (&tree, points, normalArray[i]);
      _ASSERTE (index >= 0);

      e1 = points[index] - m_points[0];
      dgFloat64 error2 = e1 % e1;
      if (error2 > (dgFloat32 (1.0e-4f) * m_diag * m_diag)) {
         m_points[1] = points[index];
         points[index].m_index = 1;
         validTetrahedrum = true;
         break;
      }
   }
   if (!validTetrahedrum) {
      m_count = 0;
      _ASSERTE (0);
      return count;
   }

   validTetrahedrum = false;
   dgBigVector e2(dgFloat32 (0.0f), dgFloat32 (0.0f), dgFloat32 (0.0f), dgFloat32 (0.0f));;
   dgBigVector normal (dgFloat32 (0.0f), dgFloat32 (0.0f), dgFloat32 (0.0f), dgFloat32 (0.0f));
   for (dgInt32 i = 2; i < normalCount; i ++) {
      dgInt32 index = SupportVertex (&tree, points, normalArray[i]);
      _ASSERTE (index >= 0);
      e2 = points[index] - m_points[0];
      normal = e1 * e2;
      dgFloat64 error2 = sqrt (normal % normal);
      if (error2 > (dgFloat32 (1.0e-4f) * m_diag * m_diag)) {
         m_points[2] = points[index];
         points[index].m_index = 1;
         validTetrahedrum = true;
         break;
      }
   }

   if (!validTetrahedrum) {
      m_count = 0;
      _ASSERTE (0);
      return count;
   }

   // find the largest possible tetrahedron
   validTetrahedrum = false;
   dgBigVector e3(dgFloat32 (0.0f), dgFloat32 (0.0f), dgFloat32 (0.0f), dgFloat32 (0.0f));

   index = SupportVertex (&tree, points, normal);
   e3 = points[index] - m_points[0];
   dgFloat64 error2 = normal % e3;
   if (fabs (error2) > (dgFloat64 (1.0e-6f) * m_diag * m_diag)) {
      // we found a valid tetrahedra, about and start build the hull by adding the rest of the points
      m_points[3] = points[index];
      points[index].m_index = 1;
      validTetrahedrum = true;
   }
   if (!validTetrahedrum) {
      dgVector n (normal.Scale(dgFloat64 (-1.0f)));
      dgInt32 index = SupportVertex (&tree, points, n);
      e3 = points[index] - m_points[0];
      dgFloat64 error2 = normal % e3;
      if (fabs (error2) > (dgFloat64 (1.0e-6f) * m_diag * m_diag)) {
         // we found a valid tetrahedra, about and start build the hull by adding the rest of the points
         m_points[3] = points[index];
         points[index].m_index = 1;
         validTetrahedrum = true;
      }
   }
   if (!validTetrahedrum) {
      for (dgInt32 i = 3; i < normalCount; i ++) {
         dgInt32 index = SupportVertex (&tree, points, normalArray[i]);
         _ASSERTE (index >= 0);

         //make sure the volume of the fist tetrahedral is no negative
         e3 = points[index] - m_points[0];
         dgFloat64 error2 = normal % e3;
         if (fabs (error2) > (dgFloat64 (1.0e-6f) * m_diag * m_diag)) {
            // we found a valid tetrahedra, about and start build the hull by adding the rest of the points
            m_points[3] = points[index];
            points[index].m_index = 1;
            validTetrahedrum = true;
            break;
         }
      }
   }
   if (!validTetrahedrum) {
      // the points do not form a convex hull
      m_count = 0;
      //_ASSERTE (0);
      return count;
   }

   m_count = 4;
   dgFloat64 volume = TetrahedrumVolume (m_points[0], m_points[1], m_points[2], m_points[3]);
   if (volume > dgFloat64 (0.0f)) {
      Swap(m_points[2], m_points[3]);
   }
   _ASSERTE (TetrahedrumVolume(m_points[0], m_points[1], m_points[2], m_points[3]) < dgFloat64(0.0f));

   return count;
}
Julio Jerez
Moderator
Moderator
 
Posts: 12249
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: NewtonCreateConvexHull returns NIL with valid vertex dat

Postby Corpsman » Wed Jun 22, 2011 2:20 pm

Jehaa, downloaded the SVN version, now its version 2.34 and works fine. Thanks for that great work.

Unfortunatunelly there is no linux make file for Win32, and so i have to wait until a new Win32 SDK is releaced to disable my workaround.

Thanks for your work.

Corpsman
--
You want to Know more about me and my projects visit http://www.Corpsman.de
I use Newton in Balanced2
Corpsman
 
Posts: 38
Joined: Mon May 01, 2006 11:42 am

Re: NewtonCreateConvexHull returns NIL with valid vertex dat

Postby Julio Jerez » Wed Jun 22, 2011 3:14 pm

what do you mean "no linux make file for win32"
there are a linux 32 and Linux 64 make files
Julio Jerez
Moderator
Moderator
 
Posts: 12249
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: NewtonCreateConvexHull returns NIL with valid vertex dat

Postby Corpsman » Wed Jun 22, 2011 3:40 pm

*g*

i am a linux user, i changed from windows to linux two years ago ( this means i know something from linux, but really not enough to solve my problems by myself)
i develop with lazarus which is portable between linux, Mac, Windows and some other plattforms.

Linux is my conviction, but i am not naive, i know that there are a lot of people, which will never change to linux.

So i compile my binaries for win32 and linux, the linux testing is easy, because i have linux machine, the windows testing much more difficult, since i don't have windows any more. I have some friends, testing my croscompilations. But they do not have any compiler and are not willing to install any of them. So i Crosscompile from my Linux 32 Bit machine to Win32 Bit. With FreePasCal ( the programming language for which Lazarus is designed for) this step is a easy one.

"linux make file for win32" in my case means, that i run a make skript from a linux shell, and the result will be a win32 newton.dll

while this is not possible, my only way is to wait for the next sdk, hoping that it will contain the newton.dll so as the 2.30 sdk does.
--
You want to Know more about me and my projects visit http://www.Corpsman.de
I use Newton in Balanced2
Corpsman
 
Posts: 38
Joined: Mon May 01, 2006 11:42 am

Re: NewtonCreateConvexHull returns NIL with valid vertex dat

Postby Corpsman » Sat Aug 27, 2011 4:10 am

I testet SVN revision 716, Newton ver. 2,34. Under Kubuntu 11.04 32-Bit, everything seems to work fine.

( expect the need of change gcc to g++ in the makefile )
--
You want to Know more about me and my projects visit http://www.Corpsman.de
I use Newton in Balanced2
Corpsman
 
Posts: 38
Joined: Mon May 01, 2006 11:42 am


Return to Bugs and Fixes

Who is online

Users browsing this forum: No registered users and 2 guests