Exemplo n.º 1
0
  //--------------------------------------------------------------------------------------
  // Figure out the velocity based on keyboard input & drag if any
  //--------------------------------------------------------------------------------------
  void CBaseCamera::GetInput( bool bGetKeyboardInput, bool bGetMouseInput, bool bGetGamepadInput,
                              bool bResetCursorAfterMove )
  {
      mKeyboardDirection = vec3( 0, 0, 0 );
      if( bGetKeyboardInput )
      {
          // Update acceleration vector based on keyboard state
          if( IsKeyDown( mKeys[CAM_MOVE_FORWARD] ) )
              mKeyboardDirection.z -= 1.0f;
          if( IsKeyDown( mKeys[CAM_MOVE_BACKWARD] ) )
              mKeyboardDirection.z += 1.0f;
          if( mEnableYAxisMovement )
          {
              if( IsKeyDown( mKeys[CAM_MOVE_UP] ) )
                  mKeyboardDirection.y += 1.0f;
              if( IsKeyDown( mKeys[CAM_MOVE_DOWN] ) )
                  mKeyboardDirection.y -= 1.0f;
          }
          if( IsKeyDown( mKeys[CAM_STRAFE_RIGHT] ) )
              mKeyboardDirection.x += 1.0f;
          if( IsKeyDown( mKeys[CAM_STRAFE_LEFT] ) )
              mKeyboardDirection.x -= 1.0f;
      }

      if( bGetMouseInput )
      {
          UpdateMouseDelta();
      }
      else {
        mMouseDelta = vec2(0.0);
      }
  }
//--------------------------------------------------------------------------------------
// Update the view matrix based on user input & elapsed time
//--------------------------------------------------------------------------------------
void FirstPersonCamera::FrameMove( float fElapsedTime )
{
//	if( Base::Timer::GlobalTimer().IsStopped() )         
//        fElapsedTime = static_cast<float>(Base::Timer::GlobalTimer().FrameDelta());

    if( IsKeyDown(m_aKeys[CAM_RESET]) )
        Reset();

    // Get the mouse movement (if any) if the mouse button are down
    if( m_nActiveButtonMask & m_nCurrentButtonMask )
        UpdateMouseDelta( fElapsedTime );

    // Get amount of velocity based on the keyboard input and drag (if any)
    UpdateVelocity( fElapsedTime );

    // Simple euler method to calculate position delta
    vector3 vPosDelta = m_vVelocity * fElapsedTime;

    // If rotating the camera 
    if( m_nActiveButtonMask & m_nCurrentButtonMask )
    {
        // 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 = std::max( -floatPi/2.0f,  m_fCameraPitchAngle );
		m_fCameraPitchAngle = std::min( +floatPi/2.0f,  m_fCameraPitchAngle );
    }

    // Make a rotation matrix based on the camera's yaw & pitch
    matrix44 mCameraRot;
	mCameraRot.rotate_y( m_fCameraYawAngle );
	mCameraRot.rotate_x( m_fCameraPitchAngle );
	mCameraRot.rotate_z( 0 );

    // Transform vectors based on camera's rotation matrix
    vector3 vLocalUp    = vector3(0,1,0);
    vector3 vLocalAhead = vector3(0,0,1);
	vector3 vWorldUp = mCameraRot.transform_coord( vLocalUp );
	vector3 vWorldAhead = mCameraRot.transform_coord( vLocalAhead );

    // Transform the position delta by the camera's rotation 
    vector3 vPosDeltaWorld = mCameraRot.transform_coord(vPosDelta);
	vPosDeltaWorld.x *= -1;
	//vPosDeltaWorld.y *= -1;

//	Base::debugLog << "y delta " << vPosDeltaWorld.y << std::endl;

    if( !m_bEnableYAxisMovement )
        vPosDeltaWorld.y = 0.0f;

    // Move the eye position 
    m_vEye += vPosDeltaWorld;
    if( m_bClipToBoundary )
        ConstrainToBoundary( &m_vEye );

    // Update the lookAt position based on the eye position 
    m_vLookAt = m_vEye + vWorldAhead;

    // Update the view matrix
	m_mView.ident();
	m_mView.set_translation ( m_vEye );
	//m_mView.lookatRh( m_vLookAt, vLocalUp );
	m_mView *= mCameraRot;

	m_mCameraWorld = m_mView;
	m_mCameraWorld.invert();
}
Exemplo n.º 3
0
//--------------------------------------------------------------------------------------
// Update the view matrix & the model's world matrix based 
//       on user input & elapsed time
//--------------------------------------------------------------------------------------
VOID CModelViewerCamera::FrameMove( FLOAT fElapsedTime )
{
    if( IsKeyDown(m_aKeys[CAM_RESET]) )
        Reset();

    // Get the mouse movement (if any) if the mouse button are down
    if( m_nCurrentButtonMask != 0 ) 
        UpdateMouseDelta( fElapsedTime );

    // Get amount of velocity based on the keyboard input and drag (if any)
    UpdateVelocity( fElapsedTime );

    // Simple euler method to calculate position delta
    D3DXVECTOR3 vPosDelta = m_vVelocity * fElapsedTime;

    // Change the radius from the camera to the model based on wheel scrolling
    if( m_nMouseWheelDelta && m_nZoomButtonMask == MOUSE_WHEEL )
        m_fRadius -= m_nMouseWheelDelta * m_fRadius * 0.1f;
    m_fRadius = min( m_fMaxRadius, m_fRadius );
    m_fRadius = max( m_fMinRadius, m_fRadius );
    m_nMouseWheelDelta = 0;

    // Get the inverse of the arcball's rotation matrix
    D3DXMATRIX mCameraRot;
    D3DXMatrixInverse( &mCameraRot, NULL, m_ViewArcBall.GetRotationMatrix() );

    // Transform vectors based on camera's rotation matrix
    D3DXVECTOR3 vWorldUp, vWorldAhead;
    D3DXVECTOR3 vLocalUp    = D3DXVECTOR3(0,1,0);
    D3DXVECTOR3 vLocalAhead = D3DXVECTOR3(0,0,1);
    D3DXVec3TransformCoord( &vWorldUp, &vLocalUp, &mCameraRot );
    D3DXVec3TransformCoord( &vWorldAhead, &vLocalAhead, &mCameraRot );

    // Transform the position delta by the camera's rotation 
    D3DXVECTOR3 vPosDeltaWorld;
    D3DXVec3TransformCoord( &vPosDeltaWorld, &vPosDelta, &mCameraRot );

    // Move the lookAt position 
    m_vLookAt += vPosDeltaWorld;
    if( m_bClipToBoundary )
        ConstrainToBoundary( &m_vLookAt );

    // Update the eye point based on a radius away from the lookAt position
    m_vEye = m_vLookAt - vWorldAhead * m_fRadius;

    // Update the view matrix
    D3DXMatrixLookAtLH( &m_mView, &m_vEye, &m_vLookAt, &vWorldUp );

    D3DXMATRIX mInvView;
    D3DXMatrixInverse( &mInvView, NULL, &m_mView );
    mInvView._41 = mInvView._42 = mInvView._43 = 0;

    D3DXMATRIX mModelLastRotInv;
    D3DXMatrixInverse(&mModelLastRotInv, NULL, &m_mModelLastRot);

    // 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.
    D3DXMATRIX mModelRot;
    mModelRot = *m_WorldArcBall.GetRotationMatrix();
    m_mModelRot *= m_mView * mModelLastRotInv * mModelRot * mInvView;

    if( m_ViewArcBall.IsBeingDragged() && m_bAttachCameraToModel && !IsKeyDown(m_aKeys[CAM_CONTROLDOWN]) )
    {
        // Attach camera to model by inverse of the model rotation
        D3DXMATRIX mCameraLastRotInv;
        D3DXMatrixInverse(&mCameraLastRotInv, NULL, &m_mCameraRotLast);
        D3DXMATRIX mCameraRotDelta = mCameraLastRotInv * mCameraRot; // local to world matrix
        m_mModelRot *= mCameraRotDelta;
    }
    m_mCameraRotLast = mCameraRot; 

    m_mModelLastRot = mModelRot;

    // Since we're accumulating delta rotations, we need to orthonormalize 
    // the matrix to prevent eventual matrix skew
    D3DXVECTOR3* pXBasis = (D3DXVECTOR3*) &m_mModelRot._11;
    D3DXVECTOR3* pYBasis = (D3DXVECTOR3*) &m_mModelRot._21;
    D3DXVECTOR3* pZBasis = (D3DXVECTOR3*) &m_mModelRot._31;
    D3DXVec3Normalize( pXBasis, pXBasis );
    D3DXVec3Cross( pYBasis, pZBasis, pXBasis );
    D3DXVec3Normalize( pYBasis, pYBasis );
    D3DXVec3Cross( pZBasis, pXBasis, pYBasis );

    // Translate the rotation matrix to the same position as the lookAt position
    m_mModelRot._41 = m_vLookAt.x;
    m_mModelRot._42 = m_vLookAt.y;
    m_mModelRot._43 = m_vLookAt.z;

    // Translate world matrix so its at the center of the model
    D3DXMATRIX mTrans;
    D3DXMatrixTranslation( &mTrans, -m_vModelCenter.x, -m_vModelCenter.y, -m_vModelCenter.z );
    m_mWorld = mTrans * m_mModelRot;
}