런타임에 google ar core의 ArSceneView에서 2D 텍스처를 전환하는 방법

아샤웨

우리는 모두 Instagram이나 Snapchat 또는 다른 애플리케이션에서 증강된 얼굴 텍스처를 사용했습니다. 얼굴에 ar 개체를 시도할 수 있는 샘플 앱을 개발하려고 합니다. 지금까지 그 물체를 얼굴에 표시할 수 있었습니다.

그런 다음 사용자가 개체를 다른 개체로 전환할 수 있도록 아래 항목 목록을 표시합니다( instagram / snapchat에서 새 필터를 시도하는 것과 유사).

다음은 한 개체에 대한 기본 코드입니다.

         Texture.builder()
               .setSource(this, R.drawable.fox_face_mesh_texture)
                .build()
                .thenAccept(texture -> faceMeshTexture1 = texture);

        ArSceneView sceneView = arFragment.getArSceneView();
        sceneView.setCameraStreamRenderPriority(Renderable.RENDER_PRIORITY_FIRST);
        Scene scene = sceneView.getScene();
        scene.addOnUpdateListener(new Scene.OnUpdateListener() {
            @Override
            public void onUpdate(FrameTime frameTime) {
                if (faceMeshTexture1 == null)
                    return;

                Collection<AugmentedFace> faceList =
                        sceneView.getSession().getAllTrackables(AugmentedFace.class);

                for (AugmentedFace face : faceList) {
                    if (!faceNodeMap.containsKey(face)) {
                        AugmentedFaceNode faceNode = new AugmentedFaceNode(face);
                        faceNode.setParent(scene);
                        faceNode.setFaceMeshTexture(faceMeshTexture1);
                        faceNodeMap.put(face, faceNode);
                    }
                }

                Iterator<Map.Entry<AugmentedFace, AugmentedFaceNode>> iter = 
                    faceNodeMap.entrySet().iterator();
                    while (iter.hasNext()) {
                        Map.Entry<AugmentedFace, AugmentedFaceNode> entry = iter.next();
                        AugmentedFace face = entry.getKey();
                        if (face.getTrackingState() == TrackingState.STOPPED) {
                            AugmentedFaceNode faceNode = entry.getValue();
                            faceNode.setParent(null);
                            iter.remove();
                        }
                    }
                }
        });

내가 시도한 것

In 버튼 onClick - 다음을 수행하여 새 텍스처를 만들었습니다. Texture.builder().setSource ...

1) for 루프를 작성하려고 했지만 for (AugmentedFace face : faceList) { ... }아무 것도 하지 않았습니다.

2) onUpdate()기능 의 전체 내용을 포함시키려고 노력했습니다 . 하지만 그것도 효과가 없었습니다.

3) 그런 다음 2개의 텍스처를 만들고 부울 변수를 사용하여 부울 값( 버튼 클릭 시)을 반대로 하여 해당 텍스처( onUpdate 메서드에서)를 전환하려고 했습니다. 다음과 같이 보입니다.

         Texture.builder()
               .setSource(this, R.drawable.fox_face_mesh_texture)
                .build()
                .thenAccept(texture -> faceMeshTexture1 = texture);
        Texture.builder()
                .setSource(this, R.drawable.red_lipstick)
                .build()
                .thenAccept(texture -> faceMeshTexture2 = texture);



        ArSceneView sceneView = arFragment.getArSceneView();

        sceneView.setCameraStreamRenderPriority(Renderable.RENDER_PRIORITY_FIRST);
        Scene scene = sceneView.getScene();
        scene.addOnUpdateListener(new Scene.OnUpdateListener() {
            @Override
            public void onUpdate(FrameTime frameTime) {
                if (faceMeshTexture1 == null || faceMeshTexture2 == null)
                    return;

                Collection<AugmentedFace> faceList =
                        sceneView.getSession().getAllTrackables(AugmentedFace.class);

                for (AugmentedFace face : faceList) {
                    if (!faceNodeMap.containsKey(face)) {
                        AugmentedFaceNode faceNode = new AugmentedFaceNode(face);
                        faceNode.setParent(scene);
                        if( !redOrFox ) {
                            faceNode.setFaceMeshTexture(faceMeshTexture1);
                            Log.d(TAG, "onUpdate: redorfox:" + redOrFox);
                        }
                        else {
                            faceNode.setFaceMeshTexture(faceMeshTexture2);
                            Log.d(TAG, "onUpdate: else redorfox:" + redOrFox);
                        }
                        faceNodeMap.put(face, faceNode);
                    }
                }

                Iterator<Map.Entry<AugmentedFace, AugmentedFaceNode>> iter = faceNodeMap.entrySet().iterator();
                while (iter.hasNext()) {
                    Map.Entry<AugmentedFace, AugmentedFaceNode> entry = iter.next();
                    AugmentedFace face = entry.getKey();
                    if (face.getTrackingState() == TrackingState.STOPPED) {
                        AugmentedFaceNode faceNode = entry.getValue();
                        faceNode.setParent(null);
                        iter.remove();
                    }
                }
            }
        });

        mBtnBlueLip.setOnClickListener(v -> {
            redOrFox = true;
            Log.d(TAG, "onCreate: blue clicked");
        });

        mBtnRedLip.setOnClickListener(v -> {
            redOrFox = false;
            Log.d(TAG, "onCreate: red clicked");
        });

하지만 그것도 아무 소용이 없었다. 이 시점에서 나는 무엇을 해야 할지 막막합니다. 증강 얼굴과 몇 가지 샘플 앱에 관한 문서는 거의 없습니다(그러나 Kotlin에는 있음). 비슷한 질문 이 발견되었지만(3D의 경우) 답변이 없습니다.

편집: 또한 디버깅 후에도 onUpdate 함수가 한 번만 호출되는 것처럼 보입니다. 여기에서 무슨 일이 일어나고 있는지 이해하지 못합니까?

아샤웨

Kristina Simakova가 개발한 kotlin 앱 에서 해결책을 찾았 습니다 .

올바른 길을 가고 있었던 것 같습니다. 내가 놓친 것은 face객체가 이미 faceList배열에 있으므로 if 조건에 전혀 들어가지 않는다는 것입니다.

if (!faceNodeMap.containsKey(face)) { ... }

다른 사람이 없었기 때문에 아무 일도 일어나지 않았습니다.

솔루션에는 버튼이 클릭되었는지 여부를 확인하는 또 다른 부울 변수가 있습니다!

Boolean isFox = false, changeModel = false;

...

scene.addOnUpdateListener(frameTime -> { 

...
  for (AugmentedFace face : faceList) {
    if (!faceNodeMap.containsKey(face)) {
        AugmentedFaceNode faceNode = new AugmentedFaceNode(face);
        faceNode.setParent(scene);
        faceNode.setFaceMeshTexture(faceMeshTexture1);
        faceNodeMap.put(face, faceNode);
    }
    else if (changeModel) {    // check whether we want to change texture
        if(isFox)
            faceNodeMap.get(face).setFaceMeshTexture(faceMeshTexture1);
        else
            faceNodeMap.get(face).setFaceMeshTexture(faceMeshTexture2);
    }
  }
changeModel = false; // after the for loop ends


...


    mBtnBlueLip.setOnClickListener(v -> {
        isFox = true;
        changeModel = true;
    });

    mBtnRedLip.setOnClickListener(v -> {
        changeModel = true;
        isFox = false;
    });

Kristina도 비슷한 접근 방식을 사용했습니다. 앱을 테스트 중이고 텍스처가 2개뿐이므로 부울 변수를 사용했습니다 isFox. 또한 텍스처 배열을 유지하고 faceMeshTexture어떤 버튼을 클릭했는지에 따라 값을 가져오는 변수 하나만 유지할 수 있습니다 .

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

for 루프에서 setValues () 및 copyto ()를 사용하는 Google 앱 스크립트의 런타임을 줄이는 방법

런타임에 TextView의 스타일을 변경하는 방법

AR 장면에서 런타임에 SceneKit Depth Buffer를 추출하는 방법은 무엇입니까?

AR 카메라를 이용하여 Unity 버튼 클릭시 런타임시 오브젝트의 텍스처를 변경하는 방법

Android 기기의 갤러리에서 Unity 앱의 텍스처로 런타임에 이미지를 매핑하는 방법은 무엇입니까?

런타임에 Spring의 @Scheduled fixedDelay를 변경하는 방법

3개의 js에서 렌더 타겟의 텍스처를 전환하는 방법은 무엇입니까?

런타임에 FMX ListBoxGroupHeader 텍스트를 변경하는 방법

C++: 런타임에 결정된 크기의 멤버 2D 배열을 만드는 방법

런타임 중에 Google 테스트 포인트에 인수를 전달하는 방법은 무엇입니까?

EF Core에서 런타임 스캐 폴딩을 활성화하는 방법

Google Cloud Platform의 App Engine에서 PHP 버전 (런타임)을 변경하는 방법은 무엇입니까?

.net Core 2.2 (런타임 이벤트)에서 EventListener를 사용하는 방법

런타임에 클래스를 다시 변환하는 방법

모델을 사용하여 런타임에 SQL Database를 전환하는 방법

런타임에 DiscriminatorValue를 얻는 방법

Android ArCore Sceneform API. 런타임에서 텍스처를 변경하는 방법은 무엇입니까?

C#의 WPF 창에 런타임에 텍스트 상자를 추가하는 방법은 무엇입니까?

런타임에 타일에 개체(나무)를 생성하는 방법은 무엇입니까? (유니티 2D 타일맵)

2D 배열에서 요소의 위치를 전환하는 방법은 무엇입니까?

런타임에서 Marklogic 엔티티 정의를 검색하는 방법

Unix의 grep 명령에서 런타임 변수를 사용하는 방법

Android에서 런타임에 리소스를 임의로로드하는 방법이 있습니까?

런타임에서만 생성되는 디자인 타임의 구성 요소를 코딩하는 방법

쉘 스크립트를 통해 C의 함수에 런타임 인수를 전달하는 방법

OpenGL에서 2D 텍스처 배열을 사용하는 방법

webgl2에서 3d 텍스처를 처리하는 방법

mocha 테스트 내에서 sails 앱의 런타임 URL을 얻는 방법

클래스 내의 필드에서 런타임 주석을 읽는 방법

TOP 리스트

  1. 1

    JNDI를 사용하여 Spring Boot에서 다중 데이터 소스 구성

  2. 2

    std :: regex의 일관성없는 동작

  3. 3

    JSoup javax.net.ssl.SSLHandshakeException : <url>과 일치하는 주체 대체 DNS 이름이 없습니다.

  4. 4

    PrematureCloseException : 연결이 너무 일찍 닫혔습니다.

  5. 5

    Xcode10 유효성 검사 : 이미지에 투명성이 없지만 여전히 수락되지 않습니까?

  6. 6

    정점 셰이더에서 카메라에서 개체까지의 XY 거리

  7. 7

    Ionic 2 로더가 적시에 표시되지 않음

  8. 8

    Seaborn에서 축 제목 숨기기

  9. 9

    C #에서 'System.DBNull'형식의 개체를 'System.String'형식으로 캐스팅 할 수 없습니다.

  10. 10

    복사 / 붙여 넣기 비활성화

  11. 11

    ArrayBufferLike의 typescript 정의의 깊은 의미

  12. 12

    Google Play Console에서 '예기치 않은 오류가 발생했습니다. 나중에 다시 시도해주세요. (7100000)'오류를 수정하는 방법은 무엇입니까?

  13. 13

    Kubernetes Horizontal Pod Autoscaler (HPA) 테스트

  14. 14

    jfreecharts에서 x 및 y 축 선을 조정하는 방법

  15. 15

    PRNG 기간보다 순열이 더 많은 목록을 무작위로 섞는 방법은 무엇입니까?

  16. 16

    C # HttpWebRequest 기본 연결이 닫혔습니다. 전송시 예기치 않은 오류가 발생했습니다.

  17. 17

    다음 컨트롤이 추가되었지만 사용할 수 없습니다.

  18. 18

    잘못된 구성 개체입니다. Webpack이 Angular의 API 스키마와 일치하지 않는 구성 개체를 사용하여 초기화되었습니다.

  19. 19

    Android Kotlin은 다른 활동에서 함수를 호출합니다.

  20. 20

    R의 마침표와 숫자 사이에 문자열 삽입

  21. 21

    Assets의 BitmapFactory.decodeStream이 Android 7에서 null을 반환합니다.

뜨겁다태그

보관