209 lines
8.4 KiB
C#
209 lines
8.4 KiB
C#
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.Rendering;
|
|
|
|
namespace Assets.AR
|
|
{
|
|
public abstract class ARObjectsController : MonoBehaviour
|
|
{
|
|
public float MaximumVisibilityDistance = 200f;
|
|
private readonly Vector3 CameraOriginOffset = Vector3.up * -100f;
|
|
protected static readonly Vector3 DefaultObjectPosition = new Vector3(0.0f, 1000f, 0.0f);
|
|
protected List<ARObject> arObjects = new List<ARObject>();
|
|
protected Material matShadow { get; set; }
|
|
protected Material matModelMask;
|
|
protected AVProVideoPlayer videoPlayer { get; set; }
|
|
protected VideoPointsSync videoSync{ get; set; }
|
|
protected Vector3 cameraPositionOffset { get; set; }
|
|
private GameObject panoramaObject;
|
|
private Material panoramaMaterial;
|
|
private Material skyboxMaterialBackup;
|
|
protected GameObject trajectoryObject;
|
|
private float ambientIntensity;
|
|
private GameObject camGo;
|
|
protected Dictionary<int, ARObjectsController.Segment> trajectorySegments = new Dictionary<int, ARObjectsController.Segment>();
|
|
protected int lapCount = 1;
|
|
protected double lapLength;
|
|
|
|
public bool AR360Version { get; private set; }
|
|
|
|
public Camera UnityCamera { get; protected set; }
|
|
|
|
public float FrameIndexDistanceCorrection { get; set; }
|
|
|
|
public ARRoute Route { get; private set; }
|
|
|
|
protected float CameraDistance { get; private set; }
|
|
|
|
public float TargetCameraDistance { get; private set; }
|
|
|
|
public Camera PanoramaCamera { get; private set; }
|
|
|
|
public bool PassedPanorama { get; set; }
|
|
|
|
public bool IsMultilap => this.lapCount > 1;
|
|
|
|
protected virtual void Awake()
|
|
{
|
|
this.ambientIntensity = RenderSettings.ambientIntensity;
|
|
this.matShadow = Resources.Load<Material>("UI/Material/TransparentPlane");
|
|
//this.matModelMask = Resources.Load<Material>("Materials/ModelDepth");
|
|
this.arObjects.Clear();
|
|
this.arObjects.AddRange(FindObjectsOfType<ARObject>());
|
|
SetupCamera();
|
|
}
|
|
|
|
protected virtual void SetupCamera()
|
|
{
|
|
this.UnityCamera = Camera.main;
|
|
}
|
|
|
|
public virtual void SetArRoute(ARRoute route, VideoPointsSync videoSync,AVProVideoPlayer mediaPlayer)
|
|
{
|
|
videoPlayer = mediaPlayer;
|
|
this.Route = route;
|
|
this.videoSync = videoSync;
|
|
if (this.Route.CameraRotationsRear != null && this.Route.CameraRotationsRear.Length == this.Route.CameraRotations.Length)
|
|
{
|
|
this.AR360Version = true;
|
|
ARObject.MaxDistanceVisibilityModels = 200f;
|
|
this.MaximumVisibilityDistance = 500f;
|
|
}
|
|
else
|
|
{
|
|
this.AR360Version = false;
|
|
ARObject.MaxDistanceVisibilityModels = 80f;
|
|
this.MaximumVisibilityDistance = 200f;
|
|
}
|
|
if (route == null)
|
|
return;
|
|
foreach (ARObject arObject in this.arObjects)
|
|
{
|
|
arObject.VideoSync = videoSync;
|
|
arObject.Route = route;
|
|
}
|
|
this.trajectoryObject = new GameObject("TrajectoryMesh");
|
|
this.trajectoryObject.transform.parent = this.transform;
|
|
//this.trajectoryObject.layer = 9;
|
|
}
|
|
|
|
protected virtual void UpdateObjects(
|
|
float videoFrame,
|
|
float visibilityRear,
|
|
float visibilityFront)
|
|
{
|
|
foreach (ARObject arObject in this.arObjects)
|
|
{
|
|
arObject.CameraPositionOffset = this.cameraPositionOffset;
|
|
if (arObject is ARLaneObject arLaneObject)
|
|
arLaneObject.FrameIndexDistanceCorrection = this.FrameIndexDistanceCorrection;
|
|
//if (this.SelectedPanorama != null && (arObject.ObjectType == ARObjectType.Box || arObject.ObjectType == ARObjectType.Sphere))
|
|
//{
|
|
// arObject.gameObject.SetActive(false);
|
|
//}
|
|
//else
|
|
{
|
|
if (arObject.TimeTransforms != null && arObject.TimeTransforms.Length > 1)
|
|
arObject.UpdateByTimeDefinitions(videoFrame);
|
|
arObject.UpdateVisibility(videoFrame, visibilityRear, visibilityFront, this.IsMultilap);
|
|
bool flag = this.IsArObjectActive(arObject);
|
|
arObject.gameObject.SetActive(flag);
|
|
}
|
|
}
|
|
}
|
|
|
|
protected virtual bool IsArObjectActive(ARObject arObject) => (double)arObject.VisibilityLevel > 0.0 ;
|
|
|
|
|
|
protected virtual Material GetTrajectoryMaterial() => this.matShadow;
|
|
|
|
|
|
protected virtual void Update()
|
|
{
|
|
if (this.Route == null)
|
|
return;
|
|
|
|
float num1 = this.videoPlayer.CurrentFrame - (float)this.Route.VideoFrameOffset;
|
|
{
|
|
this.cameraPositionOffset = this.Route.GetCameraPosition(num1) - this.CameraOriginOffset;
|
|
Camera.main.transform.position = this.CameraOriginOffset;
|
|
Camera.main.transform.rotation = this.Route.GetCameraRotation(num1);
|
|
//this.Route.SetCameraProjection(num1, Camera.main); //TODO:暂时注释掉
|
|
}
|
|
this.CameraDistance = this.videoSync.GetDistanceForVideoFrame(num1 + this.FrameIndexDistanceCorrection);
|
|
float num2 = Mathf.Min(float.MaxValue, this.Route.GetVisibility(num1));
|
|
float num3 = num2;
|
|
float visibilityRear = 200f;
|
|
if ((double)num3 == 0.0)
|
|
num3 = 600f;
|
|
if ((double)visibilityRear == 0.0)
|
|
visibilityRear = 600f;
|
|
this.UpdateTrajectory(num1, num3);//更新轨迹
|
|
this.UpdateObjects(num1, visibilityRear, num3);//更新骑手等位置
|
|
}
|
|
|
|
|
|
//更新当前可见轨迹
|
|
private void UpdateTrajectory(float frame, float defaultVisibility)
|
|
{
|
|
int start;
|
|
int end;
|
|
this.Route.GetVisibleSlamSegments((int)frame, out start, out end, defaultVisibility);
|
|
List<int> intList = new List<int>();
|
|
foreach (int key in this.trajectorySegments.Keys)
|
|
{
|
|
if (key < start || key > end)
|
|
intList.Add(key);
|
|
}
|
|
foreach (int key in intList)
|
|
{
|
|
UnityEngine.Object.Destroy((UnityEngine.Object)this.trajectorySegments[key].GameObject);
|
|
this.trajectorySegments.Remove(key);
|
|
}
|
|
for (int index = start; index <= end; ++index)
|
|
{
|
|
if (!this.trajectorySegments.ContainsKey(index))
|
|
{
|
|
GameObject trajectory = this.CreateTrajectory(index, 0.0f, 0.0f);
|
|
ARObjectsController.Segment segment = new ARObjectsController.Segment(trajectory, trajectory.transform.position);
|
|
this.trajectorySegments.Add(index, segment);
|
|
}
|
|
}
|
|
foreach (int key in this.trajectorySegments.Keys)
|
|
{
|
|
ARObjectsController.Segment trajectorySegment = this.trajectorySegments[key];
|
|
trajectorySegment.GameObject.transform.position = trajectorySegment.Position - this.cameraPositionOffset;
|
|
}
|
|
}
|
|
|
|
//创建轨迹
|
|
protected virtual GameObject CreateTrajectory(
|
|
int segment,
|
|
float lOffset,
|
|
float rOffset,
|
|
float margin = float.NaN)
|
|
{
|
|
GameObject trajectory = ARMeshFactory.CreateTrajectory(this.Route, segment, lOffset, rOffset, margin);
|
|
trajectory.transform.parent = this.trajectoryObject.transform;
|
|
//trajectory.layer = 9;
|
|
trajectory.GetComponent<MeshRenderer>().shadowCastingMode = ShadowCastingMode.Off;
|
|
trajectory.GetComponent<MeshRenderer>().material = this.GetTrajectoryMaterial();
|
|
return trajectory;
|
|
}
|
|
|
|
protected Vector3 GetCameraPosition(float frame) => this.Route.GetCameraPosition(frame) - this.cameraPositionOffset;
|
|
|
|
public class Segment
|
|
{
|
|
public GameObject GameObject;
|
|
public Vector3 Position;
|
|
|
|
public Segment(GameObject gameObject, Vector3 position)
|
|
{
|
|
this.GameObject = gameObject;
|
|
this.Position = position;
|
|
}
|
|
}
|
|
}
|
|
}
|