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; }
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(); }
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; }
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)); }
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); } } }
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; } } }
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(); } } }
float Math_LengthSquared(const Vector2& v) { return v.LengthSquared(); }