welcome to linkAR technical documentation



Add Models

3.1.- Create a Model

The model is the basic object in our 3D world that will load the EAD and where we will manage all our transformations, animations, textures, videos, etc…

We have to add models before the Start function.

This scene we are showcasing has 4 groups: the root containing the girl and the earth piece, the animation objects, the sky dome and the buttons.

#define IBOX(x) [NSNumber numberWithInt:x]
@interface ViewController () {
NSNumber* modelrootObjId;
NSNumber* skyDomeOjbId;
NSNumber* buttonsRootObjId;

When we create a new model object, we can set its unique Id or we can let the system generate one for us:

   // Create Girl model Root object
   modelrootObjId = [glView createModel:IBOX(0)];
   // Create Sky model root object
   skyDomeOjbId = [glView createModel];
   // Create Buttons model Root object
   buttonsRootObjId = [glView createModel];

For each EAD object you want to load you need to create a new model, therefore you will be able to manage them separately. This items are usually called Worlds

3.2- Load and attach EAD

Once we have created a world, we will load the EAD object and attach it to its world. The EAD file is the exported model / scene from 3DMax.

We define some parameters:

@interface ViewController () {
   NSNumber* animationObjId;
   NSNumber* leftButton;
   NSNumber* midButton;
   NSNumber* rightButton;
   NSNumber* headId;
   NSNumber* rightLegId;
   NSNumber* leftLegId;
   NSNumber* swordId;
   EAD_RESULT buttonsEADRes;
   EAD_RESULT anim1;
   EAD_RESULT anim2;
   EAD_RESULT anim3;
   EAD_RESULT lights1;
// Load 3D Model scene graphics from file.
    // 1.-
    girlEADRes = [glView loadEAD:@"data/Models/girlscene/girl_model.EAD"];
    // 2.-
    if ( [girlEADRes.EADId intValue] > -1 )
        // Attach graphics to the model.
        // 3.-
        if(! [glView attachEAD:girlEADRes.EADId withModelId:modelrootObjId] )
            // Error: Failed to attach the 3D object.
  1. First, the model is loaded in the engine. Since this moment, the object will be ready to be attached to a world.
  2. We ensure that the model is correctly loaded.
  3. We attach the scene to the modelrootObjId world.
        // Load animations.
        anim1 = [glView loadEAD:@"data/Models/girlscene/girl_animation_01.EAD"];
        anim2 = [glView loadEAD:@"data/Models/girlscene/girl_animation_02.EAD"];
        anim3 = [glView loadEAD:@"data/Models/girlscene/girl_animation_03.EAD"];
        if ( anim1.IsAnimationLoaded )
            NSLog(@"Animation loaded girl_animation_01.EAD");
        if ( anim2.IsAnimationLoaded )
            NSLog(@"Animation loaded girl_animation_02.EAD");
        if ( anim3.IsAnimationLoaded )
            NSLog(@"Animation loaded girl_animation_03.EAD");

When we load the animations, the animations are ready to be set to the model. Consider the animations are playable only in the scene that they were designed for.

    // Load Sky scene graphics from file.
    skyEADRes = [glView loadEAD:@"data/Models/girlscene/skydome.EAD"];
    if ( [skyEADRes.EADId intValue] > -1 )
        // Attach graphics to the model.
        if(![glView attachEAD:skyEADRes.EADId withModelId:skyDomeOjbId] )
                return; // Error: Failed to attach the 3D object.

We load the Sky EAD and attach it to the skyDomeOjbId world.

    // Load Button scene graphics from file.
    buttonsEADRes = [glView loadEAD:@"data/Models/girlscene/buttons.EAD"];
    if ( [buttonsEADRes.EADId intValue] > -1 )
        // Attach graphics to the model.
        if(![glView attachEAD:buttonsEADRes.EADId withModelId:buttonsRootObjId] )
                return; // Error: Failed to attach the 3D object.

The buttons are loaded in buttonsRootObjId world.

    // Load scene Lights from file.
    lights1 = [glView loadEAD:@"data/Models/girlscene/girl_lights.EAD"];
    if ( [lights1.EADId intValue] < 0 )
        NSLog(@"Error loading girl_lights.EAD");

Finally we load the lights, the lights do not need to be attached to any world, they will affect (by default) all the objects in the scene. Later we will explain how to avoid objects from being affected by lights.

3.3- Getting scene information

It is necessary that you know the details of the scene you are loading into the engine. However, we provide you with some functions that help you to get extra scene information:

  1. getHierarchyNames: Provides you a list of all the parts of the model. In the girl scene, those are composed by Bones and Meshes.
    1. Bones: You can find additional information here. The functions you can use with these objects are transformations (SetModelRotation, setModelScale, setModelPosition,setModelMatrix) and animations (setAnimation). These functions can also be applied to worlds.
    2. Meshes: The function getMeshesNames provides you a list of all the meshes of the model. These meshes are the objects that support the functions regarding visibility (setVisibilityForHierarhchy), textures (getTexturesList), lights (setAffectedByLights).

To apply those functions you will need to know the object ID. For that purpose you must use the getModel function. After loading and attaching the girl scene, we can get some of the girl parts:


In this case, we know the girl head is controlled through the "ctl_head" bone. Any animation or transformation we apply to "HeadModelID" will affect only the girl head.
Another part of the model is the girl skeleton object. In this case whatever animation/transformation we apply on the skeleton will be applied only to the girl and  its sword, but not to the piece of earth under it.
HeadModelID = [glView getModel:@"ctl_head" witheadId:girlEADRes.EADId];
animationObjId = [glView getModel:@"ctl_girl_root" witheadId:girlEADRes.EADId];


As explained before, we will need to get the ID of the mesh we want to change its visibility parameters.
GirlShirtModel = [glView getModel:@"m_girl_shirt" witheadId:girlEADRes.EADId];

For its convenience, it is recommended that the designer names the parts of the model according to ARLAb patterns.

3.4.- Replacing Textures

Each EAD object has several intrinsic textures to load. Those textures can be modified using the replaceTexture function.

   [glView replaceTexture:GirlShirtModel oldTexture:@"data/Models/girlscene/Textures/girl_texture.png" newTexture:@"data/Models/girlscene/Textures/scenery_texture.png"];

With this function you can replace any texture that is defined in each model (For instance girl_texture.png or girl_normal.png).

  1. Remember to apply this function to meshes objects.
  2. Consider replacing the texture modifies all the meshes that use that texture file.

When you replace textures be sure that the new texture has the same size as the replaced one.