저번 포스팅에서 ARCore의 Scenefrom 라이브러리를 사용하기 위한 세팅을 하는 법을 알아보았다.
이번 포스팅에서는 실제로 AR을 구현해보는 시간을 가져 볼 예정이다.
카메라 내에 원하는 지점에 터치를 하게 되면 그에 맞춰서 3D 오브젝트가 생성되는 실습이다.
대부분 라이브러리가 지원해주기 때문에 크게 어려움 없이 쉽게 구현할 수 있다.
레이아웃 설정
먼저 메인 레이아웃을 다음과 같이 설정해 준다.
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<fragment
android:id="@+id/arFragment"
android:name="com.google.ar.sceneform.ux.ArFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
카메라가 비춰질 화면은 프래그먼트이며 이번 실습해서는 해당 프래그먼트가 화면 전체를 차지하도록 만들었다.
3D 오브젝트 설정
사용자가 원하는 지점을 터치하게 되면 오브젝트가 생성되는데, 이 오브젝트를 만들어줘야 한다.
우리는 그럴 정도의 능력은 없으니 인터넷에 있는 3D 오브젝트로 실습을 진행하겠다.
다음 링크를 타고 들어가 본인이 원하는 오브젝트를 다운로드하면 된다.
glf, obj 둘 다 상관없지만 개인적으로 obj가 실습하기 더 수월했기 때문에 obj로 받을 것을 추천한다.
본인이 원하는 파일을 받았다면 sampledata라는 이름의 폴더를 생성한 후 그 안에 받은 파일들을 넣어준다.
폴더를 넣었으면 obj 파일을 우클릭한 후 Import Scenceform Asset을 클릭 한 뒤 Finish를 눌러준다.
조금 기다리면 assets 폴더에 sfb파일이 하나 생성된 것을 확인할 수 있다. 우리는 이 sfb파일을 이용하여 카메라 내에 오브젝트를 띄울 예정이다.
메인 코드 작성
먼저 MainActivity에 다음과 같이 작성해 준다.
class MainActivity : AppCompatActivity() {
private lateinit var arFragment : ArFragment
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
arFragment = supportFragmentManager.findFragmentById(R.id.arFragment) as ArFragment
arFragment.setOnTapArPlaneListener(BaseArFragment.OnTapArPlaneListener { hitResult, plane, motionEvent ->
var anchor : Anchor = hitResult.createAnchor()
ModelRenderable.builder()
.setSource(this, Uri.parse("model.sfb"))
.build()
.thenAccept{ addModelToScence(anchor,it) }
.exceptionally {
val builder : AlertDialog.Builder = AlertDialog.Builder(this)
builder.setMessage(it.localizedMessage)
.show()
return@exceptionally null
}
})
}
Scenceform 라이브러리에 있는 ModelRenderable을 이용하여 sfb 파일을 Renderable로 변환하는 작업이다.
여기서 AR 화면 구성에 있어서 몇 가지 명칭을 살펴보자.
- Node : 하나의 오브젝트가 차지하는 영역을 의미한다.
- Renderable : Node 영역 안에 있는 오브젝트를 의미한다. ( = sfb 파일 )
- Anchor : 오브젝트를 놓을 수 있는 공간을 표시하는 요소. 하얀 점으로 표시되며 여러 개의 Anchor가 모여 오브젝트가 놓일 수 있는 공간을 만든다.
- Scene : AR 화면을 의미한다.
우리가 변환시킨 sfb 파일을 Renderable로 만들고 해당 오브젝트를 Anchor 위에 놓을 수 있다.
Sceneform 라이브러리를 사용하면 우리가 일일이 좌표 값을 계산하지 않고도 알아서 오브젝트를 생성할 수 있는 위치를 파악할 수 있고, 그에 맞춰 오브젝트가 생성된다. 이때 오브젝트는 확대/축소도 가능하고 회전 또한 가능하다. 이 모든 게 Sceneform 라이브러리 하나로 가능한 기본적인 기능들이다.
마지막으로 thenAccept의 람다인 addModelToScence() 함수를 설정해주면 끝난다.
addModelToScene()의 역할은 Renderable 파일을 실제 Scene에 올릴 수 있도록 하는 함수다. 이 역시 Scenceform 라이브러리를 이용하여 좌표, 오브젝트의 위치 등은 자동적으로 계산해준다.
private fun addModelToScence(anchor: Anchor, it: ModelRenderable?) {
val anchorNode : AnchorNode = AnchorNode(anchor)
val transform : TransformableNode = TransformableNode(arFragment.transformationSystem)
transform.setParent(anchorNode)
transform.renderable = it
arFragment.arSceneView.scene.addChild(anchorNode)
transform.select()
}
TransformableNode를 이용하면 위치 정보의 대한 모든 기능들을 자동적으로 수행할 수 있다. 굉장히 편리한 라이브러리가 아닌가?
실제 화면
실제로 실행해 보면 평면인 곳을 터치하면 내가 설정해준 오브젝트가 정상적으로 생성되는 것을 확인할 수 있다.
이동도 가능하고, 확대/축소도 가능하고 회전도 가능하다!!
AR은 굉장히 매력적이다. 그러나 막상 구현해보라고 한다면 막막하기만 한 기술이라고 생각할 것이다. 그러나 이미 AR구현을 위해 많은 라이브러리들이 존재하고, 이를 잘 이용한다면 간단하게 퀄리티 있는 AR 기능을 개발할 수 있을 것이라고 생각한다.
해당 실습에 대한 전체 코드는 Github에 올려놓았으니 잘 모를 경우 천천히 보면서 실습해보길 바란다.
지금 하는 실습은 AR 기초에 관한 것이므로 여기서 좀 더 발전하여 멋있는 AR을 만들어 보았으면 좋겠다!!!
https://github.com/kangmin1012/AndroidExcercise/tree/ARCore_Sceneform
'안드로이드' 카테고리의 다른 글
[Android/짤팁] 작업 중인 액티비티만 실행하고 싶을 경우 (0) | 2020.05.07 |
---|---|
[Android/Kotlin] 카메라로 사진 찍고 이미지뷰에 넣기 (2) (0) | 2020.04.22 |
[Kotlin] ARCore를 이용한 AR 구현 (1) - 세팅 (3) | 2020.04.01 |
[Android/Kotlin] 재생/멈춤 아이콘 애니메이션 (VectorDrawable) (0) | 2020.03.05 |
[Android/Kotlin] 카메라로 사진 찍고 이미지뷰에 넣기 (0) | 2020.02.19 |