LargeMesh issue

sandeep_slash
Posts: 48
Joined: Thu Jul 10, 2008 6:36 pm

LargeMesh issue

Post by sandeep_slash »

I've a level with TriangleCount ~ 350,000 and I'm trying to use BvhTriangleMeshShape for this. But it crashes.... herez my callstack:

Code: Select all

btAlignedObjectArray<btOptimizedBvhNode>::copy(int start=0, int end=131072, btOptimizedBvhNode * dest=0x00000000) 
btAlignedObjectArray<btOptimizedBvhNode>::reserve(int _Count=262144) 
btAlignedObjectArray<btOptimizedBvhNode>::push_back(const btOptimizedBvhNode & _Val={...})
btOptimizedBvh::build'::`2'::NodeTriangleCallback::internalProcessTriangleIndex(btVector3 * triangle=0x7004ed20, int partId=0, int triangleIndex=131072)
btStridingMeshInterface::InternalProcessAllTriangles(btInternalTriangleIndexCallback * callback=0x7004ee68, const btVector3 & aabbMin={...}, const btVector3 & aabbMax={...})
btOptimizedBvh::build(btStridingMeshInterface * triangles=0x400f7e50, bool useQuantizedAabbCompression=false, const btVector3 & bvhAabbMin={...}, const btVector3 & bvhAabbMax={...})
btBvhTriangleMeshShape::btBvhTriangleMeshShape(btStridingMeshInterface * meshInterface=0x400f7e50, bool useQuantizedAabbCompression=false, bool buildBvh=true)
I think it fails to allocate memory in btAlignedObjectArray::reserve() function...

What might be the problem?

Thanks,
Sandeep.
sparkprime
Posts: 508
Joined: Fri May 30, 2008 2:51 am
Location: Ossining, New York

Re: LargeMesh issue

Post by sparkprime »

That's a hell of a lot of triangles. I have never done anything that large, but I can offer a few ideas. Have you tried it with fewer triangles? Is the system generally low on memory? What kind of system are you running on? Bullet has a lot of compile time options for allocation depending on the system.

I think the struct in question is 16 bytes and you're asking for 262144 of them, which would be exactly 4 megabytes. Is this more than the malloc implementation can malloc?

It's quite likely it is this function that is ultimately being used:

Code: Select all

static inline void *btAlignedAllocDefault(size_t size, int alignment)
{
  void *ret;
  char *real;
  unsigned long offset;

  real = (char *)malloc(size + sizeof(void *) + (alignment-1));
  if (real) {
    offset = (alignment - (unsigned long)(real + sizeof(void *))) & (alignment-1);
    ret = (void *)((real + sizeof(void *)) + offset);
    *((void **)(ret)-1) = (void *)(real);
  } else {
    ret = (void *)(real);
  }
  return (ret);
}
And as you can see, it may well return NULL, and then the vector would try coping into the NULL, hence the crash.

I think you have probably found a bug since the NULL should always be checked.
sandeep_slash
Posts: 48
Joined: Thu Jul 10, 2008 6:36 pm

Re: LargeMesh issue

Post by sandeep_slash »

It works fine with fewer triangles, but most of the levels that I'm working on are quite big....

I'm running it on the X360 platform.
sparkprime
Posts: 508
Joined: Fri May 30, 2008 2:51 am
Location: Ossining, New York

Re: LargeMesh issue

Post by sparkprime »

One option is obviously to partition the level a bit. Ther e would be more broadphase overhead but I don't see any other problems.
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA

Re: LargeMesh issue

Post by Erwin Coumans »

Bullet has been used with triangle meshes of over a million triangles in a single btBvhTriangleMeshShape, so that should not be a problem.
btAlignedObjectArray<btOptimizedBvhNode>::push_back(const btOptimizedBvhNode & _Val={...})
btOptimizedBvh::build'::`2'::NodeTriangleCallback::internalProcessTriangleIndex(btVector3 * triangle=0x7004ed20, int partId=0, int triangleIndex=131072)
btStridingMeshInterface::InternalProcessAllTriangles(btInternalTriangleIndexCallback * callback=0x7004ee68, const btVector3 & aabbMin={...}, const btVector3 & aabbMax={...})
btOptimizedBvh::build(btStridingMeshInterface * triangles=0x400f7e50, bool useQuantizedAabbCompression=false, const btVector3 & bvhAabbMin={...}, const btVector3 & bvhAabbMax={...})
btBvhTriangleMeshShape::btBvhTriangleMeshShape(btStridingMeshInterface * meshInterface=0x400f7e50, bool useQuantizedAabbCompression=false, bool buildBvh=true)
It is better to use "useQuantizedAabbCompression=true", because it makes the tree data structure 4 times smaller: sizeof(btOptimizedBvhNode)=64 and sizeof(btQuantizedBvhNode) = 16 bytes. Note that the number of AABB tree nodes is twice the number of triangles.

Instead of creating the tree on the XBox 360 console, it is better to deserialize it directly from disk to memory. See btOptimizedBvh::deSerializeInPlace in Demos/ConcaveDemo/ConcavePhysicsDemo.cpp
Thanks,
Erwin