使用GPS位置在ARCore中渲染3D对象?

时间:2018-08-17 04:15:54

标签: java android core-location arcore

我试图在Android中使用arcore构建增强现实导航。 AR导航方向在印度可用吗?我只是按照此链接开发了使用arcre进行核心机芯导航的导航。 https://github.com/appoly/ARCore-Location/tree/legacy

是否可以在Android中使用ARCore进行ar导航?任何帮助,不胜感激。...

3 个答案:

答案 0 :(得分:9)

我也从事此工作,根据我的看法,这是可能的。由于其他一些工作,我还没有完成它,但是我可以告诉您实现此目标的步骤。

一开始,您需要找出如何放置对象而不点击屏幕的方法,因为ARCore示例不允许这样做。我在StackOverflow上问了这个问题,最后得到了一个满意的答案,该答案确实有效。 How to place a object without tapping on the screen。您可以参考此内容来实现。

此后,您需要找出放置ar对象作为方向所需要的方向。为此,请使用此公式找出标题

let lat1:Double = latSource/180 * .pi
let lng1:Double = lngSource/180 * .pi
let lat2:Double = latDestination/180 * .pi
let lng2:Double = lngDestination/180 * .pi

let y = sin(lng2 - lng1)*cos(lat2)
let x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(lng2 - lng1)

let tan2 = atan2(y, x)
let degre = tan2 * 180 / .pi
if degre < 0 {  return degre+360  }
else {  return degre  }

您需要传递源和目标的纬度和经度,这将使您从目标的TrueNorth返回角度。 这是Swift写的,希望您可以将其转换为所需的语言。 Java或Kotlin

然后,您需要将此角度与设备指南针角度匹配,并且当两个角度都匹配时,请使用不放置对象的方法。我已经分享了链接。 这会将物体带到目的地。

然后,进行循环并将对象放置在不同的z轴上。这是我编写的代码,

@Override
public void onUpdate(FrameTime frameTime) {



        frame = fragment.getArSceneView().getArFrame();

        if (frame != null) {

            for (Object o : frame.getUpdatedTrackables(Plane.class)) {

                plane = (Plane) o;

                if (plane.getTrackingState() == TrackingState.TRACKING) {
                    fragment.getPlaneDiscoveryController().hide();

                    Iterator iterableAnchor = frame.getUpdatedAnchors().iterator();

                    if (!iterableAnchor.hasNext()) {
                        method(plane, frame);
                    }
                }
            }
        }

}

public void makeAr(Plane plane, Frame frame ) {

    for (int k = 0; k <10 ; k ++) {
        if (this.degree >= 160 && this.degree <= 170) {
            Toast.makeText(this, "walk", Toast.LENGTH_SHORT).show();
            List<HitResult> hitTest = frame.hitTest(screenCenter().x, screenCenter().y);

            Iterator hitTestIterator = hitTest.iterator();

            while (hitTestIterator.hasNext()) {
                HitResult hitResult = (HitResult) hitTestIterator.next();

                modelAnchor = null;
                modelAnchor = plane.createAnchor(hitResult.getHitPose());

                AnchorNode anchorNode = new AnchorNode(modelAnchor);
                anchorNode.setParent(fragment.getArSceneView().getScene());

                TransformableNode transformableNode = new TransformableNode(fragment.getTransformationSystem());
                transformableNode.setParent(anchorNode);
                transformableNode.setRenderable(MainActivity.this.andyRenderable);

                float x = modelAnchor.getPose().tx();
                float y = modelAnchor.getPose().compose(Pose.makeTranslation(0f, 0f, 0)).ty();

                transformableNode.setWorldPosition(new Vector3(x, y, -k));

            }
        }
    }
}

private Vector3 screenCenter() {
    View vw = findViewById(android.R.id.content);
    return new Vector3(vw.getWidth() / 2f, vw.getHeight() / 2f, 0f);
}

此OnUpdate方法将Ar拉向目标。获取此信息后,您需要使用Google Map Api数据安排所有内容。

根据我的说法,这是使用ARCore在AR中进行导航的最佳方法,因为ARCore的局限性在于将来可能还会有其他一些库可以使之变得简单。

我也尝试过ArCore Location,但是这对您没有帮助,因为它会放置2D图像而不是3D图像,并且在您行走时不稳定。

祝你好运,希望你能完成这个事情。

答案 1 :(得分:0)

  

AR导航方向在印度可用吗?

是的,正如您所见here

,今天唯一明智的地方是中国
  

是否可以在Android中使用ARCore进行ar导航?

不确定我是否知道,但是可以,您可以使用AR Core在您的应用中进行导航(例如步行),并在屏幕上显示AR Objects或从设备移动中获取姿势/帧信息。 您可以将锚放置在世界上,并将此锚与GPS位置连接,然后将该锚保存在云/数据库中并加载到其他手机中。或直接渲染对象并将其保存在数据库中。当用户走近某个地方时,您会将其加载到手机中。

答案 2 :(得分:0)

这里有三个功能

有人在现实世界中使用x,y和z添加节点。

秒正在计算方位角。有关更多信息:   https://www.sunearthtools.com/tools/distance.php#top

第三名根据给定的位置计算x,y和z。

private fun addPointByXYZ(x: Float, y: Float, z: Float, name: String) {
    ViewRenderable.builder().setView(this, R.layout.sample_layout).build().thenAccept {
        val imageView = it.view.findViewById<ImageView>(R.id.imageViewSample)
        val textView = it.view.findViewById<TextView>(R.id.textViewSample)

        textView.text = name

        val node = AnchorNode()
        node.renderable = it
        scene.addChild(node)
        node.worldPosition = Vector3(x, y, z)

        val cameraPosition = scene.camera.worldPosition
        val direction = Vector3.subtract(cameraPosition, node.worldPosition)
        val lookRotation = Quaternion.lookRotation(direction, Vector3.up())
        node.worldRotation = lookRotation
    }
}

private fun bearing(locA: Location, locB: Location): Double {
    val latA = locA.latitude * PI / 180
    val lonA = locA.longitude * PI / 180
    val latB = locB.latitude * PI / 180
    val lonB = locB.longitude * PI / 180

    val deltaOmega = ln(tan((latB / 2) + (PI / 4)) / tan((latA / 2) + (PI / 4)))
    val deltaLongitude = abs(lonA - lonB)

    return atan2(deltaLongitude, deltaOmega)
}

private fun placeARByLocation(myLocation: Location, targetLocation: LatLng, name: String) {
    val tLocation = Location("")
    tLocation.latitude = targetLocation.latitude
    tLocation.longitude = targetLocation.longitude

    val degree = (360 - (bearing(myLocation, tLocation) * 180 / PI))
    val distant = 3.0

    val y = 0.0
    val x = distant * cos(PI * degree / 180)
    val z = -1 * distant * sin(PI * degree / 180)
    addPointByXYZ(x.toFloat(), y.toFloat(), z.toFloat(), name)

    Log.i("ARCore_MyLat", myLocation.latitude.toString())
    Log.i("ARCore_MyLon", myLocation.longitude.toString())
    Log.i("ARCore_TargetLat", targetLocation.latitude.toString())
    Log.i("ARCore_TargetLon", targetLocation.longitude.toString())
    Log.i("ARCore_COMPASS", azimuth.toString())
    Log.i("ARCore_Degree", degree.toString())
    Log.i("ARCore_X", x.toString())
    Log.i("ARCore_Y", y.toString())
    Log.i("ARCore_Z", z.toString())
    Toast.makeText(this@LatLngActivity, "Compass: $azimuth, Degree: $degree", Toast.LENGTH_LONG).show()
}

您在此处看到的方位角是传感器的指南针度。

完整的代码可以在我的要旨中找到。

https://gist.github.com/SinaMN75/5fed506622054d4247112a22ef72f375