xexuxjy / bullet-xna

Automatically exported from code.google.com/p/bullet-xna
Other
21 stars 5 forks source link

Some triangles on BvhTriMesh are inverted #15

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Pretty consistently some triangles in BvhTriangleMeshShapes using IndexedMesh 
and TriangleIndexVertexArray are inverted and the normals are facing the wrong 
way.

  So..   we have an oval ellipsoid..   supposed to be like

     /\
     ||
  __________
/           \
|-\       /-|
|  ------   |
\___________/
     ||
     \/

but in bullet-xna, it ends up like:

      ||
      \/
  _||||||||_
/           \
|-\       /-|
|  -||||-   |
\__|||||||_/
      /\
      ||

and often results in Bodies getting stuck inside bvhTriangleShape collision 
objects.

Not all of the triangles are inverted, but about half of them are.  The 
triangles that are inverted are opposite each other on the shape.

           |
 (inverted)|
           |
     --------------
           |
           |  (inverted)
           |

I tested the exact code against the native bullet library and it gave me a 
proper collision shape..   so there seems to be a bug in the triangle 
orientation or normal direction.  

-------------------------------------
C# Code

internal static object CreateMeshShape2(object pWorld, int pIndicesCount, int[] 
indices, int pVerticesCount, float[] verticesAsFloats)
{
    ObjectArray<int> indicesarr = new ObjectArray<int>(indices);
    ObjectArray<float> vertices = new ObjectArray<float>(verticesAsFloats);
    var world = pWorld as DiscreteDynamicsWorld;
    IndexedMesh mesh = new IndexedMesh();
    mesh.m_indexType = PHY_ScalarType.PHY_INTEGER;
    mesh.m_numTriangles = pIndicesCount/3;
    mesh.m_numVertices = pVerticesCount;
    mesh.m_triangleIndexBase = indicesarr;
    mesh.m_vertexBase = vertices;
    mesh.m_vertexStride = 3;
    mesh.m_vertexType = PHY_ScalarType.PHY_FLOAT;
    mesh.m_triangleIndexStride = 3;

    TriangleIndexVertexArray tribuilder = new TriangleIndexVertexArray();
    tribuilder.AddIndexedMesh(mesh, PHY_ScalarType.PHY_INTEGER);
    BvhTriangleMeshShape meshShape = new BvhTriangleMeshShape(tribuilder, true,true);
    meshShape.SetMargin(world.WorldSettings.Params.collisionMargin);
    return meshShape;
}

C++ code (native lib)
// =====================================================================
// Mesh, hull, shape and body creation helper routines
EXTERN_C DLL_EXPORT btCollisionShape* CreateMeshShape2(Sim* sim, 
                        int indicesCount, int* indices, int verticesCount, float* vertices )
{
    btCollisionShape* shape = sim->CreateMeshShape2(indicesCount, indices, verticesCount, vertices);
    bsDebug_RememberCollisionShape(shape);
    return shape;
}

// If using Bullet' convex hull code, refer to following link for parameter 
setting
// http://kmamou.blogspot.com/2011/11/hacd-parameters.html
// Another useful reference for ConvexDecomp
// http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=7159

btCollisionShape* Sim::CreateMeshShape2(int indicesCount, int* indices, int 
verticesCount, float* vertices )
{
    //We must copy the indices and vertices since the passed memory is released when this call returns.
    btIndexedMesh indexedMesh;
    int* copiedIndices = new int[indicesCount];
    bsMemcpy(copiedIndices, indices, indicesCount * sizeof(int));
    int numVertices = verticesCount * 3;
    float* copiedVertices = new float[numVertices];
    bsMemcpy(copiedVertices, vertices, numVertices * sizeof(float));
    indexedMesh.m_indexType = PHY_INTEGER;
    indexedMesh.m_triangleIndexBase = (const unsigned char*)copiedIndices;
    indexedMesh.m_triangleIndexStride = sizeof(int) * 3;
    indexedMesh.m_numTriangles = indicesCount / 3;
    indexedMesh.m_vertexType = PHY_FLOAT;
    indexedMesh.m_numVertices = verticesCount;
    indexedMesh.m_vertexBase = (const unsigned char*)copiedVertices;
    indexedMesh.m_vertexStride = sizeof(float) * 3;
    btTriangleIndexVertexArray* vertexArray = new btTriangleIndexVertexArray();
    vertexArray->addIndexedMesh(indexedMesh, PHY_INTEGER);
    btBvhTriangleMeshShape* meshShape = new btBvhTriangleMeshShape(vertexArray, true, true);
    meshShape->setMargin(m_worldData.params->collisionMargin);
    return meshShape;
}

Original issue reported on code.google.com by tera...@gmail.com on 14 Dec 2012 at 10:03

GoogleCodeExporter commented 9 years ago
Example:   http://www.youtube.com/watch?v=YiJt5vi0Xho

Original comment by tera...@gmail.com on 14 Dec 2012 at 10:46

GoogleCodeExporter commented 9 years ago
Thanks. I'll look into this.

Original comment by xexu...@gmail.com on 17 Dec 2012 at 8:49

GoogleCodeExporter commented 9 years ago
Can I just confirm that this is against the latest head revision of code, 
rather than the prebuilt version from Downloads? Thanks.

Original comment by xexu...@gmail.com on 17 Dec 2012 at 10:22

GoogleCodeExporter commented 9 years ago
This is against revision 173 add a missing condition in penetration depth 
solver..   fixes some convex shapes passing through each other.

(just a note, the convex hulls are working OK, if I convert it to a convex 
hull, it collides OK)

Original comment by tera...@gmail.com on 18 Dec 2012 at 2:34

GoogleCodeExporter commented 9 years ago
I've had a look and can't see anything obviously wrong based on a comparison of 
the code. I did notice that the xna shape drawer seemed to have issues with 
drawing triangle meshes like that, but I think thats just a graphical issue.
Do you have have your model vertex/index data as a file that you could attach 
so that I can build a testcase for it?

Thanks.

Original comment by xexu...@gmail.com on 18 Dec 2012 at 10:16

GoogleCodeExporter commented 9 years ago
Indices and Vertices passed.

Original comment by tera...@gmail.com on 19 Dec 2012 at 4:18

Attachments:

GoogleCodeExporter commented 9 years ago
Also..  I'm seeing quite a bit of this: 
unconservative Y, diffY = 5.960464E-08, oldY=-0.9389408,newY=-0.9389408

unconservative Y, diffY = 9.536743E-07, oldY=14.33049,newY=14.33049

unconservative X, diffX = 7.152557E-07, oldX=2.816294,newX=2.816293

unconservative Y, diffY = 9.536743E-07, oldY=14.33245,newY=14.33245

Original comment by tera...@gmail.com on 19 Dec 2012 at 4:19

GoogleCodeExporter commented 9 years ago
Thanks,

I've created a demo project : BvhBugDemo that has your shape in it.
it has 2 options, creating the shape from a list of floats (your example) and 
also from a list of IndexedVector3 (just to test)
As far as I can see the shape displays normally, both in solid and wireframe 
mode (and the normals are correct in wire frame).
I also tried it with a standard TriangleMesh rather than the Bvh version, and 
this did show up an issue with list of floats (list of vector3s worked) . 

Could you have a look at the demo (and the other minor checkins) and see if it 
represents your bug and if you still see an error?

Those log outputs are a bit odd, but I think are reasonable outputs based on 
the quantization. I've disabled the debug output in QuantizedBvh by default 
now, so you shouldn't get those lines.

Thanks

Original comment by xexu...@gmail.com on 19 Dec 2012 at 9:32

GoogleCodeExporter commented 9 years ago
When trying the demo as is, it worked better then what I'm seeing in my 
application but it wasn't right as demonstrated: 
http://www.youtube.com/watch?v=dqwdDOse6WM

Original comment by tera...@gmail.com on 19 Dec 2012 at 10:16

GoogleCodeExporter commented 9 years ago
If I tweak the demo to use floats and bvhTriangleMesh, it exhibits what I'm 
seeing in my application.

Demo:
http://www.youtube.com/watch?v=v6fACDIhHZw

Original comment by tera...@gmail.com on 19 Dec 2012 at 10:21

GoogleCodeExporter commented 9 years ago
My Tweaked BvhBugDemo.

Original comment by tera...@gmail.com on 19 Dec 2012 at 10:23

Attachments:

GoogleCodeExporter commented 9 years ago
Thanks. I've been able to re-create the issue with thrown boxes sometimes going 
through or getting stuck in the shape, both as tri-mesh and bvh mesh. Will 
continue working on it.

Original comment by xexu...@gmail.com on 20 Dec 2012 at 9:12

GoogleCodeExporter commented 9 years ago
Ok, as bizarre as it sounds it looks like the issue is/was with the continuous 
collision detection (ccd) values for the shootbox in the demo.... I updated 
those to be the same as the C++ version and I stopped getting objects going 
through the main shape.
I also applied the c# values to the C++ demo and got the same behaviour with 
objects going through the main shape. 
I've checked in a slighly updated version of the base DemoApplication class 
with this fix. I've also fixed a couple of other  issues that I came across 
when I was investigating this. One of which was the incorrect buildling of the 
tri-mesh when just using floats (as opposed to vector3)

Can you give it a try when you get chance and let me know of any more problems.

Thanks.

Original comment by xexu...@gmail.com on 21 Dec 2012 at 4:07

GoogleCodeExporter commented 9 years ago
bizarre or not, it solved the issue.

Thanks.

http://www.youtube.com/watch?v=k37DZHKWksg

Original comment by tera...@gmail.com on 21 Dec 2012 at 8:16

GoogleCodeExporter commented 9 years ago

Original comment by xexu...@gmail.com on 21 Dec 2012 at 11:17