Пример #1
0
bool Math_Intersect(const Circle& c, const LineSegment& l)
{
	Vector2 startToCenter = c.center - l.from;
	Vector2 startToEnd = l.to - l.from;
	float len = startToEnd.Length();
	Vector2 dir = startToEnd / len;

	// Find the closest point to the line segment
	float projection = Math_Dot(startToCenter, dir);
	Vector2 closestPoint;
	if (projection > len)
	{
		closestPoint = l.to;
	}
	else if (projection < 0.0f)
	{
		closestPoint = l.from;
	}
	else
	{
		closestPoint = l.from + (dir * projection);
	}

	// Check if the closest point is within the circle
	Vector2 closestToCenter = c.center - closestPoint;
	if (closestToCenter.LengthSquared() > c.radius * c.radius)
	{
		return false;
	}
	return true;
}
Пример #2
0
Vector2 Controller::MakeLookDisc(const Mathematics::Vector2 p_ScreenCentre) const
{
	Vector2 ret = m_States.MouseAndKeyboard().Position - p_ScreenCentre;
	ret = (ret.LengthSquared() > deadDist * deadDist) ? ret : Zero2();
	//ret += m_States.Gamepad().RightStick;

	return ret.IsAtOrigin() ? Zero2() : ret.Direction();
}
Пример #3
0
bool Physics_BoundingCircleTest(const Circle& srcCircle, const Circle& intersectCircle)
{
	Vector2 vecToTarget = intersectCircle.center - srcCircle.center;
	float distanceSqr = vecToTarget.LengthSquared();
	float radii = intersectCircle.radius + srcCircle.radius;
	float radiiSqr = radii * radii;

	bool intersect = (distanceSqr < radiiSqr);
	return intersect;
}
Пример #4
0
bool Circle::Intersects(const Rect& rectangle) const
{
	Vector2 v(MathHelper::Clamp(_center.X, rectangle.X, rectangle.X + rectangle.Width), MathHelper::Clamp(_center.Y, rectangle.Y, rectangle.Y + rectangle.Height));

	Vector2 direction = _center - v;

	float distanceSquared = direction.LengthSquared();

	return ((distanceSquared > 0) && (distanceSquared < _radius * _radius));
}
Пример #5
0
void Fluid::AddForces(const Vector2& position, const Vector2& direction, 
                      float sigma, float amplitude,
                      View2f* velocities) const {
  if (direction.LengthSquared() < 1e-4f) {
    return AddForces(position, sigma, amplitude, velocities);
  }
  
  const int x = std::lroundf(position.x * Width());
  const int y = std::lroundf((1.0f - position.y) * Height());
  const int radius = std::lround(3.3f * sigma);
  const Vector2 dn = direction.Normalized();
  const float sigmaSq = sigma * sigma;
  for (int j = y - radius; j <= y + radius; ++j) {
    for (int i = x - radius; i <= x + radius; ++i) {
      const int s = i - x;
      const int t = y - j;  // Flips at y-axis.
      const float e = amplitude * std::exp(-(0.5f / sigmaSq) * (s * s + t * t));
      AddValue(i, j, e * dn, velocities);
    }
  }
}
	// static
	float Vector2::LengthSquared(const Vector2& p_Vector)
	{
		return p_Vector.LengthSquared();
	}
void MobileSimulator::MouseMotionEvent(Vec2i screenCoordinates)
{
	Vector2 pos = MathUtil::ScreenToWorld(screenCoordinates);
	_fingerGhost1->SetPosition(pos);
	_fingerGhost2->SetPosition(-pos);

	if (_mouseDown)
	{
		//move touch(es)
		TouchList *tl = &TouchListener::GetTouchList();
		if (tl->size() > 0)
		{
			(*tl)[0]->CurrentPoint = screenCoordinates;
			if ( (*tl)[0]->MotionStartTime < 0.0f )
			{
				(*tl)[0]->MotionStartTime = theWorld.GetCurrentTimeSeconds();
			}
		}
		if (tl->size() > 1)
		{
			Vector2 negCoordsVec = MathUtil::WorldToScreen(-pos);
			Vec2i negCoords(negCoordsVec.X, negCoordsVec.Y);
			(*tl)[1]->CurrentPoint = negCoords;
			if ( (*tl)[1]->MotionStartTime < 0.0f )
			{
				(*tl)[1]->MotionStartTime = theWorld.GetCurrentTimeSeconds();
			}

			Touch* t1 = (*tl)[0];
			Touch* t2 = (*tl)[1];

			Vector2 start1(t1->StartingPoint);
			Vector2 current1(t1->CurrentPoint);
			Vector2 start2(t2->StartingPoint);
			Vector2 current2(t2->CurrentPoint);

			Vector2 initialVector = start2 - start1;
			Vector2 currentVector = current2 - current1;

			Vector2 initNorm = Vector2::Normalize(initialVector);
			Vector2 currentNorm = Vector2::Normalize(currentVector);
			float radiansRotated = acos(Vector2::Dot(initNorm, currentNorm));

			if (!_multiGestureOngoing)
			{					
				Vector2 motion = current1 - start1;

				if (motion.LengthSquared() >= (MULTI_MIN_DISTANCE * MULTI_MIN_DISTANCE) )
				{
					_multiGestureOngoing = true;
					
					// figure out if it's a rotate or a pinch
					if (radiansRotated > MULTI_ROTATE_ANGLE)
					{
						_gestureType = ROTATE;
					}
					else
					{
						_gestureType = PINCH;
					}
				}
			}

			if (_multiGestureOngoing)
			{
				GestureData gd;
				gd.Velocity = 0.0f; // don't want to store all the extra datums
									//  needed to actually calculate this

				if      (_gestureType == ROTATE)
				{
					float cross = Vector2::Cross(initNorm, currentNorm);
					if (cross > 0.0f)
					{
						radiansRotated = -radiansRotated;
					}
					gd.GestureMagnitude = radiansRotated;
					theSwitchboard.Broadcast(new TypedMessage<GestureData>("MultiTouchRotate", gd));
				}
				else if (_gestureType == PINCH)
				{
					gd.GestureMagnitude = currentVector.Length() / initialVector.Length();
					theSwitchboard.Broadcast(new TypedMessage<GestureData>("MultiTouchPinch", gd));	
				}
			}
		}
	}
}
void MobileSimulator::MouseUpEvent(Vec2i screenCoordinates, MouseButtonInput button)
{
	_multiGestureOngoing = false;
	_gestureType = NONE;
	_mouseDown = false;

	TouchList* tl = &TouchListener::GetTouchList();
	
	if (theInput.IsKeyDown(ANGEL_KEY_LEFTCONTROL) || theInput.IsKeyDown(ANGEL_KEY_RIGHTCONTROL))
	{
		TouchList::iterator it = tl->begin();
		while (it != tl->end())
		{
			SendTouchNotifiers((*it), TOUCH_END);
			delete (*it);
			it = tl->erase(it);
		}
	}
	else
	{
		// just a single touch, but we'll iterate anyway
		TouchList::iterator it = tl->begin();
		while (it != tl->end())
		{
			if ( (theWorld.GetCurrentTimeSeconds() - (*it)->MotionStartTime) < SWIPE_MAX_DURATION)
			{
				Vector2 start((*it)->StartingPoint.X, (*it)->StartingPoint.Y);
				Vector2 end((*it)->CurrentPoint.X, (*it)->CurrentPoint.Y);
				Vector2 motion = end - start;
				if (motion.LengthSquared() >= (SWIPE_MIN_DISTANCE * SWIPE_MIN_DISTANCE))
				{
					float angle = MathUtil::ToDegrees(acos(Vector2::Dot(Vector2::UnitX, Vector2::Normalize(motion))));
					if (motion.Y > 0.0f)
					{
						angle = 360.0f - angle;
					}

					if      ( (angle > 45.0f) && (angle <= 135.0f) )
					{
						// swipe up
						theSwitchboard.Broadcast(new Message("MultiTouchSwipeUp"));
					}
					else if ( (angle > 135.0f) && (angle <= 225.0f) )
					{
						// swipe left
						theSwitchboard.Broadcast(new Message("MultiTouchSwipeLeft"));
					}
					else if ( (angle > 225.0f) && (angle <= 315.0f) )
					{
						// swipe down
						theSwitchboard.Broadcast(new Message("MultiTouchSwipeDown"));
					}
					else
					{
						// swipe right
						theSwitchboard.Broadcast(new Message("MultiTouchSwipeRight"));
					}
				}
			}
			SendTouchNotifiers((*it), TOUCH_END);
			delete (*it);
			it = tl->erase(it);
		}
	}
}
Пример #9
0
void CameraManager::Update(float a_dt)
{
	m_currentCamera = &m_gameCamera;
	
	// Process camera controls
	InputManager & inMan = InputManager::Get();
	if (DebugMenu::Get().IsDebugMenuEnabled())
	{
		m_currentCamera = &m_debugCamera;
	
		// Create a view direction matrix
		Matrix cameraMat = m_currentCamera->GetCameraMatrix();
		Vector camPos = m_currentCamera->GetPosition();
		Vector camTarget = m_currentCamera->GetTarget();
		const float speed = m_currentCamera->GetTranslationSpeed();
		const float rotSpeed = m_currentCamera->GetRotationSpeed();
		
		// Don't change camera while there is a dialog up
		if (!DebugMenu::Get().IsDebugMenuActive())
		{
			// WSAD for FPS style movement
			Vector moveOffset(0.0f);
			if (inMan.IsKeyDepressed(SDLK_w)) {	moveOffset -= cameraMat.GetUp() * a_dt * speed; }	
			if (inMan.IsKeyDepressed(SDLK_s)) {	moveOffset += cameraMat.GetUp() * a_dt * speed; }	
			if (inMan.IsKeyDepressed(SDLK_d)) { moveOffset += cameraMat.GetRight() * a_dt * speed; }	
			if (inMan.IsKeyDepressed(SDLK_a)) {	moveOffset -= cameraMat.GetRight() * a_dt * speed; }
			if (inMan.IsKeyDepressed(SDLK_q)) {	moveOffset += Vector(0.0f, 0.0f, speed * a_dt); }
			if (inMan.IsKeyDepressed(SDLK_e)) { moveOffset -= Vector(0.0f, 0.0f, speed * a_dt); }	
		
			// Move both the camera and the target together
			m_currentCamera->SetPosition(camPos + moveOffset);
			m_currentCamera->SetTarget(camTarget + moveOffset);

			// Set rotation based on mouse delta while hotkey pressed
			if (inMan.IsKeyDepressed(SDLK_LSHIFT))
			{
				// Get current camera inputs
				const float maxRot = 360.0f;
				Vector2 curInput = inMan.GetMousePosRelative();
				Vector2 lastInput = m_debugOrientationInput;

				// Cancel out mouse movement above an epsilon to prevent the camera jumping around
				const float cameraMoveEpsilonSq = 0.05f;
				Vector2 vecInput = curInput - lastInput;
				if (vecInput.LengthSquared() > cameraMoveEpsilonSq)
				{
					vecInput = Vector2::Vector2Zero();
				}

				m_debugMouseLookAngleEuler += Vector(vecInput.GetY() * a_dt * rotSpeed, 0.0f, -vecInput.GetX() * a_dt * rotSpeed);
				Quaternion rotation(m_debugMouseLookAngleEuler);
				Matrix rotMat = Matrix::Identity();
				rotation.ApplyToMatrix(rotMat);
				Vector newTarget = rotMat.Transform(Vector(0.0f, Camera::sc_defaultCameraTargetDistance, 0.0f));
				m_currentCamera->SetTarget(camPos + newTarget);

				m_debugOrientationInput = curInput;
			}


			// Draw camera position on top of everything
			if (DebugMenu::Get().IsDebugMenuEnabled())
			{
				const Vector & camPos = m_currentCamera->GetPosition();
				char buf[32];
				sprintf(buf, "%.2f, %.2f, %.2f", camPos.GetX(), camPos.GetY(), camPos.GetZ());
				FontManager::Get().DrawDebugString2D(buf, Vector2(0.8f, 0.95f));
			}
		}
	}

	m_currentCamera->Update();
}
void LongPressGestureDetector::SendEvent(const Integration::TouchEvent& event)
{
  unsigned int pointCount( event.GetPointCount() );

  switch (mState)
  {
    // Clear: Wait till one point touches the screen before starting timer.
    case Clear:
    {
      const TouchPoint& point = event.points[0];

      if ( point.state == TouchPoint::Down )
      {
        mTouchPositions.clear();
        mTouchPositions[point.deviceId] = point.screen;

        mTouchTime = event.time;

        mTimer.SetInterval(GetSystemValue());
        mTimer.Start();

        // A long press gesture may be possible, tell Core about this and change state to Touched.
        mState = Touched;
        EmitGesture( Gesture::Possible );
      }

      break;
    }

    // Touched: Monitor movement and addition/removal of points.
    case Touched:
    {
      if (pointCount > mMaximumTouchesRequired)
      {
        // A long press did not occur, tell Core that it was cancelled and change state to Failed.
        EmitGesture( Gesture::Cancelled );
        mTouchPositions.clear();
        mTimer.Stop();
        mState = Failed;
        break;
      }

      bool endLoop(false);

      for (std::vector<TouchPoint>::const_iterator iter = event.points.begin(), endIter = event.points.end();
           iter != endIter && !endLoop; ++iter)
      {
        switch( iter->state )
        {
          // add point.
          case TouchPoint::Down:
          {
            mTouchPositions[iter->deviceId] = iter->screen;
            break;
          }

          // remove point.
          case TouchPoint::Up:
          case TouchPoint::Interrupted:
          {
            // System has interrupted us, long press is not possible, inform Core
            EmitGesture( Gesture::Cancelled );
            mTouchPositions.clear();
            mTimer.Stop();
            mState = ( pointCount == 1 ) ? Clear : Failed; // Change state to Clear if only one point, Failed otherwise.
            endLoop = true;
            break;
          }

          case TouchPoint::Motion:
          {
            const Vector2 touchPosition( mTouchPositions[iter->deviceId] - iter->screen );
            float distanceSquared = touchPosition.LengthSquared();

            if (distanceSquared > ( MAXIMUM_MOTION_ALLOWED * MAXIMUM_MOTION_ALLOWED ) )
            {
              // We have moved more than the allowable motion for a long press gesture. Inform Core and change state to Failed.
              EmitGesture( Gesture::Cancelled );
              mTimer.Stop();
              mState = Failed;
              endLoop = true;
            }
            break;
          }

          case TouchPoint::Stationary:
          case TouchPoint::Leave:
          case TouchPoint::Last:
          {
            break;
          }
        }
      }
      break;
    }

    // Failed/Finished: Monitor the touches, waiting for all touches to be released.
    case Failed:
    case Finished:
    {
      // eventually the final touch point will be removed, marking the end of this gesture.
      if ( pointCount == 1 )
      {
        TouchPoint::State primaryPointState = event.points[0].state;

        if ( (primaryPointState == TouchPoint::Up) || (primaryPointState == TouchPoint::Interrupted) )
        {
          if(mState == Finished)
          {
            // When the last touch point is lifted, we should inform the Core that the Long press has finished.
            EmitGesture(Gesture::Finished);
          }
          mTouchPositions.clear();
          mState = Clear; // Reset state to clear when last touch point is lifted.
        }
      }
      break;
    }
  }
}
Пример #11
0
void InputState::Update()
{
	Reset();
	m_System->Update();

	//buttons

	if (m_System->IsKeyDown(Keys::SPACE) || m_System->IsGamePadButtonDown(Xbox::A))
	{
		m_ActionPressed = true;
	}

	if (m_System->IsKeyDown(Keys::ENTER) || m_System->IsGamePadButtonDown(Xbox::X))
	{
		m_ConfirmPressed = true;
	}

	if (m_System->IsKeyDown(Keys::ESCAPE) || m_System->IsGamePadButtonDown(Xbox::Y))
	{
		m_DenyPressed = true;
	}

	if(m_System->IsKeyDown(Keys::F1))
	{
		m_FullscreenPressed = true;
	}
	
	//axes or discs

	Vector2 leftRaw;
	Vector2 rightRaw;

	if (m_System->GamepadIsConnected())
	{
		leftRaw(1) = -m_System->GetLeftAnalogX();
		leftRaw(2) = m_System->GetLeftAnalogY();
		rightRaw(1) = m_System->GetRightAnalogX();
		rightRaw(2) = m_System->GetRightAnalogY();

		m_LeftDisc = leftRaw - m_LeftDiscCentre;
		m_RightDisc = rightRaw - m_LeftDiscCentre;
	}
	else
	{
		if (m_System->IsKeyDown(Keys::A))
		{
			leftRaw += U();
		}

		if (m_System->IsKeyDown(Keys::D))
		{
			leftRaw += -U();
		}

		if (m_System->IsKeyDown(Keys::W))
		{
			leftRaw += V();
		}

		if (m_System->IsKeyDown(Keys::S))
		{
			leftRaw += -V();
		}

		if (m_System->IsKeyDown(Keys::LEFT))
		{
			rightRaw += -U();
		}

		if (m_System->IsKeyDown(Keys::RIGHT))
		{
			rightRaw += U();
		}

		if (m_System->IsKeyDown(Keys::UP))
		{
			rightRaw += V();
		}

		if (m_System->IsKeyDown(Keys::DOWN))
		{
			rightRaw += -V();
		}

		if (!EquivalentToZero(leftRaw.LengthSquared()))
		{
			m_LeftDisc = leftRaw.Direction();
		}

		if (!EquivalentToZero(rightRaw.LengthSquared()))
		{
			m_RightDisc = rightRaw.Direction();
		}
	}
}
Пример #12
0
float Math_LengthSquared(const Vector2& v)
{
	return v.LengthSquared();
}