summaryrefslogtreecommitdiff
path: root/common/accel-power.hpp
blob: b3e16fb19551ff9f648cb731a0d65b9a7265d247 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#pragma once

#include "rawaccel-base.hpp"

#include <float.h>

namespace rawaccel {

	struct power_base {
		static double base_fn(double x, const accel_args& args)
		{
			// f(x) = w(mx)^k
			return args.weight * pow(args.scale * x, args.exponent_power);
		}
	};

	template <bool Gain> struct power;

	template <>
	struct power<LEGACY> : power_base {
		vec2d cap = { DBL_MAX, DBL_MAX };

		power(const accel_args& args)
		{
			if (args.cap.x > 0) {
				cap.x = args.cap.x;
				cap.y = base_fn(cap.x, args);
			}
		}

		double operator()(double speed, const accel_args& args) const
		{
			if (speed < cap.x) {
				return base_fn(speed, args);
			}
			return cap.y;
		}

	};

	template <>
	struct power<GAIN> : power_base {
		vec2d cap = { DBL_MAX, DBL_MAX };
		double constant = 0;

		power(const accel_args& args) 
		{
			if (args.cap.x > 0) {
				cap.x = args.cap.x;
				double output = base_fn(cap.x, args);
				cap.y = output * (args.exponent_power + 1);
				constant = -args.exponent_power * output * args.cap.x;
			}
		}

		double operator()(double speed, const accel_args& args) const
		{
			if (speed < cap.x) {
				return base_fn(speed, args);
			}
			else {
				return cap.y + constant / speed;
			}
		}

	};

}