# 13. ARCore Connect API

ARCore can be connected and used with ARGear. Once connected with ARGear, you can use both ARCore and ARGear functions such as items, beauty, and bulge.

For the details of ARCore, please refer to “[https://developers.google.com/ar/develop](https://developers.google.com/ar/develop%E2%80%9D)".



## **13.1 Configuration Settings**

Additional settings are required after "1. Configuration Settings" step as below.

In order to connect with ARCore, argear-renderer.aar instead of argear.aar needs to be used.

{% code title="<build.gradle settings>" %}
```java
defaultConfig {

    minSdkVersion 24
}

dependencies {
   implementation "com.google.ar:core:1.17.0"
   implementation "de.javagl:obj:0.2.1"
   implementation (name: 'argear-renderer', ext: 'aar')

}
```
{% endcode %}

{% code title="<AndroidManifest.xml settings>" %}
```java
<application>
   ...
    <meta-data
        android:name="com.google.ar.core"
        android:value="required" />
   …
</application>
```
{% endcode %}



## **13.2 Session Creation and Execution**

Both the ARGSession and ARCore Session need to be created and executed together. For the ARGSession, please refer to chapter [3. ARGSession](api-url-and-key-setting).

{% hint style="danger" %}
When creating ARGSession, the ARGInferenceConfig.Feature setting is not required for ARCore.
{% endhint %}

Sample code for Session creation and execution is written below.

{% code title="<ARGSession Creation>" %}
```java
private void createSession() {

    // create ARGear session
    ARGConfig argConfig
            = new ARGConfig(AppConfig.API_URL, 
                                          AppConfig.API_KEY, 
                                          AppConfig.SECRET_KEY, 
                                          AppConfig.AUTH_KEY);
    argSession = new ARGSession(this, argConfig);
}

```
{% endcode %}

{% code title="<ARCore Session Creation/Execution & ARGSession Execution>" %}
```java
private void createSession() {

    // create ARCore session
    arcoreSession = new ARCoreSession(this);

    // create ARGear session
    ARGConfig argConfig
            = new ARGConfig(AppConfig.API_URL, 
                                          AppConfig.API_KEY, 
                                          AppConfig.SECRET_KEY, 
                                          AppConfig.AUTH_KEY);
    argsession = new ARGSession(this, argConfig);
}

protected void onCreate(Bundle savedInstanceState) {
    ...
    createSession()
}

protected void onResume() {
    super.onResume();

    argsession.resume();

    arcoreSession.resume(this);
}

```
{% endcode %}



## **13.3 Rendering**

In order to draw a resulting frame, ARCore session update must be called in advance and the texture ID used for the update should be fed to ARGear. Moreover, mesh vertices and matrix obtained from ARCore session should be fed to ARGear.

Once ARGSession.drawFrame is called, rendering starts with fed information from ARCore. If Item, Filter, or Beauty is set (Reference: [8. Set Contents](beauty-function-setting)), the effect will be rendered together with the ARCore frame and ARGFrame will be returned as the result.

The ARGFrame contains the final rendered texture ID and you can draw the frame on screen using this texture ID.

Below is a sample rendering code.

{% code title="<Rendering Example Code>" %}
```java
ArrayList<FloatBuffer> verticesList = new ArrayList<>();
ArrayList<float []> poseMatrixList = new ArrayList<>();
float[] mProjectionMatrix = new float[16];
float[] mViewMatrix = new float[16];

public void onDrawFrame(GL10 gl) {

    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);

    arcoreSession.setCameraTextureName(backgroundRenderer.getTextureId());

    // update arcore session
    Frame frame = arcoreSession.update();

    if (frame == null || frame.getCamera() == null) return;

    if (frame.getTimestamp() == 0) return;

    if (arcoreSession.isAugmentedFaceMode()) {
        verticesList.clear();
        poseMatrixList.clear();

        for (AugmentedFace face : arcoreSession.getSession().getAllTrackables(AugmentedFace.class)) {
            if (face.getTrackingState() == TrackingState.TRACKING) {
                // mesh vertices
                FloatBuffer faceVertices = face.getMeshVertices();
                verticesList.add(faceVertices);

               // center and region poses
                float[] facePoseMatrix = new float[16];
                Pose facePose = face.getCenterPose();
                facePose.toMatrix(facePoseMatrix, 0);
                poseMatrixList.add(facePoseMatrix);
            }
        }

        // arcore camera projection matrix
        frame.getCamera().getProjectionMatrix(mProjectionMatrix, 0, 0.1f, 100.0f);

        // arcore camera view matrix
        frame.getCamera().getViewMatrix(mViewMatrix, 0);

        Size textureSize = arcoreSession.getSession().getCameraConfig().getTextureSize();
        if (mTextureSize == null || !mTextureSize.equals(textureSize)) {
            mTextureSize = textureSize;
            mARGSession.setCameraConfig(new ARGCameraConfig(textureSize.getWidth(),
                    textureSize.getHeight(),
                    0,
                    0,
                    0,
                    true,
                    0));
        }

        // feed mesh vertices, pose matrix, projection matrix, view matrix
        mARGSession.applyAdditionalFaceInfo(verticesList, poseMatrixList, mProjectionMatrix, mViewMatrix);

        // feed texture id
        mARGSession.feedTexture(arcoreSession.getTextureId(), mTextureSize);

        // render argear frame
        ARGFrame argFrame = mARGSession.drawFrame(gl, mScreenWidth, mScreenHeight);

        // render screen
        mScreenRenderer.draw(argFrame, mScreenWidth, mScreenHeight, mTextureSize.getWidth(), mTextureSize.getHeight());
    }
}

```
{% endcode %}



## **13.4 Set Contents**

Please refer to the chapter [8. Set Contents](beauty-function-setting).









