Class SurfaceWorldMarkerRenderer
public sealed class SurfaceWorldMarkerRenderer : IDisposable, IMarkerStyle
- Inheritance
-
objectSurfaceWorldMarkerRenderer
- Implements
Constructors
SurfaceWorldMarkerRenderer(MarkerStore)
Shares an existing store - typically a fullscreen MarkerLayer's - so the same markers render on both the screen path and the tabletop without copying, and a 2D-to-tabletop switch is a pure view swap. The owning layer keeps its dirty-range fast path; this layer re-uploads whole when the store's Version moves. Known cost: in shared mode ANY mutation re-uploads the whole buffer here, so a very large shared store with per-frame marker animation pays a full SetData per frame on this side - fine for switch-and-view usage, wrong for animating hundreds of thousands of shared markers.
public SurfaceWorldMarkerRenderer(MarkerStore sharedStore)
Parameters
sharedStoreMarkerStore
SurfaceWorldMarkerRenderer(int)
public SurfaceWorldMarkerRenderer(int initialCapacity)
Parameters
initialCapacityint
Fields
HideOutsideSurface
public bool HideOutsideSurface
Field Value
MaxAltitudeMercator
Upper altitude bound (mercator units), inclusive. See MinAltitudeMercator.
public float MaxAltitudeMercator
Field Value
MinAltitudeMercator
Lower altitude bound (mercator units,
AltitudeMercator) a marker must
meet to be uploaded/drawn by this layer, inclusive.
NegativeInfinity, the default, means no lower
bound. Per-layer-instance: the shared-store convention pairs this
with a MarkerLayer filtered to
alt <= 0, filtering this layer to alt > 0 so the
ground and floating tiers of one shared store never both draw the
same marker.
public float MinAltitudeMercator
Field Value
Store
public readonly MarkerStore Store
Field Value
Properties
ApplyZoomRange
When true, the default, each marker's stored min/max zoom window hides it outside that range. When false the windows stay stored but every marker on this layer is drawn and pickable at any zoom. Combined with the per-marker flag: both must be true to apply.
public bool ApplyZoomRange { get; set; }
Property Value
CustomShapes
Registered shape sources in shape-id order, so index i is shape id FirstCustomShapeId + i. Baked SDF entries belong to this layer; the others are the caller's own textures.
public IReadOnlyList<Texture2D> CustomShapes { get; }
Property Value
- IReadOnlyList<Texture2D>
OutlineColor
public Color OutlineColor { get; set; }
Property Value
- Color
OutlineWidthPx
public float OutlineWidthPx { get; set; }
Property Value
ShapeAtlas
The packed shape atlas, or null before the first RegisterShape(Texture2D, bool).
public Texture2D ShapeAtlas { get; }
Property Value
- Texture2D
StemWidthPx
public float StemWidthPx { get; set; }
Property Value
StemsEnabled
public bool StemsEnabled { get; set; }
Property Value
Visible
public bool Visible { get; set; }
Property Value
Methods
Dispose()
Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
public void Dispose()
RegisterCustomShape(Texture2D, bool)
Registers a readable texture as a marker shape on this tier and returns the shape to pass to the store.
public MarkerShape RegisterCustomShape(Texture2D readableTexture, bool asSdf = false)
Parameters
readableTextureTexture2DCPU-readable texture, for example a sprite rasterized from an imported SVG.
asSdfboolTrue bakes the alpha silhouette into a distance field so the shape stays crisp at any size (monochrome, tinted by the marker color). False keeps a full-color sprite.
Returns
- MarkerShape
Shape whose numeric value is at or above FirstCustomShapeId.
Remarks
The world-space counterpart to RegisterCustomShape(Texture2D, bool): same atlas packing, same asSdf semantics, same shape-id namespace. Each tier keeps its own registry, so markers drawn on both call this once per tier; registering in the same order on each keeps one stored shape value meaning the same picture on both.
The source texture must be CPU-readable (tick Read/Write Enabled on the texture importer). A tier holds at most 64 custom shapes. Registering one at a time repacks the atlas per call; to register a set, use RegisterCustomShapes(IReadOnlyList<CustomShapeRequest>, List<MarkerShape>), which packs once.
Ownership: with asSdf true this tier bakes a new
texture, owns it, and destroys it on Dispose(), while
your source stays yours. With asSdf false it
packs your texture and never destroys it, so keep it alive for as
long as this tier draws that shape.
RegisterCustomShapes(IReadOnlyList<CustomShapeRequest>, List<MarkerShape>)
Registers several shapes at once on this tier, packing the shape atlas exactly once.
public void RegisterCustomShapes(IReadOnlyList<CustomShapeRequest> requests, List<MarkerShape> ids)
Parameters
requestsIReadOnlyList<CustomShapeRequest>Shapes to register, in the order their ids are wanted.
idsList<MarkerShape>Cleared, then filled with one shape per request, in request order.
Remarks
Same per-shape contract as RegisterCustomShape(Texture2D, bool), and the same cost argument as RegisterCustomShapes(IReadOnlyList<CustomShapeRequest>, List<MarkerShape>): registering n shapes individually packs the atlas n times, this packs once.
A batch is all or nothing. Whether it is refused for exceeding the 64-shape limit or one of its textures turns out not to be readable, this tier is left exactly as it was, so the same batch can be handed back after the bad texture is fixed without the failed attempt having consumed any shape slots.
RegisterShape(Texture2D, bool)
Registers a readable texture as a marker shape on this tier and returns the id to store in MarkerInstanceData.Shape.
public int RegisterShape(Texture2D readableTexture, bool asSdf = false)
Parameters
readableTextureTexture2DCPU-readable texture, for example a sprite rasterized from an imported SVG.
asSdfboolTrue bakes the alpha silhouette into a distance field so the shape stays crisp at any size (monochrome, tinted by the marker color). False keeps a full-color sprite.
Returns
- int
Shape id at or above FirstCustomShapeId, as an int.
Remarks
Identical to RegisterCustomShape(Texture2D, bool) except for the return type. Prefer RegisterCustomShape(Texture2D, bool), which hands back the MarkerShape the store methods already take, so no cast is needed at the call site.
Render(MapViewTransform, in SurfaceUvMap, Transform, Renderer)
Submits this frame's draw. Call once per frame after the surface view is final (LateUpdate).
public void Render(MapViewTransform view, in SurfaceUvMap uvMap, Transform plane, Renderer planeRenderer)
Parameters
viewMapViewTransformThe surface's own view (pitch 0).
uvMapSurfaceUvMapUV parameterisation of the table mesh.
planeTransformThe table transform the markers stand on; positions and the billboard size follow it every frame, so a moving table carries its markers rigidly.
planeRendererRendererRenderer whose world bounds anchor the draw's culling bounds; expanded upward by the tallest marker so a camera looking only at airspace above the table still renders it, and - when HideOutsideSurface is off - widened horizontally to cover markers standing outside the table too, since that is the toggle's whole purpose and an under-sized bounds here would cull the entire draw call, not just the off-table markers.
TryPick(Ray, MapViewTransform, in SurfaceUvMap, Transform, float, out int)
Picks the nearest marker along a world-space ray (a camera ray in an AR/VR scene), altitude-aware: a raised billboard is hit at its raised position, not at its ground pixel. Returns false when no marker comes within its pick radius. O(active markers) - fine for a pointer event, not for per-frame batch queries.
public bool TryPick(Ray worldRay, MapViewTransform view, in SurfaceUvMap uvMap, Transform plane, float pickRadiusPx, out int slot)
Parameters
worldRayRayRay in world space (Camera.ScreenPointToRay).
viewMapViewTransformThe surface's own view.
uvMapSurfaceUvMapUV parameterisation of the table mesh.
planeTransformThe table transform markers stand on.
pickRadiusPxfloatExtra grab slack in marker pixels, added to each marker's own visual radius.
slotintStore slot of the hit marker.
Returns
TryPick(Ray, MapViewTransform, in SurfaceUvMap, Transform, float, out int, out float)
Same as TryPick(Ray, MapViewTransform, SurfaceUvMap, Transform, float, out int) plus the along-ray distance of the hit, in world units, for ranking against tabletop prefabs.
public bool TryPick(Ray worldRay, MapViewTransform view, in SurfaceUvMap uvMap, Transform plane, float pickRadiusPx, out int slot, out float along)
Parameters
worldRayRayviewMapViewTransformuvMapSurfaceUvMapplaneTransformpickRadiusPxfloatslotintalongfloat