DirectX::SimpleMath::Ray D3D11App::CalcPickingRay(int sx, int sy) { XMMATRIX view = g_objTrackballCameraController.View(); //投影变换 Matrix P = g_objTrackballCameraController.Proj(); float vx = (+2.0f*sx / mClientWidth - 1.0f) / (P(0, 0)); float vy = (-2.0f*sy / mClientHeight + 1.0f) / (P(1, 1)); // Ray definition in view space. XMVECTOR rayOrigin = XMVectorSet(0.0f, 0.0f, 0.0f, 1.0f); XMVECTOR rayDir = XMVectorSet(vx, vy, 1.0f, 0.0f); XMMATRIX invP = XMMatrixInverse(&XMMatrixDeterminant(P), P); // Tranform ray to local space of Mesh. XMMATRIX V = view; XMMATRIX invView = XMMatrixInverse(&XMMatrixDeterminant(V), V); XMMATRIX W = Matrix::Identity; XMMATRIX invWorld = XMMatrixInverse(&XMMatrixDeterminant(W), W); XMMATRIX toLocal = XMMatrixMultiply(invView, invWorld); rayOrigin = XMVector3TransformCoord(rayOrigin, toLocal); rayDir = XMVector3TransformNormal(rayDir, toLocal); // Make the ray direction unit length for the intersection tests. rayDir = XMVector3Normalize(rayDir); DirectX::SimpleMath::Ray ray(rayOrigin, rayDir); return ray; }
void Direct3D::updateConstantBuffers() { //First pass constant buffer update m_FirstPassStruct.firstPass = 1; m_DeviceContext->UpdateSubresource(m_FirstPassCBuffer, 0, 0, &m_FirstPassStruct, 0, 0); m_DeviceContext->CSSetConstantBuffers(0, 1, &m_FirstPassCBuffer); //Primary Constant buffer PrimaryConstBuffer PCBufferStruct; PCBufferStruct.cameraPos = m_pCamera->getPosition(); //Inverse view matrix XMMATRIX mInvView = XMLoadFloat4x4(&m_pCamera->getViewMat()); XMVECTOR mViewDet = XMMatrixDeterminant(mInvView); mInvView = XMMatrixInverse(&mViewDet, mInvView); mInvView = XMMatrixTranspose(mInvView); XMStoreFloat4x4(&PCBufferStruct.IV, mInvView); //Inverse projection matrix XMMATRIX mInvProj = XMLoadFloat4x4(&m_pCamera->getProjMat()); XMVECTOR mProjDet = XMMatrixDeterminant(mInvProj); mInvProj = XMMatrixInverse(&mProjDet, mInvProj); mInvProj = XMMatrixTranspose(mInvProj); XMStoreFloat4x4(&PCBufferStruct.IP, mInvProj); m_DeviceContext->UpdateSubresource(m_PrimaryCBuffer, 0, 0, &PCBufferStruct, 0, 0); //Intersection constant buffer IntersectionConstBuffer ICBufferStruct; ICBufferStruct.sphere = m_sphere; for(int i = 0; i < NROFTRIANGLES; i++) { ICBufferStruct.triangles[i] = m_triangles[i]; } ICBufferStruct.nrOfFaces = m_mesh.getFaces(); ICBufferStruct.pad = XMFLOAT3(0.f, 0.f, 0.f); m_DeviceContext->UpdateSubresource(m_IntersectionCBuffer, 0, 0, &ICBufferStruct, 0, 0); //Color constant buffer ColorConstBuffer CCBufferStruct; CCBufferStruct.sphere = m_sphere; for(int i = 0; i < NROFTRIANGLES; i++) { CCBufferStruct.triangles[i] = m_triangles[i]; } for(int i = 0; i < NROFLIGHTS; i++) { CCBufferStruct.lightList[i] = m_lightList[i]; } CCBufferStruct.nrOfFaces = m_mesh.getFaces(); CCBufferStruct.pad = XMFLOAT3(0.f, 0.f, 0.f); m_DeviceContext->UpdateSubresource(m_ColorCBuffer, 0, 0, &CCBufferStruct, 0, 0); }
int DuckHuntMain::pick(float x, float y, std::vector<BasicModelInstance> models) { XMMATRIX P = mCam.Proj(); // Compute picking ray in view space. int newWidth, newHeight; float fs; newWidth = mScreenViewport.Width; newHeight = mScreenViewport.Height; fs = 1.0f; float vx = (+2.0f*x / newWidth - fs) / P(0, 0); float vy = (-2.0f*y / newHeight + fs) / P(1, 1); // Ray definition in view space. XMVECTOR rayOrigin = XMVectorSet(0.0f, 0.0f, 0.0f, 1.0f); XMVECTOR rayDir = XMVectorSet(vx, vy, 1.0f, 0.0f); // Tranform ray to local space of Mesh. XMMATRIX V = mCam.View(); XMMATRIX invView = XMMatrixInverse(&XMMatrixDeterminant(V), V); for (unsigned i = 0; i < models.size(); ++i) { XMMATRIX W = XMLoadFloat4x4(&models[i].World); XMMATRIX invWorld = XMMatrixInverse(&XMMatrixDeterminant(W), W); XMMATRIX toLocal = XMMatrixMultiply(invView, invWorld); rayOrigin = XMVector3TransformCoord(rayOrigin, toLocal); rayDir = XMVector3TransformNormal(rayDir, toLocal); // Make the ray direction unit length for the intersection tests. rayDir = XMVector3Normalize(rayDir); float tmin = 0.0f; // The Returned Distance if (XNA::IntersectRayAxisAlignedBox(rayOrigin, rayDir, &models[i].Model->collisionBox, &tmin)) { //WE ARE IN THE MESH .. DO WHATEVER YOU WANT return i; } } return -1; }
XMMATRIX InverseTranspose(CXMMATRIX M) { XMMATRIX A = M; A.r[3] = XMVectorSet(0.0f, 0.0f, 0.0f, 1.0f); XMVECTOR det = XMMatrixDeterminant(A); return XMMatrixTranspose(XMMatrixInverse(&det, A)); }
// Set the render state before drawing this object //----------------------------------------------------------------------------- void CPUTModelDX11::UpdateShaderConstants(CPUTRenderParameters &renderParams) { ID3D11DeviceContext *pContext = ((CPUTRenderParametersDX*)&renderParams)->mpContext; D3D11_MAPPED_SUBRESOURCE mapInfo; pContext->Map( mpModelConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapInfo ); { CPUTModelConstantBuffer *pCb = (CPUTModelConstantBuffer*)mapInfo.pData; // TODO: remove construction of XMM type XMMATRIX world((float*)GetWorldMatrix()); pCb->World = world; CPUTCamera *pCamera = renderParams.mpCamera; XMVECTOR cameraPos = XMLoadFloat3(&XMFLOAT3( 0.0f, 0.0f, 0.0f )); if( pCamera ) { XMMATRIX view((float*)pCamera->GetViewMatrix()); XMMATRIX projection((float*)pCamera->GetProjectionMatrix()); float *pCameraPos = (float*)&pCamera->GetPosition(); cameraPos = XMLoadFloat3(&XMFLOAT3( pCameraPos[0], pCameraPos[1], pCameraPos[2] )); // Note: We compute viewProjection to a local to avoid reading from write-combined memory. // The constant buffer uses write-combined memory. We read this matrix when computing WorldViewProjection. // It is very slow to read it directly from the constant buffer. XMMATRIX viewProjection = view * projection; pCb->ViewProjection = viewProjection; pCb->WorldViewProjection = world * viewProjection; XMVECTOR determinant = XMMatrixDeterminant(world); pCb->InverseWorld = XMMatrixInverse(&determinant, XMMatrixTranspose(world)); } // TODO: Have the lights set their render states? XMVECTOR lightDirection = XMLoadFloat3(&XMFLOAT3( gLightDir.x, gLightDir.y, gLightDir.z )); pCb->LightDirection = XMVector3Normalize(lightDirection); pCb->EyePosition = cameraPos; float *bbCWS = (float*)&mBoundingBoxCenterWorldSpace; float *bbHWS = (float*)&mBoundingBoxHalfWorldSpace; float *bbCOS = (float*)&mBoundingBoxCenterObjectSpace; float *bbHOS = (float*)&mBoundingBoxHalfObjectSpace; pCb->BoundingBoxCenterWorldSpace = XMLoadFloat3(&XMFLOAT3( bbCWS[0], bbCWS[1], bbCWS[2] )); ; pCb->BoundingBoxHalfWorldSpace = XMLoadFloat3(&XMFLOAT3( bbHWS[0], bbHWS[1], bbHWS[2] )); ; pCb->BoundingBoxCenterObjectSpace = XMLoadFloat3(&XMFLOAT3( bbCOS[0], bbCOS[1], bbCOS[2] )); ; pCb->BoundingBoxHalfObjectSpace = XMLoadFloat3(&XMFLOAT3( bbHOS[0], bbHOS[1], bbHOS[2] )); ; // Shadow camera XMMATRIX shadowView, shadowProjection; CPUTCamera *pShadowCamera = gpSample->GetShadowCamera(); if( pShadowCamera ) { shadowView = XMMATRIX((float*)pShadowCamera->GetViewMatrix()); shadowProjection = XMMATRIX((float*)pShadowCamera->GetProjectionMatrix()); pCb->LightWorldViewProjection = world * shadowView * shadowProjection; } } pContext->Unmap(mpModelConstantBuffer,0); }
Box::Box(float x, float y, float z, XMVECTOR position, float mass, bool fixed, XMVECTOR orientation) { this->position = position; // its the center position of the box this->velocity = XMVectorSet(0.f, 0.f, 0.f, 0.f); length = XMVectorSet(x, y, z, 0.f); centerOfMass = Point(position, false); this->transform = XMMatrixTranslationFromVector(this->position); this->centerOfMass.fixed = fixed; this->orientation = XMQuaternionRotationRollPitchYawFromVector(orientation); if (fixed) { centerOfMass.mass = 1.0f; massInverse = 0.0f; intertiaTensorInverse = XMMATRIX(); } else { centerOfMass.mass = mass; massInverse = 1.0f / mass; float prefix = (1.0f / 12.0f) * centerOfMass.mass; XMMATRIX matrix = XMMATRIX(XMVectorSet(prefix*(y*y + z*z), 0.f, 0.f, 0.f), XMVectorSet(0.f, prefix * (x*x + z*z), 0.f, 0.f), XMVectorSet(0.f, 0.f, prefix*(x*x + y*y),0.f), XMVectorSet(0.f, 0.f, 0.f, 1.f)); intertiaTensorInverse = XMMatrixInverse(&XMMatrixDeterminant(matrix), matrix); } XMVECTOR xLength = XMVectorSet(x, 0.f, 0.f, 0.f) / 2; XMVECTOR yLength = XMVectorSet(0.f, y, 0.f, 0.f) / 2; XMVECTOR zLength = XMVectorSet(0.f, 0.f, z, 0.f) / 2; for (int i = 0; i < 8; i++) { corners[0] = XMVECTOR(); } this->angularMomentum = XMVECTOR(); this->angularVelocity = XMVECTOR(); this->torqueAccumulator = XMVECTOR(); corners[0] = -xLength - yLength - zLength; corners[1] = xLength - yLength - zLength; corners[2] = -xLength + yLength - zLength; corners[3] = xLength + yLength - zLength; corners[4] = -xLength - yLength + zLength; corners[5] = xLength - yLength + zLength; corners[6] = -xLength + yLength + zLength; corners[7] = xLength + yLength + zLength; }
// Returns the inverse transpose. XMMATRIX InverseTranspose(CXMMATRIX M) { // Inverse-transpose is just applied to normals. So zero out // translation row so that it doesn't get into our inverse-transpose // calculation--we don't want the inverse-transpose of the translation. XMMATRIX A = M; A.r[3] = XMVectorSet(0.0f, 0.0f, 0.0f, 1.0f); XMVECTOR det = XMMatrixDeterminant(A); return XMMatrixTranspose(XMMatrixInverse(&det, A)); }
void AnimationPlayer::StartClip(AnimationClip& clip) { mCurrentClip = &clip; mCurrentTime = 0.0f; mCurrentKeyframe = 0; mIsPlayingClip = true; XMMATRIX inverseRootTransform = XMMatrixInverse(&XMMatrixDeterminant(mModel->RootNode()->TransformMatrix()), mModel->RootNode()->TransformMatrix()); XMStoreFloat4x4(&mInverseRootTransform, inverseRootTransform); GetBindPose(*(mModel->RootNode())); }
void FrustumCulling::FrustumCull(std::vector<GenericModelInstance>& instances, Camera& camera) { if (!mFrustumCullingEnabled) return; mNumVisible = 0; XMVECTOR detView = XMMatrixDeterminant(camera.GetViewMatrix()); XMMATRIX invView = XMMatrixInverse(&detView, camera.GetViewMatrix()); for (UINT i = 0; i < instances.size(); ++i) { instances[i].isVisible = false; XMMATRIX W = XMLoadFloat4x4(&instances[i].world); XMMATRIX invWorld = XMMatrixInverse(&XMMatrixDeterminant(W), W); // View space to the object's local space. XMMATRIX toLocal = XMMatrixMultiply(invView, invWorld); // Decompose the matrix into its individual parts. XMVECTOR scale; XMVECTOR rotQuat; XMVECTOR translation; XMMatrixDecompose(&scale, &rotQuat, &translation, toLocal); // Transform the camera frustum from view space to the object's local space. XNA::Frustum localspaceFrustum; XNA::TransformFrustum(&localspaceFrustum, &camera.GetFrustum(), XMVectorGetX(scale), rotQuat, translation); // Perform the box/frustum intersection test in local space. if(XNA::IntersectAxisAlignedBoxFrustum(&instances[i].model->boundingBox, &localspaceFrustum) != 0) { // Write the instance data to dynamic VB of the visible objects. //dataView[mVisibleObjectCount++] = mInstancedData[i]; mNumVisible++; instances[i].isVisible = true; } } }
void XMCamera::UpdateView() { // rotate m_rotationMatrix = XMMatrixRotationRollPitchYaw(m_pitch, m_yaw, m_roll); // transform const FVEC3 dv(0, 0, 1); const FVEC3 du(0, 1, 0); m_lookAt = TVectorTransform(dv, m_rotationMatrix); m_up = TVectorTransform(du, m_rotationMatrix); // forward & right m_forward = Normalize(m_lookAt); m_right = Cross(m_up, m_forward); m_right = Normalize(m_right); // update lookAt m_lookAt = m_position + m_lookAt; // update viewMatrix XMFLOAT3 p(m_position.x, m_position.y, m_position.z); XMFLOAT3 l(m_lookAt.x, m_lookAt.y, m_lookAt.z); XMFLOAT3 u(m_up.x, m_up.y, m_up.z); m_viewMatrix = XMMatrixLookAtLH(XMLoadFloat3(&p), XMLoadFloat3(&l), XMLoadFloat3(&u)); //m_viewMatrix = TMatrixTranspose(m_viewMatrix); // update inverse matrix m_inverseViewMatrix = XMMatrixInverse(&XMMatrixDeterminant(m_viewMatrix), m_viewMatrix); m_inverseProjectionMatrix = XMMatrixInverse(&XMMatrixDeterminant(m_projectionMatrix), m_projectionMatrix); /* (world) view projection */ //m_viewProjectionMatrix = m_projectionMatrix * m_viewMatrix; m_viewProjectionMatrix = m_projectionMatrix * m_viewMatrix; m_inverseWVP = XMMatrixInverse(&XMMatrixDeterminant(m_viewProjectionMatrix), m_viewProjectionMatrix); }
void render() { UINT stride = sizeof(Vertex); UINT offset = 0; //XMVECTOR Eye = XMVectorSet(cos(t)*5.0f, 2.0f, sin(t)*5.0f, 0.0f); XMVECTOR Eye = XMVectorSet(g_R * sin(g_Theta) * cos(g_Phi), g_R * sin(g_Phi), g_R * cos(g_Theta) * cos(g_Phi), 1.0f); XMVECTOR At = XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f); XMVECTOR Up = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f); g_View = XMMatrixLookAtLH(Eye, At, Up); cBufferShader1 cb1; cb1.mWorld = XMMatrixTranspose(XMMatrixIdentity()); cb1.mView = XMMatrixTranspose(g_View); cb1.mProjection = XMMatrixTranspose(g_Projection); cb1.color = XMFLOAT4(1.0f, 0.0f, 0.0f, 1.0f); cb1.LightDir = XMFLOAT3(0.0f, -1.0f, -1.0f); XMStoreFloat3(&cb1.EyePos, Eye); XMStoreFloat3(&cb1.EyeDir, At - Eye); XMMATRIX A = cb1.mWorld; //A.r[3] = XMVectorSet(0.0f, 0.0f, 0.0f, 1.0f); XMVECTOR det = XMMatrixDeterminant(A); cb1.mWorldInvTrans = XMMatrixInverse(&det, A); g_pImmediateContext->UpdateSubresource(g_pcBufferShader1, 0, NULL, &cb1, 0, 0); float ClearColor[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; g_pImmediateContext->ClearRenderTargetView(g_pRenderTargetView, ClearColor); g_pImmediateContext->ClearDepthStencilView(g_pDepthStencilView, D3D11_CLEAR_DEPTH, 1.0f, 0); g_pImmediateContext->IASetVertexBuffers(0, 1, &g_pVertexBuffer, &stride, &offset); g_pImmediateContext->IASetIndexBuffer(g_pIndexBuffer, DXGI_FORMAT_R16_UINT, 0); g_pImmediateContext->VSSetShader(g_pVertexShader, NULL, 0); g_pImmediateContext->VSSetConstantBuffers(0, 1, &g_pcBufferShader1); g_pImmediateContext->PSSetConstantBuffers(0, 1, &g_pcBufferShader1); g_pImmediateContext->PSSetShader(g_pPixelShader, NULL, 0); for (int i = 0; i < Spheres.size(); i++) { cb1.mWorld = XMMatrixTranspose(XMMatrixMultiply(XMMatrixScaling(Spheres[i].Radius, Spheres[i].Radius, Spheres[i].Radius), XMMatrixTranslation(Spheres[i].Position.x, Spheres[i].Position.y, Spheres[i].Position.z))); cb1.color = Spheres[i].Color; g_pImmediateContext->UpdateSubresource(g_pcBufferShader1, 0, NULL, &cb1, 0, 0); g_pImmediateContext->DrawIndexed(num_sphere_indices, 0, 0); } g_pSwapChain->Present(0, 0); }
/***************************************************************** * SetWorldVelocty(): Sets Local Velocity based on passed in World Velocity and * current world matrix * * Ins: XMFLOAT3 - World Velocity * * Outs: N/A * * Returns: N/A * * Mod. Date: 8/20/2015 * Mod. Initials: MZ *****************************************************************/ void IObject::SetWorldVelocity(XMFLOAT3 f3Velocity) { XMMATRIX matTranslateZ = XMMatrixTranslation(f3Velocity.x, f3Velocity.y, f3Velocity.z); XMFLOAT4X4 matLocalSpace; XMMATRIX matWorld = XMLoadFloat4x4(&m_mWorld); matWorld.r[0].m128_f32[3] = 0.0f; matWorld.r[1].m128_f32[3] = 0.0f; matWorld.r[2].m128_f32[3] = 0.0f; matWorld.r[3].m128_f32[0] = 0.0f; matWorld.r[3].m128_f32[1] = 0.0f; matWorld.r[3].m128_f32[2] = 0.0f; matWorld = XMMatrixInverse(&XMMatrixDeterminant(matWorld), matWorld); XMStoreFloat4x4(&matLocalSpace, XMMatrixMultiply(matTranslateZ, matWorld)); XMFLOAT3 f3LocalVelocity; f3LocalVelocity.x = matLocalSpace._41; f3LocalVelocity.y = matLocalSpace._42; f3LocalVelocity.z = matLocalSpace._43; SetVelocity(f3LocalVelocity); }
void CRtwShadowRenderer::DrawFinal() { GetDX11Context()->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST); GetDX11Context()->OMSetDepthStencilState(DepthStencilStates::DepthTestDSS, 0); if( GetAsyncKeyState('2') & 0x8000 ) GetDX11Context()->RSSetState(RasterizerStates::WireframeRS); GetDX11Context()->OMSetBlendState(BlendStates::AlphaBlendBS, 0, 0xffffffff); GetDX11Context()->RSSetViewports(1, &m_finalScreenViewport); static float bgColor[4] = {(0.0f, 0.0f, 0.0f, 0.0f)}; GetDX11Context()->ClearRenderTargetView(Globals::Get().device.m_renderTargetView, bgColor); GetDX11Context()->ClearDepthStencilView(Globals::Get().device.m_depthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0); GetDX11Context()->OMSetRenderTargets(1, &Globals::Get().device.m_renderTargetView, Globals::Get().device.m_depthStencilView); ////////// GetDX11Context()->HSSetShader(m_finalHS, 0, 0); GetDX11Context()->DSSetShader(m_finalDS, 0, 0); ////////// GetDX11Context()->VSSetShader(m_finalVS, 0, 0); GetDX11Context()->PSSetShader(m_finalPS, 0, 0); GetDX11Context()->IASetInputLayout(m_inputLayout); GetDX11Context()->PSSetSamplers(0, 1, &SamplerStates::PointWrapSampler); GetDX11Context()->PSSetSamplers(1, 1, &SamplerStates::DefaultSamplerWrap); GetDX11Context()->PSSetSamplers(2, 1, &SamplerStates::DefaultSamplerClamp); int modelsCount = Globals::Get().scene.m_models.size(); for(int i = 0; i < modelsCount; i++) { D3DPERF_BeginEvent(D3DCOLOR_XRGB(255, 0, 0), L"DRAW_FINAL_WITH_SHADOW"); XMMATRIX world = Globals::Get().scene.m_models[i]->m_transformation.GetWorld(); XMMATRIX lightView = XMLoadFloat4x4(&GetRenderer().mLightView); XMMATRIX lightProj = XMLoadFloat4x4(&GetRenderer().mLightProj); XMMATRIX lightViewProj = XMMatrixMultiply(lightView, lightProj); SRenderFinalVSCbuffer cbufferVS; cbufferVS.mtxView = XMMatrixTranspose(GetCamera().GetView()); cbufferVS.mtxProj = XMMatrixTranspose(GetCamera().GetProj()); cbufferVS.mtxWorld = XMMatrixTranspose(world); cbufferVS.mtxWorldIt = XMMatrixTranspose(XMMatrixInverse(&XMMatrixDeterminant(world), world)); cbufferVS.mtxShadowVP = XMMatrixTranspose(lightViewProj); cbufferVS.g_texScale = Globals::Get().scene.m_models[i]->texScale; GetDX11Context()->UpdateSubresource(m_finalVSCBuffer, 0, NULL, &cbufferVS, 0, 0); GetDX11Context()->VSSetConstantBuffers(0, 1, &m_finalVSCBuffer); /////// GetDX11Context()->DSSetConstantBuffers(0, 1, &m_finalVSCBuffer); /////// SRenderFinalPSCBuffer cbufferPS; cbufferPS.lightDir.x = GetGlobalState().GetSun().Direction.x; cbufferPS.lightDir.y = GetGlobalState().GetSun().Direction.y; cbufferPS.lightDir.z = GetGlobalState().GetSun().Direction.z; GetDX11Context()->UpdateSubresource(m_finalPSCBuffer, 0, NULL, &cbufferPS, 0, 0); GetDX11Context()->PSSetConstantBuffers(0, 1, &m_finalPSCBuffer); /////////// set textures GetDX11Context()->PSSetShaderResources(0, 1, &Globals::Get().scene.m_models[i]->m_material->m_diffuseRV); GetDX11Context()->PSSetShaderResources(1, 1, &m_warpedShadowMap); GetDX11Context()->PSSetShaderResources(2, 1, &m_horizWarpSRV); GetDX11Context()->PSSetShaderResources(3, 1, &m_vertWarpSRV); uint offset = 0; GetDX11Context()->IASetIndexBuffer(Globals::Get().scene.m_models[i]->m_mesh->m_indexBuffer, DXGI_FORMAT_R32_UINT, 0); GetDX11Context()->IASetVertexBuffers(0, 1, &Globals::Get().scene.m_models[i]->m_mesh->m_vertexBuffer, &Globals::Get().scene.m_models[i]->m_mesh->m_stride, &offset); GetDX11Context()->DrawIndexed(Globals::Get().scene.m_models[i]->m_mesh->m_indexCount, 0, 0 ); D3DPERF_EndEvent(); } GetDX11Context()->HSSetShader(NULL, 0, 0); GetDX11Context()->DSSetShader(NULL, 0, 0); GetDX11Context()->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); }
bool CScene::Picking( int x, int y ) { // 2차원 점의 투영 공간으로의 변환 XMMATRIX p = XMLoadFloat4x4( &( m_pCamera->GetProjectionMatrix( ) ) ); D3D11_VIEWPORT d3dViewport = m_pCamera->GetViewport( ); XMFLOAT3 vPickPosition; vPickPosition.x = ( ( ( 2.0f * ( x - d3dViewport.TopLeftX ) ) / d3dViewport.Width ) - 1 ) / p( 0, 0 ); vPickPosition.y = -( ( ( 2.0f * ( y - d3dViewport.TopLeftY ) ) / d3dViewport.Height ) - 1 ) / p( 1, 1 ); XMVECTOR rayOrigin = XMVectorSet( 0.0f, 0.0f, 0.0f, 1.0f ); XMVECTOR rayDir = XMVectorSet( vPickPosition.x, vPickPosition.y, 1.0, 0.0f ); // 2차원 점의 시야공간으로의 변환 XMMATRIX v = XMLoadFloat4x4( &( m_pCamera->GetViewMatrix( ) ) ); XMMATRIX invView = XMMatrixInverse( &XMMatrixDeterminant( v ), v ); // determinant = 행렬식 // 각 물체와 충돌체크 float fHitDist = FLT_MAX, fNearDist = FLT_MAX; XMFLOAT3 vHitPos, vNearPos; bool bIntersection = false; CGameObject *IntersectionObject = NULL; // 충돌된 오브젝트 정보를 가짐 // 여러개의 셰이더를 돌면서 검사함 for (int i = 1; i < m_nShaders; i++) // 0번째 셰이더는 스카이박스만 그리므고 검사할 필요가 없음 { for (int j = 0; j < m_ppShaders[i]->getObjectCount( ); j++) { CGameObject* tempObj = m_ppShaders[i]->getObjects( )[j]; XMMATRIX w = XMLoadFloat4x4( &( tempObj->m_mtxWorld ) ); XMMATRIX invWorld = XMMatrixInverse( &XMMatrixDeterminant( w ), w ); XMMATRIX toLocal = XMMatrixMultiply( invView, invWorld ); rayOrigin = XMVector3TransformCoord( rayOrigin, toLocal ); // XMVector3TransformCoord 함수는 벡터의 4번째 성분이 1이라고 가정하고 계산, 따라서 점을 변환할 때 사용 rayDir = XMVector3TransformNormal( rayDir, toLocal ); // XMVector3TransformNormal 함수는 벡터의 4번째 성분이 0이라고 가정하고 계산, 따라서 벡터를 변환할 때 사용 rayDir = XMVector3Normalize( rayDir ); // 교차 판정을 위해 반직선 방향벡터를 단위길이로 정규화 // 참일 경우 충돌된 것이므로 현재 가장 가까운 곳에 충돌된 것과 검사 if (tempObj->CheckRayIntersection( &rayOrigin, &rayDir, &fHitDist, &vHitPos )) { bIntersection = true; if (fNearDist > fHitDist) { fNearDist = fHitDist; IntersectionObject = tempObj; vNearPos = vHitPos; } } } } if (IntersectionObject != NULL) { pPickedObject = IntersectionObject; if (pPickedObject->m_iType == BACK_GROUND) { vPickPos = vNearPos; // vNearPos는 오브젝트의 로컬좌표계이므로 이를 월드좌표계로 변환 vPickPos = MathHelper::GetInstance( )->Vector3TransformNormal( vPickPos, pPickedObject->m_mtxWorld ); } } return bIntersection; }
void InstancingAndCullingApp::UpdateScene(float dt) { // // Control the camera. // if( GetAsyncKeyState('W') & 0x8000 ) mCam.Walk(10.0f*dt); if( GetAsyncKeyState('S') & 0x8000 ) mCam.Walk(-10.0f*dt); if( GetAsyncKeyState('A') & 0x8000 ) mCam.Strafe(-10.0f*dt); if( GetAsyncKeyState('D') & 0x8000 ) mCam.Strafe(10.0f*dt); if( GetAsyncKeyState('1') & 0x8000 ) mFrustumCullingEnabled = true; if( GetAsyncKeyState('2') & 0x8000 ) mFrustumCullingEnabled = false; // // Perform frustum culling. // mCam.UpdateViewMatrix(); mVisibleObjectCount = 0; if(mFrustumCullingEnabled) { XMVECTOR detView = XMMatrixDeterminant(mCam.View()); XMMATRIX invView = XMMatrixInverse(&detView, mCam.View()); D3D11_MAPPED_SUBRESOURCE mappedData; md3dImmediateContext->Map(mInstancedBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedData); InstancedData* dataView = reinterpret_cast<InstancedData*>(mappedData.pData); for(UINT i = 0; i < mInstancedData.size(); ++i) { XMMATRIX W = XMLoadFloat4x4(&mInstancedData[i].World); XMMATRIX invWorld = XMMatrixInverse(&XMMatrixDeterminant(W), W); // View space to the object's local space. XMMATRIX toLocal = XMMatrixMultiply(invView, invWorld); // Decompose the matrix into its individual parts. XMVECTOR scale; XMVECTOR rotQuat; XMVECTOR translation; XMMatrixDecompose(&scale, &rotQuat, &translation, toLocal); // Transform the camera frustum from view space to the object's local space. XNA::Frustum localspaceFrustum; XNA::TransformFrustum(&localspaceFrustum, &mCamFrustum, XMVectorGetX(scale), rotQuat, translation); // Perform the box/frustum intersection test in local space. if(XNA::IntersectAxisAlignedBoxFrustum(&mSkullBox, &localspaceFrustum) != 0) { // Write the instance data to dynamic VB of the visible objects. dataView[mVisibleObjectCount++] = mInstancedData[i]; } } md3dImmediateContext->Unmap(mInstancedBuffer, 0); } else // No culling enabled, draw all objects. { D3D11_MAPPED_SUBRESOURCE mappedData; md3dImmediateContext->Map(mInstancedBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedData); InstancedData* dataView = reinterpret_cast<InstancedData*>(mappedData.pData); for(UINT i = 0; i < mInstancedData.size(); ++i) { dataView[mVisibleObjectCount++] = mInstancedData[i]; } md3dImmediateContext->Unmap(mInstancedBuffer, 0); } std::wostringstream outs; outs.precision(6); outs << L"Instancing and Culling Demo" << L" " << mVisibleObjectCount << L" objects visible out of " << mInstancedData.size(); mMainWndCaption = outs.str(); }
void Projekt::UpdateScene(float dt) { mPlayer.Update(dt, mDirectInput); for (UINT i = 0; i < mGenSkinnedInstances.size(); ++i) mGenSkinnedInstances[i].Update(dt); /* // Up if (mDirectInput->GetKeyboardState()[DIK_W] && 0x80) { mPlayer.GetCamera()->walk(30.0f*dt); } // Left if (mDirectInput->GetKeyboardState()[DIK_A] & 0x80) { mPlayer.GetCamera()->strafe(-30.0f*dt); } // Down if (mDirectInput->GetKeyboardState()[DIK_S] & 0x80) { mPlayer.GetCamera()->walk(-30.0f*dt); } // Right if (mDirectInput->GetKeyboardState()[DIK_D] & 0x80) { mPlayer.GetCamera()->strafe(30.0f*dt); } // Mouse has moved in x-axis if (mDirectInput->MouseHasMoved()) { // Make each pixel correspond to a quarter of a degree. float dx = XMConvertToRadians(0.25f*static_cast<float>(mDirectInput->GetMouseState().lX)); float dy = XMConvertToRadians(0.25f*static_cast<float>(mDirectInput->GetMouseState().lY)); mPlayer.GetCamera()->yaw(dx); mPlayer.GetCamera()->pitch(dy); } */ //DetectInput(dt); // Movement // if(GetAsyncKeyState('W') & 0x8000) // mPlayer.GetCamera()->walk(30.0f*dt); // // if(GetAsyncKeyState('S') & 0x8000) // mPlayer.GetCamera()->walk(-30.0f*dt); // // if(GetAsyncKeyState('A') & 0x8000) // mPlayer.GetCamera()->strafe(-30.0f*dt); // // if(GetAsyncKeyState('D') & 0x8000) // mPlayer.GetCamera()->strafe(30.0f*dt); // Change shadow map resolution // if(GetAsyncKeyState('1') & 0x8000) // { // mShadowMapSize = 256; // mShadowMap->setResolution(mDirect3D->GetDevice(), mShadowMapSize, mShadowMapSize); // } // // if(GetAsyncKeyState('2') & 0x8000) // { // mShadowMapSize = 512; // mShadowMap->setResolution(mDirect3D->GetDevice(), mShadowMapSize, mShadowMapSize); // } // // if(GetAsyncKeyState('3') & 0x8000) // { // mShadowMapSize = 1024; // mShadowMap->setResolution(mDirect3D->GetDevice(), mShadowMapSize, mShadowMapSize); // } // // if(GetAsyncKeyState('4') & 0x8000) // { // mShadowMapSize = 2048; // mShadowMap->setResolution(mDirect3D->GetDevice(), mShadowMapSize, mShadowMapSize); // } // // if(GetAsyncKeyState('5') & 0x8000) // { // mShadowMapSize = 4096; // mShadowMap->setResolution(mDirect3D->GetDevice(), mShadowMapSize, mShadowMapSize); // } // // if(GetAsyncKeyState('6') & 0x8000) // { // mShadowMapSize = 8192; // mShadowMap->setResolution(mDirect3D->GetDevice(), mShadowMapSize, mShadowMapSize); // } // Walk/fly mode // if(GetAsyncKeyState('Z') & 0x8000) // mWalkCamMode = true; // if(GetAsyncKeyState('X') & 0x8000) // mWalkCamMode = false; // Walk mode if (mWalkCamMode) { XMFLOAT3 camPos = mPlayer.GetCamera()->getPosition(); float y = mTerrain.GetHeight(camPos.x, camPos.z); mPlayer.GetCamera()->setPosition(camPos.x, y + 2.0f, camPos.z); } // Update particle systems mFire.update(dt, mTimer.getTimeElapsedS()); // Build shadow map transform buildShadowTransform(); // Update camera mPlayer.GetCamera()->updateViewMatrix(); //------------------------------------------------------------------ // Frustum culling //------------------------------------------------------------------ mVisibleObjectCount = 0; if (mFrustumCullingEnabled) { XMVECTOR detView = XMMatrixDeterminant(mPlayer.GetCamera()->getViewMatrix()); XMMATRIX invView = XMMatrixInverse(&detView, mPlayer.GetCamera()->getViewMatrix()); for (UINT i = 0; i < mGenericInstances.size(); ++i) { mGenericInstances[i].isVisible = false; XMMATRIX W = XMLoadFloat4x4(&mGenericInstances[i].world); XMMATRIX invWorld = XMMatrixInverse(&XMMatrixDeterminant(W), W); // View space to the object's local space. XMMATRIX toLocal = XMMatrixMultiply(invView, invWorld); // Decompose the matrix into its individual parts. XMVECTOR scale; XMVECTOR rotQuat; XMVECTOR translation; XMMatrixDecompose(&scale, &rotQuat, &translation, toLocal); // Transform the camera frustum from view space to the object's local space. XNA::Frustum localspaceFrustum; XNA::TransformFrustum(&localspaceFrustum, &mCamFrustum, XMVectorGetX(scale), rotQuat, translation); // Perform the box/frustum intersection test in local space. if(XNA::IntersectAxisAlignedBoxFrustum(&mGenericInstances[i].model->boundingBox, &localspaceFrustum) != 0) { // Write the instance data to dynamic VB of the visible objects. //dataView[mVisibleObjectCount++] = mInstancedData[i]; mVisibleObjectCount++; mGenericInstances[i].isVisible = true; } } } else { for (UINT i = 0; i < mGenericInstances.size(); ++i) { mGenericInstances[i].isVisible = true; mVisibleObjectCount++; } } std::wostringstream outs; outs.precision(6); outs << L" " << mVisibleObjectCount << L" objects visible out of " << mGenericInstances.size(); mMainWndCaption = outs.str(); }
float determinant() const { return XMVectorGetX(XMMatrixDeterminant(*this)); }
void MyApp::editTerrain() { if (!glb_bOn || !m_LButtonDown) return; //------------------------------------------------------------ int w = width(), h = height(); XMMATRIX P = m_camera.getProjectionMatrix(); // Compute picking ray in view space. float vx = (+2.0f*m_mouseX/w - 1.0f)/P(0,0); float vy = (-2.0f*m_mouseY/h + 1.0f)/P(1,1); // Ray definition in view space. XMVECTOR rayOrigin = XMVectorSet(0.0f, 0.0f, 0.0f, 1.0f); XMVECTOR rayDir = XMVectorSet(vx, vy, 1.0f, 0.0f); // Tranform ray to local space of Mesh. XMMATRIX V = m_camera.getViewMatrix(); XMMATRIX invView = XMMatrixInverse(&XMMatrixDeterminant(V), V); rayOrigin = XMVector3TransformCoord(rayOrigin, invView); rayDir = XMVector3TransformNormal(rayDir, invView); rayDir = XMVector3Normalize(rayDir); XMFLOAT4 oo, rr; XMStoreFloat4(&oo, rayOrigin); XMStoreFloat4(&rr, rayDir); XMVECTOR a = XMVectorSet(0,0,0,1); // point on plane XMVECTOR n = XMVectorSet(0,1,0,0); // plane's normal XMVECTOR res = XMVector3Dot((a - rayOrigin), n) / XMVector4Dot(rayDir, n); float t = XMVectorGetX(res); XMVECTOR hit_point = rayOrigin + t*rayDir; XMFLOAT4 hp; XMStoreFloat4(&hp, hit_point); XMFLOAT2 coords; coords.x = XMVectorGetX(hit_point) / GRID_WIDTH + 0.5f; coords.y = XMVectorGetZ(hit_point) / GRID_WIDTH + 0.5f; coords.y = 1.0f - coords.y; XMFLOAT4 mo, md; XMStoreFloat4(&mo, rayOrigin); XMStoreFloat4(&md, rayDir); //------------------------------------------------------------ // save/set Render Target View ID3D11DepthStencilView* dsv; ID3D11RenderTargetView* rtv; _dxImmedDC->OMGetRenderTargets(1, &rtv, &dsv); D3D11_VIEWPORT vp; UINT vp_num = 1; _dxImmedDC->RSGetViewports(&vp_num, &vp); D3D11_VIEWPORT new_vp; new_vp.Height = 1024; new_vp.Width = 1024; new_vp.MaxDepth =1.0f; new_vp.MinDepth = 0.0f; new_vp.TopLeftX = new_vp.TopLeftY = 0.0f; _dxImmedDC->RSSetViewports(1, &new_vp); _dxImmedDC->OMSetRenderTargets(1, &m_rtvDynamicHmap, 0); // save input layout ID3D11InputLayout* ia; _dxImmedDC->IAGetInputLayout(&ia); // set null layout _dxImmedDC->IASetInputLayout(0); _dxImmedDC->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); setBoolVar(m_fxDynamicTerrain, glb_bAdditive, "bAdditive"); setVectorVar(m_fxDynamicTerrain, (void*)&coords, "vCoords"); setFloatVar(m_fxDynamicTerrain, glb_Range, "fRange"); // draw 4 points (-> quad) ID3DX11EffectTechnique* tech; tech = m_fxDynamicTerrain->GetTechniqueByIndex(0); tech->GetPassByIndex(0)->Apply(0, _dxImmedDC); _dxImmedDC->Draw(4, 0); // restore IA layout, rtv, dsv _dxImmedDC->OMSetRenderTargets(1, &rtv, dsv); _dxImmedDC->IASetInputLayout(ia); _dxImmedDC->OMSetBlendState(0, 0, 0xffffffff); _dxImmedDC->OMSetDepthStencilState(0, 0); _dxImmedDC->RSSetViewports(1, &vp); }
void wam::Pick(int sx, int sy) { XMMATRIX P = mCam.Proj(); // Compute picking ray in view space. float vx = (+2.0f*sx/mClientWidth - 1.0f)/P(0,0); float vy = (-2.0f*sy/mClientHeight + 1.0f)/P(1,1); // Ray definition in view space. XMVECTOR rayOrigin = XMVectorSet(0.0f, 0.0f, 0.0f, 1.0f); XMVECTOR rayDir = XMVectorSet(vx, vy, 1.0f, 0.0f); // Tranform ray to local space of Mesh. XMMATRIX V = mCam.View(); XMMATRIX invView = XMMatrixInverse(&XMMatrixDeterminant(V), V); XMMATRIX W = XMLoadFloat4x4(&mGridWorld); XMMATRIX invWorld = XMMatrixInverse(&XMMatrixDeterminant(W), W); XMMATRIX toLocal = XMMatrixMultiply(invView, invWorld); rayOrigin = XMVector3TransformCoord(rayOrigin, toLocal); rayDir = XMVector3TransformNormal(rayDir, toLocal); // Make the ray direction unit length for the intersection tests. rayDir = XMVector3Normalize(rayDir); XNA::Sphere tmpSphere11,tmpSphere12,tmpSphere13,tmpSphere21,tmpSphere22,tmpSphere23,tmpSphere31,tmpSphere32,tmpSphere33; float radius =0.5f; tmpSphere11.Radius = radius; tmpSphere12.Radius = radius; tmpSphere13.Radius = radius; tmpSphere21.Radius = radius; tmpSphere22.Radius = radius; tmpSphere23.Radius = radius; tmpSphere31.Radius = radius; tmpSphere32.Radius = radius; tmpSphere33.Radius = radius; tmpSphere11.Center = XMFLOAT3(-5.0f,-1.0f,-5.0f); tmpSphere12.Center = XMFLOAT3( 0.0f,-1.0f,-5.0f); tmpSphere13.Center = XMFLOAT3( 5.0f,-1.0f,-5.0f); tmpSphere21.Center = XMFLOAT3(-5.0f,-1.0f, 0.0f); tmpSphere22.Center = XMFLOAT3( 0.0f,-1.0f, 0.0f); tmpSphere23.Center = XMFLOAT3( 5.0f,-1.0f, 0.0f); tmpSphere31.Center = XMFLOAT3(-5.0f,-1.0f, 5.0f); tmpSphere32.Center = XMFLOAT3( 0.0f,-1.0f, 5.0f); tmpSphere33.Center = XMFLOAT3( 5.0f,-1.0f, 5.0f); UINT PickedSphere=0; FLOAT tmpDist; //IntersectRaySphere( FXMVECTOR Origin, FXMVECTOR Direction, const Sphere* pVolume, FLOAT* pDist ); if(XNA::IntersectRaySphere( rayOrigin, rayDir, &tmpSphere11, &tmpDist )) PickedSphere= 11; if(XNA::IntersectRaySphere( rayOrigin, rayDir, &tmpSphere12, &tmpDist )) PickedSphere= 12; if(XNA::IntersectRaySphere( rayOrigin, rayDir, &tmpSphere13, &tmpDist )) PickedSphere= 13; if(XNA::IntersectRaySphere( rayOrigin, rayDir, &tmpSphere21, &tmpDist )) PickedSphere= 21; if(XNA::IntersectRaySphere( rayOrigin, rayDir, &tmpSphere22, &tmpDist )) PickedSphere= 22; if(XNA::IntersectRaySphere( rayOrigin, rayDir, &tmpSphere23, &tmpDist )) PickedSphere= 23; if(XNA::IntersectRaySphere( rayOrigin, rayDir, &tmpSphere31, &tmpDist )) PickedSphere= 31; if(XNA::IntersectRaySphere( rayOrigin, rayDir, &tmpSphere32, &tmpDist )) PickedSphere= 32; if(XNA::IntersectRaySphere( rayOrigin, rayDir, &tmpSphere33, &tmpDist )) PickedSphere= 33; if(PickedSphere!=0) { int ps =PickedSphere; } }