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); } } }