我正在使用 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/