Jelajahi Sumber

Added VR controllers layer

vpenades 2 tahun lalu
induk
melakukan
560208db98

+ 1 - 1
demos/Demo4.VR/Demo4.VR.csproj

@@ -15,7 +15,7 @@
  </ItemGroup>
 
   <ItemGroup>
-    <Content Include="..\SharedResources\*.glb" LinkBase="Content" CopyToOutputDirectory="PreserveNewest" />
+    <Content Include="..\SharedResources\**\*.*" LinkBase="Content" CopyToOutputDirectory="PreserveNewest" />
   </ItemGroup>
 
   <ItemGroup>

+ 9 - 7
demos/Demo4.VR/VRGameDemo.cs

@@ -26,9 +26,13 @@ namespace Primitives3D
         {
             base.LoadContent();
 
-            var component = new VRSceneDemo(this);
-            component.Initialize();
-            this.Components.Add(component);
+            var component1 = new VRSceneDemo(this);
+            component1.Initialize();
+            this.Components.Add(component1);
+
+            var component2 = new VRHandsLayer(this);
+            component2.Initialize();
+            this.Components.Add(component2);
         }
 
         #endregion                
@@ -50,7 +54,7 @@ namespace Primitives3D
         /// <inheritdoc/>
         protected override void Update(GameTime gameTime)
         {
-            UpdateXRDevice();
+            UpdateXRDevice(Matrix.CreateTranslation(0, 1.7f, 0));
 
             HandleInput();
 
@@ -123,9 +127,7 @@ namespace Primitives3D
         /// <inheritdoc/>        
         protected override void Draw(GameTime gameTime)
         {
-            var cameraPosition = new Vector3(0, 1.7f, 0);            
-
-            this.DrawStereo(gameTime, cameraPosition, out var leftView, out var rightView);
+            this.DrawStereo(gameTime, out var leftView, out var rightView);
 
             if (true)
             {

+ 87 - 0
demos/Demo4.VR/VRSHandsLayer.cs

@@ -0,0 +1,87 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Graphics;
+
+using MonoScene.Graphics;
+
+namespace Primitives3D
+{
+    class VRHandsLayer : XRGameComponent
+    {
+        #region lifecycle
+        public VRHandsLayer(XRGame game) : base(game)
+        {
+        }
+
+        protected override void LoadContent()
+        {
+            base.LoadContent();
+            
+            var gltfFactory = new MonoScene.Graphics.Pipeline.GltfModelFactory(this.GraphicsDevice);
+
+            _LeftTemplate = gltfFactory.LoadModel("Content\\OculusTouchForQuestAndRiftS\\OculusTouchForQuestAndRiftS_Left.gltf");
+            _RightTemplate = gltfFactory.LoadModel("Content\\OculusTouchForQuestAndRiftS\\OculusTouchForQuestAndRiftS_Right.gltf");
+        }
+
+        protected override void UnloadContent()
+        {
+            _LeftTemplate?.Dispose();
+            _RightTemplate?.Dispose();
+
+            base.UnloadContent();            
+        }
+        #endregion
+
+        #region data
+
+        private PBREnvironment _LightsAndFog = PBREnvironment.CreateDefault();
+        
+        private DeviceModelCollection _LeftTemplate;
+        private DeviceModelCollection _RightTemplate;
+
+        private ModelInstance _LeftHand;
+        private ModelInstance _RightHand;       
+
+        #endregion
+
+        #region update
+
+        public override void Update(GameTime gameTime)
+        {
+            base.Update(gameTime);
+
+            _LeftHand ??= _LeftTemplate.DefaultModel.CreateInstance();
+            _RightHand ??= _RightTemplate.DefaultModel.CreateInstance();
+
+            var hands = this.GetHandsState();            
+
+            var controllerXForm = Matrix.CreateScale(0.01f) * Matrix.CreateRotationY((float)Math.PI);            
+
+            _LeftHand.WorldMatrix = controllerXForm * hands.LHandTransform * this.XRGame.HeadMatrix;
+            _RightHand.WorldMatrix = controllerXForm * hands.RHandTransform * this.XRGame.HeadMatrix;
+        }
+
+        #endregion
+
+        #region draw
+
+        public override void Draw(GameTime gameTime, XRSceneContext sceneContext)
+        {
+            var dc = new ModelDrawingContext(this.GraphicsDevice);
+            
+            dc.SetCamera(Matrix.Invert(sceneContext.ViewMatrix));            
+            dc.SetProjectionMatrix(sceneContext.GetProjectionMatrix(0.1f, 100));
+
+            dc.DrawSceneInstances(_LightsAndFog, _LeftHand, _RightHand);
+
+            base.Draw(gameTime, sceneContext);            
+        }
+
+        #endregion
+    }
+}

+ 9 - 8
demos/Demo4.VR/XRGame.cs

@@ -37,10 +37,7 @@ namespace Microsoft.Xna.Framework
 
         protected override void Dispose(bool disposing)
         {
-            if (disposing)
-            {
-                ovrDevice?.Dispose();
-            }
+            if (disposing) { ovrDevice?.Dispose(); }
 
             base.Dispose(disposing);
         }
@@ -53,17 +50,21 @@ namespace Microsoft.Xna.Framework
 
         OvrDevice ovrDevice;
 
+        public Matrix HeadMatrix { get; private set; }
+
         #endregion
 
-        #region Update
+        #region Update        
 
         public HandsState GetHandsState()
         {
             return ovrDevice.GetHandsState();
         }           
 
-        protected void UpdateXRDevice()
+        protected void UpdateXRDevice(Matrix headMatrix)
         {
+            this.HeadMatrix = headMatrix;
+
             if (!ovrDevice.IsConnected)
             {
                 try
@@ -83,7 +84,7 @@ namespace Microsoft.Xna.Framework
 
         #region Draw
 
-        protected virtual void DrawStereo(GameTime gameTime, Vector3 cameraPosition, out Matrix leftView, out Matrix rightView)
+        protected virtual void DrawStereo(GameTime gameTime, out Matrix leftView, out Matrix rightView)
         {
             leftView = Matrix.Identity;
             rightView = Matrix.Identity;
@@ -104,7 +105,7 @@ namespace Microsoft.Xna.Framework
                 // VR eye view and projection
                 var view = headsetState.GetEyeView(eye);
 
-                Matrix globalWorld = Matrix.CreateWorld(cameraPosition, Vector3.Forward, Vector3.Up);
+                Matrix globalWorld = this.HeadMatrix;
                 view = Matrix.Invert(globalWorld) * view;
 
                 if (eye == 0) leftView = view;