bool CFrustum::setFrustum(const D3DXMATRIXA16& pmatViewProj ) { D3DXMATRIXA16 matInv; D3DXMatrixIdentity( &matInv ); // 투영행렬까지 거치면 모든 3차원 월드좌표의 점은 (-1,-1,0) ~ (1,1,1)사이의 값으로 바뀐다. // m_vtx에 이 동차공간의 경계값을 넣어둔다. m_vtx[0].x = -1.0f; m_vtx[0].y = -1.0f; m_vtx[0].z = 0.0f; m_vtx[1].x = 1.0f; m_vtx[1].y = -1.0f; m_vtx[1].z = 0.0f; m_vtx[2].x = 1.0f; m_vtx[2].y = -1.0f; m_vtx[2].z = 1.0f; m_vtx[3].x = -1.0f; m_vtx[3].y = -1.0f; m_vtx[3].z = 1.0f; m_vtx[4].x = -1.0f; m_vtx[4].y = 1.0f; m_vtx[4].z = 0.0f; m_vtx[5].x = 1.0f; m_vtx[5].y = 1.0f; m_vtx[5].z = 0.0f; m_vtx[6].x = 1.0f; m_vtx[6].y = 1.0f; m_vtx[6].z = 1.0f; m_vtx[7].x = -1.0f; m_vtx[7].y = 1.0f; m_vtx[7].z = 1.0f; // view * proj의 역행렬을 구한다. D3DXMatrixInverse(&matInv, NULL, &pmatViewProj ); // Vertex_최종 = Vertex_local * Matrix_world * Matrix_view * Matrix_Proj 인데, // Vertex_world = Vertex_local * Matrix_world이므로, // Vertex_최종 = Vertex_world * Matrix_view * Matrix_Proj 이다. // Vertex_최종 = Vertex_world * ( Matrix_view * Matrix_Proj ) 에서 // 역행렬( Matrix_view * Matrix_Proj )^-1를 양변에 곱하면 // Vertex_최종 * 역행렬( Matrix_view * Matrix_Proj )^-1 = Vertex_World 가 된다. // 그러므로, m_vtx * matInv = Vertex_world가 되어, 월드좌표계의 프러스텀 좌표를 얻을 수 있다. for( int i = 0; i < 8; i++ ) D3DXVec3TransformCoord( &m_vtx[i], &m_vtx[i], &matInv ); // 0번과 5번은 프러스텀중 near평면의 좌측상단과 우측하단이므로, 둘의 좌표를 더해서 2로 나누면 // 카메라의 좌표를 얻을 수 있다.(정확히 일치하는 것은 아니다.) m_vPos = ( m_vtx[0] + m_vtx[5] ) / 2.0f; // 얻어진 월드좌표로 프러스텀 평면을 만든다 // 벡터가 프러스텀 안쪽에서 바깥쪽으로 나가는 평면들이다. D3DXPlaneFromPoints(&m_plane[0], m_vtx+4, m_vtx+7, m_vtx+6); // 상 평면(top) D3DXPlaneFromPoints(&m_plane[1], m_vtx , m_vtx+1, m_vtx+2); // 하 평면(bottom) D3DXPlaneFromPoints(&m_plane[2], m_vtx , m_vtx+4, m_vtx+5); // 근 평면(near) D3DXPlaneFromPoints(&m_plane[3], m_vtx+2, m_vtx+6, m_vtx+7); // 원 평면(far) D3DXPlaneFromPoints(&m_plane[4], m_vtx , m_vtx+3, m_vtx+7); // 좌 평면(left) D3DXPlaneFromPoints(&m_plane[5], m_vtx+1, m_vtx+5, m_vtx+6); // 우 평면(right) return TRUE; }
// // WndProc // LRESULT CALLBACK d3d::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch( msg ) { case WM_DESTROY: ::PostQuitMessage(0); break; case WM_KEYDOWN: if( wParam == VK_ESCAPE ) ::DestroyWindow(hwnd); break; case WM_LBUTTONDOWN: // compute the ray in view space given the clicked screen point d3d::Ray ray = CalcPickingRay(LOWORD(lParam), HIWORD(lParam)); // transform the ray to world space D3DXMATRIX view ; static D3DXMATRIX lastView; Device->GetTransform(D3DTS_VIEW, &view); if (view!= lastView) { OutputDebugString("!=\n"); } lastView = view; D3DXMATRIX viewInverse; D3DXMatrixInverse(&viewInverse, 0, &view); TransformRay(&ray, &viewInverse); // test for a hit if( RaySphereIntTest(&ray, &BSphere) ) ::MessageBox(0, "Hit!", "HIT", 0); break; } return ::DefWindowProc(hwnd, msg, wParam, lParam); }
Ray PickVisitor::PickInvMatrix( Ray ray, D3DXMATRIX a_Matrix) { // Get the inverse view matrix D3DXMATRIX matrix; D3DXMatrixInverse( &matrix, NULL, &a_Matrix ); Ray result; // Transform the pick ray (normaly WorldView) into object space D3DXVec4Transform(&result.orig, &ray.orig, &matrix); D3DXVec4Transform(&result.dir, &ray.dir, &matrix); //TODO: test ray with and without normalize D3DXVec3Normalize((D3DXVECTOR3*)&result.dir, (D3DXVECTOR3*)&result.dir); result.dir.w=0.0; return result; }
void mouseUtil::calcRayVectorOrthoRH(D3DXMATRIX matView, D3DXMATRIX matProj) { D3DXMATRIX matInvView; D3DVECTOR v; D3DXMatrixInverse( &matInvView, NULL, &matView ); v.x = ( ( ( ( 2.0f * ( m_nMouseX ) ) / m_nScreenWidth ) - 1 ) - matProj._31 ) / matProj._11; v.y = ( -( ( ( 2.0f * ( m_nMouseY ) ) / m_nScreenHeight ) - 1 ) - matProj._32 ) / matProj._22; v.z = -1.0f; m_vRayPos.x = v.x * matInvView._11 + v.y * matInvView._21 + v.z * matInvView._31; m_vRayPos.y = v.x * matInvView._12 + v.y * matInvView._22 + v.z * matInvView._32; m_vRayPos.z = matInvView._43; m_vRayDir.x = matInvView._41; m_vRayDir.y = matInvView._42; m_vRayDir.z = v.x * matInvView._13 + v.y * matInvView._23 + v.z * matInvView._33; }
void SkinnedMeshNode::LinkToBone(Entity* pEntity) { assert(!m_vecBoneRef.empty()); D3DXMATRIX tmBoneWorldReferenceInv; size_t iBoneRef=0,nBoneRefSize =m_vecBoneRef.size() ; for (iBoneRef=0;iBoneRef<nBoneRefSize;iBoneRef++) { BONEREFINFO& refItem=m_vecBoneRef[iBoneRef]; refItem.pNode = pEntity->FindNode(refItem.strNodeName); assert(refItem.pNode!=NULL); // 찾지 못하는경우가 있어서는 안됨 블렌트 버택스에 boneIndex가 들어가있으므로 D3DXMatrixInverse(&tmBoneWorldReferenceInv,NULL,&refItem.pNode->GetNodeTM()); refItem.SkinOffset = GetNodeTM() * tmBoneWorldReferenceInv; // LocalTM = WorldTM * Parent.WorldTM.Inverse } }
// 地面との当たり判定 bool Collision::CheckDown( iexMesh* org, const Vector3& pos, float& outHeight ) { Vector3 p( pos.x, pos.y + 2.0f, pos.z ); Vector3 vec( 0, -1.0f, 0 ); Vector3 out; outHeight = pos.y; float dist = 100.0f; // オブジェクトの逆行列を算出 org->Update(); Matrix mat = org->TransMatrix; Matrix invMat; // 逆行列 D3DXMatrixInverse( &invMat, null, &mat ); // 逆行列でレイをローカル化 Vector3 invVec; invVec.x = invMat._11 * vec.x + invMat._21 * vec.y + invMat._31 * vec.z; invVec.y = invMat._12 * vec.x + invMat._22 * vec.y + invMat._32 * vec.z; invVec.z = invMat._13 * vec.x + invMat._23 * vec.y + invMat._33 * vec.z; Vector3 invPos; invPos.x = invMat._11 * p.x + invMat._21 * p.y + invMat._31 * p.z + invMat._41; invPos.y = invMat._12 * p.x + invMat._22 * p.y + invMat._32 * p.z + invMat._42; invPos.z = invMat._13 * p.x + invMat._23 * p.y + invMat._33 * p.z + invMat._43; if ( org->RayPick( &out, &invPos, &invVec, &dist ) >= 0 ) { Vector3 resultPos; resultPos.x = mat._11 * out.x + mat._21 * out.y + mat._31 * out.z + mat._41; resultPos.y = mat._12 * out.x + mat._22 * out.y + mat._32 * out.z + mat._42; resultPos.z = mat._13 * out.x + mat._23 * out.y + mat._33 * out.z + mat._43; outHeight = resultPos.y; if ( pos.y < resultPos.y ) { return true; } } return false; }
void XFileDemo::drawScene() { HR(gd3dDevice->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffeeeeee, 1.0f, 0)); HR(gd3dDevice->BeginScene()); HR(mFX->SetValue(mhLight, &mLight, sizeof(DirLight))); HR(mFX->SetMatrix(mhWVP, &(mWorld*mView*mProj))); D3DXMATRIX worldInvTrans; D3DXMatrixInverse(&worldInvTrans, 0, &mWorld); D3DXMatrixTranspose(&worldInvTrans, &worldInvTrans); HR(mFX->SetMatrix(mhWorldInvTrans, &worldInvTrans)); HR(mFX->SetMatrix(mhWorld, &mWorld)); HR(mFX->SetTechnique(mhTech)); UINT numPasses = 0; HR(mFX->Begin(&numPasses, 0)); HR(mFX->BeginPass(0)); for (int j = 0; j < mMtrl.size(); ++j) { HR(mFX->SetValue(mhMtrl, &mMtrl[j], sizeof(Material))); if (mTex[j] != 0) { HR(mFX->SetTexture(mhTex, mTex[j])); } else { HR(mFX->SetTexture(mhTex, mWhiteTex)); } HR(mFX->CommitChanges()); HR(mMesh->DrawSubset(j)); } HR(mFX->EndPass()); HR(mFX->End()); mGfxStats->display(D3DCOLOR_XRGB(0,0,0)); HR(gd3dDevice->EndScene()); HR(gd3dDevice->Present(0, 0, 0, 0)); }
// 输入摄像机投影矩阵,得到6个平面 bool ZFrustum::Make(D3DXMATRIX* pmatViewProj,float fEpsilon) { m_fEpsilon = fEpsilon; int i; D3DXMATRIX matInv; m_vtx[0].x = -1.0f; m_vtx[0].y = -1.0f; m_vtx[0].z = 0.0f; m_vtx[1].x = 1.0f; m_vtx[1].y = -1.0f; m_vtx[1].z = 0.0f; m_vtx[2].x = 1.0f; m_vtx[2].y = -1.0f; m_vtx[2].z = 1.0f; m_vtx[3].x = -1.0f; m_vtx[3].y = -1.0f; m_vtx[3].z = 1.0f; m_vtx[4].x = -1.0f; m_vtx[4].y = 1.0f; m_vtx[4].z = 0.0f; m_vtx[5].x = 1.0f; m_vtx[5].y = 1.0f; m_vtx[5].z = 0.0f; m_vtx[6].x = 1.0f; m_vtx[6].y = 1.0f; m_vtx[6].z = 1.0f; m_vtx[7].x = -1.0f; m_vtx[7].y = 1.0f; m_vtx[7].z = 1.0f; // 求得view*proj的逆矩阵 D3DXMatrixInverse(&matInv,NULL,pmatViewProj); // 将8个顶点转换到世界空间 for (i = 0;i < 8;i++) { D3DXVec3TransformCoord(&m_vtx[i],&m_vtx[i],&matInv); D3DXVECTOR3 v = m_vtx[i]; } // 求出摄像机的大致坐标(近裁截面中心,非准确摄像机位置) m_vPos = (m_vtx[0] + m_vtx[5]) / 2.0f; // 通过8个顶点的世界坐标,制作平截台体平面,法线方向向外 // top D3DXPlaneFromPoints(&m_plane[0],m_vtx + 4,m_vtx + 7,m_vtx + 6); // bottom D3DXPlaneFromPoints(&m_plane[1],m_vtx,m_vtx + 1,m_vtx + 2); // near D3DXPlaneFromPoints(&m_plane[2],m_vtx,m_vtx + 4,m_vtx + 5); // far D3DXPlaneFromPoints(&m_plane[3],m_vtx + 2,m_vtx + 6,m_vtx + 7); // left D3DXPlaneFromPoints(&m_plane[4],m_vtx,m_vtx + 3,m_vtx + 7); // right D3DXPlaneFromPoints(&m_plane[5],m_vtx + 1,m_vtx + 5,m_vtx + 6); return true; }
void PTGScene::onObjRender(HwSceneObject *sender) { HwMaterial *mat = sender->getMaterial(); HwShader *shd = mat->getPass(0)->getShader(); HwCamera *cam = pEng->getScene()->getCamera(); if (shd == NULL) return; if (mat->getCurrTechn() == 0) { D3DXMATRIX wvm = sender->worldMatrix() * cam->viewM(); shd->getPass(0)->vp()->setConst("g_mWorldView", wvm); shd->getPass(0)->vp()->setConst("g_mProj", cam->projM()); } else { D3DXMATRIX mLightView = pLCam->viewM(); D3DXMATRIXA16 mViewToLightProj = cam->viewM(); D3DXMatrixInverse( &mViewToLightProj, NULL, &mViewToLightProj ); mViewToLightProj = mViewToLightProj * mLightView * pLCam->projM(); shd->getPass(0)->vp()->setConst("g_mViewToLightProj", mViewToLightProj); D3DXMATRIX wvm = sender->worldMatrix() * cam->viewM(); shd->getPass(0)->vp()->setConst("g_mWorldView", wvm); shd->getPass(0)->vp()->setConst("g_mProj", cam->projM()); shd->getPass(0)->pp()->setConst("g_fCosTheta", cosf(D3DX_PI / 4)); shd->getPass(0)->pp()->setConst( "g_vLightDiffuse", D3DXVECTOR4(1, 1, 1, 1.0)); shd->getPass(0)->pp()->setConst( "g_vMaterial", D3DXVECTOR4(1, 1, 1, 1.0)); shd->getPass(0)->pp()->setConst( "g_vLightAmbient", D3DXVECTOR4(0.3, 0.3, 0.3, 1.0)); D3DXVECTOR3 v = pLCam->getEye(); D3DXVECTOR4 v4; D3DXVec3Transform( &v4, &v, &cam->viewM()); shd->getPass(0)->pp()->setConst( "g_vLightPos", v4); v4 = D3DXVECTOR4(pLCam->getDirection(), 0); D3DXVec4Transform( &v4, &v4, &cam->viewM() ); // Direction in view space D3DXVec3Normalize( ( D3DXVECTOR3* )&v4, ( D3DXVECTOR3* )&v4 ); shd->getPass(0)->pp()->setConst( "g_vLightDir", v4); } }
//----------------------------------------------------------------------------- // Name: OneTimeSceneInit // Desc: //----------------------------------------------------------------------------- HRESULT CMyD3DApplication::OneTimeSceneInit() { HRESULT hr; // Initialize Water if(FAILED(hr = m_Water.Initialize(64.0f, WATER_DEPTH))) return hr; // Initialize Environment if(FAILED(hr = m_Environment.Initialize(1000.0f))) return hr; // Misc stuff D3DXMatrixRotationX(&m_matPosition, D3DX_PI * -0.3f); m_matPosition._42 = 15.0f; m_matPosition._43 = 15.0f; D3DXMatrixInverse(&m_matView, NULL, &m_matPosition); return S_OK; }
INT CLcXSkinIns::FrameMove() { LPDIRECT3DDEVICE9 pDev = (LPDIRECT3DDEVICE9)LcDev_GetD3Device(); m_dTimeCur += m_fElapse; // For Sort...(optional) D3DXMATRIX mtViwI; pDev->GetTransform( D3DTS_VIEW, &mtViwI ); D3DXMatrixInverse(&mtViwI, NULL, &mtViwI); D3DXVECTOR3 vcCam = D3DXVECTOR3(mtViwI._41, mtViwI._42, mtViwI._43); D3DXVECTOR3 vcZ = D3DXVECTOR3(mtViwI._31, mtViwI._32, mtViwI._33); D3DXVECTOR3 vcTmp = m_vcTrn - vcCam; m_fStlSrtR = D3DXVec3Dot(&vcZ, &vcTmp); return 0; }
Vec2 Graphics::ScreenToWorldSpace(Vec2 screenPosition) { //Convert to normalized screen space 0 to 1 screenPosition.x /= SurfaceSize.x; screenPosition.y /= SurfaceSize.y; //Convert to projected space -1 to 1 screenPosition *= 2.0f; screenPosition -= Vec2(1,1); screenPosition.y *= -1; //Unproject the point by applying the inverse //of the ViewProjection matrix Mat4 inverseViewProjection; float det; D3DXMatrixInverse(&inverseViewProjection,&det,&ViewProjMatrix); Vec4 worldSpacePosition; D3DXVec2Transform(&worldSpacePosition,&screenPosition,&inverseViewProjection); return Vec2(worldSpacePosition.x,worldSpacePosition.y); }
//----------------------------------------------------------------------------- // Updates the object. //----------------------------------------------------------------------------- void SceneObject::Update( float elapsed, bool addVelocity ) { // Calculate the friction for this update. float friction = 1.0f - m_friction * elapsed; // Move the object. m_velocity *= friction; if( addVelocity == true ) { D3DXVECTOR3 velocity = m_velocity * elapsed; AddTranslation( velocity.x, velocity.y, velocity.z ); } // Spin the object. m_spin *= friction; D3DXVECTOR3 spin = m_spin * elapsed; AddRotation( spin.x, spin.y, spin.z ); // Update the object's world matrix. D3DXMatrixMultiply( &m_worldMatrix, &m_rotationMatrix, &m_translationMatrix ); // Create a view matrix for the object. D3DXMatrixInverse( &m_viewMatrix, NULL, &m_worldMatrix ); // Update the object's forward vector. m_forward.x = (float)sin( m_rotation.y ); m_forward.y = (float)-tan( m_rotation.x ); m_forward.z = (float)cos( m_rotation.y ); D3DXVec3Normalize( &m_forward, &m_forward ); // Update the object's right vector. m_right.x = (float)cos( m_rotation.y ); m_right.y = (float)tan( m_rotation.z ); m_right.z = (float)-sin( m_rotation.y ); D3DXVec3Normalize( &m_right, &m_right ); // Update the object's bounding volume using the translation matrix only. // This will maintain an axis aligned bounding box around the object in // world space rather than the object's local space. RepositionBoundingVolume( &m_translationMatrix ); }
bool CGameProc::Pick(POINT ptMouse) { LPMONINFO oldMonInfo=g_pPlayer->m_pTargetInfo; D3DXMATRIX pmatProj = g_pCamera->GetProjMatrix(&pmatProj); D3DXVECTOR3 v; v.x = ( ( ( 2.0f * m_pt.x ) / m_clientWidth) - 1 ) / pmatProj._11; v.y = -( ( ( 2.0f * m_pt.y ) / m_clientHeight) - 1 ) / pmatProj._22; v.z = 1.0f; D3DXMATRIX matView=g_pCamera->GetViewMatrix(&matView); D3DXMATRIX m; D3DXVECTOR3 vDir,vPos; D3DXMatrixInverse(&m,NULL,&matView); vDir.x = v.x * m._11 + v.y * m._21 + v.z * m._31; vDir.y = v.x * m._12 + v.y * m._22 + v.z * m._32; vDir.z = v.x * m._13 + v.y * m._23 + v.z * m._33; vPos.x = m._41; vPos.y = m._42; vPos.z = m._43; m_xMonsterList.MoveCurrentToTop(); for (int nCnt=0;nCnt<m_xMonsterList.GetCounter();nCnt++) { CMonster *pMonster; pMonster=m_xMonsterList.GetCurrentData(); if(pMonster->m_pMonsterMesh->GetBoundBox()->CheckIntersectByRay(&vPos,&vDir)) { // pMonster->m_pMonsterMesh->m_bFoucs=true; g_pPlayer->m_pTargetInfo=&pMonster->m_xMonsterInfo; return true; } // else // { // // pMonster->m_pMonsterMesh->m_bFoucs=false; // g_pPlayer->m_pTargetInfo=NULL; // } m_xMonsterList.MoveNextNode(); } return false; }
/************************************************************************* * D3DXIntersectTri */ BOOL WINAPI D3DXIntersectTri(CONST D3DXVECTOR3 *p0, CONST D3DXVECTOR3 *p1, CONST D3DXVECTOR3 *p2, CONST D3DXVECTOR3 *praypos, CONST D3DXVECTOR3 *praydir, FLOAT *pu, FLOAT *pv, FLOAT *pdist) { D3DXMATRIX m; D3DXVECTOR4 vec; m.u.m[0][0] = p1->x - p0->x; m.u.m[1][0] = p2->x - p0->x; m.u.m[2][0] = -praydir->x; m.u.m[3][0] = 0.0f; m.u.m[0][1] = p1->y - p0->z; m.u.m[1][1] = p2->y - p0->z; m.u.m[2][1] = -praydir->y; m.u.m[3][1] = 0.0f; m.u.m[0][2] = p1->z - p0->z; m.u.m[1][2] = p2->z - p0->z; m.u.m[2][2] = -praydir->z; m.u.m[3][2] = 0.0f; m.u.m[0][3] = 0.0f; m.u.m[1][3] = 0.0f; m.u.m[2][3] = 0.0f; m.u.m[3][3] = 1.0f; vec.x = praypos->x - p0->x; vec.y = praypos->y - p0->y; vec.z = praypos->z - p0->z; vec.w = 0.0f; if ( D3DXMatrixInverse(&m, NULL, &m) ) { D3DXVec4Transform(&vec, &vec, &m); if ( (vec.x >= 0.0f) && (vec.y >= 0.0f) && (vec.x + vec.y <= 1.0f) && (vec.z >= 0.0f) ) { *pu = vec.x; *pv = vec.y; *pdist = fabs( vec.z ); return TRUE; } } return FALSE; }
void NVUTCamera::SetProjParams(FLOAT fFOV, FLOAT fAspect, D3DXMATRIX mView, D3DXVECTOR3 vBBox[2]) { D3DXMATRIX mViewInv; D3DXMatrixInverse(&mViewInv, NULL, &mView); D3DXVECTOR3 vView, vCorner[2], vEye; D3DXVECTOR3 vTmp(0, 0, 1); D3DXVec3TransformNormal(&vView, &vTmp, &mViewInv); vTmp = D3DXVECTOR3(0, 0, 0); D3DXVec3TransformCoord(&vEye, &vTmp, &mViewInv); D3DXVec3Normalize(&vView, &vView); for (int ic = 0; ic < 3; ++ic) { vCorner[0][ic] = (vView[ic] < 0) ? vBBox[0][ic] : vBBox[1][ic]; vCorner[1][ic] = (vView[ic] < 0) ? vBBox[1][ic] : vBBox[0][ic]; } vTmp = vCorner[0] - vEye; float fFar = max(0.01f, 1.2f * D3DXVec3Dot(&vTmp, &vView)); vTmp = vCorner[1] - vEye; float fNear = max(fFar / 100, D3DXVec3Dot(&vTmp, &vView)); CModelViewerCamera::SetProjParams(fFOV, fAspect, fNear, fFar); }
QUAT Storm3D_Spotlight::getOrientation() const { D3DXVECTOR3 lightPosition(data->properties.position.x, data->properties.position.y, data->properties.position.z); D3DXVECTOR3 up(0, 1.f, 0); D3DXVECTOR3 lookAt = lightPosition; lookAt += D3DXVECTOR3(data->properties.direction.x, data->properties.direction.y, data->properties.direction.z); D3DXMATRIX tm; D3DXMatrixLookAtLH(&tm, &lightPosition, &lookAt, &up); float det = D3DXMatrixDeterminant(&tm); D3DXMatrixInverse(&tm, &det, &tm); MAT m; for(int j = 0; j < 4; ++j) for(int i = 0; i < 4; ++i) m.Set(j*4 + i, tm[j*4 + i]); return m.GetRotation(); }
void PropsDemo::drawObject(Object3D& obj, const D3DXMATRIX& toWorld) { // Transform AABB into the world space. AABB box; obj.box.xform(toWorld, box); // Only draw if AABB is visible. if( gCamera->isVisible( box ) ) { HR(mFX->SetMatrix(mhWVP, &(toWorld*gCamera->viewProj()))); D3DXMATRIX worldInvTrans; D3DXMatrixInverse(&worldInvTrans, 0, &toWorld); D3DXMatrixTranspose(&worldInvTrans, &worldInvTrans); HR(mFX->SetMatrix(mhWorldInvTrans, &worldInvTrans)); HR(mFX->SetMatrix(mhWorld, &toWorld)); for(UINT j = 0; j < obj.mtrls.size(); ++j) { HR(mFX->SetValue(mhMtrl, &obj.mtrls[j], sizeof(Mtrl))); // If there is a texture, then use. if(obj.textures[j] != 0) { HR(mFX->SetTexture(mhTex, obj.textures[j])); } // But if not, then set a pure white texture. When the texture color // is multiplied by the color from lighting, it is like multiplying by // 1 and won't change the color from lighting. else { HR(mFX->SetTexture(mhTex, mWhiteTex)); } HR(mFX->CommitChanges()); HR(obj.mesh->DrawSubset(j)); } } }
// Update the scene for every frame void Camera::OnFrameMove() { // No need to handle if no drag since last frame move if(!m_bDragSinceLastUpdate) return ; m_bDragSinceLastUpdate = false ; if(m_nMouseWheelDelta) { m_fRadius -= m_nMouseWheelDelta * m_fRadius * 0.1f / 120.0f; // Make the radius in range of [m_fMinRadius, m_fMaxRadius] // This can Prevent the cube became too big or too small m_fRadius = max(m_fRadius, m_fMinRadius) ; m_fRadius = min(m_fRadius, m_fMaxRadius) ; } // The mouse delta is retrieved IN every WM_MOUSE message and do not accumulate, so clear it after one frame m_nMouseWheelDelta = 0 ; // Get the inverse of the view Arcball's rotation matrix D3DXMATRIX mCameraRot ; D3DXMatrixInverse( &mCameraRot, NULL, m_ViewArcBall.GetRotationMatrix() ); // Transform vectors based on camera's rotation matrix D3DXVECTOR3 vWorldUp; D3DXVECTOR3 vLocalUp = D3DXVECTOR3( 0, 1, 0 ); D3DXVec3TransformCoord( &vWorldUp, &vLocalUp, &mCameraRot ); D3DXVECTOR3 vWorldAhead; D3DXVECTOR3 vLocalAhead = D3DXVECTOR3( 0, 0, 1 ); D3DXVec3TransformCoord( &vWorldAhead, &vLocalAhead, &mCameraRot ); // Update the eye point based on a radius away from the lookAt position m_vEyePt = m_vLookatPt - vWorldAhead * m_fRadius; // Update the view matrix D3DXMatrixLookAtLH( &m_matView, &m_vEyePt, &m_vLookatPt, &vWorldUp ); }
void AmbientDiffuseDemo::drawScene() { // Clear the backbuffer and depth buffer. HR(gd3dDevice->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffeeeeee, 1.0f, 0)); HR(gd3dDevice->BeginScene()); // Setup the rendering FX HR(mFX->SetTechnique(mhTech)); HR(mFX->SetMatrix(mhWVP, &(mWorld*mView*mProj))); D3DXMATRIX worldInverseTranspose; D3DXMatrixInverse(&worldInverseTranspose, 0, &mWorld); D3DXMatrixTranspose(&worldInverseTranspose, &worldInverseTranspose); HR(mFX->SetMatrix(mhWorldInverseTranspose, &worldInverseTranspose)); HR(mFX->SetValue(mhLightVecW, &mLightVecW, sizeof(D3DXVECTOR3))); HR(mFX->SetValue(mhDiffuseMtrl, &mDiffuseMtrl, sizeof(D3DXCOLOR))); HR(mFX->SetValue(mhDiffuseLight, &mDiffuseLight, sizeof(D3DXCOLOR))); HR(mFX->SetValue(mhAmbientMtrl, &mAmbientMtrl, sizeof(D3DXCOLOR))); HR(mFX->SetValue(mhAmbientLight, &mAmbientLight, sizeof(D3DXCOLOR))); // Begin passes. UINT numPasses = 0; HR(mFX->Begin(&numPasses, 0)); for(UINT i = 0; i < numPasses; ++i) { HR(mFX->BeginPass(i)); HR(mTeapot->DrawSubset(0)); HR(mFX->EndPass()); } HR(mFX->End()); mGfxStats->display(); HR(gd3dDevice->EndScene()); // Present the backbuffer. HR(gd3dDevice->Present(0, 0, 0, 0)); }
Matrix3& Matrix3::Invert() { #ifdef __USE_D3DX__ Float32 fDet; fDet = D3DXMatrixDeterminant( (D3DXMATRIX*)&mat ); D3DXMatrixInverse( (D3DXMATRIX*)&mat, &fDet, (D3DXMATRIX*)&mat ); #else Real inv[16], fDet; inv[0] = e[5] * e[10] * e[15] - e[5] * e[11] * e[14] - e[9] * e[6] * e[15] + e[9] * e[7] * e[14] + e[13] * e[6] * e[11] - e[13] * e[7] * e[10]; inv[4] =-e[4] * e[10] * e[15] + e[4] * e[11] * e[14] + e[8] * e[6] * e[15] - e[8] * e[7] * e[14] - e[12] * e[6] * e[11] + e[12] * e[7] * e[10]; inv[8] = e[4] * e[9] * e[15] - e[4] * e[11] * e[13] - e[8] * e[5] * e[15] + e[8] * e[7] * e[13] + e[12] * e[5] * e[11] - e[12] * e[7] * e[9]; inv[12] =-e[4] * e[9] * e[14] + e[4] * e[10] * e[13] + e[8] * e[5] * e[14] - e[8] * e[6] * e[13] - e[12] * e[5] * e[10] + e[12] * e[6] * e[9]; inv[1] =-e[1] * e[10] * e[15] + e[1] * e[11] * e[14] + e[9] * e[2] * e[15] - e[9] * e[3] * e[14] - e[13] * e[2] * e[11] + e[13] * e[3] * e[10]; inv[5] = e[0] * e[10] * e[15] - e[0] * e[11] * e[14] - e[8] * e[2] * e[15] + e[8] * e[3] * e[14] + e[12] * e[2] * e[11] - e[12] * e[3] * e[10]; inv[9] =-e[0] * e[9] * e[15] + e[0] * e[11] * e[13] + e[8] * e[1] * e[15] - e[8] * e[3] * e[13] - e[12] * e[1] * e[11] + e[12] * e[3] * e[9]; inv[13] = e[0] * e[9] * e[14] - e[0] * e[10] * e[13] - e[8] * e[1] * e[14] + e[8] * e[2] * e[13] + e[12] * e[1] * e[10] - e[12] * e[2] * e[9]; inv[2] = e[1] * e[6] * e[15] - e[1] * e[7] * e[14] - e[5] * e[2] * e[15] + e[5] * e[3] * e[14] + e[13] * e[2] * e[7] - e[13] * e[3] * e[6]; inv[6] =-e[0] * e[6] * e[15] + e[0] * e[7] * e[14] + e[4] * e[2] * e[15] - e[4] * e[3] * e[14] - e[12] * e[2] * e[7] + e[12] * e[3] * e[6]; inv[10] = e[0] * e[5] * e[15] - e[0] * e[7] * e[13] - e[4] * e[1] * e[15] + e[4] * e[3] * e[13] + e[12] * e[1] * e[7] - e[12] * e[3] * e[5]; inv[14] =-e[0] * e[5] * e[14] + e[0] * e[6] * e[13] + e[4] * e[1] * e[14] - e[4] * e[2] * e[13] - e[12] * e[1] * e[6] + e[12] * e[2] * e[5]; inv[3] =-e[1] * e[6] * e[11] + e[1] * e[7] * e[10] + e[5] * e[2] * e[11] - e[5] * e[3] * e[10] - e[9] * e[2] * e[7] + e[9] * e[3] * e[6]; inv[7] = e[0] * e[6] * e[11] - e[0] * e[7] * e[10] - e[4] * e[2] * e[11] + e[4] * e[3] * e[10] + e[8] * e[2] * e[7] - e[8] * e[3] * e[6]; inv[11] =-e[0] * e[5] * e[11] + e[0] * e[7] * e[9] + e[4] * e[1] * e[11] - e[4] * e[3] * e[9] - e[8] * e[1] * e[7] + e[8] * e[3] * e[5]; inv[15] = e[0] * e[5] * e[10] - e[0] * e[6] * e[9] - e[4] * e[1] * e[10] + e[4] * e[2] * e[9] + e[8] * e[1] * e[6] - e[8] * e[2] * e[5]; fDet = e[0] * inv[0] + e[1] * inv[4] + e[2] * inv[8] + e[3] * inv[12]; if( fDet != 0 ) { fDet = 1.0f / fDet; for( Int32 i = 0; i < 16; i++ ) (*this)[i] = inv[i] * fDet; } #endif return *this; }
void PondWater::buildFX() { ID3DXBuffer* errors = 0; HR(D3DXCreateEffectFromFile(gd3dDevice, _T("PondWater.fx"), 0, 0, D3DXSHADER_DEBUG, 0, &mFX, &errors)); if( errors ) MessageBoxA(0, (char*)errors->GetBufferPointer(), 0, 0); mhTech = mFX->GetTechniqueByName("WaterTech"); mhWorld = mFX->GetParameterByName(0, "gWorld"); mhWorldInv = mFX->GetParameterByName(0, "gWorldInv"); mhWVP = mFX->GetParameterByName(0, "gWVP"); mhEyePosW = mFX->GetParameterByName(0, "gEyePosW"); mhLight = mFX->GetParameterByName(0, "gLight"); mhMtrl = mFX->GetParameterByName(0, "gMtrl"); mhWaveMap0 = mFX->GetParameterByName(0, "gWaveMap0"); mhWaveMap1 = mFX->GetParameterByName(0, "gWaveMap1"); mhWaveMapOffset0 = mFX->GetParameterByName(0, "gWaveMapOffset0"); mhWaveMapOffset1 = mFX->GetParameterByName(0, "gWaveMapOffset1"); mhRefractBias = mFX->GetParameterByName(0, "gRefractBias"); mhRefractPower = mFX->GetParameterByName(0, "gRefractPower"); mhRippleScale = mFX->GetParameterByName(0, "gRippleScale"); mhReflectMap = mFX->GetParameterByName(0, "gReflectMap"); mhRefractMap = mFX->GetParameterByName(0, "gRefractMap"); // We don't need to set these every frame since they do not change. HR(mFX->SetMatrix(mhWorld, &mInitInfo.toWorld)); D3DXMATRIX worldInv; D3DXMatrixInverse(&worldInv, 0, &mInitInfo.toWorld); HR(mFX->SetMatrix(mhWorldInv, &worldInv)); HR(mFX->SetTechnique(mhTech)); HR(mFX->SetTexture(mhWaveMap0, mWaveMap0)); HR(mFX->SetTexture(mhWaveMap1, mWaveMap1)); HR(mFX->SetValue(mhLight, &mInitInfo.dirLight, sizeof(DirLight))); HR(mFX->SetValue(mhMtrl, &mInitInfo.mtrl, sizeof(Mtrl))); HR(mFX->SetValue(mhRefractBias, &mInitInfo.refractBias, sizeof(float))); HR(mFX->SetValue(mhRefractPower, &mInitInfo.refractPower, sizeof(float))); HR(mFX->SetValue(mhRippleScale, &mInitInfo.rippleScale, sizeof(D3DXVECTOR2))); }
Vector3 Camera::Get3DPickingRay() { Vector3 v; POINT p; if(GetCursorPos(&p)) { if(ScreenToClient(this->g_hWnd, &p)) { v.x = (((2.0f * p.x) / this->params.windowWidth) - 1) / this->GetProjectionMatrix()._11; v.y = -(((2.0f * p.y) / this->params.windowHeight) - 1) / this->GetProjectionMatrix()._22; v.z = 1.0f; D3DXMATRIX m; D3DXVECTOR3 rayOrigin,rayDir; D3DXMatrixInverse(&m, NULL, &this->GetViewMatrix()); // Transform the screen space pick ray into 3D space rayDir.x = v.x * m._11 + v.y * m._21 + v.z * m._31; rayDir.y = v.x * m._12 + v.y * m._22 + v.z * m._32; rayDir.z = v.x * m._13 + v.y * m._23 + v.z * m._33; rayOrigin.x = m._41; rayOrigin.y = m._42; rayOrigin.z = m._43; rayDir = this->NormalizeVector(rayDir); v.x = rayDir.x; v.y = rayDir.y; v.z = rayDir.z; } else MaloW::Debug("Get3DPickingRay failed."); } else MaloW::Debug("Get3DPickingRay failed."); return v; }
void DXSampleWidget::mousePressEvent(QMouseEvent *event) { D3DXMATRIX projectionMatrix; m_d3d->getProjectionMatrix(projectionMatrix); float x = ((2.0f * (float)event->x()) / (float)width() - 1.0f) / projectionMatrix._11; float y = ((-2.0f * (float)event->y()) / (float)height() + 1.0f) / projectionMatrix._22; D3DXVECTOR3 lightDirection (x, y, 1.0f); D3DXMATRIX viewMatrix, inverseViewMatrix; m_camera->getViewMatrix(viewMatrix); D3DXMatrixInverse(&inverseViewMatrix, NULL, &viewMatrix); D3DXVec3TransformNormal(&lightDirection, &lightDirection, &inverseViewMatrix); lightDirection.x *= m_camera->getPosition().z; lightDirection.y *= m_camera->getPosition().z; D3DXVec3Normalize(&lightDirection, &lightDirection); m_light->setDirection(lightDirection.x, lightDirection.y, lightDirection.z); }
// @brief : 行列の作成 //-------------------------------------------------------------------- void TransLookCameraDx9::CreateMatrix(void) { const D3DXVECTOR3 pos = Vector3(Position); const Camera *cam = Cam(); D3DXMATRIX mtx_rot; { D3DXVECTOR3 eye = -Vector3(cam->Eye); D3DXVECTOR3 at = -Vector3(cam->At); D3DXVECTOR3 up = -Vector3(cam->Up); D3DXMatrixLookAtLH(&mtx_rot,&eye,&at,&up); D3DXMatrixInverse(&mtx_rot,NULL,&mtx_rot); mtx_rot._14 = mtx_rot._24 = mtx_rot._34 = mtx_rot._41 = mtx_rot._42 = mtx_rot._43 = 0.0f; mtx_rot._44 = 1.0f; } D3DXMATRIX mtx_pos; D3DXMatrixTranslation(&mtx_pos,pos.x,pos.y,pos.z); D3DXMatrixMultiply(&m_Matrix,&mtx_rot,&mtx_pos); }
void SpotlightDemo::drawGrid() { HR(gd3dDevice->SetStreamSource(0, mVB, 0, sizeof(VertexPN))); HR(gd3dDevice->SetIndices(mIB)); HR(gd3dDevice->SetVertexDeclaration(VertexPN::Decl)); D3DXMATRIX W, WIT; D3DXMatrixIdentity(&W); D3DXMatrixInverse(&WIT, 0, &W); D3DXMatrixTranspose(&WIT, &WIT); HR(mFX->SetMatrix(mhWorld, &W)); HR(mFX->SetMatrix(mhWVP, &(W*mView*mProj))); HR(mFX->SetMatrix(mhWorldInvTrans, &WIT)); HR(mFX->SetValue(mhAmbientMtrl, &mGridMtrl.ambient, sizeof(D3DXCOLOR))); HR(mFX->SetValue(mhDiffuseMtrl, &mGridMtrl.diffuse, sizeof(D3DXCOLOR))); HR(mFX->SetValue(mhSpecMtrl, &mGridMtrl.spec, sizeof(D3DXCOLOR))); HR(mFX->SetFloat(mhSpecPower, mGridMtrl.specPower)); HR(mFX->CommitChanges()); HR(gd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, mNumGridVertices, 0, mNumGridTriangles)); }
// 撮影 void Camera::View() { D3DXMATRIX *m_temp = new D3DXMATRIX; D3DXMatrixIdentity(&m_view); D3DXMatrixIdentity(m_temp); // 行列を回転する D3DXMatrixRotationYawPitchRoll(m_temp, rota.y, rota.x, rota.z); m_view *= *m_temp; // 行列を平行移動させる D3DXMatrixTranslation(m_temp, pos.x, pos.y, pos.z); m_view *= *m_temp; D3DXMatrixIdentity(m_temp); D3DXMatrixInverse(m_temp, nullptr, &m_view); // カメラの逆行列を求める // ビュー行列を設定 render->GetD3d()->SetTransform(D3DTS_VIEW, m_temp); delete m_temp; }
// 카메라에 따라 occlusion의 평면을 갱신한다. void ROcclusionList::UpdateCamera(rmatrix &matWorld,rvector &cameraPos) { // TODO : matWorld 가 identity 가 아닌경우 검증이 안되어있음 float fDet; rmatrix invWorld; D3DXMatrixInverse(&invWorld,&fDet,&matWorld); // camera 의 좌표를 local로 가져온다 rvector localCameraPos; D3DXVec3TransformCoord(&localCameraPos,&cameraPos,&invWorld); rmatrix trInvMat; D3DXMatrixTranspose(&trInvMat, &invWorld); for(ROcclusionList::iterator i=begin();i!=end();i++) { ROcclusion *poc=*i; bool bm_pPositive=D3DXPlaneDotCoord(&poc->plane,&localCameraPos)>0; // 로컬의 평면의 방정식을 월드로 가져가고 싶다. matWorld 로 변환하면되는데, // D3DXPlaneTransform 의 사용법이 변환행렬의 inverse transpose 매트릭스를 넘겨줘야하므로 // tr(inv(matWorld)) 가 되므로 결국 tr(mat) 가 된다 D3DXPlaneTransform(poc->pPlanes,poc->pPlanes,&trInvMat); poc->pPlanes[0] = bm_pPositive ? poc->plane : -poc->plane; for(int j=0;j<poc->nCount;j++) { if(bm_pPositive) D3DXPlaneFromPoints(poc->pPlanes+j+1,&poc->pVertices[j],&poc->pVertices[(j+1)%poc->nCount],&localCameraPos); else D3DXPlaneFromPoints(poc->pPlanes+j+1,&poc->pVertices[(j+1)%poc->nCount],&poc->pVertices[j],&localCameraPos); // 로컬의 평면의 방정식을 월드로 가져가고 싶다. 위와 같다 D3DXPlaneTransform(poc->pPlanes+j+1,poc->pPlanes+j+1,&trInvMat); } } }
void Graphics::setEffectParameters(D3DXMATRIX world) { Light lights1[4]; for(int i = 0; i < mLightList->size(); i++) lights1[i] = *mLightList->operator[](i); // Calculate the inverse transpose matrix. D3DXMATRIX worldInverseTranspose; D3DXMatrixInverse(&worldInverseTranspose, 0, &world); D3DXMatrixTranspose(&worldInverseTranspose, &worldInverseTranspose); // Set the parameters. HR(mFX->SetMatrix(mhWVP, &(world*gCamera->getViewMatrix()*gCamera->getProjectionMatrix()))); HR(mFX->SetMatrix(mhWorld, &world)); HR(mFX->SetVector(mhEyePos, &D3DXVECTOR4(gCamera->getPosition(), 0))); HR(mFX->SetMatrix(mhWorldInverseTranspose, &worldInverseTranspose)); HR(mFX->SetInt(mhNumLights, mLightList->size())); HR(mFX->SetRawValue(mhLights, (void*)&lights1, 0, sizeof(Light)*mLightList->size())); // Set the DEFUALT = WHITE object material and the light array (max 4 lights right now). HR(mFX->SetRawValue(mhObjectMaterial, (void*)&Material(), 0, sizeof(Material))); }
void FrustumPlanes::GetPoints(const MATRIX& WorldViewProj,VEC3* points) { assert(points); MATRIX WorldViewProjInv; D3DXMatrixInverse( &WorldViewProjInv, NULL, &WorldViewProj); D3DXVECTOR3 P[] = { D3DXVECTOR3(-1.f, -1.f, 0.f), D3DXVECTOR3(+1.f, -1.f, 0.f), D3DXVECTOR3(-1.f, +1.f, 0.f), D3DXVECTOR3(+1.f, +1.f, 0.f), D3DXVECTOR3(-1.f, -1.f, 1.f), D3DXVECTOR3(+1.f, -1.f, 1.f), D3DXVECTOR3(-1.f, +1.f, 1.f), D3DXVECTOR3(+1.f, +1.f, 1.f) }; D3DXVec3TransformCoord(&points[0], &P[0], &WorldViewProjInv); D3DXVec3TransformCoord(&points[1], &P[1], &WorldViewProjInv); D3DXVec3TransformCoord(&points[2], &P[2], &WorldViewProjInv); D3DXVec3TransformCoord(&points[3], &P[3], &WorldViewProjInv); D3DXVec3TransformCoord(&points[4], &P[4], &WorldViewProjInv); D3DXVec3TransformCoord(&points[5], &P[5], &WorldViewProjInv); D3DXVec3TransformCoord(&points[6], &P[6], &WorldViewProjInv); D3DXVec3TransformCoord(&points[7], &P[7], &WorldViewProjInv); }