Using pivot point scaling / rotation on collision obj?

Post Reply
lebron
Posts: 3
Joined: Thu Apr 10, 2014 3:12 pm

Using pivot point scaling / rotation on collision obj?

Post by lebron »

I can rotate and scale my meshes around any point like you can do in a 3d editor such as maya when you press "D" and move the pivot point.

However, I cant do the same with the attached Bullet btBoxShape collision mesh. For example if I have my pivot point glm::vec3 rsPivot at (1.f, 0.f, 0.f) and scale (obviously it doesnt work here). I've tried various things but either the scale or the rotation don't both work at the same time.

How can I use a pivot point for scaling and rotation with bullet collision object (and preferably keep the GLM workflow I have ) ?

Image

Code: Select all

void Object::render(glm::mat4 PV)
{
	scaleM = glm::scale(glm::mat4(), s->val_3);
	rotationM = glm::toMat4(r_quat);
	translationM = glm::translate(glm::mat4(), t->val_3);
	transLocal1M = glm::translate(glm::mat4(), -rsPivot->val_3);
	transLocal2M = glm::translate(glm::mat4(), rsPivot->val_3);
	MVP = PV * translationM * transLocal2M * rotationM * scaleM * transLocal1M;
}

void Object::autoBB() //called during a mesh update IE: changing scaleX value from gui
{
	bbMin = bbMax = glm::vec3(0.f);
	vector<glm::vec3> bbCheck;

	if (type->val_s == "triDebug")
		bbCheck = meshV;

	for (int i = 0; i < bbCheck.size(); ++i)
	{
		if (bbCheck[i].x < bbMin.x)
			bbMin.x = bbCheck[i].x;
		if (bbCheck[i].y < bbMin.y)
			bbMin.y = bbCheck[i].y;
		if (bbCheck[i].z < bbMin.z)
			bbMin.z = bbCheck[i].z;

		if (bbCheck[i].x > bbMax.x)
			bbMax.x = bbCheck[i].x;
		if (bbCheck[i].y > bbMax.y)
			bbMax.y = bbCheck[i].y;
		if (bbCheck[i].z > bbMax.z)
			bbMax.z = bbCheck[i].z;
	}

	bbCenter = .5f * (bbMin + bbMax);
	bbSize = .5f * (bbMax - bbMin);

	bbScaleM = glm::scale(glm::mat4(), s->val_3 * bbSize);
	r_quat = glm::quat(glm::radians(r->val_3));
	bbRotationM = glm::toMat4(r_quat);
	bbTranslationM = glm::translate(glm::mat4(), t->val_3 + bbCenter);

	bbMVP = bbTranslationM * bbRotationM * bbScaleM;
	bbXform = mat4ToBullet(bbMVP); //btTransform !!!

	for (int i = 0; i < myWin.myEtc->bulletDynW->getNumCollisionObjects(); ++i)
	{
		QString *bulletPtrName = static_cast<QString*>(myWin.myEtc->bulletDynW->getCollisionObjectArray()[i]->getUserPointer());

		if (name->val_s == bulletPtrName)
			myWin.myEtc->bulletDynW->getCollisionObjectArray()[i]->setWorldTransform(bbXform);
	}
}

btTransform Object::mat4ToBullet(glm::mat4 transform)
{
	const float* data = glm::value_ptr(transform);
	btTransform bulletTransform;
	bulletTransform.setFromOpenGLMatrix(data);

	return bulletTransform;
}

nikomaster
Posts: 13
Joined: Fri May 16, 2014 9:55 am

Re: Using pivot point scaling / rotation on collision obj?

Post by nikomaster »

As I understand you want to rotate and scale synch graphics and bullet right?


I think scaling is not possible this way. You may use btCollisionShape->setLocalScaling to scale the rigidbody shape. And then apply the transform. It works for me. If you are sending the opengl matrix directly then rotation would not be an issue.
lebron
Posts: 3
Joined: Thu Apr 10, 2014 3:12 pm

Re: Using pivot point scaling / rotation on collision obj?

Post by lebron »

nikomaster wrote:As I understand you want to rotate and scale synch graphics and bullet right?


I think scaling is not possible this way. You may use btCollisionShape->setLocalScaling to scale the rigidbody shape. And then apply the transform. It works for me. If you are sending the opengl matrix directly then rotation would not be an issue.
My BB just disappears if I set the local scaling like this or is visible but doesnt respect the size of the points of the object if I do it the second way. Thus it would be just a cube since I dont multiply by BBsize.

Do you have a working code example that shows how I can do pivot point scaling and rotation?

Code: Select all

btVector3 myScale(s->val_3.x * bbSize.x, s->val_3.y * bbSize.y, s->val_3.z * bbSize.z);
boxCollisionShape->setLocalScaling(myScale);

Code: Select all

btVector3 myScale(s->val_3.x, s->val_3.y, s->val_3.z);
boxCollisionShape->setLocalScaling(myScale);
nikomaster
Posts: 13
Joined: Fri May 16, 2014 9:55 am

Re: Using pivot point scaling / rotation on collision obj?

Post by nikomaster »

Objects on bullet rotate around their center of mass which usually is the center of the bounding box. If you want to move that pivot you need to shift the center of mass of the rigidbody and synch it with the graphics engine check this thread explaining this:

http://www.bulletphysics.org/Bullet/php ... f=9&t=2828
lebron
Posts: 3
Joined: Thu Apr 10, 2014 3:12 pm

Re: Using pivot point scaling / rotation on collision obj?

Post by lebron »

nikomaster wrote:Objects on bullet rotate around their center of mass which usually is the center of the bounding box. If you want to move that pivot you need to shift the center of mass of the rigidbody and synch it with the graphics engine check
Thanks so much for the help so far. Im setting up the compound shape but Im not sure how to do this center of mass shift on the rigid body that you mentioned. I read that thread but am still getting incorrect results when I set it up like this.

I'm trying to set the pivot point on the controlling compound or the child to be at (1,0,0) but the behavior i get is inverted or doesnt match up.

Code: Select all

    boxCollisionShape = new btBoxShape(btVector3(1.f, 1.f, 1.f));

    bbCompound = new btCompoundShape();
//        bbXformLocal.setIdentity();
//        bbXformLocal.setOrigin(btVector3(.5f, 0.f, 0.f)); //rsPivot->val_3

    bbXformLocal = mat4ToBullet(glm::translate(glm::mat4(), rsPivot->val_3)); //the (1, 0, 0) pivot

    bbCompound->addChildShape(bbXformLocal, boxCollisionShape);

    btDefaultMotionState* motionstate = new btDefaultMotionState(bbXform);
    btRigidBody::btRigidBodyConstructionInfo rigidBodyCI(0, motionstate, bbCompound, btVector3(0.f, 0.f, 0.f));

    rigidBody = new btRigidBody(rigidBodyCI);
    rigidBody->setUserPointer(&name->val_s);
//        rigidBody->setCenterOfMassTransform(bbXformLocal); //??

    myWin.myEtc->bulletDynW->addRigidBody(rigidBody);
Image
nikomaster
Posts: 13
Joined: Fri May 16, 2014 9:55 am

Re: Using pivot point scaling / rotation on collision obj?

Post by nikomaster »

The box would shifted at the position you specified , nevertheless the center of the compound would remaing at 0,0,0 so by rotating the compound the box would not rotate on its axis but around the axis of the compound which would be 0,0,0 but the box would be shifted.

I had a similar issue coordinating a cylinder with the cylinder shape, and the problem was, I was talking as the origin the base of the cylinder (on opengl) when bullet takes -half-lenght as minimum and half-length as maximum and in between the center so it was easier creating the mesh talking the center of the axis x,y,z(0,0,0) as the center of the mesh instead of the base of the cylinder as the center of mass of the mesh. You could probably have the same issue there.

Why not instead of setting the coords of the triangle on (0,0,0),(0.5,1,0),(1,0,0) better set them on (-0.5,-0.5,0),(0,0.5,0)(0.5,-0.5,0)
in this way the center of the triangle would be on 0,0,0 and you may match the center of mass of the box
Post Reply