이번 포스팅에선 AR core 라이브러리를 사용하여 간단한 AR 앱을 만들어 보겠습니다.
그 전에 먼저 아래 조건을 전부 만족하는지 확인이 필요합니다.
- API 레벨 24 이상
- 안드로이드 스튜디오 3.1 이상
그러나 3.6 버전 이상에선 AR core 작동에 필요한 Sceneform 라이브러리 1.15.0 버전이 작동하지 않는 문제가 있어서, 3.5.x 버전의 안드로이드 스튜디오를 다운받아 이 예제를 공부하시는 걸 추천드립니다.
옛날 버전의 안드로이드 스튜디오는 아래 링크에서 다운받을 수 있습니다.
https://developer.android.com/studio/archive
안드로이드 스튜디오가 준비되었다면 먼저 매니페스트에 아래 문장들을 추가해줍니다.
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera.ar" />
<meta-data android:name="com.google.ar.core" android:value="required" />
<meta-data> 태그는 <application> 안의 아무 곳에나 넣어주면 됩니다. 태그 밖에 입력하면 안됩니다.
그리고 앱 수준 gradle 파일에 아래의 의존성 문구를 넣어줍니다.
implementation 'com.google.ar:core:1.21.0'
implementation "com.google.ar.sceneform.ux:sceneform-ux:1.15.0"
또한 앱 수준 gradle 파일의 android 안에 아래 문구를 넣어줍니다.
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
그리고 File > Settings > Plugins에 들어가서 Google Sceneform Tools (Beta)를 설치합니다.
설치가 완료되면 IDE를 재시작합니다.
그리고 아래 링크에서 필요한 3D assets 들을 가져와야 합니다. 코드 전체를 다운로드받아서 samples/hellosceneform/app/models 폴더 안의 4개 파일들만 갖고 오면 됩니다.
- andy.mtl
- andy.obj
- andy.png
- andy.sfa
https://github.com/google-ar/sceneform-android-sdk/tree/v1.15.0
이제 app 패키지 밑에 sampledata 라는 폴더를 만들어줍니다. app 폴더 우클릭 > New > Directory를 누르고 sampledata를 입력하면 됩니다.
그리고 그 안에 models 폴더를 만들고, 이 models 폴더 안에 위에서 가져온 4개 파일들을 넣어줍니다.
아래 형태로 보이면 됩니다.
다음으로 메인 액티비티의 XML 파일을 만들어줍니다.
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<fragment android:name="com.google.ar.sceneform.ux.ArFragment"
android:id="@+id/ux_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
그리고 자바 파일은 아래와 같이 만들어줍니다.
public class MainActivity extends AppCompatActivity
{
private static final String TAG = MainActivity.class.getSimpleName();
private static final double MIN_OPENGL_VERSION = 3.0;
private ArFragment arFragment;
private ModelRenderable andyRenderable;
@Override
@SuppressWarnings({"AndroidApiChecker", "FutureReturnValueIgnored"})
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// AR 사용 가능 여부 체크
if (!checkIsSupportedDeviceOrFinish(this)) {
return;
}
setContentView(R.layout.activity_main);
arFragment = (ArFragment) getSupportFragmentManager().findFragmentById(R.id.ux_fragment);
ModelRenderable.builder()
.setSource(this, Uri.parse("andy.sfb"))
.build()
.thenAccept(renderable -> andyRenderable = renderable)
.exceptionally(
throwable -> {
Toast toast =
Toast.makeText(this, "andy renderable을 불러올 수 없습니다", Toast.LENGTH_LONG);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
return null;
});
// 화면을 탭해서 3D 객체 생성
arFragment.setOnTapArPlaneListener(
(HitResult hitResult, Plane plane, MotionEvent motionEvent) -> {
if (andyRenderable == null) {
return;
}
Anchor anchor = hitResult.createAnchor();
AnchorNode anchorNode = new AnchorNode(anchor);
anchorNode.setParent(arFragment.getArSceneView().getScene());
TransformableNode andy = new TransformableNode(arFragment.getTransformationSystem());
andy.setParent(anchorNode);
andy.setRenderable(andyRenderable);
andy.select();
});
}
public static boolean checkIsSupportedDeviceOrFinish(final Activity activity) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
Log.e(TAG, "Sceneform은 누가 버전 이상에서만 사용할 수 있습니다");
activity.finish();
return false;
}
String openGlVersionString =
((ActivityManager) activity.getSystemService(Context.ACTIVITY_SERVICE))
.getDeviceConfigurationInfo()
.getGlEsVersion();
if (Double.parseDouble(openGlVersionString) < MIN_OPENGL_VERSION) {
Log.e(TAG, "Sceneform은 OpenGL ES 3.0 이상 버전을 요구합니다");
activity.finish();
return false;
}
return true;
}
}
이렇게 한 후 앱을 실행하면 아래와 같이 작동합니다.
평면(바닥)을 인식해야 하기 때문에 평평한 곳에서 실행하는 게 좋을 것 같습니다.
'안드로이드 자바' 카테고리의 다른 글
[JAVA][Android] JetPack UI 컴포넌트 Pallete 사용해보기 (0) | 2021.08.27 |
---|---|
[JAVA][Android] 액션바 커스텀 하기 (0) | 2021.08.22 |
[JAVA][Android] Bottom Navigation 만들기 (0) | 2021.08.18 |
[JAVA] 경과 시간 구하기 (0) | 2021.08.16 |
[JAVA][Android] 서비스 구현하기 (0) | 2021.08.13 |