ShowDebugPolygon callback no index data

Report any bugs here and we'll post fixes

Moderators: Sascha Willems, Thomas

ShowDebugPolygon callback no index data

Postby Lax » Mon Dec 11, 2017 2:52 pm

Hi,

I'm trying to get OgreNewt running with new Ogre2.1. I'm stuck with the OgreNewtDebugger, as there is the callback function:
Code: Select all
void _CDECL Debugger::newtonPerPoly(void* userData, int vertexCount, const dFloat* faceVertec, int id)

which is called inside newton in ShowDebugPolygon. But the issue is:
Since Ogre2.1 each manual object needs indices, but Its not possible to get them from newton, even there are available inside ShowDebugPolygon. But the callback is called with those parameters:
Code: Select all
data.m_callback (data.m_userData, indexCount, &triplex[0].m_x, indexArray[-1]);

Where the index array is wrong and has wrong dimension. E.g. if indexCount is 4, the index array should also have 4 values.

See code in OgreNewt:
Code: Select all
void _CDECL Debugger::newtonPerPoly(void* userData, int vertexCount, const dFloat* faceVertec, int id)
   {
      Ogre::ManualObject* lines = (Ogre::ManualObject*)userData;
      Ogre::Vector3 p0, p1;

      if (vertexCount < 2)
         return;

      int i = vertexCount - 1;
      p0 = Ogre::Vector3(faceVertec[(i * 3) + 0], faceVertec[(i * 3) + 1], faceVertec[(i * 3) + 2]);

      for (i = 0; i < vertexCount; i++)
      {
         p1 = Ogre::Vector3(faceVertec[(i * 3) + 0], faceVertec[(i * 3) + 1], faceVertec[(i * 3) + 2]);

         lines->position(p0);
         lines->position(p1);
         lines->line(?, ?);

         p0 = p1;
      }
}

So what sould be the indices for lines->line ?

Any idea, how to fix this?

Regards
Lax
Lax
 
Posts: 46
Joined: Sat Jan 08, 2011 8:24 am

Re: ShowDebugPolygon callback no index data

Postby Lax » Tue Feb 06, 2018 8:19 am

Putting the question different:
- How is it possible to get vertex data along with the corresponding index for the vertex?

Regards
Lax
Lax
 
Posts: 46
Joined: Sat Jan 08, 2011 8:24 am

Re: ShowDebugPolygon callback no index data

Postby Julio Jerez » Tue Feb 06, 2018 10:32 am

you can not get indices for a collision shape directly, bu you can if you turn the collision shape into a NetwonMesh
Code: Select all
NewtonMesh* NewtonMeshCreateFromCollision(const NewtonCollision* const collision);

this this will provide all kind of queries for the mesh.

for usage example look at file: ...\applications\demosSandbox\sdkDemos\DemoMesh.cpp function
Code: Select all
DemoMesh::DemoMesh(const char* const name, const NewtonCollision* const collision, const char* const texture0, const char* const texture1, const char* const texture2, dFloat opacity)


for an example hwo to do it, this is what the newton demos use for convection any shape into a graphics objects.
Julio Jerez
Moderator
Moderator
 
Posts: 10168
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: ShowDebugPolygon callback no index data

Postby Lax » Thu Feb 08, 2018 5:59 pm

Hi,

thanks for the response. I analyized deeply and found out the following:
- Using NewtonMesh as you recommended does not work correctly. My example was a simple box. When I use NewtonMesh to get vertexArray etc. the vertex count was just 8 and the index count 24, which is not enough.
I created an Ogre::ManualObject out of that. The result was, the lots of lines were missing and even more worse, some positions were wrong.

So I got back to the callback function:
Code: Select all
static void _CDECL newtonPerPoly( void* userData, int vertexCount, const float* faceVertec, int id );

Which works correctly! I get a total vertex count of 36 (function called 6 times) and the faceVertec array has also correct positions, but the indices array is here missing. I thought, it is the last parameter (id). So I debugged newton and indeed, the parameter should be an indexArray, but maybe Its a bug, because this is the function for the callback in newton:
Code: Select all
dgIntersectStatus dgCollisionBVH::ShowDebugPolygon (void* const context, const dgFloat32* const polygon, dgInt32 strideInBytes, const dgInt32* const indexArray, dgInt32 indexCount, dgFloat32 hitDistance)
{
   dgTriplex triplex[128];
   dgInt32 stride = dgInt32 (strideInBytes / sizeof (dgFloat32));

   dgCollisionBVHShowPolyContext& data = *(dgCollisionBVHShowPolyContext*) context;
   for (dgInt32 i = 0; i < indexCount; i ++ ) {
      dgVector p (&polygon[indexArray[i] * stride]);
      p = data.m_matrix.TransformVector(p);
      triplex[i].m_x = p.m_x;
      triplex[i].m_y = p.m_y;
      triplex[i].m_z = p.m_z;
   }
   data.m_callback (data.m_userData, indexCount, &triplex[0].m_x, indexArray[-1]);

   return t_ContinueSearh;
}

So why is indexArray[-1] delivered to the callback?
Is it possible to fix that, so that the correct indexArray is delivered? Like "const dFloat* indexArray".

Because else, I see no chance to get debug collision lines working. I'm stuck on this topic for over a year now.

Any help is appreciated

Regards
Lax
Lax
 
Posts: 46
Joined: Sat Jan 08, 2011 8:24 am

Re: ShowDebugPolygon callback no index data

Postby Julio Jerez » Thu Feb 08, 2018 6:11 pm

is a vertex list index list
24 index if you device by 6 (number of faces) is 4 which are the indices of each face.

if you want the mesh in different mode, you can call function on the mesh and I will converted to almost any format you need. you can call Triangulate, and the it will give 36 indices which will be an triangle list in which if face share to vetrices.

the function I pointed to you work, because the demos use it very much the same way to say Ogre Uses manual mesh. this is what the SDK use to render shapes made for collision shapes.

I suggested you use that function because there is not way in newton to get indices for a collision shape, this is in fact a lot more efficient because it give you more efficient rendering shapes.

I look at the function, is this

Code: Select all
DemoMesh::DemoMesh(const char* const name, const NewtonCollision* const collision, const char* const texture0, const char* const texture1, const char* const texture2, dFloat opacity)
   :DemoMeshInterface()
   ,dList<DemoSubMesh>()
   ,m_uv(NULL)
   ,m_vertex(NULL)
   ,m_normal(NULL)
   ,m_optimizedOpaqueDiplayList(0)      
   ,m_optimizedTransparentDiplayList(0)
{
   // create a helper mesh from the collision collision
   NewtonMesh* const mesh = NewtonMeshCreateFromCollision(collision);

   // apply the vertex normals
   NewtonMeshCalculateVertexNormals(mesh, 30.0f * dDegreeToRad);

   // apply uv projections
   NewtonCollisionInfoRecord info;
   NewtonCollisionGetInfo (collision, &info);
   switch (info.m_collisionType)
   {
      case SERIALIZE_ID_SPHERE:
      {
         NewtonMeshApplySphericalMapping(mesh, LoadTexture (texture0));
         break;
      }

      case SERIALIZE_ID_CONE:
      case SERIALIZE_ID_CAPSULE:
      case SERIALIZE_ID_CYLINDER:
      case SERIALIZE_ID_CHAMFERCYLINDER:
      {
         //NewtonMeshApplySphericalMapping(mesh, LoadTexture(texture0));
         NewtonMeshApplyCylindricalMapping(mesh, LoadTexture(texture0), LoadTexture(texture1));
         break;
      }

      default:
      {
         int tex0 = LoadTexture(texture0);
         int tex1 = LoadTexture(texture1);
         int tex2 = LoadTexture(texture2);
         NewtonMeshApplyBoxMapping(mesh, tex0, tex1, tex2);
         break;
      }
   }

   // extract vertex data  from the newton mesh      
   int vertexCount = NewtonMeshGetPointCount (mesh);
   AllocVertexData(vertexCount);
   NewtonMeshGetVertexChannel(mesh, 3 * sizeof (dFloat), (dFloat*)m_vertex);
   NewtonMeshGetNormalChannel(mesh, 3 * sizeof (dFloat), (dFloat*)m_normal);
   NewtonMeshGetUV0Channel(mesh, 2 * sizeof (dFloat), (dFloat*)m_uv);

   // extract the materials index array for mesh
   void* const geometryHandle = NewtonMeshBeginHandle (mesh);
   for (int handle = NewtonMeshFirstMaterial (mesh, geometryHandle); handle != -1; handle = NewtonMeshNextMaterial (mesh, geometryHandle, handle)) {
      int material = NewtonMeshMaterialGetMaterial (mesh, geometryHandle, handle);
      int indexCount = NewtonMeshMaterialGetIndexCount (mesh, geometryHandle, handle);

      DemoSubMesh* const segment = AddSubMesh();

      segment->m_textureHandle = (GLuint)material;
      segment->SetOpacity(opacity);

      segment->AllocIndexData (indexCount);
      NewtonMeshMaterialGetIndexStream (mesh, geometryHandle, handle, (int*)segment->m_indexes);
   }
   NewtonMeshEndHandle (mesh, geometryHandle);

   // destroy helper mesh
   NewtonMeshDestroy(mesh);

   // optimize this mesh for hardware buffers if possible
   OptimizeForRender ();
}


notice that is use the function,
int vertexCount = NewtonMeshGetPointCount (mesh);
not get vertex count, believe that's the way to go when using newton.
Julio Jerez
Moderator
Moderator
 
Posts: 10168
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: ShowDebugPolygon callback no index data

Postby Lax » Tue Feb 13, 2018 12:59 pm

Hi,

I used the functions you suggested.
In my simple test scenario, I want to create a collision representation for a cube.
The vertexArray is as follows:
Code: Select all
vertexArray,24
      [0]   1.00000000   float
      [1]   0.000000000   float
      [2]   -1.00000000   float
      [3]   1.00000000   float
      [4]   0.000000000   float
      [5]   -1.00000000   float
      [6]   1.00000000   float
      [7]   0.000000000   float
      [8]   -1.00000000   float
      [9]   1.00000000   float
      [10]   0.000000000   float
      [11]   1.00000000   float
      [12]   1.00000000   float
      [13]   0.000000000   float
      [14]   1.00000000   float
      [15]   1.00000000   float
      [16]   0.000000000   float
      [17]   1.00000000   float
      [18]   -1.00000000   float
      [19]   0.000000000   float
      [20]   -1.00000000   float
      [21]   -1.00000000   float
      [22]   0.000000000   float
      [23]   -1.00000000   float

The index array:
Code: Select all
indexArray,36
      [0]   0   unsigned int
      [1]   4   unsigned int
      [2]   10   unsigned int
      [3]   0   unsigned int
      [4]   10   unsigned int
      [5]   6   unsigned int
      [6]   1   unsigned int
      [7]   8   unsigned int
      [8]   17   unsigned int
      [9]   1   unsigned int
      [10]   17   unsigned int
      [11]   18   unsigned int
      [12]   2   unsigned int
      [13]   20   unsigned int
      [14]   21   unsigned int
      [15]   2   unsigned int
      [16]   21   unsigned int
      [17]   3   unsigned int
      [18]   5   unsigned int
      [19]   22   unsigned int
      [20]   12   unsigned int
      [21]   5   unsigned int
      [22]   12   unsigned int
      [23]   9   unsigned int
      [24]   7   unsigned int
      [25]   11   unsigned int
      [26]   13   unsigned int
      [27]   7   unsigned int
      [28]   13   unsigned int
      [29]   15   unsigned int
      [30]   14   unsigned int
      [31]   23   unsigned int
      [32]   19   unsigned int
      [33]   14   unsigned int
      [34]   19   unsigned int
      [35]   16   unsigned int

I think the vertexArray and the indexArray is correct. In the past everything worked fine, because the ManualObject was different and there was no need to call manualObject->index[..]. But that has changed. What I tried:
Code: Select all
int vertexCount = NewtonMeshGetPointCount(mesh);
object->estimateVertexCount(vertexCount);
dFloat* vertexArray = new dFloat[3 * vertexCount];
memset(vertexArray, 0, 3 * vertexCount * sizeof(dFloat));

NewtonMeshGetVertexChannel(mesh, 3 * sizeof(dFloat), (dFloat*)vertexArray);

void* const geometryHandle = NewtonMeshBeginHandle(mesh);
for (int handle = NewtonMeshFirstMaterial(mesh, geometryHandle); handle != -1; handle = NewtonMeshNextMaterial(mesh, geometryHandle, handle))
{
   int material = NewtonMeshMaterialGetMaterial(mesh, geometryHandle, handle);
   int indexCount = NewtonMeshMaterialGetIndexCount(mesh, geometryHandle, handle);
   object->estimateIndexCount(indexCount);
   unsigned int* indexArray = new unsigned[indexCount];

   NewtonMeshMaterialGetIndexStream(mesh, geometryHandle, handle, (int*)indexArray);

   object->begin("BlueNoLightning", Ogre::OperationType::OT_LINE_LIST);
   for (int vert = 0; vert < vertCount ; vert++)
   {
      object->position(vertexArray[(vert * 3) + 0], vertexArray[(vert * 3) + 1], vertexArray[(vert * 3) + 2]);
   }
   for (int index= 0; index < indexCount ; index++)
   {
      object->index(indexArray[index]);
   }
}
object->end();

The result looks like:
Image

I tried thousands of variations, but without success.

Regards and Thanks in advance
Lax
Lax
 
Posts: 46
Joined: Sat Jan 08, 2011 8:24 am

Re: ShowDebugPolygon callback no index data

Postby Julio Jerez » Tue Feb 13, 2018 2:33 pm

Can you post the complete function you wrote?
Julio Jerez
Moderator
Moderator
 
Posts: 10168
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: ShowDebugPolygon callback no index data

Postby JernejL » Wed Feb 14, 2018 10:44 am

Maybe this helps.. i use NewtonCollisionForEachPolygonDo and can assure it works correctly, so to follow on your issues: NewtonCollisionForEachPolygonDo will not always give you triangles or quads, shapes can be sent to you with any amout of vertices.

To display that data - while the newtonmesh method will probably work, it would make more use for you to create internally in ogre - a debug shape, make your own indexes as you receive vertexes & shapes, and then render shapes you get at once when newton iteration of NewtonCollisionForEachPolygonDo finishes.
Help improving the Newton Game Dynamics WIKI
User avatar
JernejL
 
Posts: 1364
Joined: Mon Dec 06, 2004 2:00 pm
Location: Slovenia

Re: ShowDebugPolygon callback no index data

Postby Lax » Fri Feb 16, 2018 9:52 am

Maybe this helps.. i use NewtonCollisionForEachPolygonDo and can assure it works correctly

I have used this function for a long time, but since Newton3 and Ogre2.1 I'm having this issue.

What I totally forgot is the function:
Code: Select all
NewtonMeshTriangulate(mesh);

Now I get an vertex array of 72 elements, which seems correct. But still I'm unable to create the collision debug shape properly. What I'm missing. Code:
Code: Select all
      void* const geometryHandle = NewtonMeshBeginHandle(mesh);
      for (int handle = NewtonMeshFirstMaterial(mesh, geometryHandle); handle != -1; handle = NewtonMeshNextMaterial(mesh, geometryHandle, handle))
      {
         int material = NewtonMeshMaterialGetMaterial(mesh, geometryHandle, handle);
         int indexCount = NewtonMeshMaterialGetIndexCount(mesh, geometryHandle, handle);
         object->estimateIndexCount(indexCount);
         unsigned int* indexArray = new unsigned[indexCount];

         NewtonMeshMaterialGetIndexStream(mesh, geometryHandle, handle, (int*)indexArray);

         object->getUserObjectBindings().setUserAny(Ogre::Any(indexArray));

         float matrix[16];
         Converters::QuatPosToMatrix(Ogre::Quaternion::IDENTITY, Ogre::Vector3::ZERO, &matrix[0]);
         NewtonCollisionForEachPolygonDo(body->getNewtonCollision(), &matrix[0], newtonPerPoly, object);
...
...
void _CDECL Debugger::newtonPerPoly(void* userData, int vertexCount, const dFloat* faceVertec, int id)
{
   static int j = 0;
   Ogre::ManualObject* lines = (Ogre::ManualObject*)userData;
   unsigned int* indices = Ogre::any_cast<unsigned int*>((lines)->getUserObjectBindings().getUserAny());

   Ogre::Vector3 p0, p1;

   if (vertexCount < 2)
      return;

   int i = vertexCount - 1;
   p0 = Ogre::Vector3(faceVertec[(i * 3) + 0], faceVertec[(i * 3) + 1], faceVertec[(i * 3) + 2]);

   for (i = 0; i < vertexCount; i++)
   {
      p1 = Ogre::Vector3(faceVertec[(i * 3) + 0], faceVertec[(i * 3) + 1], faceVertec[(i * 3) + 2]);

      lines->position(p0);
      lines->position(p1);
      lines->line(indices[j++], indices[j++]);
      p0 = p1;
   }
}


The result does look a bit better now:
https://postimg.org/image/xrv2i7mg5/
But still there is geometry missing and the shape is on the wrong position. The red cube is my bounding box of the object I made invisible. It should be on the same position as the bounding box.
Lax
 
Posts: 46
Joined: Sat Jan 08, 2011 8:24 am

Re: ShowDebugPolygon callback no index data

Postby Julio Jerez » Fri Feb 16, 2018 11:26 am

Lax what JernejL is saying should also work. I mentioned the NewtonMesh because you were talking about making an index list vertex list mesh, and the collision callback do not provide indices

There is a simple demo tha show hwo to use NewtonMesh in the SDK demos.
../applications\demosSandbox\sdkDemos\demos\UsingNewtonMeshTool.cpp

funtion CreateSimpleNewtonMeshBox
the build a box form starch and converted to a newton mesh.
if that demo works the all you nee to do is find out where the you bug is.

look carefully at funtion call
DemoMesh* const visualMesh = new DemoMesh (newtonMesh);

tshi funtion build a mesh for rendering form the data that was use to make a box, if it work here it should also work in Ogre.
Julio Jerez
Moderator
Moderator
 
Posts: 10168
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles


Return to Bugs and Fixes

Who is online

Users browsing this forum: No registered users and 1 guest

cron