Topic: Pooling marker3D

Hi
I want to implement a pooling system for my marker3D gameobject.

I noticed that it's possible to create marker3D from existing gameobject (instead of instancing prefab).

So i'm asking myself if i should :

- 1) make a pooling system for the gameobjects, and create marker3D (from pooled gameobject) when i need it and remove the marker3D when i put the gameobject back in the pool

- 2) make a pooling system for marker3D directly. Use OnlineMapsMarker3DManager.instance.Create to populate my pool and disable those marker, then just activate and set position when i need a marker.

From your experience, what would be best ?

solution 2) seems to be more in the "pooling" spirit.
But does a disabled marker3D "cost" anything in term of GPU ? Is it enought to disable its gameObject or is there a specific way to "shut it down" when it's not currently in use?

Thx for help smile

Re: Pooling marker3D

Hello.

If you don't need marker events, then the best way is to position GameObjects on the map yourself using OnlineMapsTileSetControl.GetWorldPosition.
In fact, marker events are easy to implement using MonoBehaviour, so this should not be a problem.

First, it will work faster, because the markers have a lot of specific logic that is not needed for most projects.
Secondly, you no longer need to think about the features and limitations of the markers. You work directly with GameObjects.

No, the disabled marker doesn't cost anything for GPU, but still cost a little for CPU.

Kind Regards,
Infinity Code Team.

Boost your productivity a lot and immediately using Ultimate Editor Enhancer. Trial and non-commerce versions available.

Re: Pooling marker3D

Thanks for the response.

What i really need for those gameobjects are:

- follow the map when it's moving (so it stay at the exact gps location & altitude)
- keep the same size proportionnally to the map zoom lvl (my gameObject should grow in size when the user zoom on the map)
- be disabled when out of the square map view

I think i could work with that. Is it an overkill to use 3D marker for this behaviour ?

Now correct me if i'm wrong, but to implement this behaviour myself, i need to : 

1) position my gameobject based on its GPS location. I will use this function : 

/// <summary>
    /// Return the World position of a GpsCoordinates position
    /// </summary>
    /// <param name="pos">GpsCoordinates position to convert</param>
    public static Vector3 GetWorldPositionWithAltitude(GpsCoordinates pos)
    {
        Vector3 p = OnlineMapsTileSetControl.instance.GetWorldPosition(pos.Longitude, pos.Latitude);

        OnlineMaps.instance.UpdateCorners();
        double tlx, tly, brx, bry;
        OnlineMaps.instance.GetCorners(out tlx, out tly, out brx, out bry);

        p.y = (float)pos.Altitude;
        
        p.y += OnlineMapsElevationManagerBase.GetUnscaledElevation(pos.Longitude, pos.Latitude, tlx, tly, brx, bry);
        p.y *= OnlineMapsElevationManagerBase.GetBestElevationYScale(tlx, tly, brx, bry);
        p.y *= OnlineMaps.instance.transform.localScale.x;
        return p;
    }

Then to keep the proper position i would need to subscribe to

OnlineMapsTileSetControl.instance.OnMeshUpdated

and use the function above to reposition my gameobject.

I also need to subscribe to

OnlineMapsTileSetControl.instance.OnSmoothZoomProcess

to keep a  proper scale for my gameobject. I think i should store the original scale of the gameobject for a given zoom lvl and adapt it to the current zoom level. Something like :

/// <summary>
    /// Zoom, when the scale = 1.
    /// </summary>
    public int defaultZoom = 20;

And then each time OnSmoothZoomProcess is called :

float originalScale = 1 << defaultZoom;
float currentScale = 1 << OnlineMaps.instance.zoom;
float scale = currentScale / originalScale;
transform.localScale = new Vector3(scale, scale, scale);

I'm not sure that my pieces of codes are correct. I also don't now if i'm missing some important stuff

Re: Pooling marker3D

Yes, with proper implementation it will work faster than markers.

In general, the code looks (I have not tested it) well, except for the last part with scaling.
This way works for int zoom, but does not work for float zoom.
The right way:
http://forum.infinity-code.com/viewtopi … 4529#p4529

You forgot to mention disabling / enabling the markers.
You can see the implementation of this in OnlineMapsMarker3D.Update.

Kind Regards,
Infinity Code Team.

Boost your productivity a lot and immediately using Ultimate Editor Enhancer. Trial and non-commerce versions available.

Re: Pooling marker3D

So i finally had time to implement it, and it's working well smile

One problem remains though : the altitude calculation.

I'm using elevation, and the function

/// <summary>
    /// Return the World position of a GpsCoordinates position
    /// </summary>
    /// <param name="pos">GpsCoordinates position to convert</param>
    public static Vector3 GetWorldPositionWithAltitude(GpsCoordinates pos)
    {
        Vector3 p = OnlineMapsTileSetControl.instance.GetWorldPosition(pos.Longitude, pos.Latitude);

        OnlineMaps.instance.UpdateCorners();
        double tlx, tly, brx, bry;
        OnlineMaps.instance.GetCorners(out tlx, out tly, out brx, out bry);

        p.y = (float)pos.Altitude;
        
        p.y += OnlineMapsElevationManagerBase.GetUnscaledElevation(pos.Longitude, pos.Latitude, tlx, tly, brx, bry);
        p.y *= OnlineMapsElevationManagerBase.GetBestElevationYScale(tlx, tly, brx, bry);
        p.y *= OnlineMaps.instance.transform.localScale.x;
        return p;
    }

make my object appears below the ground. I need to calculate the relative altitude (if i feed my function with a position with altitude = 0, i want it to appear at the surface of the ground, whenever i'm at the top of a mountain or at the bottom of a hole)

I tried to look at the markers3D code for the calculation of the relative altitude but failed to find the answer hmm

Re: Pooling marker3D

Your code looks fine and should work (theoretically) for Bottom Mode - Zero.
For Bottom Mode - Min Value you need to do:

p.y = (float)pos.Altitude;
p.y += OnlineMapsElevationManagerBase.GetUnscaledElevation(pos.Longitude, pos.Latitude, tlx, tly, brx, bry);
p.y -= OnlineMapsElevationManagerBase.instance.minValue;

Or you can try to do it this way:

public static Vector3 GetWorldPositionWithAltitude(GpsCoordinates pos)
{
    double tlx, tly, brx, bry;
    OnlineMaps.instance.GetCorners(out tlx, out tly, out brx, out bry);

    Vector3 p = OnlineMapsTileSetControl.instance.GetWorldPositionWithElevation(pos.Longitude, pos.Latitude, tlx, tly, brx, bry);
    float el = OnlineMapsElevationManagerBase.GetUnscaledElevation(pos.Longitude, pos.Latitude, tlx, tly, brx, bry);

    float yOff = pos.y - el;
    yOff *= OnlineMapsElevationManagerBase.GetBestElevationYScale(tlx, tly, brx, bry);
    yOff *= OnlineMaps.instance.transform.localScale.x;
    p.y += yOff;

    return p;
}

P.S. I wrote it without IDE, so there may be typos.

Kind Regards,
Infinity Code Team.

Boost your productivity a lot and immediately using Ultimate Editor Enhancer. Trial and non-commerce versions available.