void InteractionHandler::resetCameraDirection() { LINFO("Setting camera direction to point at focus node."); glm::dquat rotation = _camera->rotationQuaternion(); glm::dvec3 focusPosition = focusNode()->worldPosition(); glm::dvec3 cameraPosition = _camera->positionVec3(); glm::dvec3 lookUpVector = _camera->lookUpVectorWorldSpace(); glm::dvec3 directionToFocusNode = glm::normalize(focusPosition - cameraPosition); // To make sure the lookAt function won't fail static const double epsilon = 0.000001; if (glm::dot(lookUpVector, directionToFocusNode) > 1.0 - epsilon) { // Change the look up vector a little bit lookUpVector = glm::normalize(lookUpVector + glm::dvec3(epsilon)); } // Create the rotation to look at focus node glm::dmat4 lookAtMat = glm::lookAt( glm::dvec3(0, 0, 0), directionToFocusNode, lookUpVector); glm::dquat rotationLookAtFocusNode = normalize(quat_cast(inverse(lookAtMat))); // Update camera Rotation _camera->setRotation(rotationLookAtFocusNode); }
void AnimatedTransform::decompose(const mat4x4& m, vec3* translation, quat* rotation, mat4x4* scale) { // Decompose function from Pbrt // https://github.com/mmp/pbrt-v2/blob/master/src/core/transform.cpp // Extract translation from transformation matrix translation->x = m[3][0]; translation->y = m[3][1]; translation->z = m[3][2]; // Compute new transformation matrix M without translation mat4x4 M = m; for (int i = 0; i < 3; ++i) M[i][3] = M[3][i] = 0.f; M[3][3] = 1.f; // Extract rotation from transformation matrix float norm; int count = 0; mat4x4 R = M; do { // Compute next matrix Rnext in series mat4x4 Rnext; mat4x4 Rit = inverse(transpose(R)); for (int i = 0; i < 4; ++i) for (int j = 0; j < 4; ++j) Rnext[i][j] = 0.5f * (R[i][j] + Rit[i][j]); // Compute norm of difference between R and Rnext norm = 0.f; for (int i = 0; i < 3; ++i) { float n = (fabsf(R[i][0] - Rnext[i][0]) + fabsf(R[i][1] - Rnext[i][1]) + fabsf(R[i][2] - Rnext[i][2]) ); norm = max(norm, n); } R = Rnext; } while (++count < 100 && norm > .0001f); *rotation = quat_cast(R); // Compute scale _S_ using rotation and original matrix *scale = inverse(R) * M; }
detail::tquat<valType> toQuat( detail::tmat4x4<valType> const & x){return quat_cast(x);}
GLM_FUNC_DECL tquat<T, P> toQuat( tmat4x4<T, P> const & x){return quat_cast(x);}
GLM_FUNC_DECL tquat<T, P> toQuat( mat<4, 4, T, P> const& x){return quat_cast(x);}
detail::tquat<T, P> toQuat( detail::tmat4x4<T, P> const & x){return quat_cast(x);}
void Transform::setRotationEuler(glm::vec3 angles){ assert(!glm::any(glm::isnan(angles))); mat4 rot = yawPitchRoll(angles.y, angles.x, angles.z); setRotation(quat_cast(rot)); }
void Transform::setLocalRotationEuler(glm::vec3 angles){ assert(!glm::any(glm::isnan(angles))); mat4 rot = yawPitchRoll(angles.y, angles.x, angles.z); mLocalRotationQuat = quat_cast(rot); markLocalDirty(); }
void Camera::SetLookAt(glm::vec3 pos) { look_at = pos; rotation_quaternion = quat_cast(lookAt(position, pos, vec3(0,1,0))); }