지금까지 프로젝트의 공통적인 설정을 했다면, 이제부터는 구현하려는 프로젝트에 따라 달라질 수 있는 부분을 처리 해 보도록 하겠습니다.
* android stuido의 update/ upgrade
위와 같이, android studio의 update가 자주 있는데, 특별한 이유가 없다면 그 때 그 때 해 주도록 하겠습니다. 간혹 새 버젼 설치하면 작동에 문제가 되는 코드나 설정이 있을 수 있는데, 그런 문제 수정하면서 또 배워 볼 수 있으니~ Camera 사용 때문에 Emulator 사용에 대한 문서도 따로 있었던 것 같아요. 제가 사용하는 컴퓨터는 메인보드에서 무슨 설정이 맞지 않아 쓸 수 없는 상태라서 실제 장비를 연결해서 씁니다.
1. hellosceneform 참고
hellosceneform을 참고해서 코드를 입력 해 보겠습니다. 그냥 복사해서 붙여 넣어도 상관 없을 것 같습니다.
2. 코드 구성
fragment로 구현 된 프로젝트이며, onCreate에서 필요한 조건이 갖춰져 있는지 확인합니다.
arfragment와 renderable을 만든 후, fragment에 tap listener를 등록하며서 renderable을 연결해서 작동하도록 합니다.
필요한 조건이란, 지원하는 OpenGL 버젼(3.0)이 적합한지, 그리고, android sdk 버젼(N)이 맞는지 확인하는 것입니다.
별도 함수를 만들어 onCreate에서 가장 먼저 확인합니다.
if (!checkIsSupportedDeviceOrFinish(this)) {
return;
}
fragment를 사용하기 위해서, 정의한 layout은 아래와 같습니다. 자세한 내용은 차차 알아보도록 하고 일단 한번 띄워보는 것을 목적으로 하니, 똑같이 만들어 줍니다. (repository에서 가져와도 되고~) 이렇게 정의 된 layout을 setContentsView로 할당합니다.
<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=".HelloSceneformActivity">
<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>
그 후, arfragment와 renderable을 각각 만들고 Listener에서 할당합니다.
이에 대한 상세한 코드는 이후에 따로 리뷰 해 보도록 하고, 일단 돌아가는 앱을 만들기 위해 기계적으로 따라 해 보겠습니다.
2. 사용 방법
앱을 구동하면, 단말기를 빙빙 돌리는 모습의 animation이 나옵니다. 단말기를 움직여서 (단말기 animation이 사라질 때까지)초기화를 한 후(바닥 인식 과정 같기도 하구요...), 화면을 탭 하면 andy가 바닥에 추가됩니다.
정말 간단하게 되죠???
이제 이 프로젝트 기반으로 sceneform의 다른 기능들을 리뷰 하면서 추가 해 보도록 하겠습니다.
3. 오류 처리
error: lambda expressions are not supported in -source 1.7
(use -source 8 or higher to enable lambda expressions)
검색을 해 보니, 람다표현식을 쓰려면 android 지원 버젼 설정을 해줘야 하네요.
아래 포스트에 잘 설명이 되어 있습니다.
https://fluorite94.tistory.com/85
android studio 버젼에 따라 조금 달라질 수도 있는데, source compatibility 속성입니다.
Target도 같이 1.8로 변경 해 줍니다.
import android.support.v7.app.AppCompatActivity 에서 오류 발생
일단 그냥 주석처리해도 상관 없는 것 같네요.
샘플 코드를 그냥 전부 복사해서 붙여넣기 하면 android studio의 작성 당시의 상태와 맞지 않는 코드가 들어가는 것 같습니다. 그래서, 일단 import 구문은 복사해서 넣지 말고, 코드만 넣은 후, 필요한 것만 추가하는 것이 더 좋은 것 같습니다. 요즘은 워낙 자동으로 코드 보완이 잘 되어서 거의 다 되네요. 제가 직접 추가 해 준 것은 android.os.Build.VERSION_CODES 뿐이었어요.
hellosceneform project를 그대로 보시면 됩니다만, 제가 작성하는 코드도 따로 github에 정리해서 올립니다.
위 내용까지는 2020.1.15 오전 버젼으로 커밋했습니다.
https://github.com/red112/sceneform.git
이번 포스트 내용과 비슷한 내용을 이전에 벌써 정리 해 두신 분도 계시네요.
https://idlecomputer.tistory.com/277
[MainActivity.java]
package com.wonil.arform;
import androidx.appcompat.app.AppCompatActivity;
import android.app.Activity;
import android.app.ActivityManager;
import android.content.Context;
import android.os.Build;
import android.os.Bundle;
import android.os.Build.VERSION_CODES;
import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.widget.Toast;
import com.google.ar.core.Anchor;
import com.google.ar.core.HitResult;
import com.google.ar.core.Plane;
import com.google.ar.sceneform.AnchorNode;
import com.google.ar.sceneform.rendering.ModelRenderable;
import com.google.ar.sceneform.ux.ArFragment;
import com.google.ar.sceneform.ux.TransformableNode;
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"})
// CompletableFuture requires api level 24
// FutureReturnValueIgnored is not valid
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (!checkIsSupportedDeviceOrFinish(this)) {
return;
}
setContentView(R.layout.activity_ux);
arFragment = (ArFragment) getSupportFragmentManager().findFragmentById(R.id.ux_fragment);
ModelRenderable.builder()
.setSource(this, R.raw.andy)
.build()
.thenAccept(renderable -> andyRenderable = renderable)
.exceptionally(
throwable -> {
Toast toast =
Toast.makeText(this, "Unable to load andy renderable", Toast.LENGTH_LONG);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
return null;
});
arFragment.setOnTapArPlaneListener(
(HitResult hitResult, Plane plane, MotionEvent motionEvent) -> {
if (andyRenderable == null) {
return;
}
// Create the Anchor.
Anchor anchor = hitResult.createAnchor();
AnchorNode anchorNode = new AnchorNode(anchor);
anchorNode.setParent(arFragment.getArSceneView().getScene());
// Create the transformable andy and add it to the anchor.
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 < VERSION_CODES.N) {
Log.e(TAG, "Sceneform requires Android N or later");
Toast.makeText(activity, "Sceneform requires Android N or later", Toast.LENGTH_LONG).show();
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 requires OpenGL ES 3.0 later");
Toast.makeText(activity, "Sceneform requires OpenGL ES 3.0 or later", Toast.LENGTH_LONG)
.show();
activity.finish();
return false;
}
return true;
}
}
다음 시간에는 AR 공간에 그릴 모델을 원하는 것으로 바꿔 보도록 하겠습니다.
https://learn-and-give.tistory.com/4
'공허의 유산 > 표현의 자유' 카테고리의 다른 글
[opengl].[#1.Setup] Windows/VS2019/glut 기반의 셋업(2) - glut(freeglut)로 opengl 창 띄우기 (0) | 2020.08.08 |
---|---|
[opengl].[#1.Setup] Windows/VS2019/glut 기반의 셋업(1) - Visual studio 2019 설치 (0) | 2020.08.08 |
[sceneform]#4. augmented face review (0) | 2020.03.02 |
[sceneform]#3. model 변경하기 (0) | 2020.01.18 |
[Sceneform]#1. 개발 환경 구축 (2) | 2020.01.11 |
댓글