welcome to linkAR technical documentation

next previous

Transformations

You can apply these transformations to any Bone object. As explained here, Bones are parts of the model that you can move, rotate and scale.

8.1- Rotation

The rotation is applied to the objects considering each object axis orientation. This means that the axis do not usually correspond to the world axis, but each object has a different axis orientation.
We can set the model initial rotation offset:

    NSArray * offset = [NSArray arrayWithObjects:
                        FBOX(90.0f),
                        FBOX(0.0f),
                        FBOX(0.0f), nil];
 
    //Set Model initial rotation offset
    if(![glView SetRotationsOffset:offset withModelId:modelrootObjId])
        NSLog(@"Error applying rotation offset");


Other samples of rotation:

#define HEAD_STEP_ROTATION 360.0/200
#define HEAD_MAX_ROTATION 360.0/10

Applies the sky rotation in frameRendered function:

    static float fAngleSky = 0.0f;
 
	if (fAngleSky > 36000.0f)
		fAngleSky = 0.0f;
 
	fAngleSky += 0.75f;
 
    NSArray * skyRot = [NSArray arrayWithObjects:FBOX(0.0f),
                        FBOX(-fAngleSky/10.0f),
                        FBOX(0.0f),
                        nil];
 
    // Set model rotation (applied to 3 axes).
    [glView SetModelRotation:skyRot withModelId:skyDomeOjbId];
    //Configure initials parameters.
    head_rotation_b=true;
    head_rotation_angle=0.0;

Applies the head rotation in frameRendered function:

    if(head_rotation_b){
        head_rotation_angle+=HEAD_STEP_ROTATION;
        if(head_rotation_angle>HEAD_MAX_ROTATION)
            head_rotation_b=!head_rotation_b;
 
    }else{
        head_rotation_angle-=HEAD_STEP_ROTATION;
        if(head_rotation_angle<-HEAD_MAX_ROTATION)
            head_rotation_b=!head_rotation_b;
 
    }
    NSArray * headRot = [NSArray arrayWithObjects:FBOX(0.0f),
                        FBOX(0.0f),
                        FBOX(head_rotation_angle),
                        nil];
 
    // Set model rotation (applied to 3 axes).
    [glView SetModelRotation:headRot withModelId:headId];

Additional graphic:

8.2- Scale

To scale an object you will need to give each axis a separate scale factor. Consider the following:

  • 0 < k < 1: The object size is reduced.
  • k > 1: The object size is incremented.
  • k < 0: The object is inverted.
     NSArray * modelScale = [NSArray arrayWithObjects:
                            FBOX(10.0f),
                            FBOX(10.0f),
                            FBOX(10.0f), nil];
 
    // Set Model initial scale.
    if(![glView setModelScale:modelScale withModelId:skyDomeOjbId])
        NSLog(@"Error setting model scale");

8.3- Translation

To translate an object you will need to give each axis a separate position value.

Applies the model movement around its position (FLOATING EFFECT) inside the frameRendered function:

    static float fAngle = 0.0f; 
 
	if (fAngle > 360.0f)
		fAngle = 0.0f;
 
	fAngle += 0.75f;
    float s = sin(fAngle/8),
    c = cos(fAngle/8);
 
    NSArray * rootPos = [NSArray arrayWithObjects:FBOX(c+s + 10),
                         FBOX(s + c -5),
                         FBOX(s+c + 10),
                         nil];
    // Set model positing (Move model to other value).
    [glView setModelPosition:rootPos withModelId:modelrootObjId];

8.4- Model matrix

If you calculate the matrix to apply to an object, you can apply it directly (note that this will affect the rotate/scale/translate values).

In this case we will use the CMMotionManager provided inside the library to get the device orientation matrix.

//ViewController.h
#import <CoreMotion/CoreMotion.h>
//ViewController.m
#import <3dEngine/CC3GLMatrix.h>
 
@interface ViewController (){
   ...
   CMMotionManager *motionManager;
}
        // Init and setup the motion manager in viewDidLoad.
 
        motionManager = [[CMMotionManager alloc] init]; // motionManager is an instance variable
        motionManager.accelerometerUpdateInterval = 0.01; // 100Hz
        [motionManager startDeviceMotionUpdates];
        [motionManager startDeviceMotionUpdatesUsingReferenceFrame:CMAttitudeReferenceFrameXMagneticNorthZVertical];

Using that matrix will move the girl model according to the device orientation.

 // Apply rotation matrix to the model (The model gets the ability to move). 
    CMAttitude *currentAttitude = motionManager.deviceMotion.attitude;
 
    // Quaternion
    CC3Vector4 v4;
    v4.x = currentAttitude.quaternion.x;
    v4.y = currentAttitude.quaternion.y;
    v4.z = currentAttitude.quaternion.z;
    v4.w = currentAttitude.quaternion.w;
 
    // TRANSLATION VECTOR
    CC3Vector v;
    v.x = 0.0;
    v.y = 0.0;
    v.z = 0.0;
 
    // SCALE VECTOR
    CC3Vector v2;
    v2.x = 1.0;
    v2.y = 1.0;
    v2.z = 1.0;
 
    CC3GLMatrix *modelMatrix = [CC3GLMatrix matrix];
    //Or Translation
    [modelMatrix populateFromTranslation:v];
    //Or Scale
    [modelMatrix populateFromScale:v2];
 
    [modelMatrix rotateByQuaternion:v4];
 
 
    // QUATERNION
    NSArray * m = [NSArray arrayWithObjects:
                   FBOX(modelMatrix.glMatrix[0]), FBOX(modelMatrix.glMatrix[1]), FBOX(modelMatrix.glMatrix[2]), FBOX(modelMatrix.glMatrix[3]),
                   FBOX(modelMatrix.glMatrix[4]), FBOX(modelMatrix.glMatrix[5]), FBOX(modelMatrix.glMatrix[6]), FBOX(modelMatrix.glMatrix[7]),
                   FBOX(modelMatrix.glMatrix[8]), FBOX(modelMatrix.glMatrix[9]), FBOX(modelMatrix.glMatrix[10]), FBOX(modelMatrix.glMatrix[11]),
                   FBOX(modelMatrix.glMatrix[12]), FBOX(modelMatrix.glMatrix[13]), FBOX(modelMatrix.glMatrix[14]), FBOX(modelMatrix.glMatrix[15]),
                   nil];    

Finally set the class calculated matrix to the model. In this case we want the whole girl scene to be moved altogether, so we apply it to the modelrootObjId world.

[glView setModelMatrix:m withModelId:modelrootObjId];

Quaternion vector:

Additional Information

next previous