ImageTracking_MultiTarget_SameImage¶
Attention
The content of this page will be updated soon.
Demonstrate different ways of tracking multiple targets.
Demonstrate how to track multiple same targets simultaneously
Demonstrate how to load image target using custom code
How It Works¶
Create multiple targets from one image¶
This sample use a fully customized method to load image target, so that the same image will not be loaded multiple times from the storage.
It loads Texture2D, and create multiple targets after that.
private void Start()
{
imageTracker = Session.GetComponentInChildren<ImageTrackerFrameFilter>();
HandleTrackerEvents(imageTracker);
var source = new ImageTargetController.Texture2DSourceData()
{
Texture = TargetTexture,
Name = TargetTexture.name,
Scale = 0.09f
};
if (!source.IsTextureLoadable)
{
throw new Exception($"Error loading target Texture2D data for {source.Name}: {source.TextureUnloadableReason}");
}
LoadTexture2DData(source);
}
private unsafe void LoadTexture2DData(ImageTargetController.Texture2DSourceData source)
{
var data = source.Texture.GetRawTextureData<byte>();
var size = new Vector2Int(source.Texture.width, source.Texture.height);
var pixelFormat = source.TexturePixelFormat.Value;
var scale = source.Scale;
var ptr = data.GetUnsafeReadOnlyPtr();
int oneLineLength = size.x * ((pixelFormat == PixelFormat.RGBA8888 || pixelFormat == PixelFormat.BGRA8888) ? 4 : ((pixelFormat == PixelFormat.RGB888 || pixelFormat == PixelFormat.BGR888) ? 3 : 1));
int totalLength = oneLineLength * size.y;
using (var buffer = easyar.Buffer.create(totalLength))
{
for (int i = 0; i < size.y; i++)
{
buffer.tryCopyFrom(new IntPtr(ptr), oneLineLength * i, totalLength - oneLineLength * (i + 1), oneLineLength);
}
using (var image = easyar.Image.create(buffer, pixelFormat, size.x, size.y, size.x, size.y))
{
CreateMultipleTargetsFromOneImage(image, 10, name, scale);
}
}
}
We use the ImageTarget.createFromParameters method to create the ImageTarget directly.
using (var param = new ImageTargetParameters())
{
param.setImage(image);
param.setName(name);
param.setScale(scale);
param.setUid(Guid.NewGuid().ToString());
param.setMeta(string.Empty);
var targetOptional = ImageTarget.createFromParameters(param);
...
}
Create a GameObject with ImageTargetController and set the above ImageTarget to ImageTargetController.Source so that the controller can be initialized with ImageTargetController.DataSource.Target.
var target = targetOptional.Value;
var go = new GameObject(name + " <" + i + ">", typeof(ImageTargetController));
var controller = go.GetComponent<ImageTargetController>();
HandleTargetControllerEvents(controller);
controller.TargetDataLoad += (_) => target.Dispose();
controller.Source = new ImageTargetController.TargetSourceData
{
Target = target
};
controller.Tracker = imageTracker;
You can always use this method to setup ImageTargetController using a pre-created target, including a target manually created or a target from CloudRecognizer callback.
Loop above procedure to produce multiple targets in the scene.
private void CreateMultipleTargetsFromOneImage(Image image, int count, string name, float scale)
{
for (int i = 0; i < count; i++)
{
using (var param = new ImageTargetParameters())
{
...
var targetOptional = ImageTarget.createFromParameters(param);
if (targetOptional.OnSome)
{
var target = targetOptional.Value;
...
}
else
{
throw new Exception("invalid parameter");
}
}
}
}