public static XMVector Unproject( XMVector v, float viewportX, float viewportY, float viewportWidth, float viewportHeight, float viewportMinZ, float viewportMaxZ, XMMatrix projection, XMMatrix view, XMMatrix world) { XMVector d = XMVector.FromFloat(-1.0f, 1.0f, 0.0f, 0.0f); XMVector scale = new XMVector(viewportWidth * 0.5f, -viewportHeight * 0.5f, viewportMaxZ - viewportMinZ, 1.0f); scale = scale.Reciprocal(); XMVector offset = new XMVector(-viewportX, -viewportY, -viewportMinZ, 0.0f); offset = XMVector.MultiplyAdd(scale, offset, d); XMMatrix transform = XMMatrix.Multiply(world, view); transform = XMMatrix.Multiply(transform, projection); transform = transform.Inverse(); XMVector result = XMVector.MultiplyAdd(v, scale, offset); return(XMVector3.TransformCoord(result, transform)); }
public virtual void SetViewParams(XMVector vEyePt, XMVector vLookatPt) { m_vEye = vEyePt; m_vDefaultEye = vEyePt; m_vLookAt = vLookatPt; m_vDefaultLookAt = vLookatPt; // Calc the view matrix XMMatrix mView = XMMatrix.LookAtLH(vEyePt, vLookatPt, XMVector.FromFloat(0.0f, 1.0f, 0.0f, 0.0f)); m_mView = mView; XMMatrix mInvView = mView.Inverse(); // The axis basis vectors and camera position are stored inside the // position matrix in the 4 rows of the camera's world matrix. // To figure out the yaw/pitch of the camera, we just need the Z basis vector XMFloat3 zBasis = new XMFloat3(mInvView.M31, mInvView.M32, mInvView.M33); m_fCameraYawAngle = (float)Math.Atan2(zBasis.X, zBasis.Z); float fLen = (float)Math.Sqrt(zBasis.Z * zBasis.Z + zBasis.X * zBasis.X); m_fCameraPitchAngle = -(float)Math.Atan2(zBasis.Y, fLen); }
private void RenderParticles(XMMatrix mView, XMMatrix mProj) { var context = this.deviceResources.D3DContext; context.OutputMergerGetBlendState(out D3D11BlendState pBlendState0, out float[] BlendFactor0, out uint SampleMask0); context.OutputMergerGetDepthStencilState(out D3D11DepthStencilState pDepthStencilState0, out uint StencilRef0); context.VertexShaderSetShader(this.g_pRenderParticlesVS, null); context.GeometryShaderSetShader(this.g_pRenderParticlesGS, null); context.PixelShaderSetShader(this.g_pRenderParticlesPS, null); context.InputAssemblerSetInputLayout(this.g_pParticleVertexLayout); // Set IA parameters D3D11Buffer[] pBuffers = { this.g_pParticleBuffer }; uint[] stride = { ParticleVertex.Size }; uint[] offset = { 0 }; context.InputAssemblerSetVertexBuffers(0, pBuffers, stride, offset); context.InputAssemblerSetPrimitiveTopology(D3D11PrimitiveTopology.PointList); D3D11ShaderResourceView[] aRViews = { this.g_pParticlePosVeloRV0 }; context.VertexShaderSetShaderResources(0, aRViews); ConstantBufferGS pCBGS = new ConstantBufferGS { m_WorldViewProj = mView * mProj, m_InvView = mView.Inverse() }; context.UpdateSubresource(this.g_pcbGS, 0, null, pCBGS, 0, 0); context.GeometryShaderSetConstantBuffers(0, new[] { this.g_pcbGS }); context.PixelShaderSetShaderResources(0, new[] { this.g_pParticleTexRV }); context.PixelShaderSetSamplers(0, new[] { this.g_pSampleStateLinear }); context.OutputMergerSetBlendState(this.g_pBlendingStateParticle, new float[] { 0.0f, 0.0f, 0.0f, 0.0f }, 0xFFFFFFFF); context.OutputMergerSetDepthStencilState(this.g_pDepthStencilState, 0); context.Draw(MaxParticles, 0); D3D11ShaderResourceView[] ppSRVNULL = { null }; context.VertexShaderSetShaderResources(0, ppSRVNULL); context.PixelShaderSetShaderResources(0, ppSRVNULL); /*ID3D11Buffer* ppBufNULL[1] = { NULL }; * pd3dImmediateContext->GSSetConstantBuffers( 0, 1, ppBufNULL );*/ context.GeometryShaderSetShader(null, null); context.OutputMergerSetBlendState(pBlendState0, BlendFactor0, SampleMask0); context.OutputMergerSetDepthStencilState(pDepthStencilState0, StencilRef0); D3D11Utils.DisposeAndNull(ref pBlendState0); D3D11Utils.DisposeAndNull(ref pDepthStencilState0); }
private void UpdateLightDir() { XMMatrix mInvView = m_mView.Inverse(); mInvView.M41 = 0; mInvView.M42 = 0; mInvView.M43 = 0; XMMatrix mLastRotInv = m_mRotSnapshot.Inverse(); XMMatrix mRot = m_ArcBall.GetRotationMatrix(); m_mRotSnapshot = mRot; // Accumulate the delta of the arcball's rotation in view space. // Note that per-frame delta rotations could be problematic over long periods of time. m_mRot *= m_mView * mLastRotInv * mRot * mInvView; // Since we're accumulating delta rotations, we need to orthonormalize // the matrix to prevent eventual matrix skew XMVector pXBasis = XMVector.FromFloat(m_mRot.M11, m_mRot.M12, m_mRot.M13, 0); XMVector pYBasis = XMVector.FromFloat(m_mRot.M21, m_mRot.M22, m_mRot.M23, 0); XMVector pZBasis = XMVector.FromFloat(m_mRot.M31, m_mRot.M32, m_mRot.M33, 0); pXBasis = XMVector3.Normalize(pXBasis); pYBasis = XMVector3.Cross(pZBasis, pXBasis); pYBasis = XMVector3.Normalize(pYBasis); pZBasis = XMVector3.Cross(pXBasis, pYBasis); pXBasis.W = m_mRot.M14; pYBasis.W = m_mRot.M24; pZBasis.W = m_mRot.M34; XMVector pWBasis = XMVector.FromFloat(m_mRot.M41, m_mRot.M42, m_mRot.M43, m_mRot.M44); m_mRot = new XMMatrix(pXBasis, pYBasis, pZBasis, pWBasis); // Transform the default direction vector by the light's rotation matrix m_vCurrentDir = XMVector3.TransformNormal(m_vDefaultDir, m_mRot); }
public override void FrameMove(double fElapsedTime) { if (IsKeyDown(m_aKeys[(int)SdkCameraKey.Reset])) { Reset(); } // Get keyboard/mouse/gamepad input GetInput(m_bEnablePositionMovement, (m_nActiveButtonMask & m_nCurrentButtonMask) != 0 || m_bRotateWithoutButtonDown); //// Get the mouse movement (if any) if the mouse button are down //if( (m_nActiveButtonMask & m_nCurrentButtonMask) || m_bRotateWithoutButtonDown ) // UpdateMouseDelta( fElapsedTime ); // Get amount of velocity based on the keyboard input and drag (if any) UpdateVelocity(fElapsedTime); // Simple euler method to calculate position delta XMVector vVelocity = m_vVelocity; XMVector vPosDelta = vVelocity * (float)fElapsedTime; // If rotating the camera if ((m_nActiveButtonMask & m_nCurrentButtonMask) != 0 || m_bRotateWithoutButtonDown) { // Update the pitch & yaw angle based on mouse movement float fYawDelta = m_vRotVelocity.X; float fPitchDelta = m_vRotVelocity.Y; // Invert pitch if requested if (m_bInvertPitch) { fPitchDelta = -fPitchDelta; } m_fCameraPitchAngle += fPitchDelta; m_fCameraYawAngle += fYawDelta; // Limit pitch to straight up or straight down m_fCameraPitchAngle = Math.Max(-XMMath.PIDivTwo, m_fCameraPitchAngle); m_fCameraPitchAngle = Math.Min(+XMMath.PIDivTwo, m_fCameraPitchAngle); } // Make a rotation matrix based on the camera's yaw & pitch XMMatrix mCameraRot = XMMatrix.RotationRollPitchYaw(m_fCameraPitchAngle, m_fCameraYawAngle, 0); // Transform vectors based on camera's rotation matrix XMVector vWorldUp = XMVector3.TransformCoord(XMVector.FromFloat(0.0f, 1.0f, 0.0f, 0.0f), mCameraRot); XMVector vWorldAhead = XMVector3.TransformCoord(XMVector.FromFloat(0.0f, 0.0f, 1.0f, 0.0f), mCameraRot); // Transform the position delta by the camera's rotation if (!m_bEnableYAxisMovement) { // If restricting Y movement, do not include pitch // when transforming position delta vector. mCameraRot = XMMatrix.RotationRollPitchYaw(0.0f, m_fCameraYawAngle, 0.0f); } XMVector vPosDeltaWorld = XMVector3.TransformCoord(vPosDelta, mCameraRot); // Move the eye position XMVector vEye = m_vEye; vEye += vPosDeltaWorld; if (m_bClipToBoundary) { vEye = ConstrainToBoundary(vEye); } m_vEye = vEye; // Update the lookAt position based on the eye position XMVector vLookAt = vEye + vWorldAhead; m_vLookAt = vLookAt; // Update the view matrix XMMatrix mView = XMMatrix.LookAtLH(vEye, vLookAt, vWorldUp); m_mView = mView; XMMatrix mCameraWorld = mView.Inverse(); m_mCameraWorld = mCameraWorld; }
public override void FrameMove(double fElapsedTime) { if (IsKeyDown(m_aKeys[(int)SdkCameraKey.Reset])) { Reset(); } // If no dragged has happend since last time FrameMove is called, // and no camera key is held down, then no need to handle again. if (!m_bDragSinceLastUpdate && m_cKeysDown == 0) { return; } m_bDragSinceLastUpdate = false; //// If no mouse button is held down, //// Get the mouse movement (if any) if the mouse button are down //if( m_nCurrentButtonMask != 0 ) // UpdateMouseDelta( fElapsedTime ); GetInput(m_bEnablePositionMovement, m_nCurrentButtonMask != 0); // Get amount of velocity based on the keyboard input and drag (if any) UpdateVelocity(fElapsedTime); // Simple euler method to calculate position delta XMVector vPosDelta = XMVector.LoadFloat3(m_vVelocity) * (float)fElapsedTime; // Change the radius from the camera to the model based on wheel scrolling if (m_nMouseWheelDelta != 0 && m_nZoomButtonMask == SdkCameraMouseKeys.Wheel) { m_fRadius -= m_nMouseWheelDelta * m_fRadius * 0.1f / 120.0f; } m_fRadius = Math.Min(m_fMaxRadius, m_fRadius); m_fRadius = Math.Max(m_fMinRadius, m_fRadius); m_nMouseWheelDelta = 0; // Get the inverse of the arcball's rotation matrix XMMatrix mCameraRot = m_ViewArcBall.GetRotationMatrix().Inverse(); // Transform vectors based on camera's rotation matrix XMVector vWorldUp = XMVector3.TransformCoord(XMVector.FromFloat(0.0f, 1.0f, 0.0f, 0.0f), mCameraRot); XMVector vWorldAhead = XMVector3.TransformCoord(XMVector.FromFloat(0.0f, 0.0f, 1.0f, 0.0f), mCameraRot); // Transform the position delta by the camera's rotation XMVector vPosDeltaWorld = XMVector3.TransformCoord(vPosDelta, mCameraRot); // Move the lookAt position XMVector vLookAt = m_vLookAt; vLookAt += vPosDeltaWorld; if (m_bClipToBoundary) { vLookAt = ConstrainToBoundary(vLookAt); } m_vLookAt = vLookAt; // Update the eye point based on a radius away from the lookAt position XMVector vEye = vLookAt - vWorldAhead * m_fRadius; m_vEye = vEye; // Update the view matrix XMMatrix mView = XMMatrix.LookAtLH(vEye, vLookAt, vWorldUp); m_mView = mView; XMMatrix mInvView = mView.Inverse(); mInvView.M41 = 0.0f; mInvView.M42 = 0.0f; mInvView.M43 = 0.0f; XMMatrix mModelLastRot = m_mModelLastRot; XMMatrix mModelLastRotInv = mModelLastRot.Inverse(); // Accumulate the delta of the arcball's rotation in view space. // Note that per-frame delta rotations could be problematic over long periods of time. XMMatrix mModelRot0 = m_WorldArcBall.GetRotationMatrix(); XMMatrix mModelRot = m_mModelRot; mModelRot *= mView * mModelLastRotInv * mModelRot0 * mInvView; if (m_ViewArcBall.IsBeingDragged() && m_bAttachCameraToModel && !IsKeyDown(m_aKeys[(int)SdkCameraKey.ControlDown])) { // Attach camera to model by inverse of the model rotation XMMatrix mCameraRotLast = m_mCameraRotLast; XMMatrix mCameraLastRotInv = mCameraRotLast.Inverse(); XMMatrix mCameraRotDelta = mCameraLastRotInv * mCameraRot; // local to world matrix mModelRot *= mCameraRotDelta; } m_mModelLastRot = mModelRot0; m_mCameraRotLast = mCameraRot; // Since we're accumulating delta rotations, we need to orthonormalize // the matrix to prevent eventual matrix skew XMVector xBasis = XMVector3.Normalize(XMVector.FromFloat(mModelRot.M11, mModelRot.M12, mModelRot.M13, mModelRot.M14)); XMVector yBasis = XMVector3.Cross(XMVector.FromFloat(mModelRot.M31, mModelRot.M32, mModelRot.M33, mModelRot.M34), xBasis); yBasis = XMVector3.Normalize(yBasis); XMVector zBasis = XMVector3.Cross(xBasis, yBasis); mModelRot.M11 = xBasis.X; mModelRot.M12 = xBasis.Y; mModelRot.M13 = xBasis.Z; mModelRot.M21 = yBasis.X; mModelRot.M22 = yBasis.Y; mModelRot.M23 = yBasis.Z; mModelRot.M31 = zBasis.X; mModelRot.M32 = zBasis.Y; mModelRot.M33 = zBasis.Z; // Translate the rotation matrix to the same position as the lookAt position mModelRot.M41 = vLookAt.X; mModelRot.M42 = vLookAt.Y; mModelRot.M43 = vLookAt.Z; m_mModelRot = mModelRot; // Translate world matrix so its at the center of the model XMMatrix mTrans = XMMatrix.Translation(-m_vModelCenter.X, -m_vModelCenter.Y, -m_vModelCenter.Z); XMMatrix mWorld = mTrans * mModelRot; m_mWorld = mWorld; }