//================================================================================================================================
//
// Copyright (c) 2015-2019 VisionStar Information Technology (Shanghai) Co., Ltd. All Rights Reserved.
// EasyAR is the registered trademark or trademark of VisionStar Information Technology (Shanghai) Co., Ltd in China
// and other countries for the augmented reality technology developed by VisionStar Information Technology (Shanghai) Co., Ltd.
//
//================================================================================================================================
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace easyar
{
public class ObjectTargetController : TargetController
{
///
/// EasyAR Sense API. Accessible after TargetAvailable event.
///
public ObjectTarget Target { get; private set; }
public DataSource SourceType = DataSource.ObjFile;
[HideInInspector, SerializeField]
public ObjFileSourceData ObjFileSource = new ObjFileSourceData();
public ObjectTarget TargetSource;
[HideInInspector, SerializeField]
private bool trackerHasSet;
[HideInInspector, SerializeField]
private ObjectTrackerFrameFilter tracker;
private ObjectTrackerFrameFilter loader;
private float scale = 1;
private float scaleX = 1;
private bool preHFlip;
public event Action TargetAvailable;
public event Action TargetLoad;
public event Action TargetUnload;
public enum DataSource
{
ObjFile,
Target,
}
public ObjectTrackerFrameFilter Tracker
{
get
{
return tracker;
}
set
{
tracker = value;
UpdateTargetInTracker();
}
}
public List BoundingBox
{
get
{
var boundingBox = new List();
if (Target == null)
{
return boundingBox;
}
var boundingBoxVec3F = Target.boundingBox();
foreach (var box in boundingBoxVec3F)
{
boundingBox.Add(box.ToUnityVector());
}
return boundingBox;
}
private set { }
}
protected override void Start()
{
base.Start();
if (!EasyARController.Initialized)
{
return;
}
switch (SourceType)
{
case DataSource.ObjFile:
LoadObjFile(new ObjFileSourceData()
{
PathType = ObjFileSource.PathType,
ObjPath = ObjFileSource.ObjPath,
ExtraFilePaths = ObjFileSource.ExtraFilePaths,
Name = ObjFileSource.Name,
Scale = ObjFileSource.Scale
});
break;
case DataSource.Target:
LoadTarget(TargetSource);
break;
default:
break;
}
}
protected virtual void Update()
{
CheckScale();
}
protected virtual void OnDestroy()
{
if (tracker)
{
tracker = null;
UpdateTargetInTracker();
}
if (Target != null)
{
Target.Dispose();
Target = null;
}
}
protected override void OnTracking()
{
CheckScale();
}
private void LoadObjFile(ObjFileSourceData source)
{
EasyARController.Instance.StartCoroutine(LoadObjFileFromSource(source));
}
private void LoadTarget(ObjectTarget source)
{
Target = source;
if (Target != null && TargetAvailable != null)
{
TargetAvailable();
}
UpdateScale();
UpdateTargetInTracker();
}
private IEnumerator LoadObjFileFromSource(ObjFileSourceData source)
{
using (var objBufferDic = new BufferDictionary())
{
yield return EasyARController.Instance.StartCoroutine(FileUtil.LoadFile(source.ObjPath, source.PathType, (Buffer buffer) =>
{
objBufferDic.set(FileUtil.PathToUrl(source.ObjPath), buffer.Clone());
}));
foreach (var filePath in source.ExtraFilePaths)
{
yield return EasyARController.Instance.StartCoroutine(FileUtil.LoadFile(filePath, source.PathType, (Buffer buffer) =>
{
objBufferDic.set(FileUtil.PathToUrl(filePath), buffer.Clone());
}));
}
using (var param = new ObjectTargetParameters())
{
param.setBufferDictionary(objBufferDic);
param.setObjPath(FileUtil.PathToUrl(source.ObjPath));
param.setName(source.Name);
param.setScale(source.Scale);
param.setUid(Guid.NewGuid().ToString());
param.setMeta(string.Empty);
var targetOptional = ObjectTarget.createFromParameters(param);
if (targetOptional.OnSome)
{
Target = targetOptional.Value;
if (Target != null && TargetAvailable != null)
{
TargetAvailable();
}
}
else
{
throw new Exception("invalid parameter");
}
}
}
UpdateTargetInTracker();
}
private void UpdateTargetInTracker()
{
if (Target == null)
{
return;
}
if (loader && loader != tracker)
{
loader.UnloadObjectTarget(this, (target, status) =>
{
if (TargetUnload != null)
{
TargetUnload(target, status);
}
});
loader = null;
}
if (tracker && tracker != loader)
{
var trackerLoad = tracker;
tracker.LoadObjectTarget(this, (target, status) =>
{
if (trackerLoad == tracker && !status)
{
loader = null;
}
UpdateScale();
if (TargetLoad != null)
{
TargetLoad(target, status);
}
});
loader = tracker;
}
}
private void UpdateScale()
{
if (Target == null)
return;
scale = Target.scale();
var vec3Unit = Vector3.one;
if (HorizontalFlip)
{
vec3Unit.x = -vec3Unit.x;
}
transform.localScale = vec3Unit * scale;
scaleX = transform.localScale.x;
preHFlip = HorizontalFlip;
}
private void CheckScale()
{
if (Target == null)
return;
if (scaleX != transform.localScale.x)
{
Target.setScale(Math.Abs(transform.localScale.x));
UpdateScale();
}
else if (scale != transform.localScale.y)
{
Target.setScale(Math.Abs(transform.localScale.y));
UpdateScale();
}
else if (scale != transform.localScale.z)
{
Target.setScale(Math.Abs(transform.localScale.z));
UpdateScale();
}
else if (scale != Target.scale())
{
UpdateScale();
}
else if (preHFlip != HorizontalFlip)
{
UpdateScale();
}
}
[Serializable]
public class ObjFileSourceData
{
public PathType PathType = PathType.StreamingAssets;
public string ObjPath = string.Empty;
public List ExtraFilePaths = new List();
public string Name = string.Empty;
public float Scale = 1;
}
}
}