# Bullet: Apply any Transformation to RigidBody?

I'm using Bullet for CollisionDetection. I load a scene from a Collada-File using Assimp. Let's say I want to give every object in the scene a RigidBody with a box as CollisionShape. Right now I first load the vertices of the object from the file into my Model-Object and then store the transformation matrix. After that I create the CollisionShape with the following code:

btVector3 rigidBodyPos;
btCollisionShape* collisionShape;

glm::vec3* minMax = getMinMaxVertexCoords();
glm::vec3 minCoords = minMax; //The minmum/maximum x/y/z values in the Mesh
glm::vec3 maxCoords = minMax;
glm::vec3 middleSize = glm::vec3((maxCoords.x - minCoords.x) / 2, (maxCoords.y - minCoords.y) / 2, (maxCoords.z - minCoords.z) / 2);
glm::vec3 middlePos = glm::vec3((maxCoords.x + minCoords.x) / 2, (maxCoords.y + minCoords.y) / 2, (maxCoords.z + minCoords.z) / 2);

collisionShape = new btBoxShape(btVector3(middleSize.x, middleSize.y, middleSize.z));
rigidBodyPos = btVector3(middlePos.x, middlePos.y, middlePos.z);


Here's a look at my getMinMaxVertexCoords():

glm::vec3* Model::getMinMaxVertexCoords() {
float maxValue = std::numeric_limits<float>::max();
float minValue = std::numeric_limits<float>::lowest();
glm::vec3 lowestVec = glm::vec3(maxValue, maxValue, maxValue);
glm::vec3 highestVec = glm::vec3(minValue, minValue, minValue);
for (Vertex v : getVertices()){
//Apply Transform
glm::vec4 pos = getModelMatrix() * glm::vec4(v.position, 1);
glm::vec3 homogenizedPos = glm::vec3(pos.x / pos.w, pos.y /     pos.w, pos.z / pos.w);
lowestVec.x = min(pos.x, lowestVec.x);
lowestVec.y = min(pos.y, lowestVec.y);
lowestVec.z = min(pos.z, lowestVec.z);
highestVec.x = max(pos.x, highestVec.x);
highestVec.y = max(pos.y, highestVec.y);
highestVec.z = max(pos.z, highestVec.z);
}
glm::vec3 res = { lowestVec, highestVec };
return res;
}


The problem doing it this way is, if my scene contains a rotated cube, the collisionbox is obviously not rotated, but parallel to the axes.

I tried solving this by applying the transformation matrix only after creating the RigidBody (so when creating the CollisionShape the ModelMatrix is the identity matrix) and then transforming the RigidBody afterwards:

btTransform transform;
transform.setFromOpenGLMatrix(glm::value_ptr(getModelMatrix()));
_rigidBody->setWorldTransform(transform);


The problem with this however is that the box might be rotated now, but if the transformation contains a Scaling - which is very likely - Bullet does not accept it, and my RigidBody basically disappears (no collision is detected anymore).

Does anybody know a solution to this problem?

I solved the problem myself!

I now create the CollisionShape before applying the transformation. For transforming the RigidBody correctly, I extract the sacling-value from the matrix and give it to _rigidBody->getCollisionShape()->setLocalScaling. I then remove the scaling from the matrix and give that to the setWorldTransform.

Here's my code:

float scaleX = glm::length(glm::vec3(modelMat, modelMat, modelMat));
float scaleY = glm::length(glm::vec3(modelMat, modelMat, modelMat));
float scaleZ = glm::length(glm::vec3(modelMat, modelMat, modelMat));
glm::mat4 matWithoutScale = glm::scale(modelMat, glm::vec3(1.0f / scaleX, 1.0f / scaleY, 1.0f / scaleZ));

_rigidBody->getCollisionShape()->setLocalScaling(btVector3(scaleX, scaleY, scaleZ));
btTransform transform;
transform.setFromOpenGLMatrix(glm::value_ptr(matWithoutScale));
_rigidBody->setWorldTransform(transform);