109 lines
2.8 KiB
Objective-C
109 lines
2.8 KiB
Objective-C
#import "JOYAxes3D.h"
|
|
#import "JOYElement.h"
|
|
|
|
@implementation JOYAxes3D
|
|
{
|
|
JOYElement *_element1, *_element2, *_element3;
|
|
double _state1, _state2, _state3;
|
|
int32_t _minX, _minY, _minZ;
|
|
int32_t _maxX, _maxY, _maxZ;
|
|
double _gApproximation;
|
|
}
|
|
|
|
+ (NSString *)usageToString: (JOYAxes3DUsage) usage
|
|
{
|
|
if (usage < JOYAxes3DUsageNonGenericMax) {
|
|
return (NSString *[]) {
|
|
@"None",
|
|
@"Acceleretion",
|
|
@"Orientation",
|
|
@"Gyroscope",
|
|
}[usage];
|
|
}
|
|
if (usage >= JOYAxes3DUsageGeneric0) {
|
|
return [NSString stringWithFormat:@"Generic 3D Analog Control %d", usage - JOYAxes3DUsageGeneric0];
|
|
}
|
|
|
|
return [NSString stringWithFormat:@"Unknown Usage 3D Axes %d", usage];
|
|
}
|
|
|
|
- (NSString *)usageString
|
|
{
|
|
return [self.class usageToString:_usage];
|
|
}
|
|
|
|
- (uint64_t)uniqueID
|
|
{
|
|
return _element1.uniqueID;
|
|
}
|
|
|
|
- (NSString *)description
|
|
{
|
|
return [NSString stringWithFormat:@"<%@: %p, %@ (%llu); State: (%.2f, %.2f, %.2f)>", self.className, self, self.usageString, self.uniqueID, _state1, _state2, _state3];
|
|
}
|
|
|
|
- (instancetype)initWithFirstElement:(JOYElement *)element1 secondElement:(JOYElement *)element2 thirdElement:(JOYElement *)element3
|
|
{
|
|
self = [super init];
|
|
if (!self) return self;
|
|
|
|
_element1 = element1;
|
|
_element2 = element2;
|
|
_element3 = element3;
|
|
|
|
_maxX = element1? element1.max : 1;
|
|
_maxY = element2? element2.max : 1;
|
|
_maxZ = element3? element3.max : 1;
|
|
_minX = element1? element1.min : -1;
|
|
_minY = element2? element2.min : -1;
|
|
_minZ = element3? element3.min : -1;
|
|
|
|
return self;
|
|
}
|
|
|
|
- (JOYPoint3D)rawValue
|
|
{
|
|
return (JOYPoint3D){_state1, _state2, _state3};
|
|
}
|
|
|
|
- (JOYPoint3D)normalizedValue
|
|
{
|
|
double distance = sqrt(_state1 * _state1 + _state2 * _state2 + _state3 * _state3);
|
|
if (distance == 0) {
|
|
distance = 1;
|
|
}
|
|
return (JOYPoint3D){_state1 / distance, _state2 / distance, _state3 / distance};
|
|
}
|
|
|
|
- (JOYPoint3D)gUnitsValue
|
|
{
|
|
double distance = _gApproximation ?: 1;
|
|
return (JOYPoint3D){_state1 / distance, _state2 / distance, _state3 / distance};
|
|
}
|
|
|
|
- (bool)updateState
|
|
{
|
|
int32_t x = [_element1 value];
|
|
int32_t y = [_element2 value];
|
|
int32_t z = [_element3 value];
|
|
|
|
if (x == 0 && y == 0 && z == 0) return false;
|
|
|
|
double old1 = _state1, old2 = _state2, old3 = _state3;
|
|
_state1 = (x - _minX) / (double)(_maxX - _minX) * 2 - 1;
|
|
_state2 = (y - _minY) / (double)(_maxY - _minY) * 2 - 1;
|
|
_state3 = (z - _minZ) / (double)(_maxZ - _minZ) * 2 - 1;
|
|
|
|
double distance = sqrt(_state1 * _state1 + _state2 * _state2 + _state3 * _state3);
|
|
if (_gApproximation == 0) {
|
|
_gApproximation = distance;
|
|
}
|
|
else {
|
|
_gApproximation = _gApproximation * 0.9999 + distance * 0.0001;
|
|
}
|
|
|
|
return old1 != _state1 || old2 != _state2 || old3 != _state3;
|
|
}
|
|
|
|
@end
|