/*! Rotates the node around its local origin relative to the space expressed by 'relativeTo'. */ void SLNode::rotate(const SLQuat4f& rot, SLTransformSpace relativeTo) { SLQuat4f norm = rot.normalized(); SLMat4f rotation = rot.toMat4(); if (relativeTo == TS_object) { _om *= rotation; } else if (_parent && relativeTo == TS_world) { SLMat4f rot; rot.translate(updateAndGetWM().translation()); rot.multiply(rotation); rot.translate(-updateAndGetWM().translation()); _om = _parent->_wm.inverse() * rot * updateAndGetWM(); } else // relativeTo == TS_Parent || relativeTo == TS_World && !_parent { SLMat4f rot; rot.translate(translation()); rot.multiply(rotation); rot.translate(-translation()); _om.setMatrix(rot * _om); } needUpdate(); }
/*! sets the rotation of this node. The axis parameter will be transformed into 'relativeTo' space. So an passing in an axis of (0, 1, 0) with TS_Object will rotate the node around its own up axis. */ void SLNode::rotation(const SLQuat4f& rot, SLTransformSpace relativeTo) { SLMat4f rotation = rot.toMat4(); if (_parent && relativeTo == TS_world) { // get the inverse parent rotation to remove it from our current rotation // we want the input quaternion to absolutely set our new rotation relative // to the world axes SLMat4f parentRotInv = _parent->updateAndGetWMI(); parentRotInv.translation(0, 0, 0); // set the om rotation to the inverse of the parents rotation to achieve a // 0, 0, 0 relative rotation in world space _om.rotation(0, 0, 0, 0); _om *= parentRotInv; needUpdate(); rotate(rot, relativeTo); } else if (relativeTo == TS_parent) { // relative to parent, reset current rotation and just rotate again _om.rotation(0, 0, 0, 0); needUpdate(); rotate(rot, relativeTo); } else { // in TS_Object everything is relative to our current orientation _om.rotation(0, 0, 0, 0); _om *= rotation; needUpdate(); } }
/*! set a rotation for this node */ void SLBoneNode::rotation(SLQuat4f& rot) { _globalTransform = _poseTransform; _transform = _poseTransform; SLMat4f rotation = rot.toMat4(); _transform *= rotation; }
/*! Applies the view transform to the modelview matrix depending on the eye: eye=-1 for left, eye=1 for right */ void SLCamera::setView(SLSceneView* sv, const SLEye eye) { SLScene* s = SLScene::current; SLMat4f vm = updateAndGetWMI(); if (eye == centerEye) { _stateGL->modelViewMatrix.identity(); _stateGL->viewMatrix.setMatrix(vm); } else // stereo viewing { if (_projection == stereoSideBySideD) { // half interpupilar disqtance //_eyeSeparation = s->oculus()->interpupillaryDistance(); update old rift code SLfloat halfIPD = (SLfloat)eye * _eyeSeparation * -0.5f; SLMat4f trackingPos; if (_useDeviceRot) { // get the oculus or mobile device orientation SLQuat4f rotation; if (s->oculus()->isConnected()) { rotation = s->oculus()->orientation(eye); trackingPos.translate(-s->oculus()->position(eye)); } else rotation = sv->deviceRotation(); SLfloat rotX, rotY, rotZ; rotation.toMat4().toEulerAnglesZYX(rotZ, rotY, rotX); //SL_LOG("rotx : %3.1f, roty: %3.1f, rotz: %3.1f\n", rotX*SL_RAD2DEG, rotY*SL_RAD2DEG, rotZ*SL_RAD2DEG); SLVec3f viewAdjust = s->oculus()->viewAdjust(eye) * _unitScaling; SLMat4f vmEye(SLMat4f(viewAdjust.x, viewAdjust.y, viewAdjust.z) * rotation.inverted().toMat4() * trackingPos * vm); _stateGL->modelViewMatrix = vmEye; _stateGL->viewMatrix = vmEye; } else { SLMat4f vmEye(SLMat4f(halfIPD, 0.0f, 0.f) * vm); _stateGL->modelViewMatrix = vmEye; _stateGL->viewMatrix = vmEye; } } else { // Get central camera vectors eye, lookAt, lookUp out of the view matrix vm SLVec3f EYE, LA, LU, LR; vm.lookAt(&EYE, &LA, &LU, &LR); // Shorten LR to half of the eye dist (eye=-1 for left, eye=1 for right) LR *= _eyeSeparation * 0.5f * (SLfloat)eye; // Set the OpenGL view matrix for the left eye SLMat4f vmEye; vmEye.lookAt(EYE+LR, EYE + _focalDist*LA+LR, LU); _stateGL->modelViewMatrix = vmEye; _stateGL->viewMatrix = vmEye; } } }