215 lines
8.5 KiB
C#
215 lines
8.5 KiB
C#
using UnityEngine;
|
|
|
|
namespace Assets.AR
|
|
{
|
|
public class ARGameObject : MonoBehaviour
|
|
{
|
|
public string Hash;
|
|
public const int Layer = 1;
|
|
public const int TestRidersLayer = 10;
|
|
public static float MaxDistanceVisibilityModels = 80f;
|
|
public const float VisibilityHidingTime = 0.2f;
|
|
public const float VisibilityHidingeRange = 0.5f;
|
|
protected VideoPointsSync videoSync { get; set; }
|
|
protected ARRoute route { get; set; }
|
|
public float frame;
|
|
private float lastVisibilityLevel;
|
|
public float distance;
|
|
private int nextTimeDefIndex;
|
|
protected bool useMultilapTransform;
|
|
public Vector3 PositionOffset = Vector3.zero;
|
|
public Vector3 RotationOffset = Vector3.zero;
|
|
public Vector3 Scale = Vector3.one;
|
|
|
|
private float FrameRate = 29.97f;
|
|
|
|
public ARVideoTransform[] TimeTransforms { get; set; }
|
|
|
|
public string CustomUrl { get; set; }
|
|
|
|
public string ArName { get; set; }
|
|
|
|
public int UserId { get; set; }
|
|
|
|
public Vector3 CameraPositionOffset { get; set; }
|
|
|
|
public float Frame => !this.useMultilapTransform ? this.frame : this.frame + this.videoSync.LastVideoFrame;
|
|
|
|
public float VisibilityLevel { get; protected set; }
|
|
|
|
public float ManualVisibility { get; set; }
|
|
|
|
public bool IsMain { get; set; }
|
|
|
|
public ARRoute Route
|
|
{
|
|
get => this.route;
|
|
set
|
|
{
|
|
if (this.route == value)
|
|
return;
|
|
this.route = value;
|
|
this.SetFrame();
|
|
}
|
|
}
|
|
|
|
public VideoPointsSync VideoSync
|
|
{
|
|
get => this.videoSync;
|
|
set
|
|
{
|
|
if (this.videoSync == value)
|
|
return;
|
|
this.videoSync = value;
|
|
this.SetFrame();
|
|
}
|
|
}
|
|
|
|
public float DeltaDistance { get; set; }
|
|
public float NextDistance { get; set; }
|
|
|
|
public float Distance
|
|
{
|
|
get => this.distance;
|
|
set
|
|
{
|
|
if (this.distance == value)
|
|
return;
|
|
this.distance = value;
|
|
this.SetFrame();
|
|
}
|
|
}
|
|
|
|
public virtual void UpdateTransform()
|
|
{
|
|
if (this.Route == null)
|
|
return;
|
|
var cameraRotation = this.GetCameraRotation(this.frame);
|
|
var filteredCameraPosition = this.GetFilteredCameraPosition(this.frame);
|
|
this.transform.rotation = cameraRotation * Quaternion.Euler(this.RotationOffset);
|
|
this.transform.position = filteredCameraPosition + cameraRotation * this.PositionOffset;
|
|
this.transform.localScale = this.Scale;
|
|
}
|
|
|
|
|
|
public void UpdateByTimeDefinitions(float currentFrame)
|
|
{
|
|
if (this.TimeTransforms == null || this.TimeTransforms.Length == 0)
|
|
return;
|
|
|
|
if (this.nextTimeDefIndex > this.TimeTransforms.Length - 1)
|
|
this.nextTimeDefIndex = 0;
|
|
|
|
if (this.nextTimeDefIndex > 0 && (double)this.TimeTransforms[this.nextTimeDefIndex - 1].Frame > (double)currentFrame)
|
|
this.nextTimeDefIndex = 0;
|
|
|
|
while (this.nextTimeDefIndex < this.TimeTransforms.Length - 1 && (double)this.TimeTransforms[this.nextTimeDefIndex].Frame <= (double)currentFrame)
|
|
++this.nextTimeDefIndex;
|
|
|
|
if (this.nextTimeDefIndex == 0)
|
|
{
|
|
this.Distance = this.TimeTransforms[0].Distance;
|
|
this.PositionOffset = this.TimeTransforms[0].PositionOffset;
|
|
this.Scale = this.TimeTransforms[0].Scale;
|
|
this.RotationOffset = this.TimeTransforms[0].RotationOffset;
|
|
}
|
|
else
|
|
{
|
|
var t = Mathf.Clamp01((currentFrame - (float)this.TimeTransforms[this.nextTimeDefIndex - 1].Frame) / (float)(this.TimeTransforms[this.nextTimeDefIndex].Frame - this.TimeTransforms[this.nextTimeDefIndex - 1].Frame));
|
|
this.Distance = Mathf.Lerp(this.TimeTransforms[this.nextTimeDefIndex - 1].Distance, this.TimeTransforms[this.nextTimeDefIndex].Distance, t);
|
|
this.PositionOffset = Vector3.Lerp(this.TimeTransforms[this.nextTimeDefIndex - 1].PositionOffset, this.TimeTransforms[this.nextTimeDefIndex].PositionOffset, t);
|
|
this.Scale = Vector3.Lerp(this.TimeTransforms[this.nextTimeDefIndex - 1].Scale, this.TimeTransforms[this.nextTimeDefIndex].Scale, t);
|
|
this.RotationOffset = Vector3.Lerp(this.TimeTransforms[this.nextTimeDefIndex - 1].RotationOffset, this.TimeTransforms[this.nextTimeDefIndex].RotationOffset, t);
|
|
}
|
|
}
|
|
|
|
|
|
public void UpdateOffsets()
|
|
{
|
|
if (this.Route == null || this.VideoSync == null)
|
|
return;
|
|
var quaternion = Quaternion.Inverse(this.GetCameraRotation(this.frame));
|
|
var filteredCameraPosition = this.GetFilteredCameraPosition(this.frame);
|
|
this.RotationOffset = (quaternion * this.transform.rotation).eulerAngles;
|
|
this.PositionOffset = quaternion * (this.transform.position - filteredCameraPosition);
|
|
this.Scale = this.transform.localScale;
|
|
}
|
|
|
|
public void UpdateVisibility(
|
|
float videoFrame,
|
|
float visibilityRear,
|
|
float visibilityFront,
|
|
bool multiLap)
|
|
{
|
|
if (this.ManualVisibility > 0.0)
|
|
{
|
|
visibilityFront = this.ManualVisibility;
|
|
visibilityRear = this.ManualVisibility;
|
|
}
|
|
var deltaVisibility = Time.deltaTime * 5f;
|
|
var a = this.GetVisibilityParameter(this.frame, videoFrame, visibilityRear, visibilityFront, deltaVisibility);
|
|
if (multiLap && (double)a <= 0.0)
|
|
{
|
|
var visibilityParameter = this.GetVisibilityParameter(this.frame + this.videoSync.LastVideoFrame, videoFrame, visibilityRear, visibilityFront, deltaVisibility);
|
|
a = Mathf.Max(a, visibilityParameter);
|
|
if ((double)a > 0.0)
|
|
this.useMultilapTransform = true;
|
|
}
|
|
else
|
|
this.useMultilapTransform = false;
|
|
this.VisibilityLevel = a;
|
|
this.lastVisibilityLevel = this.VisibilityLevel;
|
|
}
|
|
protected virtual void Update()
|
|
{
|
|
if (this.Route == null || this.VideoSync == null)
|
|
return;
|
|
|
|
this.UpdateTransform();
|
|
}
|
|
protected virtual void Awake()
|
|
{
|
|
|
|
}
|
|
protected Quaternion GetCameraRotation(float frame) => this.Route.GetTrajectoryOrientation(this.useMultilapTransform ? frame + this.videoSync.LastVideoFrame : frame);
|
|
|
|
protected Vector3 GetFilteredCameraPosition(float frame) => this.Route.GetFilteredCameraPosition(this.useMultilapTransform ? frame + this.videoSync.LastVideoFrame : frame) - this.CameraPositionOffset;
|
|
|
|
private void SetFrame()
|
|
{
|
|
if (this.Route == null || this.VideoSync == null)
|
|
return;
|
|
this.frame = this.VideoSync.GetVideoFrameAtDistance(this.Distance);
|
|
}
|
|
|
|
private float GetVisibilityParameter(
|
|
float objectFrame,
|
|
float videoFrame,
|
|
float visibilityRear,
|
|
float visibilityFront,
|
|
float deltaVisibility)
|
|
{
|
|
if (objectFrame < videoFrame - visibilityRear)
|
|
return 0.0f;
|
|
if (visibilityFront <= 0.0)
|
|
return 1f;
|
|
if (this.ManualVisibility == -1.0)
|
|
return Mathf.Clamp(0.0f, this.lastVisibilityLevel - deltaVisibility, this.lastVisibilityLevel + deltaVisibility);
|
|
float num1;
|
|
if (objectFrame > videoFrame)
|
|
{
|
|
var num2 = (float)(videoFrame + visibilityFront - 0.5 * this.FrameRate);
|
|
var num3 = videoFrame + visibilityFront;
|
|
num1 = 1f - Mathf.Clamp01((float)((objectFrame - num2) / (num3 - num2)));
|
|
}
|
|
else
|
|
{
|
|
var num4 = videoFrame - visibilityRear;
|
|
var num5 = (float)(videoFrame - visibilityRear + 0.5 *this.FrameRate);
|
|
num1 = Mathf.Clamp01((float)((objectFrame - num4) / (num5 - num4)));
|
|
}
|
|
return Mathf.Clamp(num1, this.lastVisibilityLevel - deltaVisibility, this.lastVisibilityLevel + deltaVisibility);
|
|
}
|
|
}
|
|
}
|