简体   繁体   English

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

[英]Render 3D Objects in ARCore using GPS location?

I trying to build augmented reality navigation using arcore in android. 我试图在Android中使用arcore构建增强现实导航。 Is AR navigation direction is available in india? AR导航方向在印度是否可用? I just followed this link to develop ar navigation with core loaction using arcore. 我只是按照这个链接使用arcore开发带有核心loaction的ar导航。 https://github.com/appoly/ARCore-Location/tree/legacy . https://github.com/appoly/ARCore-Location/tree/legacy

Is it possible to do ar navigation using ARCore in android? 是否有可能在Android中使用ARCore进行导航? Any help much appreciated pls.... 任何帮助非常感谢请....

I also worked on this and According to me, it is possible. 我也在研究这个问题,据我说,这是有可能的。 I haven't finished it yet due to some other works but I can tell you the steps you can follow to achieve this. 由于其他一些工作,我还没有完成它,但我可以告诉你为实现这一目标你可以遵循的步骤。

Initially, you need to find out how to place an object without tapping on the screen as ARCore sample won't allow this. 最初,您需要了解如何在不点击屏幕的情况下放置对象,因为ARCore示例不允许这样做。 I asked this question on StackOverflow and finally getting a satisfactory answer which actually worked. 我在StackOverflow上问了这个问题,最后得到了一个确实有效的答案。 How to place a object without tapping on the screen . 如何在不点击屏幕的情况下放置对象 You can refer this to achieve that. 你可以参考这个来实现这一点。

After this, you need to find out the direction to which you need to place your ar object showing as the direction. 在此之后,您需要找出将ar对象显示为方向所需的方向。 for this, find out the heading using this formula 为此,使用此公式找出标题

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  }

You need to pass the latitude and longitude of source and destination then this will return you the angle from TrueNorth of your destination. 您需要传递源和目的地的纬度和经度,然后这将返回您目的地的TrueNorth角度。 This is written is Swift, I hope you can convert it into your desired language. 这是写的Swift,我希望你能把它转换成你想要的语言。 Java or Kotlin Java或Kotlin

Then you need to match this angle with your device compass angle and when it both matches use the method of without placing an object. 然后,您需要将此角度与设备罗盘角度匹配,并且当两者匹配时使用不放置对象的方法。 I already shared the link. 我已经分享了这个链接。 This will give you the object towards your destination. 这将为您提供目的地的对象。

After that, make a loop and place object at different z-axis. 之后,进行循环并将对象放在不同的z轴上。 This is the code which I wrote the do this 这是我写的代码

@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);
}

This OnUpdate method draw the Ar towards the destination. 此OnUpdate方法将Ar绘制到目标。 After getting this, you need to arrange everything with the Google Map Api data. 完成此操作后,您需要使用Google Map Api数据安排所有内容。

According to me, this is the best possible way to do navigation in AR using ARCore because there are very limitation in ARCore may be in future there will be some other libraries which will available to make it easy. 据我所知,这是使用ARCore在AR中进行导航的最佳方式,因为在ARCore中有非常的限制,将来会有一些其他库可以使它变得容易。

I also tried the ArCore Location but this won't help you beacuse it places the 2D image not the 3D as well as it is not stable when you are walking on the road. 我也尝试过ArCore位置,但这不会帮助你因为放置2D图像而不是3D,以及当你在路上行走时它不稳定。

Good Luck, Hope you'll finish this. 祝你好运,希望你能完成这件事。

Is AR navigation direction is available in india? AR导航方向在印度是否可用?

Yes, the only sensible place today is China, as you can see here 是的,今天唯一明智的地方是中国,你可以在这里看到

Is it possible to do ar navigation using ARCore in android? 是否有可能在Android中使用ARCore进行导航?

Not sure if I get, but yes, you can use AR Core to navigate with your app, like walk, and show AR Objects on the screen or get pose/frame informations from the device movement. 我不确定是否可以,但是,您可以使用AR Core导航您的应用程序,如步行,并在屏幕上显示AR对象或从设备移动获取姿势/帧信息。 You can put anchor in the world and connect this anchors with GPS locations, save this anchors on cloud/database and load in others cellphones. 您可以将锚点放在世界中并将此锚点与GPS位置连接,将此锚点保存在云/数据库上并加载到其他手机中。 Or direct objects renders and save they on DB. 或直接对象渲染并将其保存在DB上。 When a user walk close to a place you load this in his cellphone. 当用户走近一个地方时,你可以在他的手机中加载它。

here there are three functions 这里有三个功能

one is adding a node using x,y and z in real world. 一个是在现实世界中使用x,y和z添加节点。

second is calculating bearing. 第二是计算轴承。 more information on: https://www.sunearthtools.com/tools/distance.php#top 有关更多信息: https//www.sunearthtools.com/tools/distance.php#top

third is calculating x,y and z based on the location given. 第三是根据给定的位置计算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()
}

the azimuth you're seeing here is the compass degree from sensors. 你在这里看到的方位角是来自传感器的罗盘度。

the full code is available in my gist. 完整的代码可以在我的要点中找到。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM