Пример #1
0
        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));
        }
Пример #2
0
        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);
        }
Пример #3
0
        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);
        }
Пример #4
0
        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);
        }
Пример #5
0
        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;
        }