Пример #1
0
        protected void UpdateVelocity(double fElapsedTime)
        {
            XMVector vMouseDelta  = m_vMouseDelta;
            XMVector vRotVelocity = vMouseDelta * m_fRotationScaler;

            m_vRotVelocity = vRotVelocity;

            XMVector vKeyboardDirection = m_vKeyboardDirection;
            XMVector vAccel             = vKeyboardDirection;

            // Normalize vector so if moving 2 dirs (left & forward),
            // the camera doesn't move faster than if moving in 1 dir
            vAccel = XMVector3.Normalize(vAccel);

            // Scale the acceleration vector
            vAccel *= m_fMoveScaler;

            if (m_bMovementDrag)
            {
                // Is there any acceleration this frame?
                if (XMVector3.LengthSquare(vAccel).X > 0)
                {
                    // If so, then this means the user has pressed a movement key
                    // so change the velocity immediately to acceleration
                    // upon keyboard input.  This isn't normal physics
                    // but it will give a quick response to keyboard input
                    m_vVelocity = vAccel;

                    m_fDragTimer = m_fTotalDragTimeToZero;

                    m_vVelocityDrag = vAccel / (float)m_fDragTimer;
                }
                else
                {
                    // If no key being pressed, then slowly decrease velocity to 0
                    if (m_fDragTimer > 0)
                    {
                        // Drag until timer is <= 0
                        XMVector vVelocity     = m_vVelocity;
                        XMVector vVelocityDrag = m_vVelocityDrag;

                        vVelocity -= vVelocityDrag * (float)fElapsedTime;

                        m_vVelocity = vVelocity;

                        m_fDragTimer -= fElapsedTime;
                    }
                    else
                    {
                        // Zero velocity
                        m_vVelocity = XMVector.Zero;
                    }
                }
            }
            else
            {
                // No drag, so immediately change the velocity
                m_vVelocity = vAccel;
            }
        }
        public bool Intersects(XMVector v0, XMVector v1, XMVector v2)
        {
            // Load the sphere.
            XMVector v_center = this.center;
            XMVector v_radius = XMVector.Replicate(this.radius);

            // Compute the plane of the triangle (has to be normalized).
            XMVector n = XMVector3.Normalize(XMVector3.Cross(v1 - v0, v2 - v0));

            // Assert that the triangle is not degenerate.
            Debug.Assert(!XMVector3.Equal(n, XMGlobalConstants.Zero), "Reviewed");

            // Find the nearest feature on the triangle to the sphere.
            XMVector dist = XMVector3.Dot(v_center - v0, n);

            // If the center of the sphere is farther from the plane of the triangle than
            // the radius of the sphere, then there cannot be an intersection.
            XMVector noIntersection = XMVector.Less(dist, -v_radius);

            noIntersection = XMVector.OrInt(noIntersection, XMVector.Greater(dist, v_radius));

            // Project the center of the sphere onto the plane of the triangle.
            XMVector point = v_center - (n * dist);

            // Is it inside all the edges? If so we intersect because the distance
            // to the plane is less than the radius.
            XMVector intersection = Internal.PointOnPlaneInsideTriangle(point, v0, v1, v2);

            // Find the nearest point on each edge.
            XMVector radiusSq = v_radius * v_radius;

            // Edge 0,1
            point = Internal.PointOnLineSegmentNearestPoint(v0, v1, v_center);

            // If the distance to the center of the sphere to the point is less than
            // the radius of the sphere then it must intersect.
            intersection = XMVector.OrInt(intersection, XMVector.LessOrEqual(XMVector3.LengthSquare(v_center - point), radiusSq));

            // Edge 1,2
            point = Internal.PointOnLineSegmentNearestPoint(v1, v2, v_center);

            // If the distance to the center of the sphere to the point is less than
            // the radius of the sphere then it must intersect.
            intersection = XMVector.OrInt(intersection, XMVector.LessOrEqual(XMVector3.LengthSquare(v_center - point), radiusSq));

            // Edge 2,0
            point = Internal.PointOnLineSegmentNearestPoint(v2, v0, v_center);

            // If the distance to the center of the sphere to the point is less than
            // the radius of the sphere then it must intersect.
            intersection = XMVector.OrInt(intersection, XMVector.LessOrEqual(XMVector3.LengthSquare(v_center - point), radiusSq));

            return(XMVector4.EqualInt(XMVector.AndComplementInt(intersection, noIntersection), XMVector.TrueInt));
        }
        public MainGameComponent()
        {
            var vLightDir = new XMFloat3(-1, 1, -1);

            this.LightDirection = XMVector3.Normalize(vLightDir);

            XMVector eye           = new XMVector(0.0f, 0.0f, -100.0f, 0.0f);
            XMVector at            = new XMVector(0.0f, 0.0f, -0.0f, 0.0f);
            XMVector up            = new XMVector(0.0f, 1.0f, 0.0f, 0.0f);
            float    fObjectRadius = 378.15607f;
            XMVector radius        = XMVector3.Normalize(at - eye).Scale(fObjectRadius * 3.0f);

            this.ViewMatrix = XMMatrix.LookAtLH(eye, at, up) * XMMatrix.TranslationFromVector(radius);

            this.WorldMatrix = XMMatrix.Identity;
        }
        protected override void CreateDeviceDependentResources()
        {
            base.CreateDeviceDependentResources();

            this.mainGameComponent.CreateDeviceDependentResources(this.DeviceResources);

            float fObjectRadius = 378.15607f;

            // Setup the camera's view parameters
            XMFloat3 vecEye = new XMFloat3(0.0f, 0.0f, -100.0f);
            XMFloat3 vecAt  = new XMFloat3(0.0f, 0.0f, -0.0f);

            this.camera.SetViewParams(vecEye, vecAt);
            this.camera.SetRadius(fObjectRadius * 3.0f, fObjectRadius * 0.5f, fObjectRadius * 10.0f);

            var vLightDir = new XMFloat3(-1, 1, -1);

            vLightDir = XMVector3.Normalize(vLightDir);
            this.lightControl.SetLightDirection(vLightDir);
        }
Пример #5
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);
        }
        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;
        }
Пример #7
0
        public static bool CalculateEigenVectors(
            float m11,
            float m12,
            float m13,
            float m22,
            float m23,
            float m33,
            float e1,
            float e2,
            float e3,
            out XMVector pV1,
            out XMVector pV2,
            out XMVector pV3)
        {
            pV1 = Internal.CalculateEigenVector(m11, m12, m13, m22, m23, m33, e1);
            pV2 = Internal.CalculateEigenVector(m11, m12, m13, m22, m23, m33, e2);
            pV3 = Internal.CalculateEigenVector(m11, m12, m13, m22, m23, m33, e3);

            bool v1z = false;
            bool v2z = false;
            bool v3z = false;

            XMVector zero = XMGlobalConstants.Zero;

            if (XMVector3.Equal(pV1, zero))
            {
                v1z = true;
            }

            if (XMVector3.Equal(pV2, zero))
            {
                v2z = true;
            }

            if (XMVector3.Equal(pV3, zero))
            {
                v3z = true;
            }

            // check for non-orthogonal vectors
            bool e12 = Math.Abs(XMVector3.Dot(pV1, pV2).X) > 0.1f;
            bool e13 = Math.Abs(XMVector3.Dot(pV1, pV3).X) > 0.1f;
            bool e23 = Math.Abs(XMVector3.Dot(pV2, pV3).X) > 0.1f;

            // all eigenvectors are 0- any basis set
            if ((v1z && v2z && v3z) || (e12 && e13 && e23) ||
                (e12 && v3z) || (e13 && v2z) || (e23 && v1z))
            {
                pV1 = XMGlobalConstants.IdentityR0;
                pV2 = XMGlobalConstants.IdentityR1;
                pV3 = XMGlobalConstants.IdentityR2;
                return(true);
            }

            if (v1z && v2z)
            {
                XMVector v_tmp = XMVector3.Cross(XMGlobalConstants.IdentityR1, pV3);

                if (XMVector3.LengthSquare(v_tmp).X < 1e-5f)
                {
                    v_tmp = XMVector3.Cross(XMGlobalConstants.IdentityR0, pV3);
                }

                pV1 = XMVector3.Normalize(v_tmp);
                pV2 = XMVector3.Cross(pV3, pV1);
                return(true);
            }

            if (v3z && v1z)
            {
                XMVector v_tmp = XMVector3.Cross(XMGlobalConstants.IdentityR1, pV2);

                if (XMVector3.LengthSquare(v_tmp).X < 1e-5f)
                {
                    v_tmp = XMVector3.Cross(XMGlobalConstants.IdentityR0, pV2);
                }

                pV3 = XMVector3.Normalize(v_tmp);
                pV1 = XMVector3.Cross(pV2, pV3);
                return(true);
            }

            if (v2z && v3z)
            {
                XMVector v_tmp = XMVector3.Cross(XMGlobalConstants.IdentityR1, pV1);

                if (XMVector3.LengthSquare(v_tmp).X < 1e-5f)
                {
                    v_tmp = XMVector3.Cross(XMGlobalConstants.IdentityR0, pV1);
                }

                pV2 = XMVector3.Normalize(v_tmp);
                pV3 = XMVector3.Cross(pV1, pV2);
                return(true);
            }

            if (v1z || e12)
            {
                pV1 = XMVector3.Cross(pV2, pV3);
                return(true);
            }

            if (v2z || e23)
            {
                pV2 = XMVector3.Cross(pV3, pV1);
                return(true);
            }

            if (v3z || e13)
            {
                pV3 = XMVector3.Cross(pV1, pV2);
                return(true);
            }

            return(true);
        }
Пример #8
0
        public static XMVector CalculateEigenVector(float m11, float m12, float m13, float m22, float m23, float m33, float e)
        {
            XMVector v_tmp = new XMFloat3(
                (float)((m12 * m23) - (m13 * (m22 - e))),
                (float)((m13 * m12) - (m23 * (m11 - e))),
                (float)(((m11 - e) * (m22 - e)) - (m12 * m12)));

            // planar or linear
            if (XMVector3.Equal(v_tmp, XMGlobalConstants.Zero))
            {
                float f1, f2, f3;

                // we only have one equation - find a valid one
                if ((m11 - e != 0.0f) || (m12 != 0.0f) || (m13 != 0.0f))
                {
                    f1 = m11 - e;
                    f2 = m12;
                    f3 = m13;
                }
                else if ((m12 != 0.0f) || (m22 - e != 0.0f) || (m23 != 0.0f))
                {
                    f1 = m12;
                    f2 = m22 - e;
                    f3 = m23;
                }
                else if ((m13 != 0.0f) || (m23 != 0.0f) || (m33 - e != 0.0f))
                {
                    f1 = m13;
                    f2 = m23;
                    f3 = m33 - e;
                }
                else
                {
                    // error, we'll just make something up - we have NO context
                    f1 = 1.0f;
                    f2 = 0.0f;
                    f3 = 0.0f;
                }

                if (f1 == 0.0f)
                {
                    v_tmp.X = 0.0f;
                }
                else
                {
                    v_tmp.X = 1.0f;
                }

                if (f2 == 0.0f)
                {
                    v_tmp.Y = 0.0f;
                }
                else
                {
                    v_tmp.Y = 1.0f;
                }

                if (f3 == 0.0f)
                {
                    v_tmp.Z = 0.0f;

                    // recalculate y to make equation work
                    if (m12 != 0.0f)
                    {
                        v_tmp.Y = (float)(-f1 / f2);
                    }
                }
                else
                {
                    v_tmp.Z = (float)((f2 - f1) / f3);
                }
            }

            if (XMVector3.LengthSquare(v_tmp).X > 1e-5f)
            {
                return(XMVector3.Normalize(v_tmp));
            }
            else
            {
                // Multiply by a value large enough to make the vector non-zero.
                v_tmp *= 1e5f;
                return(XMVector3.Normalize(v_tmp));
            }
        }