Wanted to ask here while I am trying to figure it out by myself... ))
I am rotating the camera around an object with a constraint applied on it, like when you would turn on yourself while holding an object which would then constantly present the same face to you. Only, despite the constraint, the object rotates as the camera rotates, see 2 pics here attached.
What is the best way to keep the object facing the camera  rotate object in the opposite direction, update basis of the constraint, both?
Thank you in advance for giving it a though!
[SOLVED] Rotate camera around constraint object...
[SOLVED] Rotate camera around constraint object...
 Attachments

 IMG_4524.PNG (881.27 KiB) Viewed 1111 times

 IMG_4523.PNG (910.9 KiB) Viewed 1111 times
Last edited by LastBlow on Thu Jun 21, 2018 8:46 am, edited 9 times in total.
 drleviathan
 Posts: 521
 Joined: Tue Sep 30, 2014 6:03 pm
 Location: San Francisco
Re: Rotate around constraint object...
As the object rotates you want to slave the camera to it such that the camera always looks at a particular face of the object?
Or do you want to slave the object to the camera such that whenever the camera moves the object rotates to present the same face?
If the first: don't use a constraint. Instead just compute the camera's transform as an offset from the object's transform.
If the second: you could use a constraint on the object, but it would be constrained to the world (as opposed to being constrained to another object, or the camera directly) and you would want to update the constraint's target transform whenever the camera moves. Another way to do it would be to make a custom Action that quickly spins the object toward its target transform.
Or do you want to slave the object to the camera such that whenever the camera moves the object rotates to present the same face?
If the first: don't use a constraint. Instead just compute the camera's transform as an offset from the object's transform.
If the second: you could use a constraint on the object, but it would be constrained to the world (as opposed to being constrained to another object, or the camera directly) and you would want to update the constraint's target transform whenever the camera moves. Another way to do it would be to make a custom Action that quickly spins the object toward its target transform.
Re: Rotate camera around constraint object...
Thank you for the reply! ))
Yes, there is a constraint applied to the object, so it can be carried around like it was held in a hand while walking and turning around.
Did add the line here below to account for the camera rotation. The object now faces the camera but jerks when grabbed because its initial rotation is overwritten at first by the camera rotation. Now looking into how to take into account the initial object rotation...
`
Yes, there is a constraint applied to the object, so it can be carried around like it was held in a hand while walking and turning around.
Did add the line here below to account for the camera rotation. The object now faces the camera but jerks when grabbed because its initial rotation is overwritten at first by the camera rotation. Now looking into how to take into account the initial object rotation...
Code: Select all
pickConstraint>getFrameOffsetA().setBasis(glm2bulletR(m_camera>getRotationMatrix()));
Last edited by LastBlow on Thu Jun 21, 2018 8:46 am, edited 3 times in total.
 drleviathan
 Posts: 521
 Joined: Tue Sep 30, 2014 6:03 pm
 Location: San Francisco
Re: Rotate around constraint object...
This is how I reason through such problems:
Define some notation:
Tbw = transform from body to World = body>getWorldTransForm();
Tcw = transform from camera to world = camera>getWorldTransform();
Tbc = transform from body to camera, which will be constant
At the moment the body is grabbed you want to compute the relative transform between it and the camera Tbc and save for later: this will be a constant.
The simplest way to think about it for both GLM and Bullet is: transforms always operate from the left on column vectors to the right. Therefore transform equation is:
Thereafter you want to compute the new Tbw for subsequent values of Twc:
Rotations are hard, but maybe that outline is helpful.
Define some notation:
Tbw = transform from body to World = body>getWorldTransForm();
Tcw = transform from camera to world = camera>getWorldTransform();
Tbc = transform from body to camera, which will be constant
At the moment the body is grabbed you want to compute the relative transform between it and the camera Tbc and save for later: this will be a constant.
The simplest way to think about it for both GLM and Bullet is: transforms always operate from the left on column vectors to the right. Therefore transform equation is:
Code: Select all
// Tbc = Twc * Tbw = Tcw^1 * Tbw
btTransform Tbc = camera>getWorldTransform().inverse() * body>getWorldTransform()
Code: Select all
//Tbw = Tcw * Tbc
btTransform newTbw = camera>getWorldTransform() * Tbc;
Re: Rotate camera around constraint object...
Right, rotations are always harder than translations... ))
Here below the final version  did save the initial transform, then used it to constantly update the basis of the constraint.
Only, make sure there are no other constraints on y, so the object can be rotated around y to face the camera:
Thank you for your answer, it did help me! Hope it helps someone else one day.
Will mark the post solved.
Here below the final version  did save the initial transform, then used it to constantly update the basis of the constraint.
Only, make sure there are no other constraints on y, so the object can be rotated around y to face the camera:
Code: Select all
revolutionSurface>getRigidBody()>setAngularFactor(btVector3(0, 1, 0)); // up straight
Will mark the post solved.
Code: Select all
void InceptionPhysics::addHitConstraint(const btVector3& endPosition, bool limitAngularMotion) {
if (m_dynamicsWorld) {
RayCast rayCast;
if (!hitObject(glm2bullet(m_camera>getPosition()), endPosition, rayCast))
return;
logFileStderr(VERBOSE, "MESSAGE: Picking up object!...\n");
m_pickedRigidBody = rayCast.rigidBody;
m_pickedRigidBody>setActivationState(DISABLE_DEACTIVATION);
m_initialTransform = glm::inverse(m_camera>getRotationMatrix()) * bullet2glm(m_pickedRigidBody>getWorldTransform());
btTransform transform;
transform.setIdentity();
btVector3 localPoint = m_pickedRigidBody>getCenterOfMassTransform().inverse() * rayCast.point;
transform.setOrigin(localPoint);
m_previousPickingDistance = (rayCast.point  glm2bullet(m_camera>getPosition())).length();
m_pickConstraint = new btGeneric6DofConstraint(*m_pickedRigidBody, transform, false);
float CFM = 0.5f; // strength constraint all axis 05
float ERP = 0.5f; // error reduction constraint all axis 05
for (int i = 0; i < 6; i++) {
m_pickConstraint>setParam(BT_CONSTRAINT_STOP_CFM, CFM, i);
m_pickConstraint>setParam(BT_CONSTRAINT_STOP_ERP, ERP, i);
}
m_dynamicsWorld>addConstraint(m_pickConstraint, true);
}
}
void InceptionPhysics::moveObject(const btVector3 &position) {
// logStderr(VERBOSE, "MESSAGE: Moving object...\n");
if (m_pickedRigidBody) {
if (!m_pickConstraint)
return;
btVector3 target = position  glm2bullet(m_camera>getPosition());
target.normalize();
target *= m_previousPickingDistance;
btVector3 newPivot = glm2bullet(m_camera>getPosition()) + target;
m_pickConstraint>getFrameOffsetA().setOrigin(newPivot);
m_pickConstraint>getFrameOffsetA().setBasis(glm2bulletR(m_camera>getRotationMatrix() * m_initialTransform));
}
}
btMatrix3x3 glm2bulletR(const glm::mat4& matrix) {
btMatrix3x3 basis;
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
basis[j][i] = matrix[i][j];
return basis;
}