Question

I want to add 3D objects from cocos3d as camera overlay for augmented reality in my iPhone app. I've got CC3Scene with some model. I've create motionManager capturing to get information about device camera's direction, and then in -(void)update:(ccTime)dt I'm trying to update cocos3d in-scene camera's position (up direction of the scene is the Z axis):

-(void) update:(ccTime)dt
{
    CMDeviceMotion *currentDeviceMotion = motionManager.deviceMotion;
    CMAttitude *currentAttitude = currentDeviceMotion.attitude;

    CC3Camera *cam = (CC3Camera*)[cc3Scene getNodeNamed:@"Camera"];

    static double lastY = 0;
    static double lastP = 0;
    static double lastR = 0;

    double yaw = CC_RADIANS_TO_DEGREES(currentAttitude.yaw-lastY);
    double pitch = CC_RADIANS_TO_DEGREES(currentAttitude.pitch-lastP);
    double roll = CC_RADIANS_TO_DEGREES(currentAttitude.roll-lastR);

    CC3Vector fd = cc3v(0,1,0);
    [cam rotateByAngle:roll aroundAxis:fd];

    CC3Vector rp = cc3v(1,0,0);
    [cam rotateByAngle:pitch aroundAxis:rp];

    CC3Vector up = cc3v(0,0,1);
    [cam rotateByAngle:yaw aroundAxis:up];

lastY = currentAttitude.yaw;
lastP = currentAttitude.pitch;
lastR = currentAttitude.roll;

[super update:dt];
}

I could not directly use cam.rotation = cc3v(pitch, roll, yaw) since the order of rotation in cocos (with my current axes) does not match the one in the device. But my code is not working correct neither. There is a error while rotating camera manually, and I dont know how should I rotate it to make it correct (i've tried almost all combinations of order and axes).

So the question is how can I match cocos's camera rotation and device's one? Am I missing something? Or could you provide code or tutorial projects with such subjects? I understand that is it rather simple question to solve since there is only trigonometry, but I've blown my mind trying to do it.

Thanks!

Was it helpful?

Solution

finished with that code, that works fine

-(CC3Vector4)multiplyQuaternion:(CC3Vector4)q2 onAxis:(CC3Vector4)axis byDegress:(float)degrees{

  CC3Vector4 q1;

  q1.x = axis.x;
  q1.y = axis.y;
  q1.z = axis.z;

  // Converts the angle in degrees to radians.
  float radians = CC_DEGREES_TO_RADIANS(degrees);

  // Finds the sin and cosine for the half angle.
  float sin = sinf(radians * 0.5);
  float cos = cosf(radians * 0.5);

  // Formula to construct a new Quaternion based on direction and angle.
  q1.w = cos;
  q1.x = q1.x * sin;
  q1.y = q1.y * sin;
  q1.z = q1.z * sin;

  // Multiply quaternion, q1 x q2 is not equal to q2 x q1

  CC3Vector4 newQ;
  newQ.w = q1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z;
  newQ.x = q1.w * q2.x + q1.x * q2.w + q1.y * q2.z - q1.z * q2.y;
  newQ.y = q1.w * q2.y - q1.x * q2.z + q1.y * q2.w + q1.z * q2.x;
  newQ.z = q1.w * q2.z + q1.x * q2.y - q1.y * q2.x + q1.z * q2.w;

  return  newQ;
}

-(void)updateCameraFromMotion:(CMDeviceMotion *)deviceMotion {

  CMAttitude  * attitude    = deviceMotion.attitude;
  CMQuaternion  quaternion  = attitude.quaternion;
  CC3Vector4    camQuaternion;
  camQuaternion.w =  quaternion.w;
  camQuaternion.x = -quaternion.x;
  camQuaternion.y = -quaternion.z;
  camQuaternion.z =  quaternion.y;
  camQuaternion   = [self multiplyQuaternion:camQuaternion onAxis:CC3Vector4Make(1, 0, 0, 0) byDegress:90];
  self.activeCamera.quaternion = camQuaternion;  

}

Note, that forwardDirection of camera on start does matter, I set it to (1,0,0)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top