using UnityEngine; public class CameraContainer: ObjectContainer { protected override System.Type _serializeType => typeof(CameraContainerSerializable); protected override System.Type _keyframeType => typeof(KeyframeDataCamera); public CameraOrbit Camera; public KeyframeDataCamera LastPosition; public LineRenderer LineRenderer; public CameraSettings Settings; private void Update() { if (!LineRenderer.enabled) return; float fov = Settings.Fov; float aspect = Camera.Cam.aspect; float nearPlane = Camera.Cam.nearClipPlane; float farPlane = Camera.Cam.farClipPlane; Vector3[] far = CalculateCameraFrustRect(fov, aspect, farPlane, transform); Vector3[] near = CalculateCameraFrustRect(fov, aspect, nearPlane, transform); var edges = new Vector3[] { far[0], far[1], far[2], far[3], far[0], near[0], near[1], near[2], near[3], near[0], near[1], far[1], far[2], near[2], near[3], far[3] }; LineRenderer.positionCount = edges.Length; LineRenderer.SetPositions(edges); } private static Vector3[] CalculateCameraFrustRect(float fieldOfView, float aspect, float dist, Transform transform) { dist = Mathf.Clamp(dist, 0.1f, 20f); Vector3[] rect = new Vector3[4]; float frustumHeight = 2.0F * dist * Mathf.Tan(fieldOfView * 0.5F * Mathf.Deg2Rad); rect[0] = transform.TransformPoint(new Vector3(-frustumHeight * aspect / 2, frustumHeight / 2, dist)); rect[1] = transform.TransformPoint(new Vector3(frustumHeight * aspect / 2, frustumHeight / 2, dist)); rect[2] = transform.TransformPoint(new Vector3(frustumHeight * aspect / 2, -frustumHeight / 2, dist)); rect[3] = transform.TransformPoint(new Vector3(-frustumHeight * aspect / 2, -frustumHeight / 2, dist)); return (rect); } Vector3 TransformPoint(Vector3 transforPos, Quaternion transformRotation, Vector3 transformScale, Vector3 pos) { Matrix4x4 matrix = Matrix4x4.TRS(transforPos, transformRotation, transformScale); return matrix.MultiplyPoint3x4(pos); } Vector3 InverseTransformPoint(Vector3 transforPos, Quaternion transformRotation, Vector3 transformScale, Vector3 pos) { Matrix4x4 matrix = Matrix4x4.TRS(transforPos, transformRotation, transformScale); Matrix4x4 inverse = matrix.inverse; return inverse.MultiplyPoint3x4(pos); } public override void Lerp(KeyframeData frame1, KeyframeData frame2, float amount) { var tsf = frame1 as KeyframeDataCamera; if (frame1 != frame2) { tsf = tsf.Lerp(frame2, amount) as KeyframeDataCamera; } var orbitLocator = ModelViewerMain.GetInstance().MainCameraOrbit; if (ModelViewerMain.GetInstance().GetCameraHandler() == ModelViewerMain.GetInstance().WorkCameraOrbit) { //if in work camera mode, move the camera locator only orbitLocator.transform.position = tsf.Root.Position; orbitLocator.transform.eulerAngles = tsf.Root.Rotation; orbitLocator.LastPosition = tsf; } else { orbitLocator.PastePose(tsf, new PoseLoadOptions(true)); } } public override void PastePose(KeyframeData frame, PoseLoadOptions pasteParams = null) { var keyframe = frame as KeyframeDataCamera; Camera.transform.localPosition = keyframe.Root.Position; Camera.transform.localEulerAngles = keyframe.Root.Rotation; Camera.lookRotation = keyframe.Root.Rotation; //if (Camera.lookRotation.x > 90) Camera.lookRotation.x -= 360; //if (Camera.lookRotation.x < -90) Camera.lookRotation.x += 360; //lookRotation.x = lookRotation.x - 360; Debug.Log(keyframe.CameraLock); using (new KeyframeToggleContext(this)) { Settings.DropdownCameraMode.value = keyframe.CameraMode; Settings.ToggleCameraLock.isOn = keyframe.CameraLock; Settings.SliderFov.value = keyframe.Fov; Settings.SliderCamDist.value = keyframe.CamDist; Settings.SliderCamHeight.value = keyframe.CamHeight; Settings.SliderTargetHeight.value = keyframe.TargetHeigh; Settings.SliderCamAngle.value = keyframe.CamAngle; } Camera.UpdateImmediate(true); } public override void Destroy() { //Do not destroy cameras Debug.Log("Clearing camera"); Frames.Clear(); SetDefaultFrame(); } }