Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- float radial(float vX, float vY, float X, float Y)
- {
- if (X!=0.0f && Y!=0.0f)
- return (vX * X + vY * Y) / sqrt(X * X + Y * Y);
- else
- return 0.0f;
- }
- ///////////////////////////////////////////////////////
- bool clippingIsActive = true;
- bool clippingIsRadial = false;
- float clippingThreshhold = 600.0f;
- float clippingRampUp = 600.0f;
- float factor_integral = 80.0f;
- float factor_proportional = 80.0f;
- float outer_deadzone = 0.05f;
- float inner_deadzone = 0.15f;
- bool inClippingZone = false;
- float edgePushAmount = 0.0f;
- const static int smoothingSteps = 8;
- float previousOutputX[smoothingSteps] = {};
- float previousOutputY[smoothingSteps] = {};
- float previousOutputInward[smoothingSteps] = {};
- float previousVelocitiesX[smoothingSteps] = {};
- float previousVelocitiesY[smoothingSteps] = {};
- int smoothingCounter = 0;
- float smoothingDistance = 0.1f;
- //////////////////////////////////////////////////////////////////////
- else if (stickMode == StickMode::HYBRID_AIM)
- {
- // prepare new values
- float velocityX = rawX - rawLastX;
- float velocityY = -rawY + rawLastY;
- float velocityRadial = radial(velocityX, velocityY, rawX, -rawY);
- float deflection = rawLength;
- float deflection_old = sqrt(rawLastX * rawLastX + rawLastY * rawLastY);
- float magnitude = 0;
- float angle = atan2f(-rawY, rawX);
- bool outputIsInward = false;
- // check deadzones
- if (deflection > jc->inner_deadzone)
- {
- magnitude = (deflection - jc->inner_deadzone) / (1.0f - jc->inner_deadzone - jc->outer_deadzone);
- jc->inClippingZone = true;
- // check outer_deadzone
- if (deflection > 1.0f - jc->outer_deadzone)
- {
- // clip outward radial velocity
- if (velocityRadial > 0.0f)
- {
- float dotProduct = velocityX * sin(angle) + velocityY * -cos(angle);
- velocityX = dotProduct * sin(angle);
- velocityY = dotProduct * -cos(angle);
- }
- magnitude = 1.0f;
- // check entering
- if (deflection_old <= 1.0f - jc->outer_deadzone)
- {
- //change it so it smoothes not by time but by distance so fast movements are more accurate
- float cumulativeVX = 0.0f;
- float cumulativeVY = 0.0f;
- int steps = 0;
- int counter = jc->smoothingCounter;
- while (sqrt(cumulativeVX * cumulativeVX + cumulativeVY * cumulativeVY) < jc->smoothingDistance && steps < jc->smoothingSteps)
- {
- cumulativeVX += jc->previousVelocitiesX[counter];
- cumulativeVY += jc->previousVelocitiesY[counter];
- if (counter == 0)
- counter = jc->smoothingSteps - 1;
- else
- counter--;
- steps++;
- }
- jc->edgePushAmount = radial(cumulativeVX, cumulativeVY, rawX, -rawY) / steps;
- }
- }
- }
- else
- {
- jc->edgePushAmount = 0.0f;
- // smooth reset inClippingZone too as the controller updates slower than JSM (?) therefore velocity is often zero
- float cumulativeVX = velocityX;
- float cumulativeVY = velocityY;
- for (int i = 0; i < jc->smoothingSteps; i++)
- {
- cumulativeVX += jc->previousVelocitiesX[i];
- cumulativeVY += jc->previousVelocitiesY[i];
- }
- if (radial(cumulativeVX, cumulativeVY, rawX, -rawY) >= 0.0f)
- {
- jc->inClippingZone = false;
- }
- bool debug = jc->inClippingZone;
- }
- // compute output
- float magnitudeX = magnitude * cos(angle);
- float magnitudeY = magnitude * sin(angle);
- float outputX = jc->factor_integral * magnitudeX * deltaTime;
- float outputY = jc->factor_integral * magnitudeY * deltaTime;
- outputX += jc->factor_proportional * magnitudeX * jc->edgePushAmount;
- outputY += jc->factor_proportional * magnitudeY * jc->edgePushAmount;
- outputX += jc->factor_proportional * velocityX;
- outputY += jc->factor_proportional * velocityY;
- float outputInward = radial(outputX, outputY, rawX, -rawY);
- if (outputInward < 0.f)
- outputIsInward = true;
- else
- outputInward = 0.f;
- // for smoothing edgePush and clipping on returning to center
- if (jc->smoothingCounter < jc->smoothingSteps - 1)
- {
- jc->smoothingCounter++;
- }
- else
- {
- jc->smoothingCounter = 0;
- }
- jc->previousVelocitiesX[jc->smoothingCounter] = velocityX;
- jc->previousVelocitiesY[jc->smoothingCounter] = velocityY;
- jc->previousOutputInward[jc->smoothingCounter] = outputInward;
- jc->previousOutputX[jc->smoothingCounter] = outputX;
- jc->previousOutputY[jc->smoothingCounter] = outputY;
- // clip output while returning to center
- if (jc->clippingIsActive && jc->inClippingZone)
- {
- if (outputIsInward)
- {
- if (jc->clippingIsRadial)
- {
- float averageOutputInward = 0;
- for (int i = 0; i < jc->smoothingSteps; i++)
- {
- averageOutputInward += jc->previousOutputInward[i];
- }
- averageOutputInward /= jc->smoothingSteps;
- float fraction = ( (-averageOutputInward / deltaTime) - jc->clippingThreshhold) / jc->clippingRampUp;
- if (fraction < 0.f)
- fraction = 0.f;
- if (fraction > 1.f)
- fraction = 1.f;
- outputX += cos(angle) * (-1 + fraction) * outputInward;
- outputY += sin(angle) * (-1 + fraction) * outputInward;
- }
- else
- {
- float averageOutputX = 0.f;
- float averageOutputY = 0.f;
- for (int i = 0; i < jc->smoothingSteps; i++)
- {
- averageOutputX += jc->previousOutputX[i];
- averageOutputY += jc->previousOutputY[i];
- }
- float averageOutput = sqrt(averageOutputX * averageOutputX + averageOutputY * averageOutputY) / jc->smoothingSteps;
- float fraction = ( (averageOutput / deltaTime) - jc->clippingThreshhold) / jc->clippingRampUp;
- if (fraction < 0.f)
- fraction = 0.f;
- if (fraction > 1.f)
- fraction = 1.f;
- outputX *= fraction;
- outputY *= fraction;
- }
- //outputX = 0.f; //for debugging
- //outputY = 0.f;
- }
- }
- moveMouse(outputX, outputY);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement