Я пытаюсь получить расстояние между камерой и центром головы пользователя с помощью AugmentedFace. Это на самом деле хорошо работает, но я могу получить этот результат только один раз, даже если мои вычисления установлены в методе onUpdate. Я где-то что-то упустил, но не понимаю почему.
Вот код.
public class HelloSceneformActivity extends AppCompatActivity implements Scene.OnUpdateListener{
private static final String TAG = HelloSceneformActivity.class.getSimpleName();
private static final double MIN_OPENGL_VERSION = 3.0;
private HashMap<AugmentedFace, AugmentedFaceNode> faceNodeMap = new HashMap<>();
private FaceArFragment arFragment;
private ModelRenderable faceRegionsRenderable;
private Texture faceMeshTexture;
private Pose centerFace;
private TextView tv;
private float distance;
private ArSceneView sceneView;
private Scene scene;
private Session session;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (!checkIsSupportedDeviceOrFinish(this)) {
return;
}
setContentView(R.layout.activity_ux);
tv = findViewById(R.id.tv);
arFragment = (FaceArFragment) getSupportFragmentManager().findFragmentById(R.id.ux_fragment);
ModelRenderable.builder()
.setSource(this, R.raw.fox_face)
.build()
.thenAccept(
modelRenderable -> {
faceRegionsRenderable = modelRenderable;
modelRenderable.setShadowCaster(false);
modelRenderable.setShadowReceiver(false);
});
Texture.builder()
.setSource(this,R.drawable.fox_face_mesh_texture)
.build()
.thenAccept(texture -> faceMeshTexture = texture);
sceneView = arFragment.getArSceneView();
// This is important to make sure that the camera stream renders first so that
// the face mesh occlusion works correctly.
sceneView.setCameraStreamRenderPriority(Renderable.RENDER_PRIORITY_FIRST);
scene = sceneView.getScene();
scene.addOnUpdateListener(
this::onUpdate);
}
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;
}
@Override
public void onUpdate(FrameTime frameTime){
Frame frame = arFragment.getArSceneView().getArFrame();
Pose cameraPose = frame.getCamera().getPose();
Log.d("test",String.valueOf(cameraPose));
if (faceRegionsRenderable == null || faceMeshTexture == 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);
centerFace = face.getCenterPose();
faceNodeMap.put(face, faceNode);
faceNode.setFaceMeshTexture(faceMeshTexture);
}
}
// 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();
}
}
if(centerFace != null) {
Pose objectPose = centerFace;
float dx = objectPose.tx() - cameraPose.tx();
float dy = objectPose.ty() - cameraPose.ty();
float dz = objectPose.tz() - cameraPose.tz();
///Compute the straight-line distance.
float distance = (float) Math.sqrt(dx * dx + dy * dy + dz * dz);
Log.d("test", String.valueOf(distance));
}
}
}
Я начал с примера googles do c. Если кто-то более знаком с этой технологией на android, я был бы признателен за любые советы. Большое спасибо!