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); }
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; }
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); }
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)); } }