arcore 示例
In this tutorial, we’ll be discussing Augmented Reality and implement a hello world sample in our android application using Sceneform.
在本教程中,我们将讨论增强现实,并使用Sceneform在我们的android应用程序中实现一个hello world示例。
增强现实 (Augmented Reality)
Augmented Reality is gaining more popularity day by day. It’s used to show you virtual 3d models/graphics in a real world through your mobile’s camera. It’s useful in demonstrating simulated stuff in the real world such as paints/decoration you’d like to see on your wall.
增强现实正在日益普及。 它用于通过手机的相机向您展示真实世界中的虚拟3D模型/图形。 在演示现实世界中模拟的东西(例如您想在墙上看到的油漆/装饰)时非常有用。
Augmented Reality lies somewhere between Virtual Reality and Real environment.
增强现实位于虚拟现实和现实环境之间。
Android ARCore (Android ARCore)
Google has come up with ARCore library to enhance AR development.
Google提出了ARCore库来增强AR开发。
ARCore does motion tracking in the real world through the camera to create paths on planes/surfaces over which we can place our 3D Models and graphics.
ARCore通过摄像头在现实世界中进行运动跟踪,以在平面/表面上创建路径,我们可以在上面放置3D模型和图形。
SceneForm is a 3D framework that’s come up recently and is a better alternative to OpenGL. OpenGL looks intimidating to code.
SceneForm是最近出现的3D框架,是OpenGL的更好替代方案。 OpenGL看起来令人胆怯。
SceneForm allows us to quickly render 3d objects without the need to learn graphics or OpenGL.
SceneForm使我们能够快速渲染3d对象,而无需学习图形或OpenGL。
We can download the Google Sceneform Tools plugin in our Android Studio to view and render the 3d models.
我们可以在Android Studio中下载Google Sceneform Tools插件,以查看和渲染3D模型。
You can go to https://poly.google.com/ and download a sample model. Don’t forget to credit the creator!
您可以访问https://poly.google.com/并下载示例模型。 不要忘记相信创作者!
Typically, the OBJ and GLTX formats are used for rendering augmented images.
通常,OBJ和GLTX格式用于渲染增强图像。
Now let’s build our first AR application where we’ll use the above 3D model as our AR image.
现在,让我们构建第一个AR应用程序,在该应用程序中,我们将上述3D模型用作AR图像。
增强现实Android示例项目结构 (Augmented Reality Android Example Project Structure)
In the above project, we’ve created a sampledata
directory, where we add the obj and mtl file downloaded earlier.
在上面的项目中,我们创建了一个sampledata
目录,在其中添加了先前下载的obj和mtl文件。
Add the following dependency in your project’s build.gradle:
在项目的build.gradle中添加以下依赖项:
classpath 'com.google.ar.sceneform:plugin:1.0.1'
Add the following in your app’s build.gradle :
在您应用的build.gradle中添加以下内容:
implementation 'com.google.ar.sceneform.ux:sceneform-ux:1.0.0'
You need to set the ar plugin in your app’s Gradle file as well.
Add the following below the dependencies:
您还需要在应用程序的Gradle文件中设置ar插件。
在依赖项下面添加以下内容:
apply plugin: 'com.google.ar.sceneform.plugin'
We have used the following image, you can download it from this link and put it in the sampledata directory:
我们使用了以下图像,您可以从此链接下载它并将其放在sampledata目录中:
Now right click on the obj file and choose import sceneform assets:
现在,右键单击obj文件,然后选择导入sceneform资产:
This would automatically create the Renderable AR sceneform assets. It would automatically add the following lines at the end of the app’s build.gradle:
这将自动创建Renderable AR Sceneform资源。 它将自动在应用程序的build.gradle末尾添加以下行:
sceneform.asset('sampledata/Coffee Cup_final.obj',
'default',
'sampledata/Coffee Cup_final.sfa',
'src/main/assets/Coffee Cup_final')
The build.gradle of the app looks like this finally:
Android ARCore Sceneform requires Java 8 or higher version.
Android ARCore Sceneform需要Java 8或更高版本。
The sja and sjb are the Sceneform Asset Description
and Sceneform Binary
files.
sja和sjb是Sceneform Asset Description
和Sceneform Binary
文件。
The sjb file is visible in the 3D viewer. It is shipped with the APK.
sjb文件在3D查看器中可见。 它与APK一起提供。
The sja file is used to set properties for the sjb file.
该SJA文件用于为SJB文件的属性集。
scale
of the model in the sja file.
scale
。
Android增强现实示例代码 (Android Augmented Reality Example Code)
To configure ARCore in your application add the following permission and metadata to your AndroidManifest.xml file.
要在您的应用程序中配置ARCore,请在您的AndroidManifest.xml文件中添加以下权限和元数据。
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature
android:name="android.hardware.camera.ar"
android:required="true" />
metadata goes inside the application tag.
元数据位于应用程序标记内。
<meta-data
android:name="com.google.ar.core"
android:value="required" />
The code for the activity_main.xml class is given below:
下面给出了activity_main.xml类的代码:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:app="https://schemas.android.com/apk/res-auto"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?android:attr/actionBarSize"
android:background="?android:attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<include layout="@layout/content_main" />
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="@dimen/fab_margin"
app:srcCompat="@android:drawable/ic_input_add" />
</android.support.design.widget.CoordinatorLayout>
The code for the content_main.xml
is given below:
下面给出了content_main.xml
的代码:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:app="https://schemas.android.com/apk/res-auto"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context=".MainActivity"
tools:showIn="@layout/activity_main">
<fragment
android:id="@+id/sceneForm"
android:name="com.google.ar.sceneform.ux.ArFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
We’ve set the fragment as ArFragment. The ArFragment
checks if the phone is compatible with ARCore.
我们将片段设置为ArFragment。 ArFragment
检查手机是否与ARCore兼容。
Also, it checks if the camera permission is granted. If it isn’t, it’ll ask for it automatically.
此外,它还会检查是否授予了相机许可。 如果不是,它将自动要求它。
Also, it’ll ask you to download the ARCore by Google Application.
另外,它还会要求您通过Google Application下载ARCore。
The code for MainActivity.java class is given below:
MainActivity.java类的代码如下:
package com.journaldev.androidarsceneform;
import android.graphics.Point;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import com.google.ar.core.Anchor;
import com.google.ar.core.Frame;
import com.google.ar.core.HitResult;
import com.google.ar.core.Plane;
import com.google.ar.core.Trackable;
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;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
public class MainActivity extends AppCompatActivity {
ArFragment arFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
addObject(Uri.parse("Coffee Cup_Final.sfb"));
}
});
arFragment = (ArFragment) getSupportFragmentManager().findFragmentById(R.id.sceneForm);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
private void addObject(Uri parse) {
Frame frame = arFragment.getArSceneView().getArFrame();
Point point = getScreenCenter();
if (frame != null) {
List<HitResult> hits = frame.hitTest((float) point.x, (float) point.y);
for (int i = 0; i < hits.size(); i++) {
Trackable trackable = hits.get(i).getTrackable();
if (trackable instanceof Plane && ((Plane) trackable).isPoseInPolygon(hits.get(i).getHitPose())) {
placeObject(arFragment, hits.get(i).createAnchor(), parse);
}
}
}
}
private final void placeObject(final ArFragment fragment, final Anchor createAnchor, Uri model) {
ModelRenderable.builder().setSource(fragment.getContext(), model).build().thenAccept((new Consumer() {
public void accept(Object var1) {
this.accept((ModelRenderable) var1);
}
public final void accept(ModelRenderable it) {
if (it != null)
MainActivity.this.addNode(arFragment, createAnchor, it);
}
})).exceptionally((new Function() {
public Object apply(Object var1) {
return this.apply((Throwable) var1);
}
@Nullable
public final Void apply(Throwable it) {
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setMessage(it.getMessage()).setTitle("error!");
AlertDialog dialog = builder.create();
dialog.show();
return null;
}
}));
}
private void addNode(ArFragment fragment, Anchor createAnchor, ModelRenderable renderable) {
AnchorNode anchorNode = new AnchorNode(createAnchor);
TransformableNode transformableNode = new TransformableNode(fragment.getTransformationSystem());
transformableNode.setRenderable(renderable);
transformableNode.setParent(anchorNode);
fragment.getArSceneView().getScene().addChild(anchorNode);
transformableNode.select();
}
private Point getScreenCenter() {
View vw = findViewById(android.R.id.content);
return new Point(vw.getWidth() / 2, vw.getHeight() / 2);
}
}
The anchor is the position where the model or the Node is placed in the screen. It’s the center of the screen here.
锚点是模型或节点在屏幕中的放置位置。 这是屏幕的中心。
In the addObject()
the ARFragment gets the hit points on the plane using motion tracking.
在addObject()
,ARFragment使用运动跟踪获取平面上的命中点。
placeObject()
asynchronously sets the node to the center of the screen.
placeObject()
异步将节点设置为屏幕的中心。
Following are the outputs when the application is launched:
以下是启动应用程序时的输出:
In the final output, the cup is positioned on the plane which consists of white dots.
在最终输出中,杯子位于由白点组成的平面上。
The above screenshot is from Samsung S8.
上面的截图来自三星S8。
Now try changing the model scale in SFA file!
现在尝试更改SFA文件中的模型比例!
This brings an end to this tutorial. You can download the final AndroidArSceneform Project from the link below.
本教程到此结束。 您可以从下面的链接下载最终的AndroidArSceneform项目 。
The size of the project is big, thanks to the OBJ file.
该项目的规模很大,这要归功于OBJ文件。
翻译自: https://www.journaldev.com/21479/android-augmented-reality-arcore-example
arcore 示例