문제

나는 CmdeViceMotion과 태도의 쿼터니온을 사용하여 피치 yaw 가치를 얻고 카메라를 회전시키기 위해 CC3Camera에 적용됩니다. .

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

피치는 범위가 [-π, π]입니다. 장치가 피치= 0을 향하게하고 테이블에서 장치를 가져 와서 사진을 찍기 위해 π / 2가됩니다. [-π, π] 범위는 나를 360 ° 회전시킬 수 있습니다. 아래로 향하면 (즉, 장치가 거꾸로되어 있음) 피치 값은 π입니다.

요 범위는 [-π / 2, π / 2]입니다. 그것은 0에서 시작하여 장치를 왼쪽으로 회전 할 때 π / 2로갑니다. 그러나 π / 2를 넘어서서 회전하면 요 값이 감소하기 시작합니다.

범위와 마찬가지로 yaw 값을 왼쪽으로 180 °만큼 왼쪽으로 회전 할 수있는 것이 더 유용 할 수 있습니다. 오른쪽으로 가득 차있는 360 ° 뷰를 가득 차 있으며 카메라를 보면서 장치를 수직으로 뒤집기 대신

도움이 되었습니까?

해결책

내장 함수를 사용하여 결국 어떻게했는지는 다음과 같습니다.

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

결과 :

카메라를 회전 시켜서 Skybox에서 일반적으로 기기의 등 카메라를 통해 세계를 보는 것처럼 보일 수 있습니다.내 CC3Camera 객체는 내부에 HDRI 이미지가 매핑 된 Sphere 안에 있습니다 (이) 게시물).

카메라를 부드럽게 회전하려면 :

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

이것은 다른 사람도 도움이되기를 바랍니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top