Question

J'utilise CMDevicemotion et le quaternion de l'attitude pour obtenir les valeurs PITCH et BATAW , qui sont ensuite appliquées à une cc3camera dans une scène Cocos3D pour faire pivoter la caméra autour de .

#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));
}

Le pas est dans la plage [-π, π]. Lorsque le périphérique est fait face au pitch= 0 et qu'il devient π / 2 lorsque je prends le périphérique de la table et pointez-le pour prendre une photo (mode portrait). La plage de [-π, π] me permet de faire pivoter le dispositif à 360 °. Face vers le bas (c'est-à-dire le périphérique à l'envers), la valeur de la hauteur est π.

La plage de lacet est uniquement [-π / 2, π / 2]. Il commence à 0 et va à π / 2 lorsque je fais pivoter le périphérique à gauche. Mais si je le fais pivoter au-delà de π / 2, la valeur de la lacet commence à diminuer.

puis-je obtenir la valeur de lacette dans la plage [-π, π], comme le pitch? Il serait plus utile de pouvoir faire pivoter la caméra latéralement de 180 ° (à gauche et à droite, avoir une vue complète à 360 °) au lieu de retourner le dispositif verticalement pour regarder derrière la caméra.

Était-ce utile?

La solution

Voici comment je l'ai fini par les fonctions intégrées:

- (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);
}

Le résultat:

La rotation de la caméra comme tellement vous permet de regarder autour de la Skybox comme si vous regardez normalement le monde à travers la caméra arrière du périphérique.Mon objet CC3Camera est à l'intérieur d'une sphère avec une image HDRI mappée sur celle-ci, à l'intérieur (voir POST).

Pour faire pivoter correctement la caméra:

[_cameraBoom runAction:[CC3ActionRotateTo actionWithDuration:0.15 rotateTo:cc3v(-rot.x, -rot.z, rot.y)]];

J'espère que cela aide quelqu'un d'autre aussi.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top