使用 ArCore 将静态对象放置在屏幕的一角
Placing a static object in the corner of a screen with ArCore
我正在构建一个 AR 导航应用程序,但我不太熟悉它的 AR 方面。是否可以将对象放置在静态位置,例如屏幕的一角?
我的应用程序基于 Google 中的 sceneform 示例:https://github.com/google-ar/sceneform-android-sdk/tree/master/samples/hellosceneform。我已经导入了我想要使用的 3D 模型。目前,该应用程序正在寻找可以放置对象的锚点。我只是想在屏幕的一角放置一个导航箭头,不过箭头应该仍然可以旋转。
我已经搜索过示例或类似问题,但没有找到。感谢您的帮助。
使 3D 模型成为相机节点的子节点,通过使其成为相机节点的子节点,您可以强制它的位置相对于相机而不是锚点进行更新。使用局部旋转来旋转模型。
[更新]
您还可以将 sceneform 用作应用 layout.xml 的一部分。在视图的 layout.xml 中,将 SceneView 添加为视图布局的一部分。
<com.google.ar.sceneform.SceneView
android:id="@+id/sceneView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorPrimary"
/>
然后在你的 MainActivity.java
import android.net.Uri
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.widget.Toast
import com.google.ar.sceneform.Node
import com.google.ar.sceneform.Scene
import com.google.ar.sceneform.math.Vector3
import com.google.ar.sceneform.rendering.ModelRenderable
import kotlinx.android.synthetic.main.act_main.*
class MainActivity : AppCompatActivity() {
private lateinit var scene: Scene
private lateinit var node: Node
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.act_main)
scene = sceneView.scene
render(Uri.parse("coffee_cup.sfb"))
}
private fun render(uri: Uri) {
ModelRenderable.builder()
.setSource(this, uri)
.build()
.thenAccept {
addNode(it)
}
.exceptionally {
Toast.makeText(this, "Error", Toast.LENGTH_SHORT).show()
return@exceptionally null
}
}
private fun addNode(model: ModelRenderable?) {
model?.let {
node = Node().apply {
setParent(scene)
localPosition = Vector3(0f, -2f, -7f)
localScale = Vector3(3f, 3f, 3f)
renderable = it
}
scene.addChild(node)
}
}
override fun onPause() {
super.onPause()
sceneView.pause()
}
override fun onResume() {
super.onResume()
sceneView.resume()
}
}
if (useStaticArrow) {
// Rotation at the registerListeners is measured, so that the arrow points to north in our coordinate system
camera.getPose().compose(Pose.makeTranslation(0.37f, -0.17f, -1f))
.extractTranslation().toMatrix(cameraAnchorMatrix, 0);
// Rotate the arrow in the needed direction to the next target
Matrix.rotateM(cameraAnchorMatrix, 0, neededStartRotation + directionChange, 0f, 1f, 0f);
virtualObject.updateModelMatrix(cameraAnchorMatrix, scaleFactor / 12f);
virtualObject.draw(viewmtx, projmtx, colorCorrectionRgba, arrowColor);
}
(Renjith 的完整代码片段)
我正在构建一个 AR 导航应用程序,但我不太熟悉它的 AR 方面。是否可以将对象放置在静态位置,例如屏幕的一角?
我的应用程序基于 Google 中的 sceneform 示例:https://github.com/google-ar/sceneform-android-sdk/tree/master/samples/hellosceneform。我已经导入了我想要使用的 3D 模型。目前,该应用程序正在寻找可以放置对象的锚点。我只是想在屏幕的一角放置一个导航箭头,不过箭头应该仍然可以旋转。
我已经搜索过示例或类似问题,但没有找到。感谢您的帮助。
使 3D 模型成为相机节点的子节点,通过使其成为相机节点的子节点,您可以强制它的位置相对于相机而不是锚点进行更新。使用局部旋转来旋转模型。
[更新]
您还可以将 sceneform 用作应用 layout.xml 的一部分。在视图的 layout.xml 中,将 SceneView 添加为视图布局的一部分。
<com.google.ar.sceneform.SceneView
android:id="@+id/sceneView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorPrimary"
/>
然后在你的 MainActivity.java
import android.net.Uri
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.widget.Toast
import com.google.ar.sceneform.Node
import com.google.ar.sceneform.Scene
import com.google.ar.sceneform.math.Vector3
import com.google.ar.sceneform.rendering.ModelRenderable
import kotlinx.android.synthetic.main.act_main.*
class MainActivity : AppCompatActivity() {
private lateinit var scene: Scene
private lateinit var node: Node
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.act_main)
scene = sceneView.scene
render(Uri.parse("coffee_cup.sfb"))
}
private fun render(uri: Uri) {
ModelRenderable.builder()
.setSource(this, uri)
.build()
.thenAccept {
addNode(it)
}
.exceptionally {
Toast.makeText(this, "Error", Toast.LENGTH_SHORT).show()
return@exceptionally null
}
}
private fun addNode(model: ModelRenderable?) {
model?.let {
node = Node().apply {
setParent(scene)
localPosition = Vector3(0f, -2f, -7f)
localScale = Vector3(3f, 3f, 3f)
renderable = it
}
scene.addChild(node)
}
}
override fun onPause() {
super.onPause()
sceneView.pause()
}
override fun onResume() {
super.onResume()
sceneView.resume()
}
}
if (useStaticArrow) {
// Rotation at the registerListeners is measured, so that the arrow points to north in our coordinate system
camera.getPose().compose(Pose.makeTranslation(0.37f, -0.17f, -1f))
.extractTranslation().toMatrix(cameraAnchorMatrix, 0);
// Rotate the arrow in the needed direction to the next target
Matrix.rotateM(cameraAnchorMatrix, 0, neededStartRotation + directionChange, 0f, 1f, 0f);
virtualObject.updateModelMatrix(cameraAnchorMatrix, scaleFactor / 12f);
virtualObject.draw(viewmtx, projmtx, colorCorrectionRgba, arrowColor);
}
(Renjith 的完整代码片段)