using System.Collections.Generic; using UnityEngine; using UnityEngine.Rendering; namespace Assets.AR { public abstract class ARGameObjectsController : 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 arObjects = new List(); 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 trajectorySegments = new Dictionary(); 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("UI/Material/TransparentPlane"); //this.matModelMask = Resources.Load("Materials/ModelDepth"); this.arObjects.Clear(); this.arObjects.AddRange(FindObjectsOfType()); 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; ARGameObject.MaxDistanceVisibilityModels = 200f; this.MaximumVisibilityDistance = 500f; } else { this.AR360Version = false; ARGameObject.MaxDistanceVisibilityModels = 80f; this.MaximumVisibilityDistance = 200f; } if (route == null) return; foreach (ARGameObject 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 UpdateGameObjects( float videoFrame, float visibilityRear, float visibilityFront) { foreach (ARGameObject arObject in this.arObjects) { arObject.CameraPositionOffset = this.cameraPositionOffset; if (arObject is ARLaneGameObject arLaneObject) arLaneObject.FrameIndexDistanceCorrection = this.FrameIndexDistanceCorrection; if (arObject.TimeTransforms != null && arObject.TimeTransforms.Length > 1) arObject.UpdateByTimeDefinitions(videoFrame); arObject.UpdateVisibility(videoFrame, visibilityRear, visibilityFront, this.IsMultilap); bool flag = this.IsObjectActive(arObject); } } protected virtual bool IsObjectActive(ARGameObject arObject) => (double)arObject.VisibilityLevel > 0.0 ; protected virtual Material GetTrajectoryMaterial() => this.matShadow; protected virtual void Update() { if (this.Route == null) return; var num1 = this.videoPlayer.CurrentFrame - (float)this.Route.VideoFrameOffset; { this.cameraPositionOffset = this.Route.GetCameraPosition(num1) - this.CameraOriginOffset; UnityCamera.transform.position = this.CameraOriginOffset; UnityCamera.transform.rotation = this.Route.GetCameraRotation(num1); //this.Route.SetCameraProjection(num1, Camera.main); //TODO:暂时注释掉 } this.CameraDistance = this.videoSync.GetDistanceForVideoFrame(num1 + this.FrameIndexDistanceCorrection); var num2 = Mathf.Min(float.MaxValue, this.Route.GetVisibility(num1)); var num3 = num2; var visibilityRear = 200f; if ((double)num3 == 0.0) num3 = 600f; if ((double)visibilityRear == 0.0) visibilityRear = 600f; this.UpdateTrajectory(num1, num3);//更新轨迹 this.UpdateGameObjects(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 intList = new List(); 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); ARGameObjectsController.Segment segment = new ARGameObjectsController.Segment(trajectory, trajectory.transform.position); this.trajectorySegments.Add(index, segment); } } foreach (int key in this.trajectorySegments.Keys) { ARGameObjectsController.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 = ARGameObjectFactory.CreateTrajectory(this.Route, segment, lOffset, rOffset, margin); trajectory.transform.parent = this.trajectoryObject.transform; //trajectory.layer = 9; trajectory.GetComponent().shadowCastingMode = ShadowCastingMode.Off; trajectory.GetComponent().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; } } } }