void CineCameraClass::Pan(float degree) { //NOTE: currently the argument delta is not used wchar_t* outstring = L"CineCameraClass::Pan\n"; WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), outstring, wcslen(outstring), NULL, NULL); /*TO DO Pan the camera left rotating CW about the up vector direction vector Create a Rotaton Quaternion that represents a rotation about the camera's up vector. A Quaternion is created by supplying a vector and an angle and represents a rotation of that angle about the vector See how this is done for the tilt operation */ rotation.x += degree*(XM_PIDIV2/100*CAMERA_PAN_SPEED); //Pan the camera right rotating CW about the up vector direction vector double horizontalMagnitude = sqrt(direction.x * direction.x + direction.z * direction.z); float angle = (float)atan(direction.y / horizontalMagnitude); XMVECTOR sideWaysVector = XMVector3Normalize(XMVector3Cross(XMLoadFloat3(&upDirection), XMLoadFloat3(&direction) )); XMVECTOR tiltRotationQuaternion = XMQuaternionRotationAxis(sideWaysVector, angle); XMStoreFloat3(&direction, XMVector3Rotate( XMLoadFloat3(&direction), tiltRotationQuaternion)); XMStoreFloat3(&upDirection, XMVector3Rotate( XMLoadFloat3(&upDirection), tiltRotationQuaternion)); XMVECTOR panRotationQuaternion = XMQuaternionRotationAxis(XMLoadFloat3(&upDirection), degree*(XM_PIDIV2/100*CAMERA_PAN_SPEED)); XMStoreFloat3(&direction, XMVector3Rotate( XMLoadFloat3(&direction), panRotationQuaternion)); sideWaysVector = XMVector3Normalize(XMVector3Cross(XMLoadFloat3(&upDirection), XMLoadFloat3(&direction) )); tiltRotationQuaternion = XMQuaternionRotationAxis(sideWaysVector, -angle); XMStoreFloat3(&direction, XMVector3Rotate( XMLoadFloat3(&direction), tiltRotationQuaternion)); XMStoreFloat3(&upDirection, XMVector3Rotate( XMLoadFloat3(&upDirection), tiltRotationQuaternion)); }
XMFLOAT4 Weapon::GetWeaponOffsetRotation() { XMVECTOR quat = XMQuaternionIdentity(); XMFLOAT3 direction = GetFloat3Value( Direction ); XMFLOAT3 aimPos; XMFLOAT3 pipePos; if (GetJointPosition("PipeAim", aimPos) && GetJointPosition("Pipe", pipePos)) { //handPos.y = pipePos.y; XMVECTOR directionV = XMLoadFloat3(&direction); XMVECTOR handPosV = XMLoadFloat3(&aimPos); XMVECTOR pipePosV = XMLoadFloat3(&pipePos); XMVECTOR offsetDirectionV = pipePosV - handPosV; XMVECTOR angleV = XMVector3AngleBetweenVectors(directionV, offsetDirectionV); float angle; XMStoreFloat(&angle, angleV); if (angle != 0) { XMVECTOR axis = XMVector3Cross(directionV, offsetDirectionV); quat = XMQuaternionRotationAxis(axis, angle); } } XMFLOAT4 result; XMStoreFloat4(&result, quat); return result; }
XMFLOAT4 quat_from_axis_angle(XMFLOAT3 axis, float angle) { auto qr = XMQuaternionRotationAxis(XMLoadFloat3(&axis), XMConvertToRadians(angle)); XMFLOAT4 quat; XMStoreFloat4(&quat, qr); return quat; }
XMFLOAT4 SphereWalker::getBehind(float dist) { XMVECTOR xperp = XMVectorSet(-cosf(angle), sinf(angle), 0,0); XMVECTOR incrementalRotation; incrementalRotation = XMQuaternionRotationAxis( xperp, -dist); XMFLOAT4 ret; XMStoreFloat4(&ret, XMQuaternionMultiply(incrementalRotation , XMLoadFloat4(&qPos))); return ret; }
void HydraRenderer::Render(D3DRenderer* renderer) { CBPerObject perObject; perObject.Material.HasDiffuseTex = false; perObject.Material.HasNormalTex = false; perObject.Material.HasSpecTex = false; perObject.Material.HasEmissiveTex = false; HydraManager* hydra = InputSystem::get()->getHydra(); for (int controller = 0; controller < sixenseGetMaxControllers(); controller++) { if (sixenseIsControllerEnabled(controller)) { XMVECTOR rotationQuat = hydra->getRotation(controller); XMVECTOR position = hydra->getPosition(controller); //XMVectorSetZ(position, -XMVectorGetZ(position));//Flip Z axis //position += XMVectorSet(0.0f, 0.9f, 0.0f, 0.0f);//Offset for table height perObject.World = XMMatrixRotationQuaternion(XMQuaternionRotationAxis(XMLoadFloat3(&XMFLOAT3(1.0f, 0.0f, 0.0f)), XMConvertToRadians(90.0f))) * XMMatrixTranslation(0.0f, 0.0f, 0.07f) * //XMMatrixTranslation(0.0f, 0.0f, 0.25f) * XMMatrixRotationQuaternion(rotationQuat) * XMMatrixTranslationFromVector(position); perObject.WorldInvTranspose = XMMatrixInverse(NULL, XMMatrixTranspose(perObject.World)); perObject.WorldViewProj = perObject.World * renderer->getPerFrameBuffer()->ViewProj; renderer->setPerObjectBuffer(perObject); mpPointerRenderer->Render(renderer); //Render root trackers perObject.World = XMMatrixRotationQuaternion(XMQuaternionRotationAxis(XMLoadFloat3(&XMFLOAT3(1.0f, 0.0f, 0.0f)), XMConvertToRadians(90.0f))) * XMMatrixRotationQuaternion(rotationQuat) * XMMatrixTranslationFromVector(position); perObject.WorldInvTranspose = XMMatrixInverse(NULL, XMMatrixTranspose(perObject.World)); perObject.WorldViewProj = perObject.World * renderer->getPerFrameBuffer()->ViewProj; renderer->setPerObjectBuffer(perObject); mpRootRenderer->Render(renderer); } } }
void RaceScene::Enter() { mFollowCamera = mSceneManager->addFpsCameraNode(2, nullptr, XMFLOAT3(0, 100.0f, -100.0f), XMFLOAT3(0, 1.0f, 0.0f), XMFLOAT3(0, 1.0f, 0), true); mFollowCamera->setNearZ(1.0f); mFollowCamera->setFarZ(1000.0f); mFollowCamera->setShadowRange(300.0f); mSideCamera = mSceneManager->addFpsCameraNode(3, nullptr); mSideCamera->setNearZ(1.0f); mSideCamera->setFarZ(1000.0f); mSideCamera->setShadowRange(300.0f); mPlayerVehicle = new Vehicle(mSceneManager, mTerrainNode, "carA"); mSceneManager->setActiveCamera(2); XMFLOAT3 camPos = mFreeCamera->getPosition(); mPlayerVehicle->setPosition(camPos); mFreeCamera->update(0); XMFLOAT3 look = mFreeCamera->getLookVector(); XMVECTOR look_v = XMVector3Normalize(XMVectorSet(look.x, 0, look.z, 0)); XMVECTOR neg_x_v = XMVectorSet(-1.0f, 0, 0, 0); XMVECTOR axis = XMVector3Normalize(XMVector3Cross(neg_x_v, look_v)); XMVECTOR angle = XMVector3AngleBetweenNormals(neg_x_v, look_v); XMVECTOR quat_v = XMQuaternionRotationAxis(axis, XMVectorGetX(angle)); XMFLOAT4 quat; XMStoreFloat4(&quat, quat_v); mPlayerVehicle->setRotation(quat); mVideoDriver->setDeferredAntiAliasing(true); IMeshNode* skyNode = mSceneManager->getSkyNode(); if (skyNode) skyNode->setMaterialName("skydome_material"); u32 textureWidth = mVideoDriver->getBackBufferWidth() / 2; u32 textureHeight = mVideoDriver->getBackBufferHeight() / 2; ITextureManager* textureManager = ITextureManager::getInstance(); mTireTrailTexture = textureManager->createTexture2D("tire_trail", textureWidth, textureHeight, ETBT_SHADER_RESOURCE | ETBT_RENDER_TARGET, nullptr, 1, EGF_R16_FLOAT); mTireTrailDepthSurface = textureManager->createDepthStencilSurface("tire_trail_depth", textureWidth, textureHeight, 16, 0, false, 1, 0, false, false); }
void CineCameraClass::RollLeft() { //NOTE: currently the argument delta is not used wchar_t* outstring = L"CineCameraClass::RollLeft\n"; WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), outstring, wcslen(outstring), NULL, NULL); //create the quaternion the rotates about the direction vector of the camera XMVECTOR rollRotationQuaternion = XMQuaternionRotationAxis(XMLoadFloat3(&direction), XM_PIDIV4/100*CAMERA_ROLL_SPEED); //Modify both the camera's up vector using the //rotation quaternion. XMStoreFloat3(&upDirection, XMVector3Rotate( XMLoadFloat3(&upDirection), rollRotationQuaternion)); }
void rotate_degrees(QuaternionTransform &qt, float amt) { XMVECTOR quat = XMLoadFloat4(&qt.quat); XMVECTOR axis; float angle; XMQuaternionToAxisAngle(&axis, &angle, quat); angle = XMConvertToDegrees(angle); angle += amt; angle = XMConvertToRadians(angle); quat = XMQuaternionRotationAxis(axis, angle); XMStoreFloat4(&qt.quat, quat); }
void SphereWalker::move(float dt) { XMVECTOR perp = XMVectorSet(-cosf(angle), sinf(angle), 0,0); XMVECTOR incrementalRotation; incrementalRotation = XMQuaternionRotationAxis(perp, dt ); XMStoreFloat4(&qPos, XMQuaternionMultiply(incrementalRotation , XMLoadFloat4(&qPos))); orientationToPos(qPos, pos); //Rotate in space XMMATRIX globalRotation = XMMatrixRotationQuaternion( XMLoadFloat4(&qPos)); XMMATRIX localRotation; XMVECTOR up = XMVectorSet( 0,0,1,0); localRotation = XMMatrixRotationAxis(up, -angle); XMStoreFloat4x4(&orientation, localRotation * globalRotation); }
XMVECTOR HydraManager::getRotation(int controllerIndex) const { if (sixenseIsControllerEnabled(controllerIndex)) { XMVECTOR axis; float angle; XMQuaternionToAxisAngle(&axis, &angle, XMLoadFloat4(&XMFLOAT4(&mAcd.controllers[controllerIndex].rot_quat[0]))); axis = XMVectorSet(-XMVectorGetX(axis), XMVectorGetY(axis), -XMVectorGetZ(axis), 0.0f); XMVECTOR rotationQuat = XMQuaternionRotationAxis(axis, angle); return rotationQuat; } return XMQuaternionIdentity(); }
void CineCameraClass::Tilt(float degree) { double horizontalMagnitude = sqrt(direction.x * direction.x + direction.z * direction.z); float angle = (float)atan(direction.y / horizontalMagnitude); if ((angle - degree*(XM_PIDIV2/100*CAMERA_TILT_SPEED) < XM_PIDIV2) && (angle - degree*(XM_PIDIV2/100*CAMERA_TILT_SPEED) > -XM_PIDIV2)) { rotation.y += degree*(XM_PIDIV2/100*CAMERA_TILT_SPEED); //NOTE: currently the argument delta is not used wchar_t* outstring = L"CineCameraClass::Tilt\n"; WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), outstring, wcslen(outstring), NULL, NULL); //Tilt the camera upwards rotating about the sideways direction vector XMVECTOR sideWaysVector = XMVector3Normalize(XMVector3Cross(XMLoadFloat3(&upDirection), XMLoadFloat3(&direction) )); XMVECTOR tiltRotationQuaternion = XMQuaternionRotationAxis(sideWaysVector, degree*(XM_PIDIV2/100*CAMERA_TILT_SPEED)); XMStoreFloat3(&direction, XMVector3Rotate( XMLoadFloat3(&direction), tiltRotationQuaternion)); XMStoreFloat3(&upDirection, XMVector3Rotate( XMLoadFloat3(&upDirection), tiltRotationQuaternion)); } }
vector KinectMeshAnimator::GetSkeletonOrientation(NUI_SKELETON_DATA& skeleton, int index1, int index2) { vector orientation; Joint* joint1 = bindings[index1]; Joint* joint2 = bindings[index2]; if (!joint1 || !joint2) return XMVectorSet(0.0, 1.0, 0.0, 0.0); // INVERT Z orientation = XMVectorSet( skeleton.SkeletonPositions[index2].x - skeleton.SkeletonPositions[index1].x, skeleton.SkeletonPositions[index2].y - skeleton.SkeletonPositions[index1].y, skeleton.SkeletonPositions[index1].z - skeleton.SkeletonPositions[index2].z, 0.0); vector bindOrientation = bindOrientations[index1]; vector axis = XMVector3Normalize(XMVector3Cross(bindOrientation, orientation)); if (XMVector3Equal(axis, XMVectorZero())) return XMVectorSet(0.0, 1.0, 0.0, 0.0); float angle; XMStoreFloat(&angle, XMVector3Dot(bindOrientation, orientation)); angle = acos(angle); return XMQuaternionRotationAxis(axis, angle); }
Quaternion(const Vector3& axis, float angle) { XMStoreFloat4A(this, XMQuaternionRotationAxis(axis, angle)); }
//------------------------------------------- // とりあえずIK void BoneModel::VMDIkAnimation() { //XMStoreFloat4() //XMLoadFloat4() if (mBone.empty())return; if (mMotion.empty())return; DWORD mBoneNum = mBone.size(); DWORD mIkNum = mIk.size(); // IK計算 for (DWORD i = 0; i < mIkNum; i++){ //{ // int i = 0; Ik& ik = mIk[i]; UINT tg_idx = ik.target_bone_index; UINT ik_idx = ik.bone_index; for (UINT ite = 0; ite<ik.iterations; ++ite){ for (UINT chn = 0; chn<ik.chain_length; ++chn){ UINT link_idx = ik.child_bone_index[chn];// if (link_idx >= mBoneNum)continue; Bone& link_bone = mBone[link_idx]; //UINT link_pidx = link_bone.mIkBoneIdx; UINT link_pidx = link_bone.mHierarchy.mIdxParent; //if (link_bone.mIkBoneIdx != 0){ // continue; //} if (link_pidx >= mBoneNum)continue; Bone& link_parent = mBone[link_pidx]; Bone& tg_bone = mBone[tg_idx]; (void)tg_bone; Bone& ik_bone = mBone[ik_idx]; (void)ik_bone; XMVECTOR target_wpos = mBone[tg_idx].mMtxPose.r[3]; XMVECTOR ik_wpos = mBone[ik_idx].mMtxPose.r[3]; XMVECTOR lp_wpos = link_parent.mMtxPose.r[3]; //Linkボーンのローカル空間に変換 XMVECTOR Determinant; XMMATRIX inv_mtx = XMMatrixInverse(&Determinant, link_bone.mMtxPose); XMVECTOR tg_pos = XMVector4Transform(target_wpos, inv_mtx); XMVECTOR ik_pos = XMVector4Transform(ik_wpos, inv_mtx); XMVECTOR lp_pos = XMVector4Transform(lp_wpos, inv_mtx); // 回転軸と角度 XMVECTOR rot_axis = XMVectorSet(1, 0, 0, 0); float ang = 0.0f; bool same_dir = false; if (!RotDir(tg_pos, ik_pos, ik.control_weight, &rot_axis, &ang)){ same_dir = true; } if (!same_dir){ //tg_dirをik_dirに一致させるための回転 XMVECTOR rot = XMQuaternionRotationAxis(rot_axis, ang); XMVECTOR lrot = FloatToVector(link_bone.mRot); XMVECTOR bone_rot_before = lrot; link_bone.mRot = VectorToFloat(XMQuaternionMultiply(rot, lrot)); float dist_tg = XMVectorGetX(XMVector3Length(tg_pos)); float dist_ik = XMVectorGetX(XMVector3Length(ik_pos)); (void)dist_ik; float dist_lp = XMVectorGetX(XMVector3Length(lp_pos)); (void)dist_lp; float dist_pltg = XMVectorGetX(XMVector3Length(lp_pos - tg_pos)); float dist_plik = XMVectorGetX(XMVector3Length(lp_pos - ik_pos)); float dot_tgik = XMVectorGetX(XMVector3Dot(XMVector3Normalize(tg_pos), XMVector3Normalize(ik_pos))); (void)dot_tgik; // 回転制限 if (/*link.bLimit*/ 1){ XMVECTOR rotmax, rotmin; //114.5916 = 2 float a = 2;// XM_PI / 180.0f * 57.25f; rotmax = XMVectorSet(a, a, a, 0);//link.vMax; rotmin = XMVectorSet(-a, -a, -a, 0);//link.vMin; //名前に"ひざ"があったら回転制限 if (std::string::npos != link_bone.mStrName.find("ひざ")){ rotmax = XMVectorSet(-XM_PI / 180.0f*0.5f, 0, 0, 0); rotmin = XMVectorSet(-XM_PI, 0, 0, 0); } struct IkLink{ XMFLOAT4 mMax; XMFLOAT4 mMin; }; IkLink link = { VectorToFloat(rotmax), VectorToFloat(rotmin) }; //Bone& link = link_bone; link_bone.mRot = VectorToFloat(LimitAngle(FloatToVector(link_bone.mRot), rotmin, rotmax)); XMVECTOR angxyz = GetAngle(rot); //膝を曲げるための仮処理 かなりてきとう if (XMVectorGetX(angxyz) >= 0 && //0.9f < dot_tgik && //dist_tg > dist_ik && dist_pltg > dist_plik && link.mMax.x < 0 && link.mMax.y == link.mMin.y && link.mMax.z == link.mMin.z){ //親リンクの回転接平面(できるだけこの平面に近づけたほうがよりIK目標に近づける) XMVECTOR lp_nor = XMVector3Normalize(-lp_pos);//平面の法線 //lp_norとの内積が0になる位置を目標にする //2つあるので回転制限後の|内積|が小さいほう XMVECTOR tng = XMVector3Cross(XMVectorSet(1, 0, 0, 0), lp_nor); //+tngと-tngの2つ XMVECTOR rot_axis0, rot_axis1; float ang0 = 0, ang1 = 0; // 回転軸をXに限定 rot_axis1 = rot_axis0 = XMVectorSet(1, 0, 0, 0); XMVECTOR tdir = XMVector3Normalize(XMVectorSetX(tg_pos, 0)); tng = XMVector3Normalize(XMVectorSetX(tng, 0)); RotDir(tdir, tng, ik.control_weight, &rot_axis0, &ang0); RotDir(tdir, -tng, ik.control_weight, &rot_axis1, &ang1); if (XMVectorGetX(rot_axis0) < 0.0f)ang0 = -ang0; if (XMVectorGetX(rot_axis1) < 0.0f)ang1 = -ang1; //これは絶対違う ぴくぴく対策 float coef = (dist_pltg - dist_plik) / dist_tg; if (coef > 1)coef = 1; ang0 *= coef; ang1 *= coef; //ang0,1は現在の位置からの相対角度 // 回転制限を考慮した相対角度に float angx_b = XMVectorGetX(GetAngle(bone_rot_before)); float angx_a0 = angx_b + ang0; float angx_a1 = angx_b + ang1; if (angx_a0 < link.mMin.x) angx_a0 = link.mMin.x; if (angx_a0 > link.mMax.x) angx_a0 = link.mMax.x; if (angx_a1 < link.mMin.x) angx_a1 = link.mMin.x; if (angx_a1 > link.mMax.x) angx_a1 = link.mMax.x; ang0 = angx_a0 - angx_b; ang1 = angx_a1 - angx_b; XMVECTOR rot0 = XMQuaternionRotationRollPitchYaw(ang0, 0, 0); XMVECTOR rot1 = XMQuaternionRotationRollPitchYaw(ang1, 0, 0); XMVECTOR tdir0 = XMVector3TransformCoord(tdir, XMMatrixRotationQuaternion(rot0)); XMVECTOR tdir1 = XMVector3TransformCoord(tdir, XMMatrixRotationQuaternion(rot1)); float d0 = XMVectorGetX(XMVectorAbs(XMVector3Dot(tdir0, lp_nor))); float d1 = XMVectorGetX(XMVectorAbs(XMVector3Dot(tdir1, lp_nor))); if (d0 < d1){ link_bone.mRot = VectorToFloat(XMQuaternionMultiply(rot0, bone_rot_before)); } else{ link_bone.mRot = VectorToFloat(XMQuaternionMultiply(rot1, bone_rot_before)); } } } } //ワールド行列更新 link_bone.mMtxPose = SQTMatrix(FloatToVector(link_bone.mScale), FloatToVector(link_bone.mRot), FloatToVector(link_bone.mPos)); if (link_bone.mHierarchy.mIdxParent < mBoneNum){ link_bone.mMtxPose = XMMatrixMultiply(link_bone.mMtxPose, mBone[link_bone.mHierarchy.mIdxParent].mMtxPose); } // 子階層のリンク再計算 for (int lidown = chn - 1; lidown >= 0; --lidown){ UINT idx = ik.child_bone_index[lidown]; if (idx >= mBoneNum)continue; Bone& linkb = mBone[idx]; linkb.mMtxPose = SQTMatrix(FloatToVector(linkb.mScale), FloatToVector(linkb.mRot), FloatToVector(linkb.mPos)); if (linkb.mHierarchy.mIdxParent < mBoneNum){ linkb.mMtxPose = XMMatrixMultiply(linkb.mMtxPose, mBone[linkb.mHierarchy.mIdxParent].mMtxPose); } } mBone[tg_idx].mMtxPose = SQTMatrix(FloatToVector(mBone[tg_idx].mScale), FloatToVector(mBone[tg_idx].mRot), FloatToVector(mBone[tg_idx].mPos)); if (mBone[tg_idx].mHierarchy.mIdxParent < mBoneNum){ mBone[tg_idx].mMtxPose = XMMatrixMultiply(mBone[tg_idx].mMtxPose, mBone[mBone[tg_idx].mHierarchy.mIdxParent].mMtxPose); } } } //Bone& b = mBone[tg_idx]; //Bone& b2 = mBone[mBone[tg_idx].mHierarchy.mIdxParent]; //Bone& b3 = mBone[b2.mHierarchy.mIdxParent]; //int sa = 1; //IKの計算結果を子階層に反映 //UpdatePose(); } UpdatePose(); }
Quaternion Quaternion::FromAxisAngle(const Float3& axis, float angle) { XMVECTOR q = XMQuaternionRotationAxis(axis.ToSIMD(), angle); return Quaternion(q); }
/** * Utility/Rotations.cpp * (c) Jonathan Capps * Created 11 Oct. 2011 */ #include <Windows.h> #include <xnamath.h> extern const XMVECTOR IDENTITY_QUAT = XMQuaternionIdentity(); extern const XMVECTOR QUARTER_TURN = XMQuaternionRotationAxis( XMVectorSet( 0.0f, 0.0f, -1.0f, 0.0f ), XM_PIDIV2 ); extern const XMVECTOR HALF_TURN = XMQuaternionRotationAxis( XMVectorSet( 0.0f, 0.0f, -1.0f, 0.0f ), XM_PI ); extern const XMVECTOR THREE_QUARTER_TURN = XMQuaternionRotationAxis( XMVectorSet( 0.0f, 0.0f, -1.0f, 0.0f ), 3.0f * XM_PIDIV2 ); extern const XMVECTOR TOP_JOIN = XMQuaternionRotationRollPitchYaw( 0.0f, -XM_PIDIV2, 0.0f ); extern const XMVECTOR SIDE_JOIN = XMQuaternionRotationRollPitchYaw( -XM_PIDIV2, -XM_PIDIV2, 0.0f );
QuatApp::QuatApp(HINSTANCE hInstance) : D3DApp(hInstance), mShapesVB(0), mShapesIB(0), mSkullVB(0), mSkullIB(0), mFloorTexSRV(0), mStoneTexSRV(0), mBrickTexSRV(0), mSkullIndexCount(0), mAnimTimePos(0.0f) { mMainWndCaption = L"Quaternion Demo"; mLastMousePos.x = 0; mLastMousePos.y = 0; mCam.Pitch(XMConvertToRadians(25.0f)); mCam.SetPosition(0.0f, 8.0f, -20.0f); XMMATRIX I = XMMatrixIdentity(); XMStoreFloat4x4(&mGridWorld, I); XMMATRIX boxScale = XMMatrixScaling(3.0f, 1.0f, 3.0f); XMMATRIX boxOffset = XMMatrixTranslation(0.0f, 0.5f, 0.0f); XMStoreFloat4x4(&mBoxWorld, XMMatrixMultiply(boxScale, boxOffset)); for(int i = 0; i < 5; ++i) { XMStoreFloat4x4(&mCylWorld[i*2+0], XMMatrixTranslation(-5.0f, 1.5f, -10.0f + i*5.0f)); XMStoreFloat4x4(&mCylWorld[i*2+1], XMMatrixTranslation(+5.0f, 1.5f, -10.0f + i*5.0f)); XMStoreFloat4x4(&mSphereWorld[i*2+0], XMMatrixTranslation(-5.0f, 3.5f, -10.0f + i*5.0f)); XMStoreFloat4x4(&mSphereWorld[i*2+1], XMMatrixTranslation(+5.0f, 3.5f, -10.0f + i*5.0f)); } mDirLights[0].Ambient = XMFLOAT4(0.2f, 0.2f, 0.2f, 1.0f); mDirLights[0].Diffuse = XMFLOAT4(0.5f, 0.5f, 0.5f, 1.0f); mDirLights[0].Specular = XMFLOAT4(0.5f, 0.5f, 0.5f, 1.0f); mDirLights[0].Direction = XMFLOAT3(0.57735f, -0.57735f, 0.57735f); mDirLights[1].Ambient = XMFLOAT4(0.0f, 0.0f, 0.0f, 1.0f); mDirLights[1].Diffuse = XMFLOAT4(0.20f, 0.20f, 0.20f, 1.0f); mDirLights[1].Specular = XMFLOAT4(0.25f, 0.25f, 0.25f, 1.0f); mDirLights[1].Direction = XMFLOAT3(-0.57735f, -0.57735f, 0.57735f); mDirLights[2].Ambient = XMFLOAT4(0.0f, 0.0f, 0.0f, 1.0f); mDirLights[2].Diffuse = XMFLOAT4(0.2f, 0.2f, 0.2f, 1.0f); mDirLights[2].Specular = XMFLOAT4(0.0f, 0.0f, 0.0f, 1.0f); mDirLights[2].Direction = XMFLOAT3(0.0f, -0.707f, -0.707f); mGridMat.Ambient = XMFLOAT4(0.8f, 0.8f, 0.8f, 1.0f); mGridMat.Diffuse = XMFLOAT4(0.8f, 0.8f, 0.8f, 1.0f); mGridMat.Specular = XMFLOAT4(0.8f, 0.8f, 0.8f, 16.0f); mCylinderMat.Ambient = XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f); mCylinderMat.Diffuse = XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f); mCylinderMat.Specular = XMFLOAT4(0.8f, 0.8f, 0.8f, 16.0f); mSphereMat.Ambient = XMFLOAT4(0.6f, 0.8f, 0.9f, 1.0f); mSphereMat.Diffuse = XMFLOAT4(0.6f, 0.8f, 0.9f, 1.0f); mSphereMat.Specular = XMFLOAT4(0.9f, 0.9f, 0.9f, 16.0f); mBoxMat.Ambient = XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f); mBoxMat.Diffuse = XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f); mBoxMat.Specular = XMFLOAT4(0.8f, 0.8f, 0.8f, 16.0f); mSkullMat.Ambient = XMFLOAT4(0.4f, 0.4f, 0.4f, 1.0f); mSkullMat.Diffuse = XMFLOAT4(0.8f, 0.8f, 0.8f, 1.0f); mSkullMat.Specular = XMFLOAT4(0.8f, 0.8f, 0.8f, 16.0f); // // Define the animation keyframes // XMVECTOR q0 = XMQuaternionRotationAxis(XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f), XMConvertToRadians(30.0f)); XMVECTOR q1 = XMQuaternionRotationAxis(XMVectorSet(1.0f, 1.0f, 2.0f, 0.0f), XMConvertToRadians(45.0f)); XMVECTOR q2 = XMQuaternionRotationAxis(XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f), XMConvertToRadians(-30.0f)); XMVECTOR q3 = XMQuaternionRotationAxis(XMVectorSet(1.0f, 0.0f, 0.0f, 0.0f), XMConvertToRadians(70.0f)); mSkullAnimation.Keyframes.resize(5); mSkullAnimation.Keyframes[0].TimePos = 0.0f; mSkullAnimation.Keyframes[0].Translation = XMFLOAT3(-7.0f, 0.0f, 0.0f); mSkullAnimation.Keyframes[0].Scale = XMFLOAT3(0.25f, 0.25f, 0.25f); XMStoreFloat4(&mSkullAnimation.Keyframes[0].RotationQuat, q0); mSkullAnimation.Keyframes[1].TimePos = 2.0f; mSkullAnimation.Keyframes[1].Translation = XMFLOAT3(0.0f, 2.0f, 10.0f); mSkullAnimation.Keyframes[1].Scale = XMFLOAT3(0.5f, 0.5f, 0.5f); XMStoreFloat4(&mSkullAnimation.Keyframes[1].RotationQuat, q1); mSkullAnimation.Keyframes[2].TimePos = 4.0f; mSkullAnimation.Keyframes[2].Translation = XMFLOAT3(7.0f, 0.0f, 0.0f); mSkullAnimation.Keyframes[2].Scale = XMFLOAT3(0.25f, 0.25f, 0.25f); XMStoreFloat4(&mSkullAnimation.Keyframes[2].RotationQuat, q2); mSkullAnimation.Keyframes[3].TimePos = 6.0f; mSkullAnimation.Keyframes[3].Translation = XMFLOAT3(0.0f, 1.0f, -10.0f); mSkullAnimation.Keyframes[3].Scale = XMFLOAT3(0.5f, 0.5f, 0.5f); XMStoreFloat4(&mSkullAnimation.Keyframes[3].RotationQuat, q3); mSkullAnimation.Keyframes[4].TimePos = 8.0f; mSkullAnimation.Keyframes[4].Translation = XMFLOAT3(-7.0f, 0.0f, 0.0f); mSkullAnimation.Keyframes[4].Scale = XMFLOAT3(0.25f, 0.25f, 0.25f); XMStoreFloat4(&mSkullAnimation.Keyframes[4].RotationQuat, q0); }
void TransformTool::Update(float dt) { HydraManager* hydra = InputSystem::get()->getHydra(); mPreviousHydraPositions[0] = mHydraPositions[0]; mPreviousHydraPositions[1] = mHydraPositions[1]; mHydraPositions[0] = hydra->getPointerPosition(0); mHydraPositions[1] = hydra->getPointerPosition(1); XMVECTOR hydraAveragePosition = (mHydraPositions[0] + mHydraPositions[1]) * 0.5f; static const int bumperBit = 1 << 7; if (mpTargetTransform != NULL && (hydra->getButtons(0) & bumperBit) && (hydra->getButtons(1) & bumperBit)) //Rotation { XMVECTOR oldOrientationVector = XMVector3Normalize(mPreviousHydraPositions[0] - mPreviousHydraPositions[1]); XMVECTOR orientationVector = XMVector3Normalize(mHydraPositions[0] - mHydraPositions[1]); if (!XMVector3Equal(oldOrientationVector, orientationVector)) { XMVECTOR rotationAxis = XMVector3Normalize(XMVector3Cross(oldOrientationVector, orientationVector)); float rotationAmount = XMVectorGetX(XMVector3Dot(oldOrientationVector, orientationVector)); //Avoid undefined values from acosf if (rotationAmount > 1.0) { rotationAmount = 1.0; } else if (rotationAmount < -1.0) { rotationAmount = -1.0; } rotationAmount = acosf(rotationAmount); XMVECTOR rotationQuaternion = XMQuaternionRotationAxis(rotationAxis, rotationAmount); //Handle rotations around the grab point XMVECTOR newTranslation = mpTargetTransform->getTranslation(); XMVECTOR translationOffset = newTranslation - hydraAveragePosition;//From point between two controllers to origin of translation newTranslation = hydraAveragePosition + XMVector3Rotate(translationOffset, rotationQuaternion); mpTargetTransform->setTranslation(newTranslation); mpTargetTransform->rotate(rotationQuaternion); } } else if (mpTargetTransform != NULL && (hydra->getButtons(1) & bumperBit)) //Translation { XMVECTOR offsetVector = mHydraPositions[1] - mPreviousHydraPositions[1]; mpTargetTransform->translate(offsetVector); } else if (mpTargetTransform != NULL && (hydra->getButtons(0) & bumperBit)) //Scaling { float oldDistance = XMVectorGetX(XMVector3Length(mPreviousHydraPositions[0] - mPreviousHydraPositions[1])); float newDistance = XMVectorGetX(XMVector3Length(mHydraPositions[0] - mHydraPositions[1])); float ratio = newDistance / oldDistance; XMVECTOR newTranslation = mpTargetTransform->getTranslation(); XMVECTOR translationOffset = newTranslation - hydraAveragePosition;//From point between two controllers to origin of translation newTranslation = hydraAveragePosition + translationOffset * ratio; mpTargetTransform->setTranslation(newTranslation); mpTargetTransform->scale(ratio); } }