virocore icon indicating copy to clipboard operation
virocore copied to clipboard

[AR] How to place a 3D animation in a specific longitude and latitude?

Open HLneoh opened this issue 5 years ago • 16 comments

Hi guys, I want to implement AR feature. How can I place a 3D animation in specific longitude and latitude? So that when my camera is close to the specific location, the 3D animation can be seen.

Thanks in advance.

HLneoh avatar Aug 06 '18 14:08 HLneoh

See the comments on this issue regarding lat long (location based) imlpementation -> https://github.com/viromedia/viro/issues/131

dam00n avatar Aug 06 '18 14:08 dam00n

Thanks for the comment. Instead of using viro react, can I use viro core (java) to place 3D animations in a specifc longitutde and latitude?

If yes, may I know how can I achieve that?

HLneoh avatar Sep 04 '18 16:09 HLneoh

HI @HLneoh,

The react sample code for this would translate fairly well to java: https://github.com/viromedia/viro/files/1865035/HelloWorldSceneAR.js.zip

Here's some code on how it might work in Java using ViroCore:

// Convert lat/long coords to 2d mercator projection.
private float latLongToMerc(float at_deg, float lon_deg) {
   float lon_rad = (lon_deg / 180.0 * Math.PI);
   float lat_rad = (lat_deg / 180.0 * Math.PI);
   float sm_a = 6378137.0f;
   float xmeters  = sm_a * lon_rad;
   float ymeters = sm_a * Math.log((Math.sin(lat_rad) + 1) / Math.cos(lat_rad));
   float returnArr[] = new float[] {xmeters, ymeters};
   return returnArr;
}

// Take lat/long point and transform point to AR space. 
// TODO: Add code to rotate AR coords by angle from true north.
private float[] transformPointToAR(float lat, float long) {
  float objPoint[] = this.latLongToMerc(lat, long);
   // change this to be the lat/long of the device...
  float devicePoint[] = this.latLongToMerc(47.618534, -122.338478);

  // latitude(north,south) maps to the z axis in AR
  // longitude(east, west) maps to the x axis in AR
  float objFinalPosZ = objPoint[1] - devicePoint[1]
  float objFinalPosX = objPoint[0]- devicePoint[0];
  //flip the z, as negative z(is in front of us which is north, pos z is behind(south).
   float returnArr[] = new float[] {objFinalPosX, -objFinalPosZ};
   return returnArr;
}

Then in your scene.. when you position your nodes:

//position point at following lat/long.
float northPoint[] = this.transformPointToAR(47.618574, -122.338475);
Node node = new Node();
//this assumes device is facing true north. If not, rotate coords by angle from north
node.setPosition(northPoint[0], 0, northPoint[1]);

In addition to the above you'll have to rotate the AR coords by the angle from from true north using the device compass or by asking the user what true north is and rotating by that since the device compass may not be reliable due to interference.

You can place and object or an object with an animation attached using the above code. Try that and see if it works :)

VikAdvani avatar Sep 04 '18 20:09 VikAdvani

Hi, @VikAdvani. Thanks for the response. I have two questions regarding your comment.

  1. In function transformPointToAR, as it stated latitude(north,south) maps to the z axis in AR longitude(east, west) maps to the x axis in AR

Why the codes in your comment are: float objFinalPosZ = objPoint[1] - devicePoint[1] float objFinalPosX = objPoint[0]- devicePoint[0];

Instead of float objFinalPosZ = objPoint[0] - devicePoint[0] float objFinalPosX = objPoint[1]- devicePoint[1];

As from my interpretation, I think objPoint[0] and devicePoint[0] refer to latitude whereas objPoint[1] and devicePoint[1] refer to longitude. Then, objFinalPosZ (z-axis in AR) will get the latitude value whereas objFinalPosX (x-axis in AR) will get the longitude value.

  1. For the last code in your comment [ node.setPosition(northPoint[0], 0, northPoint[2]); ], why there is northPoint[2] in z-coordinate? I think it should be node.setPosition(northPoint[1], 0, northPoint[0]); if my interpretation in first question is corrent.

Can I seek for your advice?

HLneoh avatar Sep 06 '18 17:09 HLneoh

Hi @HLneoh, Your questions addressed below

  1. The method latLongToMerc returns the longitude at index 0 and latitude at index 1, hence the values the way they are.

  2. You are correct on this point, it is incorrect but the values should be: node.setPosition(northPoint[0], 0, northPoint[1]); I'll fix the sample code I posted. My mistake!

Let me know if have any more questions. Thanks!

VikAdvani avatar Sep 06 '18 18:09 VikAdvani

Hi, @VikAdvani. Thanks for your clarification.

In my scene, when I position my nodes:

Here are your codes in the comment: float northPoint[] = this.transformPointToAR(47.618574, -122.338475); Node node = new Node(); node.setPosition(northPoint[0], 0, northPoint[1]);

After your codes, I have added the following codes: node.setOpacity(1); myARScene.getRootNode().addChildNode(node); // add node to ARScene view.setScene(myARScene);

However, by using the codes above, when my device enters the ARScene, the object appears for a second, then it disappears (like a flash).

I have read the viro core documentation and found a statement - "While it's possible to add a Node to the ARScene at an arbitrary point in world coordinate space, this is not recommended" under Tracking and Anchors. Therefore, I decided to add the object to arbitrary positions by anchoring that object using ARScene.createAnchoredNode(Vector). [The third method as below]

image

Below are my codes: private ARNode arNode; //global variable

float northPoint[] = this.transformPointToAR(47.618574, -122.338475); Node node = new Node(); node.setPosition(northPoint[0], 0, northPoint[1]); node.setOpacity(1); arNode= myARScene.createAnchoredNode(northPoint[0], 0, northPoint[1]); arNode.addChildNode(node); view.setScene(myARScene);

However, my app keeps stopping and unable to enter the AR scene at all.

May I seek for your advices?

HLneoh avatar Sep 07 '18 10:09 HLneoh

Hi, can someone lend me a hand pls? :( @VikAdvani

HLneoh avatar Sep 08 '18 17:09 HLneoh

Hi @HLneoh, I suspect createAnchoredNode is returning NULL, and crashing your app. This will happen if the AR scene isn't initialized. If you wait for tracking to initialize then this should work.

VikAdvani avatar Sep 08 '18 17:09 VikAdvani

Hi @VikAdvani, my app does not crash as I createAnchoredNode after AR scene is initialized. However, the object still appears for a second (less than one second I think), then it disappears. [like a flash].

Can I have your advice pls?

HLneoh avatar Sep 08 '18 18:09 HLneoh

Hi @HLneoh, Curious how far is the lat/long point from you? Perhaps the point or node is getting 'culled' so it's not rendering because it's too far from your current location.

VikAdvani avatar Sep 10 '18 17:09 VikAdvani

Hi, for experiment purpose, I just set createAnchoredNode(0,0,-2) [just two meters from my camera view based on documentation of viro core under tracking and anchor].

HLneoh avatar Sep 10 '18 17:09 HLneoh

Hi @HLneoh, can I see the full code you have around createAnchoredNode? Do the other ViroCore samples work you? What device do you have? (ie, Android OS vs and device model)

VikAdvani avatar Sep 10 '18 18:09 VikAdvani

Hi @VikAdvani , I am using Samsung A5 and Android Studio 3.1.2

The first picture is used to call initAR function after the tracking is initialized as below: image

The second picture encompasses the codes of initAR function as below: image

image

image

HLneoh avatar Sep 13 '18 12:09 HLneoh

@VikAdvani

HLneoh avatar Sep 17 '18 03:09 HLneoh

Hi @HLneoh and @VikAdvani Have you found the solution for the above conversation.? if so could you please mention here..

SamplesCZ avatar Oct 23 '18 05:10 SamplesCZ

Hi @SamplesCZ, Since the thread on this issue is long, what specific issue are you running into or do you need help with? This thread details how to specify a longitude and latitude in AR in detail so let me know if there are some gaps you need help with.

VikAdvani avatar Oct 23 '18 19:10 VikAdvani