From 7d7f52bcd847b40512dc8341bb3635cbed6a3f5a Mon Sep 17 00:00:00 2001 From: Martin Finkel <me@martinfinkel.com> Date: Wed, 26 Feb 2025 13:49:24 +0700 Subject: [PATCH] samples: update 360 sample use projection mode on sphere fix up/down navigation refactor code --- .../VLCUnity/Demos/Scenes/VLCThreeSixty.unity | 264 ++++++++++++++++-- .../VLCUnity/Demos/Scripts/VLCThreeSixty.cs | 165 +++++------ 2 files changed, 317 insertions(+), 112 deletions(-) diff --git a/Assets/VLCUnity/Demos/Scenes/VLCThreeSixty.unity b/Assets/VLCUnity/Demos/Scenes/VLCThreeSixty.unity index f5a8ce4..0a41c55 100644 --- a/Assets/VLCUnity/Demos/Scenes/VLCThreeSixty.unity +++ b/Assets/VLCUnity/Demos/Scenes/VLCThreeSixty.unity @@ -13,7 +13,7 @@ OcclusionCullingSettings: --- !u!104 &2 RenderSettings: m_ObjectHideFlags: 0 - serializedVersion: 9 + serializedVersion: 10 m_Fog: 0 m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} m_FogMode: 3 @@ -38,13 +38,12 @@ RenderSettings: m_ReflectionIntensity: 1 m_CustomReflection: {fileID: 0} m_Sun: {fileID: 0} - m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1} m_UseRadianceAmbientProbe: 0 --- !u!157 &3 LightmapSettings: m_ObjectHideFlags: 0 - serializedVersion: 11 - m_GIWorkflowMode: 1 + serializedVersion: 13 + m_BakeOnSceneLoad: 0 m_GISettings: serializedVersion: 2 m_BounceScale: 1 @@ -67,9 +66,6 @@ LightmapSettings: m_LightmapParameters: {fileID: 0} m_LightmapsBakeMode: 1 m_TextureCompression: 1 - m_FinalGather: 0 - m_FinalGatherFiltering: 1 - m_FinalGatherRayCount: 256 m_ReflectionCompression: 2 m_MixedBakeMode: 2 m_BakeBackend: 1 @@ -98,13 +94,13 @@ LightmapSettings: m_TrainingDataDestination: TrainingData m_LightProbeSampleCountMultiplier: 4 m_LightingDataAsset: {fileID: 0} - m_UseShadowmask: 1 + m_LightingSettings: {fileID: 757142518} --- !u!196 &4 NavMeshSettings: serializedVersion: 2 m_ObjectHideFlags: 0 m_BuildSettings: - serializedVersion: 2 + serializedVersion: 3 agentTypeID: 0 agentRadius: 0.5 agentHeight: 2 @@ -117,10 +113,133 @@ NavMeshSettings: cellSize: 0.16666667 manualTileSize: 0 tileSize: 256 - accuratePlacement: 0 + buildHeightMesh: 0 + maxJobWorkers: 0 + preserveTilesOutsideBounds: 0 debug: m_Flags: 0 m_NavMeshData: {fileID: 0} +--- !u!1 &246358331 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 246358335} + - component: {fileID: 246358334} + - component: {fileID: 246358333} + - component: {fileID: 246358332} + - component: {fileID: 246358336} + m_Layer: 0 + m_Name: Sphere + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!135 &246358332 +SphereCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 246358331} + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_IsTrigger: 0 + m_ProvidesContacts: 0 + m_Enabled: 1 + serializedVersion: 3 + m_Radius: 0.5 + m_Center: {x: 0, y: 0, z: 0} +--- !u!23 &246358333 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 246358331} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 0 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 0 + m_ReflectionProbeUsage: 0 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RayTracingAccelStructBuildFlagsOverride: 0 + m_RayTracingAccelStructBuildFlags: 1 + m_SmallMeshCulling: 1 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: dda856af5216c6d45874c074cf358a10, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!33 &246358334 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 246358331} + m_Mesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0} +--- !u!4 &246358335 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 246358331} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 4, y: 0.48, z: 0} + m_LocalScale: {x: 5, y: 5, z: 5} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &246358336 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 246358331} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 699ff01a0b194194c91de64b70b01b1d, type: 3} + m_Name: + m_EditorClassIdentifier: --- !u!1 &363825485 GameObject: m_ObjectHideFlags: 0 @@ -146,9 +265,8 @@ Light: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 363825485} m_Enabled: 1 - serializedVersion: 10 + serializedVersion: 11 m_Type: 1 - m_Shape: 0 m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1} m_Intensity: 1 m_Range: 10 @@ -197,8 +315,13 @@ Light: m_UseColorTemperature: 0 m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0} m_UseBoundingSphereOverride: 0 + m_UseViewFrustumForShadowCasterCull: 1 + m_ForceVisible: 0 m_ShadowRadius: 0 m_ShadowAngle: 0 + m_LightUnit: 1 + m_LuxAtDistance: 1 + m_EnableSpotReflector: 1 --- !u!4 &363825487 Transform: m_ObjectHideFlags: 0 @@ -206,12 +329,13 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 363825485} + serializedVersion: 2 m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261} m_LocalPosition: {x: 0, y: 3, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 0} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0} --- !u!1 &603997761 GameObject: @@ -253,9 +377,17 @@ Camera: m_projectionMatrixMode: 1 m_GateFitMode: 2 m_FOVAxisMode: 0 + m_Iso: 200 + m_ShutterSpeed: 0.005 + m_Aperture: 16 + m_FocusDistance: 10 + m_FocalLength: 50 + m_BladeCount: 5 + m_Curvature: {x: 2, y: 11} + m_BarrelClipping: 0.25 + m_Anamorphism: 0 m_SensorSize: {x: 36, y: 24} m_LensShift: {x: 0, y: 0} - m_FocalLength: 50 m_NormalizedViewPortRect: serializedVersion: 2 x: 0 @@ -289,13 +421,75 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 603997761} + serializedVersion: 2 m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 1, z: -10} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 0} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!850595691 &757142518 +LightingSettings: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Settings.lighting + serializedVersion: 9 + m_EnableBakedLightmaps: 1 + m_EnableRealtimeLightmaps: 0 + m_RealtimeEnvironmentLighting: 1 + m_BounceScale: 1 + m_AlbedoBoost: 1 + m_IndirectOutputScale: 1 + m_UsingShadowmask: 1 + m_BakeBackend: 1 + m_LightmapMaxSize: 1024 + m_LightmapSizeFixed: 0 + m_UseMipmapLimits: 1 + m_BakeResolution: 40 + m_Padding: 2 + m_LightmapCompression: 3 + m_AO: 0 + m_AOMaxDistance: 1 + m_CompAOExponent: 1 + m_CompAOExponentDirect: 0 + m_ExtractAO: 0 + m_MixedBakeMode: 2 + m_LightmapsBakeMode: 1 + m_FilterMode: 1 + m_LightmapParameters: {fileID: 15204, guid: 0000000000000000f000000000000000, type: 0} + m_ExportTrainingData: 0 + m_EnableWorkerProcessBaking: 1 + m_TrainingDataDestination: TrainingData + m_RealtimeResolution: 2 + m_ForceWhiteAlbedo: 0 + m_ForceUpdates: 0 + m_PVRCulling: 1 + m_PVRSampling: 1 + m_PVRDirectSampleCount: 32 + m_PVRSampleCount: 512 + m_PVREnvironmentSampleCount: 256 + m_PVREnvironmentReferencePointCount: 2048 + m_LightProbeSampleCountMultiplier: 4 + m_PVRBounces: 2 + m_PVRMinBounces: 2 + m_PVREnvironmentImportanceSampling: 1 + m_PVRFilteringMode: 1 + m_PVRDenoiserTypeDirect: 1 + m_PVRDenoiserTypeIndirect: 1 + m_PVRDenoiserTypeAO: 1 + m_PVRFilterTypeDirect: 0 + m_PVRFilterTypeIndirect: 0 + m_PVRFilterTypeAO: 0 + m_PVRFilteringGaussRadiusDirect: 1 + m_PVRFilteringGaussRadiusIndirect: 5 + m_PVRFilteringGaussRadiusAO: 2 + m_PVRFilteringAtrousPositionSigmaDirect: 0.5 + m_PVRFilteringAtrousPositionSigmaIndirect: 2 + m_PVRFilteringAtrousPositionSigmaAO: 1 + m_RespectSceneVisibilityWhenBakingGI: 0 --- !u!1 &798205350 GameObject: m_ObjectHideFlags: 0 @@ -309,7 +503,7 @@ GameObject: - component: {fileID: 798205353} - component: {fileID: 798205354} m_Layer: 0 - m_Name: VLC 360 + m_Name: Screen m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 @@ -322,12 +516,13 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 798205350} + serializedVersion: 2 m_LocalRotation: {x: -0.6598657, y: 0, z: 0, w: 0.7513836} - m_LocalPosition: {x: 0, y: 1.39, z: 0} - m_LocalScale: {x: -1, y: 1, z: 1} + m_LocalPosition: {x: -2, y: 1.39, z: 0} + m_LocalScale: {x: -0.5, y: 0.5, z: 0.5} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 0} - m_RootOrder: 3 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!33 &798205352 MeshFilter: @@ -348,10 +543,15 @@ MeshRenderer: m_CastShadows: 1 m_ReceiveShadows: 0 m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 m_MotionVectors: 1 m_LightProbeUsage: 1 m_ReflectionProbeUsage: 1 m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RayTracingAccelStructBuildFlagsOverride: 0 + m_RayTracingAccelStructBuildFlags: 1 + m_SmallMeshCulling: 1 m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: @@ -376,6 +576,7 @@ MeshRenderer: m_SortingLayerID: 0 m_SortingLayer: 0 m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} --- !u!114 &798205354 MonoBehaviour: m_ObjectHideFlags: 0 @@ -439,10 +640,15 @@ MeshRenderer: m_CastShadows: 1 m_ReceiveShadows: 1 m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 m_MotionVectors: 1 m_LightProbeUsage: 1 m_ReflectionProbeUsage: 1 m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RayTracingAccelStructBuildFlagsOverride: 0 + m_RayTracingAccelStructBuildFlags: 1 + m_SmallMeshCulling: 1 m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: @@ -467,6 +673,7 @@ MeshRenderer: m_SortingLayerID: 0 m_SortingLayer: 0 m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} --- !u!4 &1092884458 Transform: m_ObjectHideFlags: 0 @@ -474,12 +681,13 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1092884455} + serializedVersion: 2 m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: -23, y: -1, z: 1} + m_LocalPosition: {x: -10, y: -3, z: 1} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 0} - m_RootOrder: 4 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &1573063551 GameObject: @@ -511,6 +719,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 4f231c4fb786f3946a6b90b886c48677, type: 3} m_Name: m_EditorClassIdentifier: + m_SendPointerHoverToParent: 1 m_HorizontalAxis: Horizontal m_VerticalAxis: Vertical m_SubmitButton: Submit @@ -540,10 +749,21 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1573063551} + serializedVersion: 2 m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 0} - m_RootOrder: 2 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1660057539 &9223372036854775807 +SceneRoots: + m_ObjectHideFlags: 0 + m_Roots: + - {fileID: 603997764} + - {fileID: 363825487} + - {fileID: 1573063554} + - {fileID: 798205351} + - {fileID: 1092884458} + - {fileID: 246358335} diff --git a/Assets/VLCUnity/Demos/Scripts/VLCThreeSixty.cs b/Assets/VLCUnity/Demos/Scripts/VLCThreeSixty.cs index fa818cd..ea482d1 100644 --- a/Assets/VLCUnity/Demos/Scripts/VLCThreeSixty.cs +++ b/Assets/VLCUnity/Demos/Scripts/VLCThreeSixty.cs @@ -6,143 +6,128 @@ public class VLCThreeSixty : MonoBehaviour { LibVLC _libVLC; - MediaPlayer _mediaPlayer; + MediaPlayer _mediaPlayerScreen; + MediaPlayer _mediaPlayerSphere; const int seekTimeDelta = 5000; - Texture2D tex = null; + Texture2D texScreen, texSphere; + Renderer screen, sphere; bool playing; - - float Yaw; - float Pitch; - float Roll; + float Yaw, Pitch, Roll; void Awake() { Core.Initialize(Application.dataPath); - _libVLC = new LibVLC(enableDebugLogs: true); - Application.SetStackTraceLogType(LogType.Log, StackTraceLogType.None); - //_libVLC.Log += (s, e) => UnityEngine.Debug.Log(e.FormattedLog); // enable this for logs in the editor - - PlayPause(); + screen = GameObject.Find("Screen").GetComponent<Renderer>(); + sphere = GameObject.Find("Sphere").GetComponent<Renderer>(); } - void OnDisable() - { - _mediaPlayer?.Stop(); - _mediaPlayer?.Dispose(); - _mediaPlayer = null; + void Start() => PlayPause(); + void OnDisable() + { + _mediaPlayerScreen?.Stop(); + _mediaPlayerScreen?.Dispose(); + _mediaPlayerSphere?.Dispose(); _libVLC?.Dispose(); - _libVLC = null; } public void PlayPause() { - Debug.Log ("[VLC] Toggling Play Pause !"); - if (_mediaPlayer == null) + if (_mediaPlayerScreen == null) { - _mediaPlayer = new MediaPlayer(_libVLC); + // keep default projection for the screen, thus with viewpoint navigation enabled + _mediaPlayerScreen = new MediaPlayer(_libVLC); } - if (_mediaPlayer.IsPlaying) + if (_mediaPlayerSphere == null) + { + // disable default projection for the sphere, no libvlc viewpoint navigation + _mediaPlayerSphere = new MediaPlayer(_libVLC); + _mediaPlayerSphere.SetProjectionMode(VideoProjection.Rectangular); + } + + Debug.Log("[VLC] Toggling Play Pause!"); + + if (_mediaPlayerScreen.IsPlaying || _mediaPlayerSphere.IsPlaying) { - _mediaPlayer.Pause(); + _mediaPlayerScreen.Pause(); + _mediaPlayerSphere.Pause(); } else { playing = true; - - if(_mediaPlayer.Media == null) + if (_mediaPlayerScreen.Media == null) { - // download https://streams.videolan.org/streams/360/eagle_360.mp4 - // to your computer (to avoid network requests for smoother navigation) - // and adjust the Uri to the local path + // better save the media locally to avoid slow networks var media = new Media(new Uri("https://streams.videolan.org/streams/360/eagle_360.mp4")); - - Task.Run(async () => + Task.Run(async () => { var result = await media.ParseAsync(_libVLC, MediaParseOptions.ParseNetwork); - var trackList = media.TrackList(TrackType.Video); - var is360 = trackList[0].Data.Video.Projection == VideoProjection.Equirectangular; - - if(is360) - Debug.Log("The video is a 360 video"); - else - Debug.Log("The video was not identified as a 360 video by VLC, make sure it is properly tagged"); - - trackList.Dispose(); + Debug.Log(media.TrackList(TrackType.Video)[0].Data.Video.Projection == VideoProjection.Equirectangular + ? "The video is a 360 video" : "The video was not identified as a 360 video by VLC"); }); - - _mediaPlayer.Media = media; + _mediaPlayerScreen.Media = _mediaPlayerSphere.Media = media; } - - _mediaPlayer.Play(); + _mediaPlayerScreen.Play(); + _mediaPlayerSphere.Play(); } } void Update() { - if(!playing) return; + if (!playing) return; + UpdateTexture(ref texScreen, _mediaPlayerScreen, screen); + UpdateTexture(ref texSphere, _mediaPlayerSphere, sphere); + } - if (tex == null) + void UpdateTexture(ref Texture2D texture, MediaPlayer player, Renderer renderer) + { + if (texture == null) { - // If received size is not null, it and scale the texture - uint i_videoHeight = 0; - uint i_videoWidth = 0; + uint width = 0, height = 0; + player.Size(0, ref width, ref height); + var texPtr = player.GetTexture(width, height, out bool updated); - _mediaPlayer.Size(0, ref i_videoWidth, ref i_videoHeight); - var texptr = _mediaPlayer.GetTexture(i_videoWidth, i_videoHeight, out bool updated); - if (i_videoWidth != 0 && i_videoHeight != 0 && updated && texptr != IntPtr.Zero) + if (width != 0 && height != 0 && updated && texPtr != IntPtr.Zero) { - Debug.Log("Creating texture with height " + i_videoHeight + " and width " + i_videoWidth); - tex = Texture2D.CreateExternalTexture((int)i_videoWidth, - (int)i_videoHeight, - TextureFormat.RGBA32, - false, - true, - texptr); - GetComponent<Renderer>().material.mainTexture = tex; + Debug.Log($"Creating texture with height {height} and width {width}"); + texture = Texture2D.CreateExternalTexture((int)width, (int)height, TextureFormat.RGBA32, false, true, texPtr); + renderer.material.mainTexture = texture; } } - else if (tex != null) + else { - var texptr = _mediaPlayer.GetTexture((uint)tex.width, (uint)tex.height, out bool updated); - if (updated) - { - tex.UpdateExternalTexture(texptr); - } + var texPtr = player.GetTexture((uint)texture.width, (uint)texture.height, out bool updated); + if (updated) texture.UpdateExternalTexture(texPtr); } } - void OnGUI() - { - Do360Navigation(); - } - + void OnGUI() => Do360Navigation(); + void Do360Navigation() { var range = Math.Max(UnityEngine.Screen.width, UnityEngine.Screen.height); - - Yaw = _mediaPlayer.Viewpoint.Yaw; - Pitch = _mediaPlayer.Viewpoint.Pitch; - Roll = _mediaPlayer.Viewpoint.Roll; + Yaw = _mediaPlayerScreen.Viewpoint.Yaw; + Pitch = _mediaPlayerScreen.Viewpoint.Pitch; + Roll = _mediaPlayerScreen.Viewpoint.Roll; var fov = 80; - if (Input.GetKey(KeyCode.RightArrow)) - { - _mediaPlayer.UpdateViewpoint(Yaw + (float)( 80 * + 40 / range), Pitch, Roll, fov); - } - else if(Input.GetKey(KeyCode.LeftArrow)) - { - _mediaPlayer.UpdateViewpoint(Yaw - (float)( 80 * + 40 / range), Pitch, Roll, fov); - } - else if(Input.GetKey(KeyCode.DownArrow)) - { - _mediaPlayer.UpdateViewpoint(Yaw, Pitch + (float)( 80 * + 20 / range), Roll, fov); - } - else if(Input.GetKey(KeyCode.UpArrow)) - { - _mediaPlayer.UpdateViewpoint(Yaw, Pitch - (float)( 80 * + 20 / range), Roll, fov); - } + if (Input.GetKey(KeyCode.RightArrow)) RotateView(20f, 80 * 40 / range, 0); + else if (Input.GetKey(KeyCode.LeftArrow)) RotateView(-20f, -80 * 40 / range, 0); + else if (Input.GetKey(KeyCode.DownArrow)) RotateView(0, 0, 1); + else if (Input.GetKey(KeyCode.UpArrow)) RotateView(0, 0, -1); + } + + void RotateView(float sphereRotation, float yawDelta, float pitchDelta) + { + // no viewpoint changes for the sphere as the whole video is shown on the texture + // we can rotate the texture instead + sphere.transform.Rotate(Vector3.up * sphereRotation * Time.deltaTime); + sphere.transform.Rotate(Vector3.right * pitchDelta * 10 * Time.deltaTime); + + Pitch = Mathf.Clamp(Pitch + pitchDelta, -90f, 90f); + _mediaPlayerScreen.UpdateViewpoint(Yaw + yawDelta, Pitch, Roll, 80); } -} + +} \ No newline at end of file -- GitLab