static void AddImpulse(void) { static Vector4 vPosition(0.0f, 0.0f, 0.0f, 0.0f); //Vector4 vDiff = vPosition - g_vPosition; Vector4 vDiff = g_vPosition - vPosition; Vector4 vLength = vDiff.Length(); if ( vLength[0]<2.0f ) return; Vector4 vDir = vDiff / vLength; Vector4 vVec0(vDir[1],-vDir[0], 0.0f, 0.0f); Vector4 vVec1(vDir[0], vDir[1], 0.0f, 0.0f); vPosition = g_vPosition; Vector4 vVec0_old = g_orient_matrix[0]; Vector4 vVec1_old = g_orient_matrix[1]; Vector4 vVec0_new = VectorLerp(vVec0_old, vVec0, 0.2f); Vector4 vVec1_new = VectorLerp(vVec1_old, vVec1, 0.2f); vVec0_new.Normalize(); vVec1_new.Normalize(); Vector4 vVec2_new = Vector3CrossProduct(vVec0_new, vVec1_new); g_orient_matrix.Identity(); g_orient_matrix[0] = vVec0_new; g_orient_matrix[1] = vVec1_new; g_orient_matrix[2] = vVec2_new; LPDIRECT3DDEVICE9 device = GutGetGraphicsDeviceDX9(); device->SetRenderTarget(0, g_pSurfaces[TEX_HEIGHT1]); device->SetDepthStencilSurface(NULL); Matrix4x4 view_matrix = g_Control.GetViewMatrix(); Matrix4x4 world_matrix; world_matrix.Scale_Replace(g_fRippleSize, g_fRippleSize, 1.0f); world_matrix[3] = g_vPosition; Matrix4x4 wvp_matrix = g_orient_matrix * world_matrix * view_matrix * g_proj_matrix; D3DXHANDLE shader = g_pWaterEffect->GetTechniqueByName("AddImpulse"); D3DXHANDLE wvp_matrix_var = g_pWaterEffect->GetParameterByName(NULL, "wvp_matrix"); D3DXHANDLE force_var = g_pWaterEffect->GetParameterByName(NULL, "fForce"); g_pWaterEffect->SetTechnique(shader); g_pWaterEffect->SetMatrix(wvp_matrix_var, (D3DXMATRIX *)&wvp_matrix); g_pWaterEffect->SetFloat(force_var, 0.05f); g_pWaterEffect->Begin(NULL, 0); g_pWaterEffect->BeginPass(0); g_Model_DX9.Render(0); g_pWaterEffect->EndPass(); g_pWaterEffect->End(); vPosition = g_vPosition; }
void Vector3Test() { printf("3ÔªÏòÁ¿²âÊÔ\n"); S3D::Vector3 v1(1.0f,1.0f,1.0f); S3D::Vector3 v2(2.0f,2.0f,2.0f); S3D::Vector3Normalize(&v1); S3D::print(&v1);PRINT_LINE; S3D::Vector3 v3=v1+v2; S3D::print(&v3);PRINT_LINE; S3D::Vector3 vResult; v2=S3D::Vector3(1.0f,2.0f,3.0f); printf("%f\n",S3D::Vector3DotProduct(&v1,&v2)); Vector3CrossProduct(&vResult,&v1,&v2); S3D::print(&vResult);PRINT_LINE; printf("%f\n",S3D::Vector3DotProduct(&vResult,&v2)); printf("%f\n",S3D::Vector3DotProduct(&vResult,&v1)); PRINT_START; PRINT(proj & prep); S3D::Vector3Proj(&vResult,&v1,&v2); S3D::print(&vResult);PRINT_LINE; S3D::Vector3 vPerp; S3D::Vector3Perp(&vPerp,&v1,&v2); S3D::print(&vPerp);PRINT_LINE; printf("%f\n",S3D::Vector3DotProduct(&vResult,&vPerp)); printf("length:proj perp v1\n %f %f %f wanted valuie %f\n",S3D::Vector3Length(&vResult), S3D::Vector3Length(&vPerp),S3D::Vector3Length(&v1),sqrtf(powf(S3D::Vector3Length(&vResult),2)+powf(S3D::Vector3Length(&vPerp),2))); { S3D::Vector3 v1(1.0f,2.0f,3.0f); S3D::Vector3 v2(-1.0f,1.0f,1.0f); S3D::Vector3 v3(4.0f,5.0f,6.0f); S3D::Vector3 vProj; S3D::Vector3Proj(&vProj,&v2,&v1); S3D::print(&vProj);PRINT_LINE; Vector3Orthongonlize(&v1,&v2,&v3); S3D::print(&v1);PRINT_LINE; S3D::print(&v2);PRINT_LINE; S3D::print(&v3);PRINT_LINE; printf("%f\n",S3D::Vector3DotProduct(&v1,&v2)); printf("%f\n",S3D::Vector3DotProduct(&v2,&v3)); float f1=S3D::Vector3DotProduct(&v1,&v2); float f2=S3D::Vector3DotProduct(&v2,&v3); printf("%f %f ",f1,f2); float f3=0.00000001f; float* pf1=&f1; float* pf2=&f2; // Sleep(f1*f2); } };
void GetUserInput(void) { // `讀取滑鼠` GutMouseInfo mouse; GutReadMouse(&mouse); // `讀取鍵盤` char keyboard_state[256]; GutReadKeyboard(keyboard_state); // `取得畫完前一個畫面到現在所經歷的時間` float time_diff = g_Timer.Stop(); g_Timer.Restart(); float moving_speed = 2.0f * time_diff; float rotation_speed = 1.0 * time_diff; // `極座標系統` static float theta = -MATH_PI * 0.5f; static float phi = 0.0f; // `如果按下滑鼠左鍵, 就旋轉鏡頭.` if ( mouse.button[0] ) { theta += mouse.x * rotation_speed; phi -= mouse.y * rotation_speed; } float sin_phi, cos_phi; float sin_theta, cos_theta; FastMath::SinCos(phi, sin_phi, cos_phi); FastMath::SinCos(theta, sin_theta, cos_theta); // `計算鏡頭的面向` Vector4 camera_facing; camera_facing[0] = cos_phi * cos_theta; camera_facing[1] = sin_phi; camera_facing[2] = cos_phi * sin_theta; // `計算鏡頭正上方的軸向` Vector4 camera_up; FastMath::SinCos(phi + MATH_PI*0.5f, sin_phi, cos_phi); camera_up[0] = cos_phi * cos_theta; camera_up[1] = sin_phi; camera_up[2] = cos_phi * sin_theta; // `取得鏡面右方的方向` Vector4 camera_right = Vector3CrossProduct(camera_facing, camera_up); // `按下W或方向鍵向上` if ( keyboard_state[GUTKEY_W] || keyboard_state[GUTKEY_UP] ) { g_eye += camera_facing * moving_speed; } // `按下S或方向鍵向下` if ( keyboard_state[GUTKEY_S] || keyboard_state[GUTKEY_DOWN] ) { g_eye -= camera_facing * moving_speed; } // `按下A或方向鍵向左` if ( keyboard_state[GUTKEY_A] || keyboard_state[GUTKEY_LEFT] ) { g_eye -= camera_right * moving_speed; } // `按下D或方向鍵向右` if ( keyboard_state[GUTKEY_D] || keyboard_state[GUTKEY_RIGHT] ) { g_eye += camera_right * moving_speed; } // `計算出鏡頭對準的點, 產生鏡頭轉換矩陣時會用到.` g_lookat = g_eye + camera_facing; // `因為是對2個軸轉動, 需要更新鏡頭朝上的軸.` g_up = camera_up; }
void GetUserControl_FPSCamera(Vector4 &vEye, Vector4 &vUp, Vector4 &vLookAt, float time_advance) { // 讀取滑鼠 GutMouseInfo mouse; GutReadMouse(&mouse); // 讀取鍵盤 char keyboard_state[256]; GutReadKeyboard(keyboard_state); float moving_speed = 2.0f * time_advance; float rotation_speed = 1.0f * time_advance; // 極座標系統 static float theta = -MATH_PI * 0.5f; static float phi = 0.0f; // 如果按下滑鼠左鍵,就旋轉鏡頭 if ( mouse.button[0] ) { theta += mouse.x * rotation_speed; phi -= mouse.y * rotation_speed; } float sin_phi, cos_phi; float sin_theta, cos_theta; FastMath::SinCos(phi, sin_phi, cos_phi); FastMath::SinCos(theta, sin_theta, cos_theta); // 計算鏡頭的面向 Vector4 camera_facing; camera_facing[0] = cos_phi * cos_theta; camera_facing[1] = sin_phi; camera_facing[2] = cos_phi * sin_theta; // 計算鏡頭正上方的軸向 Vector4 camera_up; FastMath::SinCos(phi + MATH_PI*0.5f, sin_phi, cos_phi); camera_up[0] = cos_phi * cos_theta; camera_up[1] = sin_phi; camera_up[2] = cos_phi * sin_theta; // 取得鏡面右方的方向 Vector4 camera_right = Vector3CrossProduct(camera_up, camera_facing); // 按下W或方向鍵向上 if ( keyboard_state[GUTKEY_W] || keyboard_state[GUTKEY_UP] ) { vEye += camera_facing * moving_speed; } // 按下S或方向鍵向下 if ( keyboard_state[GUTKEY_S] || keyboard_state[GUTKEY_DOWN] ) { vEye -= camera_facing * moving_speed; } // 按下A或方向鍵向左 if ( keyboard_state[GUTKEY_A] || keyboard_state[GUTKEY_LEFT] ) { vEye += camera_right * moving_speed; } // 按下D或方向鍵向右 if ( keyboard_state[GUTKEY_D] || keyboard_state[GUTKEY_RIGHT] ) { vEye -= camera_right * moving_speed; } // 計算出鏡頭對準的點, 產生鏡頭轉換矩陣時會用到. vLookAt = vEye + camera_facing; // 因為是對2個軸轉動, 需要更新鏡頭朝上的軸 vUp = camera_up; vEye[3] = vUp[3] = vLookAt[3] = 1.0f; }
//====== // 更新 //====== void cPMDIK::update( void ) { Vector3 vec3OrgTargetPos; vec3OrgTargetPos.x = m_pTargetBone->m_matLocal[3][0]; vec3OrgTargetPos.y = m_pTargetBone->m_matLocal[3][1]; vec3OrgTargetPos.z = m_pTargetBone->m_matLocal[3][2]; Vector3 vec3EffPos; Vector3 vec3TargetPos; for( short i = m_cbNumLink - 1 ; i >= 0 ; i-- ){ m_ppBoneList[i]->updateMatrix(); } m_pEffBone->updateMatrix(); for( unsigned short it = 0 ; it < m_unCount ; it++ ) { for( unsigned char cbLinkIdx = 0 ; cbLinkIdx < m_cbNumLink ; cbLinkIdx++ ) { // エフェクタの位置の取得 vec3EffPos.x = m_pEffBone->m_matLocal[3][0]; vec3EffPos.y = m_pEffBone->m_matLocal[3][1]; vec3EffPos.z = m_pEffBone->m_matLocal[3][2]; // ワールド座標系から注目ノードの局所(ローカル)座標系への変換 Matrix matInvBone; MatrixInverse( matInvBone, m_ppBoneList[cbLinkIdx]->m_matLocal ); // エフェクタ,到達目標のローカル位置 Vector3Transform( &vec3EffPos, &vec3EffPos, matInvBone ); Vector3Transform( &vec3TargetPos, &vec3OrgTargetPos, matInvBone ); // 十分近ければ終了 Vector3 vec3Diff; Vector3Sub( &vec3Diff, &vec3EffPos, &vec3TargetPos ); if( Vector3DotProduct( &vec3Diff, &vec3Diff ) < 0.0000001f ) return; // (1) 基準関節→エフェクタ位置への方向ベクトル Vector3Normalize( &vec3EffPos, &vec3EffPos ); // (2) 基準関節→目標位置への方向ベクトル Vector3Normalize( &vec3TargetPos, &vec3TargetPos ); // ベクトル (1) を (2) に一致させるための最短回転量(Axis-Angle) // // 回転角 float fRotAngle = acosf( Vector3DotProduct( &vec3EffPos, &vec3TargetPos ) ); if( 0.00000001f < fabsf( fRotAngle ) ) { if( fRotAngle < -m_fFact ) fRotAngle = -m_fFact; else if( m_fFact < fRotAngle ) fRotAngle = m_fFact; // 回転軸 Vector3 vec3RotAxis; Vector3CrossProduct( &vec3RotAxis, &vec3EffPos, &vec3TargetPos ); if( Vector3DotProduct( &vec3RotAxis, &vec3RotAxis ) < 0.0000001f ) continue; Vector3Normalize( &vec3RotAxis, &vec3RotAxis ); // 関節回転量の補正 Vector4 vec4RotQuat; QuaternionCreateAxis( &vec4RotQuat, &vec3RotAxis, fRotAngle ); if( m_ppBoneList[cbLinkIdx]->m_bIKLimitAngle ) limitAngle( &vec4RotQuat, &vec4RotQuat ); QuaternionNormalize( &vec4RotQuat, &vec4RotQuat ); QuaternionMultiply( &m_ppBoneList[cbLinkIdx]->m_vec4Rotation, &m_ppBoneList[cbLinkIdx]->m_vec4Rotation, &vec4RotQuat ); QuaternionNormalize( &m_ppBoneList[cbLinkIdx]->m_vec4Rotation, &m_ppBoneList[cbLinkIdx]->m_vec4Rotation ); for( short i = cbLinkIdx ; i >= 0 ; i-- ){ m_ppBoneList[i]->updateMatrix(); } m_pEffBone->updateMatrix(); } } } }