arcball transform system for camera
							parent
							
								
									df59c033ef
								
							
						
					
					
						commit
						a8e8402833
					
				
							
								
								
									
										2
									
								
								FNA
								
								
								
								
							
							
								
								
								
								
								
								
							
						
						
									
										2
									
								
								FNA
								
								
								
								
							|  | @ -1 +1 @@ | ||||||
| Subproject commit 9a8a84c3d427f47759a92342aaa8f7f08e751a64 | Subproject commit c665d2e08c25fb63e58e987b7c1af75af22aa010 | ||||||
							
								
								
									
										2
									
								
								Kav
								
								
								
								
							
							
								
								
								
								
								
								
							
						
						
									
										2
									
								
								Kav
								
								
								
								
							|  | @ -1 +1 @@ | ||||||
| Subproject commit d156fbc39a771ac990cbb809b82ba771464785a5 | Subproject commit 55b1555df2ded543e623c8b5eb60d3a3fff9e32c | ||||||
|  | @ -0,0 +1,14 @@ | ||||||
|  | using Encompass; | ||||||
|  | 
 | ||||||
|  | namespace KavTest | ||||||
|  | { | ||||||
|  |     public struct ArcballTransformComponent : IComponent | ||||||
|  |     { | ||||||
|  |         public ArcballTransform ArcballTransform { get; } | ||||||
|  | 
 | ||||||
|  |         public ArcballTransformComponent(ArcballTransform arcballTransform) | ||||||
|  |         { | ||||||
|  |             ArcballTransform = arcballTransform; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -4,9 +4,9 @@ using KavTest.Messages; | ||||||
| 
 | 
 | ||||||
| namespace KavTest.Engines | namespace KavTest.Engines | ||||||
| { | { | ||||||
|     [Reads(typeof(CameraComponent))] |     [Reads(typeof(CameraComponent), typeof(ArcballTransformComponent))] | ||||||
|     [Receives(typeof(MoveCameraMessage))] |     [Receives(typeof(MoveCameraMessage), typeof(RotateCameraMessage))] | ||||||
|     [Sends(typeof(LocalTranslationMessage))] |     [Writes(typeof(ArcballTransformComponent))] | ||||||
|     public class CameraEngine : Engine |     public class CameraEngine : Engine | ||||||
|     { |     { | ||||||
|         public override void Update(double dt) |         public override void Update(double dt) | ||||||
|  | @ -14,11 +14,21 @@ namespace KavTest.Engines | ||||||
|             if (SomeComponent<CameraComponent>()) |             if (SomeComponent<CameraComponent>()) | ||||||
|             { |             { | ||||||
|                 var cameraEntity = ReadEntity<CameraComponent>(); |                 var cameraEntity = ReadEntity<CameraComponent>(); | ||||||
|  |                 var arcballTransformComponent = GetComponent<ArcballTransformComponent>(cameraEntity); | ||||||
|  | 
 | ||||||
|  |                 var transform = arcballTransformComponent.ArcballTransform; | ||||||
| 
 | 
 | ||||||
|                 foreach (var moveMessage in ReadMessages<MoveCameraMessage>()) |                 foreach (var moveMessage in ReadMessages<MoveCameraMessage>()) | ||||||
|                 { |                 { | ||||||
|                     SendMessage(new LocalTranslationMessage(cameraEntity, moveMessage.Translation * (float)dt)); |                     transform = transform.TranslateLocal(moveMessage.Translation * (float)dt); | ||||||
|                 } |                 } | ||||||
|  | 
 | ||||||
|  |                 foreach (var rotateMessage in ReadMessages<RotateCameraMessage>()) | ||||||
|  |                 { | ||||||
|  |                     transform = transform.RotateLocal(-rotateMessage.Yaw * 0.25f * (float)dt, rotateMessage.Pitch * 0.25f * (float)dt); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 SetComponent(cameraEntity, new ArcballTransformComponent(transform)); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -1,16 +1,35 @@ | ||||||
| using Encompass; | using Encompass; | ||||||
|  | using KavTest.Components; | ||||||
| using KavTest.Messages; | using KavTest.Messages; | ||||||
| using Microsoft.Xna.Framework; | using Microsoft.Xna.Framework; | ||||||
| using Microsoft.Xna.Framework.Input; | using Microsoft.Xna.Framework.Input; | ||||||
| 
 | 
 | ||||||
| namespace KavTest.Engines | namespace KavTest.Engines | ||||||
| { | { | ||||||
|     [Sends(typeof(MoveCameraMessage))] |     [Reads(typeof(CameraComponent))] | ||||||
|  |     [Sends( | ||||||
|  |         typeof(MoveCameraMessage), | ||||||
|  |         typeof(RotateCameraMessage) | ||||||
|  |     )] | ||||||
|     public class InputEngine : Engine |     public class InputEngine : Engine | ||||||
|     { |     { | ||||||
|  |         private int centerX; | ||||||
|  |         private int centerY; | ||||||
|  | 
 | ||||||
|  |         public InputEngine(int centerX, int centerY) | ||||||
|  |         { | ||||||
|  |             System.Console.WriteLine(centerX); | ||||||
|  |             System.Console.WriteLine(centerY); | ||||||
|  |             this.centerX = centerX; | ||||||
|  |             this.centerY = centerY; | ||||||
|  |             Mouse.SetPosition(centerX, centerY); | ||||||
|  |             System.Console.WriteLine(Mouse.GetState().X); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         public override void Update(double dt) |         public override void Update(double dt) | ||||||
|         { |         { | ||||||
|             var keyboardState = Keyboard.GetState(); |             var keyboardState = Keyboard.GetState(); | ||||||
|  |             var mouseState = Mouse.GetState(); | ||||||
| 
 | 
 | ||||||
|             if (keyboardState.IsKeyDown(Keys.W)) |             if (keyboardState.IsKeyDown(Keys.W)) | ||||||
|             { |             { | ||||||
|  | @ -31,6 +50,15 @@ namespace KavTest.Engines | ||||||
|             { |             { | ||||||
|                 SendMessage(new MoveCameraMessage(new Vector3(5, 0, 0))); |                 SendMessage(new MoveCameraMessage(new Vector3(5, 0, 0))); | ||||||
|             } |             } | ||||||
|  | 
 | ||||||
|  |             var mouseMovement = new Vector2(centerX - mouseState.X, centerY - mouseState.Y); | ||||||
|  |             Mouse.SetPosition(centerX, centerY); | ||||||
|  | 
 | ||||||
|  |             if (SomeComponent<CameraComponent>()) | ||||||
|  |             { | ||||||
|  |                 var cameraEntity = ReadEntity<CameraComponent>(); | ||||||
|  |                 SendMessage(new RotateCameraMessage(cameraEntity, mouseMovement.X, mouseMovement.Y)); | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -36,7 +36,7 @@ namespace KavTest | ||||||
|                 Smuggler.Importer.ImportGLB(GraphicsDevice, File.OpenRead("Content/rustysphere.glb")) |                 Smuggler.Importer.ImportGLB(GraphicsDevice, File.OpenRead("Content/rustysphere.glb")) | ||||||
|             ); |             ); | ||||||
| 
 | 
 | ||||||
|             WorldBuilder.AddEngine(new InputEngine()); |             WorldBuilder.AddEngine(new InputEngine(GraphicsDevice.Viewport.Width / 2, GraphicsDevice.Viewport.Height / 2)); | ||||||
|             WorldBuilder.AddEngine(new AngularVelocityEngine()); |             WorldBuilder.AddEngine(new AngularVelocityEngine()); | ||||||
|             WorldBuilder.AddEngine(new MotionEngine()); |             WorldBuilder.AddEngine(new MotionEngine()); | ||||||
|             WorldBuilder.AddEngine(new CameraEngine()); |             WorldBuilder.AddEngine(new CameraEngine()); | ||||||
|  | @ -65,15 +65,13 @@ namespace KavTest | ||||||
|                 300f |                 300f | ||||||
|             )); |             )); | ||||||
| 
 | 
 | ||||||
|             var cameraTransform = new Transform3D( |  | ||||||
|                 new Vector3(0, 0, -10), |  | ||||||
|                 Quaternion.CreateFromAxisAngle(Vector3.Up, MathHelper.Pi), |  | ||||||
|                 Vector3.One |  | ||||||
|             ); |  | ||||||
| 
 |  | ||||||
|             var cameraEntity = WorldBuilder.CreateEntity(); |             var cameraEntity = WorldBuilder.CreateEntity(); | ||||||
|             WorldBuilder.SetComponent(cameraEntity, new Transform3DComponent( |             WorldBuilder.SetComponent(cameraEntity, new ArcballTransformComponent( | ||||||
|                 cameraTransform |                 new ArcballTransform( | ||||||
|  |                     new Vector3(0, 0, -10), | ||||||
|  |                     MathHelper.Pi, | ||||||
|  |                     0 | ||||||
|  |                 ) | ||||||
|             )); |             )); | ||||||
|             WorldBuilder.SetComponent(cameraEntity, new CameraComponent( |             WorldBuilder.SetComponent(cameraEntity, new CameraComponent( | ||||||
|                 Matrix.CreatePerspectiveFieldOfView( |                 Matrix.CreatePerspectiveFieldOfView( | ||||||
|  |  | ||||||
|  | @ -0,0 +1,18 @@ | ||||||
|  | using Encompass; | ||||||
|  | 
 | ||||||
|  | namespace KavTest | ||||||
|  | { | ||||||
|  |     public struct RotateCameraMessage : IMessage, IHasEntity | ||||||
|  |     { | ||||||
|  |         public Entity Entity { get; } | ||||||
|  |         public float Yaw { get; } | ||||||
|  |         public float Pitch { get; } | ||||||
|  | 
 | ||||||
|  |         public RotateCameraMessage(Entity entity, float yaw, float pitch) | ||||||
|  |         { | ||||||
|  |             Entity = entity; | ||||||
|  |             Yaw = yaw; | ||||||
|  |             Pitch = pitch; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -54,11 +54,11 @@ namespace KavTest.Renderers | ||||||
|             if (SomeComponent<CameraComponent>()) |             if (SomeComponent<CameraComponent>()) | ||||||
|             { |             { | ||||||
|                 var cameraEntity = ReadEntity<CameraComponent>(); |                 var cameraEntity = ReadEntity<CameraComponent>(); | ||||||
|                 var transformComponent = GetComponent<Transform3DComponent>(cameraEntity); |                 var transformComponent = GetComponent<ArcballTransformComponent>(cameraEntity); | ||||||
|                 var cameraComponent = GetComponent<CameraComponent>(cameraEntity); |                 var cameraComponent = GetComponent<CameraComponent>(cameraEntity); | ||||||
| 
 | 
 | ||||||
|                 var camera = new Kav.Camera( |                 var camera = new Kav.Camera( | ||||||
|                     transformComponent.Transform.TransformMatrix, |                     transformComponent.ArcballTransform.TransformMatrix, | ||||||
|                     cameraComponent.Projection |                     cameraComponent.Projection | ||||||
|                 ); |                 ); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -0,0 +1,51 @@ | ||||||
|  | using Microsoft.Xna.Framework; | ||||||
|  | 
 | ||||||
|  | namespace KavTest | ||||||
|  | { | ||||||
|  |     public struct ArcballTransform | ||||||
|  |     { | ||||||
|  |         public Vector3 Position { get; } | ||||||
|  |         public float Yaw { get; } | ||||||
|  |         public float Pitch { get; } | ||||||
|  | 
 | ||||||
|  |         private Matrix RotationMatrix { get; } | ||||||
|  |         public Matrix TransformMatrix { get; } | ||||||
|  |         public Vector3 Forward { get { return TransformMatrix.Forward; } } | ||||||
|  |         public Vector3 Right { get { return TransformMatrix.Right; } } | ||||||
|  |         public Vector3 Up { get { return TransformMatrix.Up; } } | ||||||
|  | 
 | ||||||
|  |         public ArcballTransform(Vector3 position, float yaw, float pitch) | ||||||
|  |         { | ||||||
|  |             Position = position; | ||||||
|  |             Yaw = yaw; | ||||||
|  |             Pitch = pitch; | ||||||
|  |             RotationMatrix = CreateRotationMatrix(Yaw, Pitch); | ||||||
|  |             TransformMatrix = CreateTransformMatrix(Position, RotationMatrix); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public ArcballTransform RotateLocal(float deltaYaw, float deltaPitch) | ||||||
|  |         { | ||||||
|  |             return new ArcballTransform(Position, Yaw + deltaYaw, Pitch + deltaPitch); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public ArcballTransform TranslateLocal(Vector3 localTranslation) | ||||||
|  |         { | ||||||
|  |             var worldTranslation = Vector3.Transform(localTranslation, RotationMatrix); | ||||||
|  |             return new ArcballTransform(Position + worldTranslation, Yaw, Pitch); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         private static Matrix CreateRotationMatrix(float yaw, float pitch) | ||||||
|  |         { | ||||||
|  |             return | ||||||
|  |                 Matrix.CreateRotationX(pitch) * | ||||||
|  |                 Matrix.CreateRotationY(yaw); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         private static Matrix CreateTransformMatrix(Vector3 position, Matrix rotation) | ||||||
|  |         { | ||||||
|  |             return | ||||||
|  |                 rotation * | ||||||
|  |                 Matrix.CreateTranslation(position); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -1 +1 @@ | ||||||
| Subproject commit 0a30dab3c2a8ef4ce435af8123bcb64efe4926d8 | Subproject commit bdd9f595493609444d8ebb31b9d07b7ef320eafb | ||||||
		Loading…
	
		Reference in New Issue