Gierbereich auf dem iPhone 5s
-
21-12-2019 - |
Frage
Ich verwende CMDeviceMotion und die Quaternion der Einstellung, um das zu erhalten Tonhöhe Und gieren Werte, die dann auf eine CC3Camera in einer Cocos3D-Szene angewendet werden, um die Kamera zu drehen.
#define RadiansToDegrees(x) ((180 / M_PI) * x)
- (void)initializeScene
{
//...
CC3Camera *cam = [CC3Camera nodeWithName:@"Camera"];
cam.location = cc3v(0, 10, 0.0001);
cam.targetLocation = cc3v(0, 0, 0);
_cameraBoom = [CC3Node nodeWithName:@"CameraBoom"];
_cameraBoom.location = cc3v(0, 0, 0);
[_cameraBoom addChild:cam];
[self addChild:_cameraBoom];
[self setActiveCamera:cam];
_cameraBoom.rotation = cc3v(0, 90, 0);
//...
_motionManager = [[CMMotionManager alloc] init];
_referenceAttitude = nil;
_initialCameraRotation = _cameraBoom.rotation;
[self enableMotion];
}
- (void)enableMotion
{
CMDeviceMotion *deviceMotion = _motionManager.deviceMotion;
_referenceAttitude = deviceMotion.attitude;
_initialCameraRotation = _cameraBoom.rotation;
[_motionManager startDeviceMotionUpdates];
if (!_gyroTimer) {
_gyroTimer = [NSTimer scheduledTimerWithTimeInterval:1 / 30.0
target:self
selector:@selector(doGyroUpdate)
userInfo:nil
repeats:YES];
}
}
- (void)doGyroUpdate
{
CMDeviceMotion *deviceMotion = _motionManager.deviceMotion;
CMAttitude *attitude = deviceMotion.attitude;
if (_referenceAttitude != nil) {
[attitude multiplyByInverseOfAttitude:_referenceAttitude];
}
CMQuaternion quat = attitude.quaternion;
double pitch = RadiansToDegrees(atan2(2 * (quat.x * quat.w + quat.y * quat.z), 1 - 2 * (quat.x * quat.x + quat.z * quat.z)));
double yaw = RadiansToDegrees(asin(2 * (quat.x * quat.y + quat.w * quat.z)));
_cameraBoom.rotation = CC3VectorAdd(_initialCameraRotation, cc3v(pitch, yaw, 0));
}
Die Tonhöhe liegt im Bereich [-π, π].Wenn das Gerät nach oben zeigt, ist die Neigung = 0 und wird zu π/2, wenn ich das Gerät vom Tisch nehme und es zum Fotografieren ausrichte (Hochformat).Der [-π, π]-Bereich ermöglicht es mir, das Gerät um 360° zu drehen.Wenn es nach unten zeigt (d. h.Gerät steht auf dem Kopf) beträgt der Tonhöhenwert π.
Der Gierbereich beträgt nur [-π/2, π/2].Es beginnt bei 0 und geht auf π/2, wenn ich das Gerät nach links drehe.Aber wenn ich es über π/2 hinaus drehe, beginnt der Gierwert abzunehmen.
Kann ich den Gierwert im Bereich [-π, π] erhalten, genau wie die Neigung? Es wäre sinnvoller, die Kamera seitlich um 180° drehen zu können (nach links und rechts, um eine vollständige 360°-Ansicht zu erhalten), anstatt das Gerät vertikal umzudrehen, um mit der Kamera nach hinten zu schauen.
Lösung
So habe ich es letztendlich mit den integrierten Funktionen gemacht:
- (void)doGyroUpdate
{
CMDeviceMotion *deviceMotion = _motionManager.deviceMotion;
CMAttitude *attitude = deviceMotion.attitude;
if (_referenceAttitude != nil) {
[attitude multiplyByInverseOfAttitude:_referenceAttitude];
}
CMQuaternion quat = attitude.quaternion;
CC3Quaternion cc3Quat = CC3QuaternionMake(quat.x, quat.y, quat.z, quat.w);
CC3Vector rot = CC3RotationFromQuaternion(cc3Quat);
_cameraBoom.rotation = cc3v(-rot.x, -rot.z, rot.y);
}
Das Ergebnis:
Wenn Sie die Kamera so drehen, können Sie sich in der Skybox umsehen, als würden Sie die Welt normalerweise durch die Rückkamera des Geräts betrachten.Mein CC3Camera-Objekt befindet sich in einer Kugel, auf deren Innenseite ein HDRi-Bild abgebildet ist (siehe Das Post).
Um die Kamera sanft zu drehen:
[_cameraBoom runAction:[CC3ActionRotateTo actionWithDuration:0.15 rotateTo:cc3v(-rot.x, -rot.z, rot.y)]];
Ich hoffe, das hilft auch jemand anderem.