java - Augmented Faces API (ARCore) - 如何使用 Android Studio 中的按钮将 mask 替换为另一个 mask

标签 java android arcore android-augmented-reality

我正在使用 Android Studio 中的 ARCore-Augmented Faces API 开发 AR android 应用程序。现在,我已经完成了应用程序的设置(5 个按钮及其关联的 3d 模型),当我第一次单击其中一个按钮启动应用程序时,它运行良好。问题是当我单击另一个按钮来更改当前 mask 时,它不会用新 mask 替换当前 mask 。

但是,要解决这个问题。我尝试使用 restart() 方法并尝试删除 facenode。但似乎,这些解决方案根本不起作用。

这是我目前正在处理的代码的一部分(不是修复代码),我仍然遇到了我遇到的问题。


        alchemist_ovalbtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                alchemistOval();
            }
        });

        scene.addOnUpdateListener(
                (FrameTime frameTime) -> {
                    if (faceRegionsRenderable == null) {
                        return;
                    }

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

                    // Make new AugmentedFaceNodes for any new faces.
                    for (AugmentedFace face : faceList) {
                        if (!faceNodeMap.containsKey(face)) {
                            AugmentedFaceNode faceNode = new AugmentedFaceNode(face);
                            faceNode.setParent(scene);
                            faceNode.setFaceRegionsRenderable(faceRegionsRenderable);
                            faceNode.setFaceMeshTexture(faceMeshTexture);
                            faceNodeMap.put(face, faceNode);
                        }
                    }

                });

// Remove any AugmentedFaceNodes associated with an AugmentedFace that stopped tracking.

        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();
            }
        }

public void alchemistOval() {

        ModelRenderable.builder()
                .setSource(this, R.raw.alchemist_oval)
                .build()
                .thenAccept(
                        modelRenderable -> {
                            faceRegionsRenderable = modelRenderable;
                            modelRenderable.setShadowCaster(false);
                            modelRenderable.setShadowReceiver(false);
                        });

    }

因此,我希望当用户单击另一个按钮时,当前的 mask 将被新的 mask 替换。

最佳答案

此代码在点击时在 3 个 mask 之间交换,希望对您有所帮助。

package com.example.faceplay;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;

import com.google.ar.core.AugmentedFace;
import com.google.ar.core.TrackingState;
import com.google.ar.sceneform.ArSceneView;
import com.google.ar.sceneform.FrameTime;
import com.google.ar.sceneform.Scene;
import com.google.ar.sceneform.rendering.ModelRenderable;
import com.google.ar.sceneform.rendering.Renderable;
import com.google.ar.sceneform.rendering.Texture;
import com.google.ar.sceneform.ux.AugmentedFaceNode;

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {


    private FaceFragment arFragment;

    private Texture faceMeshTexture;
    Scene scene;
    ArSceneView sceneView;
    AugmentedFaceNode faceNode;

    private final HashMap<AugmentedFace, AugmentedFaceNode> faceNodeMap = new HashMap<>();

    ImageView mask, eyemask, skull_1;
    View arrayView[];

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        arFragment = (FaceFragment) getSupportFragmentManager().findFragmentById(R.id.face_fragment);



        mask = (ImageView)findViewById(R.id.mask);
        eyemask = (ImageView)findViewById(R.id.eyemask);
        skull_1 = (ImageView)findViewById(R.id.skull_1);

        setArrayView();
        setClickListener();


        sceneView = arFragment.getArSceneView();
        sceneView.setCameraStreamRenderPriority(Renderable.RENDER_PRIORITY_FIRST);
        scene = sceneView.getScene();



        scene.addOnUpdateListener(

                (FrameTime frameTime) -> {

                    if ( faceMeshTexture == null) {
                        return;
                    }

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

                    for (AugmentedFace face : faceList) {

                        if (!faceNodeMap.containsKey(face)) {

                           faceNode = new AugmentedFaceNode(face);

                            faceNode.setParent(scene);
                            faceNode.setFaceMeshTexture(faceMeshTexture);

                            faceNodeMap.put(face, faceNode);

                        }

                    }

                });
    }

    private void AugmentedFaceDisplay(int resource){

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            Texture.builder()
                    .setSource(this, resource)
                    .build()
                    .thenAccept(texture -> faceMeshTexture = texture);
        }


    }

    private void setArrayView(){
        arrayView = new View[]{
                mask, eyemask, skull_1
        };
    }

    private void setClickListener(){
        for ( int i = 0; i < arrayView.length; i++){
            arrayView[i].setOnClickListener(this);
        }
    }

    @Override
    public void onClick(View v) {

        // First face mask 
        if( v.getId() == R.id.mask )
        {
            faceNodeMap.clear();
            try{
                faceNode.setParent(null);
            }
            catch (Exception e){

            }

            AugmentedFaceDisplay(R.drawable.mask);
        }

        // Second face mask      
        else  if( v.getId() == R.id.eyemask)
        {
            faceNodeMap.clear();
            try{
                faceNode.setParent(null);
            }
            catch (Exception e){

            }
            AugmentedFaceDisplay(R.drawable.eyemask);
        }

        // Third face mask 
        else  if( v.getId() == R.id.skull_1 )
        {
            faceNodeMap.clear();
            try{
                faceNode.setParent(null);
            }
            catch (Exception e){

            }
            AugmentedFaceDisplay(R.drawable.skull1);
        }
    }
}

关于java - Augmented Faces API (ARCore) - 如何使用 Android Studio 中的按钮将 mask 替换为另一个 mask ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56051634/

相关文章:

java - 正则表达式按“:{ in java?”分割

Java AWT Window实现不运行paint()函数

android - NDK从 native 代码调用函数

android apk 非市场安装更新通知

c# - ARCore – 如何在 C# 中将 YUV 相机帧转换为 RGB 帧?

java - 新线程执行后代码块未运行

java - 使用 jMock 模拟 javax.mail.message

android - Sceneform 与相机的碰撞

java - 顺利更改按钮文本

android - AR平面未检测到垂直表面