I want to specify a slider constraint that allows the body to slide between point A and point B. To specify the constraint, I assign two bodies to restrict, in this case, one dynamic body limited by the static world, think of a sliding door. The third and fourth parameters are transformations, reference frame A and reference frame B. To create and manage transformations, the library supports quaternions, matrices, and Euler angles.
The default slider constraint slides along the body along the x axis. My question is:
How do I set up two transformations so that Body B slides along the axis defined by its own origin and an extra point in space?
I naively tried:
frameA.setOrigin(origin_of_point);
frameA.setRotation(Quaternion(directionToB, 0 rotation));
frameB.setOrigin(0,0,0);
frameB.setRotation(Quaternion(directionToPoint,0))
However, quaternions do not seem to work as I expected. My mathematical knowledge about them is not very good, therefore, if someone can fill me with why this does not work, I would be grateful. It happens that the body slides along an axis orthogonal to the direction. When I change the rotational part in the Quaternion constructor, the body rotates around this sliding direction.
Edit:
The foundation is bullet physics. These two transformations are how the slider joint is attached to each body relative to the local coordinate system of the body.
Edit2
I could also set the rotational parts of the transforms through an orthogonal basis, but then I would have to reliably build an orthogonal basis from one vector. I was hoping the quaternions would prevent this.
Edit3
:
btTransform trafoA, trafoB;
trafoA.setIdentity();
trafoB.setIdentity();
vec3 bodyorigin(entA->getTrafo().col_t);
vec3 thisorigin(trafo.col_t);
vec3 dir=bodyorigin-thisorigin;
dir.Normalize();
mat4x4 dg=dgGrammSchmidt(dir);
mat4x4 dg2=dgGrammSchmidt(-dir);
btMatrix3x3 m(
dg.col_x.x, dg.col_y.x, dg.col_z.x,
dg.col_x.y, dg.col_y.y, dg.col_z.y,
dg.col_x.z, dg.col_y.z, dg.col_z.z);
btMatrix3x3 m2(
dg2.col_x.x, dg2.col_y.x, dg2.col_z.x,
dg2.col_x.y, dg2.col_y.y, dg2.col_z.y,
dg2.col_x.z, dg2.col_y.z, dg2.col_z.z);
trafoA.setBasis(m);
trafoB.setBasis(m2);
trafoA.setOrigin(btVector3(trafo.col_t.x,trafo.col_t.y,trafo.col_t.z));
btSliderConstraint* sc=new btSliderConstraint(*game.worldBody, *entA->getBody(), trafoA, trafoB, true);
, GramSchmidt trafoB, .
.
Edit4
, , , :
btTransform rbat = rba->getCenterOfMassTransform();
btVector3 up(rbat.getBasis()[0][0], rbat.getBasis()[1][0], rbat.getBasis()[2][0]);
btVector3 direction = (rbb->getWorldTransform().getOrigin() - btVector3(trafo.col_t.x, trafo.col_t.y, trafo.col_t.z)).normalize();
btScalar angle = acos(up.dot(direction));
btVector3 axis = up.cross(direction);
trafoA.setRotation(btQuaternion(axis, angle));
trafoB.setRotation(btQuaternion(axis, angle));
trafoA.setOrigin(btVector3(trafo.col_t.x,trafo.col_t.y,trafo.col_t.z));