VOID UpdateViewMatrix() { XMVECTOR vCameraPos = XMLoadFloat4A( &g_CameraPos ); XMVECTOR vCameraTarget = vCameraPos * XMVectorSet( 1, 0, 1, 1 ); XMMATRIX matView = XMMatrixLookAtLH( vCameraPos, vCameraTarget, XMVectorSet( 0, 0, 1, 0 ) ); XMStoreFloat4x4A( &g_matView, matView ); }
// 정상적으로 동작하지 않습니다. 반드시 기본 포맷을 이용하여 적절한 Position 값을 대입해야 합니다. int CMesh::CheckRayIntersection(FXMVECTOR xmvRayPosition, FXMVECTOR xmvRayDirection, MESHINTERSECTINFO * pd3dxIntersectInfo) { vector<XMVECTOR> m_pd3dxvPositions; auto m_nIndices = static_cast<UINT>(m_vIndies.size()); int nIntersections = 0; BYTE * pbPositions = reinterpret_cast<BYTE *>(&m_pd3dxvPositions[0]) + m_vVertexOffset[0]; auto nOffset = (m_d3dPrimitiveTopology == D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST) ? 3 : 1; UINT nPrimitives = (m_d3dPrimitiveTopology == D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST) ? (m_nVertices / 3) : (m_nVertices - 2); if (m_vIndies.size() > 0) nPrimitives = (m_d3dPrimitiveTopology == D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST) ? (m_nIndices / 3) : (m_nIndices - 2); XMFLOAT4A v0, v1, v2; float fHitDistance, fNearHitDistance = FLT_MAX; for (UINT i = 0; i < nPrimitives; i++) { v0 = *(XMFLOAT4A *) (pbPositions + ((m_nIndices > 0) ? (m_vIndies[(i * nOffset) + 0]) : ((i * nOffset) + 0)) * m_vVertexStrides[0]); v1 = *(XMFLOAT4A *) (pbPositions + ((m_nIndices > 0) ? (m_vIndies[(i * nOffset) + 1]) : ((i * nOffset) + 1)) * m_vVertexStrides[0]); v2 = *(XMFLOAT4A *) (pbPositions + ((m_nIndices > 0) ? (m_vIndies[(i * nOffset) + 2]) : ((i * nOffset) + 2)) * m_vVertexStrides[0]); XMVECTOR xmv[3] { XMLoadFloat4A(&v0), XMLoadFloat4A(&v1), XMLoadFloat4A(&v2) }; if (DirectX::TriangleTests::Intersects(xmvRayPosition, XMVector4Normalize(xmvRayDirection), xmv[0], xmv[1], xmv[2], fHitDistance)) { if (fHitDistance < fNearHitDistance) { fNearHitDistance = fHitDistance; if (pd3dxIntersectInfo) { pd3dxIntersectInfo->m_dwFaceIndex = i; pd3dxIntersectInfo->m_fU = 0.f; pd3dxIntersectInfo->m_fV = 0.f; pd3dxIntersectInfo->m_fDistance = fHitDistance; } } nIntersections++; } } return(nIntersections); }
operator XMVECTOR () const { return XMLoadFloat4A(this); }
//-------------------------------------------------------------------------------------- // Handles mouse input //-------------------------------------------------------------------------------------- void CALLBACK OnMouse( bool bLeftButtonDown, bool bRightButtonDown, bool bMiddleButtonDown, bool bSideButton1Down, bool bSideButton2Down, int nMouseWheelDelta, int xPos, int yPos, void* pUserContext ) { if( g_bDrawTerrain ) { if( bRightButtonDown ) { if( g_pInspectionTexture != NULL ) { g_pInspectionTexture = NULL; } else { g_pInspectionTexture = g_pTerrainView->GetInspectionTexture(); } g_InspectionSliceIndex = 0; } return; } static BOOL MouseDragging = FALSE; static XMFLOAT4 DragMouseCursorPos( 0, 0, 0, 0 ); static XMFLOAT4 DragCameraPos( 0, 0, 0, 0 ); // vMousePos is the mouse cursor's location on the Z far and near planes in homogenous space XMVECTOR vMousePosFar = XMVectorSet( ( (FLOAT)xPos - g_HalfClientWidthPixels ) / g_HalfClientWidthPixels, ( (FLOAT)yPos - g_HalfClientHeightPixels ) / -g_HalfClientHeightPixels, 1, 1 ); XMMATRIX matView = XMLoadFloat4x4A( &g_matView ); XMMATRIX matViewProj = matView * XMLoadFloat4x4A( &g_matProjection ); XMVECTOR vDet; XMMATRIX matInvViewProj = XMMatrixInverse( &vDet, matViewProj ); // vMouseWorldPos is the location in world space of the mouse cursor on the near plane XMVECTOR vMouseWorldPosFar = XMVector3TransformCoord( vMousePosFar, matInvViewProj ); XMVECTOR vCameraPosWorld = XMLoadFloat4A( &g_CameraPos ); const XMVECTOR vPlaneNormal = XMVectorSet( 0, 1, 0, 0 ); const XMVECTOR vPlaneDistance = XMVectorZero(); XMVECTOR vCameraToMouseWorldFar = vMouseWorldPosFar - vCameraPosWorld; XMVECTOR t = ( vPlaneDistance - XMVector3Dot( vPlaneNormal, vCameraPosWorld ) ) / XMVector3Dot( vPlaneNormal, vCameraToMouseWorldFar ); XMVECTOR vMouseCursorWorld = vCameraPosWorld + t * vCameraToMouseWorldFar; if( bLeftButtonDown ) { if( !MouseDragging ) { MouseDragging = TRUE; XMStoreFloat4( &DragMouseCursorPos, vMouseCursorWorld ); XMStoreFloat4( &DragCameraPos, vCameraPosWorld ); } else { XMVECTOR vDragPos = XMLoadFloat4( &DragMouseCursorPos ); XMVECTOR vCameraDelta = vMouseCursorWorld - vDragPos; vCameraPosWorld -= vCameraDelta; XMStoreFloat4A( &g_CameraPos, vCameraPosWorld ); UpdateViewMatrix(); XMStoreFloat4( &DragCameraPos, vCameraPosWorld ); } } else if( MouseDragging ) { MouseDragging = FALSE; } if( bRightButtonDown ) { ID3D11TiledTexture2D* pCurrentTexture = g_pInspectionTexture; g_pInspectionTexture = NULL; UINT SceneObjectCount = (UINT)g_SceneObjects.size(); for( UINT i = 0; i < SceneObjectCount; ++i ) { const SceneObject* pSO = g_SceneObjects[i]; FLOAT X = pSO->matWorld._41; FLOAT Y = pSO->matWorld._43; FLOAT DeltaX = fabsf( X - XMVectorGetX( vMouseCursorWorld ) ); FLOAT DeltaY = fabsf( Y - XMVectorGetZ( vMouseCursorWorld ) ); if( DeltaX <= 0.5f && DeltaY <= 0.5f ) { g_pInspectionTexture = pSO->Textures[0].pTexture; break; } } if( g_pInspectionTexture != pCurrentTexture ) { g_InspectionSliceIndex = 0; } } if( nMouseWheelDelta != 0 ) { const FLOAT LogMoveSpeed = 0.05f * ( (FLOAT)nMouseWheelDelta / 120.0f ); FLOAT CameraY = XMVectorGetY( vCameraPosWorld ); float LogYPos = logf( CameraY ); LogYPos -= LogMoveSpeed; vCameraPosWorld = XMVectorSetY( vCameraPosWorld, max( 0.001f, expf( LogYPos ) ) ); XMStoreFloat4A( &g_CameraPos, vCameraPosWorld ); UpdateViewMatrix(); } }