powerfun-unity/Assets/AR/ARGameObject.cs

215 lines
8.5 KiB
C#
Raw Permalink Normal View History

2022-12-05 18:29:49 +08:00
using UnityEngine;
2022-11-25 19:18:21 +08:00
namespace Assets.AR
{
2023-01-31 18:22:15 +08:00
public class ARGameObject : MonoBehaviour
2022-11-25 19:18:21 +08:00
{
public string Hash;
2022-12-05 18:29:49 +08:00
public const int Layer = 1;
2022-11-25 19:18:21 +08:00
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;
2023-01-31 18:22:15 +08:00
public ARVideoTransform[] TimeTransforms { get; set; }
2022-11-29 16:29:59 +08:00
2022-11-25 19:18:21 +08:00
public string CustomUrl { get; set; }
public string ArName { get; set; }
2023-01-31 18:22:15 +08:00
public int UserId { get; set; }
2022-11-25 19:18:21 +08:00
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; }
2023-01-13 10:45:42 +08:00
public bool IsMain { get; set; }
2022-11-25 19:18:21 +08:00
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();
}
}
2022-11-29 16:29:59 +08:00
public float DeltaDistance { get; set; }
2022-12-08 19:17:34 +08:00
public float NextDistance { get; set; }
2022-11-29 16:29:59 +08:00
2022-11-25 19:18:21 +08:00
public float Distance
{
get => this.distance;
set
{
2023-04-18 17:10:48 +08:00
if (this.distance == value)
2022-11-25 19:18:21 +08:00
return;
this.distance = value;
this.SetFrame();
}
}
public virtual void UpdateTransform()
{
if (this.Route == null)
return;
2023-04-18 17:10:48 +08:00
var cameraRotation = this.GetCameraRotation(this.frame);
var filteredCameraPosition = this.GetFilteredCameraPosition(this.frame);
2022-11-25 19:18:21 +08:00
this.transform.rotation = cameraRotation * Quaternion.Euler(this.RotationOffset);
this.transform.position = filteredCameraPosition + cameraRotation * this.PositionOffset;
this.transform.localScale = this.Scale;
}
2022-11-29 16:29:59 +08:00
public void UpdateByTimeDefinitions(float currentFrame)
{
if (this.TimeTransforms == null || this.TimeTransforms.Length == 0)
return;
2023-04-18 17:10:48 +08:00
2022-11-29 16:29:59 +08:00
if (this.nextTimeDefIndex > this.TimeTransforms.Length - 1)
this.nextTimeDefIndex = 0;
2023-04-18 17:10:48 +08:00
2022-11-29 16:29:59 +08:00
if (this.nextTimeDefIndex > 0 && (double)this.TimeTransforms[this.nextTimeDefIndex - 1].Frame > (double)currentFrame)
this.nextTimeDefIndex = 0;
2023-04-18 17:10:48 +08:00
2022-11-29 16:29:59 +08:00
while (this.nextTimeDefIndex < this.TimeTransforms.Length - 1 && (double)this.TimeTransforms[this.nextTimeDefIndex].Frame <= (double)currentFrame)
++this.nextTimeDefIndex;
2023-04-18 17:10:48 +08:00
2022-11-29 16:29:59 +08:00
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
{
2023-04-18 17:10:48 +08:00
var t = Mathf.Clamp01((currentFrame - (float)this.TimeTransforms[this.nextTimeDefIndex - 1].Frame) / (float)(this.TimeTransforms[this.nextTimeDefIndex].Frame - this.TimeTransforms[this.nextTimeDefIndex - 1].Frame));
2022-11-29 16:29:59 +08:00
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);
}
}
2022-11-25 19:18:21 +08:00
public void UpdateOffsets()
{
if (this.Route == null || this.VideoSync == null)
return;
2023-04-18 17:10:48 +08:00
var quaternion = Quaternion.Inverse(this.GetCameraRotation(this.frame));
var filteredCameraPosition = this.GetFilteredCameraPosition(this.frame);
2022-11-25 19:18:21 +08:00
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)
{
2023-04-18 17:10:48 +08:00
if (this.ManualVisibility > 0.0)
2022-11-25 19:18:21 +08:00
{
visibilityFront = this.ManualVisibility;
visibilityRear = this.ManualVisibility;
}
2023-04-18 17:10:48 +08:00
var deltaVisibility = Time.deltaTime * 5f;
var a = this.GetVisibilityParameter(this.frame, videoFrame, visibilityRear, visibilityFront, deltaVisibility);
2022-11-25 19:18:21 +08:00
if (multiLap && (double)a <= 0.0)
{
2023-04-18 17:10:48 +08:00
var visibilityParameter = this.GetVisibilityParameter(this.frame + this.videoSync.LastVideoFrame, videoFrame, visibilityRear, visibilityFront, deltaVisibility);
2022-11-25 19:18:21 +08:00
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)
{
2023-04-18 17:10:48 +08:00
if (objectFrame < videoFrame - visibilityRear)
2022-11-25 19:18:21 +08:00
return 0.0f;
2023-04-18 17:10:48 +08:00
if (visibilityFront <= 0.0)
2022-11-25 19:18:21 +08:00
return 1f;
2023-04-18 17:10:48 +08:00
if (this.ManualVisibility == -1.0)
2022-11-25 19:18:21 +08:00
return Mathf.Clamp(0.0f, this.lastVisibilityLevel - deltaVisibility, this.lastVisibilityLevel + deltaVisibility);
float num1;
2023-04-18 17:10:48 +08:00
if (objectFrame > videoFrame)
2022-11-25 19:18:21 +08:00
{
2023-04-18 17:10:48 +08:00
var num2 = (float)(videoFrame + visibilityFront - 0.5 * this.FrameRate);
var num3 = videoFrame + visibilityFront;
num1 = 1f - Mathf.Clamp01((float)((objectFrame - num2) / (num3 - num2)));
2022-11-25 19:18:21 +08:00
}
else
{
2023-04-18 17:10:48 +08:00
var num4 = videoFrame - visibilityRear;
var num5 = (float)(videoFrame - visibilityRear + 0.5 *this.FrameRate);
num1 = Mathf.Clamp01((float)((objectFrame - num4) / (num5 - num4)));
2022-11-25 19:18:21 +08:00
}
return Mathf.Clamp(num1, this.lastVisibilityLevel - deltaVisibility, this.lastVisibilityLevel + deltaVisibility);
}
}
}