//============================================================================================================= void AirPlane::Update(double time) { // ez lesz a lagg effekt if( lastinput > 0 && (time - lastinput > 0.1f) ) state = Idle; float pitch = 0, roll = 0, yaw = 0, move = 0; if( state & RollLeft ) roll = -0.2f; else if( state & RollRight ) roll = 0.2f; else if( state & PitchUp ) pitch = -0.2f; else if( state & PitchDown ) pitch = 0.2f; else if( state & YawLeft ) yaw = -0.2f; else if( state & YawRight ) yaw = 0.2f; if( state & AirPlane::Move ) move = -2; D3DXVECTOR3& p = position.current; D3DXQUATERNION& q = rotation.current; D3DXVECTOR3 x, y, z; D3DXQUATERNION t, u, v, w; x.x = q.w * q.w + q.x * q.x - q.y * q.y - q.z * q.z; x.y = 2.0f * (q.z * q.w + q.x * q.y); x.z = 2.0f * (q.x * q.z - q.y * q.w); y.x = 2.0f * (q.y * q.x - q.z * q.w); y.y = q.w * q.w + q.y * q.y - q.z * q.z - q.x * q.x; y.z = 2.0f * (q.x * q.w + q.y * q.z); z.x = 2.0f * (q.y * q.w + q.z * q.x); z.y = 2.0f * (q.z * q.y - q.x * q.w); z.z = q.w * q.w + q.z * q.z - q.x * q.x - q.y * q.y; D3DXQuaternionRotationAxis(&u, &z, roll); D3DXQuaternionRotationAxis(&v, &x, pitch); D3DXQuaternionRotationAxis(&t, &y, yaw); D3DXQuaternionMultiply(&w, &u, &v); D3DXQuaternionMultiply(&w, &w, &t); rotation.previous = q; D3DXQuaternionMultiply(&q, &q, &w); D3DXVec3Normalize(&z, &z); position.previous = p; p += z * move; }
//--------------------------------------------------------------------------- Quaternion::Quaternion (float angleX, float angleY, float angleZ) : D3DXQUATERNION(0.0f, 0.0f, 0.0f, 1.0f) { Quaternion rot; // TODO : test this ! should we reset rot first ? D3DXQuaternionRotationAxis(&rot, &Vector3::UNIT_X, angleX); *this *= rot; D3DXQuaternionRotationAxis(&rot, &Vector3::UNIT_Y, angleY); *this *= rot; D3DXQuaternionRotationAxis(&rot, &Vector3::UNIT_Z, angleZ); *this *= rot; }
void CameraManager::Update( float fpsMod ) { if ( m_pCam == NULL ) return; bool W = (GetAsyncKeyState(0x0057) & 0x8000) ? true : false; bool S = (GetAsyncKeyState(0x0053) & 0x8000) ? true : false; bool A = (GetAsyncKeyState(0x0041) & 0x8000) ? true : false; bool D = (GetAsyncKeyState(0x0044) & 0x8000) ? true : false; POINT Mouse; GetCursorPos(&Mouse); SetCursorPos(600, 600); Vec3 cAxis; D3DXVec3Cross(&cAxis, &m_pCam->Up, &m_pCam->Direction); float Speed = 1.0f; fpsMod = 0.01f; if(W) m_pCam->Position += m_pCam->Direction * (Speed * fpsMod); if(S) m_pCam->Position -= m_pCam->Direction * (Speed * fpsMod); if(A) m_pCam->Position -= cAxis * (Speed * fpsMod); if(D) m_pCam->Position += cAxis * (Speed * fpsMod); Vec4 TransformTemp; Quat RXq; D3DXQuaternionRotationAxis(&RXq, &m_pCam->Up, ( (D3DX_PI / 4.0f) / 150) * (Mouse.x - 600)); Matrix44 RX; D3DXMatrixRotationQuaternion(&RX, &RXq); D3DXVec3Transform(&TransformTemp, &m_pCam->Direction, &RX); m_pCam->Direction.x = TransformTemp.x; m_pCam->Direction.y = TransformTemp.y; m_pCam->Direction.z = TransformTemp.z; Quat RYq; D3DXVec3Cross(&cAxis, &m_pCam->Up, &m_pCam->Direction); D3DXQuaternionRotationAxis(&RYq, &cAxis, ( (D3DX_PI / 4.0f) / 150) * (Mouse.y - 600)); Matrix44 RY; D3DXMatrixRotationQuaternion(&RY, &RYq); D3DXVec3Transform(&TransformTemp, &m_pCam->Direction, &RY); m_pCam->Direction.x = TransformTemp.x; m_pCam->Direction.y = TransformTemp.y; m_pCam->Direction.z = TransformTemp.z; Vec3 Target = m_pCam->Position + m_pCam->Direction; D3DXMatrixLookAtLH(&m_pCam->View, &m_pCam->Position, &Target, &m_pCam->Up); }
void cFastGun::Shot(const D3DXVECTOR3& vDir, cObjBase* pObj) { if (m_IsCanShot) { _GETS(cSystemMgr)->CreateSound(L"Data/Sound/shot.wav", false); D3DXMATRIXA16 matRot; D3DXQUATERNION q; auto matWorld = pObj->GetWorldMatrix(); D3DXVECTOR3 vObjPos = D3DXVECTOR3(matWorld._41, matWorld._42, matWorld._43); D3DXVECTOR3 vPos; for (int n = 0; n < 2; ++n) { D3DXQuaternionRotationAxis(&q, &_GETSINGLE(cObjectMgr)->GetWorldUp(), (n * 2 - 1) * D3DX_PI * 0.25f); D3DXMatrixRotationQuaternion(&matRot, &q); D3DXVec3TransformCoord(&vPos, &vDir, &matRot); vPos += vObjPos; auto pBullet = InstantiateBullet(vDir, vPos); if (pBullet != NULL) { this->BulletTypeSetup(pBullet, pObj); } } this->SetCoolTime(); } }
int SOSetSymMotionPoint( int symmtype, CMotionPoint* srcmp, CMotionPoint* dstmp, int deginvflag ) { CMotionPoint tempmp; tempmp = *srcmp; D3DXQUATERNION symmxq; symmxq.w = tempmp.m_q.w; symmxq.x = tempmp.m_q.x; symmxq.y = tempmp.m_q.y; symmxq.z = tempmp.m_q.z; D3DXVECTOR3 symmaxis; float symmangle; D3DXQuaternionToAxisAngle( &symmxq, &symmaxis, &symmangle ); if( deginvflag != 0 ){ symmangle *= -1.0f;//!!! } switch( symmtype ){ case SYMMTYPE_XP: case SYMMTYPE_XM: case SYMMTYPE_X: symmaxis.x *= -1.0f; tempmp.m_mvx *= -1.0f; break; case SYMMTYPE_YP: case SYMMTYPE_YM: case SYMMTYPE_Y: symmaxis.y *= -1.0f; tempmp.m_mvy *= -1.0f; break; case SYMMTYPE_ZP: case SYMMTYPE_ZM: case SYMMTYPE_Z: symmaxis.z *= -1.0f; tempmp.m_mvz *= -1.0f; break; default: DbgOut( "SymmOpe : SetSymMotionPoint : symmtype error !!!\n" ); _ASSERT( 0 ); return 1; break; } D3DXQUATERNION newxq; D3DXQuaternionRotationAxis( &newxq, &symmaxis, symmangle ); tempmp.m_q.w = newxq.w; tempmp.m_q.x = newxq.x; tempmp.m_q.y = newxq.y; tempmp.m_q.z = newxq.z; *dstmp = tempmp; return 0; }
void Mesh::RotateAxis(D3DXVECTOR3 around, float angle) { D3DXQUATERNION quaternion = D3DXQUATERNION(0, 0, 0, 1); D3DXQuaternionRotationAxis(&quaternion, &around, angle); D3DXQuaternionMultiply(&this->rotQuat, &this->rotQuat, &quaternion); this->RecreateWorldMatrix(); }
void CBody::AdjustAxisVelocity(D3DXVECTOR3& axis, float radianAngle) { D3DXQUATERNION thisRotation; D3DXQuaternionRotationAxis(&thisRotation, &axis, -radianAngle); D3DXQUATERNION angularVelocityTemp = m_angularVelocity; D3DXQuaternionMultiply(&m_angularVelocity, &thisRotation, &angularVelocityTemp); }
//first attempt at an implementation - use 'force' as an impulse, and change velocities instantaneously void CRigidBody::OnCollision(const PAVECTOR* pLocation, const PAVECTOR* pForce) { D3DXVECTOR3 dxLocation = DXVector(*pLocation); D3DXVECTOR3 dxForce = DXVector(*pForce); m_velocity += dxForce / m_mass; // find the vector from the origin to the point through which the force is exerted D3DXVECTOR3 radius; // first find some multiplier A for which radius = location + A * force float A; float forceMagnitude = D3DXVec3Length(&dxForce); A = - D3DXVec3Dot(&dxLocation, &dxForce) / (forceMagnitude * forceMagnitude); radius = dxLocation + A * dxForce; if (D3DXVec3Length(&radius) < 0.001) { //the force is effectively acting directly through the COM, and is therefore purely translational return; } // now consider two sections of the mass, divided by the force. One is attmpting to turn one way, the other section attempts to turn the other way. // the plane separating the two sections is described by two vectors. One is the force, the other is perpendicular to the force and the radius. D3DXVECTOR3 rotationAxis; D3DXVec3Cross(&rotationAxis, &radius, &dxForce); // section one: the smaller section /* D3DXVECTOR3 sec1COM; float sec1Size = m_hitbox.GetSplitSection(&sec1COM, &force, &rotationAxis); if (sec1Size < 0.0001) { // the force is right on the edge of the object, and is purely rotational */ D3DXQUATERNION change; D3DXQuaternionRotationAxis(&change, &rotationAxis, D3DXVec3Length(&rotationAxis)); m_angularVelocity += change / (m_mass * GetMomentOfInertia(&PAVector(rotationAxis))); return; /* } { // a combination of translation and rotation D3DXVECTOR3 sec1Radius; } */ }
STDMETHODIMP CAtlBase::QuaternionRotationByNDir(FLOAT* x, FLOAT* y, FLOAT* z, FLOAT* w, LONG nDir) { D3DXQUATERNION rotation(*x, *y, *z, *w); FLOAT fAngle = (nDir - 192) * 2 * D3DX_PI / 256; D3DXVECTOR3 axis(0.0f, 1.0f, 0.0f); D3DXQuaternionRotationAxis(&rotation, &axis, fAngle); *x = rotation.x; *y = rotation.y; *z = rotation.z; *w = rotation.w; return S_OK; }
void quater::setRotation(const vector3& axis, double angle) { #ifdef USE_D3DFUNC D3DXQuaternionRotationAxis( *this, axis, angle); #else double fHalfAngle=( 0.5*angle ); double fSin = sin(fHalfAngle); w = cos(fHalfAngle); x = fSin*axis.x; y = fSin*axis.y; z = fSin*axis.z; #endif }
void CBody::AdjustAxisAngle(D3DXVECTOR3& axis, float radianAngle) { D3DXQUATERNION thisRotation; D3DXQuaternionRotationAxis(&thisRotation, &axis, -radianAngle); D3DXQUATERNION orientationTemp = m_orientation; D3DXQuaternionMultiply(&m_orientation, &thisRotation, &orientationTemp); /* D3DXVECTOR3 fwd, up; fwd = GetForward(); up = GetUp(); debugf("fwd: (%.0f, %.0f, %.0f)\tup: (%.0f, %.0f, %.0f)\n", fwd.x, fwd.y, fwd.z, up.x, up.y, up.z); */ }
bool Application::OnUpdate() { lcTime::Get()->Update(); m_pKeyboard->Update(); m_pMouse->Update(); lcCamera::FreeLookCamera(m_pCamera,1.0f,1.0f); m_pCamera->Update(); if(lcKeyboard::IsKeyDown(KEY_ESCAPE)) return 0; D3DXMATRIX outMat; D3DXQUATERNION invQuat; m_pScene->SetTranslate(g_kRootPosition); D3DXQUATERNION tempq; D3DXVECTOR3 tempAxis; float tempAngle; D3DXQuaternionToAxisAngle(&g_kRootRotation, &tempAxis, &tempAngle); tempAxis = -tempAxis; D3DXQuaternionRotationAxis(&tempq, &tempAxis, tempAngle); D3DXMatrixRotationQuaternion(&outMat,&tempq); m_pScene->SetRotate(outMat); if(g_bWireframe) { g_pkBox->SetPrimativeTopology(D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP); } else { g_pkBox->SetPrimativeTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); } lcRenderer::GetDeviceContext()->PSSetSamplers(0,1,&CubeSampleState); m_pScene->Update(); return m_pWindow->Tick(); }
//----------------------------------------------------------------------------- // Name: D3DUtil_GetRotationFromCursor() // Desc: Returns a quaternion for the rotation implied by the window's cursor // position. //----------------------------------------------------------------------------- D3DXQUATERNION D3DUtil_GetRotationFromCursor( HWND hWnd, FLOAT fTrackBallRadius ) { POINT pt; RECT rc; GetCursorPos( &pt ); GetClientRect( hWnd, &rc ); ScreenToClient( hWnd, &pt ); FLOAT sx = ( ( ( 2.0f * pt.x ) / (rc.right-rc.left) ) - 1 ); FLOAT sy = ( ( ( 2.0f * pt.y ) / (rc.bottom-rc.top) ) - 1 ); FLOAT sz; if( sx == 0.0f && sy == 0.0f ) return D3DXQUATERNION( 0.0f, 0.0f, 0.0f, 1.0f ); FLOAT d2 = sqrtf( sx*sx + sy*sy ); if( d2 < fTrackBallRadius * 0.70710678118654752440 ) // Inside sphere sz = sqrtf( fTrackBallRadius*fTrackBallRadius - d2*d2 ); else // On hyperbola sz = (fTrackBallRadius*fTrackBallRadius) / (2.0f*d2); // Get two points on trackball's sphere D3DXVECTOR3 p1( sx, sy, sz ); D3DXVECTOR3 p2( 0.0f, 0.0f, fTrackBallRadius ); // Get axis of rotation, which is cross product of p1 and p2 D3DXVECTOR3 vAxis; D3DXVec3Cross( &vAxis, &p1, &p2); // Calculate angle for the rotation about that axis D3DXVECTOR3 vecDiff = p2-p1; FLOAT t = D3DXVec3Length( &vecDiff ) / ( 2.0f*fTrackBallRadius ); if( t > +1.0f) t = +1.0f; if( t < -1.0f) t = -1.0f; FLOAT fAngle = 2.0f * asinf( t ); // Convert axis to quaternion D3DXQUATERNION quat; D3DXQuaternionRotationAxis( &quat, &vAxis, fAngle ); return quat; }
int CRps::CalcSymPose( TSELEM* tsptr, CModel* srcmodel, CTraQ* traq, CQuaternion* newqptr, D3DXVECTOR3* newtraptr, D3DXVECTOR3* neweulptr, D3DXVECTOR3 befeul ) { int ret; CQuaternion tmpq = traq->m_q; D3DXVECTOR3 tmptra = traq->m_tra; D3DXVECTOR3 tmpeul = traq->m_cureul; D3DXQUATERNION symmxq; symmxq.w = tmpq.w; symmxq.x = tmpq.x; symmxq.y = tmpq.y; symmxq.z = tmpq.z; D3DXVECTOR3 symmaxis; float symmangle; D3DXQuaternionToAxisAngle( &symmxq, &symmaxis, &symmangle ); symmangle *= -1.0f;//!!! symmaxis.x *= -1.0f; tmptra.x *= -1.0f; D3DXQUATERNION newxq; D3DXQuaternionRotationAxis( &newxq, &symmaxis, symmangle ); CQuaternion srcq; srcq.SetParams( newxq.w, newxq.x, newxq.y, newxq.z ); CQuaternion axisq; D3DXVECTOR3 cureul; ret = traq->QtoEul( srcmodel, srcq, befeul, 1, tsptr->jointno, &cureul, &axisq ); _ASSERT( !ret ); newqptr->SetParams( newxq.w, newxq.x, newxq.y, newxq.z ); *newtraptr = tmptra; *neweulptr = cureul; return 0; }
void RagDoll::InitRagdoll() { Release(); InitBones((Bone*)m_pRootBone); Bone* Head_End = (Bone*)D3DXFrameFind(m_pRootBone, "Head_End"); Bone* Head = (Bone*)D3DXFrameFind(m_pRootBone, "Head"); Bone* Neck = (Bone*)D3DXFrameFind(m_pRootBone, "Neck"); Bone* Pelvis = (Bone*)D3DXFrameFind(m_pRootBone, "Pelvis"); Bone* Spine = (Bone*)D3DXFrameFind(m_pRootBone, "Spine"); Bone* R_Shoulder = (Bone*)D3DXFrameFind(m_pRootBone, "Shoulder_Right"); Bone* L_Shoulder = (Bone*)D3DXFrameFind(m_pRootBone, "Shoulder_Left"); Bone* U_R_Arm = (Bone*)D3DXFrameFind(m_pRootBone, "Upper_Arm_Right"); Bone* U_L_Arm = (Bone*)D3DXFrameFind(m_pRootBone, "Upper_Arm_Left"); Bone* L_R_Arm = (Bone*)D3DXFrameFind(m_pRootBone, "Lower_Arm_Right"); Bone* L_L_Arm = (Bone*)D3DXFrameFind(m_pRootBone, "Lower_Arm_Left"); Bone* R_Hand = (Bone*)D3DXFrameFind(m_pRootBone, "Hand_Right"); Bone* L_Hand = (Bone*)D3DXFrameFind(m_pRootBone, "Hand_Left"); Bone* R_Pelvis = (Bone*)D3DXFrameFind(m_pRootBone, "Pelvis_Right"); Bone* L_Pelvis = (Bone*)D3DXFrameFind(m_pRootBone, "Pelvis_Left"); Bone* R_Thigh = (Bone*)D3DXFrameFind(m_pRootBone, "Thigh_Right"); Bone* L_Thigh = (Bone*)D3DXFrameFind(m_pRootBone, "Thigh_Left"); Bone* R_Calf = (Bone*)D3DXFrameFind(m_pRootBone, "Calf_Right"); Bone* L_Calf = (Bone*)D3DXFrameFind(m_pRootBone, "Calf_Left"); Bone* R_Foot = (Bone*)D3DXFrameFind(m_pRootBone, "Foot_Right"); Bone* L_Foot = (Bone*)D3DXFrameFind(m_pRootBone, "Foot_Left"); Bone* R_Foot_End = (Bone*)D3DXFrameFind(m_pRootBone, "Foot_Right_End"); Bone* L_Foot_End = (Bone*)D3DXFrameFind(m_pRootBone, "Foot_Left_End"); D3DXQUATERNION q, q2; D3DXQuaternionIdentity(&q); D3DXQuaternionRotationAxis(&q2, &D3DXVECTOR3(0.0f, 0.0f, 1.0f), D3DX_PI * -0.5f); //Head OBB* o01 = CreateBoneBox(Head, Head_End, D3DXVECTOR3(0.3f, 0.2f, 0.2f), q); //Right Arm OBB* o03 = CreateBoneBox(U_R_Arm, L_R_Arm, D3DXVECTOR3(0.3f, 0.12f, 0.12f), q); OBB* o04 = CreateBoneBox(L_R_Arm, R_Hand, D3DXVECTOR3(0.3f, 0.12f, 0.12f), q); //Left Arm OBB* o06 = CreateBoneBox(U_L_Arm, L_L_Arm, D3DXVECTOR3(0.3f, 0.12f, 0.12f), q); OBB* o07 = CreateBoneBox(L_L_Arm, L_Hand, D3DXVECTOR3(0.3f, 0.12f, 0.12f), q); //Spine OBB* o08 = CreateBoneBox(Spine, Neck, D3DXVECTOR3(0.5f, 0.35f, 0.15f), q); //Right Leg OBB* o09 = CreateBoneBox(R_Thigh, R_Calf, D3DXVECTOR3(0.4f, 0.15f, 0.15f), q); OBB* o10 = CreateBoneBox(R_Calf, R_Foot, D3DXVECTOR3(0.4f, 0.14f, 0.14f), q); OBB* o11 = CreateBoneBox(R_Foot, R_Foot_End, D3DXVECTOR3(0.15f, 0.06f, 0.12f), q2); //Left Leg OBB* o12 = CreateBoneBox(L_Thigh, L_Calf, D3DXVECTOR3(0.4f, 0.15f, 0.15f), q); OBB* o13 = CreateBoneBox(L_Calf, L_Foot, D3DXVECTOR3(0.4f, 0.14f, 0.14f), q); OBB* o14 = CreateBoneBox(L_Foot, L_Foot_End, D3DXVECTOR3(0.15f, 0.06f, 0.12f), q2); //Constraints CreateTwistCone(Neck, o01, o08, D3DX_PI * 0.15f, D3DXVECTOR3(0.0f, 0.0f, D3DX_PI * 0.5f), D3DXVECTOR3(0.0f, 0.0f, D3DX_PI * 0.5f)); CreateTwistCone(L_Pelvis, o08, o12, D3DX_PI * 0.5f, D3DXVECTOR3(0.3f, D3DX_PI * 0.5f, -D3DX_PI * 0.5f), D3DXVECTOR3(0.0f, 0.0f, D3DX_PI * 0.5f)); CreateHinge(L_Calf, o12, o13, 0.0f, -2.0f, D3DXVECTOR3(0.0f, 0.0f, D3DX_PI * 0.5f), D3DXVECTOR3(0.0f, 0.0f, D3DX_PI * 0.5f)); CreateHinge(L_Foot, o13, o14, 1.5f, 1.0f, D3DXVECTOR3(0.0f, 0.0f, D3DX_PI * 0.5f), D3DXVECTOR3(0.0f, 0.0f, D3DX_PI * 0.5f)); CreateTwistCone(R_Pelvis, o08, o09, D3DX_PI * 0.5f, D3DXVECTOR3(0.3f, D3DX_PI * 0.5f, -D3DX_PI * 0.5f), D3DXVECTOR3(0.0f, 0.0f, D3DX_PI * 0.5f)); CreateHinge(R_Calf, o09, o10, 0.0f, -2.0f, D3DXVECTOR3(0.0f, 0.0f, D3DX_PI * 0.5f), D3DXVECTOR3(0.0f, 0.0f, D3DX_PI * 0.5f)); CreateHinge(R_Foot, o10, o11, 1.5f, 1.0f, D3DXVECTOR3(0.0f, 0.0f, D3DX_PI * 0.5f), D3DXVECTOR3(0.0f, 0.0f, D3DX_PI * 0.5f)); CreateTwistCone(U_L_Arm, o08, o06, D3DX_PI * 0.6f, D3DXVECTOR3(0.0f, D3DX_PI * 0.75f, D3DX_PI * 0.0f), D3DXVECTOR3(0.0f, 0.0f, 0.0f)); CreateHinge(L_L_Arm, o06, o07, 2.0f, 0.0f, D3DXVECTOR3(0.0f, 0.0f, D3DX_PI * 0.5f), D3DXVECTOR3(0.0f, 0.0f, D3DX_PI * 0.5f)); CreateTwistCone(U_R_Arm, o08, o03, D3DX_PI * 0.6f, D3DXVECTOR3(0.0f, D3DX_PI * 0.75f, D3DX_PI * 0.0f), D3DXVECTOR3(D3DX_PI, 0.0f, 0.0f)); CreateHinge(L_R_Arm, o03, o04, 2.0f, 0.0f, D3DXVECTOR3(0.0f, 0.0f, -D3DX_PI * 0.5f), D3DXVECTOR3(0.0f, 0.0f, -D3DX_PI * 0.5f)); //Assign Pelvis bone to Spine OBB Pelvis->m_pObb = o08; D3DXVECTOR3 PelvisPos(Pelvis->CombinedTransformationMatrix(3, 0), Pelvis->CombinedTransformationMatrix(3, 1), Pelvis->CombinedTransformationMatrix(3, 2)); Pelvis->m_pivot = o08->SetPivot(PelvisPos); }
bool bgParserASE::ReadNodeInfo(int iNumObj) { bool hr = true; TCHAR szWordArray[2][MAX_PATH * 4]; // 월드행렬 정보 저장 IF_FALSE_RETURN(FindWord(_T("*NODE_NAME"))); ZeroMemory(m_pModel->m_ObjectList[iNumObj].szNodeName, MAX_PATH * 4); m_pszToken = _tcstok(m_szLine, _T("\"")); m_pszToken = _tcstok(NULL, _T("\"")); _tcscpy(m_pModel->m_ObjectList[iNumObj].szNodeName, m_pszToken); _tcscpy(szWordArray[0], _T("*NODE_PARENT")); _tcscpy(szWordArray[1], _T("*NODE_TM")); switch (FindWordArray(szWordArray, 2)) { case 0: // *NODE_PARENT 부모 노드가 있다면 ============================ { ZeroMemory(m_pModel->m_ObjectList[iNumObj].szNodeParent, MAX_PATH * 4); m_pszToken = _tcstok(m_szLine, _T("\"")); m_pszToken = _tcstok(NULL, _T("\"")); _tcscpy(m_pModel->m_ObjectList[iNumObj].szNodeParent, m_pszToken); IF_FALSE_RETURN(FindWord(_T("*NODE_TM"))); } break; case 1: // *NODE_TM 부모 노드가 없다면 ============================ { ZeroMemory(m_pModel->m_ObjectList[iNumObj].szNodeParent, MAX_PATH * 4); m_pModel->m_ObjectList[iNumObj].pNodeParent = NULL; } break; case -1: // 찾는 단어 없음 ================================================= default: // 나머지 (배열 요소가 2개이므로 나올 수 없음) return false; break; } IF_FALSE_RETURN(FindWord(_T("*TM_ROW0"))); _stscanf(m_szLine, _T("%s %f%f%f"), m_szWord, &m_pModel->m_ObjectList[iNumObj].nodeTM.matWorld._11, &m_pModel->m_ObjectList[iNumObj].nodeTM.matWorld._13, &m_pModel->m_ObjectList[iNumObj].nodeTM.matWorld._12); m_pModel->m_ObjectList[iNumObj].nodeTM.matWorld._14 = 0.0f; IF_FALSE_RETURN(FindWord(_T("*TM_ROW1"))); _stscanf(m_szLine, _T("%s %f%f%f"), m_szWord, &m_pModel->m_ObjectList[iNumObj].nodeTM.matWorld._31, &m_pModel->m_ObjectList[iNumObj].nodeTM.matWorld._33, &m_pModel->m_ObjectList[iNumObj].nodeTM.matWorld._32); m_pModel->m_ObjectList[iNumObj].nodeTM.matWorld._34 = 0.0f; IF_FALSE_RETURN(FindWord(_T("*TM_ROW2"))); _stscanf(m_szLine, _T("%s %f%f%f"), m_szWord, &m_pModel->m_ObjectList[iNumObj].nodeTM.matWorld._21, &m_pModel->m_ObjectList[iNumObj].nodeTM.matWorld._23, &m_pModel->m_ObjectList[iNumObj].nodeTM.matWorld._22); m_pModel->m_ObjectList[iNumObj].nodeTM.matWorld._24 = 0.0f; IF_FALSE_RETURN(FindWord(_T("*TM_ROW3"))); _stscanf(m_szLine, _T("%s %f%f%f"), m_szWord, &m_pModel->m_ObjectList[iNumObj].nodeTM.matWorld._41, &m_pModel->m_ObjectList[iNumObj].nodeTM.matWorld._43, &m_pModel->m_ObjectList[iNumObj].nodeTM.matWorld._42); m_pModel->m_ObjectList[iNumObj].nodeTM.matWorld._44 = 1.0f; // 인버스 매트릭스 확인 코드 D3DXVECTOR3 v0, v1, v2, v3; v0 = m_pModel->m_ObjectList[iNumObj].nodeTM.matWorld.m[0]; v1 = m_pModel->m_ObjectList[iNumObj].nodeTM.matWorld.m[1]; v2 = m_pModel->m_ObjectList[iNumObj].nodeTM.matWorld.m[2]; D3DXVec3Cross(&v3, &v1, &v2); if (D3DXVec3Dot(&v3, &v0) < 0.0f) { D3DXMATRIX matW; D3DXMatrixScaling(&matW, -1.0f, -1.0f, -1.0f); D3DXMatrixMultiply(&m_pModel->m_ObjectList[iNumObj].nodeTM.matWorld, &m_pModel->m_ObjectList[iNumObj].nodeTM.matWorld, &matW); } // 분해된 월드행렬 정보 저장 float fAngle; D3DXQUATERNION qRotate; D3DXVECTOR3 vVector, vAxis; D3DXMATRIX matRotation, matRotationInv; IF_FALSE_RETURN(FindWord(_T("*TM_POS"))); _stscanf(m_szLine, _T("%s %f%f%f"), m_szWord, &vVector.x, &vVector.z, &vVector.y); m_pModel->m_ObjectList[iNumObj].nodeTM.vPos = vVector; D3DXMatrixTranslation(&m_pModel->m_ObjectList[iNumObj].matWorldPos, vVector.x, vVector.y, vVector.z); IF_FALSE_RETURN(FindWord(_T("*TM_ROTAXIS"))); _stscanf(m_szLine, _T("%s %f%f%f"), m_szWord, &vVector.x, &vVector.z, &vVector.y); m_pModel->m_ObjectList[iNumObj].nodeTM.vRotAxis = vVector; IF_FALSE_RETURN(FindWord(_T("*TM_ROTANGLE"))); _stscanf(m_szLine, _T("%s %f"), m_szWord, &fAngle); m_pModel->m_ObjectList[iNumObj].nodeTM.fRotAngle = fAngle; D3DXQuaternionRotationAxis(&qRotate, &vVector, fAngle); D3DXMatrixRotationQuaternion(&m_pModel->m_ObjectList[iNumObj].matWorldRot, &qRotate); IF_FALSE_RETURN(FindWord(_T("*TM_SCALE"))); _stscanf(m_szLine, _T("%s %f%f%f"), m_szWord, &vVector.x, &vVector.z, &vVector.y); m_pModel->m_ObjectList[iNumObj].nodeTM.vScale = vVector; D3DXMatrixScaling(&m_pModel->m_ObjectList[iNumObj].matWorldScl, vVector.x, vVector.y, vVector.z); IF_FALSE_RETURN(FindWord(_T("*TM_SCALEAXIS"))); _stscanf(m_szLine, _T("%s %f%f%f"), m_szWord, &vAxis.x, &vAxis.z, &vAxis.y); m_pModel->m_ObjectList[iNumObj].nodeTM.vScaleAxis = vAxis; IF_FALSE_RETURN(FindWord(_T("*TM_SCALEAXISANG"))); _stscanf(m_szLine, _T("%s %f"), m_szWord, &fAngle); m_pModel->m_ObjectList[iNumObj].nodeTM.fScaleAxisAngle = fAngle; D3DXMatrixRotationAxis(&matRotation, &vAxis, fAngle); D3DXMatrixInverse(&matRotationInv, NULL, &matRotation); m_pModel->m_ObjectList[iNumObj].matWorldScl = matRotationInv * m_pModel->m_ObjectList[iNumObj].matWorldScl * matRotation; IF_FALSE_RETURN(FindWord(_T("}"))); // NODE_TM 탈출 return hr; }
bool bgParserASE::ReadTMAnimation(int iNumObj) { bool hr = true; TCHAR szWordArray[2][MAX_PATH * 4]; TCHAR szWordTrack[4][MAX_PATH * 4]; AnimTrackInfo animData; bool bAnimEnd, bTrackEnd; m_pModel->m_ObjectList[iNumObj].Anim.PosTrack.clear(); m_pModel->m_ObjectList[iNumObj].Anim.RotTrack.clear(); m_pModel->m_ObjectList[iNumObj].Anim.SclTrack.clear(); _tcscpy(szWordTrack[0], _T("*CONTROL_POS_TRACK")); _tcscpy(szWordTrack[1], _T("*CONTROL_ROT_TRACK")); _tcscpy(szWordTrack[2], _T("*CONTROL_SCALE_TRACK")); _tcscpy(szWordTrack[3], _T("}")); bAnimEnd = false; while (bAnimEnd == false) { switch (FindWordArray(szWordTrack, 4)) { case 0: // *CONTROL_POS_TRACK ========================================== { _tcscpy(szWordArray[0], _T("*CONTROL_POS_SAMPLE")); _tcscpy(szWordArray[1], _T("}")); animData.Init(); bTrackEnd = false; while (bTrackEnd == false) { switch (FindWordArray(szWordArray, 2)) { case 0: // *CONTROL_POS_SAMPLE ---------------------------- { // 트랙 추가 _stscanf(m_szLine, _T("%s %d %f%f%f"), m_szWord, &animData.iTick, &animData.vVector.x, &animData.vVector.z, &animData.vVector.y); m_pModel->m_ObjectList[iNumObj].Anim.PosTrack.push_back(animData); continue; } break; case 1: // } ---------------------------- { // 트랙 종료 처리 bTrackEnd = true; } break; case -1: // 찾는 단어 없음 ----------------------------------- default: // 나머지 (배열 요소가 2개이므로 나올 수 없음) return false; break; } } } break; case 1: // *CONTROL_ROT_TRACK ========================================== { _tcscpy(szWordArray[0], _T("*CONTROL_ROT_SAMPLE")); _tcscpy(szWordArray[1], _T("}")); animData.Init(); bTrackEnd = false; while (bTrackEnd == false) { switch (FindWordArray(szWordArray, 2)) { case 0: // *CONTROL_ROT_SAMPLE ---------------------------- { // 트랙 추가 _stscanf(m_szLine, _T("%s %d %f%f%f %f"), m_szWord, &animData.iTick, &animData.qRotate.x, &animData.qRotate.z, &animData.qRotate.y, &animData.qRotate.w); D3DXQuaternionRotationAxis(&animData.qRotate, &D3DXVECTOR3(animData.qRotate.x, animData.qRotate.y, animData.qRotate.z), animData.qRotate.w); int iRotTrackSize = m_pModel->m_ObjectList[iNumObj].Anim.RotTrack.size(); if (iRotTrackSize) { D3DXQuaternionMultiply(&animData.qRotate, &m_pModel->m_ObjectList[iNumObj].Anim.RotTrack[iRotTrackSize - 1].qRotate, &animData.qRotate); } m_pModel->m_ObjectList[iNumObj].Anim.RotTrack.push_back(animData); continue; } break; case 1: // } ---------------------------- { // 트랙 종료 처리 bTrackEnd = true; } break; case -1: // 찾는 단어 없음 ----------------------------------- default: // 나머지 (배열 요소가 2개이므로 나올 수 없음) return false; break; } } } break; case 2: // *CONTROL_SCALE_TRACK ======================================== { _tcscpy(szWordArray[0], _T("*CONTROL_SCALE_SAMPLE")); _tcscpy(szWordArray[1], _T("}")); animData.Init(); bTrackEnd = false; while (bTrackEnd == false) { switch (FindWordArray(szWordArray, 2)) { case 0: // *CONTROL_SCALE_SAMPLE ------------------------ { // 트랙 추가 _stscanf(m_szLine, _T("%s %d %f%f%f %f%f%f%f"), m_szWord, &animData.iTick, &animData.vVector.x, &animData.vVector.z, &animData.vVector.y, &animData.qRotate.x, &animData.qRotate.z, &animData.qRotate.y, &animData.qRotate.w); D3DXQuaternionRotationAxis(&animData.qRotate, &D3DXVECTOR3(animData.qRotate.x, animData.qRotate.y, animData.qRotate.z), animData.qRotate.w); m_pModel->m_ObjectList[iNumObj].Anim.SclTrack.push_back(animData); continue; } break; case 1: // } ---------------------------- { // 트랙 종료 처리 bTrackEnd = true; } break; case -1: // 찾는 단어 없음 ----------------------------------- default: // 나머지 (배열 요소가 2개이므로 나올 수 없음) return false; break; } } } break; case 3: // } ======================================================== { // 애니메이션 종료 처리 bAnimEnd = true; } break; case -1: // 찾는 단어 없음 =============================================== default: // 나머지 (배열 요소가 4개이므로 나올 수 없음) return false; break; } } return hr; }
bool CPythonItem::TGroundItemInstance::Update() { if (bAnimEnded) return false; if (dwEndTime < CTimer::Instance().GetCurrentMillisecond()) { ThingInstance.SetRotationQuaternion(qEnd); /*D3DXVECTOR3 v3Adjust = -v3Center; D3DXMATRIX mat; D3DXMatrixRotationYawPitchRoll(&mat, D3DXToRadian(rEnd.y), D3DXToRadian(rEnd.x), D3DXToRadian(rEnd.z)); D3DXVec3TransformCoord(&v3Adjust,&v3Adjust,&mat);*/ D3DXQUATERNION qAdjust(-v3Center.x, -v3Center.y, -v3Center.z, 0.0f); D3DXQUATERNION qc; D3DXQuaternionConjugate(&qc, &qEnd); D3DXQuaternionMultiply(&qAdjust,&qAdjust,&qEnd); D3DXQuaternionMultiply(&qAdjust,&qc,&qAdjust); ThingInstance.SetPosition(v3EndPosition.x+qAdjust.x, v3EndPosition.y+qAdjust.y, v3EndPosition.z+qAdjust.z); //ThingInstance.Update(); bAnimEnded = true; __PlayDropSound(eDropSoundType, v3EndPosition); } else { DWORD time = CTimer::Instance().GetCurrentMillisecond() - dwStartTime; DWORD etime = dwEndTime - CTimer::Instance().GetCurrentMillisecond(); float rate = time * 1.0f / (dwEndTime - dwStartTime); D3DXVECTOR3 v3NewPosition=v3EndPosition;// = rate*(v3EndPosition - v3StartPosition) + v3StartPosition; v3NewPosition.z += 100-100*rate*(3*rate-2);//-100*(rate-1)*(3*rate+2); D3DXQUATERNION q; D3DXQuaternionRotationAxis(&q, &v3RotationAxis, etime * 0.03f *(-1+rate*(3*rate-2))); //ThingInstance.SetRotation(rEnd.y + etime*rStart.y, rEnd.x + etime*rStart.x, rEnd.z + etime*rStart.z); D3DXQuaternionMultiply(&q,&qEnd,&q); ThingInstance.SetRotationQuaternion(q); D3DXQUATERNION qAdjust(-v3Center.x, -v3Center.y, -v3Center.z, 0.0f); D3DXQUATERNION qc; D3DXQuaternionConjugate(&qc, &q); D3DXQuaternionMultiply(&qAdjust,&qAdjust,&q); D3DXQuaternionMultiply(&qAdjust,&qc,&qAdjust); ThingInstance.SetPosition(v3NewPosition.x+qAdjust.x, v3NewPosition.y+qAdjust.y, v3NewPosition.z+qAdjust.z); /*D3DXVECTOR3 v3Adjust = -v3Center; D3DXMATRIX mat; D3DXMatrixRotationYawPitchRoll(&mat, D3DXToRadian(rEnd.y + etime*rStart.y), D3DXToRadian(rEnd.x + etime*rStart.x), D3DXToRadian(rEnd.z + etime*rStart.z)); D3DXVec3TransformCoord(&v3Adjust,&v3Adjust,&mat); //Tracef("%f %f %f\n",v3Adjust.x,v3Adjust.y,v3Adjust.z); v3NewPosition += v3Adjust; ThingInstance.SetPosition(v3NewPosition.x, v3NewPosition.y, v3NewPosition.z);*/ } ThingInstance.Transform(); ThingInstance.Deform(); return !bAnimEnded; }
void SpaceShip::Update(float RelativeTime) { m_RelativeTime = RelativeTime; if (!m_Moving) { // Allow friction to slow the ship down float NewSpeed = m_Speed - m_Speed * m_Acceleration * m_RelativeTime * 0.2f; if (m_Speed > 0) m_Speed = (NewSpeed < 0 ? 0 : NewSpeed); else m_Speed = (NewSpeed > 0 ? 0 : NewSpeed); } if (!m_Turning) { // Rotate back to normal float NewRot = abs(m_RotZ) - 0.03f * m_RelativeTime; if (NewRot < 0) NewRot = 0; if (m_RotZ > 0) m_RotZ = NewRot; else m_RotZ = -NewRot; } // Set y-rotation m_RotY -= 0.01f * m_RotZ * m_Speed * m_RelativeTime; // Rotate ship D3DXMATRIX matrix; D3DXQuaternionRotationAxis(&m_QuatY, new D3DXVECTOR3(0, 1, 0), m_RotY); D3DXQuaternionRotationAxis(&m_QuatZ, new D3DXVECTOR3(0, 0, 1), m_RotZ); D3DXVECTOR4 vec = D3DXVECTOR4(0, 0, 1, 1); D3DXVec4Transform(&vec, &vec, D3DXMatrixRotationQuaternion(&matrix, &m_QuatY)); D3DXVec4Normalize(&vec, &vec); // Move ship Vector3D OldPosition = m_Position; D3DXVECTOR4 newvec = vec * m_Speed * m_RelativeTime; m_Position += Vector3D(newvec.x, newvec.y, newvec.z); FollowTerrain(); // Compare current position height and new position height float Scale = 1.0f; if (OldPosition.Y > m_Position.Y) // Ship is going down Scale += (OldPosition.Y - m_Position.Y); else if (OldPosition.Y < m_Position.Y) // Ship is going up Scale -= (m_Position.Y - OldPosition.Y) * 0.1f; // Move ship vec *= m_Speed * Scale * m_RelativeTime; m_Position = OldPosition + Vector3D(vec.x, vec.y, vec.z); // Set kilometres per hour m_NextKPH++; if (m_NextKPH == m_NumKPH) m_NextKPH = 0; m_KPH[m_NextKPH] = abs((int)(m_Speed * Scale * 100.0f)); FollowTerrain(); // See if the player is going off the edge Rect bounds = m_Terrain->GetBounds(); if (m_Position.X < bounds.X) m_Position.X = bounds.X; else if (m_Position.X > bounds.X + bounds.W) m_Position.X = bounds.X + bounds.W; if (m_Position.Z < bounds.Y) m_Position.Z = bounds.Y; else if (m_Position.Z > bounds.Y + bounds.H) m_Position.Z = bounds.Y + bounds.H; // Update camera UpdateCamera(); // Set mesh position Matrix pos, rot, out; Quaternion quat = m_QuatZ * m_QuatY; D3DXMatrixTranslation(&pos, m_Position.X, m_Position.Y, m_Position.Z); D3DXMatrixRotationQuaternion(&rot, &quat); out = rot * pos; m_Mesh->SetWorldMatrix(&out); }
void Tank::Update(Input* input, float time, QuadTree *m_QuadTree){ int deltaX, deltaY; input->GetMouseDelta(deltaX, deltaY); m_tankState->SetTime(time); m_tankState->ApplyForce(D3DXVECTOR3(0.0f, 0.0f, forward)); forward = 0; m_tankState->SetYaw(turn * time); yaw -= turn * time; turn = 0; D3DXVECTOR3 position = *getTankState()->GetPosition(), vgarbage, normal5; float height; m_QuadTree->GetHeightAtPosition(position.x, position.z, height, normal5); float netforce = -0.00098f; float y = m_tankState->GetPosition()->y; if (y-(height+17) < 0) { netforce -= (y-(height+17)) * 0.000065f; } m_tankState->ApplyForce(D3DXVECTOR3(0,netforce,0)); //m_turretState->SetPitch(deltaY*0.01f);*/ //m_turretState->SetYaw(rotation); D3DXQUATERNION quat = *m_tankState->GetRotation(); D3DXQUATERNION inverse; D3DXQuaternionInverse(&inverse, &quat); D3DXQUATERNION temp; D3DXVECTOR3 output; float garbage; temp = quat * D3DXQUATERNION(FRONTRIGHT.x, FRONTRIGHT.y, FRONTRIGHT.z, 0.0f) * inverse; D3DXQuaternionToAxisAngle(&temp, &output, &garbage); m_frontRight = *m_tankState->GetPosition() + output; temp = quat * D3DXQUATERNION(FRONTLEFT.x, FRONTLEFT.y, FRONTLEFT.z, 0.0f) * inverse; D3DXQuaternionToAxisAngle(&temp, &output, &garbage); m_frontLeft = *m_tankState->GetPosition() + output; temp = quat * D3DXQUATERNION(REARLEFT.x, REARLEFT.y, REARLEFT.z, 0.0f) * inverse; D3DXQuaternionToAxisAngle(&temp, &output, &garbage); m_rearLeft = *m_tankState->GetPosition() + output; temp = quat * D3DXQUATERNION(REARRIGHT.x, REARRIGHT.y, REARRIGHT.z, 0.0f) * inverse; D3DXQuaternionToAxisAngle(&temp, &output, &garbage); m_rearRight = *m_tankState->GetPosition() + output; temp = quat * D3DXQUATERNION(CENTER.x, CENTER.y, CENTER.z, 0.0f) * inverse; D3DXQuaternionToAxisAngle(&temp, &output, &garbage); m_center = *m_tankState->GetPosition() + output; // Get the height of the triangle that is directly underneath the given tank position. //result = m_QuadTree->GetHeightAtPosition(position.x, position.z, height, vgarbage); //if(result) { // If there was a triangle under the tank then position the tank just above it by one unit. // getTankState()->SetPosition(D3DXVECTOR3(position.x,m_tankState->GetPosition()->y, position.z)); //} int count = 5; //D3DXVECTOR3 normal1, normal2, normal3, normal4, normal5; //result = m_QuadTree->GetHeightAtPosition(m_frontRight.x, m_frontRight.z, height, normal1); //if(!result) { // normal1 = D3DXVECTOR3(0.0f, 0.0f, 0.0f); // count--; //} //result = m_QuadTree->GetHeightAtPosition(m_frontLeft.x, m_frontLeft.z, height, normal2); //if(!result) { // normal2 = D3DXVECTOR3(0.0f, 0.0f, 0.0f); // count--; //} //result = m_QuadTree->GetHeightAtPosition(m_rearRight.x, m_rearRight.z, height, normal3); //if(!result) { // normal3 = D3DXVECTOR3(0.0f, 0.0f, 0.0f); // count--; //} //result = m_QuadTree->GetHeightAtPosition(m_rearLeft.x, m_rearLeft.z, height, normal4); //if(!result) { // normal4 = D3DXVECTOR3(0.0f, 0.0f, 0.0f); // count--; //} //result = m_QuadTree->GetHeightAtPosition(m_center.x, m_center.z, height, normal5); //if(!result) { // normal5 = D3DXVECTOR3(0.0f, 0.0f, 0.0f); // count--; //} D3DXVECTOR3 line3; if (count > 0) line3 = normal5; //line3 = (normal1+normal2+normal3+normal4+normal5)/float(count); else line3 = *m_tankState->GetUp(); float angle = acos(D3DXVec3Dot(&line3, m_tankState->GetUp()));// assume normalized vectors /(D3DXVec3Length(&line3)*D3DXVec3Length(m_tankState->getUp()))); angle /= 15.0f;// * time; //if (angle > 0.015f) //{ D3DXVECTOR3 cross; D3DXVec3Cross(&cross, &line3, m_tankState->GetUp()); D3DXVec3Normalize(&cross, &cross); D3DXQUATERNION quaternion; D3DXQuaternionRotationAxis(&quaternion, &cross, -angle); m_tankState->multiplyOrientation(&quaternion); //} m_tankState->Update(); D3DXQUATERNION orien; D3DXVECTOR3 slope, forward, turretProj; D3DXVec3Cross(&slope, m_tankState->GetUp(), &D3DXVECTOR3(0, 1, 0)); D3DXVec3Normalize(&slope, &slope); D3DXVec3Cross(&forward, m_tankState->GetUp(), &slope); D3DXVec3Normalize(&forward, &forward); D3DXVec3Cross(&turretProj, m_tankState->GetUp(), m_turretState->GetForward()); D3DXVec3Normalize(&turretProj, &turretProj); D3DXVec3Cross(&turretProj, m_tankState->GetUp(), &turretProj); D3DXVec3Normalize(&turretProj, &turretProj); float projangle = acos(abs(D3DXVec3Dot(&turretProj, &forward))); if (D3DXVec3Dot(&turretProj, &forward) < 0) projangle = float(D3DX_PI - projangle); float slopeangle = acos(abs(D3DXVec3Dot(&D3DXVECTOR3(0, 1, 0), &forward))); slopeangle = float(D3DX_PI/2 - slopeangle); float pitchOffset = (1 - cos(projangle)) * slopeangle; D3DXQuaternionRotationYawPitchRoll(&orien, yaw, pitch - pitchOffset, 0); orien = orien * *m_tankState->GetRotation(); m_turretState->SetOrientation(&orien); m_turretState->Update(); m_Bullet->Update(time); }
void GGbsModel::SingleAniFrame() { D3DXMATRIX matWldTrans; D3DXMATRIX matWldRotate; D3DXMATRIX matWldScale; D3DXMatrixIdentity(&matWldTrans); D3DXMatrixIdentity(&matWldRotate); D3DXMatrixIdentity(&matWldScale); m_fTickFrame += g_fSecPerFrame * m_fFrameSpeed *m_fTickPerFrame; if (m_fTickFrame >= m_fLastFrame * m_fTickPerFrame /*마지막 프레임 틱수*/) { m_fTickFrame = 0.0f; } if (m_vGeomObj[0].get()->m_bHasAniTrack) { //Translation if (m_vGeomObj[0].get()->m_vPosTrack.size() != 0) { GAnimTrack* pStartTrack = NULL; GAnimTrack* pEndTrack = NULL; //현재 Tick이 어디인지 찾자. GetAnimationTrack(m_fTickFrame, &pStartTrack, &pEndTrack, ANITRACK_TYPE_POS); //애니메이션 보간. D3DXVECTOR3 vResultVector; D3DXVECTOR3 vP1 = pStartTrack->vecVector; D3DXVECTOR3 vP2 = pEndTrack->vecVector; float fTValue = (m_fTickFrame - pStartTrack->iTick) / (pEndTrack->iTick - pStartTrack->iTick); D3DXVec3Lerp(&vResultVector, &vP1, &vP2, fTValue); //T행렬 값 대입 matWldTrans._41 = vResultVector.x; matWldTrans._42 = vResultVector.y; matWldTrans._43 = vResultVector.z; } //Rotation if (m_vGeomObj[0].get()->m_vRotTrack.size() != 0) { GAnimTrack* pStartTrack = NULL; GAnimTrack* pEndTrack = NULL; D3DXQUATERNION qR; //현재 Tick이 어디인지 찾자. GetAnimationTrack(m_fTickFrame, &pStartTrack, &pEndTrack, ANITRACK_TYPE_ROT); //사원수간의 보간.. if (pStartTrack == NULL) { qR = m_vGeomObj[0].get()->m_qRotation; float fTValue = (m_fTickFrame - 0) / (pEndTrack->iTick - 0); D3DXQuaternionSlerp(&qR, &qR, &pEndTrack->qRotate, fTValue); } else if (pEndTrack == NULL) { qR = m_vGeomObj[0].get()->m_vRotTrack[m_vGeomObj[0].get()->m_vRotTrack.size() - 1].get()->qRotate; float fTValue = ((m_fTickFrame - pStartTrack->iTick) / (m_fFrameSpeed*m_fTickPerFrame)); D3DXQuaternionSlerp(&qR, &qR, &qR, fTValue); } else { qR = pStartTrack->qRotate; float fTValue = (m_fTickFrame - pStartTrack->iTick) / (pEndTrack->iTick - pStartTrack->iTick); D3DXQuaternionSlerp(&qR, &qR, &pEndTrack->qRotate, fTValue); } //사원수에서 행렬로 변환. D3DXMatrixRotationQuaternion(&matWldRotate, &qR);// 사원수에서 행렬로 변환 } //Scale if (m_vGeomObj[0].get()->m_vSclTrack.size() != 0) { GAnimTrack* pStartTrack = NULL; GAnimTrack* pEndTrack = NULL; D3DXMATRIX matScaleRot, matInvScaleRot; D3DXMatrixIdentity(&matScaleRot); D3DXMatrixIdentity(&matInvScaleRot); D3DXQUATERNION qS; float fStartTick = 0.0f, fEndTick = 0.0f; D3DXVECTOR3 vScale(m_vGeomObj[0].get()->m_matWldScale._11, m_vGeomObj[0].get()->m_matWldScale._22, m_vGeomObj[0].get()->m_matWldScale._33); //현재 Tick이 어디인지 찾자. GetAnimationTrack(m_fTickFrame, &pStartTrack, &pEndTrack, ANITRACK_TYPE_SCL); //신축트랙 보간 if (pStartTrack == NULL) { //vScale = m_vGeomObj[0].get()->m_vecTM_SCALE; D3DXQuaternionRotationAxis(&qS, &m_vGeomObj[0].get()->m_vecTM_SCALE_AXIS, m_vGeomObj[0].get()->m_fTM_SCALEAXISANG); fStartTick = 0.0f; fEndTick = pEndTrack->iTick; } else if (pEndTrack == NULL) { vScale = pStartTrack->vecVector; qS = pStartTrack->qRotate; fStartTick = pStartTrack->iTick; fEndTick = pStartTrack->iTick + (m_fFrameSpeed*m_fTickPerFrame); } else { vScale = pStartTrack->vecVector; qS = pStartTrack->qRotate; fStartTick = pStartTrack->iTick; fEndTick = pEndTrack->iTick; } float fTValue = (m_fTickFrame - fStartTick) / (fEndTick - fStartTick); D3DXVec3Lerp(&vScale, &vScale, &pEndTrack->vecVector, fTValue); D3DXQuaternionSlerp(&qS, &qS, &pEndTrack->qRotate, fTValue); //사원수 -> 행렬로 변환등... D3DXMatrixScaling(&matWldScale, vScale.x, vScale.y, vScale.z); D3DXMatrixRotationQuaternion(&matScaleRot, &qS); D3DXMatrixInverse(&matInvScaleRot, NULL, &matScaleRot); matWldScale = matInvScaleRot * matWldScale * matScaleRot; } m_vGeomObj[0].get()->m_matCalculation = matWldScale * matWldRotate * matWldTrans; } }
inline void __Quaternion::RotationAxis(const __Vector3& v, float fRadian) { D3DXQuaternionRotationAxis(this, &v, fRadian); }
// // 오브젝트를 움직이는데 필요한 메시지를 발생 // int CWndWorld::ControlGround( DWORD dwMessage, CPoint point ) { bool fCastCancel = false; int nMsg = 0; BOOL bTempKey, bSit; // ,bCombatKey, bFlyKey BOOL bUp, bDown, bLeft, bRight, bSpace, bBoard, bLForward = FALSE, bRForward = FALSE; BOOL bWalk; static BOOL s_bWalk2 = 0; CMover* pMover = CMover::GetActiveMover(); CWndChat* pWndChat = (CWndChat*) g_WndMng.GetApplet( APP_COMMUNICATION_CHAT ); BOOL bWhisper = g_bKeyTable['R']; if( pWndChat && bWhisper ) { if( 0 < strlen( g_Neuz.m_szWhisperName ) ) { CString strWhisper; strWhisper.Format( "/whisper %s ", g_Neuz.m_szWhisperName ); pWndChat->SetFocus(); CWndEditChat* pWndEdit = &pWndChat->m_wndEdit; pWndEdit->SetString( strWhisper ); pWndEdit->SetFocus(); g_bKeyTable['R'] = FALSE; } } // 전진/후진/스톱 CWndBase* pWndBaseFocus = (CWndBase*) g_WndMng.GetFocusWnd(); if( g_Neuz.m_bActiveNeuz == FALSE || ( pWndChat && pWndBaseFocus && pWndBaseFocus == pWndChat ) ) { g_bKeyTable[g_Neuz.Key.chUp] = FALSE;// | m_bRButtonDown; g_bKeyTable[g_Neuz.Key.chLeft] = FALSE; g_bKeyTable['S'] = FALSE; g_bKeyTable['D'] = FALSE; g_bKeyTable['Q'] = FALSE; g_bKeyTable['E'] = FALSE; } bUp = g_bKeyTable[g_Neuz.Key.chUp]; // | m_bRButtonDown; bDown = g_bKeyTable['S']; #ifdef __BS_ADJUST_SYNC //gmpbigsun : 키보드 조작중에는 마우스이동 불가 if( bUp || bDown ) m_bLButtonDown = FALSE; #endif if( bDown ) { g_WndMng.m_bAutoRun = FALSE; } if( bUp ) { m_timerAutoRunPush.Reset(); if( m_nDubleUp == 2 && m_timerAutoRun.TimeOut() == FALSE ) { m_nDubleUp = 3; g_WndMng.m_bAutoRun = TRUE; m_timerAutoRun.Reset(); m_timerAutoRunBlock.Reset(); } else { m_nDubleUp = 1; m_timerAutoRun.Reset(); } if( m_timerAutoRunBlock.TimeOut() ) g_WndMng.m_bAutoRun = FALSE; } else { if( m_timerAutoRunPush.TimeOut() == FALSE ) { if( m_nDubleUp == 1 ) m_nDubleUp = 2; } else { m_nDubleUp = 0; } } if( g_WndMng.m_bAutoRun ) bUp = TRUE; // 좌/우 회전 bLeft = g_bKeyTable[g_Neuz.Key.chLeft]; bRight = g_bKeyTable['D']; bSpace = g_bKeyTable[ VK_SPACE ]; // bCombatKey = g_bKeyTable['C']; // g_bKeyTable['C'] = 0; bBoard = g_bKeyTable['B']; bSit = g_bKeyTable['V']; g_bKeyTable['V'] = 0; /* if( g_Option.m_nInterface == 2 ) { bLForward = g_bKeyTable['Q']; bRForward = g_bKeyTable['E']; if( m_bLButtonDown ) { if( bLeft ) { bLeft = FALSE; bLForward = TRUE; } if( bRight ) { bRight = FALSE; bRForward = TRUE; } } } */ CWorld* pWorld = g_WorldMng.Get(); CRect rect = GetClientRect(); D3DXVECTOR3 vRayEnd; CObj* pFocusObj = pWorld->GetObjFocus(); CActionMover *pAct = pMover->m_pActMover; pAct->m_dwCtrlMsg = 0; if( m_bLButtonDown ) pAct->m_dwCtrlMsg |= CTRLMSG_LDOWN; #if __VER >= 12 // __ITEMCREATEMON_S0602 D3DXVECTOR3 vec3Tri[3]; pWorld->ClientPointToVector( vec3Tri, rect, point, &pWorld->m_matProj, &g_Neuz.m_camera.m_matView, &vRayEnd, TRUE ); g_Neuz.m_vCursorPos = vRayEnd; if( g_Neuz.m_pCreateMonItem ) { if( bUp || bDown || bLeft || bRight || bSpace || m_bLButtonDown ) { BOOL bSendCM = TRUE; if( m_bLButtonDown ) { D3DXVECTOR3 vDist2 = g_pPlayer->GetPos() - g_Neuz.m_vCursorPos; float fDist = D3DXVec3Length( &vDist2 ); // 두좌표간의 거리 if( 15.f < fDist ) { g_WndMng.PutString( prj.GetText( TID_GAME_CREATEMON_F_15 ), NULL, prj.GetTextColor( TID_GAME_CREATEMON_F_15 ) ); bSendCM = FALSE; } if( bSendCM ) { int nAttr = g_pPlayer->GetWorld()->GetHeightAttribute( g_Neuz.m_vCursorPos.x, g_Neuz.m_vCursorPos.z ); // 이동할 위치의 속성 읽음. if( nAttr == HATTR_NOWALK || nAttr == HATTR_NOMOVE || g_pPlayer->IsRegionAttr( RA_SAFETY ) || g_pPlayer->GetWorld()->GetID() == WI_WORLD_GUILDWAR ) // 못 움직이는 곳이거나 안전지역이면 Pass { g_WndMng.PutString( prj.GetText( TID_GAME_CREATEMON_F_AREA ), NULL, prj.GetTextColor( TID_GAME_CREATEMON_F_AREA ) ); bSendCM = FALSE; } else if( g_pPlayer->GetWorld()->GetID() != WI_WORLD_MADRIGAL ) { g_WndMng.PutString( prj.GetText( TID_GAME_CREATEMON_F_AREA ), NULL, prj.GetTextColor( TID_GAME_CREATEMON_F_AREA ) ); bSendCM = FALSE; } if( bSendCM ) { g_DPlay.SendCreateMonster( MAKELONG( ITYPE_ITEM, g_Neuz.m_pCreateMonItem->m_dwObjId ), g_Neuz.m_vCursorPos ); } } m_bLButtonDown = FALSE; } if( bSendCM ) g_Neuz.m_pCreateMonItem = NULL; } } #endif // __ITEMCREATEMON_S0602 //TODO:ata3k님 꼭 고쳐주세요. 왜 그런지 아무도 몰라! // 이동금지 상태가 아닐때만 클릭으로 이동할수 있다. #ifdef __Y_INTERFACE_VER3 bool *bpButton; if( g_Option.m_nInterface == 2 ) bpButton = &m_bLButtonUp; else bpButton = &m_bLButtonDown; if( *bpButton ) #else //__Y_INTERFACE_VER3 if( m_bLButtonDown ) #endif //__Y_INTERFACE_VER3 { #ifdef __Y_INTERFACE_VER3 if( g_Option.m_nInterface == 2 ) { *bpButton = FALSE; if( m_timerLButtonDown.GetLeftTime() > 200 ) return nMsg; } #endif //__Y_INTERFACE_VER3 D3DXVECTOR3 vec3Tri[3]; if( pWorld->ClientPointToVector( vec3Tri, rect, point, &pWorld->m_matProj, &g_Neuz.m_camera.m_matView, &vRayEnd, TRUE ) ) { // 이동 포인트를 얻어 목표 세팅 if( m_bFreeMove ) { // if( m_bLButtonDown ) // 이동금지 상태가 아닐때만 클릭으로 이동할수 있다. { { if( m_pWndGuideSystem && m_pWndGuideSystem->IsVisible()) #if __VER >= 12 // __MOD_TUTORIAL m_pWndGuideSystem->m_Condition.bIsClickOnLand = true; #else m_pWndGuideSystem->SendGuideMessage(GUIDE_EVENT_MOVE); #endif #ifdef __IAOBJ0622 if( GetLastPickObj() && GetLastPickObj()->GetType() == OT_SHIP ) pMover->SetDestPos( (CShip *)GetLastPickObj(), vRayEnd ); else pMover->SetDestPos( vRayEnd ); #else pMover->SetDestPos( vRayEnd ); #endif pMover->m_nCorr = -1; #ifndef __J0823 m_bFreeMove = FALSE; g_DPlay.SendSnapshot( TRUE ); fCastCancel = true; if( g_pMoveMark && g_pMoveMark->m_pSfxObj ) g_pMoveMark->m_pSfxObj->m_nCurFrame = 180; CSfx *pObj = CreateSfx(g_Neuz.m_pd3dDevice,XI_GEN_MOVEMARK01,vRayEnd); D3DXVECTOR3 vVector1 = vec3Tri[2] - vec3Tri[0]; D3DXVECTOR3 vVector2 = vec3Tri[1] - vec3Tri[0]; D3DXVECTOR3 vNormal; D3DXVec3Cross( &vNormal, &vVector1, &vVector2); D3DXVec3Normalize( &vNormal, &vNormal ); D3DXVECTOR3 v3Up = D3DXVECTOR3( 0.0f, -1.0f, 0.0f ); D3DXVECTOR3 v3Cross; FLOAT fDot; FLOAT fTheta; D3DXVec3Cross( &v3Cross, &v3Up, &vNormal ); fDot = D3DXVec3Dot( &v3Up, &vNormal ); fTheta = acos( fDot ); D3DXQUATERNION qDirMap; D3DXQuaternionRotationAxis( &qDirMap, &v3Cross, fTheta ); D3DXVECTOR3 vYPW; QuaternionRotationToYPW( qDirMap, vYPW ); pObj->m_pSfxObj->m_vRotate.x = D3DXToDegree(vYPW.x); pObj->m_pSfxObj->m_vRotate.y = D3DXToDegree(vYPW.y); pObj->m_pSfxObj->m_vRotate.z = D3DXToDegree(vYPW.z); #endif // __J0823 m_objidTracking = NULL_ID; } } } } } //if( !pMover->IsEmptyDestPos() || !pMover->IsEmptyDestObj() ) // return nMsg; #ifdef __Y_INTERFACE_VER3 if( bUp || bDown || bLeft || bRight || bSpace || bLForward || bRForward ) // 이동 키조작이 들어가면 자동공격 멈춤. #else //__Y_INTERFACE_VER3 if( bUp || bDown || bLeft || bRight || bSpace ) // 이동 키조작이 들어가면 자동공격 멈춤. #endif //__Y_INTERFACE_VER3 { if( bUp || bDown ) #if __VER >= 12 // __MOD_TUTORIAL { CWndGuideSystem* pWndGuide = NULL; pWndGuide = (CWndGuideSystem*)GetWndBase( APP_GUIDE ); if(pWndGuide && pWndGuide->IsVisible()) pWndGuide->m_Condition.bIsKeyMove = true; } #else m_pWndGuideSystem->SendGuideMessage(GUIDE_EVENT_KEY_MOVE); #endif m_bAutoAttack = FALSE; g_pPlayer->ClearCmd(); if( !bSpace ) m_objidTracking = NULL_ID; } if( m_objidTracking != NULL_ID ) { CMover* pObjTracking = prj.GetMover( m_objidTracking ); if( pObjTracking ) { D3DXVECTOR3 vDis = pMover->GetPos() - pObjTracking->GetPos(); if( D3DXVec3LengthSq( &vDis ) > 16 ) pMover->SetDestObj( m_objidTracking ); } else m_objidTracking = NULL_ID; } bool fMoved = false; bool fBehavior = false; if( bUp ) { if( pMover->SendActMsg( OBJMSG_FORWARD ) == 1 ) { fMoved = true; fCastCancel = true; } } else if( bDown ) { if( pMover->SendActMsg( OBJMSG_BACKWARD ) == 1 ) { fMoved = true; fCastCancel = true; } } #ifdef __Y_INTERFACE_VER3 else if( bLForward ) { if( pMover->SendActMsg( OBJMSG_LFORWARD ) == 1 ) { fMoved = true; fCastCancel = true; } } else if( bRForward ) { if( pMover->SendActMsg( OBJMSG_RFORWARD ) == 1 ) { fMoved = true; fCastCancel = true; } } #endif //__Y_INTERFACE_VER3 else // if( (bUp == FALSE && s_bUped == TRUE) || (bDown == FALSE && s_bDowned == TRUE) ) // 키를 뗀 순간에만 처리해보자.. if( bUp == FALSE || bDown == FALSE ) { if( pMover->IsEmptyDest() ) { if( pMover->m_pActMover->IsActJump() == FALSE && (pMover->m_pActMover->IsStateFlag( OBJSTAF_SIT ) ) == 0 ) // 앉아있을땐 실행하면 안된다. { if( pMover->SendActMsg( OBJMSG_STAND ) == 1 ) { fMoved = true; // TRACE( "PlayerMoved, " ); } } } } // s_bUped = bUp; // s_bDowned = bDown; if( bLeft ) { if( pMover->SendActMsg( OBJMSG_LTURN ) == 1 ) { fMoved = true; } } else if( bRight ) { if( pMover->SendActMsg( OBJMSG_RTURN ) == 1 ) { fMoved = true; } } else { if( pMover->SendActMsg( OBJMSG_STOP_TURN ) == 1 ) { fMoved = true; // fBehavior = true; } } // jump if( bSpace ) { #if __VER < 12 // __MOD_TUTORIAL if( m_pWndGuideSystem ) m_pWndGuideSystem->SendGuideMessage(GUIDE_EVENT_KEY_JUMP); #endif if( pMover->SendActMsg( OBJMSG_JUMP ) == 1 ) { fBehavior = true; fCastCancel = true; } } if( m_bLButtonDown == TRUE && m_bRButtonDown == TRUE ) { if( m_timerLButtonDown.GetLeftTime() < 500 && m_timerRButtonDown.GetLeftTime() < 500 ) { if( g_pPlayer->SendActMsg( OBJMSG_JUMP ) == 1 ) { fBehavior = true; fCastCancel = true; } } } #ifdef __Y_INTERFACE_VER3 if( g_Option.m_nInterface == 2 ) { if( g_bKeyTable[VK_DIVIDE] || g_bKeyTable[191] ) { bWalk = TRUE; } else { bWalk = FALSE; } } else { bWalk = g_bKeyTable[g_Neuz.Key.chWalk]; } #else //__Y_INTERFACE_VER3 bWalk = g_bKeyTable[g_Neuz.Key.chWalk]; #endif //__Y_INTERFACE_VER3 if( bWalk && !s_bWalk2 ) // 걷기 모드 토글. { if( pMover->m_pActMover->IsStateFlag( OBJSTAF_WALK ) ) { if( pMover->SendActMsg( OBJMSG_MODE_RUN ) == 1 ) { g_WndMng.PutString( prj.GetText( TID_GAME_RUN ), NULL, prj.GetTextColor( TID_GAME_RUN ) , CHATSTY_SYSTEM_CLIENT ); fBehavior = true; } } else { #if __VER < 12 // __MOD_TUTORIAL if(m_pWndGuideSystem) m_pWndGuideSystem->SendGuideMessage(GUIDE_EVENT_KEY_RUN); #endif if( pMover->SendActMsg( OBJMSG_MODE_WALK ) == 1 ) { g_WndMng.PutString( prj.GetText( TID_GAME_WALK ), NULL, prj.GetTextColor( TID_GAME_WALK ) , CHATSTY_SYSTEM_CLIENT ); fBehavior = true; } } } s_bWalk2 = bWalk; if( fMoved || fBehavior ) { g_pPlayer->ClearDest(); #ifdef __J0823 g_DPlay.ClearPlayerDestPos(); #endif // __J0823 } if( fMoved ) g_DPlay.SendPlayerMoved(); if( fBehavior ) g_DPlay.SendPlayerBehavior(); if( g_pPlayer->IsStateMode( STATE_BASEMOTION_MODE ) && fCastCancel ) // 캐스트 취소 { g_DPlay.SendStateModeCancel( STATE_BASEMOTION_MODE, STATEMODE_BASEMOTION_CANCEL ); } // 운영자가 쓰는 키. 서버로부터 좌표받아오기. if( bTempKey = g_bKeyTable[ '8' ] ) { if( !m_bTemp3ed ) { pMover->SendActMsg( OBJMSG_TEMP2 ); // __bTestLOD ^= 1; } } m_bTemp3ed = bTempKey; //----------- 스킬사용. /* static BOOL s_bShift2, s_bKeyC2; BOOL bShift, bKeyC; if( g_Option.m_nInterface == 1 ) // 신버전 인터페이스 방식은 X 가 스킬사용이다. { bShift = g_bKeyTable[ VK_SHIFT ]; bKeyC = g_bKeyTable[ 'C' ]; if( bKeyC ) { int a = 0; } if( (bShift && !s_bShift2) || (bKeyC && !s_bKeyC2) ) { CObj* pTargetObj = CObj::m_pObjHighlight; // 커서를 대고 있던 오브젝트가 하이라이트 오브젝이다. if( pTargetObj ) // 커서를 대고 있던 오브젝트가 있으면 { pWorld->SetObjFocus( pTargetObj ); // 그놈을 셀렉트 하는 동시에. CMover* pMover = (CMover*)pTargetObj; if( pMover->GetType() == OT_MOVER ) m_dwNextSkill = NEXTSKILL_ACTIONSLOT; // 스킬 사용 예약. } else m_dwNextSkill = NEXTSKILL_ACTIONSLOT; // 스킬 사용 예약. } s_bShift2 = bShift; s_bKeyC2 = bKeyC; } */ //------------ 비공정 타기 if( bBoard ) { if( !s_bBoarded ) // 플레이어가 비공정에 올라타있는 상태에서. 탑승키를 누르면. { if( g_pShip == NULL ) { if( g_pPlayer->GetIAObjLink() && g_pPlayer->GetIAObjLink()->GetType() == OT_SHIP && g_pPlayer->GetIAObjLink()->GetIndex() == 3 ) { CShip *pShip = (CShip *)g_pPlayer->GetIAObjLink(); if( pShip->GetMover() == NULL ) // 쥔장이 없는 배일때. { pShip->SetMover( g_pPlayer ); // 쥔장을 g_pPlayer로 설정. g_pShip = pShip; } } } else // 이미 배를 조종하고 있을때 { g_pShip->SetMover( NULL ); g_pShip = NULL; } } } s_bBoarded = bBoard; #ifdef _DEBUG // 디버깅용 키 if( bTempKey = g_bKeyTable[ VK_F2 ] ) { if( !s_bTempKeyed ) { // pMover->SendActMsg( OBJMSG_TEMP ); // g_Option.m_nObjectDetail ++; // if( g_Option.m_nObjectDetail > 2 ) g_Option.m_nObjectDetail = 0; } } s_bTempKeyed = bTempKey; if( bTempKey = g_bKeyTable[ 'F' ] ) { if( !m_bTemp2ed ) { pMover->SendActMsg( OBJMSG_TEMP3 ); } } m_bTemp2ed = bTempKey; #endif return nMsg; }
void RollToQuatRH(D3DXQUATERNION& q, float fRoll) { D3DXQuaternionRotationAxis(&q, &AXIS_ROLL_RH, fRoll); }
void PitchToQuatRH(D3DXQUATERNION& q, float fPitch) { D3DXQuaternionRotationAxis(&q, &AXIS_PITCH_RH, fPitch); }
void YawToQuatRH(D3DXQUATERNION& q, float fYaw) { D3DXQuaternionRotationAxis(&q, &AXIS_YAW_RH, fYaw); }
void Quaternion::BuildAxisAngle(const Vec3& axis, const float radians) { D3DXQuaternionRotationAxis(this, &axis, radians); }
inline void __Quaternion::RotationAxis(float fX, float fY, float fZ, float fRadian) { __Vector3 v(fX, fY, fZ); D3DXQuaternionRotationAxis(this, &v, fRadian); }
void IK::solve() { //don't solve anything if this chain is simulated if (checkSimulated()) return; //set up local variables used in solving the IK chain AMBone* destBone = _info.DestinationBone; AMBone* endEffBone = _info.EndEffectorBone; AMBone* curBone = NULL; D3DXVECTOR3 dest = D3DXVECTOR3(destBone->getCombinedTrans()(3,0), destBone->getCombinedTrans()(3,1), destBone->getCombinedTrans()(3,2)); //lol I still have no clue how this crazy shit works //algorithm is pretty much taken directly from MMD IKLink *cl; BoneInfo *ci; for (int i=0;i<(int)_info.IterationCount;i++) { for (int b=0;b<(int)_info.NumberOfLinks;b++) { cl = &_info.BoneLinkList[b]; curBone = cl->LinkBone; ci = curBone->getInfo(); D3DXVECTOR3 left = curBone->getPosWorld()-endEffBone->getPosWorld(); D3DXVECTOR3 right = curBone->getPosWorld()-destBone->getPosWorld(); D3DXVECTOR3 axis; D3DXVECTOR3 vec = left - right; if (D3DXVec3Length(&vec)*D3DXVec3Length(&vec) < 1E-04f) { i = _info.IterationCount; break; } D3DXVec3Normalize(&left, &left); D3DXVec3Normalize(&right, &right); D3DXVec3Cross(&axis, &left, &right); if (D3DXVec3Length(&axis)*D3DXVec3Length(&axis) < 1E-7 && i > 0) continue; D3DXVec3Normalize(&axis, &axis); /*if (cl->AngleLimit && i < _info.IterationCount/2) { if (cl->LowerLimit.y == 0.0f && cl->UpperLimit.y == 0.0f && cl->LowerLimit.z == 0.0f && cl->UpperLimit.z == 0.0f) { float n = (axis.x*ci->Parent->getCombinedTrans()._11) + (axis.y*ci->Parent->getCombinedTrans()._12) + (axis.z*ci->Parent->getCombinedTrans()._13); if (n >= 0.0f) axis.x = 1.0f; else axis.x = -1.0f; axis.y = 0.0f; axis.z = 0.0f; } else { if (cl->LowerLimit.x == 0.0f && cl->UpperLimit.x == 0.0f && cl->LowerLimit.z == 0.0f && cl->UpperLimit.z == 0.0f) { float n = (axis.x*ci->Parent->getCombinedTrans()._21) + (axis.y*ci->Parent->getCombinedTrans()._22) + (axis.z*ci->Parent->getCombinedTrans()._23); if (n >= 0.0f) axis.y = 1.0f; else axis.y = -1.0f; axis.x = 0.0f; axis.z = 0.0f; } else { if (cl->LowerLimit.x == 0.0f && cl->UpperLimit.x == 0.0f && cl->LowerLimit.y == 0.0f && cl->UpperLimit.y == 0.0f) { float n = (axis.x*ci->Parent->getCombinedTrans()._31) + (axis.y*ci->Parent->getCombinedTrans()._32) + (axis.z*ci->Parent->getCombinedTrans()._33); if (n >= 0.0f) axis.z = 1.0f; else axis.z = -1.0f; axis.x = 0.0f; axis.y = 0.0f; } else { D3DXVECTOR3 v; v.x = (axis.x*curBone->getCombinedTrans()._11)+(axis.y*curBone->getCombinedTrans()._12)+(axis.z*curBone->getCombinedTrans()._13); v.y = (axis.x*curBone->getCombinedTrans()._21)+(axis.y*curBone->getCombinedTrans()._22)+(axis.z*curBone->getCombinedTrans()._23); v.z = (axis.x*curBone->getCombinedTrans()._31)+(axis.y*curBone->getCombinedTrans()._32)+(axis.z*curBone->getCombinedTrans()._33); D3DXVec3Normalize(&axis, &v); } } } } else*/ { D3DXVECTOR3 v; v.x = (axis.x*curBone->getCombinedTrans()._11)+(axis.y*curBone->getCombinedTrans()._12)+(axis.z*curBone->getCombinedTrans()._13); v.y = (axis.x*curBone->getCombinedTrans()._21)+(axis.y*curBone->getCombinedTrans()._22)+(axis.z*curBone->getCombinedTrans()._23); v.z = (axis.x*curBone->getCombinedTrans()._31)+(axis.y*curBone->getCombinedTrans()._32)+(axis.z*curBone->getCombinedTrans()._33); D3DXVec3Normalize(&axis, &v); } float dot = D3DXVec3Dot(&left, &right); if (dot > 1.0f) dot = 1.0f; else if (dot < -1.0f) dot = -1.0f; float angle = acosf(dot); if (angle > (_info.AngleConstraint * (b+1)*2)) { angle = (_info.AngleConstraint * (b+1)*2); } D3DXQUATERNION newIkRot; D3DXQuaternionRotationAxis(&newIkRot, &axis, angle); D3DXQuaternionMultiply(&cl->IKQuat, &newIkRot, &cl->IKQuat); if (i == 0) //on first loop, apply rotation taken from the motion data D3DXQuaternionMultiply(&cl->IKQuat, &cl->IKQuat, &curBone->getRot()); D3DXMATRIX matrix; D3DXMatrixRotationQuaternion(&matrix, &cl->IKQuat); if (cl->AngleLimit) { if ((double)cl->LowerLimit.x > -1.5707963267948966 && (double)cl->UpperLimit.x < 1.5707963267948966) { float num5 = -matrix._32; float num6 = asinf(num5); if (abs(num6) > 1.535889f) { if (num6 < 0.0f) num6 = -1.535889f; else num6 = 1.535889f; } float num7 = cosf(num6); float num8 = matrix._31/num7; float num9 = matrix._33/num7; float num10 = atan2f(num8, num9); float num11 = matrix._12/num7; float num12 = matrix._22/num7; float num13 = atan2f(num11, num12); bool loopFlag = i<(int)_info.IterationCount/2; num6 = GetUpperLowerRadian(num6, cl->LowerLimit.x, cl->UpperLimit.x, loopFlag); num10 = GetUpperLowerRadian(num10, cl->LowerLimit.y, cl->UpperLimit.y, loopFlag); num13 = GetUpperLowerRadian(num13, cl->LowerLimit.z, cl->UpperLimit.z, loopFlag); D3DXMATRIX nx, ny, nz; D3DXMatrixRotationX(&nx, num6); D3DXMatrixRotationY(&ny, num10); D3DXMatrixRotationZ(&nz, num13); matrix = nz*nx*ny; } else { if ((double)cl->LowerLimit.y > -1.5707963267948966 && (double)cl->UpperLimit.y < 1.5707963267948966) { float num14 = -matrix._13; float num15 = asinf(num14); if (abs(num15) > 1.535889f) { if (num15 < 0.0f) { num15 = -1.535889f; } else { num15 = 1.535889f; } } float num16 = cosf(num15); float num17 = matrix._23 / num16; float num18 = matrix._33 / num16; float num19 = atan2f(num17, num18); float num20 = matrix._12 / num16; float num21 = matrix._11 / num16; float num22 = atan2f(num20, num21); bool loopFlag = i<(int)_info.IterationCount/2; num19 = GetUpperLowerRadian(num19, cl->LowerLimit.x, cl->UpperLimit.x, loopFlag); num15 = GetUpperLowerRadian(num15, cl->LowerLimit.y, cl->UpperLimit.y, loopFlag); num22 = GetUpperLowerRadian(num22, cl->LowerLimit.z, cl->UpperLimit.z, loopFlag); D3DXMATRIX nx, ny, nz; D3DXMatrixRotationX(&nx, num19); D3DXMatrixRotationY(&ny, num15); D3DXMatrixRotationZ(&nz, num22); matrix = nx*ny*nz; } else { float num23 = -matrix._21; float num24 = asinf(num23); if (abs(num24) > 1.535889f) { if (num24 < 0.0f) { num24 = -1.535889f; } else { num24 = 1.535889f; } } float num25 = cosf(num24); float num26 = matrix._23 / num25; float num27 = matrix._22 / num25; float num28 = atan2f(num26, num27); float num29 = matrix._31 / num25; float num30 = matrix._11 / num25; float num31 = atan2f(num29, num30); bool loopFlag = i<(int)_info.IterationCount/2; num28 = GetUpperLowerRadian(num28, cl->LowerLimit.x, cl->UpperLimit.x, loopFlag); num31 = GetUpperLowerRadian(num31, cl->LowerLimit.y, cl->UpperLimit.y, loopFlag); num24 = GetUpperLowerRadian(num24, cl->LowerLimit.z, cl->UpperLimit.z, loopFlag); D3DXMATRIX nx, ny, nz; D3DXMatrixRotationX(&nx, num28); D3DXMatrixRotationY(&ny, num31); D3DXMatrixRotationZ(&nz, num24); matrix = ny*nz*nx; } } D3DXQuaternionRotationMatrix(&cl->IKQuat, &matrix); } curBone->setRot(cl->IKQuat); //curBone->setCombTrans(matrix); for (int j=b;j>=0;j--) { _info.BoneLinkList[j].LinkBone->UpdateFromIK(); } endEffBone->UpdateFromIK(); } } for (int i=0;i<(int)_info.NumberOfLinks;i++) { _info.BoneLinkList[i].IKQuat = D3DXQUATERNION(0,0,0,1); } }