void CPanel::Rotate(CVector const &HA, Quaternion &Qt, double const &angle) { // HA is a point on the rotation axis // for a VLM analysis, we need to rotate : // - the control point // - the vortice vector // - the vortice's end points W.x = VortexPos.x - HA.x; W.y = VortexPos.y - HA.y; W.z = VortexPos.z - HA.z; Qt.Conjugate(W); VortexPos.x = W.x + HA.x; VortexPos.y = W.y + HA.y; VortexPos.z = W.z + HA.z; W.x = CtrlPt.x - HA.x; W.y = CtrlPt.y - HA.y; W.z = CtrlPt.z - HA.z; Qt.Conjugate(W); CtrlPt.x = W.x + HA.x; CtrlPt.y = W.y + HA.y; CtrlPt.z = W.z + HA.z; Qt.Conjugate(Vortex); Normal.RotateY(angle); //TODO ; remove ? // What's the point of A and B anyway? // are they used anywhere W.x = A.x - HA.x; W.y = A.y - HA.y; W.z = A.z - HA.z; Qt.Conjugate(W); A.x = W.x + HA.x; A.y = W.y + HA.y; A.z = W.z + HA.z; W.x = B.x - HA.x; W.y = B.y - HA.y; W.z = B.z - HA.z; Qt.Conjugate(W); B.x = W.x + HA.x; B.y = W.y + HA.y; B.z = W.z + HA.z; }
void MayaCamera::OnUpdate(TimeStep timeStep) { const Application& app = Application::GetApplication(); if (app.IsKeyPressed(GLFW_KEY_LEFT_ALT)) { const vec2& mouse = app.GetMousePos(); vec2 delta = mouse - m_InitialMousePosition; m_InitialMousePosition = mouse; if (app.GetMouseButton() == GLFW_MOUSE_BUTTON_MIDDLE) MousePan(delta); else if (app.GetMouseButton() == GLFW_MOUSE_BUTTON_LEFT) MouseRotate(delta); else if (app.GetMouseButton() == GLFW_MOUSE_BUTTON_RIGHT) MouseZoom(delta.y); } // MouseZoom(window->GetMouseScrollPosition().y); m_Position = CalculatePosition(); Quaternion orientation = GetOrientation(); m_Rotation = orientation.ToEulerAngles() * (180.0f / 3.14f); m_View = mat4::Translate(vec3(0, 0, 1)) * mat4::Rotate(orientation.Conjugate()) * mat4::Translate(-m_Position); }
// 点或向量乘以四元数(点或向量经四元数变换) Vector3 operator*(Vector3 vec, Quaternion q) { Quaternion vecQ = Quaternion(0, vec.x, vec.y, vec.z); Quaternion resultQ = q * vecQ * q.Conjugate(); return Vector3(resultQ.x, resultQ.y, resultQ.z); }
// set the rotation of the 3D viewer void Viewer3dParam::SetPose( Quaternion q, Vec3f t ) { Rotation( q.Conjugate() ); Translation( t ); }
Vec3 Vec3::Rotate(const Quaternion& rotation) { Quaternion conjugateQ = rotation.Conjugate(); Quaternion q = rotation * (*this) * conjugateQ; Vec3 ret(q.x, q.y, q.z); return ret; }
Vector3D OpenGLSceneViewCore::positionFromRotatedAxisPoint(Axis axis, NSPoint point, Quaternion rotation) { DrawPlane(_camera->GetAxisX(), _camera->GetAxisY(), planeSize); Vector3D position = positionInSpaceByPoint(point); Vector3D result = _manipulated->selectionCenter(); position = rotation.Conjugate().ToMatrix().Transform(position); result[(int)axis] = position[(int)axis]; return result; }
void Quaternion::SetupSquad( const Quaternion &q0, const Quaternion &q1, const Quaternion &q2, Quaternion &a, Quaternion &b) { // assert: q0, q1, q2 are unit quaternions Quaternion q0inv = q0.Conjugate(); Quaternion q1inv = q1.Conjugate(); Quaternion p0 = q0inv * q1; Quaternion p1 = q1inv * q2; Quaternion arg = 0.25f * (p0.Ln() - p1.Ln()); Quaternion minusArg = -arg; a = q1 * arg.Exp(); b = q1 * minusArg.Exp(); }
Quaternion<Real> Quaternion<Real>::GetIntermediate(const Quaternion& rkQ0, const Quaternion& rkQ1, const Quaternion& rkQ2) { // assert: Q0, Q1, Q2 all unit-length Quaternion<Real> kQ1Inv = rkQ1.Conjugate(); Quaternion<Real> kP0 = kQ1Inv* rkQ0; Quaternion<Real> kP2 = kQ1Inv* rkQ2; Quaternion<Real> kArg = -((Real) 0.25) * (kP0.Log() + kP2.Log()); Quaternion<Real> kA = rkQ1* kArg.Exp(); return kA; }
Quaternion Quaternion::Inverse() { Quaternion q; q.x = x; q.y = y; q.z = z; q.w = w; q.Conjugate().Scale(1/q.Norm()); return q; }
ShadowCameraTransform DirectionalLight::CalcShadowCameraTransform(const Vector3f& mainCameraPos, const Quaternion& mainCameraRot) const { Vector3f resultPos = mainCameraPos + mainCameraRot.GetForward() * GetHalfShadowArea(); Quaternion resultRot = GetTransform().GetTransformedRot(); float worldTexelSize = (GetHalfShadowArea()*2)/((float)(1 << GetShadowInfo().GetShadowMapSizeAsPowerOf2())); Vector3f lightSpaceCameraPos = resultPos.Rotate(resultRot.Conjugate()); lightSpaceCameraPos.SetX(worldTexelSize * floor(lightSpaceCameraPos.GetX() / worldTexelSize)); lightSpaceCameraPos.SetY(worldTexelSize * floor(lightSpaceCameraPos.GetY() / worldTexelSize)); resultPos = lightSpaceCameraPos.Rotate(resultRot); return ShadowCameraTransform(resultPos, resultRot); }
/** *Rotates the boundary condition properties which are used in stability analysis with variable control positions. *@param HA is the center of rotation *@param Qt the quaternion which defines the 3D rotation */ void Panel::RotateBC(CVector const &HA, Quaternion &Qt) { // Qt.Conjugate(Vortex); static CVector WTest; WTest.x = VortexPos.x - HA.x; WTest.y = VortexPos.y - HA.y; WTest.z = VortexPos.z - HA.z; Qt.Conjugate(WTest); VortexPos.x = WTest.x + HA.x; VortexPos.y = WTest.y + HA.y; VortexPos.z = WTest.z + HA.z; WTest.x = VA.x - HA.x; WTest.y = VA.y - HA.y; WTest.z = VA.z - HA.z; Qt.Conjugate(WTest); VA.x = WTest.x + HA.x; VA.y = WTest.y + HA.y; VA.z = WTest.z + HA.z; WTest.x = VB.x - HA.x; WTest.y = VB.y - HA.y; WTest.z = VB.z - HA.z; Qt.Conjugate(WTest); VB.x = WTest.x + HA.x; VB.y = WTest.y + HA.y; VB.z = WTest.z + HA.z; WTest.x = CtrlPt.x - HA.x; WTest.y = CtrlPt.y - HA.y; WTest.z = CtrlPt.z - HA.z; Qt.Conjugate(WTest); CtrlPt.x = WTest.x + HA.x; CtrlPt.y = WTest.y + HA.y; CtrlPt.z = WTest.z + HA.z; WTest.x = CollPt.x - HA.x; WTest.y = CollPt.y - HA.y; WTest.z = CollPt.z - HA.z; Qt.Conjugate(WTest); CollPt.x = WTest.x + HA.x; CollPt.y = WTest.y + HA.y; CollPt.z = WTest.z + HA.z; Qt.Conjugate(Vortex); Qt.Conjugate(Normal); }
void TreeSegGeo::constructGeometryData(Quaternion orient, bool topPlane, bool bottomPlane) { int numVerts = mSegmentsW * (mSegmentsH + 1) + 2; // positionData mGeoData.posData.push_back(Vector3::Zero); mGeoData.posData.push_back(Vector3(0, mLength, 0)); float heightDelta = mLength / mSegmentsH; float deltaTheta = 2*PI / mSegmentsW; for(int i = 0; i <= mSegmentsH; ++i) { float circleHeight = i * heightDelta; float circleRadius = mRadius[i]; for(int j = 0; j < mSegmentsW; ++j) { float x = circleRadius * cos(j*deltaTheta); float z = circleRadius * sin(j*deltaTheta); Vector3 vertPos(x, circleHeight, z); if(i == 0) vertPos = vertPos * orient.Conjugate(); mGeoData.posData.push_back(vertPos); } } // verts for(size_t i = 0; i < mGeoData.posData.size(); ++i) { Vert vert(i); mGeoData.verts.push_back(vert); } // triangles if(bottomPlane) { for(int i = 0; i < mSegmentsW; ++i) // 底圆面 { // 顶点索引为2 ~ sw+1 Triangle triangle(0, 2+i, 2 + (i + 1) % mSegmentsW); mGeoData.tris.push_back(triangle); } } if(topPlane) { for(int i = 0; i < mSegmentsW; ++i) // 顶圆面 { // 顶点索引为sw*sh + 2 ~ sw*(sh + 1) + 1 Triangle triangle(1, mSegmentsW*mSegmentsH + 2 + (i + 1) % mSegmentsW, mSegmentsW*mSegmentsH + 2 + i); mGeoData.tris.push_back(triangle); } } for(int i = 0; i < mSegmentsH; ++i) // 柱面 { for(int j = 0; j < mSegmentsW; ++j) { Triangle tri1; Triangle tri2; tri1.vertexIndex[0] = mSegmentsW * i + j + 2; tri1.vertexIndex[1] = mSegmentsW * (i + 1) + j + 2; tri1.vertexIndex[2] = mSegmentsW * i + (j + 1)%mSegmentsW + 2; tri2.vertexIndex[0] = mSegmentsW * (i + 1) + j + 2; tri2.vertexIndex[1] = mSegmentsW * (i + 1) + (j + 1)%mSegmentsW + 2; tri2.vertexIndex[2] = mSegmentsW * i + (j + 1)%mSegmentsW + 2; _Assert(tri1.vertexIndex[0] < mSegmentsW * (mSegmentsH + 1) + 2); _Assert(tri1.vertexIndex[1] < mSegmentsW * (mSegmentsH + 1) + 2); _Assert(tri1.vertexIndex[2] < mSegmentsW * (mSegmentsH + 1) + 2); _Assert(tri2.vertexIndex[0] < mSegmentsW * (mSegmentsH + 1) + 2); _Assert(tri2.vertexIndex[1] < mSegmentsW * (mSegmentsH + 1) + 2); _Assert(tri2.vertexIndex[2] < mSegmentsW * (mSegmentsH + 1) + 2); mGeoData.tris.push_back(tri1); mGeoData.tris.push_back(tri2); } } }
Quaternion operator~(const Quaternion &op) { return op.Conjugate(); }
void FPSCamera::Update() { vec2 windowSize = Application::GetApplication().GetWindowSize(); vec2 windowCenter = vec2((float)(int32)(windowSize.x / 2.0f), (float)(int32)(windowSize.y / 2.0f)); if (Input::IsMouseButtonPressed(SP_MOUSE_RIGHT)) { if (!Input::GetInputManager()->IsMouseGrabbed()) { Input::GetInputManager()->SetMouseGrabbed(true); Input::GetInputManager()->SetMouseCursor(SP_NO_CURSOR); } } if (Input::GetInputManager()->IsMouseGrabbed()) { vec2 mouse = Input::GetInputManager()->GetMousePosition(); mouse.x -= windowCenter.x; mouse.y -= windowCenter.y; if (m_MouseWasGrabbed) { m_Yaw += mouse.x * m_MouseSensitivity; m_Pitch += mouse.y * m_MouseSensitivity; } m_MouseWasGrabbed = true; Input::GetInputManager()->SetMousePosition(windowCenter); Quaternion orientation = GetOrientation(); m_Rotation = orientation.ToEulerAngles() * (180.0f / SP_PI); vec3 forward = GetForwardDirection(orientation); vec3 right = GetRightDirection(orientation); vec3 up = vec3::YAxis(); float speed = Input::IsKeyPressed(SP_KEY_SHIFT) ? m_SprintSpeed : m_Speed; if (Input::IsKeyPressed(SP_KEY_W)) m_Position += forward * speed; else if (Input::IsKeyPressed(SP_KEY_S)) m_Position -= forward * speed; if (Input::IsKeyPressed(SP_KEY_A)) m_Position -= right * speed; else if (Input::IsKeyPressed(SP_KEY_D)) m_Position += right * speed; if (Input::IsKeyPressed(SP_KEY_SPACE)) m_Position += up * speed; if (Input::IsKeyPressed(SP_KEY_CONTROL)) m_Position -= up * speed; mat4 rotation = mat4::Rotate(orientation.Conjugate()); mat4 translation = mat4::Translate(-m_Position); m_ViewMatrix = rotation * translation; } if (Input::IsKeyPressed(SP_KEY_ESCAPE)) { Input::GetInputManager()->SetMouseGrabbed(false); Input::GetInputManager()->SetMouseCursor(1); m_MouseWasGrabbed = false; } }