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 | ||||
| { | ||||
|     [Reads(typeof(CameraComponent))] | ||||
|     [Receives(typeof(MoveCameraMessage))] | ||||
|     [Sends(typeof(LocalTranslationMessage))] | ||||
|     [Reads(typeof(CameraComponent), typeof(ArcballTransformComponent))] | ||||
|     [Receives(typeof(MoveCameraMessage), typeof(RotateCameraMessage))] | ||||
|     [Writes(typeof(ArcballTransformComponent))] | ||||
|     public class CameraEngine : Engine | ||||
|     { | ||||
|         public override void Update(double dt) | ||||
|  | @ -14,11 +14,21 @@ namespace KavTest.Engines | |||
|             if (SomeComponent<CameraComponent>()) | ||||
|             { | ||||
|                 var cameraEntity = ReadEntity<CameraComponent>(); | ||||
|                 var arcballTransformComponent = GetComponent<ArcballTransformComponent>(cameraEntity); | ||||
| 
 | ||||
|                 var transform = arcballTransformComponent.ArcballTransform; | ||||
| 
 | ||||
|                 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 KavTest.Components; | ||||
| using KavTest.Messages; | ||||
| using Microsoft.Xna.Framework; | ||||
| using Microsoft.Xna.Framework.Input; | ||||
| 
 | ||||
| namespace KavTest.Engines | ||||
| { | ||||
|     [Sends(typeof(MoveCameraMessage))] | ||||
|     [Reads(typeof(CameraComponent))] | ||||
|     [Sends( | ||||
|         typeof(MoveCameraMessage), | ||||
|         typeof(RotateCameraMessage) | ||||
|     )] | ||||
|     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) | ||||
|         { | ||||
|             var keyboardState = Keyboard.GetState(); | ||||
|             var mouseState = Mouse.GetState(); | ||||
| 
 | ||||
|             if (keyboardState.IsKeyDown(Keys.W)) | ||||
|             { | ||||
|  | @ -31,6 +50,15 @@ namespace KavTest.Engines | |||
|             { | ||||
|                 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")) | ||||
|             ); | ||||
| 
 | ||||
|             WorldBuilder.AddEngine(new InputEngine()); | ||||
|             WorldBuilder.AddEngine(new InputEngine(GraphicsDevice.Viewport.Width / 2, GraphicsDevice.Viewport.Height / 2)); | ||||
|             WorldBuilder.AddEngine(new AngularVelocityEngine()); | ||||
|             WorldBuilder.AddEngine(new MotionEngine()); | ||||
|             WorldBuilder.AddEngine(new CameraEngine()); | ||||
|  | @ -65,15 +65,13 @@ namespace KavTest | |||
|                 300f | ||||
|             )); | ||||
| 
 | ||||
|             var cameraTransform = new Transform3D( | ||||
|                 new Vector3(0, 0, -10), | ||||
|                 Quaternion.CreateFromAxisAngle(Vector3.Up, MathHelper.Pi), | ||||
|                 Vector3.One | ||||
|             ); | ||||
| 
 | ||||
|             var cameraEntity = WorldBuilder.CreateEntity(); | ||||
|             WorldBuilder.SetComponent(cameraEntity, new Transform3DComponent( | ||||
|                 cameraTransform | ||||
|             WorldBuilder.SetComponent(cameraEntity, new ArcballTransformComponent( | ||||
|                 new ArcballTransform( | ||||
|                     new Vector3(0, 0, -10), | ||||
|                     MathHelper.Pi, | ||||
|                     0 | ||||
|                 ) | ||||
|             )); | ||||
|             WorldBuilder.SetComponent(cameraEntity, new CameraComponent( | ||||
|                 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>()) | ||||
|             { | ||||
|                 var cameraEntity = ReadEntity<CameraComponent>(); | ||||
|                 var transformComponent = GetComponent<Transform3DComponent>(cameraEntity); | ||||
|                 var transformComponent = GetComponent<ArcballTransformComponent>(cameraEntity); | ||||
|                 var cameraComponent = GetComponent<CameraComponent>(cameraEntity); | ||||
| 
 | ||||
|                 var camera = new Kav.Camera( | ||||
|                     transformComponent.Transform.TransformMatrix, | ||||
|                     transformComponent.ArcballTransform.TransformMatrix, | ||||
|                     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