Protobuf RepeatedField and btConvexHullShape

Spankenstein
Posts: 5
Joined: Sat Sep 22, 2012 11:45 pm

Protobuf RepeatedField and btConvexHullShape

Post by Spankenstein »

I'm using Protocol Buffers to save and load my settings from a binary file.

The vertices for my mesh are stored as an array of floats or what ProtoBuf refers to as RepeatedField<float>.

Normally I have no need to cast between float and btScalar but when attempting to use the RepeatedField (array of floats) I will get access violation errors.

Code: Select all

btCollisionShape* shape = new btConvexHullShape(settings.vertices().begin(), settings.vertices().size()); 
I can normally pass an array of floats in as the first argument but it will cause problems in this case. What am I doing wrong?
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA

Re: Protobuf RepeatedField and btConvexHullShape

Post by Erwin Coumans »

btConvexHullShape takes an optional third argument for the striding (size) of each vertex, which is sizeof(btVector3) by default, 16 bytes.

Is the size of your vertex also 16 bytes?

Secondly, the latest trunk of Bullet assumes the vertices to be 16-bytes aligned, so it can perform some SIMD optimizations. If you are using a 2.80 release this shouldn't apply to you.
Thanks,
Erwin
Spankenstein
Posts: 5
Joined: Sat Sep 22, 2012 11:45 pm

Re: Protobuf RepeatedField and btConvexHullShape

Post by Spankenstein »

Is the size of your vertex also 16 bytes?
Each vertex x, y, z coordinate is packed into a separate float element.

[0] [1] [2] = Vertex1
[3] [4] [5] = Vertex2, etc.

I will get an access violation error if I use anything greater than sizeof(float).

Code: Select all

btCollisionShape* shape = new btConvexHullShape(settings.vertices().data(), settings.vertices().size(), sizeof(float));
I presume I am therefore going to have to iterate through the array and create a new array of btVector3 from the elements?

Code: Select all

	int numElements = settings.vertices().size();

	btAlignedObjectArray<btVector3> vertices;
	//std::vector<btVector3> vertices;
	vertices.reserve(numElements / 3);

	for (int i = 0; i < numElements; i += 3)
	{
		vertices.push_back(btVector3(settings.vertices().Get(i), settings.vertices().Get(i + 1), settings.vertices().Get(i + 2)));
	}
In order to see if that has worked I am attempting to draw the convex hull as a wireframe. Unfortunately after trying to get the underlying btConvexPolyhedron I run into bad pointer (with *cp not *convexHullShape) problems which indicates something is incorrect.

Code: Select all

	const btConvexHullShape* convexHullShape = static_cast<const btConvexHullShape*>(m_body->getCollisionShape());
	const btConvexPolyhedron *cp = convexHullShape->getConvexPolyhedron();
I am stuck as to what that could be though.

EDIT:

The min max points for the AABB are also (0, 0, 0) showing that shape is not created correctly:

Code: Select all

	btTransform trans = m_body->getWorldTransform();
	btVector3	min;
	btVector3	max;
	convexHullShape->getAabb(trans, min, max);

	const btVector3 &pos = trans.getOrigin();
	const btVector3 &e = max - pos;
	const btMatrix3x3 &m = m_body->getWorldTransform().getBasis();
EDIT2:

I have tried adding each point explicitly, it's not ideal but I can get a valid AABB with this approach

Code: Select all

	btConvexHullShape *shape = new btConvexHullShape();
	
	for (int i = 0; i < numElements; i += 3)
	{
		shape->addPoint(btVector3(settings.vertices().Get(i), settings.vertices().Get(i + 1), settings.vertices().Get(i + 2)));
	}
The btConvexPolyhedron pointer is still not valid though.
Spankenstein
Posts: 5
Joined: Sat Sep 22, 2012 11:45 pm

Re: Protobuf RepeatedField and btConvexHullShape

Post by Spankenstein »

Creating a simple cube and add those points explicitly will not result in a valid btConvexPolyhedron pointer after the body has been created and added to the physics space.

Code: Select all

	btConvexHullShape *shape = new btConvexHullShape();

	btVector3 c(0,0,0);
	btVector3 hX(1,0,0);
	btVector3 hY(0,1,0);
	btVector3 hZ(0,0,1);

	shape->addPoint(c - hX + hY + hZ);
	shape->addPoint(c + hX + hY + hZ);
	shape->addPoint(c + hX - hY + hZ);
	shape->addPoint(c - hX - hY + hZ);
	shape->addPoint(c - hX + hY - hZ);
	shape->addPoint(c + hX + hY - hZ);
	shape->addPoint(c + hX - hY - hZ);
	shape->addPoint(c - hX - hY - hZ);
Also, it appears that btBvhTriangleMeshShape is better than btConvexHullShape for static levels such as .BSP files. Why does the BSP demo use btConvexHullShape? Does it assume that an external binary space partitioning scheme will be used with the mesh?

[EDIT]

The official BspDemo code doesn't produce a valid pointer either

Code: Select all

		virtual void	addConvexVerticesCollider(btAlignedObjectArray<btVector3>& vertices, bool isEntity, const btVector3& entityTargetLocation)
		{
			///perhaps we can do something special with entities (isEntity)
			///like adding a collision Triggering (as example)
			
			if (vertices.size() > 0)
			{
				float mass = 0.f;
				btTransform startTransform;
				//can use a shift
				startTransform.setIdentity();
				startTransform.setOrigin(btVector3(0,0,-10.f));
				//this create an internal copy of the vertices
				
				float a = vertices[0].getX();

				btCollisionShape* shape = new btConvexHullShape(&(vertices[0].getX()),vertices.size());
				m_demoApp->m_collisionShapes.push_back(shape);

				btRigidBody* body = m_demoApp->localCreateRigidBody(mass, startTransform,shape);
				//m_demoApp->localCreateRigidBody(mass, startTransform,shape);

				const btConvexHullShape* convexHullShape = static_cast<const btConvexHullShape*>(body->getCollisionShape());
				const btConvexPolyhedron *poly = convexHullShape->getConvexPolyhedron();

				int t = poly->m_vertices.size();
			}
		}
How can I draw the wireframe of the underlying polygonal mesh?
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA

Re: Protobuf RepeatedField and btConvexHullShape

Post by Erwin Coumans »

The BspDemo and all of the demos using btConvexHullShape work just fine here on all platforms.
(such as Demos/VoronoiFractureDemo, Demos/ConvexDecompositionDemo etc)

Do the unmodified Bullet demos fail for you? Which compiler/platform are you using?
Thanks,
Erwin
Spankenstein
Posts: 5
Joined: Sat Sep 22, 2012 11:45 pm

Re: Protobuf RepeatedField and btConvexHullShape

Post by Spankenstein »

Do the unmodified Bullet demos fail for you?
They do not fail in the sense that they will all build and execute with no major errors. The btConvexPolyhedron pointer is always invalid though, even when unmodified.
Which compiler/platform are you using?
Compiler: VS2010
Active Solution Platform: Win32
OS: Windows 7 x64
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA

Re: Protobuf RepeatedField and btConvexHullShape

Post by Erwin Coumans »

Ignore the btConvexPolyhedron pointer, it is currently not used by default.

When you call convexShape->initializePolyhedralFeatures, it will initialize that btConvexPolyhedron pointer, but the collision detection will not work properly.
I'm working on that, but right now it is experimental work that is not working properly yet.
Spankenstein
Posts: 5
Joined: Sat Sep 22, 2012 11:45 pm

Re: Protobuf RepeatedField and btConvexHullShape

Post by Spankenstein »

Ignore the btConvexPolyhedron pointer, it is currently not used by default.
I'm happy to use a different approach but the problem still remains.

I would like to draw a wireframe triangle mesh that shows the underlying collision shapes (triangles).

btConvexHullShape

I can get its vertices but not the indices (no getIndex)

Code: Select all

convexHullShape->getVertex()
btBvhTriangleMeshShape approach

I'm also trying to get similar information from btStridingMeshInterface but with no luck.